From b9296f8e65e35c011aec571b4f4c03bdbec4ece0 Mon Sep 17 00:00:00 2001 From: Ranjandas Date: Tue, 30 Apr 2024 01:00:15 +1000 Subject: [PATCH 001/185] Fixed broken link in the ECS documentation (#21018) --- website/content/docs/ecs/deploy/bind-addresses.mdx | 4 ++-- website/content/docs/ecs/deploy/configure-routes.mdx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/content/docs/ecs/deploy/bind-addresses.mdx b/website/content/docs/ecs/deploy/bind-addresses.mdx index 0eea916687..acee9209ea 100644 --- a/website/content/docs/ecs/deploy/bind-addresses.mdx +++ b/website/content/docs/ecs/deploy/bind-addresses.mdx @@ -17,8 +17,8 @@ Binding workloads to the loopback address ensures that your application only rec Consul service mesh must be deployed to ECS before you can bind a network address. For more information, refer to the following topics: -- [Deploy Consul to ECS using the Terraform module](/consul/docs/ecs/deploy/install-terraform) -- [Deploy Consul to ECS manually](/consul/docs/ecs/deploy/install-manual) +- [Deploy Consul to ECS using the Terraform module](/consul/docs/ecs/deploy/terraform) +- [Deploy Consul to ECS manually](/consul/docs/ecs/deploy/manual) ## Change the listening address diff --git a/website/content/docs/ecs/deploy/configure-routes.mdx b/website/content/docs/ecs/deploy/configure-routes.mdx index 11014f99a3..ed9b996104 100644 --- a/website/content/docs/ecs/deploy/configure-routes.mdx +++ b/website/content/docs/ecs/deploy/configure-routes.mdx @@ -20,8 +20,8 @@ To enable tasks to call through the service mesh, complete the following steps: Consul service mesh must be deployed to ECS before you can bind a network address. For more information, refer to the following topics: -- [Deploy Consul to ECS using the Terraform module](/consul/docs/ecs/deploy/install-terraform) -- [Deploy Consul to ECS manually](/consul/docs/ecs/deploy/install-manual) +- [Deploy Consul to ECS using the Terraform module](/consul/docs/ecs/deploy/terraform) +- [Deploy Consul to ECS manually](/consul/docs/ecs/deploy/manual) ## Configure the sidecar proxy @@ -76,4 +76,4 @@ module "web" { ] ... } -``` \ No newline at end of file +``` From bbd8080ec02dc5e50bb534a6bfd53901ecd8939f Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Wed, 1 May 2024 09:09:08 -0700 Subject: [PATCH 002/185] HCP Consul Dedicated Rebrand changes (#21026) * HCP Consul Dedicated rebrand * Dedicated rebrand * path change * Update website/content/docs/architecture/index.mdx Co-authored-by: Krastin Krastev * typo --------- Co-authored-by: Krastin Krastev --- website/content/api-docs/api-structure.mdx | 2 +- website/content/docs/architecture/index.mdx | 2 +- website/content/docs/architecture/scale.mdx | 2 +- .../content/docs/architecture/v2/index.mdx | 3 +- .../docs/concepts/service-discovery.mdx | 2 +- .../content/docs/concepts/service-mesh.mdx | 6 ++-- .../docs/connect/cluster-peering/index.mdx | 4 +-- .../usage/establish-cluster-peering.mdx | 2 +- .../content/docs/connect/dataplane/index.mdx | 4 +-- .../gateways/api-gateway/tech-specs.mdx | 4 +-- website/content/docs/ecs/index.mdx | 2 +- website/content/docs/ecs/tech-specs.mdx | 2 +- website/content/docs/enterprise/index.mdx | 10 +++---- .../content/docs/enterprise/license/faq.mdx | 4 +-- website/content/docs/install/ports.mdx | 28 +++++++++---------- .../content/docs/integrate/partnerships.mdx | 28 +++++++++---------- website/content/docs/intro/index.mdx | 2 +- website/content/docs/k8s/helm.mdx | 6 ++-- website/content/docs/k8s/multiport/index.mdx | 3 +- website/content/docs/nia/compatibility.mdx | 2 +- website/content/docs/nia/configuration.mdx | 2 +- .../content/docs/nia/enterprise/license.mdx | 2 +- .../consul-api-gateway/v0_1_x.mdx | 2 +- .../docs/release-notes/consul-k8s/v1_3_x.mdx | 2 +- .../consul-terraform-sync/v0_6_x.mdx | 6 ++-- website/data/docs-nav-data.json | 4 +-- 26 files changed, 69 insertions(+), 67 deletions(-) diff --git a/website/content/api-docs/api-structure.mdx b/website/content/api-docs/api-structure.mdx index 0959e90643..32a8a2c17c 100644 --- a/website/content/api-docs/api-structure.mdx +++ b/website/content/api-docs/api-structure.mdx @@ -163,4 +163,4 @@ representation of a 128-bit value. ## CORS HTTP Response Headers As of Consul 1.18, Consul adds an HTTP header `Access-Control-Expose-Headers: x-consul-default-acl-policy` to -all responses in order to support linking self-managed Consul clusters to HCP Consul Central. +all responses in order to support linking self-managed Enterprise clusters to HCP Consul Central. diff --git a/website/content/docs/architecture/index.mdx b/website/content/docs/architecture/index.mdx index a4656a7718..dc3f7954bd 100644 --- a/website/content/docs/architecture/index.mdx +++ b/website/content/docs/architecture/index.mdx @@ -25,7 +25,7 @@ The Consul control plane contains one or more _datacenters_. A datacenter is the ### Clusters -A collection of Consul agents that are aware of each other is called a _cluster_. The terms _datacenter_ and _cluster_ are often used interchangeably. In some cases, however, _cluster_ refers only to Consul server agents, such as in [HCP Consul](https://cloud.hashicorp.com/products/consul). In other contexts, such as the [_admin partitions_](/consul/docs/enterprise/admin-partitions) feature included with Consul Enterprise, a cluster may refer to collection of client agents. +A collection of Consul agents that are aware of each other is called a _cluster_. The terms _datacenter_ and _cluster_ are often used interchangeably. In some cases, however, _cluster_ refers only to Consul server agents, such as in [HCP Consul Dedicated](https://cloud.hashicorp.com/products/consul). In other contexts, such as the [_admin partitions_](/consul/docs/enterprise/admin-partitions) feature included with Consul Enterprise, a cluster may refer to collection of client agents. ## Agents diff --git a/website/content/docs/architecture/scale.mdx b/website/content/docs/architecture/scale.mdx index d3aceeb0d4..119e05454a 100644 --- a/website/content/docs/architecture/scale.mdx +++ b/website/content/docs/architecture/scale.mdx @@ -77,7 +77,7 @@ Consul server agents are an important part of Consul’s architecture. This sect Consul servers can be deployed on a few different runtimes: -- **HashiCorp Cloud Platform (HCP) Consul (Managed)**. These Consul servers are deployed in a hosted environment managed by HCP. To get started with HCP Consul servers in Kubernetes or VM deployments, refer to the [Deploy HCP Consul tutorial](/consul/tutorials/get-started-hcp/hcp-gs-deploy). +- **HashiCorp Cloud Platform (HCP) Consul Dedicated**. These Consul servers are deployed in a hosted environment managed by HCP. To get started with HCP Consul Dedicated servers in Kubernetes or VM deployments, refer to the [Deploy HCP Consul Dedicated tutorial](/consul/tutorials/get-started-hcp/hcp-gs-deploy). - **VMs or bare metal servers (Self-managed)**. To get started with Consul on VMs or bare metal servers, refer to the [Deploy Consul server tutorial](/consul/tutorials/get-started-vms/virtual-machine-gs-deploy). For a full list of configuration options, refer to [Agents Overview](/consul/docs/agent). - **Kubernetes (Self-managed)**. To get started with Consul on Kubernetes, refer to the [Deploy Consul on Kubernetes tutorial](/consul/tutorials/get-started-kubernetes/kubernetes-gs-deploy). - **Other container environments, including Docker, Rancher, and Mesos (Self-managed)**. diff --git a/website/content/docs/architecture/v2/index.mdx b/website/content/docs/architecture/v2/index.mdx index b4c7a1e0cc..8301f370e4 100644 --- a/website/content/docs/architecture/v2/index.mdx +++ b/website/content/docs/architecture/v2/index.mdx @@ -53,7 +53,8 @@ Be aware of the following constraints and technical limitations on the v2 catalo - The v1 and v2 catalog APIs cannot run concurrently. Because configuration entries are part of the v1 catalog, you cannot use them when the v2 catalog is enabled. Use v2 resources instead. - The Consul UI does not support the v2 catalog API in this release. You must disable the UI in the Helm chart in order to use the v2 catalog API. - Secondary datacenters in WAN-federated deployments cannot enable the v2 catalog API in this release. -- HCP Consul does not support the v2 catalog API in this release. You cannot [link a self-managed cluster to HCP Consul](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. +- HCP Consul Dedicated does not support the v2 catalog API in this release. +- You cannot [link a self-managed cluster to HCP Consul Central](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. - We do not recommend updating existing clusters to enable the v2 catalog in this release. Instead, deploy a new Consul cluster and [enable the v2 catalog in the Helm chart](/consul/docs/k8s/multiport/configure#enable-the-v2-catalog). ## Guidance diff --git a/website/content/docs/concepts/service-discovery.mdx b/website/content/docs/concepts/service-discovery.mdx index 4313ba3e15..44c83b7414 100644 --- a/website/content/docs/concepts/service-discovery.mdx +++ b/website/content/docs/concepts/service-discovery.mdx @@ -82,7 +82,7 @@ Consul's service discovery capabilities help you discover, track, and monitor th You can use Consul with virtual machines (VMs), containers, serverless technologies, or with container orchestration platforms, such as [Nomad](https://www.nomadproject.io/) and Kubernetes. Consul is platform agnostic which makes it a great fit for all environments, including legacy platforms. -Consul is available as a [self-managed](/consul/downloads) project or as a fully managed service mesh solution ([HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs)). HCP Consul enables users to discover and securely connect services without the added operational burden of maintaining a service mesh on their own. +Consul is available as a [self-managed](/consul/downloads) project or as a fully managed service mesh solution ([HCP Consul Dedicated](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs)). HCP Consul Dedicated enables users to discover and securely connect services without the added operational burden of maintaining a service mesh on their own. ## Next steps diff --git a/website/content/docs/concepts/service-mesh.mdx b/website/content/docs/concepts/service-mesh.mdx index 947984484e..33ebf1478d 100644 --- a/website/content/docs/concepts/service-mesh.mdx +++ b/website/content/docs/concepts/service-mesh.mdx @@ -107,12 +107,12 @@ In simple terms, Consul is the control plane of the service mesh. The data plane You can use Consul with virtual machines (VMs), containers, or with container orchestration platforms, such as [Nomad](https://www.nomadproject.io/) and Kubernetes. Consul is platform agnostic which makes it a great fit for all environments, including legacy platforms. -Consul is available as a [self-install](/consul/downloads) project or as a fully managed service mesh solution called [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). -HCP Consul enables users to discover and securely connect services without the added operational burden of maintaining a service mesh on their own. +Consul is available as a [self-install](/consul/downloads) project or as a fully managed service mesh solution called [HCP Consul Dedicated](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). +HCP Consul Dedicated enables users to discover and securely connect services without the added operational burden of maintaining a service mesh on their own. You can learn more about Consul by visiting the Consul [tutorials](/consul/tutorials). ## Next -Get started today with a service mesh by leveraging [HCP Consul](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). +Get started today with a service mesh by leveraging [HCP Consul Dedicated](https://portal.cloud.hashicorp.com/sign-in?utm_source=consul_docs). Prepare your organization for the future of multi-cloud and embrace a [zero-trust](https://www.hashicorp.com/solutions/zero-trust-security) architecture. diff --git a/website/content/docs/connect/cluster-peering/index.mdx b/website/content/docs/connect/cluster-peering/index.mdx index 864dadd418..1714fc0fb0 100644 --- a/website/content/docs/connect/cluster-peering/index.mdx +++ b/website/content/docs/connect/cluster-peering/index.mdx @@ -71,11 +71,11 @@ The following resources are available to help you use Consul's cluster peering f - [Manage L7 traffic with cluster peering on Kubernetes](/consul/docs/k8s/connect/cluster-peering/usage/l7-traffic) - [Create sameness groups on Kubernetes](/consul/docs/k8s/connect/cluster-peering/usage/create-sameness-groups) -### HCP Consul documentation +### HCP Consul Central documentation - [Cluster peering](/hcp/docs/consul/usage/cluster-peering) - [Cluster peering topologies](/hcp/docs/consul/usage/cluster-peering/topologies) -- [Establish cluster peering connections on HCP Consul](/hcp/docs/consul/usage/cluster-peering/create-connections) +- [Establish cluster peering connections on HCP Consul Central](/hcp/docs/consul/usage/cluster-peering/create-connections) - [Cluster peering with HCP Consul Central](/hcp/docs/extend/cluster-peering/establish) ### Reference documentation diff --git a/website/content/docs/connect/cluster-peering/usage/establish-cluster-peering.mdx b/website/content/docs/connect/cluster-peering/usage/establish-cluster-peering.mdx index 9dc315c65a..4e0128bb3e 100644 --- a/website/content/docs/connect/cluster-peering/usage/establish-cluster-peering.mdx +++ b/website/content/docs/connect/cluster-peering/usage/establish-cluster-peering.mdx @@ -16,7 +16,7 @@ This page details the process for establishing a cluster peering connection betw Cluster peering between services cannot be established until all four steps are complete. If you want to establish cluster peering connections and create sameness groups at the same time, refer to the guidance in [create sameness groups](/consul/docs/connect/cluster-peering/usage/create-sameness-groups). -For Kubernetes guidance, refer to [Establish cluster peering connections on Kubernetes](/consul/docs/k8s/connect/cluster-peering/usage/establish-peering). For HCP Consul guidance, refer to [Establish cluster peering connections on HCP Consul](/hcp/docs/consul/usage/cluster-peering/create-connections). +For Kubernetes guidance, refer to [Establish cluster peering connections on Kubernetes](/consul/docs/k8s/connect/cluster-peering/usage/establish-peering). For HCP Consul Central guidance, refer to [Establish cluster peering connections on HCP Consul Central](/hcp/docs/consul/usage/cluster-peering/create-connections). ## Requirements diff --git a/website/content/docs/connect/dataplane/index.mdx b/website/content/docs/connect/dataplane/index.mdx index f2eaa4eb78..52230cccba 100644 --- a/website/content/docs/connect/dataplane/index.mdx +++ b/website/content/docs/connect/dataplane/index.mdx @@ -121,7 +121,7 @@ Consul Dataplane on Kubernetes supports the following features: - Running Consul service mesh in AWS Fargate and GKE Autopilot is supported. - xDS load balancing is supported. - Servers running in Kubernetes and servers external to Kubernetes are both supported. -- HCP Consul is supported. +- HCP Consul Dedicated and HCP Consul Central are supported. - Consul API Gateway Consul Dataplane on ECS support the following features: @@ -130,7 +130,7 @@ Consul Dataplane on ECS support the following features: - Mesh gateways - Running Consul service mesh in AWS Fargate and EC2 - xDS load balancing -- Self-managed and HCP Consul managed servers +- Self-managed Enterprise and HCP Consul Dedicated servers ### Technical Constraints diff --git a/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx b/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx index 98f5e28c0c..e7cc1d37ea 100644 --- a/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx +++ b/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx @@ -121,10 +121,10 @@ Refer to the [Kubernetes `ReferenceGrant` documentation](https://gateway-api.sig ## Consul server deployments -- Consul Enterprise and the free community edition are both supported. +- Consul Enterprise and the community edition are both supported. - Supported Consul Server deployment types: - Self-Managed - - HCP Consul + - HCP Consul Dedicated ### Consul feature support diff --git a/website/content/docs/ecs/index.mdx b/website/content/docs/ecs/index.mdx index 7238765af2..992d7eb3df 100644 --- a/website/content/docs/ecs/index.mdx +++ b/website/content/docs/ecs/index.mdx @@ -30,7 +30,7 @@ Refer to the following documentation and tutorials for additional guidance. ### Tutorials -- [Integrate your AWS ECS services into Consul service mesh](/consul/tutorials/cloud-integrations/consul-ecs): Shows how to use Terraform to run Consul service mesh applications on ECS with self-managed Consul or HCP-managed Consul. +- [Integrate your AWS ECS services into Consul service mesh](/consul/tutorials/cloud-integrations/consul-ecs): Shows how to use Terraform to run Consul service mesh applications on ECS with self-managed Enterprise or HCP Consul Dedicated. You can also refer to the following example configurations: diff --git a/website/content/docs/ecs/tech-specs.mdx b/website/content/docs/ecs/tech-specs.mdx index b9ff7af349..d5fa5b399f 100644 --- a/website/content/docs/ecs/tech-specs.mdx +++ b/website/content/docs/ecs/tech-specs.mdx @@ -18,7 +18,7 @@ Consul on ECS supports the following environments, runtimes, and capabilities: - **Launch Types:** Fargate and EC2 - **Network Modes:** `awsvpc` - **Subnets:** Private and public subnets. Tasks must have network access to Amazon ECR or other public container registries to pull images. -- **Consul servers:** You can use your own Consul servers running on virtual machines or [use HCP Consul to host the servers for you](/hcp/docs/consul/hcp-managed). +- **Consul servers:** You can use your own Consul servers running on virtual machines or [use HCP Consul Dedicated to host the servers for you](/hcp/docs/consul/dedicated). - **ECS controller:** The ECS controller assists with reconciling state back to Consul and facilitates Consul security features. - **Admin partitions:** Enable ACLs and configure the ECS controller to use admin partitions. You must deploy one controller for each admin partition. - **Namespaces:** Enable ACLs and configure the ECS controller to use namespaces. diff --git a/website/content/docs/enterprise/index.mdx b/website/content/docs/enterprise/index.mdx index 6427926b17..b77df69692 100644 --- a/website/content/docs/enterprise/index.mdx +++ b/website/content/docs/enterprise/index.mdx @@ -65,17 +65,17 @@ The following features are [available in several forms of Consul Enterprise](#co ## Access Consul Enterprise The method of accessing Consul Enterprise and its features depends on the whether using -HashiCorp Cloud Platform or self-managed Consul. +HashiCorp Cloud Platform or self-managed Consul Enterprise. -### HCP Consul +### HCP Consul Dedicated No action is required to access Consul Enterprise in a [HashiCorp Cloud Platform](https://cloud.hashicorp.com/products/consul) installation. -You can try out HCP Consul for free. Refer to the -[HCP Consul product page](https://cloud.hashicorp.com/products/consul) for more details. +You can try out HCP Consul Dedicated for free. Refer to the +[HCP Consul Dedicated product page](https://cloud.hashicorp.com/products/consul) for more details. -### Self-Managed Consul +### Self-managed Consul Enterprise To access Consul Enterprise in a self-managed installation, [apply a purchased license](/consul/docs/enterprise/license/overview) diff --git a/website/content/docs/enterprise/license/faq.mdx b/website/content/docs/enterprise/license/faq.mdx index d8a46ee209..4278f7ec5e 100644 --- a/website/content/docs/enterprise/license/faq.mdx +++ b/website/content/docs/enterprise/license/faq.mdx @@ -120,9 +120,9 @@ Contact your organization's [HashiCorp account team](https://support.hashicorp.c The license files are not locked to a specific cluster or cluster node. The above changes apply to all nodes in a cluster. -## Q: Will this impact HCP Consul? +## Q: Will this impact HCP Consul Dedicated? -This will not impact HCP Consul. +This will not impact HCP Consul Dedicated. ## Q: Does this need to happen every time a node restarts, or is this a one-time check? diff --git a/website/content/docs/install/ports.mdx b/website/content/docs/install/ports.mdx index 787c2a29b5..3305fac86c 100644 --- a/website/content/docs/install/ports.mdx +++ b/website/content/docs/install/ports.mdx @@ -1,7 +1,7 @@ --- layout: docs page_title: Consul ports reference -description: Find information about the ports that Consul requires for its networking functions, including required ports for HCP Consul. Required ports differ for Consul servers and clients. +description: Find information about the ports that Consul requires for its networking functions, including required ports for HCP Consul Dedicated. Required ports differ for Consul servers and clients. --- # Consul ports reference @@ -16,13 +16,13 @@ The exact ports that Consul requires depend on your network's specific configura There are slight differences between the port requirements for Consul servers and clients. When a Consul server has services, proxies, or gateways registered to it, then it acts as both a server and client. -HashiCorp-managed servers deployed using [HCP Consul](/hcp/docs/consul) have distinct port assignments. For more information, refer to [cluster management in the HCP documentation](https://developer.hashicorp.com/hcp/docs/consul/concepts/cluster-management#hashicorp-managed-clusters). +[HCP Consul Dedicated servers](/hcp/docs/consul) have distinct port assignments. For more information, refer to [cluster management in the HCP documentation](https://developer.hashicorp.com/hcp/docs/consul/concepts/cluster-management#hashicorp-managed-clusters). ## Consul servers -The following table lists port names, their function, their network protocols, their default port numbers, whether they are enabled or disabled by default, port assignments for HashiCorp-managed server clusters, and the direction of traffic from the Consul server's perspective. +The following table lists port names, their function, their network protocols, their default port numbers, whether they are enabled or disabled by default, port assignments for HCP Consul Dedicated server clusters, and the direction of traffic from the Consul server's perspective. -| Port name | Use | Protocol | Default port | Default status | HCP-managed port | Direction | +| Port name | Use | Protocol | Default port | Default status | HCP Consul Dedicated port | Direction | | :------------------------ | :----------------------------------------- | :---------- | :----------- | :------------- | :--------------- | :-------------------- | | [DNS](#dns) | The DNS server | TCP and UDP | `8600` | Enabled | Unsupported | Incoming | | [HTTP](#http) | The HTTP API | TCP | `8500` | Enabled | Unsupported | Incoming | @@ -47,7 +47,7 @@ The server's DNS port does not need to be open when DNS queries are sent to Cons If you configure recursors in Consul to upstream DNS servers, then you need outbound access to those servers on port `53`. -To resolve Consul DNS requests when using HashiCorp-managed servers on HCP Consul, we recommend running Consul clients and resolving DNS against the clients. If your use case cannot accomodate this recommendation, open a support ticket. +To resolve Consul DNS requests when using HCP Consul Dedicated, we recommend running Consul clients and resolving DNS against the clients. If your use case cannot accomodate this recommendation, open a support ticket. ### HTTP @@ -63,13 +63,13 @@ The server's HTTP port does not need to be open when Consul clients service all The Consul CLI uses the HTTP port to interact with Consul by default. -HCP Consul does not support the HTTP port. +HCP Consul Dedicated does not support the HTTP port. ### HTTPS The following table lists information about the Consul server API's HTTPS port defaults: -| Default port | Protocol | Default status | Hashicorp-managed server port | +| Default port | Protocol | Default status | HCP Consul Dedicated server port | | :----------- | :------- | :------------------ | :---------------------------- | | `8501` | TCP | Disabled by default | `443` | @@ -79,7 +79,7 @@ The server HTTPS port does not need to be open when Consul clients service all H This port is disabled by default. You can enable it in the [agent configuration file](/consul/docs/agent/config/config-files#ports) or using the [`consul agent` CLI command](/consul/docs/agent/config/cli-flags). -HCP Consul assigns port `443` to HashiCorp-managed clusters, instead of the default `8501`. +HCP Consul Dedicated assigns port `443` to HCP Consul Dedicated clusters, instead of the default `8501`. ### gRPC @@ -93,13 +93,13 @@ When using [Consul Dataplane](/consul/docs/connect/dataplane), this port receive We recommend using gRPC TLS instead, so this port is disabled by default. You can enable it in the [agent configuration file](/consul/docs/agent/config/config-files#ports) or using the [`consul agent` CLI command](/consul/docs/agent/config/cli-flags). -HCP Consul does not support the gRPC port. +HCP Consul Dedicated does not support the gRPC port. ### gRPC TLS The following table lists information about the Consul API's gRPC with TLS port defaults: -| Default port | Protocol | Default status | Hashicorp-managed server port | +| Default port | Protocol | Default status | HCP Consul Dedicated server port | | :----------- | :------- | :------------------ | :---------------------------- | | `8503` | TCP | Enabled by default | `8502` | @@ -113,7 +113,7 @@ In deployments with [cluster peering connections](/consul/docs/connect/cluster-p In both local and remote cases, incoming traffic comes from the mesh gateways. -HCP Consul assigns port `8502` to HashiCorp-managed clusters, instead of the default `8503`. +HCP Consul Dedicated assigns port `8502` to clusters, instead of the default `8503`. When the [v2 catalog](/consul/docs/architecture/v2/catalog) is enabled, all API calls from external systems, such as the Consul CLI and Terraform provider, use this port. @@ -121,7 +121,7 @@ When the [v2 catalog](/consul/docs/architecture/v2/catalog) is enabled, all API The following table lists information about the Server RPC port defaults: -| Default port | Protocol | Default status | Hashicorp-managed server port | +| Default port | Protocol | Default status | HCP Consul Dedicated server port | | :----------- | :------- | :----------------- | :---------------------------- | | `8300` | TCP | Enabled by default | `8300` | @@ -135,7 +135,7 @@ When using WAN federation with mesh gateways, Consul servers must accept server The following table lists information about the LAN serf port defaults: -| Default port | Protocol | Default status | Hashicorp-managed server port | +| Default port | Protocol | Default status | HCP Consul Dedicated server port | | :----------- | :-----------| :----------------- | :---------------------------- | | `8301` | TCP and UDP | Enabled by default | `8301` | @@ -147,7 +147,7 @@ When running Enterprise deployments that use multiple admin partitions, all Cons The following table lists information about the WAN serf port defaults: -| Default port | Protocol | Default status | Hashicorp-managed server port | +| Default port | Protocol | Default status | HCP Consul Dedicated server port | | :----------- | :---------- | :----------------- | :---------------------------- | | `8302` | TCP and UDP | Enabled by default | `8302` | diff --git a/website/content/docs/integrate/partnerships.mdx b/website/content/docs/integrate/partnerships.mdx index 024ceeaefc..024a5b5413 100644 --- a/website/content/docs/integrate/partnerships.mdx +++ b/website/content/docs/integrate/partnerships.mdx @@ -17,7 +17,7 @@ The program is intended to be largely self-service with links to resources, code ## Categories of Consul Integrations -By leveraging Consul's RESTful HTTP API system, prospective partners are able to build extensible integrations at the data plane, platform, and the infrastructure layer to extend Consul's functionalities. These integrations can be performed both with the community edition of Consul, Consul Enterprise, and HCP Consul. +By leveraging Consul's RESTful HTTP API system, prospective partners are able to build extensible integrations at the data plane, platform, and the infrastructure layer to extend Consul's functionalities. These integrations can be performed both with the community edition of Consul, Consul Enterprise, and HCP Consul Dedicated. **The Consul ecosystem of integrations:** @@ -37,9 +37,9 @@ By leveraging Consul's RESTful HTTP API system, prospective partners are able to -> **Network Infrastructure Automation (NIA)***: These integrations leverage Consul's service catalog to seamlessly integrate with Consul-Terraform-Sync (CTS) to automate changes in network infrastructure via a publisher-subscriber method. Refer to the [NIA documentation](/consul/docs/integrate/nia-integration) for details. -**HCP Consul**: HCP Consul is secure by default and offers an out-of-the-box service mesh solution to streamline operations without the hassle of managing Consul servers. [Sign up for a free HCP Consul account](https://cloud.hashicorp.com/products/consul). +**HCP Consul Dedicated**: HCP Consul Dedicated is secure by default and offers an out-of-the-box service mesh solution to streamline operations without the hassle of managing Consul servers. [Sign up for a free HCP Consul Dedicated account](https://cloud.hashicorp.com/products/consul). -**Consul integration verification badges**: Partners will be issued the Consul Enterprise badge for integrations that work with [Consul Enterprise features](/consul/docs/enterprise) such as namespaces. Partners will be issued the HCP Consul badge for integrations validated to work with [HCP Consul](/hcp/docs/consul#features). Each badge would be displayed on HashiCorp's partner page as well as be available for posting on the partner's own website to provide better visibility and differentiation of the integration for joint customers. +**Consul integration verification badges**: Partners will be issued the Consul Enterprise badge for integrations that work with [Consul Enterprise features](/consul/docs/enterprise) such as namespaces. Partners will be issued the HCP Consul Dedicated badge for integrations validated to work with [HCP Consul Dedicated](/hcp/docs/consul#features). Each badge would be displayed on HashiCorp's partner page as well as be available for posting on the partner's own website to provide better visibility and differentiation of the integration for joint customers. @@ -49,12 +49,12 @@ By leveraging Consul's RESTful HTTP API system, prospective partners are able to -![HCP Consul](/img/HCPc_badge.png) +![HCP Consul Dedicated](/img/HCPc_badge.png) -Developing a valid integration with either Consul Enterprise or HCP Consul also qualifies the partner for the Premier tier of the HashiCorp Technology Partners program. The process for verification of these integrations is detailed below. +Developing a valid integration with either Consul Enterprise or HCP Consul Dedicated also qualifies the partner for the Premier tier of the HashiCorp Technology Partners program. The process for verification of these integrations is detailed below. ## Development Process @@ -87,7 +87,7 @@ Here are links to resources, documentation, examples and best practices to guide - [Consul Telemetry Documentation](/consul/docs/agent/telemetry) - [Monitoring Consul with Datadog APM](https://www.datadoghq.com/blog/consul-datadog/) -- [Monitor HCP Consul with New Relic Instant Observability](https://github.com/newrelic-experimental/hashicorp-quickstart-annex/blob/main/hcp-consul/README.md) +- [Monitor HCP Consul Dedicated with New Relic Instant Observability](https://github.com/newrelic-experimental/hashicorp-quickstart-annex/blob/main/hcp-consul/README.md) - [HCP Consul and CloudFabrix AIOps Integration](https://bot-docs.cloudfabrix.io/Bots/consul/?h=consul) - [Consul and SnappyFlow Full Stack Observability](https://docs.snappyflow.io/docs/Integrations/hcp_consul) @@ -167,17 +167,17 @@ Here are links to resources, documentation, examples and best practices to guide The only knowledge necessary to write a plugin is basic command-line skills and knowledge of the [Go programming language](http://www.golang.org). Use the plugin interface to develop your integration. All integrations should contain unit and acceptance testing. -**HCP Consul**: As a managed service, minimal configuration is required to deploy HCP Consul server clusters. You only need to install Consul client agents. Furthermore, HashiCorp provides all new users an initial credit, which provides approximately two months worth of [development cluster](https://cloud.hashicorp.com/products/consul/pricing) access. When deployed with AWS or Azure free tier services, there should be no cost beyond the time spent by the designated tester. Refer to the [Deploy HCP Consul tutorial](/consul/tutorials/get-started-hcp/hcp-gs-deploy) for details on getting started. +**HCP Consul Dedicated**: As a managed service, minimal configuration is required to deploy HCP Consul Dedicated server clusters. You only need to install Consul client agents. Furthermore, HashiCorp provides all new users an initial credit, which provides approximately two months worth of [development cluster](https://cloud.hashicorp.com/products/consul/pricing) access. When deployed with AWS or Azure free tier services, there should be no cost beyond the time spent by the designated tester. Refer to the [Deploy HCP Consul Dedicated tutorial](/consul/tutorials/get-started-hcp/hcp-gs-deploy) for details on getting started. -HCP Consul is currently only deployed on AWS and Microsoft Azure, so your application can be deployed to or run in AWS or Azure. +HCP Consul Dedicated is currently only deployed on AWS and Microsoft Azure, so your application can be deployed to or run in AWS or Azure. -#### HCP Consul Resource Links: +#### HCP Consul Dedicated Resource Links: -- [Getting Started with HCP Consul](/consul/tutorials/get-started-hcp/hcp-gs-deploy) -- [HCP Consul End-to-End Deployment](/consul/tutorials/cloud-deploy-automation/consul-end-to-end-overview) -- [Deploy HCP Consul with EKS using Terraform](/consul/tutorials/cloud-deploy-automation/consul-end-to-end-eks) -- [HCP Consul Deployment Automation](/consul/tutorials/cloud-deploy-automation) -- [HCP Consul documentation](/hcp/docs/consul/usage) +- [Getting Started with HCP Consul Dedicated](/consul/tutorials/get-started-hcp/hcp-gs-deploy) +- [HCP Consul Dedicated End-to-End Deployment](/consul/tutorials/cloud-deploy-automation/consul-end-to-end-overview) +- [Deploy HCP Consul Dedicated with EKS using Terraform](/consul/tutorials/cloud-deploy-automation/consul-end-to-end-eks) +- [HCP Consul Dedicated Deployment Automation](/consul/tutorials/cloud-deploy-automation) +- [HCP Consul Dedicated documentation](/hcp/docs/consul/usage) **Consul Enterprise**: An integration qualifies for Consul Enterprise when it is tested and compatible with Consul Enterprise Namespaces. diff --git a/website/content/docs/intro/index.mdx b/website/content/docs/intro/index.mdx index 42655814ce..9bf7989b44 100644 --- a/website/content/docs/intro/index.mdx +++ b/website/content/docs/intro/index.mdx @@ -77,7 +77,7 @@ Rolling out changes can be risky, especially in complex network environments. Up HashiCorp offers core Consul functionality for free in the community edition, which is ideal for smaller businesses and teams that want to pilot Consul within their organizations. As your business grows, you can upgrade to Consul Enterprise, which offers additional capabilities designed to address organizational complexities of collaboration, operations, scale, and governance. -### HCP Consul +### HCP Consul Dedicated HashiCorp Cloud Platform (HCP) Consul is our SaaS that delivers Consul Enterprise capabilities and shifts the burden of managing the control plane to us. Create an HCP organization and leverage our expertise to simplify control plane maintenance and configuration. Learn more at [HashiCorp Cloud Platform](https://cloud.hashicorp.com/products/consul). diff --git a/website/content/docs/k8s/helm.mdx b/website/content/docs/k8s/helm.mdx index a2525a8b38..1bdbd57630 100644 --- a/website/content/docs/k8s/helm.mdx +++ b/website/content/docs/k8s/helm.mdx @@ -693,7 +693,7 @@ Use these links to navigate to a particular top-level stanza. This can either be used to [configure a new cluster](/hcp/docs/consul/self-managed/new) or [link an existing one](/hcp/docs/consul/self-managed/existing). - Note: this setting should not be enabled for [HashiCorp-managed clusters](/hcp/docs/consul/hcp-managed). + Note: this setting should not be enabled for [HCP Consul Dedicated clusters](/hcp/docs/consul/dedicated). It is strictly for linking self-managed clusters. - `resourceId` ((#v-global-cloud-resourceid)) - The resource id of the HCP Consul Central cluster to link to. Eg: @@ -2841,8 +2841,8 @@ Use these links to navigate to a particular top-level stanza. - `resourceId` ((#v-telemetrycollector-cloud-resourceid)) - The resource id of the HCP Consul Central cluster to push metrics for. Eg: `organization/27109cd4-a309-4bf3-9986-e1d071914b18/project/fcef6c24-259d-4510-bb8d-1d812e120e34/hashicorp.consul.global-network-manager.cluster/consul-cluster` - This is used for HCP Consul Central-linked or managed clusters where global.cloud.resourceId is unset. For example, when using externalServers - with HCP Consul-managed clusters or HCP Consul Central-linked clusters in a different admin partition. + This is used for HCP Consul Central-linked or HCP Consul Dedicated clusters where global.cloud.resourceId is unset. For example, when using externalServers + with HCP Consul Dedicated clusters or HCP Consul Central-linked clusters in a different admin partition. If global.cloud.resourceId is set, this should either be unset (defaulting to global.cloud.resourceId) or be the same as global.cloud.resourceId. diff --git a/website/content/docs/k8s/multiport/index.mdx b/website/content/docs/k8s/multiport/index.mdx index bc03fcbb05..acef6abc7c 100644 --- a/website/content/docs/k8s/multiport/index.mdx +++ b/website/content/docs/k8s/multiport/index.mdx @@ -41,7 +41,8 @@ Be aware of the following constraints and technical limitations on using multi-p - When running the v2 catalog for multi-port services, you cannot run the v1 catalog API at the same time. - Because configuration entries are part of the v1 catalog, you cannot use them when the v2 catalog is enabled. Use v2 resources instead to configure multi-port service behavior in the service mesh. - The Consul UI does not support multi-port services in this release. You must disable the UI in the Helm chart in order to use multi-port services. -- HCP Consul does not support multi-port services in this release. You cannot [link a self-managed cluster to HCP Consul](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. +- HCP Consul Dedicated does not support multi-port services in this release. +- You cannot [link a self-managed Enterprise cluster to HCP Consul Central](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. - We do not recommend updating existing clusters to enable the v2 catalog in this release. To register multi-port services, deploy a new Consul cluster that enables the v2 catalog. ## Guidance diff --git a/website/content/docs/nia/compatibility.mdx b/website/content/docs/nia/compatibility.mdx index d74e740ece..7e473bc356 100644 --- a/website/content/docs/nia/compatibility.mdx +++ b/website/content/docs/nia/compatibility.mdx @@ -13,7 +13,7 @@ This topic describes Consul-Terraform-Sync (CTS) cross-compatibility with Consul Below are CTS versions with supported Consul versions. The latest CTS binary supports the three most recent Consul minor versions, along with their latest patch versions. -| CTS Version | Consul Community Edition & Enterprise Version | HCP Consul Version | +| CTS Version | Consul Community Edition & Enterprise Version | HCP Consul Dedicated Version | | :--------------------- | :------------------------------ | :----------------- | | CTS Enterprise 0.6+ | 1.8+ | 1.9+ | | CTS Enterprise 0.3-0.5 | 1.8+ | N/A | diff --git a/website/content/docs/nia/configuration.mdx b/website/content/docs/nia/configuration.mdx index b6ae92105f..ec07f3474d 100644 --- a/website/content/docs/nia/configuration.mdx +++ b/website/content/docs/nia/configuration.mdx @@ -86,7 +86,7 @@ license { You can use the `auto_retrieval` block to configure the automatic license retrieval in CTS. When enabled, CTS attempts to retrieve a new license from its configured Consul Enterprise backend once a day. If CTS cannot retrieve a license and the current license is reaching its expiration date, CTS attempts to retrieve a license with increased frequency, as defined by the [License Expiration Date Handling](/consul/docs/nia/enterprise/license#license-expiration-handling). -~> Enabling `auto_retrieval` is recommended when using HCP Consul, as HCP Consul licenses expire more frequently than Consul Enterprise licenses. Without auto-retrieval enabled, you have to restart CTS every time you load a new license. +~> Enabling `auto_retrieval` is recommended when using HCP Consul Dedicated, as HCP Consul Dedicated licenses expire more frequently than Consul Enterprise licenses. Without auto-retrieval enabled, you have to restart CTS every time you load a new license. | Parameter | Required | Type | Description | Default | | --------- | -------- | ---- | ----------- | ------- | diff --git a/website/content/docs/nia/enterprise/license.mdx b/website/content/docs/nia/enterprise/license.mdx index fd71d01047..338e681344 100644 --- a/website/content/docs/nia/enterprise/license.mdx +++ b/website/content/docs/nia/enterprise/license.mdx @@ -20,7 +20,7 @@ To get a trial license for CTS, you can sign-up for the [trial license for Consu ## Automatic License Retrieval CTS automatically retrieves a license from Consul on startup and then attempts to retrieve a new license once a day. If the current license is reaching its expiration date, CTS attempts to retrieve a license with increased frequency, as defined by the [License Expiration Date Handling](/consul/docs/nia/enterprise/license#license-expiration-handling). -~> Enabling automatic license retrieval is recommended when using HCP Consul, as HCP Consul licenses expire more frequently than Consul Enterprise licenses. Without auto-retrieval enabled, you have to restart CTS every time you load a new license. +~> Enabling automatic license retrieval is recommended when using HCP Consul Dedicated, as HCP Consul Dedicated licenses expire more frequently than Consul Enterprise licenses. Without auto-retrieval enabled, you have to restart CTS every time you load a new license. ## Setting the License Manually diff --git a/website/content/docs/release-notes/consul-api-gateway/v0_1_x.mdx b/website/content/docs/release-notes/consul-api-gateway/v0_1_x.mdx index efb65ec71a..6f20ae97af 100644 --- a/website/content/docs/release-notes/consul-api-gateway/v0_1_x.mdx +++ b/website/content/docs/release-notes/consul-api-gateway/v0_1_x.mdx @@ -36,7 +36,7 @@ This release includes the following features and capabilities: - Google GKE - Azure AKS. 1. Install via the HashiCorp Consul Helm chart. -1. Works with self-managed Consul servers and HCP Consul servers +1. Works with self-managed Consul Enterprise servers and HCP Consul Dedicated servers 1. Configure via Kubernetes Gateway API - v1alpha2 1. Deploy 1 or more logical API Gateways per Kubernetes cluster 1. Support for HTTP, HTTPS, TCP, and TCP+TLS diff --git a/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx index bacbcae9f4..30edc3e165 100644 --- a/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx +++ b/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx @@ -16,7 +16,7 @@ Catalog v2 supports multi-port application deployments with a single Envoy proxy The v1 and v2 catalogs are not cross compatible, and not all Consul features are available within this v2 feature preview. - The Consul UI must be disabled. It 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. + - HCP Consul Dedicated 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. The v2 Catalog and Resources API is currently in feature preview for Consul on Kubernetes 1.3.0 and should not be used in production environments. diff --git a/website/content/docs/release-notes/consul-terraform-sync/v0_6_x.mdx b/website/content/docs/release-notes/consul-terraform-sync/v0_6_x.mdx index b5ddfaea08..9f71f17d67 100644 --- a/website/content/docs/release-notes/consul-terraform-sync/v0_6_x.mdx +++ b/website/content/docs/release-notes/consul-terraform-sync/v0_6_x.mdx @@ -16,9 +16,9 @@ We have implemented the following features in this release: You can now execute Terraform tasks in `remote` or `cloud agent` mode. For more information, refer to the [per-task execution mode documentation](/consul/docs/nia/network-drivers/terraform-cloud#remote-workspaces). -### HCP Consul Support +### HCP Consul Dedicated Support -CTS now supports interoperability with HCP Consul. CTS retrieves licenses from HCP Consul so that users can keep their HCP Consul license or Consul enterprise deployment license in sync. +CTS now supports interoperability with HCP Consul Dedicated. CTS retrieves licenses from HCP Consul Dedicated so that users can keep their HCP Consul Dedicated license or Consul enterprise deployment license in sync. ### Auto Service-registration with Consul and Health API Endpoint @@ -36,7 +36,7 @@ CTS includes a new [API endpoint](/consul/docs/nia/api/health#health) that provi ## Supported Software Versions - Consul: v1.9+ -- HCP Consul: Latest +- HCP Consul Dedicated: Latest - Terraform CLI: v0.13 - v1.1 - HCP Terraform: Latest - Terraform Enterprise: v202010-2 - Latest diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 7a9b3f6392..b7eb58cadb 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -49,7 +49,7 @@ "path": "install" }, { - "title": "Learn HCP Consul", + "title": "Learn HCP Consul Dedicated", "href": "https://developer.hashicorp.com/consul/tutorials/get-started-hcp" }, { @@ -1852,7 +1852,7 @@ "divider": true }, { - "title": "HCP Consul", + "title": "HCP Consul Dedicated", "href": "https://cloud.hashicorp.com/docs/consul" }, { From 3a6f2fba185a53be9a8591065a0e55a2ff038e0c Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Thu, 2 May 2024 13:36:02 -0400 Subject: [PATCH 003/185] security: bump envoy version and k8s.io/apimachinery (#21017) * security: bump envoy version * add changelog --- .changelog/21017.txt | 9 ++ .../nightly-test-integrations-1.15.x.yml | 4 +- .../nightly-test-integrations-1.17.x.yml | 4 +- .../workflows/nightly-test-integrations.yml | 4 +- .../workflows/test-integrations-windows.yml | 2 +- .github/workflows/test-integrations.yml | 4 +- .../xdscommon/envoy_versioning_test.go | 4 +- envoyextensions/xdscommon/proxysupport.go | 4 +- go.mod | 2 +- go.sum | 101 +----------------- .../content/docs/connect/proxies/envoy.mdx | 8 +- 11 files changed, 29 insertions(+), 117 deletions(-) create mode 100644 .changelog/21017.txt diff --git a/.changelog/21017.txt b/.changelog/21017.txt new file mode 100644 index 0000000000..0091047f7f --- /dev/null +++ b/.changelog/21017.txt @@ -0,0 +1,9 @@ +```release-note:security +Upgrade to support Envoy `1.27.5 and 1.28.3`. This resolves CVE +[CVE-2024-32475](https://nvd.nist.gov/vuln/detail/CVE-2024-32475) (`auto_sni`). +``` + +```release-note:security +Upgrade to support k8s.io/apimachinery `v0.18.7 or higher`. This resolves CVE +[CVE-2020-8559](https://nvd.nist.gov/vuln/detail/CVE-2020-8559). +``` diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index 8c9c9eabdd..5fbda17814 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -74,7 +74,7 @@ jobs: # this is further going to multiplied in envoy-integration tests by the # other dimensions in the matrix. Currently TOTAL_RUNNERS would be # 14 based on these values: - # envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.4", "1.28.2"] + # envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.5", "1.28.3"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 7 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -109,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.4", "1.28.2"] + envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.5", "1.28.3"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index c936d887d6..46940e1215 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -74,7 +74,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.8", "1.27.4"] + # envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -109,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.4"] + envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index 160388e9d2..b15b7f239d 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -71,7 +71,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.25.11", "1.26.8", "1.27.4", "1.28.2"] + # envoy-version: ["1.25.11", "1.26.8", "1.27.5", "1.28.3"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 8 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -106,7 +106,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.25.11", "1.26.8", "1.27.4", "1.28.2"] + envoy-version: ["1.25.11", "1.26.8", "1.27.5", "1.28.3"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/test-integrations-windows.yml b/.github/workflows/test-integrations-windows.yml index 3dbb55400c..e19e2333fd 100644 --- a/.github/workflows/test-integrations-windows.yml +++ b/.github/workflows/test-integrations-windows.yml @@ -62,7 +62,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: [ "1.28.2" ] + envoy-version: [ "1.28.3" ] xds-target: [ "server", "client" ] env: ENVOY_VERSION: ${{ matrix.envoy-version }} diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 019b3ece71..5c653dd31e 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -270,7 +270,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 2 based on these values: - # envoy-version: ["1.28.2"] + # envoy-version: ["1.28.3"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 2 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -305,7 +305,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.28.2"] + envoy-version: ["1.28.3"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go index e5fb171b3b..e51918a255 100644 --- a/envoyextensions/xdscommon/envoy_versioning_test.go +++ b/envoyextensions/xdscommon/envoy_versioning_test.go @@ -153,8 +153,8 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { for _, v := range []string{ "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.26.7", "1.26.8", - "1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", - "1.28.0", "1.28.1", "1.28.2", + "1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", "1.27.5", + "1.28.0", "1.28.1", "1.28.2", "1.28.3", } { cases[v] = testcase{expect: SupportedProxyFeatures{}} } diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go index 7efad44502..ded724b0a1 100644 --- a/envoyextensions/xdscommon/proxysupport.go +++ b/envoyextensions/xdscommon/proxysupport.go @@ -12,8 +12,8 @@ import "strings" // // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions var EnvoyVersions = []string{ - "1.28.2", - "1.27.4", + "1.28.3", + "1.27.5", "1.26.8", "1.25.11", } diff --git a/go.mod b/go.mod index c8ca0eeb9b..f2647de9f5 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/hashicorp/go-checkpoint v0.5.0 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-connlimit v0.3.0 - github.com/hashicorp/go-discover v0.0.0-20220714221025-1c234a67149a + github.com/hashicorp/go-discover v0.0.0-20230724184603-e89ebd1b2f65 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-immutable-radix v1.3.1 github.com/hashicorp/go-immutable-radix/v2 v2.1.0 diff --git a/go.sum b/go.sum index b191f0b262..15efa58f9b 100644 --- a/go.sum +++ b/go.sum @@ -49,34 +49,21 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl 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= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-sdk-for-go v44.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM= github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.0/go.mod h1:QRTvSZQpxqm8mSErhnbI+tANIBAKP7B+UIE2z4ypUO0= github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 h1:0W/yGmFdTIT77fvdlGZ0LMISoLHFJ7Tx4U0yeB+uFs4= github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= @@ -84,11 +71,8 @@ github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+X github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.0 h1:3I9AAI63HfcLtphd9g39ruUwRI+Ca+z/f36KHPFRUss= github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -107,12 +91,9 @@ github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmy github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= 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/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1 h1:iLrQrdwjDd52kHDA5op2UBJFjmOb9g+7scBan4RN8F0= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= @@ -139,7 +120,6 @@ 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-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 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= @@ -209,22 +189,16 @@ github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72 github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/digitalocean/godo v1.10.0 h1:uW1/FcvZE/hoixnJcnlmIUvTVNdZCLjRLzmDtRi1xXY= github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= 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/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= 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= @@ -242,7 +216,6 @@ github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfb github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/evanphx/json-patch v4.2.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= @@ -251,7 +224,6 @@ 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/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= @@ -260,7 +232,6 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6TZQas= github.com/fullstorydev/grpchan v1.1.1/go.mod h1:f4HpiV8V6htfY/K44GWV1ESQzHBTq7DinhzqQ95lpgc= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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= @@ -273,7 +244,6 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 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 v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= 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.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= @@ -286,22 +256,18 @@ github.com/go-openapi/analysis v0.21.5 h1:3tHfEBh6Ia8eKc4M7khOGjPOAlWKJ10d877Cr9 github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M= github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY= github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho= -github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.20.1 h1:MkK4VEIEZMj4wT9PmjaUmGflVBr9nvud4Q4UVFbDoBE= github.com/go-openapi/jsonpointer v0.20.1/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.20.3 h1:EjGcjTW8pD1mRis6+w/gmoBdqv5+RbE9B85D1NgDOVQ= github.com/go-openapi/jsonreference v0.20.3/go.mod h1:FviDZ46i9ivh810gqzFLl5NttD5q3tSlMLqLr6okedM= github.com/go-openapi/loads v0.21.3 h1:8sSH2FIm/SnbDUGv572md4YqVMFne/a9Eubvcd3anew= github.com/go-openapi/loads v0.21.3/go.mod h1:Y3aMR24iHbKHppOj91nQ/SHc0cuPbAr4ndY4a02xydc= github.com/go-openapi/runtime v0.26.2 h1:elWyB9MacRzvIVgAZCBJmqTi7hBzU0hlKD4IvfX0Zl0= github.com/go-openapi/runtime v0.26.2/go.mod h1:O034jyRZ557uJKzngbMDJXkcKJVzXJiymdSfgejrcRw= -github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.20.12 h1:cgSLbrsmziAP2iais+Vz7kSazwZ8rsUZd6TUzdDgkVI= github.com/go-openapi/spec v0.20.12/go.mod h1:iSCgnBcwbMW9SfzJb8iYynXvcY6C/QFrI7otzF7xGM4= github.com/go-openapi/strfmt v0.21.10 h1:JIsly3KXZB/Qf4UzvzJpg4OELH/0ASDQsyk//TTBDDk= github.com/go-openapi/strfmt v0.21.10/go.mod h1:vNDMwbilnl7xKiO/Ve/8H8Bb2JIInBnH+lqiw6QWgis= -github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.22.5 h1:fVS63IE3M0lsuWRzuom3RLwUMVI2peDH01s6M70ugys= github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-openapi/validate v0.22.4 h1:5v3jmMyIPKTR8Lv9syBAIRxG6lY0RqeBPB1LKEijzk8= @@ -315,7 +281,6 @@ github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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= @@ -325,7 +290,6 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -341,7 +305,6 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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 v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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= @@ -385,11 +348,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.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= @@ -427,14 +388,9 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m 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/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.3.0 h1:6sjpKIpVwRIIwmcEGp+WwNovNsem+c+2vm6oxshRpL8= github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 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= @@ -462,8 +418,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n 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-discover v0.0.0-20220714221025-1c234a67149a h1:xeDSq/xo0CfnSZnPUkNH/00Qy8Q8ySJW0Ij2u/pH680= -github.com/hashicorp/go-discover v0.0.0-20220714221025-1c234a67149a/go.mod h1:1xfdKvc3pe5WKxfUUHHOGaKMk7NLGhHY1jkyhKo6098= +github.com/hashicorp/go-discover v0.0.0-20230724184603-e89ebd1b2f65 h1:+ZwaKkFuVWS7FZoiltT+7XW/MEFckY9Wxe+xIEErLcM= +github.com/hashicorp/go-discover v0.0.0-20230724184603-e89ebd1b2f65/go.mod h1:RH2Jr1/cCsZ1nRLmAOC65hp/gRehf55SsUIYV2+NAxI= 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= @@ -544,7 +500,6 @@ github.com/hashicorp/hcp-sdk-go v0.80.0/go.mod h1:vQ4fzdL1AmhIAbCw+4zmFe5Hbpajj3 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.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= @@ -582,13 +537,11 @@ github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35n 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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 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.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= @@ -597,7 +550,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk= -github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= @@ -614,12 +566,10 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= 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.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -627,7 +577,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -644,14 +593,12 @@ 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/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -677,7 +624,6 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh 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.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= @@ -724,11 +670,9 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 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/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= @@ -742,13 +686,7 @@ github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNs github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= 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= @@ -762,7 +700,6 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR 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.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 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= @@ -840,7 +777,6 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= 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/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= @@ -853,14 +789,12 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -962,7 +896,6 @@ 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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -971,11 +904,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/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-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/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-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1027,13 +958,10 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-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= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1050,7 +978,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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-20191004110552-13f9640d40b9/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= @@ -1116,12 +1043,9 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.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-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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1143,7 +1067,6 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w 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-20191022100944-742c48ecaeb7/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= @@ -1209,7 +1132,6 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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= @@ -1233,8 +1155,6 @@ 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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-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= @@ -1451,15 +1371,12 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= 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= @@ -1471,7 +1388,6 @@ gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1497,25 +1413,16 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= 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.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= 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.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= 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/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= 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-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -1523,11 +1430,7 @@ 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-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= -sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= 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.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/website/content/docs/connect/proxies/envoy.mdx b/website/content/docs/connect/proxies/envoy.mdx index 479485af9c..ccf2d16cc4 100644 --- a/website/content/docs/connect/proxies/envoy.mdx +++ b/website/content/docs/connect/proxies/envoy.mdx @@ -58,8 +58,8 @@ apply to both Consul Enterprise and Consul community edition (CE). | Consul Version | Compatible Envoy Versions | | -------------- | -------------------------------------- | -| 1.18.x CE | 1.28.2, 1.27.4, 1.26.8, 1.25.11 | -| 1.17.x | 1.27.4, 1.26.8, 1.25.11, 1.24.12 | +| 1.18.x CE | 1.28.3, 1.27.5, 1.26.8, 1.25.11 | +| 1.17.x | 1.27.5, 1.26.8, 1.25.11, 1.24.12 | | 1.16.x | 1.26.8, 1.25.11, 1.24.12, 1.23.12 | #### Enterprise Long Term Support releases @@ -71,8 +71,8 @@ until the LTS release reaches its end of maintenance. | Consul Version | Compatible Envoy Versions | | -------------- | -----------------------------------------------------------------------------------| -| 1.18.x Ent | 1.28.2, 1.27.4, 1.26.8, 1.25.11 | -| 1.15.x Ent | 1.28.2, 1.27.4, 1.26.8, 1.25.11, 1.24.12, 1.23.12, 1.22.11 | +| 1.18.x Ent | 1.28.3, 1.27.5, 1.26.8, 1.25.11 | +| 1.15.x Ent | 1.28.3, 1.27.5, 1.26.8, 1.25.11, 1.24.12, 1.23.12, 1.22.11 | ### Envoy and Consul Dataplane From 37e3ebe5644e425ed620062e35088a404835446e Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Thu, 2 May 2024 15:18:17 -0400 Subject: [PATCH 004/185] chore: remove workstream from JIRA sync (#21031) --- .github/workflows/jira-issues.yaml | 3 +-- .github/workflows/jira-pr.yaml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/jira-issues.yaml b/.github/workflows/jira-issues.yaml index c136dfd69a..41e6992840 100644 --- a/.github/workflows/jira-issues.yaml +++ b/.github/workflows/jira-issues.yaml @@ -48,8 +48,7 @@ jobs: description: "${{ github.event.issue.body || github.event.pull_request.body }}\n\n_Created in GitHub by ${{ github.actor }}._" # customfield_10089 is "Issue Link", customfield_10371 is "Source" (use JIRA API to retrieve) extraFields: '{ "customfield_10089": "${{ github.event.issue.html_url || github.event.pull_request.html_url }}", - "customfield_10371": { "value": "GitHub" }, - "customfield_10535": [{ "value": "Service Mesh" }], + "customfield_10371": { "value": "GitHub" }], "components": [{ "name": "${{ github.event.repository.name }}" }], "labels": ${{ steps.set-ticket-labels.outputs.LABELS }} }' env: diff --git a/.github/workflows/jira-pr.yaml b/.github/workflows/jira-pr.yaml index a40bb0ae0f..e1eb8805f4 100644 --- a/.github/workflows/jira-pr.yaml +++ b/.github/workflows/jira-pr.yaml @@ -67,8 +67,7 @@ jobs: description: "${{ github.event.issue.body || github.event.pull_request.body }}\n\n_Created in GitHub by ${{ github.actor }}._" # customfield_10089 is "Issue Link", customfield_10371 is "Source" (use JIRA API to retrieve) extraFields: '{ "customfield_10089": "${{ github.event.pull_request.html_url }}", - "customfield_10371": { "value": "GitHub" }, - "customfield_10535": [{ "value": "Service Mesh" }], + "customfield_10371": { "value": "GitHub" }], "components": [{ "name": "${{ github.event.repository.name }}" }], "labels": ${{ steps.set-ticket-labels.outputs.LABELS }} }' env: From 126784ee9a5394e0544d7bce940416b3902d2617 Mon Sep 17 00:00:00 2001 From: natemollica-dev <57850649+natemollica-nm@users.noreply.github.com> Date: Thu, 2 May 2024 14:43:51 -0700 Subject: [PATCH 005/185] Update snapshot CLI command addition of Decode subcommand from PR#20824 (#21005) docs: update snapshot for subcommand decode add by PR#20824 --- website/content/commands/snapshot/decode.mdx | 52 ++++++++++++++++++++ website/data/commands-nav-data.json | 4 ++ 2 files changed, 56 insertions(+) create mode 100644 website/content/commands/snapshot/decode.mdx diff --git a/website/content/commands/snapshot/decode.mdx b/website/content/commands/snapshot/decode.mdx new file mode 100644 index 0000000000..72e908da82 --- /dev/null +++ b/website/content/commands/snapshot/decode.mdx @@ -0,0 +1,52 @@ +--- +layout: commands +page_title: 'Commands: Snapshot Decode' +description: | + The `consul snapshot decode` command outputs a stream of line delimited JSON objects for an atomic, point-in-time snapshot of the state of the Consul servers. Output includes key/value entries, registered services in the catalog, prepared queries, sessions, and ACLs. +--- + +# Consul Snapshot Decode + +Command: `consul snapshot decode` + +The `snapshot decode` command is used to decode an atomic, point-in-time +snapshot of the state of the Consul servers which includes key/value entries, +service catalog, prepared queries, sessions, and ACLs. The snapshot is read +from the given file and decode to `stdout` as JSON data for interpretation and +review. + +-> Typically this is used with Consul self-contained Snapshot files obtained +using the [`consul snapshot`](/consul/commands/snapshot) command or [Snapshot +API](/consul/api-docs/snapshot#generate-snapshot). + +The JSON stream information format: + +```json + {"Type": "SnapshotHeader", "Data": {""}} + {"Type": "","Data": {}} + {"Type": "","Data": {}} + ... +``` + +## Usage + +Usage: `consul snapshot decode FILE` + +## Examples + +To decode a snapshot from the file "backup.snap": + +```shell-session +$ consul snapshot decode backup.snap +{"Data":{"Version":1,"ID":"2-134-1713801971207","Index":134,"Term":2,"Peers":"ka4xMjcuMC4wLjE6ODMwMA==","Configuration":{"Servers":[{"Suffrage":0,"ID":"673f5fe3-0c2a-bef5-7719-c9ddbbc7a1c5","Address":"127.0.0.1:8300"}]},"ConfigurationIndex":1,"Size":20448157},"Type":"SnapshotHeader"} +{"Data":{"Name":"consul-support-namespace-1","Description":"Test namespace consul-support-namespace-1","CreateIndex":102,"ModifyIndex":102},"Type":"Namespace"} +{"Data":{"Name":"consul-support-namespace-10","Description":"Test namespace consul-support-namespace-10","CreateIndex":120,"ModifyIndex":120},"Type":"Namespace"} +{"Data":{"Name":"default","Description":"Builtin Default Partition","CreateIndex":4,"ModifyIndex":4},"Type":"Partition"} +{"Data":{"IP":"0.0.0.3","IsCounter":true},"Type":"FreeVirtualIP"} +{"Data":{"Datacenter":"dc2","ID":"df779ee7-c5ef-46d1-30cf-e46f0166cdf4","Node":"consul-server-dc2","Address":"127.0.0.2","TaggedAddresses":{"lan":"127.0.0.2","lan_ipv4":"127.0.0.2","wan":"127.0.0.2","wan_ipv4":"127.0.0.2"},"NodeMeta":{"consul-network-segment":"","consul-version":"1.18.0"},"Service":null,"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"dc2-peer","Partition":"default","Token":"","CreateIndex":40,"ModifyIndex":40},"Type":"Register"} +... +``` + + +Please see the [HTTP API](/consul/api-docs/snapshot) documentation for +more details about snapshot internals. diff --git a/website/data/commands-nav-data.json b/website/data/commands-nav-data.json index 967a8e9177..8e35ee0beb 100644 --- a/website/data/commands-nav-data.json +++ b/website/data/commands-nav-data.json @@ -543,6 +543,10 @@ "title": "agent", "path": "snapshot/agent" }, + { + "title": "decode", + "path": "snapshot/decode" + }, { "title": "inspect", "path": "snapshot/inspect" From 1793b506d50d1fb0422d4d6b47fba4a42716986d Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 3 May 2024 14:07:12 -0400 Subject: [PATCH 006/185] chore: fix JIRA workflow (#21037) fix JIRA workflow --- .github/workflows/jira-issues.yaml | 2 +- .github/workflows/jira-pr.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/jira-issues.yaml b/.github/workflows/jira-issues.yaml index 41e6992840..d2cd04748c 100644 --- a/.github/workflows/jira-issues.yaml +++ b/.github/workflows/jira-issues.yaml @@ -48,7 +48,7 @@ jobs: description: "${{ github.event.issue.body || github.event.pull_request.body }}\n\n_Created in GitHub by ${{ github.actor }}._" # customfield_10089 is "Issue Link", customfield_10371 is "Source" (use JIRA API to retrieve) extraFields: '{ "customfield_10089": "${{ github.event.issue.html_url || github.event.pull_request.html_url }}", - "customfield_10371": { "value": "GitHub" }], + "customfield_10371": { "value": "GitHub" }, "components": [{ "name": "${{ github.event.repository.name }}" }], "labels": ${{ steps.set-ticket-labels.outputs.LABELS }} }' env: diff --git a/.github/workflows/jira-pr.yaml b/.github/workflows/jira-pr.yaml index e1eb8805f4..b245abebcb 100644 --- a/.github/workflows/jira-pr.yaml +++ b/.github/workflows/jira-pr.yaml @@ -67,7 +67,7 @@ jobs: description: "${{ github.event.issue.body || github.event.pull_request.body }}\n\n_Created in GitHub by ${{ github.actor }}._" # customfield_10089 is "Issue Link", customfield_10371 is "Source" (use JIRA API to retrieve) extraFields: '{ "customfield_10089": "${{ github.event.pull_request.html_url }}", - "customfield_10371": { "value": "GitHub" }], + "customfield_10371": { "value": "GitHub" }, "components": [{ "name": "${{ github.event.repository.name }}" }], "labels": ${{ steps.set-ticket-labels.outputs.LABELS }} }' env: From 8209b3ff86fd298c8f4fed5e4cf922c7b76b9e27 Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Fri, 3 May 2024 15:09:40 -0400 Subject: [PATCH 007/185] security: fine-tune release scanner and bump coredns (#21038) * security: bump coredns * add changelog * Revert "security: bump coredns" This reverts commit dcca09d83e89b6d5a4f03106e86d72a2b791001d. * security: bump coredns * fine-tune security scanner on release * dismiss changelog --- .release/security-scan.hcl | 14 + .../connect/envoy/test-sds-server/go.mod | 6 +- .../connect/envoy/test-sds-server/go.sum | 527 +++++++++--------- 3 files changed, 289 insertions(+), 258 deletions(-) diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 83c503563b..c49ffd32fd 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -42,6 +42,13 @@ container { "CVE-2023-46219", # curl@8.4.0-r0 "CVE-2023-5678", # openssl@3.1.4-r0 ] + paths = [ + "internal/tools/proto-gen-rpc-glue/e2e/consul/*", + "test/integration/connect/envoy/test-sds-server/*", + "test/integration/consul-container/*", + "testing/deployer/*", + "test-integ/*", + ] } } } @@ -76,6 +83,13 @@ binary { vulnerabilites = [ "GO-2024-2631", # go-jose/v3@v3.0.3 (false positive) ] + paths = [ + "internal/tools/proto-gen-rpc-glue/e2e/consul/*", + "test/integration/connect/envoy/test-sds-server/*", + "test/integration/consul-container/*", + "testing/deployer/*", + "test-integ/*", + ] } } } diff --git a/test/integration/connect/envoy/test-sds-server/go.mod b/test/integration/connect/envoy/test-sds-server/go.mod index bbc4e38df8..37c97e77c9 100644 --- a/test/integration/connect/envoy/test-sds-server/go.mod +++ b/test/integration/connect/envoy/test-sds-server/go.mod @@ -4,11 +4,9 @@ go 1.16 require ( github.com/envoyproxy/go-control-plane v0.12.0 - github.com/fatih/color v1.14.1 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/hashicorp/consul v1.15.2 + github.com/hashicorp/consul v1.18.1 + github.com/hashicorp/consul/sdk v0.16.0 // indirect github.com/hashicorp/go-hclog v1.5.0 - github.com/hashicorp/go-uuid v1.0.3 // indirect golang.org/x/net v0.24.0 // indirect google.golang.org/grpc v1.58.3 ) diff --git a/test/integration/connect/envoy/test-sds-server/go.sum b/test/integration/connect/envoy/test-sds-server/go.sum index 8ba219ea04..b91d94b1ba 100644 --- a/test/integration/connect/envoy/test-sds-server/go.sum +++ b/test/integration/connect/envoy/test-sds-server/go.sum @@ -1,7 +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.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -717,121 +716,109 @@ cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vf cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= -contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v32.6.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v44.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= -github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.2/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= -github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM= -github.com/Azure/go-autorest/autorest/azure/auth v0.4.1/go.mod h1:5TgH20II424SXIV9YDBsO4rBCKsh39Vbx9DvhJZZ8rU= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/azure/auth v0.5.0/go.mod h1:QRTvSZQpxqm8mSErhnbI+tANIBAKP7B+UIE2z4ypUO0= -github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U= -github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 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/zstd v1.3.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/datadog-go v4.8.2+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI= +github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/sarama v1.21.0/go.mod h1:yuqtN/pe8cXRWG5zPaO7hCfNJp5MwmkoJEoLjkm5tCQ= github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= -github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0/go.mod h1:zpDJeKyp9ScW4NNrbdr+Eyxvry3ilGPewKoXw3XGN1k= -github.com/alangpierce/go-forceexport v0.0.0-20160317203124-8f1d6941cd75/go.mod h1:uAXEEpARkRhCZfEvy/y0Jcc888f9tHCc1W7/UeEtreE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= -github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.146/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +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/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.42.34/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= -github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= +github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM= github.com/benmathews/bench v0.0.0-20210120214102-f7c75b9ef6e7/go.mod h1:peX7BEhSFSvvnxdido50pUMhlFi24dVgtTU1oZkHTUU= github.com/benmathews/hdrhistogram-writer v0.0.0-20180430173243-73b8d31ba571/go.mod h1:W24iTD3jetRjSLj2yz0IBNF6wKdbRUvBMG5oaw4ZbzM= @@ -845,26 +832,21 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/caddyserver/caddy v1.0.4/go.mod h1:uruyfVsyMcDb3IOzSKsi1x0wOjy1my/PxOSTcD+24jM= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= -github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/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.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYutcJ5PCekLxXn56w6SY= 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= @@ -882,58 +864,51 @@ github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWH 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/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/coredns/coredns v1.6.6/go.mod h1:Bdcnka9HmKGYj12ZIDF3lpQSfDHSsMc85Wj9xEyZUts= -github.com/coredns/federation v0.0.0-20190818181423-e032b096babe/go.mod h1:MoqTEFX8GlnKkyq8eBCF94VzkNAOgjdlCJ+Pz/oCLPk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190212144455-93d5ec2c7f76/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok= +github.com/cosiner/argv v0.1.0/go.mod h1:EusR6TucWKX+zFgtdUsKT2Cvg45K5rtpCcWz4hK06d8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 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= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decker502/dnspod-go v0.2.0/go.mod h1:qsurYu1FgxcDwfSwXJdLt4kRsBLZeosEb9uq4Sy+08g= +github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= -github.com/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg= -github.com/dnstap/golang-dnstap v0.0.0-20170829151710-2cf77a2b5e11/go.mod h1:s1PfVYYVmTMgCSPtho4LKBDecEHJWtiVDPNv78Z985U= -github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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= @@ -949,6 +924,7 @@ github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go. github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/go-control-plane v0.12.0 h1:4X+VP1GHd1Mhj6IB5mMeGbLCleqxjletLK6K0rbxyZI= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= +github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e/go.mod h1:/NGEcKqwNq3HAS2vCqHfsPx9sJZbkiNQ6dGx9gTE/NA= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= @@ -957,19 +933,15 @@ github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6Ni github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= -github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +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/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= -github.com/farsightsec/golang-framestream v0.0.0-20181102145529-8a0cb8ba8710/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI= 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/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -977,18 +949,17 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fullstorydev/grpchan v1.1.1/go.mod h1:f4HpiV8V6htfY/K44GWV1ESQzHBTq7DinhzqQ95lpgc= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-acme/lego/v3 v3.1.0/go.mod h1:074uqt+JS6plx+c9Xaiz6+L+GBb+7itGtzfcDM2AhEE= -github.com/go-acme/lego/v3 v3.2.0/go.mod h1:074uqt+JS6plx+c9Xaiz6+L+GBb+7itGtzfcDM2AhEE= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= @@ -997,11 +968,13 @@ github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmn 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-ini/ini v1.44.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= @@ -1010,6 +983,13 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +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.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -1020,7 +1000,8 @@ github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2 github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= +github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= @@ -1031,19 +1012,27 @@ github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.1/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/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonpointer v0.20.1/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/jsonreference v0.20.3/go.mod h1:FviDZ46i9ivh810gqzFLl5NttD5q3tSlMLqLr6okedM= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -1054,14 +1043,15 @@ github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hs github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/loads v0.21.3/go.mod h1:Y3aMR24iHbKHppOj91nQ/SHc0cuPbAr4ndY4a02xydc= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= -github.com/go-openapi/runtime v0.24.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= +github.com/go-openapi/runtime v0.26.2/go.mod h1:O034jyRZ557uJKzngbMDJXkcKJVzXJiymdSfgejrcRw= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= @@ -1073,7 +1063,10 @@ github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFu github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= -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.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.11/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.12/go.mod h1:iSCgnBcwbMW9SfzJb8iYynXvcY6C/QFrI7otzF7xGM4= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= @@ -1083,10 +1076,10 @@ github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= +github.com/go-openapi/strfmt v0.21.8/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= +github.com/go-openapi/strfmt v0.21.10/go.mod h1:vNDMwbilnl7xKiO/Ve/8H8Bb2JIInBnH+lqiw6QWgis= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= @@ -1099,6 +1092,9 @@ github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/ github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= @@ -1107,14 +1103,16 @@ github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0 github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZIVCbJBpTUoY0= -github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-openapi/validate v0.22.3/go.mod h1:kVxh31KbfsxU8ZyoHaDbLBWU5CnMdqBUEtadQ2G4d5M= +github.com/go-openapi/validate v0.22.4/go.mod h1:qm6O8ZIcPVdSY5219468Jv7kBdGvkiZLPOmqnqTUZ2A= github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= 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-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= 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= @@ -1142,14 +1140,14 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gocql/gocql v0.0.0-20200228163523-cd4b606dd2fb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -1170,8 +1168,8 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71 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 v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= 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= @@ -1192,14 +1190,14 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +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= @@ -1218,7 +1216,6 @@ 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/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -1239,6 +1236,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/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= @@ -1251,6 +1249,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -1275,40 +1274,33 @@ github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.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/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/gulducat/go-run-programs v0.1.0/go.mod h1:6BIzJV6kUmQC9oWm1umtjUN6x2+9xNe22suw1M9aq+A= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/consul v1.15.2 h1:asG6/ZyA1Z5dw0SuhZ5sh/SG9605NI/L/PNJtCnl93M= -github.com/hashicorp/consul v1.15.2/go.mod h1:1pu3llMOz2pwT+KU3Hxqycm//67l9znFCxyhe2ufRHo= +github.com/hashi-derek/grpc-proxy v0.0.0-20231207191910-191266484d75/go.mod h1:5eEnHfK72jOkp4gC1dI/Q/E9MFNOM/ewE/vql5ijV3g= +github.com/hashicorp/consul v1.18.1 h1:SxdPLBVWI5NeGt07xixHO9/OU1Vfj6DFqaidgdVVn9c= +github.com/hashicorp/consul v1.18.1/go.mod h1:kyyrJcHYNqCbHsg97v91OJJ085ANzTsOPvREnHiVZEk= 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/go.mod h1:svUZZDvotY8zTODknUePc6mZ9pX8nN0ViGwWcUSOBEA= -github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo= -github.com/hashicorp/consul/envoyextensions v0.1.2/go.mod h1:N94DQQkgITiA40zuTQ/UdPOLAAWobgHfVT5u7wxE/aU= -github.com/hashicorp/consul/proto-public v0.2.1/go.mod h1:iWNlBDJIZQJC3bBiCThoqg9i7uk/4RQZYkqH1wiQrss= -github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= -github.com/hashicorp/consul/sdk v0.13.1/go.mod h1:SW/mM4LbKfqmMvcFu8v+eiQQ7oitXEFeiBe9StxERb0= -github.com/hashicorp/consul/troubleshoot v0.1.2/go.mod h1:q35QOtN7K5kFLPm2SXHBDD+PzsuBekcqTZuuoOTzbWA= +github.com/hashicorp/consul/api v1.26.1/go.mod h1:B4sQTeaSO16NtynqrAdwOlahJ7IUDZM9cj2420xYL8A= +github.com/hashicorp/consul/envoyextensions v0.5.1/go.mod h1:M/VMPmhwjksu66pxQ6RBKkQEI7Qn6RM8hSnIoJUgskI= +github.com/hashicorp/consul/proto-public v0.5.1/go.mod h1:SayEhfXS3DQDnW/vKSZXvkwDObg7XK60KTfrJcp0wrg= +github.com/hashicorp/consul/sdk v0.15.0/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo= +github.com/hashicorp/consul/sdk v0.16.0 h1:SE9m0W6DEfgIVCJX7xU+iv/hUl4m/nxqMTnCdMxDpJ8= +github.com/hashicorp/consul/sdk v0.16.0/go.mod h1:7pxqqhqoaPqnBnzXD1StKed62LqJeClzVsUEy85Zr0A= +github.com/hashicorp/consul/troubleshoot v0.4.1/go.mod h1:2Ca1f4r4HZkO8NwtGBJ/9YX6EUgwWrZtvUnxB3UZuAA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= @@ -1321,15 +1313,17 @@ github.com/hashicorp/go-connlimit v0.3.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VV github.com/hashicorp/go-discover v0.0.0-20220714221025-1c234a67149a/go.mod h1:1xfdKvc3pe5WKxfUUHHOGaKMk7NLGhHY1jkyhKo6098= 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.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= 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/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= @@ -1355,6 +1349,7 @@ github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2T github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= 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-secure-stdlib/tlsutil v0.1.2/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/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= @@ -1369,12 +1364,15 @@ github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pB 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.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.0/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/hcdiag v0.5.1/go.mod h1:RMC2KkffN9uJ+5mFSaL67ZFVj4CDeetPF2d/53XpwXo= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcp-scada-provider v0.2.0/go.mod h1:Q0WpS2RyhBKOPD4X/8oW7AJe7jA2HXB09EwDzwRTao0= +github.com/hashicorp/hcl/v2 v2.11.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= +github.com/hashicorp/hcl/v2 v2.14.1/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= +github.com/hashicorp/hcp-scada-provider v0.2.4/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo= github.com/hashicorp/hcp-sdk-go v0.23.0/go.mod h1:/9UoDY2FYYA8lFaKBb2HmM/jKYZGANmf65q9QRc/cVw= -github.com/hashicorp/hcp-sdk-go v0.23.1-0.20220921131124-49168300a7dc/go.mod h1:/9UoDY2FYYA8lFaKBb2HmM/jKYZGANmf65q9QRc/cVw= +github.com/hashicorp/hcp-sdk-go v0.80.0/go.mod h1:vQ4fzdL1AmhIAbCw+4zmFe5Hbpajj3NvRWkJoVuxmAk= 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.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= @@ -1385,39 +1383,47 @@ github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7H 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.4.0/go.mod h1:nz64BIjXphDLATfKGG5RzHtNUPioLeKFsXEm88yTVew= +github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= 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/go.mod h1:nTakvJ4XYq45UXtn0DbwR4aU9ZdjlnIenpbs6Cd+FM0= github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY= -github.com/hashicorp/raft-wal v0.3.0/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= +github.com/hashicorp/raft-wal v0.4.1/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +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.2/go.mod h1:ML8aYzBIhY5m1MD1B2Q0JV89cC85YVH4t5kBaZiyVaE= +github.com/hashicorp/vault/api v1.8.3/go.mod h1:4g/9lj9lmuJQMtT6CmVMHC5FW1yENaVv+Nv4ZfG8fAg= 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/go.mod h1:KyfArJkhooyba7gYCKSq8v66QdqJmnbAxtV/OX1+JTs= github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/iancoleman/strcase v0.1.3/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= 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/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +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/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062/go.mod h1:PcNJqIlcX/dj3DTG/+QQnRvSgTMG6CLpRMjWcv4+J6w= github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= +github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8= +github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= 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/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -1428,10 +1434,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWxWd04xTqnuOQxnai7XGS2PrPY2cfGoDKtMHjA= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1439,7 +1443,6 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= @@ -1452,13 +1455,13 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL 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/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -1474,15 +1477,12 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA= -github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= -github.com/liquidweb/liquidweb-go v1.6.0/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ= -github.com/lucas-clemente/quic-go v0.13.1/go.mod h1:Vn3/Fb0/77b02SGhQk36KzOUmXgVpFfizUfW5WMaqyU= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= @@ -1498,9 +1498,6 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ 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/marten-seemann/chacha20 v0.2.0/go.mod h1:HSdjFau7GzYRj+ahFNwsO3ouVJr1HFkWoEwNDb4TMtE= -github.com/marten-seemann/qpack v0.1.0/go.mod h1:LFt1NU/Ptjip0C2CPkhimBz5CGE3WGDAUWqna+CNTrI= -github.com/marten-seemann/qtls v0.4.1/go.mod h1:pxVXcHHw1pNIt8Qo0pwSYQEoZ8yYOOPXTCZLQQunvRc= 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= @@ -1509,7 +1506,6 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb 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.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= @@ -1518,33 +1514,34 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k 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/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mholt/certmagic v0.8.3/go.mod h1:91uJzK5K8IWtYQqTi5R2tsxV1pCde+wdGfaRaOZi6aQ= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= 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/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= 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/cli v1.1.4/go.mod h1:vTLESy5mRhKOs9KDp0/RATawxP1UqBmdrpVRMnpcvKQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= 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= @@ -1553,11 +1550,11 @@ github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= 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= @@ -1565,12 +1562,11 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:ifHPsLndGGzvgzcaXUvzmt6LxKT4pJ+uzEhtnMt+f7A= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/jwt v1.1.0/go.mod h1:n3cvmLfBfnpV4JJRN7lRYCyZnw48ksGsbThGXEk4w9M= github.com/nats-io/nats-server/v2 v2.1.9/go.mod h1:9qVyoewoYXzG1ME9ox0HwkkzyYvnlBDugfR4Gg/8uHU= @@ -1580,50 +1576,56 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nkeys v0.1.4/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nats-io/stan.go v0.8.1/go.mod h1:Ci6mUIpGQTjl++MqK2XzkWI/0vF+Bl72uScx7ejSYmU= -github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= 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= -github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw= -github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ= -github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= github.com/nsqio/go-nsq v1.0.8/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY= +github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= +github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5/go.mod h1:uVHyebswE1cCXr2A73cRM2frx5ld1RJUCJkFNZ90ZiI= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= -github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ= +github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/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/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1638,21 +1640,17 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= 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 v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 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-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1661,23 +1659,18 @@ github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJ github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +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.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -1685,13 +1678,12 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA= -github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy7Fmig= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rboyer/safeio v0.2.3/go.mod h1:d7RMmt7utQBJZ4B7f0H/cU/EdZibQAU1Y8NWepK2dS8= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1699,36 +1691,34 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR 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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= 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/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac= github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= +github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1739,15 +1729,18 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/streadway/amqp v0.0.0-20200108173154-1c71cc93ed71/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= 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= @@ -1770,33 +1763,37 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tencentcloud/tencentcloud-sdk-go v1.0.162/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY= -github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA= 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/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= 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= @@ -1808,13 +1805,17 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty v1.11.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd v0.5.0-alpha.5.0.20190917205325-a14579fbfb1a/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= @@ -1822,12 +1823,11 @@ go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0= +go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= 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= @@ -1836,27 +1836,32 @@ 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/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ= +go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 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/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1864,31 +1869,35 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/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-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 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-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1907,6 +1916,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220518171630-0b5c67f07fdf/go.mod h1:yh0Ynu2b5ZUe3MQfp2nM0ecK7wsgouWTDN0FNeJuIys= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/exp v0.0.0-20221215174704-0915cd710c24/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1947,15 +1958,18 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.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= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1964,10 +1978,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/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-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1979,10 +1990,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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= @@ -1994,6 +2003,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -2008,12 +2018,13 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v 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-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -2032,6 +2043,7 @@ golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -2041,13 +2053,15 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= 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-20190402181905-9f3314589c9a/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= @@ -2071,12 +2085,15 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= 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= @@ -2097,7 +2114,6 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2105,7 +2121,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2117,6 +2132,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w 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-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2125,19 +2141,17 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2165,6 +2179,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2175,7 +2190,7 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w 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-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2199,18 +2214,22 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/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-20220829200755-d48e67d00261/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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2221,11 +2240,13 @@ golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2238,14 +2259,15 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -2261,22 +2283,20 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2287,7 +2307,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -2300,8 +2319,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/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= @@ -2328,6 +2345,7 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs 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-20200505023115-26f46d2f7ef8/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= @@ -2340,6 +2358,7 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -2349,15 +2368,18 @@ 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.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= +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= @@ -2375,7 +2397,6 @@ gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6d gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -2445,14 +2466,13 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww 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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= 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-20180831171423-11092d34479b/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-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -2469,6 +2489,7 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG 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= @@ -2479,6 +2500,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D 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= @@ -2490,6 +2512,7 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D 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-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= 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= @@ -2607,14 +2630,11 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/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= @@ -2655,6 +2675,7 @@ google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwS google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -2679,7 +2700,6 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/DataDog/dd-trace-go.v1 v1.19.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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= @@ -2687,26 +2707,19 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 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/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= -gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= +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/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= @@ -2725,8 +2738,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= 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= @@ -2735,24 +2747,27 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= -k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA= +k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= -k8s.io/client-go v0.0.0-20190620085101-78d2af792bab/go.mod h1:E95RaSlHr79aHaX0aGSwcPNfygDiPKOVXdmivCIZT0k= +k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= +k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190306001800-15615b16d372/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= -k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190529001817-6999998975a7/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= @@ -2808,7 +2823,11 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= From 8bea6cd82a69b0c895ae92aa336bfa6d667d7f2d Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Fri, 3 May 2024 15:21:43 -0500 Subject: [PATCH 008/185] deployer: ensure the proxy/dns/pause containers do not continually get replaced due to a change in a docker default (#21043) --- .../sprawl/internal/tfgen/templates/container-coredns.tf.tmpl | 1 + .../sprawl/internal/tfgen/templates/container-pause.tf.tmpl | 1 + .../sprawl/internal/tfgen/templates/container-proxy.tf.tmpl | 1 + 3 files changed, 3 insertions(+) diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl index 97c0d7011d..3dabd7d50e 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl @@ -4,6 +4,7 @@ resource "docker_container" "{{.DockerNetworkName}}-coredns" { restart = "always" dns = ["8.8.8.8"] + network_mode = "bridge" networks_advanced { name = docker_network.{{.DockerNetworkName}}.name ipv4_address = "{{.IPAddress}}" diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl index ef537f0352..37a1370c63 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl @@ -23,6 +23,7 @@ ports { } {{- end }} +network_mode = "bridge" {{- range .Node.Addresses }} networks_advanced { name = docker_network.{{.DockerNetworkName}}.name diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl index f4d7fe1d94..64e09743e1 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl @@ -8,6 +8,7 @@ resource "docker_container" "{{.DockerNetworkName}}-forwardproxy" { internal = {{.InternalPort}} } + network_mode = "bridge" networks_advanced { name = docker_network.{{.DockerNetworkName}}.name ipv4_address = "{{.IPAddress}}" From 4ad1757dfec514de43059c9a4da8291f4476c877 Mon Sep 17 00:00:00 2001 From: wangxinyi7 Date: Fri, 3 May 2024 15:10:04 -0700 Subject: [PATCH 009/185] add license file (#21035) --- .github/workflows/build.yml | 12 +++++++++++- Dockerfile | 10 ++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0047d809b2..b68fb9e3fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -141,8 +141,16 @@ jobs: arch: ${{ matrix.goarch }} reproducible: report instructions: |- + cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -o "$BIN_PATH" -trimpath -buildvcs=false + - name: Copy license file + env: + LICENSE_DIR: ".release/linux/package/usr/share/doc/${{ env.PKG_NAME }}" + run: | + mkdir -p "$LICENSE_DIR" + cp LICENSE "$LICENSE_DIR/LICENSE.txt" + - name: Package if: ${{ matrix.goos == 'linux' }} uses: hashicorp/actions-packaging-linux@v1 @@ -153,7 +161,7 @@ jobs: version: ${{ needs.set-product-version.outputs.product-version }} maintainer: "HashiCorp" homepage: "https://github.com/hashicorp/consul" - license: "MPL-2.0" + license: "BSL-1.1" binary: "dist/${{ env.PKG_NAME }}" deb_depends: "openssl" rpm_depends: "openssl" @@ -232,6 +240,7 @@ jobs: arch: ${{ matrix.goarch }} reproducible: report instructions: |- + cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -o "$BIN_PATH" -trimpath -buildvcs=false build-darwin: @@ -282,6 +291,7 @@ jobs: arch: ${{ matrix.goarch }} reproducible: report instructions: |- + cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -tags netcgo -o "$BIN_PATH" -trimpath -buildvcs=false build-docker: diff --git a/Dockerfile b/Dockerfile index e68a2190b2..24c9583f91 100644 --- a/Dockerfile +++ b/Dockerfile @@ -123,7 +123,7 @@ ENV BIN_NAME=$BIN_NAME ENV PRODUCT_VERSION=$PRODUCT_VERSION ARG PRODUCT_REVISION -ARG PRODUCT_NAME=$BIN_NAME +ENV PRODUCT_NAME=$BIN_NAME # TARGETOS and TARGETARCH are set automatically when --platform is provided. ARG TARGETOS TARGETARCH @@ -136,8 +136,10 @@ LABEL org.opencontainers.image.authors="Consul Team " \ 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." \ + org.opencontainers.image.licenses="BSL-1.1" \ version=${PRODUCT_VERSION} +COPY LICENSE /usr/share/doc/$PRODUCT_NAME/LICENSE.txt # Set up certificates and base tools. # libc6-compat is needed to symlink the shared libraries for ARM builds RUN apk add -v --no-cache \ @@ -203,7 +205,6 @@ CMD ["agent", "-dev", "-client", "0.0.0.0"] # This target is used to build a Consul image for use on OpenShift. FROM registry.access.redhat.com/ubi9-minimal:9.3 as ubi -ARG PRODUCT_NAME ARG PRODUCT_VERSION ARG PRODUCT_REVISION ARG BIN_NAME @@ -212,8 +213,7 @@ ARG BIN_NAME # and the version to download. Example: PRODUCT_NAME=consul PRODUCT_VERSION=1.2.3. ENV BIN_NAME=$BIN_NAME ENV PRODUCT_VERSION=$PRODUCT_VERSION - -ARG PRODUCT_NAME=$BIN_NAME +ENV PRODUCT_NAME=$BIN_NAME # TARGETOS and TARGETARCH are set automatically when --platform is provided. ARG TARGETOS TARGETARCH @@ -226,8 +226,10 @@ LABEL org.opencontainers.image.authors="Consul Team " \ 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." \ + org.opencontainers.image.licenses="BSL-1.1" \ version=${PRODUCT_VERSION} +COPY LICENSE /usr/share/doc/$PRODUCT_NAME/LICENSE.txt # Copy license for Red Hat certification. COPY LICENSE /licenses/mozilla.txt From 86b0818c1f2dd475cd6f920fcac163e443876197 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Fri, 3 May 2024 20:18:51 -0400 Subject: [PATCH 010/185] [NET-8601] security: upgrade vault/api to remove go-jose.v2 (#20910) security: upgrade vault/api to remove go-jose.v2 This dependency has an open vulnerability (GO-2024-2631), and is no longer needed by the latest `vault/api`. This is a follow-up to the upgrade of `go-jose/v3` in this repository to make all our dependencies consolidate on v3. Also remove the recently added security scan triage block for GO-2024-2631, which was added due to incorrect reports that `go-jose/v3@3.0.3` was impacted; in reality, is was this indirect client dependency (not impacted by CVE) that the scanner was flagging. A bug report has been filed to address the incorrect reporting. --- .changelog/20910.txt | 4 ++++ .release/security-scan.hcl | 1 - api/go.mod | 6 +++--- api/go.sum | 13 +++++++------ envoyextensions/go.mod | 4 ++-- envoyextensions/go.sum | 9 +++++---- go.mod | 11 +++-------- go.sum | 19 +++++++------------ internal/tools/proto-gen-rpc-glue/go.mod | 2 +- internal/tools/proto-gen-rpc-glue/go.sum | 4 ++-- proto-public/go.mod | 2 +- proto-public/go.sum | 4 ++-- scan.hcl | 1 - sdk/go.mod | 6 +++--- sdk/go.sum | 13 +++++++------ test-integ/go.mod | 4 ++-- test-integ/go.sum | 8 ++++---- .../connect/envoy/test-sds-server/go.mod | 1 + .../connect/envoy/test-sds-server/go.sum | 6 ++++-- test/integration/consul-container/go.mod | 4 ++-- test/integration/consul-container/go.sum | 9 +++++---- .../testdata/wasm_test_files/go.mod | 2 ++ .../testdata/wasm_test_files/go.sum | 3 ++- testing/deployer/go.mod | 6 +++--- testing/deployer/go.sum | 13 +++++++------ troubleshoot/go.mod | 4 ++-- troubleshoot/go.sum | 9 +++++---- 27 files changed, 86 insertions(+), 82 deletions(-) create mode 100644 .changelog/20910.txt diff --git a/.changelog/20910.txt b/.changelog/20910.txt new file mode 100644 index 0000000000..2ec948ee6c --- /dev/null +++ b/.changelog/20910.txt @@ -0,0 +1,4 @@ +```release-note:security +Update `vault/api` to v1.12.2 to address [CVE-2024-28180](https://nvd.nist.gov/vuln/detail/CVE-2024-28180) +(removes indirect dependency on impacted `go-jose.v2`) +``` diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index c49ffd32fd..8401764bc4 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -81,7 +81,6 @@ binary { suppress { # N.b. `vulnerabilites` is the correct spelling for this tool. vulnerabilites = [ - "GO-2024-2631", # go-jose/v3@v3.0.3 (false positive) ] paths = [ "internal/tools/proto-gen-rpc-glue/e2e/consul/*", diff --git a/api/go.mod b/api/go.mod index 4c9ef724f0..611bc20695 100644 --- a/api/go.mod +++ b/api/go.mod @@ -20,7 +20,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/serf v0.10.1 github.com/mitchellh/mapstructure v1.5.0 - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 google.golang.org/protobuf v1.33.0 ) @@ -28,7 +28,7 @@ require ( require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.0.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -39,7 +39,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.41 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/api/go.sum b/api/go.sum index 723d33a130..0821e27489 100644 --- a/api/go.sum +++ b/api/go.sum @@ -23,8 +23,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 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= @@ -107,8 +107,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/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= @@ -167,8 +167,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P 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.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= 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= @@ -211,6 +211,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/envoyextensions/go.mod b/envoyextensions/go.mod index cb359f20f9..8531affc75 100644 --- a/envoyextensions/go.mod +++ b/envoyextensions/go.mod @@ -26,7 +26,7 @@ require ( github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -36,7 +36,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/envoyextensions/go.sum b/envoyextensions/go.sum index 9bde12a0d2..b215d64921 100644 --- a/envoyextensions/go.sum +++ b/envoyextensions/go.sum @@ -37,8 +37,8 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 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= @@ -121,8 +121,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/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= @@ -227,6 +227,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/go.mod b/go.mod index f2647de9f5..07b19d7b5f 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/docker/go-connections v0.4.0 github.com/envoyproxy/go-control-plane v0.12.0 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e - github.com/fatih/color v1.14.1 + github.com/fatih/color v1.16.0 github.com/fsnotify/fsnotify v1.6.0 github.com/fullstorydev/grpchan v1.1.1 github.com/go-jose/go-jose/v3 v3.0.3 @@ -78,7 +78,7 @@ require ( github.com/hashicorp/raft-wal v0.4.1 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 + github.com/hashicorp/vault/api v1.12.2 github.com/hashicorp/vault/api/auth/gcp v0.3.0 github.com/hashicorp/vault/sdk v0.7.0 github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 @@ -201,8 +201,6 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect 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-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/golang-lru/v2 v2.0.0 // indirect @@ -219,7 +217,7 @@ require ( github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // 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/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect @@ -230,7 +228,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect 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/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 @@ -263,7 +260,6 @@ require ( go.mongodb.org/mongo-driver v1.13.1 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel/trace v1.17.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/term v0.19.0 // indirect @@ -277,7 +273,6 @@ require ( 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/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/klog/v2 v2.100.1 // indirect diff --git a/go.sum b/go.sum index 15efa58f9b..6ef73b225c 100644 --- a/go.sum +++ b/go.sum @@ -220,9 +220,8 @@ github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 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/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= @@ -445,8 +444,6 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+ 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= @@ -458,7 +455,6 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 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= @@ -525,8 +521,8 @@ github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfE 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 v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE= +github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE= 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= @@ -615,8 +611,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= @@ -677,7 +673,6 @@ github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce h1:TqjP/BTDrwN7zP9 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/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= @@ -1120,6 +1115,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc 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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= @@ -1386,7 +1382,6 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHN 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= -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.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/tools/proto-gen-rpc-glue/go.mod b/internal/tools/proto-gen-rpc-glue/go.mod index 0dc54c62df..61d5a7ac53 100644 --- a/internal/tools/proto-gen-rpc-glue/go.mod +++ b/internal/tools/proto-gen-rpc-glue/go.mod @@ -2,7 +2,7 @@ module github.com/hashicorp/consul/internal/tools/proto-gen-rpc-glue go 1.17 -require github.com/stretchr/testify v1.8.3 +require github.com/stretchr/testify v1.8.4 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/internal/tools/proto-gen-rpc-glue/go.sum b/internal/tools/proto-gen-rpc-glue/go.sum index 5135bf7e71..22d8915969 100644 --- a/internal/tools/proto-gen-rpc-glue/go.sum +++ b/internal/tools/proto-gen-rpc-glue/go.sum @@ -23,8 +23,8 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/proto-public/go.mod b/proto-public/go.mod index 9996497aaa..18fb77cd33 100644 --- a/proto-public/go.mod +++ b/proto-public/go.mod @@ -3,7 +3,7 @@ module github.com/hashicorp/consul/proto-public go 1.19 require ( - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 google.golang.org/grpc v1.56.3 google.golang.org/protobuf v1.33.0 diff --git a/proto-public/go.sum b/proto-public/go.sum index bf690f6d95..58e726a627 100644 --- a/proto-public/go.sum +++ b/proto-public/go.sum @@ -12,8 +12,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 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/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/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.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= diff --git a/scan.hcl b/scan.hcl index 415a794a4f..82888d3be8 100644 --- a/scan.hcl +++ b/scan.hcl @@ -29,7 +29,6 @@ repository { suppress { # N.b. `vulnerabilites` is the correct spelling for this tool. vulnerabilites = [ - "GO-2024-2631", # go-jose/v3@v3.0.3 (false positive) ] paths = [ "internal/tools/proto-gen-rpc-glue/e2e/consul/*", diff --git a/sdk/go.mod b/sdk/go.mod index 4c7b767e7c..d7f7a4441d 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -8,16 +8,16 @@ require ( github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.2.1 github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 golang.org/x/sys v0.19.0 ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // 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/mattn/go-isatty v0.0.20 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/sdk/go.sum b/sdk/go.sum index cd4a090611..e2ef238da1 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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.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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 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= @@ -29,8 +29,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/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= @@ -41,14 +41,15 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test-integ/go.mod b/test-integ/go.mod index 919762b1c2..c3f9f3a201 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -42,7 +42,7 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-test/deep v1.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -70,7 +70,7 @@ require ( github.com/klauspost/compress v1.16.7 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect diff --git a/test-integ/go.sum b/test-integ/go.sum index f1839a5b37..b2d37902b9 100644 --- a/test-integ/go.sum +++ b/test-integ/go.sum @@ -69,8 +69,8 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -180,8 +180,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/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= diff --git a/test/integration/connect/envoy/test-sds-server/go.mod b/test/integration/connect/envoy/test-sds-server/go.mod index 37c97e77c9..796196a3b5 100644 --- a/test/integration/connect/envoy/test-sds-server/go.mod +++ b/test/integration/connect/envoy/test-sds-server/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/envoyproxy/go-control-plane v0.12.0 + github.com/fatih/color v1.16.0 // indirect github.com/hashicorp/consul v1.18.1 github.com/hashicorp/consul/sdk v0.16.0 // indirect github.com/hashicorp/go-hclog v1.5.0 diff --git a/test/integration/connect/envoy/test-sds-server/go.sum b/test/integration/connect/envoy/test-sds-server/go.sum index b91d94b1ba..1f0fba4baa 100644 --- a/test/integration/connect/envoy/test-sds-server/go.sum +++ b/test/integration/connect/envoy/test-sds-server/go.sum @@ -939,8 +939,9 @@ github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -1512,8 +1513,9 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index d44c96319b..1c0eb3789d 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -60,7 +60,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/envoyproxy/go-control-plane v0.12.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.0.1 // indirect @@ -88,7 +88,7 @@ require ( github.com/klauspost/compress v1.16.7 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index a7e36ca0b0..ac8860985c 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -91,8 +91,8 @@ github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQL 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6TZQas= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= @@ -233,8 +233,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/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= @@ -457,6 +457,7 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= 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 index 703b71414f..52bdfcb621 100644 --- 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 @@ -3,3 +3,5 @@ module main go 1.20 require github.com/tetratelabs/proxy-wasm-go-sdk v0.21.0 + +require github.com/stretchr/testify v1.8.4 // indirect 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 index e09133fbcc..4d92115d8d 100644 --- 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 @@ -1,6 +1,7 @@ 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/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/testing/deployer/go.mod b/testing/deployer/go.mod index e7bddebda1..50bec10ad4 100644 --- a/testing/deployer/go.mod +++ b/testing/deployer/go.mod @@ -17,7 +17,7 @@ require ( github.com/hashicorp/hcl/v2 v2.16.2 github.com/mitchellh/copystructure v1.2.0 github.com/rboyer/safeio v0.2.2 - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 golang.org/x/crypto v0.22.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 google.golang.org/grpc v1.56.3 @@ -32,7 +32,7 @@ require ( github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -41,7 +41,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect diff --git a/testing/deployer/go.sum b/testing/deployer/go.sum index 9b2fb31acf..db7d88bffd 100644 --- a/testing/deployer/go.sum +++ b/testing/deployer/go.sum @@ -36,8 +36,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -142,8 +142,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= 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= @@ -217,8 +217,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf 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/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/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= @@ -276,6 +276,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/troubleshoot/go.mod b/troubleshoot/go.mod index 140c51d70b..fe9a0b36f7 100644 --- a/troubleshoot/go.mod +++ b/troubleshoot/go.mod @@ -29,7 +29,7 @@ require ( github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -42,7 +42,7 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/troubleshoot/go.sum b/troubleshoot/go.sum index 62ca7bd8c6..c7b39b0299 100644 --- a/troubleshoot/go.sum +++ b/troubleshoot/go.sum @@ -39,8 +39,8 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7 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/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 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= @@ -124,8 +124,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/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= @@ -235,6 +235,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From b5b3a6318338f73a9b03cf5fab8bd5b7ab7d61af Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Mon, 6 May 2024 16:21:09 -0400 Subject: [PATCH 011/185] [NET-9098] Narrow scope of peering config on terminating gw filter chain to TCP services (#21054) --- agent/xds/listeners.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/agent/xds/listeners.go b/agent/xds/listeners.go index e7e78ce55c..b5e1e78196 100644 --- a/agent/xds/listeners.go +++ b/agent/xds/listeners.go @@ -1759,14 +1759,8 @@ type terminatingGatewayFilterChainOpts struct { } func (s *ResourceGenerator) makeFilterChainTerminatingGateway(cfgSnap *proxycfg.ConfigSnapshot, tgtwyOpts terminatingGatewayFilterChainOpts) (*envoy_listener_v3.FilterChain, error) { - // We need to at least match the SNI and use the root PEMs from the local cluster; however, requests coming - // from peered clusters where the external service is exported to will have their own SNI and root PEMs. + // We need to at least match the SNI and use the root PEMs from the local cluster sniMatches := []string{tgtwyOpts.cluster} - for _, bundle := range tgtwyOpts.peerTrustBundles { - svc := tgtwyOpts.service - sourceSNI := connect.PeeredServiceSNI(svc.Name, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), bundle.PeerName, cfgSnap.Roots.TrustDomain) - sniMatches = append(sniMatches, sourceSNI) - } tlsContext := &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: makeCommonTLSContext( @@ -1777,9 +1771,19 @@ func (s *ResourceGenerator) makeFilterChainTerminatingGateway(cfgSnap *proxycfg. RequireClientCertificate: &wrapperspb.BoolValue{Value: true}, } - err := injectSpiffeValidatorConfigForPeers(cfgSnap, tlsContext.CommonTlsContext, tgtwyOpts.peerTrustBundles) - if err != nil { - return nil, err + // For TCP connections, TLS is not terminated at the mesh gateway but is instead proxied through; + // therefore, we need to account for callers from other datacenters when setting up our filter chain. + if tgtwyOpts.protocol == "tcp" { + for _, bundle := range tgtwyOpts.peerTrustBundles { + svc := tgtwyOpts.service + sourceSNI := connect.PeeredServiceSNI(svc.Name, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), bundle.PeerName, cfgSnap.Roots.TrustDomain) + sniMatches = append(sniMatches, sourceSNI) + } + + err := injectSpiffeValidatorConfigForPeers(cfgSnap, tlsContext.CommonTlsContext, tgtwyOpts.peerTrustBundles) + if err != nil { + return nil, err + } } transportSocket, err := makeDownstreamTLSTransportSocket(tlsContext) From 502346029dcd611131a071fed1007e2578d75bd4 Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Tue, 7 May 2024 10:24:50 -0500 Subject: [PATCH 012/185] test: remove v2 integration tests (#21056) This removes any references to v2 integration tests from: - envoy integration tests (test/integration/connect) - container tests (test/integration/consul-container) - deployer tests (test-integ) --- .../explicit_destinations_l7_test.go | 504 ---------------- .../catalogv2/explicit_destinations_test.go | 315 ---------- test-integ/catalogv2/helpers_test.go | 31 - .../catalogv2/implicit_destinations_test.go | 244 -------- .../catalogv2/traffic_permissions_test.go | 459 --------------- test-integ/tenancy/client.go | 154 ----- test-integ/tenancy/common.go | 84 --- test-integ/tenancy/namespace_ce_test.go | 84 --- test-integ/topoutil/fixtures.go | 30 +- test/integration/connect/envoy/main_test.go | 39 +- test/integration/connect/envoy/run-tests.sh | 9 - test/integration/consul-container/go.mod | 26 - test/integration/consul-container/go.sum | 90 --- .../test/catalog/catalog_test.go | 43 -- .../test/trafficpermissions/tcp_test.go | 555 ------------------ .../test/upgrade/catalog/catalog_test.go | 88 --- 16 files changed, 10 insertions(+), 2745 deletions(-) delete mode 100644 test-integ/catalogv2/explicit_destinations_l7_test.go delete mode 100644 test-integ/catalogv2/explicit_destinations_test.go delete mode 100644 test-integ/catalogv2/helpers_test.go delete mode 100644 test-integ/catalogv2/implicit_destinations_test.go delete mode 100644 test-integ/catalogv2/traffic_permissions_test.go delete mode 100644 test-integ/tenancy/client.go delete mode 100644 test-integ/tenancy/common.go delete mode 100644 test-integ/tenancy/namespace_ce_test.go delete mode 100644 test/integration/consul-container/test/catalog/catalog_test.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 diff --git a/test-integ/catalogv2/explicit_destinations_l7_test.go b/test-integ/catalogv2/explicit_destinations_l7_test.go deleted file mode 100644 index 63d1473d4d..0000000000 --- a/test-integ/catalogv2/explicit_destinations_l7_test.go +++ /dev/null @@ -1,504 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalogv2 - -import ( - "fmt" - "testing" - - 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" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "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" - - "github.com/hashicorp/consul/test-integ/topoutil" -) - -func TestSplitterFeaturesL7ExplicitDestinations(t *testing.T) { - tenancies := []*pbresource.Tenancy{ - { - Partition: "default", - Namespace: "default", - }, - } - if utils.IsEnterprise() { - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "part1", - Namespace: "default", - }) - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "part1", - Namespace: "nsa", - }) - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "default", - Namespace: "nsa", - }) - } - cfg := testSplitterFeaturesL7ExplicitDestinationsCreator{ - tenancies: tenancies, - }.NewConfig(t) - - sp := sprawltest.Launch(t, cfg) - - var ( - asserter = topoutil.NewAsserter(sp) - - topo = sp.Topology() - cluster = topo.Clusters["dc1"] - - ships = topo.ComputeRelationships() - ) - - clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) - - t.Log(topology.RenderRelationships(ships)) - - for _, tenancy := range tenancies { - // Make sure things are in v2. - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, "static-client", tenancy, 1) - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, "static-server-v1", tenancy, 1) - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, "static-server-v2", tenancy, 1) - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, "static-server", tenancy, 0) - } - - // Check relationships - for _, ship := range ships { - t.Run("relationship: "+ship.String(), func(t *testing.T) { - var ( - wrk = ship.Caller - dest = ship.Destination - ) - - v1ID := dest.ID - v1ID.Name = "static-server-v1" - v1ClusterPrefix := clusterPrefix(dest.PortName, v1ID, dest.Cluster) - - v2ID := dest.ID - v2ID.Name = "static-server-v2" - v2ClusterPrefix := clusterPrefix(dest.PortName, v2ID, dest.Cluster) - - // we expect 2 clusters, one for each leg of the split - asserter.DestinationEndpointStatus(t, wrk, v1ClusterPrefix+".", "HEALTHY", 1) - asserter.DestinationEndpointStatus(t, wrk, v2ClusterPrefix+".", "HEALTHY", 1) - - // Both should be possible. - v1Expect := fmt.Sprintf("%s::%s", cluster.Name, v1ID.String()) - v2Expect := fmt.Sprintf("%s::%s", cluster.Name, v2ID.String()) - - switch dest.PortName { - case "tcp": - asserter.CheckBlankspaceNameTrafficSplitViaTCP(t, wrk, dest, - map[string]int{v1Expect: 10, v2Expect: 90}) - case "grpc": - asserter.CheckBlankspaceNameTrafficSplitViaGRPC(t, wrk, dest, - map[string]int{v1Expect: 10, v2Expect: 90}) - case "http": - asserter.CheckBlankspaceNameTrafficSplitViaHTTP(t, wrk, dest, false, "/", - map[string]int{v1Expect: 10, v2Expect: 90}) - case "http2": - asserter.CheckBlankspaceNameTrafficSplitViaHTTP(t, wrk, dest, true, "/", - map[string]int{v1Expect: 10, v2Expect: 90}) - default: - t.Fatalf("unexpected port name: %s", dest.PortName) - } - }) - } -} - -type testSplitterFeaturesL7ExplicitDestinationsCreator struct { - tenancies []*pbresource.Tenancy -} - -func (c testSplitterFeaturesL7ExplicitDestinationsCreator) NewConfig(t *testing.T) *topology.Config { - const clusterName = "dc1" - - servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName, "wan"}, nil) - - cluster := &topology.Cluster{ - Enterprise: utils.IsEnterprise(), - Name: clusterName, - Nodes: servers, - Services: make(map[topology.ID]*pbcatalog.Service), - } - - lastNode := 0 - nodeName := func() string { - lastNode++ - return fmt.Sprintf("%s-box%d", clusterName, lastNode) - } - - for _, ten := range c.tenancies { - c.topologyConfigAddNodes(t, cluster, nodeName, ten) - } - - return &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: clusterName}, - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - cluster, - }, - } -} - -func (c testSplitterFeaturesL7ExplicitDestinationsCreator) topologyConfigAddNodes( - t *testing.T, - cluster *topology.Cluster, - nodeName func() string, - currentTenancy *pbresource.Tenancy, -) { - clusterName := cluster.Name - - newID := func(name string, tenancy *pbresource.Tenancy) topology.ID { - return topology.ID{ - Partition: tenancy.Partition, - Namespace: tenancy.Namespace, - Name: name, - } - } - - tenancy := &pbresource.Tenancy{ - Partition: currentTenancy.Partition, - Namespace: currentTenancy.Namespace, - } - - v1ServerNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: currentTenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewBlankspaceWorkloadWithDefaults( - clusterName, - newID("static-server-v1", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.V2Services = []string{"static-server-v1", "static-server"} - wrk.Meta = map[string]string{ - "version": "v1", - } - wrk.WorkloadIdentity = "static-server-v1" - }, - ), - }, - } - v2ServerNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: currentTenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewBlankspaceWorkloadWithDefaults( - clusterName, - newID("static-server-v2", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.V2Services = []string{"static-server-v2", "static-server"} - wrk.Meta = map[string]string{ - "version": "v2", - } - wrk.WorkloadIdentity = "static-server-v2" - }, - ), - }, - } - clientNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: currentTenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewBlankspaceWorkloadWithDefaults( - clusterName, - newID("static-client", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.V2Services = []string{"static-client"} - for i, tenancy := range c.tenancies { - wrk.Destinations = append(wrk.Destinations, &topology.Destination{ - - ID: newID("static-server", tenancy), - PortName: "http", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5000 + (i * 4), - }, - &topology.Destination{ - - ID: newID("static-server", tenancy), - PortName: "http2", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5001 + (i * 4), - }, - &topology.Destination{ - - ID: newID("static-server", tenancy), - PortName: "grpc", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5002 + (i * 4), - }, - &topology.Destination{ - - ID: newID("static-server", tenancy), - PortName: "tcp", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5003 + (i * 4), - }, - ) - } - }, - ), - }, - } - - var sources []*pbauth.Source - for _, ten := range c.tenancies { - sources = append(sources, &pbauth.Source{ - IdentityName: "static-client", - Namespace: ten.Namespace, - Partition: ten.Partition, - }) - } - - v1TrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "static-server-v1-perms", - Tenancy: tenancy, - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "static-server-v1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: sources, - }}, - }) - - v2TrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "static-server-v2-perms", - Tenancy: tenancy, - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "static-server-v2", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: sources, - }}, - }) - - portsFunc := func(offset uint32) []*pbcatalog.ServicePort { - return []*pbcatalog.ServicePort{ - { - TargetPort: "http", - VirtualPort: 8005 + offset, - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "http2", - VirtualPort: 8006 + offset, - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - }, - { - TargetPort: "grpc", - VirtualPort: 9005 + offset, - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - }, - { - TargetPort: "tcp", - VirtualPort: 10005 + offset, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - } - } - - // Differ parent and backend virtual ports to verify we route to each correctly. - parentServicePorts := portsFunc(0) - backendServicePorts := portsFunc(100) - - // Explicitly define backend services s.t. they are not inferred from workload, - // which would assign random virtual ports. - cluster.Services[newID("static-client", tenancy)] = &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - cluster.Services[newID("static-server", tenancy)] = &pbcatalog.Service{ - Ports: parentServicePorts, - } - cluster.Services[newID("static-server-v1", tenancy)] = &pbcatalog.Service{ - Ports: backendServicePorts, - } - cluster.Services[newID("static-server-v2", tenancy)] = &pbcatalog.Service{ - Ports: backendServicePorts, - } - - httpServerRoute := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbmesh.HTTPRouteType, - Name: "static-server-http-route", - Tenancy: tenancy, - }, - }, &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - { - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server", - Tenancy: tenancy, - }, - Port: "8005", // use mix of target and virtual parent ports - }, - { - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server", - Tenancy: tenancy, - }, - Port: "http2", - }, - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server-v1", - Tenancy: tenancy, - }, - }, - Weight: 10, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server-v2", - Tenancy: tenancy, - }, - }, - Weight: 90, - }, - }, - }}, - }) - - grpcServerRoute := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbmesh.GRPCRouteType, - Name: "static-server-grpc-route", - Tenancy: tenancy, - }, - }, &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server", - Tenancy: tenancy, - }, - Port: "grpc", - }}, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server-v1", - Tenancy: tenancy, - }, - Port: "9105", // use mix of virtual and target (inferred from parent) ports - }, - Weight: 10, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server-v2", - Tenancy: tenancy, - }, - }, - Weight: 90, - }, - }, - }}, - }) - - tcpServerRoute := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbmesh.TCPRouteType, - Name: "static-server-tcp-route", - Tenancy: tenancy, - }, - }, &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server", - Tenancy: tenancy, - }, - Port: "10005", // use virtual parent port - }}, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server-v1", - Tenancy: tenancy, - }, - Port: "10105", // use explicit virtual port - }, - Weight: 10, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "static-server-v2", - Tenancy: tenancy, - }, - Port: "tcp", // use explicit target port - }, - Weight: 90, - }, - }, - }}, - }) - - cluster.Nodes = append(cluster.Nodes, - clientNode, - v1ServerNode, - v2ServerNode, - ) - - cluster.InitialResources = append(cluster.InitialResources, - v1TrafficPerms, - v2TrafficPerms, - httpServerRoute, - grpcServerRoute, - tcpServerRoute, - ) -} diff --git a/test-integ/catalogv2/explicit_destinations_test.go b/test-integ/catalogv2/explicit_destinations_test.go deleted file mode 100644 index 5529a5a73a..0000000000 --- a/test-integ/catalogv2/explicit_destinations_test.go +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalogv2 - -import ( - "fmt" - "testing" - - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "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" - - "github.com/hashicorp/consul/test-integ/topoutil" -) - -// TestBasicL4ExplicitDestinations sets up the following: -// -// - 1 cluster (no peering / no wanfed) -// - 3 servers in that cluster -// - v2 arch is activated -// - for each tenancy, only using v2 constructs: -// - a client with one explicit destination to a single port service -// - a client with multiple explicit destinations to multiple ports of the -// same multiport service -// -// When this test is executed in CE it will only use the default/default -// tenancy. -// -// When this test is executed in Enterprise it will additionally test the same -// things within these tenancies: -// -// - part1/default -// - default/nsa -// - part1/nsa -func TestBasicL4ExplicitDestinations(t *testing.T) { - - tenancies := []*pbresource.Tenancy{ - { - Partition: "default", - Namespace: "default", - }, - } - if utils.IsEnterprise() { - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "part1", - Namespace: "default", - }) - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "part1", - Namespace: "nsa", - }) - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "default", - Namespace: "nsa", - }) - } - - cfg := testBasicL4ExplicitDestinationsCreator{ - tenancies: tenancies, - }.NewConfig(t) - - sp := sprawltest.Launch(t, cfg) - - var ( - asserter = topoutil.NewAsserter(sp) - - topo = sp.Topology() - cluster = topo.Clusters["dc1"] - - ships = topo.ComputeRelationships() - ) - - clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) - - t.Log(topology.RenderRelationships(ships)) - - // Make sure things are in v2. - for _, ten := range tenancies { - for _, name := range []string{ - "single-server", - "single-client", - "multi-server", - "multi-client", - } { - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, name, ten, 1) - } - } - - // Check relationships - for _, ship := range ships { - t.Run("relationship: "+ship.String(), func(t *testing.T) { - var ( - wrk = ship.Caller - dest = ship.Destination - ) - - clusterPrefix := clusterPrefixForDestination(dest) - - asserter.DestinationEndpointStatus(t, wrk, clusterPrefix+".", "HEALTHY", 1) - asserter.HTTPServiceEchoes(t, wrk, dest.LocalPort, "") - asserter.FortioFetch2FortioName(t, wrk, dest, cluster.Name, dest.ID) - }) - } -} - -type testBasicL4ExplicitDestinationsCreator struct { - tenancies []*pbresource.Tenancy -} - -func (c testBasicL4ExplicitDestinationsCreator) NewConfig(t *testing.T) *topology.Config { - const clusterName = "dc1" - - servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName, "wan"}, nil) - - cluster := &topology.Cluster{ - Enterprise: utils.IsEnterprise(), - Name: clusterName, - Nodes: servers, - } - - lastNode := 0 - nodeName := func() string { - lastNode++ - return fmt.Sprintf("%s-box%d", clusterName, lastNode) - } - - for _, ten := range c.tenancies { - c.topologyConfigAddNodes(t, cluster, nodeName, ten) - } - - return &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: clusterName}, - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - cluster, - }, - } -} - -func (c testBasicL4ExplicitDestinationsCreator) topologyConfigAddNodes( - t *testing.T, - cluster *topology.Cluster, - nodeName func() string, - tenancy *pbresource.Tenancy, -) { - clusterName := cluster.Name - - newID := func(name string, tenancy *pbresource.Tenancy) topology.ID { - return topology.ID{ - Partition: tenancy.Partition, - Namespace: tenancy.Namespace, - Name: name, - } - } - - singleportServerNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: tenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("single-server", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.WorkloadIdentity = "single-server-identity" - }, - ), - }, - } - var singleportDestinations []*topology.Destination - for i, ten := range c.tenancies { - singleportDestinations = append(singleportDestinations, &topology.Destination{ - ID: newID("single-server", ten), - PortName: "http", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5000 + i, - }) - } - singleportClientNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: tenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("single-client", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - delete(wrk.Ports, "grpc") // v2 mode turns this on, so turn it off - delete(wrk.Ports, "http2") // v2 mode turns this on, so turn it off - wrk.WorkloadIdentity = "single-client-identity" - wrk.Destinations = singleportDestinations - }, - ), - }, - } - var sources []*pbauth.Source - for _, ten := range c.tenancies { - sources = append(sources, &pbauth.Source{ - IdentityName: "single-client-identity", - Namespace: ten.Namespace, - Partition: ten.Partition, - }) - } - singleportTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "single-server-perms", - Tenancy: tenancy, - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "single-server-identity", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: sources, - }}, - }) - - multiportServerNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: tenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("multi-server", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.WorkloadIdentity = "multi-server-identity" - }, - ), - }, - } - var multiportDestinations []*topology.Destination - for i, ten := range c.tenancies { - multiportDestinations = append(multiportDestinations, &topology.Destination{ - ID: newID("multi-server", ten), - PortName: "http", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5000 + 2*i, - }) - multiportDestinations = append(multiportDestinations, &topology.Destination{ - ID: newID("multi-server", ten), - PortName: "http2", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5000 + 2*i + 1, - }) - } - multiportClientNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: tenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("multi-client", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.WorkloadIdentity = "multi-client-identity" - wrk.Destinations = multiportDestinations - }, - ), - }, - } - - var multiportSources []*pbauth.Source - for _, ten := range c.tenancies { - multiportSources = append(multiportSources, &pbauth.Source{ - IdentityName: "multi-client-identity", - Namespace: ten.Namespace, - Partition: ten.Partition, - }) - } - multiportTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "multi-server-perms", - Tenancy: tenancy, - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "multi-server-identity", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: multiportSources, - }}, - }) - - cluster.Nodes = append(cluster.Nodes, - singleportClientNode, - singleportServerNode, - multiportClientNode, - multiportServerNode, - ) - - cluster.InitialResources = append(cluster.InitialResources, - singleportTrafficPerms, - multiportTrafficPerms, - ) -} diff --git a/test-integ/catalogv2/helpers_test.go b/test-integ/catalogv2/helpers_test.go deleted file mode 100644 index 7e6f432650..0000000000 --- a/test-integ/catalogv2/helpers_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalogv2 - -import ( - "strings" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -// Deprecated: clusterPrefixForDestination -func clusterPrefixForUpstream(dest *topology.Destination) string { - return clusterPrefixForDestination(dest) -} - -func clusterPrefixForDestination(dest *topology.Destination) string { - if dest.Peer == "" { - return clusterPrefix(dest.PortName, dest.ID, dest.Cluster) - } else { - return strings.Join([]string{dest.ID.Name, dest.ID.Namespace, dest.Peer, "external"}, ".") - } -} - -func clusterPrefix(port string, svcID topology.ID, cluster string) string { - if svcID.PartitionOrDefault() == "default" { - return strings.Join([]string{port, svcID.Name, svcID.Namespace, cluster, "internal"}, ".") - } else { - return strings.Join([]string{port, svcID.Name, svcID.Namespace, svcID.Partition, cluster, "internal-v1"}, ".") - } -} diff --git a/test-integ/catalogv2/implicit_destinations_test.go b/test-integ/catalogv2/implicit_destinations_test.go deleted file mode 100644 index c539f3fe06..0000000000 --- a/test-integ/catalogv2/implicit_destinations_test.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalogv2 - -import ( - "fmt" - "testing" - - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "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" - - "github.com/hashicorp/consul/test-integ/topoutil" -) - -// TestBasicL4ImplicitDestinations sets up the following: -// -// - 1 cluster (no peering / no wanfed) -// - 3 servers in that cluster -// - v2 arch is activated -// - for each tenancy, only using v2 constructs: -// - a server exposing 2 tcp ports -// - a client with transparent proxy enabled and no explicit upstreams -// - a traffic permission granting the client access to the service on all ports -// -// When this test is executed in CE it will only use the default/default -// tenancy. -// -// When this test is executed in Enterprise it will additionally test the same -// things within these tenancies: -// -// - part1/default -// - default/nsa -// - part1/nsa -func TestBasicL4ImplicitDestinations(t *testing.T) { - tenancies := []*pbresource.Tenancy{{ - Namespace: "default", - Partition: "default", - }} - if utils.IsEnterprise() { - tenancies = append(tenancies, &pbresource.Tenancy{ - Namespace: "default", - Partition: "nsa", - }) - tenancies = append(tenancies, &pbresource.Tenancy{ - Namespace: "part1", - Partition: "default", - }) - tenancies = append(tenancies, &pbresource.Tenancy{ - Namespace: "part1", - Partition: "nsa", - }) - } - - cfg := testBasicL4ImplicitDestinationsCreator{ - tenancies: tenancies, - }.NewConfig(t) - - sp := sprawltest.Launch(t, cfg) - - var ( - asserter = topoutil.NewAsserter(sp) - - topo = sp.Topology() - cluster = topo.Clusters["dc1"] - - ships = topo.ComputeRelationships() - ) - - clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) - - t.Log(topology.RenderRelationships(ships)) - - // Make sure things are truly in v2 not v1. - for _, tenancy := range tenancies { - for _, name := range []string{ - "static-server", - "static-client", - } { - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, name, tenancy, 1) - } - } - - // Check relationships - for _, ship := range ships { - t.Run("relationship: "+ship.String(), func(t *testing.T) { - var ( - wrk = ship.Caller - dest = ship.Destination - ) - - clusterPrefix := clusterPrefixForDestination(dest) - - asserter.DestinationEndpointStatus(t, wrk, clusterPrefix+".", "HEALTHY", 1) - if dest.LocalPort > 0 { - asserter.HTTPServiceEchoes(t, wrk, dest.LocalPort, "") - } - asserter.FortioFetch2FortioName(t, wrk, dest, cluster.Name, dest.ID) - }) - } -} - -type testBasicL4ImplicitDestinationsCreator struct { - tenancies []*pbresource.Tenancy -} - -func (c testBasicL4ImplicitDestinationsCreator) NewConfig(t *testing.T) *topology.Config { - const clusterName = "dc1" - - servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName, "wan"}, nil) - - cluster := &topology.Cluster{ - Enterprise: utils.IsEnterprise(), - Name: clusterName, - Nodes: servers, - } - - lastNode := 0 - nodeName := func() string { - lastNode++ - return fmt.Sprintf("%s-box%d", clusterName, lastNode) - } - - for i := range c.tenancies { - c.topologyConfigAddNodes(t, cluster, nodeName, c.tenancies[i]) - } - - return &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: clusterName}, - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - cluster, - }, - } -} - -func (c testBasicL4ImplicitDestinationsCreator) topologyConfigAddNodes( - t *testing.T, - cluster *topology.Cluster, - nodeName func() string, - tenancy *pbresource.Tenancy, -) { - clusterName := cluster.Name - - newID := func(name string, tenancy *pbresource.Tenancy) topology.ID { - return topology.ID{ - Partition: tenancy.Partition, - Namespace: tenancy.Namespace, - Name: name, - } - } - - serverNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: tenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("static-server", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.EnableTransparentProxy = true - }, - ), - }, - } - - var impliedDestinations []*topology.Destination - for _, ten := range c.tenancies { - // For now we include all services in the same partition as implicit upstreams. - if tenancy.Partition != ten.Partition { - continue - } - impliedDestinations = append(impliedDestinations, &topology.Destination{ - ID: newID("static-server", ten), - PortName: "http", - }) - impliedDestinations = append(impliedDestinations, &topology.Destination{ - ID: newID("static-server", ten), - PortName: "http2", - }) - } - - clientNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: tenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("static-client", tenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.EnableTransparentProxy = true - wrk.ImpliedDestinations = impliedDestinations - }, - ), - }, - } - - var sources []*pbauth.Source - for _, ten := range c.tenancies { - sources = append(sources, &pbauth.Source{ - IdentityName: "static-client", - Namespace: ten.Namespace, - Partition: ten.Partition, - }) - } - - trafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "static-server-perms", - Tenancy: tenancy, - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "static-server", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: sources, - }}, - }) - - cluster.Nodes = append(cluster.Nodes, - clientNode, - serverNode, - ) - - cluster.InitialResources = append(cluster.InitialResources, - trafficPerms, - ) -} diff --git a/test-integ/catalogv2/traffic_permissions_test.go b/test-integ/catalogv2/traffic_permissions_test.go deleted file mode 100644 index 4e97462e33..0000000000 --- a/test-integ/catalogv2/traffic_permissions_test.go +++ /dev/null @@ -1,459 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 -package catalogv2 - -import ( - "context" - "fmt" - "net/http" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/consul/test-integ/topoutil" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "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" -) - -type testCase struct { - permissions []*permission - result []*testResult -} - -type permission struct { - allow bool - excludeSource bool - includeSourceTenancy bool - excludeSourceTenancy bool - destRules []*destRules -} - -type destRules struct { - values *ruleValues - excludes []*ruleValues -} - -type ruleValues struct { - portNames []string - path string - pathPref string - pathReg string - headers []string - methods []string -} - -type testResult struct { - fail bool - port string - path string - headers map[string]string -} - -func newTrafficPermissions(p *permission, srcTenancy *pbresource.Tenancy) *pbauth.TrafficPermissions { - sources := []*pbauth.Source{{ - IdentityName: "static-client", - Namespace: srcTenancy.Namespace, - Partition: srcTenancy.Partition, - }} - destinationRules := []*pbauth.DestinationRule{} - if p != nil { - srcId := "static-client" - if p.includeSourceTenancy { - srcId = "" - } - if p.excludeSource { - sources = []*pbauth.Source{{ - IdentityName: srcId, - Namespace: srcTenancy.Namespace, - Partition: srcTenancy.Partition, - Exclude: []*pbauth.ExcludeSource{{ - IdentityName: "static-client", - Namespace: srcTenancy.Namespace, - Partition: srcTenancy.Partition, - }}, - }} - } else { - sources = []*pbauth.Source{{ - IdentityName: srcId, - Namespace: srcTenancy.Namespace, - Partition: srcTenancy.Partition, - }} - } - for _, dr := range p.destRules { - destRule := &pbauth.DestinationRule{} - if dr.values != nil { - destRule.PathExact = dr.values.path - destRule.PathPrefix = dr.values.pathPref - destRule.PathRegex = dr.values.pathReg - destRule.Methods = dr.values.methods - destRule.PortNames = dr.values.portNames - destRule.Headers = []*pbauth.DestinationRuleHeader{} - for _, h := range dr.values.headers { - destRule.Headers = append(destRule.Headers, &pbauth.DestinationRuleHeader{ - Name: h, - Present: true, - }) - } - } - var excludePermissions []*pbauth.ExcludePermissionRule - for _, e := range dr.excludes { - eRule := &pbauth.ExcludePermissionRule{ - PathExact: e.path, - PathPrefix: e.pathPref, - PathRegex: e.pathReg, - Methods: e.methods, - PortNames: e.portNames, - } - eRule.Headers = []*pbauth.DestinationRuleHeader{} - for _, h := range e.headers { - eRule.Headers = append(eRule.Headers, &pbauth.DestinationRuleHeader{ - Name: h, - Present: true, - }) - } - excludePermissions = append(excludePermissions, eRule) - } - destRule.Exclude = excludePermissions - destinationRules = append(destinationRules, destRule) - } - } - action := pbauth.Action_ACTION_ALLOW - if !p.allow { - action = pbauth.Action_ACTION_DENY - } - return &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "static-server", - }, - Action: action, - Permissions: []*pbauth.Permission{{ - Sources: sources, - DestinationRules: destinationRules, - }}, - } - -} - -// This tests runs a gauntlet of traffic permissions updates and validates that the request status codes match the intended rules -func TestL7TrafficPermissions(t *testing.T) { - testcases := map[string]testCase{ - // L4 permissions - "basic": {permissions: []*permission{{allow: true}}, result: []*testResult{{fail: false}}}, - "client-exclude": {permissions: []*permission{{allow: true, includeSourceTenancy: true, excludeSource: true}}, result: []*testResult{{fail: true}}}, - "allow-all-client-in-tenancy": {permissions: []*permission{{allow: true, includeSourceTenancy: true}}, result: []*testResult{{fail: false}}}, - "only-one-port": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{portNames: []string{"http"}}}}}}, result: []*testResult{{fail: true, port: "http2"}}}, - "exclude-port": {permissions: []*permission{{allow: true, destRules: []*destRules{{excludes: []*ruleValues{{portNames: []string{"http"}}}}}}}, result: []*testResult{{fail: true, port: "http"}}}, - // L7 permissions - "methods": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{methods: []string{"POST", "PUT", "PATCH", "DELETE", "CONNECT", "HEAD", "OPTIONS", "TRACE"}, pathPref: "/"}}}}}, - // fortio fetch2 is configured to GET - result: []*testResult{{fail: true}}}, - "headers": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{headers: []string{"a", "b"}, pathPref: "/"}}}}}, - result: []*testResult{{fail: true}, {fail: true, headers: map[string]string{"a": "1"}}, {fail: false, headers: map[string]string{"a": "1", "b": "2"}}}}, - "path-prefix-all": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/", methods: []string{"GET"}}}}}}, result: []*testResult{{fail: false}}}, - "method-exclude": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/"}, excludes: []*ruleValues{{methods: []string{"GET"}}}}}}}, - // fortio fetch2 is configured to GET - result: []*testResult{{fail: true}}}, - "exclude-paths-and-headers": {permissions: []*permission{{allow: true, destRules: []*destRules{ - { - values: &ruleValues{pathPref: "/f", headers: []string{"a"}}, - excludes: []*ruleValues{{headers: []string{"b"}, path: "/foobar"}}, - }}}}, - result: []*testResult{ - {fail: false, path: "foobar", headers: map[string]string{"a": "1"}}, - {fail: false, path: "foo", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: true, path: "foobar", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: false, path: "foo", headers: map[string]string{"a": "1"}}, - {fail: true, path: "foo", headers: map[string]string{"b": "2"}}, - {fail: true, path: "baz", headers: map[string]string{"a": "1"}}, - }}, - "exclude-paths-or-headers": {permissions: []*permission{{allow: true, destRules: []*destRules{ - {values: &ruleValues{pathPref: "/f", headers: []string{"a"}}, excludes: []*ruleValues{{headers: []string{"b"}}, {path: "/foobar"}}}}}}, - result: []*testResult{ - {fail: true, path: "foobar", headers: map[string]string{"a": "1"}}, - {fail: true, path: "foo", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: true, path: "foobar", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: false, path: "foo", headers: map[string]string{"a": "1"}}, - {fail: false, path: "foo", headers: map[string]string{"a": "1"}}, - {fail: true, path: "baz", port: "http", headers: map[string]string{"a": "1"}}, - }}, - "path-or-header": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/bar"}}, {values: &ruleValues{headers: []string{"b"}}}}}}, - result: []*testResult{ - {fail: false, path: "bar"}, - {fail: false, path: "foo", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: false, path: "bar", headers: map[string]string{"b": "2"}}, - {fail: true, path: "foo", headers: map[string]string{"a": "1"}}, - }}, - "path-and-header": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/bar", headers: []string{"b"}}}}}}, - result: []*testResult{ - {fail: true, path: "bar"}, - {fail: true, path: "foo", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: false, path: "bar", headers: map[string]string{"b": "2"}}, - {fail: true, path: "foo", headers: map[string]string{"a": "1"}}, - }}, - "path-regex-exclude": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/"}, excludes: []*ruleValues{{pathReg: ".*dns.*"}}}}}}, - result: []*testResult{{fail: true, path: "fortio/rest/dns"}, {fail: false, path: "fortio/rest/status"}}}, - "header-include-exclude-by-port": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/", headers: []string{"experiment1", "experiment2"}}, excludes: []*ruleValues{{portNames: []string{"http2"}, headers: []string{"experiment1"}}}}}}}, - result: []*testResult{{fail: true, port: "http2", headers: map[string]string{"experiment1": "a", "experiment2": "b"}}, - {fail: false, port: "http", headers: map[string]string{"experiment1": "a", "experiment2": "b"}}, - {fail: true, port: "http2", headers: map[string]string{"experiment2": "b"}}, - {fail: true, port: "http", headers: map[string]string{"experiment3": "c"}}, - }}, - "two-tp-or": {permissions: []*permission{{allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/bar"}}}}, {allow: true, destRules: []*destRules{{values: &ruleValues{headers: []string{"b"}}}}}}, - result: []*testResult{ - {fail: false, path: "bar"}, - {fail: false, path: "foo", headers: map[string]string{"a": "1", "b": "2"}}, - {fail: false, path: "bar", headers: map[string]string{"b": "2"}}, - {fail: true, path: "foo", headers: map[string]string{"a": "1"}}, - }}, - } - if utils.IsEnterprise() { - // DENY and ALLOW permissions - testcases["deny-cancel-allow"] = testCase{permissions: []*permission{{allow: true}, {allow: false}}, result: []*testResult{{fail: true}}} - testcases["l4-deny-l7-allow"] = testCase{permissions: []*permission{{allow: false}, {allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/"}}}}}, result: []*testResult{{fail: true}, {fail: true, path: "test"}}} - testcases["l7-deny-l4-allow"] = testCase{permissions: []*permission{{allow: true}, {allow: true, destRules: []*destRules{{values: &ruleValues{pathPref: "/"}}}}, {allow: false, destRules: []*destRules{{values: &ruleValues{pathPref: "/foo"}}}}}, - result: []*testResult{{fail: false}, {fail: false, path: "test"}, {fail: true, path: "foo-bar"}}} - } - - tenancies := []*pbresource.Tenancy{ - { - Partition: "default", - Namespace: "default", - }, - } - if utils.IsEnterprise() { - tenancies = append(tenancies, &pbresource.Tenancy{ - Partition: "ap1", - Namespace: "ns1", - }) - } - cfg := testL7TrafficPermissionsCreator{tenancies}.NewConfig(t) - targetImage := utils.TargetImages() - imageName := targetImage.Consul - if utils.IsEnterprise() { - imageName = targetImage.ConsulEnterprise - } - t.Log("running with target image: " + imageName) - - sp := sprawltest.Launch(t, cfg) - - asserter := topoutil.NewAsserter(sp) - - topo := sp.Topology() - cluster := topo.Clusters["dc1"] - ships := topo.ComputeRelationships() - - clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) - - // Make sure services exist - for _, tenancy := range tenancies { - for _, name := range []string{ - "static-server", - "static-client", - } { - libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, name, tenancy, len(tenancies)) - } - } - var initialTrafficPerms []*pbresource.Resource - for testName, tc := range testcases { - // Delete old TP and write new one for a new test case - mustDeleteTestResources(t, clientV2, initialTrafficPerms) - initialTrafficPerms = []*pbresource.Resource{} - for _, st := range tenancies { - for _, dt := range tenancies { - for i, p := range tc.permissions { - newTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "static-server-perms" + strconv.Itoa(i) + "-" + st.Namespace + "-" + st.Partition, - Tenancy: dt, - }, - }, newTrafficPermissions(p, st)) - mustWriteTestResource(t, clientV2, newTrafficPerms) - initialTrafficPerms = append(initialTrafficPerms, newTrafficPerms) - } - } - } - t.Log(initialTrafficPerms) - // Wait for the resource updates to go through and Envoy to be ready - time.Sleep(1 * time.Second) - // Check the default server workload envoy config for RBAC filters matching testcase criteria - serverWorkload := cluster.WorkloadsByID(topology.ID{ - Partition: "default", - Namespace: "default", - Name: "static-server", - }) - asserter.AssertEnvoyHTTPrbacFiltersContainIntentions(t, serverWorkload[0]) - // Check relationships - for _, ship := range ships { - t.Run("case: "+testName+":"+ship.Destination.PortName+":("+ship.Caller.ID.Partition+"/"+ship.Caller.ID.Namespace+ - ")("+ship.Destination.ID.Partition+"/"+ship.Destination.ID.Namespace+")", func(t *testing.T) { - var ( - wrk = ship.Caller - dest = ship.Destination - ) - for _, res := range tc.result { - if res.port != "" && res.port != ship.Destination.PortName { - continue - } - dest.ID.Name = "static-server" - destClusterPrefix := clusterPrefix(dest.PortName, dest.ID, dest.Cluster) - asserter.DestinationEndpointStatus(t, wrk, destClusterPrefix+".", "HEALTHY", len(tenancies)) - status := http.StatusForbidden - if res.fail == false { - status = http.StatusOK - } - t.Log("Test request:"+res.path, res.headers, status) - asserter.FortioFetch2ServiceStatusCodes(t, wrk, dest, res.path, res.headers, []int{status}) - } - }) - } - } -} - -func mustWriteTestResource(t *testing.T, client pbresource.ResourceServiceClient, res *pbresource.Resource) { - retryer := &retry.Timer{Timeout: time.Minute, Wait: time.Second} - rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - retry.RunWith(retryer, t, func(r *retry.R) { - readRsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: rsp.Resource.Id}) - require.NoError(r, err, "error reading %s", rsp.Resource.Id.Name) - require.NotNil(r, readRsp) - }) - -} - -func mustDeleteTestResources(t *testing.T, client pbresource.ResourceServiceClient, resources []*pbresource.Resource) { - if len(resources) == 0 { - return - } - retryer := &retry.Timer{Timeout: time.Minute, Wait: time.Second} - for _, res := range resources { - retry.RunWith(retryer, t, func(r *retry.R) { - _, err := client.Delete(context.Background(), &pbresource.DeleteRequest{Id: res.Id}) - if status.Code(err) == codes.NotFound { - return - } - if err != nil && status.Code(err) != codes.Aborted { - r.Stop(fmt.Errorf("failed to delete the resource: %w", err)) - return - } - require.NoError(r, err) - }) - } -} - -type testL7TrafficPermissionsCreator struct { - tenancies []*pbresource.Tenancy -} - -func (c testL7TrafficPermissionsCreator) NewConfig(t *testing.T) *topology.Config { - const clusterName = "dc1" - - servers := topoutil.NewTopologyServerSet(clusterName+"-server", 1, []string{clusterName, "wan"}, nil) - - cluster := &topology.Cluster{ - Enterprise: utils.IsEnterprise(), - Name: clusterName, - Nodes: servers, - } - - lastNode := 0 - nodeName := func() string { - lastNode++ - return fmt.Sprintf("%s-box%d", clusterName, lastNode) - } - - for _, st := range c.tenancies { - for _, dt := range c.tenancies { - c.topologyConfigAddNodes(cluster, nodeName, st, dt) - - } - } - - return &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: clusterName}, - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - cluster, - }, - } -} - -func (c testL7TrafficPermissionsCreator) topologyConfigAddNodes( - cluster *topology.Cluster, - nodeName func() string, - sourceTenancy *pbresource.Tenancy, - destinationTenancy *pbresource.Tenancy, -) { - clusterName := cluster.Name - - newID := func(name string, tenancy *pbresource.Tenancy) topology.ID { - return topology.ID{ - Partition: tenancy.Partition, - Namespace: tenancy.Namespace, - Name: name, - } - } - - serverNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: destinationTenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("static-server", destinationTenancy), - topology.NodeVersionV2, - nil, - ), - }, - } - - clientNode := &topology.Node{ - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Partition: sourceTenancy.Partition, - Name: nodeName(), - Workloads: []*topology.Workload{ - topoutil.NewFortioWorkloadWithDefaults( - clusterName, - newID("static-client", sourceTenancy), - topology.NodeVersionV2, - func(wrk *topology.Workload) { - wrk.Destinations = append(wrk.Destinations, &topology.Destination{ - ID: newID("static-server", destinationTenancy), - PortName: "http", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5000, - }, - &topology.Destination{ - ID: newID("static-server", destinationTenancy), - PortName: "http2", - LocalAddress: "0.0.0.0", // needed for an assertion - LocalPort: 5001, - }, - ) - wrk.WorkloadIdentity = "static-client" - }, - ), - }, - } - - cluster.Nodes = append(cluster.Nodes, - clientNode, - serverNode, - ) -} diff --git a/test-integ/tenancy/client.go b/test-integ/tenancy/client.go deleted file mode 100644 index a3152b7625..0000000000 --- a/test-integ/tenancy/client.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tenancy - -import ( - "context" - "fmt" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -// This duplicates a subset of internal/resource/resourcetest/client.go so -// we're not importing consul internals integration tests. -// -// TODO: Move to a general package if used more widely. - -type ClientOption func(*Client) - -func WithACLToken(token string) ClientOption { - return func(c *Client) { - c.token = token - } -} - -// Client decorates a resource service client with helper functions to assist -// with integration testing. -type Client struct { - pbresource.ResourceServiceClient - - timeout time.Duration - wait time.Duration - token string -} - -func NewClient(client pbresource.ResourceServiceClient, opts ...ClientOption) *Client { - c := &Client{ - ResourceServiceClient: client, - timeout: 7 * time.Second, - wait: 50 * time.Millisecond, - } - - for _, opt := range opts { - opt(c) - } - - return c -} - -func NewClientWithACLToken(client pbresource.ResourceServiceClient, token string) *Client { - return NewClient(client, WithACLToken(token)) -} - -func (client *Client) SetRetryerConfig(timeout time.Duration, wait time.Duration) { - client.timeout = timeout - client.wait = wait -} - -func (client *Client) retry(t testutil.TestingTB, fn func(r *retry.R)) { - t.Helper() - retryer := &retry.Timer{Timeout: client.timeout, Wait: client.wait} - retry.RunWith(retryer, t, fn) -} - -func (client *Client) Context(t testutil.TestingTB) 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 testutil.TestingTB, id *pbresource.ID) { - t.Helper() - - rsp, err := client.Read(client.Context(t), &pbresource.ReadRequest{Id: id}) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - require.Nil(t, rsp) -} - -func (client *Client) RequireResourceExists(t testutil.TestingTB, id *pbresource.ID) *pbresource.Resource { - t.Helper() - - rsp, err := client.Read(client.Context(t), &pbresource.ReadRequest{Id: id}) - require.NoError(t, err, "error reading %s with type %s", id.Name, ToGVK(id.Type)) - require.NotNil(t, rsp) - return rsp.Resource -} - -func ToGVK(resourceType *pbresource.Type) string { - return fmt.Sprintf("%s.%s.%s", resourceType.Group, resourceType.GroupVersion, resourceType.Kind) -} - -func (client *Client) WaitForResourceExists(t testutil.TestingTB, id *pbresource.ID) *pbresource.Resource { - t.Helper() - - var res *pbresource.Resource - client.retry(t, func(r *retry.R) { - res = client.RequireResourceExists(r, id) - }) - - return res -} - -func (client *Client) WaitForDeletion(t testutil.TestingTB, id *pbresource.ID) { - t.Helper() - - client.retry(t, func(r *retry.R) { - client.RequireResourceNotFound(r, id) - }) -} - -// MustDelete will delete a resource by its id, retrying if necessary and fail the test -// if it cannot delete it within the timeout. The clients request delay settings are -// taken into account with this operation. -func (client *Client) MustDelete(t testutil.TestingTB, id *pbresource.ID) { - t.Helper() - client.retryDelete(t, id) -} - -func (client *Client) retryDelete(t testutil.TestingTB, 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/test-integ/tenancy/common.go b/test-integ/tenancy/common.go deleted file mode 100644 index 4fea2c472b..0000000000 --- a/test-integ/tenancy/common.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tenancy - -import ( - "context" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - 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" - "github.com/hashicorp/consul/test-integ/topoutil" - "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" -) - -const ( - DefaultNamespaceName = "default" - DefaultPartitionName = "default" -) - -func newConfig(t *testing.T) *topology.Config { - const clusterName = "cluster1" - servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName}, nil) - - cluster := &topology.Cluster{ - Enterprise: utils.IsEnterprise(), - Name: clusterName, - Nodes: servers, - EnableV2: true, - EnableV2Tenancy: true, - } - - return &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{{Name: clusterName}}, - Clusters: []*topology.Cluster{cluster}, - } -} - -func createNamespaces(t *testing.T, resourceServiceClient *Client, numNamespaces int, ap string) []*pbresource.Resource { - namespaces := []*pbresource.Resource{} - for i := 0; i < numNamespaces; i++ { - namespace := &pbresource.Resource{ - Id: &pbresource.ID{ - Name: fmt.Sprintf("namespace-%d", i), - Type: pbtenancy.NamespaceType, - Tenancy: &pbresource.Tenancy{Partition: ap}, - }, - } - rsp, err := resourceServiceClient.Write(context.Background(), &pbresource.WriteRequest{Resource: namespace}) - require.NoError(t, err) - namespace = resourceServiceClient.WaitForResourceExists(t, rsp.Resource.Id) - namespaces = append(namespaces, namespace) - } - return namespaces -} - -func createServices(t *testing.T, resourceServiceClient *Client, numServices int, ap string, ns string) []*pbresource.Resource { - services := []*pbresource.Resource{} - for i := 0; i < numServices; i++ { - service := &pbresource.Resource{ - Id: &pbresource.ID{ - Name: fmt.Sprintf("service-%d", i), - Type: pbcatalog.ServiceType, - Tenancy: &pbresource.Tenancy{Partition: ap, Namespace: ns}, - }, - } - service = sprawltest.MustSetResourceData(t, service, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{}, - Ports: []*pbcatalog.ServicePort{}, - }) - rsp, err := resourceServiceClient.Write(context.Background(), &pbresource.WriteRequest{Resource: service}) - require.NoError(t, err) - service = resourceServiceClient.WaitForResourceExists(t, rsp.Resource.Id) - services = append(services, service) - } - return services -} diff --git a/test-integ/tenancy/namespace_ce_test.go b/test-integ/tenancy/namespace_ce_test.go deleted file mode 100644 index 5f82436c9c..0000000000 --- a/test-integ/tenancy/namespace_ce_test.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package tenancy - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" - "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" -) - -// TestNamespaceLifecycle sets up the following: -// -// - 1 cluster -// - 3 servers in that cluster -// - v2 resources and v2 tenancy are activated -// -// When this test is executed it tests the full lifecycle for a -// small number of namespaces: -// - creation of namespaces in the default partition -// - populating resources under namespaces -// - finally deleting everything -func TestNamespaceLifecycle(t *testing.T) { - t.Parallel() - - cfg := newConfig(t) - sp := sprawltest.Launch(t, cfg) - cluster := sp.Topology().Clusters["cluster1"] - client := NewClient(sp.ResourceServiceClientForCluster(cluster.Name)) - - // 3 namespaces - // @ 3 services per namespace - // ============================== - // 9 resources total - tenants := []*pbresource.Resource{} - numNamespaces := 3 - numServices := 3 - - // Default namespace is expected to exist - // when we boostrap a cluster - client.RequireResourceExists(t, &pbresource.ID{ - Name: DefaultNamespaceName, - Type: pbtenancy.NamespaceType, - Tenancy: &pbresource.Tenancy{Partition: DefaultPartitionName}, - }) - - // Namespaces are created in default partition - namespaces := createNamespaces(t, client, numNamespaces, DefaultPartitionName) - - for _, namespace := range namespaces { - services := createServices(t, client, numServices, DefaultPartitionName, namespace.Id.Name) - tenants = append(tenants, services...) - } - - // Verify test setup - require.Equal(t, len(tenants), numNamespaces*numServices) - - // List namespaces - listRsp, err := client.List(client.Context(t), &pbresource.ListRequest{ - Type: pbtenancy.NamespaceType, - Tenancy: &pbresource.Tenancy{}, - NamePrefix: "namespace-", - }) - require.NoError(t, err) - require.Equal(t, len(namespaces), len(listRsp.Resources)) - - // Delete all namespaces - for _, namespace := range namespaces { - _, err := client.Delete(client.Context(t), &pbresource.DeleteRequest{Id: namespace.Id}) - require.NoError(t, err) - client.WaitForDeletion(t, namespace.Id) - } - - // Make sure no namespace tenants left behind - for _, tenant := range tenants { - client.RequireResourceNotFound(t, tenant.Id) - } -} diff --git a/test-integ/topoutil/fixtures.go b/test-integ/topoutil/fixtures.go index bc905392b9..aeb82a0bc9 100644 --- a/test-integ/topoutil/fixtures.go +++ b/test-integ/topoutil/fixtures.go @@ -18,6 +18,9 @@ func NewFortioWorkloadWithDefaults( nodeVersion topology.NodeVersion, mut func(*topology.Workload), ) *topology.Workload { + if nodeVersion == topology.NodeVersionV2 { + panic("v2 nodes are not supported") + } const ( httpPort = 8080 grpcPort = 8079 @@ -30,6 +33,7 @@ func NewFortioWorkloadWithDefaults( ID: sid, Image: HashicorpDockerProxy + "/fortio/fortio", EnvoyAdminPort: adminPort, + Port: httpPort, CheckTCP: "127.0.0.1:" + strconv.Itoa(httpPort), Env: []string{ "FORTIO_NAME=" + cluster + "::" + sid.String(), @@ -43,17 +47,6 @@ func NewFortioWorkloadWithDefaults( }, } - if nodeVersion == topology.NodeVersionV2 { - wrk.Ports = map[string]*topology.Port{ - "http": {Number: httpPort, Protocol: "http"}, - "http2": {Number: httpPort, Protocol: "http2"}, - "grpc": {Number: grpcPort, Protocol: "grpc"}, - "tcp": {Number: tcpPort, Protocol: "tcp"}, - } - } else { - wrk.Port = httpPort - } - if mut != nil { mut(wrk) } @@ -66,6 +59,9 @@ func NewBlankspaceWorkloadWithDefaults( nodeVersion topology.NodeVersion, mut func(*topology.Workload), ) *topology.Workload { + if nodeVersion == topology.NodeVersionV2 { + panic("v2 nodes are not supported") + } const ( httpPort = 8080 grpcPort = 8079 @@ -78,6 +74,7 @@ func NewBlankspaceWorkloadWithDefaults( ID: sid, Image: HashicorpDockerProxy + "/rboyer/blankspace", EnvoyAdminPort: adminPort, + Port: httpPort, CheckTCP: "127.0.0.1:" + strconv.Itoa(httpPort), Command: []string{ "-name", cluster + "::" + sid.String(), @@ -87,17 +84,6 @@ func NewBlankspaceWorkloadWithDefaults( }, } - if nodeVersion == topology.NodeVersionV2 { - wrk.Ports = map[string]*topology.Port{ - "http": {Number: httpPort, Protocol: "http"}, - "http2": {Number: httpPort, Protocol: "http2"}, - "grpc": {Number: grpcPort, Protocol: "grpc"}, - "tcp": {Number: tcpPort, Protocol: "tcp"}, - } - } else { - wrk.Port = httpPort - } - if mut != nil { mut(wrk) } diff --git a/test/integration/connect/envoy/main_test.go b/test/integration/connect/envoy/main_test.go index aa83bb6bbe..1c4ab75f7b 100644 --- a/test/integration/connect/envoy/main_test.go +++ b/test/integration/connect/envoy/main_test.go @@ -19,8 +19,7 @@ import ( ) var ( - flagWin = flag.Bool("win", false, "Execute tests on windows") - flagResourceAPIs = flag.Bool("enable-resource-apis", false, "Execute tests with resource apis enabled.") + flagWin = flag.Bool("win", false, "Execute tests on windows") ) func TestEnvoy(t *testing.T) { @@ -31,14 +30,7 @@ func TestEnvoy(t *testing.T) { 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") @@ -125,33 +117,6 @@ func discoverCases() ([]string, error) { 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. diff --git a/test/integration/connect/envoy/run-tests.sh b/test/integration/connect/envoy/run-tests.sh index d9de1ade91..720f6e32a2 100755 --- a/test/integration/connect/envoy/run-tests.sh +++ b/test/integration/connect/envoy/run-tests.sh @@ -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 } diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index 1c0eb3789d..4bd2e49e6b 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -40,22 +40,15 @@ require ( 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/armon/go-metrics v0.4.1 // indirect - github.com/armon/go-radix v1.0.0 // indirect - github.com/aws/aws-sdk-go v1.44.289 // indirect github.com/beorn7/perks v1.0.1 // 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/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.3.1 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/envoyproxy/go-control-plane v0.12.0 // indirect @@ -66,24 +59,16 @@ require ( github.com/google/btree v1.0.1 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/uuid v1.4.0 // indirect - github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 // indirect github.com/hashicorp/consul-server-connection-manager v0.1.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-bexpr v0.1.2 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/go-netaddrs v0.1.0 // indirect - github.com/hashicorp/go-retryablehttp v0.6.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.0 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect - github.com/hashicorp/raft v1.5.0 // indirect - github.com/hashicorp/raft-autopilot v0.1.6 // indirect - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect github.com/itchyny/timefmt-go v0.1.5 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -92,14 +77,11 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // 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/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/morikuni/aec v1.0.0 // 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 @@ -110,19 +92,11 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/sirupsen/logrus v1.9.3 // 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.opentelemetry.io/proto/otlp v1.0.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/net v0.24.0 // indirect - golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index ac8860985c..450c6765da 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -16,10 +16,7 @@ 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/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= @@ -29,33 +26,24 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 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.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/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.44.289 h1:5CVEjiHFvdiVlKPBzv0rjG4zH/21W/onT18R5AH/qx0= -github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= 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/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= 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/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/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/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= @@ -70,8 +58,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A= -github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= 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= @@ -93,7 +79,6 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fullstorydev/grpchan v1.1.1 h1:heQqIJlAv5Cnks9a70GRL2EJke6QQoUB25VGR6TZQas= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -120,35 +105,22 @@ github.com/google/go-cmp v0.4.0/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/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -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/consul-server-connection-manager v0.1.4 h1:wrcSRV6WGXFBNpNbN6XsdoGgBOyso7ZbN5VaWPEX1jY= github.com/hashicorp/consul-server-connection-manager v0.1.4/go.mod h1:LMqHkALoLP0HUQKOG21xXYr0YPUayIQIHNTlmxG100E= 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-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 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-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= -github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= -github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= 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-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= @@ -158,14 +130,11 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -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-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= @@ -176,33 +145,18 @@ github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.0 h1:Lf+9eD8m5pncvHAOCQj49GSN6aQI8XGfI5OpXNkoWaA= -github.com/hashicorp/golang-lru/v2 v2.0.0/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= 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/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= -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/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -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/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= 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/jhump/protoreflect v1.11.0 h1:bvACHUD1Ua/3VxY4aAMpItKMhhwbimlKFJKsLsVgDjU= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/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= @@ -228,7 +182,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= @@ -248,15 +201,10 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1 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 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/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/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= 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= @@ -272,8 +220,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= -github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= 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= @@ -286,7 +232,6 @@ 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/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= 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= @@ -297,7 +242,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH 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 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= @@ -308,13 +252,11 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -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= @@ -330,41 +272,23 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/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.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.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/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/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/yuin/goldmark v1.1.27/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.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= 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= @@ -380,8 +304,6 @@ golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMe 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= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= 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.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -392,7 +314,6 @@ golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-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= @@ -406,7 +327,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= @@ -422,7 +342,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.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= @@ -431,10 +350,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/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-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-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -455,7 +372,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -464,7 +380,6 @@ golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= @@ -473,13 +388,11 @@ 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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= @@ -487,7 +400,6 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -517,14 +429,12 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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-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.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/test/integration/consul-container/test/catalog/catalog_test.go b/test/integration/consul-container/test/catalog/catalog_test.go deleted file mode 100644 index 0c8e913c8f..0000000000 --- a/test/integration/consul-container/test/catalog/catalog_test.go +++ /dev/null @@ -1,43 +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" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -var ( - cli = rtest.ConfigureTestCLIFlags() -) - -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, cli.ClientOptions(t)...) - }) - - t.Run("lifecycle", func(t *testing.T) { - catalogtest.RunCatalogV2Beta1LifecycleIntegrationTest(t, client, cli.ClientOptions(t)...) - }) -} 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 ae38dffa33..0000000000 --- a/test/integration/consul-container/test/trafficpermissions/tcp_test.go +++ /dev/null @@ -1,555 +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" - - "github.com/stretchr/testify/require" - - 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" -) - -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, - }, - } - - 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, - }, - "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/upgrade/catalog/catalog_test.go b/test/integration/consul-container/test/upgrade/catalog/catalog_test.go deleted file mode 100644 index c29e4b499f..0000000000 --- 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.18.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: false, - 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) -} From 1535844c621c562d42d6f3d1de38c801b75c8ae3 Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Tue, 7 May 2024 10:30:49 -0500 Subject: [PATCH 013/185] gossip: refactor some gossip related libraries into a central place (#21036) This refactors and relocates the following packages to live under internal/gossip instead of either in the toplevel lib or agent/consul: - librtt : related to serf coordinates - libserf : random serf stuff --- agent/acl_test.go | 7 ++-- agent/agent.go | 5 +-- agent/agent_endpoint.go | 4 +-- agent/agent_test.go | 4 +-- agent/consul/catalog_endpoint_test.go | 17 +++++---- agent/consul/client.go | 8 +++-- agent/consul/client_serf.go | 2 +- agent/consul/config.go | 5 +-- agent/consul/coordinate_endpoint_test.go | 12 +++---- agent/consul/health_endpoint_test.go | 14 ++++---- agent/consul/leader_ce_test.go | 2 +- agent/consul/rtt.go | 20 +++++------ agent/consul/rtt_test.go | 20 +++++------ agent/consul/server.go | 5 +-- agent/consul/server_ce.go | 4 +-- agent/consul/server_serf.go | 3 +- agent/consul/state/coordinate.go | 6 ++-- agent/consul/state/coordinate_test.go | 17 ++++----- agent/delegate_mock_test.go | 6 ++-- agent/dns_test.go | 20 +++++------ agent/router/router.go | 4 +-- agent/router/router_test.go | 36 +++++++++---------- command/rtt/rtt.go | 7 ++-- {lib => internal/gossip/librtt}/rtt.go | 2 +- {lib => internal/gossip/librtt}/rtt_test.go | 5 +-- {lib/serf => internal/gossip/libserf}/serf.go | 2 +- 26 files changed, 123 insertions(+), 114 deletions(-) rename {lib => internal/gossip/librtt}/rtt.go (99%) rename {lib => internal/gossip/librtt}/rtt_test.go (99%) rename {lib/serf => internal/gossip/libserf}/serf.go (99%) diff --git a/agent/acl_test.go b/agent/acl_test.go index 0958db8db6..8c5eace1f1 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -11,6 +11,8 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/stretchr/testify/require" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/serf/serf" @@ -21,12 +23,11 @@ import ( "github.com/hashicorp/consul/agent/local" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/types" - - "github.com/stretchr/testify/require" ) type authzResolver func(string) (structs.ACLIdentity, acl.Authorizer, error) @@ -128,7 +129,7 @@ func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *acl. } // All of these are stubs to satisfy the interface -func (a *TestACLAgent) GetLANCoordinate() (lib.CoordinateSet, error) { +func (a *TestACLAgent) GetLANCoordinate() (librtt.CoordinateSet, error) { return nil, fmt.Errorf("Unimplemented") } func (a *TestACLAgent) Leave() error { diff --git a/agent/agent.go b/agent/agent.go index d066b4cba6..88859a7b8b 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -70,6 +70,7 @@ import ( "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api/watch" libdns "github.com/hashicorp/consul/internal/dnsutil" + "github.com/hashicorp/consul/internal/gossip/librtt" proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" "github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/lib" @@ -189,7 +190,7 @@ type delegate interface { // are ancillary members of. // // NOTE: This assumes coordinates are enabled, so check that before calling. - GetLANCoordinate() (lib.CoordinateSet, error) + GetLANCoordinate() (librtt.CoordinateSet, error) // JoinLAN is used to have Consul join the inner-DC pool The target address // should be another node inside the DC listening on the Serf LAN address @@ -2149,7 +2150,7 @@ func (a *Agent) SyncPausedCh() <-chan struct{} { // GetLANCoordinate returns the coordinates of this node in the local pools // (assumes coordinates are enabled, so check that before calling). -func (a *Agent) GetLANCoordinate() (lib.CoordinateSet, error) { +func (a *Agent) GetLANCoordinate() (librtt.CoordinateSet, error) { return a.delegate.GetLANCoordinate() } diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index 5360eafe28..996212c97e 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -31,8 +31,8 @@ import ( token_store "github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/envoyextensions/xdscommon" + "github.com/hashicorp/consul/internal/gossip/librtt" "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" @@ -82,7 +82,7 @@ func (s *HTTPHandlers) AgentSelf(resp http.ResponseWriter, req *http.Request) (i return nil, err } - var cs lib.CoordinateSet + var cs librtt.CoordinateSet if !s.agent.config.DisableCoordinates { var err error if cs, err = s.agent.GetLANCoordinate(); err != nil { diff --git a/agent/agent_test.go b/agent/agent_test.go index b448ec432a..316adeb3dd 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -58,9 +58,9 @@ 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/gossip/librtt" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/ipaddr" - "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/proto/private/pbautoconf" "github.com/hashicorp/consul/sdk/freeport" "github.com/hashicorp/consul/sdk/testutil" @@ -3954,7 +3954,7 @@ func TestAgent_GetCoordinate(t *testing.T) { coords, err := a.GetLANCoordinate() require.NoError(t, err) - expected := lib.CoordinateSet{ + expected := librtt.CoordinateSet{ "": &coordinate.Coordinate{ Error: 1.5, Height: 1e-05, diff --git a/agent/consul/catalog_endpoint_test.go b/agent/consul/catalog_endpoint_test.go index d1fb2a6e97..18827dc981 100644 --- a/agent/consul/catalog_endpoint_test.go +++ b/agent/consul/catalog_endpoint_test.go @@ -10,19 +10,18 @@ import ( "testing" "time" - "github.com/hashicorp/go-uuid" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" "github.com/hashicorp/consul-net-rpc/net/rpc" + "github.com/hashicorp/go-uuid" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/lib/stringslice" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" @@ -1234,9 +1233,9 @@ func TestCatalog_ListNodes_DistanceSort(t *testing.T) { // Set all but one of the nodes to known coordinates. updates := structs.Coordinates{ - {Node: "foo", Coord: lib.GenerateCoordinate(2 * time.Millisecond)}, - {Node: "bar", Coord: lib.GenerateCoordinate(5 * time.Millisecond)}, - {Node: "baz", Coord: lib.GenerateCoordinate(1 * time.Millisecond)}, + {Node: "foo", Coord: librtt.GenerateCoordinate(2 * time.Millisecond)}, + {Node: "bar", Coord: librtt.GenerateCoordinate(5 * time.Millisecond)}, + {Node: "baz", Coord: librtt.GenerateCoordinate(1 * time.Millisecond)}, } if err := s1.fsm.State().CoordinateBatchUpdate(5, updates); err != nil { t.Fatalf("err: %v", err) @@ -2138,9 +2137,9 @@ func TestCatalog_ListServiceNodes_DistanceSort(t *testing.T) { // Set all but one of the nodes to known coordinates. updates := structs.Coordinates{ - {Node: "foo", Coord: lib.GenerateCoordinate(2 * time.Millisecond)}, - {Node: "bar", Coord: lib.GenerateCoordinate(5 * time.Millisecond)}, - {Node: "baz", Coord: lib.GenerateCoordinate(1 * time.Millisecond)}, + {Node: "foo", Coord: librtt.GenerateCoordinate(2 * time.Millisecond)}, + {Node: "bar", Coord: librtt.GenerateCoordinate(5 * time.Millisecond)}, + {Node: "baz", Coord: librtt.GenerateCoordinate(1 * time.Millisecond)}, } if err := s1.fsm.State().CoordinateBatchUpdate(9, updates); err != nil { t.Fatalf("err: %v", err) diff --git a/agent/consul/client.go b/agent/consul/client.go index f47a2871d1..3632828794 100644 --- a/agent/consul/client.go +++ b/agent/consul/client.go @@ -14,15 +14,17 @@ import ( "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" + "golang.org/x/time/rate" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/serf/serf" - "golang.org/x/time/rate" "github.com/hashicorp/consul/acl" rpcRate "github.com/hashicorp/consul/agent/consul/rate" "github.com/hashicorp/consul/agent/pool" "github.com/hashicorp/consul/agent/router" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/proto-public/pbresource" @@ -439,13 +441,13 @@ func (c *Client) Stats() map[string]map[string]string { // are ancillary members of. // // NOTE: This assumes coordinates are enabled, so check that before calling. -func (c *Client) GetLANCoordinate() (lib.CoordinateSet, error) { +func (c *Client) GetLANCoordinate() (librtt.CoordinateSet, error) { lan, err := c.serf.GetCoordinate() if err != nil { return nil, err } - cs := lib.CoordinateSet{c.config.Segment: lan} + cs := librtt.CoordinateSet{c.config.Segment: lan} return cs, nil } diff --git a/agent/consul/client_serf.go b/agent/consul/client_serf.go index c92fdd1726..a6f479c04e 100644 --- a/agent/consul/client_serf.go +++ b/agent/consul/client_serf.go @@ -12,8 +12,8 @@ import ( "github.com/hashicorp/serf/serf" "github.com/hashicorp/consul/agent/metadata" + "github.com/hashicorp/consul/internal/gossip/libserf" "github.com/hashicorp/consul/lib" - libserf "github.com/hashicorp/consul/lib/serf" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/types" ) diff --git a/agent/consul/config.go b/agent/consul/config.go index 03fb588eb0..1cba0f4ef1 100644 --- a/agent/consul/config.go +++ b/agent/consul/config.go @@ -9,16 +9,17 @@ import ( "os" "time" + "golang.org/x/time/rate" + "github.com/hashicorp/memberlist" "github.com/hashicorp/raft" "github.com/hashicorp/serf/serf" - "golang.org/x/time/rate" "github.com/hashicorp/consul/agent/checks" consulrate "github.com/hashicorp/consul/agent/consul/rate" hcpconfig "github.com/hashicorp/consul/agent/hcp/config" "github.com/hashicorp/consul/agent/structs" - libserf "github.com/hashicorp/consul/lib/serf" + "github.com/hashicorp/consul/internal/gossip/libserf" "github.com/hashicorp/consul/tlsutil" "github.com/hashicorp/consul/types" "github.com/hashicorp/consul/version" diff --git a/agent/consul/coordinate_endpoint_test.go b/agent/consul/coordinate_endpoint_test.go index 1c693ba83b..6ca7a32595 100644 --- a/agent/consul/coordinate_endpoint_test.go +++ b/agent/consul/coordinate_endpoint_test.go @@ -12,15 +12,15 @@ import ( "testing" "time" - "github.com/hashicorp/serf/coordinate" "github.com/stretchr/testify/require" msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" "github.com/hashicorp/consul-net-rpc/net/rpc" + "github.com/hashicorp/serf/coordinate" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" ) @@ -92,13 +92,13 @@ func TestCoordinate_Update(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - require.Equal(t, lib.CoordinateSet{}, c) + require.Equal(t, librtt.CoordinateSet{}, c) _, c, err = state.Coordinate(nil, "node2", nil) if err != nil { t.Fatalf("err: %v", err) } - require.Equal(t, lib.CoordinateSet{}, c) + require.Equal(t, librtt.CoordinateSet{}, c) // Send another update for the second node. It should take precedence // since there will be two updates in the same batch. @@ -113,7 +113,7 @@ func TestCoordinate_Update(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - expected := lib.CoordinateSet{ + expected := librtt.CoordinateSet{ "": arg1.Coord, } require.Equal(t, expected, c) @@ -122,7 +122,7 @@ func TestCoordinate_Update(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - expected = lib.CoordinateSet{ + expected = librtt.CoordinateSet{ "": arg2.Coord, } require.Equal(t, expected, c) diff --git a/agent/consul/health_endpoint_test.go b/agent/consul/health_endpoint_test.go index b47159c229..07f23cc2e0 100644 --- a/agent/consul/health_endpoint_test.go +++ b/agent/consul/health_endpoint_test.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" @@ -193,8 +193,8 @@ func TestHealth_ChecksInState_DistanceSort(t *testing.T) { t.Fatalf("err: %v", err) } updates := structs.Coordinates{ - {Node: "foo", Coord: lib.GenerateCoordinate(1 * time.Millisecond)}, - {Node: "bar", Coord: lib.GenerateCoordinate(2 * time.Millisecond)}, + {Node: "foo", Coord: librtt.GenerateCoordinate(1 * time.Millisecond)}, + {Node: "bar", Coord: librtt.GenerateCoordinate(2 * time.Millisecond)}, } if err := s1.fsm.State().CoordinateBatchUpdate(3, updates); err != nil { t.Fatalf("err: %v", err) @@ -482,8 +482,8 @@ func TestHealth_ServiceChecks_DistanceSort(t *testing.T) { t.Fatalf("err: %v", err) } updates := structs.Coordinates{ - {Node: "foo", Coord: lib.GenerateCoordinate(1 * time.Millisecond)}, - {Node: "bar", Coord: lib.GenerateCoordinate(2 * time.Millisecond)}, + {Node: "foo", Coord: librtt.GenerateCoordinate(1 * time.Millisecond)}, + {Node: "bar", Coord: librtt.GenerateCoordinate(2 * time.Millisecond)}, } if err := s1.fsm.State().CoordinateBatchUpdate(3, updates); err != nil { t.Fatalf("err: %v", err) @@ -969,8 +969,8 @@ func TestHealth_ServiceNodes_DistanceSort(t *testing.T) { t.Fatalf("err: %v", err) } updates := structs.Coordinates{ - {Node: "foo", Coord: lib.GenerateCoordinate(1 * time.Millisecond)}, - {Node: "bar", Coord: lib.GenerateCoordinate(2 * time.Millisecond)}, + {Node: "foo", Coord: librtt.GenerateCoordinate(1 * time.Millisecond)}, + {Node: "bar", Coord: librtt.GenerateCoordinate(2 * time.Millisecond)}, } if err := s1.fsm.State().CoordinateBatchUpdate(3, updates); err != nil { t.Fatalf("err: %v", err) diff --git a/agent/consul/leader_ce_test.go b/agent/consul/leader_ce_test.go index 86da505c3a..79e3cbc61a 100644 --- a/agent/consul/leader_ce_test.go +++ b/agent/consul/leader_ce_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/internal/gossip/libserf" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage" - libserf "github.com/hashicorp/consul/lib/serf" "github.com/hashicorp/consul/proto-public/pbresource" pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" "github.com/hashicorp/consul/testrpc" diff --git a/agent/consul/rtt.go b/agent/consul/rtt.go index 1599301e15..ca1ebc3610 100644 --- a/agent/consul/rtt.go +++ b/agent/consul/rtt.go @@ -8,7 +8,7 @@ import ( "sort" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" ) // nodeSorter takes a list of nodes and a parallel vector of distances and @@ -21,7 +21,7 @@ type nodeSorter struct { // newNodeSorter returns a new sorter for the given source coordinate and set of // nodes. -func (s *Server) newNodeSorter(cs lib.CoordinateSet, nodes structs.Nodes) (sort.Interface, error) { +func (s *Server) newNodeSorter(cs librtt.CoordinateSet, nodes structs.Nodes) (sort.Interface, error) { state := s.fsm.State() vec := make([]float64, len(nodes)) for i, node := range nodes { @@ -30,7 +30,7 @@ func (s *Server) newNodeSorter(cs lib.CoordinateSet, nodes structs.Nodes) (sort. return nil, err } c1, c2 := cs.Intersect(other) - vec[i] = lib.ComputeDistance(c1, c2) + vec[i] = librtt.ComputeDistance(c1, c2) } return &nodeSorter{nodes, vec}, nil } @@ -61,7 +61,7 @@ type serviceNodeSorter struct { // newServiceNodeSorter returns a new sorter for the given source coordinate and // set of service nodes. -func (s *Server) newServiceNodeSorter(cs lib.CoordinateSet, nodes structs.ServiceNodes) (sort.Interface, error) { +func (s *Server) newServiceNodeSorter(cs librtt.CoordinateSet, nodes structs.ServiceNodes) (sort.Interface, error) { state := s.fsm.State() vec := make([]float64, len(nodes)) for i, node := range nodes { @@ -70,7 +70,7 @@ func (s *Server) newServiceNodeSorter(cs lib.CoordinateSet, nodes structs.Servic return nil, err } c1, c2 := cs.Intersect(other) - vec[i] = lib.ComputeDistance(c1, c2) + vec[i] = librtt.ComputeDistance(c1, c2) } return &serviceNodeSorter{nodes, vec}, nil } @@ -101,7 +101,7 @@ type healthCheckSorter struct { // newHealthCheckSorter returns a new sorter for the given source coordinate and // set of health checks with nodes. -func (s *Server) newHealthCheckSorter(cs lib.CoordinateSet, checks structs.HealthChecks) (sort.Interface, error) { +func (s *Server) newHealthCheckSorter(cs librtt.CoordinateSet, checks structs.HealthChecks) (sort.Interface, error) { state := s.fsm.State() vec := make([]float64, len(checks)) for i, check := range checks { @@ -110,7 +110,7 @@ func (s *Server) newHealthCheckSorter(cs lib.CoordinateSet, checks structs.Healt return nil, err } c1, c2 := cs.Intersect(other) - vec[i] = lib.ComputeDistance(c1, c2) + vec[i] = librtt.ComputeDistance(c1, c2) } return &healthCheckSorter{checks, vec}, nil } @@ -141,7 +141,7 @@ type checkServiceNodeSorter struct { // newCheckServiceNodeSorter returns a new sorter for the given source coordinate // and set of nodes with health checks. -func (s *Server) newCheckServiceNodeSorter(cs lib.CoordinateSet, nodes structs.CheckServiceNodes) (sort.Interface, error) { +func (s *Server) newCheckServiceNodeSorter(cs librtt.CoordinateSet, nodes structs.CheckServiceNodes) (sort.Interface, error) { state := s.fsm.State() vec := make([]float64, len(nodes)) for i, node := range nodes { @@ -150,7 +150,7 @@ func (s *Server) newCheckServiceNodeSorter(cs lib.CoordinateSet, nodes structs.C return nil, err } c1, c2 := cs.Intersect(other) - vec[i] = lib.ComputeDistance(c1, c2) + vec[i] = librtt.ComputeDistance(c1, c2) } return &checkServiceNodeSorter{nodes, vec}, nil } @@ -172,7 +172,7 @@ func (n *checkServiceNodeSorter) Less(i, j int) bool { } // newSorterByDistanceFrom returns a sorter for the given type. -func (s *Server) newSorterByDistanceFrom(cs lib.CoordinateSet, subj interface{}) (sort.Interface, error) { +func (s *Server) newSorterByDistanceFrom(cs librtt.CoordinateSet, subj interface{}) (sort.Interface, error) { switch v := subj.(type) { case structs.Nodes: return s.newNodeSorter(cs, v) diff --git a/agent/consul/rtt_test.go b/agent/consul/rtt_test.go index aeed0b66f5..1f4a19ddfe 100644 --- a/agent/consul/rtt_test.go +++ b/agent/consul/rtt_test.go @@ -10,12 +10,12 @@ import ( "testing" "time" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" - "github.com/hashicorp/consul/testrpc" - - "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" + msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" "github.com/hashicorp/consul-net-rpc/net/rpc" + + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/internal/gossip/librtt" + "github.com/hashicorp/consul/testrpc" ) // verifyNodeSort makes sure the order of the nodes in the slice is the same as @@ -98,27 +98,27 @@ func seedCoordinates(t *testing.T, codec rpc.ClientCodec, server *Server) { { Datacenter: "dc1", Node: "node1", - Coord: lib.GenerateCoordinate(10 * time.Millisecond), + Coord: librtt.GenerateCoordinate(10 * time.Millisecond), }, { Datacenter: "dc1", Node: "node2", - Coord: lib.GenerateCoordinate(2 * time.Millisecond), + Coord: librtt.GenerateCoordinate(2 * time.Millisecond), }, { Datacenter: "dc1", Node: "node3", - Coord: lib.GenerateCoordinate(1 * time.Millisecond), + Coord: librtt.GenerateCoordinate(1 * time.Millisecond), }, { Datacenter: "dc1", Node: "node4", - Coord: lib.GenerateCoordinate(8 * time.Millisecond), + Coord: librtt.GenerateCoordinate(8 * time.Millisecond), }, { Datacenter: "dc1", Node: "node5", - Coord: lib.GenerateCoordinate(3 * time.Millisecond), + Coord: librtt.GenerateCoordinate(3 * time.Millisecond), }, } diff --git a/agent/consul/server.go b/agent/consul/server.go index cdd1904130..b687c6c65d 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -66,6 +66,7 @@ import ( "github.com/hashicorp/consul/internal/auth" "github.com/hashicorp/consul/internal/catalog" "github.com/hashicorp/consul/internal/controller" + "github.com/hashicorp/consul/internal/gossip/librtt" hcpctl "github.com/hashicorp/consul/internal/hcp" "github.com/hashicorp/consul/internal/mesh" proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" @@ -1958,13 +1959,13 @@ func (s *Server) Stats() map[string]map[string]string { // are ancillary members of. // // NOTE: This assumes coordinates are enabled, so check that before calling. -func (s *Server) GetLANCoordinate() (lib.CoordinateSet, error) { +func (s *Server) GetLANCoordinate() (librtt.CoordinateSet, error) { lan, err := s.serfLAN.GetCoordinate() if err != nil { return nil, err } - cs := lib.CoordinateSet{"": lan} + cs := librtt.CoordinateSet{"": lan} if err := s.addEnterpriseLANCoordinates(cs); err != nil { return nil, err } diff --git a/agent/consul/server_ce.go b/agent/consul/server_ce.go index ac0df9dd73..b744f2ec72 100644 --- a/agent/consul/server_ce.go +++ b/agent/consul/server_ce.go @@ -20,8 +20,8 @@ import ( "github.com/hashicorp/consul/agent/consul/reporting" resourcegrpc "github.com/hashicorp/consul/agent/grpc-external/services/resource" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logging" ) @@ -117,7 +117,7 @@ func (s *Server) GetMatchingLANCoordinate(_, _ string) (*coordinate.Coordinate, return s.serfLAN.GetCoordinate() } -func (s *Server) addEnterpriseLANCoordinates(cs lib.CoordinateSet) error { +func (s *Server) addEnterpriseLANCoordinates(cs librtt.CoordinateSet) error { return nil } diff --git a/agent/consul/server_serf.go b/agent/consul/server_serf.go index aea50aa6dd..ec2ad94688 100644 --- a/agent/consul/server_serf.go +++ b/agent/consul/server_serf.go @@ -12,6 +12,7 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/memberlist" "github.com/hashicorp/raft" @@ -20,8 +21,8 @@ import ( "github.com/hashicorp/consul/agent/consul/wanfed" "github.com/hashicorp/consul/agent/metadata" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/internal/gossip/libserf" "github.com/hashicorp/consul/lib" - libserf "github.com/hashicorp/consul/lib/serf" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/types" ) diff --git a/agent/consul/state/coordinate.go b/agent/consul/state/coordinate.go index bcd71e5a0f..90983708bf 100644 --- a/agent/consul/state/coordinate.go +++ b/agent/consul/state/coordinate.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" ) const tableCoordinates = "coordinates" @@ -117,7 +117,7 @@ func (s *Restore) Coordinates(idx uint64, updates structs.Coordinates) error { // Coordinate returns a map of coordinates for the given node, indexed by // network segment. -func (s *Store) Coordinate(ws memdb.WatchSet, node string, entMeta *acl.EnterpriseMeta) (uint64, lib.CoordinateSet, error) { +func (s *Store) Coordinate(ws memdb.WatchSet, node string, entMeta *acl.EnterpriseMeta) (uint64, librtt.CoordinateSet, error) { tx := s.db.Txn(false) defer tx.Abort() @@ -137,7 +137,7 @@ func (s *Store) Coordinate(ws memdb.WatchSet, node string, entMeta *acl.Enterpri } ws.Add(iter.WatchCh()) - results := make(lib.CoordinateSet) + results := make(librtt.CoordinateSet) for raw := iter.Next(); raw != nil; raw = iter.Next() { coord := raw.(*structs.Coordinate) results[coord.Segment] = coord.Coord diff --git a/agent/consul/state/coordinate_test.go b/agent/consul/state/coordinate_test.go index dad0ce3e32..408b06e4c0 100644 --- a/agent/consul/state/coordinate_test.go +++ b/agent/consul/state/coordinate_test.go @@ -8,12 +8,13 @@ import ( "math/rand" "testing" - "github.com/hashicorp/go-memdb" - "github.com/hashicorp/serf/coordinate" "github.com/stretchr/testify/require" + "github.com/hashicorp/go-memdb" + "github.com/hashicorp/serf/coordinate" + "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/sdk/testutil" ) @@ -52,7 +53,7 @@ func TestStateStore_Coordinate_Updates(t *testing.T) { coordinateWs := memdb.NewWatchSet() _, coords, err := s.Coordinate(coordinateWs, "nope", nil) require.NoError(t, err) - require.Equal(t, lib.CoordinateSet{}, coords) + require.Equal(t, librtt.CoordinateSet{}, coords) // Make an update for nodes that don't exist and make sure they get // ignored. @@ -104,7 +105,7 @@ func TestStateStore_Coordinate_Updates(t *testing.T) { idx, coords, err := s.Coordinate(nodeWs[i], update.Node, nil) require.NoError(t, err) require.Equal(t, uint64(3), idx, "bad index") - expected := lib.CoordinateSet{ + expected := librtt.CoordinateSet{ "": update.Coord, } require.Equal(t, expected, coords) @@ -133,7 +134,7 @@ func TestStateStore_Coordinate_Updates(t *testing.T) { idx, coords, err := s.Coordinate(nil, update.Node, nil) require.NoError(t, err) require.Equal(t, uint64(4), idx, "bad index") - expected := lib.CoordinateSet{ + expected := librtt.CoordinateSet{ "": update.Coord, } require.Equal(t, expected, coords) @@ -178,7 +179,7 @@ func TestStateStore_Coordinate_Cleanup(t *testing.T) { // Make sure it's in there. _, coords, err := s.Coordinate(nil, "node1", nil) require.NoError(t, err) - expected := lib.CoordinateSet{ + expected := librtt.CoordinateSet{ "alpha": updates[0].Coord, "beta": updates[1].Coord, } @@ -190,7 +191,7 @@ func TestStateStore_Coordinate_Cleanup(t *testing.T) { // Make sure the coordinate is gone. _, coords, err = s.Coordinate(nil, "node1", nil) require.NoError(t, err) - require.Equal(t, lib.CoordinateSet{}, coords) + require.Equal(t, librtt.CoordinateSet{}, coords) // Make sure the index got updated. idx, all, err := s.Coordinates(nil, nil) diff --git a/agent/delegate_mock_test.go b/agent/delegate_mock_test.go index a75cf2d1e2..206aac9c7e 100644 --- a/agent/delegate_mock_test.go +++ b/agent/delegate_mock_test.go @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -22,9 +22,9 @@ type delegateMock struct { mock.Mock } -func (m *delegateMock) GetLANCoordinate() (lib.CoordinateSet, error) { +func (m *delegateMock) GetLANCoordinate() (librtt.CoordinateSet, error) { ret := m.Called() - return ret.Get(0).(lib.CoordinateSet), ret.Error(1) + return ret.Get(0).(librtt.CoordinateSet), ret.Error(1) } func (m *delegateMock) Leave() error { diff --git a/agent/dns_test.go b/agent/dns_test.go index 0922939ccc..c44fd2bbc2 100644 --- a/agent/dns_test.go +++ b/agent/dns_test.go @@ -16,7 +16,6 @@ import ( "context" "errors" "fmt" - "github.com/hashicorp/consul/agent/discovery" "math" "math/rand" "net" @@ -34,9 +33,10 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/agent/consul" + "github.com/hashicorp/consul/agent/discovery" dnsConsul "github.com/hashicorp/consul/agent/dns" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" ) @@ -1069,15 +1069,15 @@ func TestDNS_PreparedQueryNearIPEDNS(t *testing.T) { t.Skip("too slow for testing.Short") } - ipCoord := lib.GenerateCoordinate(1 * time.Millisecond) + ipCoord := librtt.GenerateCoordinate(1 * time.Millisecond) serviceNodes := []struct { name string address string coord *coordinate.Coordinate }{ - {"foo1", "198.18.0.1", lib.GenerateCoordinate(1 * time.Millisecond)}, - {"foo2", "198.18.0.2", lib.GenerateCoordinate(10 * time.Millisecond)}, - {"foo3", "198.18.0.3", lib.GenerateCoordinate(30 * time.Millisecond)}, + {"foo1", "198.18.0.1", librtt.GenerateCoordinate(1 * time.Millisecond)}, + {"foo2", "198.18.0.2", librtt.GenerateCoordinate(10 * time.Millisecond)}, + {"foo3", "198.18.0.3", librtt.GenerateCoordinate(30 * time.Millisecond)}, } for name, experimentsHCL := range getVersionHCL(true) { @@ -1203,15 +1203,15 @@ func TestDNS_PreparedQueryNearIP(t *testing.T) { t.Skip("too slow for testing.Short") } - ipCoord := lib.GenerateCoordinate(1 * time.Millisecond) + ipCoord := librtt.GenerateCoordinate(1 * time.Millisecond) serviceNodes := []struct { name string address string coord *coordinate.Coordinate }{ - {"foo1", "198.18.0.1", lib.GenerateCoordinate(1 * time.Millisecond)}, - {"foo2", "198.18.0.2", lib.GenerateCoordinate(10 * time.Millisecond)}, - {"foo3", "198.18.0.3", lib.GenerateCoordinate(30 * time.Millisecond)}, + {"foo1", "198.18.0.1", librtt.GenerateCoordinate(1 * time.Millisecond)}, + {"foo2", "198.18.0.2", librtt.GenerateCoordinate(10 * time.Millisecond)}, + {"foo3", "198.18.0.3", librtt.GenerateCoordinate(30 * time.Millisecond)}, } for name, experimentsHCL := range getVersionHCL(true) { diff --git a/agent/router/router.go b/agent/router/router.go index c261b6ed7c..af6b0987cf 100644 --- a/agent/router/router.go +++ b/agent/router/router.go @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/consul/agent/metadata" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/types" ) @@ -578,7 +578,7 @@ func (r *Router) GetDatacentersByDistance() ([]string, error) { // It's OK to get a nil coordinate back, ComputeDistance // will put the RTT at positive infinity. other, _ := info.cluster.GetCachedCoordinate(parts.Name) - rtt := lib.ComputeDistance(coord, other) + rtt := librtt.ComputeDistance(coord, other) index[parts.Datacenter] = append(existing, rtt) } } diff --git a/agent/router/router_test.go b/agent/router/router_test.go index 206b0befe8..452f1c5a49 100644 --- a/agent/router/router_test.go +++ b/agent/router/router_test.go @@ -12,15 +12,15 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/hashicorp/serf/coordinate" "github.com/hashicorp/serf/serf" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/types" - - "github.com/stretchr/testify/require" ) type mockCluster struct { @@ -109,12 +109,12 @@ func (m *mockCluster) AddLANMember(dc, name, role string, coord *coordinate.Coor // mysterious dcX with no nodes with known coordinates. func testCluster(self string) *mockCluster { c := newMockCluster(self) - c.AddMember("dc0", "node0", lib.GenerateCoordinate(10*time.Millisecond)) - c.AddMember("dc1", "node1", lib.GenerateCoordinate(3*time.Millisecond)) - c.AddMember("dc1", "node2", lib.GenerateCoordinate(2*time.Millisecond)) - c.AddMember("dc1", "node3", lib.GenerateCoordinate(5*time.Millisecond)) + c.AddMember("dc0", "node0", librtt.GenerateCoordinate(10*time.Millisecond)) + c.AddMember("dc1", "node1", librtt.GenerateCoordinate(3*time.Millisecond)) + c.AddMember("dc1", "node2", librtt.GenerateCoordinate(2*time.Millisecond)) + c.AddMember("dc1", "node3", librtt.GenerateCoordinate(5*time.Millisecond)) c.AddMember("dc1", "node4", nil) - c.AddMember("dc2", "node1", lib.GenerateCoordinate(8*time.Millisecond)) + c.AddMember("dc2", "node1", librtt.GenerateCoordinate(8*time.Millisecond)) c.AddMember("dcX", "node1", nil) return c } @@ -427,8 +427,8 @@ func TestRouter_GetDatacentersByDistance(t *testing.T) { // Now add another area with a closer route for dc1. otherID := types.AreaID("other") other := newMockCluster(self) - other.AddMember("dc0", "node0", lib.GenerateCoordinate(20*time.Millisecond)) - other.AddMember("dc1", "node1", lib.GenerateCoordinate(21*time.Millisecond)) + other.AddMember("dc0", "node0", librtt.GenerateCoordinate(20*time.Millisecond)) + other.AddMember("dc1", "node1", librtt.GenerateCoordinate(21*time.Millisecond)) if err := r.AddArea(otherID, other, &fauxConnPool{}); err != nil { t.Fatalf("err: %v", err) } @@ -468,7 +468,7 @@ func TestRouter_GetDatacenterMaps(t *testing.T) { Coordinates: structs.Coordinates{ &structs.Coordinate{ Node: "node0.dc0", - Coord: lib.GenerateCoordinate(10 * time.Millisecond), + Coord: librtt.GenerateCoordinate(10 * time.Millisecond), }, }, }) { @@ -481,15 +481,15 @@ func TestRouter_GetDatacenterMaps(t *testing.T) { Coordinates: structs.Coordinates{ &structs.Coordinate{ Node: "node1.dc1", - Coord: lib.GenerateCoordinate(3 * time.Millisecond), + Coord: librtt.GenerateCoordinate(3 * time.Millisecond), }, &structs.Coordinate{ Node: "node2.dc1", - Coord: lib.GenerateCoordinate(2 * time.Millisecond), + Coord: librtt.GenerateCoordinate(2 * time.Millisecond), }, &structs.Coordinate{ Node: "node3.dc1", - Coord: lib.GenerateCoordinate(5 * time.Millisecond), + Coord: librtt.GenerateCoordinate(5 * time.Millisecond), }, }, }) { @@ -502,7 +502,7 @@ func TestRouter_GetDatacenterMaps(t *testing.T) { Coordinates: structs.Coordinates{ &structs.Coordinate{ Node: "node1.dc2", - Coord: lib.GenerateCoordinate(8 * time.Millisecond), + Coord: librtt.GenerateCoordinate(8 * time.Millisecond), }, }, }) { @@ -518,9 +518,9 @@ func TestRouter_FindLANServer(t *testing.T) { r := testRouter(t, "dc0") lan := newMockCluster("node4.dc0") - lan.AddLANMember("dc0", "node0", "consul", lib.GenerateCoordinate(10*time.Millisecond)) - lan.AddLANMember("dc0", "node1", "", lib.GenerateCoordinate(20*time.Millisecond)) - lan.AddLANMember("dc0", "node2", "", lib.GenerateCoordinate(21*time.Millisecond)) + lan.AddLANMember("dc0", "node0", "consul", librtt.GenerateCoordinate(10*time.Millisecond)) + lan.AddLANMember("dc0", "node1", "", librtt.GenerateCoordinate(20*time.Millisecond)) + lan.AddLANMember("dc0", "node2", "", librtt.GenerateCoordinate(21*time.Millisecond)) require.NoError(t, r.AddArea(types.AreaLAN, lan, &fauxConnPool{})) diff --git a/command/rtt/rtt.go b/command/rtt/rtt.go index db9e3efd06..a26e2268ec 100644 --- a/command/rtt/rtt.go +++ b/command/rtt/rtt.go @@ -8,11 +8,12 @@ import ( "fmt" "strings" - "github.com/hashicorp/serf/coordinate" "github.com/mitchellh/cli" + "github.com/hashicorp/serf/coordinate" + "github.com/hashicorp/consul/command/flags" - "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/internal/gossip/librtt" ) // TODO(partitions): how will this command work when asking for RTT between a @@ -146,7 +147,7 @@ func (c *cmd) Run(args []string) int { } // Index all the coordinates by segment. - cs1, cs2 := make(lib.CoordinateSet), make(lib.CoordinateSet) + cs1, cs2 := make(librtt.CoordinateSet), make(librtt.CoordinateSet) for _, entry := range entries { if strings.EqualFold(entry.Node, nodes[0]) { cs1[entry.Segment] = entry.Coord diff --git a/lib/rtt.go b/internal/gossip/librtt/rtt.go similarity index 99% rename from lib/rtt.go rename to internal/gossip/librtt/rtt.go index d716e6fcbe..697ddf7315 100644 --- a/lib/rtt.go +++ b/internal/gossip/librtt/rtt.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 -package lib +package librtt import ( "math" diff --git a/lib/rtt_test.go b/internal/gossip/librtt/rtt_test.go similarity index 99% rename from lib/rtt_test.go rename to internal/gossip/librtt/rtt_test.go index 1e7779b9ad..206752aa79 100644 --- a/lib/rtt_test.go +++ b/internal/gossip/librtt/rtt_test.go @@ -1,15 +1,16 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 -package lib +package librtt import ( "math" "testing" "time" - "github.com/hashicorp/serf/coordinate" "github.com/stretchr/testify/require" + + "github.com/hashicorp/serf/coordinate" ) func TestRTT_ComputeDistance(t *testing.T) { diff --git a/lib/serf/serf.go b/internal/gossip/libserf/serf.go similarity index 99% rename from lib/serf/serf.go rename to internal/gossip/libserf/serf.go index 932fed427b..f5d6a90e74 100644 --- a/lib/serf/serf.go +++ b/internal/gossip/libserf/serf.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 -package serf +package libserf import ( "time" From 093618d9235a9f9a82540844bd6af0799d3bb28b Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 7 May 2024 12:02:02 -0400 Subject: [PATCH 014/185] [NET-9141] ci: skip LICENSE copy for Ent linux packages (#21060) ci: skip LICENSE copy for Ent linux packages --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b68fb9e3fd..8921557c88 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,6 +145,7 @@ jobs: go build -ldflags="$GOLDFLAGS" -o "$BIN_PATH" -trimpath -buildvcs=false - name: Copy license file + if: ${{ !endsWith(github.repository, '-enterprise') }} env: LICENSE_DIR: ".release/linux/package/usr/share/doc/${{ env.PKG_NAME }}" run: | From f51d08052b9030f51e37ec72f8998deed8b0a235 Mon Sep 17 00:00:00 2001 From: Jeanne Angeles Franco Date: Wed, 8 May 2024 10:55:28 -0700 Subject: [PATCH 015/185] Backport assistant onboarding with LTS support #9224 (#21058) * Config changes to use backport-assistant with lts support Co-authored-by: Michael Zalimeni --------- Co-authored-by: claire labry Co-authored-by: Michael Zalimeni --- .github/workflows/backport-assistant.yml | 19 +++++++++++++++++-- .release/versions.hcl | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 .release/versions.hcl diff --git a/.github/workflows/backport-assistant.yml b/.github/workflows/backport-assistant.yml index 78125b6dab..d9e3753c27 100644 --- a/.github/workflows/backport-assistant.yml +++ b/.github/workflows/backport-assistant.yml @@ -19,7 +19,7 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.3.4 + container: hashicorpdev/backport-assistant:0.4.0 steps: - name: Run Backport Assistant for release branches run: | @@ -28,10 +28,24 @@ jobs: BACKPORT_LABEL_REGEXP: "backport/(?P\\d+\\.\\d+)" BACKPORT_TARGET_TEMPLATE: "release/{{.target}}.x" GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }} + ENABLE_VERSION_MANIFESTS: true + backport-ent: + if: github.event.pull_request.merged && contains(join(github.event.pull_request.labels.*.name), 'backport/ent') + runs-on: ubuntu-latest + container: hashicorpdev/backport-assistant:0.4.0 + steps: + - name: Trigger backport for Enterprise + uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0 + with: + token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} + repository: hashicorp/consul-enterprise + event-type: ent-backport + client-payload: ${{ toJson(github.event) }} handle-failure: needs: - backport - if: always() && needs.backport.result == 'failure' + - backport-ent + if: always() && (needs.backport.result == 'failure' || needs.backport-ent.result == 'failure') runs-on: ubuntu-latest steps: - name: Comment on PR @@ -41,3 +55,4 @@ jobs: -X POST \ -d "{ \"body\": \"${github_message}\"}" \ "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${{ github.event.pull_request.number }}/comments" + diff --git a/.release/versions.hcl b/.release/versions.hcl new file mode 100644 index 0000000000..dfaabab2f2 --- /dev/null +++ b/.release/versions.hcl @@ -0,0 +1,17 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +# This manifest file describes active releases and is consumed by the backport tooling. + +schema = 1 +active_versions { + version "1.18" { + ce_active = true + lts = true + } + version "1.17" {} + version "1.16" {} + version "1.15" { + lts = true + } +} From f56405e7457ec30e00f49bcf002120d9839cf62a Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 9 May 2024 11:11:01 -0400 Subject: [PATCH 016/185] security: Upgrade Go to 1.21.10 (#21074) This resolves CVE-2024-24787 and CVE-2024-24788. --- .changelog/21074.txt | 5 +++++ .go-version | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changelog/21074.txt diff --git a/.changelog/21074.txt b/.changelog/21074.txt new file mode 100644 index 0000000000..9b2bd21f42 --- /dev/null +++ b/.changelog/21074.txt @@ -0,0 +1,5 @@ +```release-note:security +Upgrade Go to use 1.21.10. This addresses CVEs +[CVE-2024-24787](https://nvd.nist.gov/vuln/detail/CVE-2024-24787) and +[CVE-2024-24788](https://nvd.nist.gov/vuln/detail/CVE-2024-24788) +``` diff --git a/.go-version b/.go-version index f124bfa155..ae7bbdf047 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.21.9 +1.21.10 From 8d4525ae50a838c8c9e94b5db25bdea19afdeb7c Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 9 May 2024 14:29:18 -0400 Subject: [PATCH 017/185] doc: add clarifying note to versions.hcl (#21071) Make it obvious that this file is only consumed from the default branch. --- .release/versions.hcl | 1 + 1 file changed, 1 insertion(+) diff --git a/.release/versions.hcl b/.release/versions.hcl index dfaabab2f2..abdd7f3342 100644 --- a/.release/versions.hcl +++ b/.release/versions.hcl @@ -2,6 +2,7 @@ # SPDX-License-Identifier: BUSL-1.1 # This manifest file describes active releases and is consumed by the backport tooling. +# It is only consumed from the default branch, so backporting changes to this file is not necessary. schema = 1 active_versions { From 17df32e5cb68dddd160bdf7796de8b0c1c1e766f Mon Sep 17 00:00:00 2001 From: John Murret Date: Thu, 9 May 2024 12:55:13 -0600 Subject: [PATCH 018/185] NET-9084 - add tests to peering endpoint and blockingquery package to assert blocking works properly. (#21078) --- agent/blockingquery/blockingquery.go | 6 + agent/blockingquery/blockingquery_test.go | 337 ++++++++++++++++++++- agent/blockingquery/mock_FSMServer.go | 122 ++++++++ agent/blockingquery/mock_RequestOptions.go | 94 ++++++ agent/blockingquery/mock_ResponseMeta.go | 62 ++++ agent/consul/rpc_test.go | 216 +------------ agent/peering_endpoint_test.go | 41 +++ 7 files changed, 662 insertions(+), 216 deletions(-) create mode 100644 agent/blockingquery/mock_FSMServer.go create mode 100644 agent/blockingquery/mock_RequestOptions.go create mode 100644 agent/blockingquery/mock_ResponseMeta.go diff --git a/agent/blockingquery/blockingquery.go b/agent/blockingquery/blockingquery.go index 3e073a1ffa..32f170cc1c 100644 --- a/agent/blockingquery/blockingquery.go +++ b/agent/blockingquery/blockingquery.go @@ -28,6 +28,8 @@ type QueryFn func(memdb.WatchSet, *state.Store) error // RequestOptions are options used by Server.blockingQuery to modify the // behaviour of the query operation, or to populate response metadata. +// +//go:generate mockery --name RequestOptions --inpackage type RequestOptions interface { GetToken() string GetMinQueryIndex() uint64 @@ -37,6 +39,8 @@ type RequestOptions interface { // ResponseMeta is an interface used to populate the response struct // with metadata about the query and the state of the server. +// +//go:generate mockery --name ResponseMeta --inpackage type ResponseMeta interface { SetLastContact(time.Duration) SetKnownLeader(bool) @@ -47,6 +51,8 @@ type ResponseMeta interface { // FSMServer is interface into the stateful components of a Consul server, such // as memdb or raft leadership. +// +//go:generate mockery --name FSMServer --inpackage type FSMServer interface { ConsistentRead() error DecrementBlockingQueries() uint64 diff --git a/agent/blockingquery/blockingquery_test.go b/agent/blockingquery/blockingquery_test.go index 5861ed3991..494cc41b42 100644 --- a/agent/blockingquery/blockingquery_test.go +++ b/agent/blockingquery/blockingquery_test.go @@ -3,5 +3,338 @@ package blockingquery -// TODO: move tests from the consul package, rpc_test.go, TestServer_blockingQuery -// here using mock for FSMServer w/ structs.QueryOptions and structs.QueryOptions +import ( + "fmt" + "github.com/hashicorp/consul/agent/consul/state" + "github.com/hashicorp/go-memdb" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "testing" + "time" +) + +func TestServer_blockingQuery(t *testing.T) { + t.Parallel() + getFSM := func(t *testing.T, additionalCfgFunc func(mockFSM *MockFSMServer)) *MockFSMServer { + fsm := NewMockFSMServer(t) + testCh := make(chan struct{}) + tombstoneGC, err := state.NewTombstoneGC(time.Second, time.Second) + require.NoError(t, err) + store := state.NewStateStore(tombstoneGC) + fsm.On("GetShutdownChannel").Return(testCh) + fsm.On("GetState").Return(store) + fsm.On("SetQueryMeta", mock.Anything, mock.Anything).Return(nil) + if additionalCfgFunc != nil { + additionalCfgFunc(fsm) + } + return fsm + } + + getOpts := func(t *testing.T, additionalCfgFunc func(options *MockRequestOptions)) *MockRequestOptions { + requestOpts := NewMockRequestOptions(t) + requestOpts.On("GetRequireConsistent").Return(false) + requestOpts.On("GetToken").Return("fake-token") + if additionalCfgFunc != nil { + additionalCfgFunc(requestOpts) + } + return requestOpts + } + + getMeta := func(t *testing.T, additionalCfgFunc func(mockMeta *MockResponseMeta)) *MockResponseMeta { + meta := NewMockResponseMeta(t) + if additionalCfgFunc != nil { + additionalCfgFunc(meta) + } + return meta + } + + // Perform a non-blocking query. Note that it's significant that the meta has + // a zero index in response - the implied opts.MinQueryIndex is also zero but + // this should not block still. + t.Run("non-blocking query", func(t *testing.T) { + var calls int + fn := func(_ memdb.WatchSet, _ *state.Store) error { + calls++ + return nil + } + err := Query(getFSM(t, nil), getOpts(t, func(mockOpts *MockRequestOptions) { + mockOpts.On("GetMinQueryIndex").Return(uint64(0)) + }), getMeta(t, nil), fn) + require.NoError(t, err) + require.Equal(t, 1, calls) + }) + + // Perform a blocking query that gets woken up and loops around once. + t.Run("blocking query - single loop", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(1)) + options.On("GetMaxQueryTime").Return(1*time.Second, nil) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(1)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + + var calls int + fn := func(ws memdb.WatchSet, _ *state.Store) error { + if calls == 0 { + meta.On("GetIndex").Return(uint64(3)) + + fakeCh := make(chan struct{}) + close(fakeCh) + ws.Add(fakeCh) + } else { + meta.On("GetIndex").Return(uint64(4)) + } + calls++ + return nil + } + err := Query(fsm, opts, meta, fn) + require.NoError(t, err) + require.Equal(t, 2, calls) + }) + + // Perform a blocking query that returns a zero index from blocking func (e.g. + // no state yet). This should still return an empty response immediately, but + // with index of 1 and then block on the next attempt. In one sense zero index + // is not really a valid response from a state method that is not an error but + // in practice a lot of state store operations do return it unless they + // explicitly special checks to turn 0 into 1. Often this is not caught or + // covered by tests but eventually when hit in the wild causes blocking + // clients to busy loop and burn CPU. This test ensure that blockingQuery + // systematically does the right thing to prevent future bugs like that. + t.Run("blocking query with 0 modifyIndex from state func", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(0)) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(1)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + var calls int + fn := func(ws memdb.WatchSet, _ *state.Store) error { + if opts.GetMinQueryIndex() > 0 { + // If client requested blocking, block forever. This is simulating + // waiting for the watched resource to be initialized/written to giving + // it a non-zero index. Note the timeout on the query options is relied + // on to stop the test taking forever. + fakeCh := make(chan struct{}) + ws.Add(fakeCh) + } + meta.On("GetIndex").Return(uint64(0)) + calls++ + return nil + } + err := Query(fsm, opts, meta, fn) + require.NoError(t, err) + require.Equal(t, 1, calls) + require.Equal(t, uint64(1), meta.GetIndex(), + "expect fake index of 1 to force client to block on next update") + + // Simulate client making next request + opts = getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(1)) + options.On("GetMaxQueryTime").Return(20*time.Millisecond, nil) + }) + + // This time we should block even though the func returns index 0 still + t0 := time.Now() + require.NoError(t, Query(fsm, opts, meta, fn)) + t1 := time.Now() + require.Equal(t, 2, calls) + require.Equal(t, uint64(1), meta.GetIndex(), + "expect fake index of 1 to force client to block on next update") + require.True(t, t1.Sub(t0) > 20*time.Millisecond, + "should have actually blocked waiting for timeout") + + }) + + // Perform a query that blocks and gets interrupted when the state store + // is abandoned. + t.Run("blocking query interrupted by abandonCh", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(3)) + options.On("GetMaxQueryTime").Return(20*time.Millisecond, nil) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(1)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + + var calls int + fn := func(_ memdb.WatchSet, _ *state.Store) error { + if calls == 0 { + meta.On("GetIndex").Return(uint64(1)) + + fsm.GetState().Abandon() + } + calls++ + return nil + } + err := Query(fsm, opts, meta, fn) + require.NoError(t, err) + require.Equal(t, 1, calls) + }) + + t.Run("non-blocking query for item that does not exist", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(3)) + options.On("GetMaxQueryTime").Return(20*time.Millisecond, nil) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(1)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + calls := 0 + fn := func(_ memdb.WatchSet, _ *state.Store) error { + calls++ + return ErrNotFound + } + + err := Query(fsm, opts, meta, fn) + require.NoError(t, err) + require.Equal(t, 1, calls) + }) + + t.Run("blocking query for item that does not exist", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(3)) + options.On("GetMaxQueryTime").Return(100*time.Millisecond, nil) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(1)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + calls := 0 + fn := func(ws memdb.WatchSet, _ *state.Store) error { + calls++ + if calls == 1 { + meta.On("GetIndex").Return(uint64(3)) + + ch := make(chan struct{}) + close(ch) + ws.Add(ch) + return ErrNotFound + } + meta.On("GetIndex").Return(uint64(5)) + return ErrNotFound + } + + err := Query(fsm, opts, meta, fn) + require.NoError(t, err) + require.Equal(t, 2, calls) + }) + + t.Run("blocking query for item that existed and is removed", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(3)) + // this query taks 1.002 sceonds locally so setting the timeout to 2 seconds + options.On("GetMaxQueryTime").Return(2*time.Second, nil) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(3)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + calls := 0 + fn := func(ws memdb.WatchSet, _ *state.Store) error { + calls++ + if calls == 1 { + + ch := make(chan struct{}) + close(ch) + ws.Add(ch) + return nil + } + meta = getMeta(t, func(mockMeta *MockResponseMeta) { + meta.On("GetIndex").Return(uint64(5)) + }) + return ErrNotFound + } + + start := time.Now() + require.NoError(t, Query(fsm, opts, meta, fn)) + queryDuration := time.Since(start) + maxQueryDuration, err := opts.GetMaxQueryTime() + require.NoError(t, err) + require.True(t, queryDuration < maxQueryDuration, fmt.Sprintf("query timed out - queryDuration: %v, maxQueryDuration: %v", queryDuration, maxQueryDuration)) + require.NoError(t, err) + require.Equal(t, 2, calls) + }) + + t.Run("blocking query for non-existent item that is created", func(t *testing.T) { + opts := getOpts(t, func(options *MockRequestOptions) { + options.On("GetMinQueryIndex").Return(uint64(3)) + // this query taks 1.002 sceonds locally so setting the timeout to 2 seconds + options.On("GetMaxQueryTime").Return(2*time.Second, nil) + }) + + meta := getMeta(t, func(mockMeta *MockResponseMeta) { + mockMeta.On("GetIndex").Return(uint64(3)) + }) + + fsm := getFSM(t, func(mockFSM *MockFSMServer) { + mockFSM.On("RPCQueryTimeout", mock.Anything).Return(1 * time.Second) + mockFSM.On("IncrementBlockingQueries").Return(uint64(1)) + mockFSM.On("DecrementBlockingQueries").Return(uint64(1)) + }) + calls := 0 + fn := func(ws memdb.WatchSet, _ *state.Store) error { + calls++ + if calls == 1 { + ch := make(chan struct{}) + close(ch) + ws.Add(ch) + return ErrNotFound + } + meta = getMeta(t, func(mockMeta *MockResponseMeta) { + meta.On("GetIndex").Return(uint64(5)) + }) + return nil + } + + start := time.Now() + require.NoError(t, Query(fsm, opts, meta, fn)) + queryDuration := time.Since(start) + maxQueryDuration, err := opts.GetMaxQueryTime() + require.NoError(t, err) + require.True(t, queryDuration < maxQueryDuration, fmt.Sprintf("query timed out - queryDuration: %v, maxQueryDuration: %v", queryDuration, maxQueryDuration)) + require.NoError(t, err) + require.Equal(t, 2, calls) + }) +} diff --git a/agent/blockingquery/mock_FSMServer.go b/agent/blockingquery/mock_FSMServer.go new file mode 100644 index 0000000000..1e62f391b8 --- /dev/null +++ b/agent/blockingquery/mock_FSMServer.go @@ -0,0 +1,122 @@ +// Code generated by mockery v2.32.4. DO NOT EDIT. + +package blockingquery + +import ( + time "time" + + state "github.com/hashicorp/consul/agent/consul/state" + mock "github.com/stretchr/testify/mock" +) + +// MockFSMServer is an autogenerated mock type for the FSMServer type +type MockFSMServer struct { + mock.Mock +} + +// ConsistentRead provides a mock function with given fields: +func (_m *MockFSMServer) ConsistentRead() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DecrementBlockingQueries provides a mock function with given fields: +func (_m *MockFSMServer) DecrementBlockingQueries() uint64 { + ret := _m.Called() + + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint64) + } + + return r0 +} + +// GetShutdownChannel provides a mock function with given fields: +func (_m *MockFSMServer) GetShutdownChannel() chan struct{} { + ret := _m.Called() + + var r0 chan struct{} + if rf, ok := ret.Get(0).(func() chan struct{}); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(chan struct{}) + } + } + + return r0 +} + +// GetState provides a mock function with given fields: +func (_m *MockFSMServer) GetState() *state.Store { + ret := _m.Called() + + var r0 *state.Store + if rf, ok := ret.Get(0).(func() *state.Store); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.Store) + } + } + + return r0 +} + +// IncrementBlockingQueries provides a mock function with given fields: +func (_m *MockFSMServer) IncrementBlockingQueries() uint64 { + ret := _m.Called() + + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint64) + } + + return r0 +} + +// RPCQueryTimeout provides a mock function with given fields: _a0 +func (_m *MockFSMServer) RPCQueryTimeout(_a0 time.Duration) time.Duration { + ret := _m.Called(_a0) + + var r0 time.Duration + if rf, ok := ret.Get(0).(func(time.Duration) time.Duration); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(time.Duration) + } + + return r0 +} + +// SetQueryMeta provides a mock function with given fields: _a0, _a1 +func (_m *MockFSMServer) SetQueryMeta(_a0 ResponseMeta, _a1 string) { + _m.Called(_a0, _a1) +} + +// NewMockFSMServer creates a new instance of MockFSMServer. 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 NewMockFSMServer(t interface { + mock.TestingT + Cleanup(func()) +}) *MockFSMServer { + mock := &MockFSMServer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/agent/blockingquery/mock_RequestOptions.go b/agent/blockingquery/mock_RequestOptions.go new file mode 100644 index 0000000000..7e57c86b36 --- /dev/null +++ b/agent/blockingquery/mock_RequestOptions.go @@ -0,0 +1,94 @@ +// Code generated by mockery v2.32.4. DO NOT EDIT. + +package blockingquery + +import ( + time "time" + + mock "github.com/stretchr/testify/mock" +) + +// MockRequestOptions is an autogenerated mock type for the RequestOptions type +type MockRequestOptions struct { + mock.Mock +} + +// GetMaxQueryTime provides a mock function with given fields: +func (_m *MockRequestOptions) GetMaxQueryTime() (time.Duration, error) { + ret := _m.Called() + + var r0 time.Duration + var r1 error + if rf, ok := ret.Get(0).(func() (time.Duration, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() time.Duration); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(time.Duration) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetMinQueryIndex provides a mock function with given fields: +func (_m *MockRequestOptions) GetMinQueryIndex() uint64 { + ret := _m.Called() + + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint64) + } + + return r0 +} + +// GetRequireConsistent provides a mock function with given fields: +func (_m *MockRequestOptions) GetRequireConsistent() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// GetToken provides a mock function with given fields: +func (_m *MockRequestOptions) GetToken() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// NewMockRequestOptions creates a new instance of MockRequestOptions. 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 NewMockRequestOptions(t interface { + mock.TestingT + Cleanup(func()) +}) *MockRequestOptions { + mock := &MockRequestOptions{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/agent/blockingquery/mock_ResponseMeta.go b/agent/blockingquery/mock_ResponseMeta.go new file mode 100644 index 0000000000..c038b4bcd5 --- /dev/null +++ b/agent/blockingquery/mock_ResponseMeta.go @@ -0,0 +1,62 @@ +// Code generated by mockery v2.32.4. DO NOT EDIT. + +package blockingquery + +import ( + time "time" + + mock "github.com/stretchr/testify/mock" +) + +// MockResponseMeta is an autogenerated mock type for the ResponseMeta type +type MockResponseMeta struct { + mock.Mock +} + +// GetIndex provides a mock function with given fields: +func (_m *MockResponseMeta) GetIndex() uint64 { + ret := _m.Called() + + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint64) + } + + return r0 +} + +// SetIndex provides a mock function with given fields: _a0 +func (_m *MockResponseMeta) SetIndex(_a0 uint64) { + _m.Called(_a0) +} + +// SetKnownLeader provides a mock function with given fields: _a0 +func (_m *MockResponseMeta) SetKnownLeader(_a0 bool) { + _m.Called(_a0) +} + +// SetLastContact provides a mock function with given fields: _a0 +func (_m *MockResponseMeta) SetLastContact(_a0 time.Duration) { + _m.Called(_a0) +} + +// SetResultsFilteredByACLs provides a mock function with given fields: _a0 +func (_m *MockResponseMeta) SetResultsFilteredByACLs(_a0 bool) { + _m.Called(_a0) +} + +// NewMockResponseMeta creates a new instance of MockResponseMeta. 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 NewMockResponseMeta(t interface { + mock.TestingT + Cleanup(func()) +}) *MockResponseMeta { + mock := &MockResponseMeta{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/agent/consul/rpc_test.go b/agent/consul/rpc_test.go index 39351c98ca..11dbeef5db 100644 --- a/agent/consul/rpc_test.go +++ b/agent/consul/rpc_test.go @@ -24,7 +24,6 @@ import ( "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-memdb" "github.com/hashicorp/raft" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc" @@ -232,136 +231,12 @@ func (m *MockSink) Close() error { return nil } +// TestServer_blockingQuery tests authenticated and unauthenticated calls. The +// other blocking query tests reside in blockingquery_test.go in the blockingquery package. func TestServer_blockingQuery(t *testing.T) { t.Parallel() _, s := testServerWithConfig(t) - // Perform a non-blocking query. Note that it's significant that the meta has - // a zero index in response - the implied opts.MinQueryIndex is also zero but - // this should not block still. - t.Run("non-blocking query", func(t *testing.T) { - var opts structs.QueryOptions - var meta structs.QueryMeta - var calls int - fn := func(_ memdb.WatchSet, _ *state.Store) error { - calls++ - return nil - } - err := s.blockingQuery(&opts, &meta, fn) - require.NoError(t, err) - require.Equal(t, 1, calls) - }) - - // Perform a blocking query that gets woken up and loops around once. - t.Run("blocking query - single loop", func(t *testing.T) { - opts := structs.QueryOptions{ - MinQueryIndex: 3, - } - var meta structs.QueryMeta - var calls int - fn := func(ws memdb.WatchSet, _ *state.Store) error { - if calls == 0 { - meta.Index = 3 - - fakeCh := make(chan struct{}) - close(fakeCh) - ws.Add(fakeCh) - } else { - meta.Index = 4 - } - calls++ - return nil - } - err := s.blockingQuery(&opts, &meta, fn) - require.NoError(t, err) - require.Equal(t, 2, calls) - }) - - // Perform a blocking query that returns a zero index from blocking func (e.g. - // no state yet). This should still return an empty response immediately, but - // with index of 1 and then block on the next attempt. In one sense zero index - // is not really a valid response from a state method that is not an error but - // in practice a lot of state store operations do return it unless they - // explicitly special checks to turn 0 into 1. Often this is not caught or - // covered by tests but eventually when hit in the wild causes blocking - // clients to busy loop and burn CPU. This test ensure that blockingQuery - // systematically does the right thing to prevent future bugs like that. - t.Run("blocking query with 0 modifyIndex from state func", func(t *testing.T) { - opts := structs.QueryOptions{ - MinQueryIndex: 0, - } - var meta structs.QueryMeta - var calls int - fn := func(ws memdb.WatchSet, _ *state.Store) error { - if opts.MinQueryIndex > 0 { - // If client requested blocking, block forever. This is simulating - // waiting for the watched resource to be initialized/written to giving - // it a non-zero index. Note the timeout on the query options is relied - // on to stop the test taking forever. - fakeCh := make(chan struct{}) - ws.Add(fakeCh) - } - meta.Index = 0 - calls++ - return nil - } - require.NoError(t, s.blockingQuery(&opts, &meta, fn)) - assert.Equal(t, 1, calls) - assert.Equal(t, uint64(1), meta.Index, - "expect fake index of 1 to force client to block on next update") - - // Simulate client making next request - opts.MinQueryIndex = 1 - opts.MaxQueryTime = 20 * time.Millisecond // Don't wait too long - - // This time we should block even though the func returns index 0 still - t0 := time.Now() - require.NoError(t, s.blockingQuery(&opts, &meta, fn)) - t1 := time.Now() - assert.Equal(t, 2, calls) - assert.Equal(t, uint64(1), meta.Index, - "expect fake index of 1 to force client to block on next update") - assert.True(t, t1.Sub(t0) > 20*time.Millisecond, - "should have actually blocked waiting for timeout") - - }) - - // Perform a query that blocks and gets interrupted when the state store - // is abandoned. - t.Run("blocking query interrupted by abandonCh", func(t *testing.T) { - opts := structs.QueryOptions{ - MinQueryIndex: 3, - } - var meta structs.QueryMeta - var calls int - fn := func(_ memdb.WatchSet, _ *state.Store) error { - if calls == 0 { - meta.Index = 3 - - snap, err := s.fsm.Snapshot() - if err != nil { - t.Fatalf("err: %v", err) - } - defer snap.Release() - - buf := bytes.NewBuffer(nil) - sink := &MockSink{buf, false} - if err := snap.Persist(sink); err != nil { - t.Fatalf("err: %v", err) - } - - if err := s.fsm.Restore(sink); err != nil { - t.Fatalf("err: %v", err) - } - } - calls++ - return nil - } - err := s.blockingQuery(&opts, &meta, fn) - require.NoError(t, err) - require.Equal(t, 1, calls) - }) - t.Run("ResultsFilteredByACLs is reset for unauthenticated calls", func(t *testing.T) { opts := structs.QueryOptions{ Token: "", @@ -394,93 +269,6 @@ func TestServer_blockingQuery(t *testing.T) { require.NoError(t, err) require.True(t, meta.ResultsFilteredByACLs, "ResultsFilteredByACLs should be honored for authenticated calls") }) - - t.Run("non-blocking query for item that does not exist", func(t *testing.T) { - opts := structs.QueryOptions{} - meta := structs.QueryMeta{} - calls := 0 - fn := func(_ memdb.WatchSet, _ *state.Store) error { - calls++ - return errNotFound - } - - err := s.blockingQuery(&opts, &meta, fn) - require.NoError(t, err) - require.Equal(t, 1, calls) - }) - - t.Run("blocking query for item that does not exist", func(t *testing.T) { - opts := structs.QueryOptions{MinQueryIndex: 3, MaxQueryTime: 100 * time.Millisecond} - meta := structs.QueryMeta{} - calls := 0 - fn := func(ws memdb.WatchSet, _ *state.Store) error { - calls++ - if calls == 1 { - meta.Index = 3 - - ch := make(chan struct{}) - close(ch) - ws.Add(ch) - return errNotFound - } - meta.Index = 5 - return errNotFound - } - - err := s.blockingQuery(&opts, &meta, fn) - require.NoError(t, err) - require.Equal(t, 2, calls) - }) - - t.Run("blocking query for item that existed and is removed", func(t *testing.T) { - opts := structs.QueryOptions{MinQueryIndex: 3, MaxQueryTime: 100 * time.Millisecond} - meta := structs.QueryMeta{} - calls := 0 - fn := func(ws memdb.WatchSet, _ *state.Store) error { - calls++ - if calls == 1 { - meta.Index = 3 - - ch := make(chan struct{}) - close(ch) - ws.Add(ch) - return nil - } - meta.Index = 5 - return errNotFound - } - - start := time.Now() - err := s.blockingQuery(&opts, &meta, fn) - require.True(t, time.Since(start) < opts.MaxQueryTime, "query timed out") - require.NoError(t, err) - require.Equal(t, 2, calls) - }) - - t.Run("blocking query for non-existent item that is created", func(t *testing.T) { - opts := structs.QueryOptions{MinQueryIndex: 3, MaxQueryTime: 100 * time.Millisecond} - meta := structs.QueryMeta{} - calls := 0 - fn := func(ws memdb.WatchSet, _ *state.Store) error { - calls++ - if calls == 1 { - meta.Index = 3 - - ch := make(chan struct{}) - close(ch) - ws.Add(ch) - return errNotFound - } - meta.Index = 5 - return nil - } - - start := time.Now() - err := s.blockingQuery(&opts, &meta, fn) - require.True(t, time.Since(start) < opts.MaxQueryTime, "query timed out") - require.NoError(t, err) - require.Equal(t, 2, calls) - }) } func TestRPC_ReadyForConsistentReads(t *testing.T) { diff --git a/agent/peering_endpoint_test.go b/agent/peering_endpoint_test.go index ba3b704b8b..925033f334 100644 --- a/agent/peering_endpoint_test.go +++ b/agent/peering_endpoint_test.go @@ -556,6 +556,8 @@ func TestHTTP_Peering_Read(t *testing.T) { _, err = a.rpcClientPeering.PeeringWrite(ctx, bar) require.NoError(t, err) + var lastIndex uint64 + t.Run("return foo", func(t *testing.T) { req, err := http.NewRequest("GET", "/v1/peering/foo", nil) require.NoError(t, err) @@ -578,6 +580,8 @@ func TestHTTP_Peering_Read(t *testing.T) { require.Equal(t, 0, len(apiResp.StreamStatus.ImportedServices)) require.Equal(t, 0, len(apiResp.StreamStatus.ExportedServices)) + + lastIndex = getIndex(t, resp) }) t.Run("not found", func(t *testing.T) { @@ -588,6 +592,43 @@ func TestHTTP_Peering_Read(t *testing.T) { require.Equal(t, http.StatusNotFound, resp.Code) require.Equal(t, "Peering not found for \"baz\"", resp.Body.String()) }) + + const timeout = 5 * time.Second + t.Run("read blocking query result", func(t *testing.T) { + var ( + // out and resp are not safe to read until reading from errCh + out api.Peering + resp = httptest.NewRecorder() + errCh = make(chan error, 1) + ) + go func() { + url := fmt.Sprintf("/v1/peering/foo?index=%d&wait=%s", lastIndex, timeout) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + errCh <- err + return + } + + a.srv.h.ServeHTTP(resp, req) + require.Equal(t, http.StatusOK, resp.Code) + err = json.NewDecoder(resp.Body).Decode(&out) + errCh <- err + }() + + time.Sleep(200 * time.Millisecond) + + // update peering + foo.Peering.Meta["spooky-key"] = "boo!" + _, err = a.rpcClientPeering.PeeringWrite(ctx, foo) + require.NoError(t, err) + + if err := <-errCh; err != nil { + require.NoError(t, err) + } + + require.Equal(t, "boo!", out.Meta["spooky-key"]) + require.Equal(t, "blocking-query", resp.Header().Get("X-Consul-Query-Backend")) + }) } func TestHTTP_Peering_Delete(t *testing.T) { From dc19ce36ef190507e47833fbdc12e37f86f39a98 Mon Sep 17 00:00:00 2001 From: John Murret Date: Fri, 10 May 2024 09:17:56 -0600 Subject: [PATCH 019/185] NET-9143 - sameness group queries in DNS do not respect DefaultForFailover setting and always assume failover behavior (#21029) * NET-9143 - sameness group queries in DNS do not respect DefaultForFailover setting and always assume failover behavior * update config entry docs for sameness groups * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- .../docs/connect/config-entries/sameness-group.mdx | 2 ++ .../transparent-proxy/enable-transparent-proxy.mdx | 8 ++++---- .../docs/services/discovery/dns-static-lookups.mdx | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/website/content/docs/connect/config-entries/sameness-group.mdx b/website/content/docs/connect/config-entries/sameness-group.mdx index 6e3b248bdc..e74c513fcb 100644 --- a/website/content/docs/connect/config-entries/sameness-group.mdx +++ b/website/content/docs/connect/config-entries/sameness-group.mdx @@ -152,6 +152,8 @@ When this field is set to `true`, upstream requests automatically fail over to s When this field is set to `false`, you can use a sameness group for failover by configuring the `Failover` block of a [service resolver configuration entry](/consul/docs/connect/config-entries/service-resolver). +When you [query Consul DNS](/consul/docs/services/discovery/dns-static-lookups) using sameness groups, `DefaultForFailover` must be set to `true`. Otherwise, Consul DNS returns an error. + #### Values - Default: `false` diff --git a/website/content/docs/k8s/connect/transparent-proxy/enable-transparent-proxy.mdx b/website/content/docs/k8s/connect/transparent-proxy/enable-transparent-proxy.mdx index b2cc5dac0b..ce3df409eb 100644 --- a/website/content/docs/k8s/connect/transparent-proxy/enable-transparent-proxy.mdx +++ b/website/content/docs/k8s/connect/transparent-proxy/enable-transparent-proxy.mdx @@ -16,7 +16,7 @@ Your network must meet the following environment and software requirements to us * Transparent proxy is available for Kubernetes environments. * Consul 1.10.0+ * Consul Helm chart 0.32.0+. If you want to use the Consul CNI plugin to redirect traffic, Helm chart 0.48.0+ is required. Refer to [Enable the Consul CNI plugin](#enable-the-consul-cni-plugin) for additional information. -* You must create [service intentions](/consul/docs/connect/intentions) that explicitly allow communication between intended services so that Consul can infer upstream connections and use sidecar proxies to route messages appropriately. +* You must create [service intentions](/consul/docs/connect/intentions) that explicitly allow communication between services. Consul uses service intentions to infer upstream connections and route messages appropriately between sidecar proxies. * The `ip_tables` kernel module must be running on all worker nodes within a Kubernetes cluster. If you are using the `modprobe` Linux utility, for example, issue the following command: `$ modprobe ip_tables` @@ -25,7 +25,7 @@ Your network must meet the following environment and software requirements to us ## Enable transparent proxy -Transparent proxy mode is enabled for the entire cluster by default when you install Consul on Kubernetes using the Consul Helm chart. Refer to the [Consul Helm chart reference](/consul/docs/k8s/helm) for information about all default configurations. +Transparent proxy mode is enabled for the entire cluster by default when you install Consul on Kubernetes using the Consul Helm chart. Refer to the [Consul Helm chart reference](/consul/docs/k8s/helm) for information about all default configurations. You can explicitly enable transparent proxy for the entire cluster, individual namespaces, and individual services. @@ -242,7 +242,7 @@ spec: Additional services can query the [KubeDNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/) at `sample-app.default.svc.cluster.local` to reach `sample-app`. If ACLs are enabled and configured with default `deny` policies, the configuration also requires a [`ServiceIntention`](/consul/docs/connect/config-entries/service-intentions) to allow it to talk to `sample-app`. -You can query the KubeDNS for a service that belongs to a sameness group at `sample-app.virtual.group-name.sg.consul`. This syntax is required when failover is desired and `spec.defaultForFailover` is set to `false` in the sameness group CRD. Refer to [sameness group configuration entry reference](/consul/docs/connect/config-entries/sameness-group) for more information. +You can query the KubeDNS for a service that belongs to a sameness group at `sample-app.virtual.group-name.sg.consul`. This syntax is required when failover is desired. To use KubeDNS with sameness groups, `spec.defaultForFailover` must be set to `true` in the sameness group CRD. Refer to [sameness group configuration entry reference](/consul/docs/connect/config-entries/sameness-group) for more information. ### Headless services For services that are not addressed using a virtual cluster IP, you must configure the upstream service using the [DialedDirectly](/consul/docs/connect/config-entries/service-defaults#dialeddirectly) option. Then, use DNS to discover individual instance addresses and dial them through the transparent proxy. When this mode is enabled on the upstream, services present service mesh certificates for mTLS and intentions are enforced at the destination. @@ -253,4 +253,4 @@ Note that when dialing individual instances, Consul ignores the HTTP routing rul - Deployment configurations with federation across or a single datacenter spanning multiple clusters must explicitly dial a service in another datacenter or cluster using annotations. -- When dialing headless services, the request is proxied using a plain TCP proxy. Consul does not take into consideration the upstream's protocol. \ No newline at end of file +- When dialing headless services, the request is proxied using a plain TCP proxy. Consul does not take into consideration the upstream's protocol. diff --git a/website/content/docs/services/discovery/dns-static-lookups.mdx b/website/content/docs/services/discovery/dns-static-lookups.mdx index 56e9ccc02e..74807c756a 100644 --- a/website/content/docs/services/discovery/dns-static-lookups.mdx +++ b/website/content/docs/services/discovery/dns-static-lookups.mdx @@ -109,7 +109,9 @@ The `datacenter` subdomain is optional. By default, Consul interrogates the quer The `cluster-peer` name is optional, and specifies the [cluster peer](/consul/docs/connect/cluster-peering) whose [exported services](/consul/docs/connect/config-entries/exported-services) should be the target of the query. -The `sameness-group` name is optional, and specifies the [sameness group](/consul/docs/connect/cluster-peering/usage/create-sameness-groups) that should be the target of the query. When Consul receives a DNS request for a service that is tied to a sameness group, it returns service instances from the first healthy member of the sameness group. If the local partition is a member of a sameness group, its service instances take precedence over the members of its sameness group. Optionally, you can include a namespace or admin partition when performing a lookup on a sameness group. Refer to [Service lookups for Consul Enterprise](#service-lookups-for-consul-enterprise) for more information. +The `sameness-group` name is optional, and specifies the [sameness group](/consul/docs/connect/cluster-peering/usage/create-sameness-groups) that should be the target of the query. When Consul receives a DNS request for a service that is a member of a sameness group and the sameness groups is configured with `DefaultForFailover` set to `true`, it returns service instances from the first healthy member of the sameness group. If the local partition is a member of a sameness group, local service instances take precedence over the members of its sameness group. Optionally, you can include a namespace or admin partition when performing a lookup on a sameness group. + +Only sameness groups with `DefaultForFailover` set `true` can be queried through DNS. If `DefaultForFailover` is not true, then Consul DNS returns an error response. Refer to [Service lookups for Consul Enterprise](#service-lookups-for-consul-enterprise) for more information. By default, the lookups query in the `consul` domain. Refer to [Configure DNS Behaviors](/consul/docs/services/discovery/dns-configuration) for information about using alternate domains. From 794e73080d8bfbe61f4e9832a48d136cec5462d3 Mon Sep 17 00:00:00 2001 From: nicoche <78445450+nicoche@users.noreply.github.com> Date: Sat, 11 May 2024 01:25:50 +0200 Subject: [PATCH 020/185] docs: fix typo in security/acl (#21003) --- website/content/docs/security/acl/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/security/acl/index.mdx b/website/content/docs/security/acl/index.mdx index b4f589447e..e29ac995e5 100644 --- a/website/content/docs/security/acl/index.mdx +++ b/website/content/docs/security/acl/index.mdx @@ -22,7 +22,7 @@ Refer to the [ACL API reference](/consul/api-docs/acl) and [ACL CLI reference](/ ## Workflow overview -Implementations may vary depending on the needs of the organization, but the following procedure describes the basic workflow for for creating and implementing ACLs: +Implementations may vary depending on the needs of the organization, but the following procedure describes the basic workflow for creating and implementing ACLs: 1. The person responsible for administrating ACLs in your organization specifies one or more authentication rules to define a [policy](#policies). 1. The ACL administrator uses the Consul API to generate and link a [token](#tokens) to one or more policies. The following diagram illustrates the relationship between rules, policies, and tokens: From 0b03a9251ed410a6497d9e1a5f5bc8b21e442aef Mon Sep 17 00:00:00 2001 From: Jeanne Angeles Franco Date: Mon, 13 May 2024 09:35:00 -0700 Subject: [PATCH 021/185] Roll bpa version and cleanup (#21090) --- .github/workflows/backport-assistant.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/backport-assistant.yml b/.github/workflows/backport-assistant.yml index d9e3753c27..27d83e94f5 100644 --- a/.github/workflows/backport-assistant.yml +++ b/.github/workflows/backport-assistant.yml @@ -19,7 +19,7 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.4.0 + container: hashicorpdev/backport-assistant:0.4.1 steps: - name: Run Backport Assistant for release branches run: | @@ -32,7 +32,6 @@ jobs: backport-ent: if: github.event.pull_request.merged && contains(join(github.event.pull_request.labels.*.name), 'backport/ent') runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.4.0 steps: - name: Trigger backport for Enterprise uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0 From 6bf42140ce5e32a80ece56064b9d1da0e661e86d Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 13 May 2024 12:43:17 -0400 Subject: [PATCH 022/185] ci: test BPA 0.4.1 with no-op doc change (#21091) Add a newline to docs/README.md to test a backport without functional changes. --- docs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/README.md b/docs/README.md index 72bd17d6d7..156dc946a4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -86,3 +86,4 @@ in the editor) to maintain a consistent Consul style for the diagrams. [mermaid-js live editor]: https://mermaid-js.github.io/mermaid-live-editor/edit/ [mermaid-js docs]: https://mermaid-js.github.io/mermaid/ [consul-mermaid-theme.json]: ./consul-mermaid-theme.json + From d312d0461bf74e02b80b6bc285c72551af12bbb5 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 13 May 2024 14:01:16 -0400 Subject: [PATCH 023/185] ci: temporarily re-enable retired CE backport labels (#21094) To ease migration during this week's patch releases, temporarily use the more permissive version of BPA to allow old + new backport labels to be used simultaneously. --- .github/workflows/backport-assistant.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/backport-assistant.yml b/.github/workflows/backport-assistant.yml index 27d83e94f5..39a95c9a04 100644 --- a/.github/workflows/backport-assistant.yml +++ b/.github/workflows/backport-assistant.yml @@ -19,7 +19,10 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.4.1 + # Temporarily use 0.4.0 to enable old + new label functionality prior + # to this fix in BPA that excludes CE labels: https://github.com/hashicorp/backport-assistant/pull/84 + # After the Consul May patches, this can be removed and the version updated to latest. + container: hashicorpdev/backport-assistant:0.4.0 steps: - name: Run Backport Assistant for release branches run: | From d0ebc857659f761bab540305345042dcc7b43dd5 Mon Sep 17 00:00:00 2001 From: Blake Covarrubias Date: Mon, 13 May 2024 15:05:23 -0700 Subject: [PATCH 024/185] docs: Fix docs for `-ui-content-path` CLI flag (#21095) Fix the rendering of the documentation for the `-ui-content-path` CLI flag. --- website/content/docs/agent/config/cli-flags.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/website/content/docs/agent/config/cli-flags.mdx b/website/content/docs/agent/config/cli-flags.mdx index 3ec1e8ba12..a38ddff8cb 100644 --- a/website/content/docs/agent/config/cli-flags.mdx +++ b/website/content/docs/agent/config/cli-flags.mdx @@ -424,13 +424,13 @@ information. - `-log-file` ((#\_log_file)) - writes all the Consul agent log messages to a file at the path indicated by this flag. The filename defaults to `consul.log`. - When the log file rotates, this value is used as a prefix for the path to the log and the current timestamp is + When the log file rotates, this value is used as a prefix for the path to the log and the current timestamp is appended to the file name. If the value ends in a path separator, `consul-` will be appended to the value. If the file name is missing an extension, `.log` is appended. For example, setting `log-file` to `/var/log/` would result in a log file path of `/var/log/consul.log`. `log-file` can be combined with [`-log-rotate-bytes`](#_log_rotate_bytes) and [`-log-rotate-duration`](#_log_rotate_duration) - for a fine-grained log rotation experience. After rotation, the path and filename take the following form: + for a fine-grained log rotation experience. After rotation, the path and filename take the following form: `/var/log/consul-{timestamp}.log` - `-log-rotate-bytes` ((#\_log_rotate_bytes)) - to specify the number of @@ -554,13 +554,12 @@ information. specifying only the `-ui` flag is enough to enable the Web UI. Specifying both the '-ui' and '-ui-dir' flags will result in an error. - - `-ui-content-path` ((#\_ui\_content\_path)) - This flag provides the option to change the path the Consul UI loads from and will be displayed in the browser. By default, the path is `/ui/`, for example `http://localhost:8500/ui/`. Only alphanumerics, - `-`, and `_` are allowed in a custom path.`/v1/` is not allowed as it would overwrite + `-`, and `_` are allowed in a custom path. `/v1/` is not allowed as it would overwrite the API endpoint. - +{/* list of reference-style links */} [go-sockaddr]: https://godoc.org/github.com/hashicorp/go-sockaddr/template From 48df56f7d2a517e9a08b479c0a9d54672f3e3a65 Mon Sep 17 00:00:00 2001 From: Blake Covarrubias Date: Mon, 13 May 2024 16:38:36 -0700 Subject: [PATCH 025/185] docs: Add fault injection to Envoy extensions list (#21087) Add fault injection to Envoy extensions list --- .../content/docs/connect/proxies/envoy-extensions/index.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/website/content/docs/connect/proxies/envoy-extensions/index.mdx b/website/content/docs/connect/proxies/envoy-extensions/index.mdx index 79f1dbb1f3..8fd19feed3 100644 --- a/website/content/docs/connect/proxies/envoy-extensions/index.mdx +++ b/website/content/docs/connect/proxies/envoy-extensions/index.mdx @@ -21,6 +21,7 @@ Instead of modifying Consul code, you can configure your services to use Envoy e Envoy extensions enable additional service mesh functionality in Consul by changing how the sidecar proxies behave. Extensions dynamically modify the configuration of Envoy proxies based on Consul configuration entries, enabling a wider set of use cases for the service mesh traffic that passes through an Envoy proxy. Consul supports the following extensions: - External authorization +- Fault injection - Lua - Lambda - OpenTelemetry Access Logging @@ -31,6 +32,10 @@ Envoy extensions enable additional service mesh functionality in Consul by chang The `ext-authz` extension lets you configure external authorization filters for Envoy proxy so that you can route requests to external authorization systems. Refer to the [external authorization documentation](/consul/docs/connect/proxies/envoy-extensions/usage/ext-authz) for more information. +### Fault injection + +The `fault-injection` extension lets you alter responses from an upstream service so that users can test the resilience of their system to different unexpected issues. Refer to the [fault injection documentation](/consul/docs/connect/manage-traffic/fault-injection) for more information. + ### Lambda The `lambda` Envoy extension enables services to make requests to AWS Lambda functions through the mesh as if they are a normal part of the Consul catalog. Refer to the [Lambda extension documentation](/consul/docs/connect/proxies/envoy-extensions/usage/lambda) for more information. From a975b0430297eea3de7f8ad6077de00e0a673c03 Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 14 May 2024 07:05:54 -0600 Subject: [PATCH 026/185] NET-5879 - move the filter for non-passing to occur in the health RPC layer rather than the callers of the RPC (#21098) * NET-5879 - move the filter for non-passing to occur in the health RPC layer rather than the callers of the RPC * fix import of slices * fix test --- agent/catalog_endpoint_test.go | 6 + agent/consul/health_endpoint.go | 3 +- agent/consul/prepared_query_endpoint.go | 10 +- agent/discovery/query_fetcher_v1.go | 30 ++- agent/dns.go | 24 +- agent/health_endpoint.go | 50 ++-- agent/health_endpoint_test.go | 228 +++++++++++++----- agent/proxycfg-glue/health_blocking.go | 3 +- agent/rpcclient/health/view.go | 23 +- agent/structs/structs.go | 85 ++++--- agent/structs/structs_test.go | 6 +- .../docs/upgrading/upgrade-specific.mdx | 5 + 12 files changed, 307 insertions(+), 166 deletions(-) diff --git a/agent/catalog_endpoint_test.go b/agent/catalog_endpoint_test.go index 5a5b2433d5..4aafc8a029 100644 --- a/agent/catalog_endpoint_test.go +++ b/agent/catalog_endpoint_test.go @@ -25,6 +25,12 @@ import ( "github.com/hashicorp/consul/testrpc" ) +func addQueryParam(req *http.Request, param, value string) { + q := req.URL.Query() + q.Add(param, value) + req.URL.RawQuery = q.Encode() +} + func TestCatalogEndpointsFailInV2(t *testing.T) { t.Parallel() diff --git a/agent/consul/health_endpoint.go b/agent/consul/health_endpoint.go index d26bbcd3b6..698d4c1ddb 100644 --- a/agent/consul/health_endpoint.go +++ b/agent/consul/health_endpoint.go @@ -301,7 +301,8 @@ func (h *Health) ServiceNodes(args *structs.ServiceSpecificRequest, reply *struc if err != nil { return err } - thisReply.Nodes = raw.(structs.CheckServiceNodes) + filteredNodes := raw.(structs.CheckServiceNodes) + thisReply.Nodes = filteredNodes.Filter(structs.CheckServiceNodeFilterOptions{FilterType: args.HealthFilterType}) // Note: we filter the results with ACLs *after* applying the user-supplied // bexpr filter, to ensure QueryMeta.ResultsFilteredByACLs does not include diff --git a/agent/consul/prepared_query_endpoint.go b/agent/consul/prepared_query_endpoint.go index 139556bb1a..7c2bf1f960 100644 --- a/agent/consul/prepared_query_endpoint.go +++ b/agent/consul/prepared_query_endpoint.go @@ -562,8 +562,14 @@ func (p *PreparedQuery) execute(query *structs.PreparedQuery, } // Filter out any unhealthy nodes. - nodes = nodes.FilterIgnore(query.Service.OnlyPassing, - query.Service.IgnoreCheckIDs) + filterType := structs.HealthFilterExcludeCritical + if query.Service.OnlyPassing { + filterType = structs.HealthFilterIncludeOnlyPassing + + } + + nodes = nodes.Filter(structs.CheckServiceNodeFilterOptions{FilterType: filterType, + IgnoreCheckIDs: query.Service.IgnoreCheckIDs}) // Apply the node metadata filters, if any. if len(query.Service.NodeMeta) > 0 { diff --git a/agent/discovery/query_fetcher_v1.go b/agent/discovery/query_fetcher_v1.go index dc897f7728..e2d424242e 100644 --- a/agent/discovery/query_fetcher_v1.go +++ b/agent/discovery/query_fetcher_v1.go @@ -573,14 +573,21 @@ func (f *V1DataFetcher) fetchServiceBasedOnTenancy(ctx Context, req *QueryPayloa if req.Tag != "" { serviceTags = []string{req.Tag} } + + healthFilterType := structs.HealthFilterExcludeCritical + if cfg.OnlyPassing { + healthFilterType = structs.HealthFilterIncludeOnlyPassing + } + args := structs.ServiceSpecificRequest{ - PeerName: req.Tenancy.Peer, - Connect: lookupType == LookupTypeConnect, - Ingress: lookupType == LookupTypeIngress, - Datacenter: datacenter, - ServiceName: req.Name, - ServiceTags: serviceTags, - TagFilter: req.Tag != "", + PeerName: req.Tenancy.Peer, + Connect: lookupType == LookupTypeConnect, + Ingress: lookupType == LookupTypeIngress, + Datacenter: datacenter, + ServiceName: req.Name, + ServiceTags: serviceTags, + TagFilter: req.Tag != "", + HealthFilterType: healthFilterType, QueryOptions: structs.QueryOptions{ Token: ctx.Token, AllowStale: cfg.AllowStale, @@ -604,15 +611,6 @@ func (f *V1DataFetcher) fetchServiceBasedOnTenancy(ctx Context, req *QueryPayloa return nil, ErrNotFound } - // Filter out any service nodes due to health checks - // We copy the slice to avoid modifying the result if it comes from the cache - nodes := make(structs.CheckServiceNodes, len(out.Nodes)) - copy(nodes, out.Nodes) - out.Nodes = nodes.Filter(cfg.OnlyPassing) - if err != nil { - return nil, fmt.Errorf("rpc request failed: %w", err) - } - // If we have no nodes, return not found! if len(out.Nodes) == 0 { return nil, ErrNotFound diff --git a/agent/dns.go b/agent/dns.go index ebcafc1d61..8ddfcaca3f 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -1450,14 +1450,19 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st if lookup.Tag != "" { serviceTags = []string{lookup.Tag} } + healthFilterType := structs.HealthFilterExcludeCritical + if cfg.OnlyPassing { + healthFilterType = structs.HealthFilterIncludeOnlyPassing + } args := structs.ServiceSpecificRequest{ - PeerName: lookup.PeerName, - Connect: lookup.Connect, - Ingress: lookup.Ingress, - Datacenter: lookup.Datacenter, - ServiceName: lookup.Service, - ServiceTags: serviceTags, - TagFilter: lookup.Tag != "", + PeerName: lookup.PeerName, + Connect: lookup.Connect, + Ingress: lookup.Ingress, + Datacenter: lookup.Datacenter, + ServiceName: lookup.Service, + ServiceTags: serviceTags, + TagFilter: lookup.Tag != "", + HealthFilterType: healthFilterType, QueryOptions: structs.QueryOptions{ Token: d.coalesceDNSToken(), AllowStale: cfg.AllowStale, @@ -1473,11 +1478,6 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st return out, err } - // Filter out any service nodes due to health checks - // We copy the slice to avoid modifying the result if it comes from the cache - nodes := make(structs.CheckServiceNodes, len(out.Nodes)) - copy(nodes, out.Nodes) - out.Nodes = nodes.Filter(cfg.OnlyPassing) return out, nil } diff --git a/agent/health_endpoint.go b/agent/health_endpoint.go index 1ce464d91c..9c3492faf1 100644 --- a/agent/health_endpoint.go +++ b/agent/health_endpoint.go @@ -214,12 +214,24 @@ func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Re prefix = "/v1/health/service/" } - // Pull out the service name + // Parse out the service name from the query params args.ServiceName = strings.TrimPrefix(req.URL.Path, prefix) if args.ServiceName == "" { return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing service name"} } + // Parse the passing flag from the query params and use to set the health filter type + // to HealthFilterIncludeOnlyPassing if it is present. Otherwise, do not filter by health. + passing, err := getBoolQueryParam(params, api.HealthPassing) + if err != nil { + return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Invalid value for ?passing"} + } + healthFilterType := structs.HealthFilterIncludeAll + if passing { + healthFilterType = structs.HealthFilterIncludeOnlyPassing + } + args.HealthFilterType = healthFilterType + out, md, err := s.agent.rpcClientHealth.ServiceNodes(req.Context(), args) if err != nil { return nil, err @@ -229,19 +241,7 @@ func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Re setCacheMeta(resp, &md) } out.QueryMeta.ConsistencyLevel = args.QueryOptions.ConsistencyLevel() - setMeta(resp, &out.QueryMeta) - - // FIXME: argument parsing should be done before performing the rpc - // Filter to only passing if specified - filter, err := getBoolQueryParam(params, api.HealthPassing) - if err != nil { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Invalid value for ?passing"} - } - - // FIXME: remove filterNonPassing, replace with nodes.Filter, which is used by DNSServer - if filter { - out.Nodes = filterNonPassing(out.Nodes) - } + _ = setMeta(resp, &out.QueryMeta) // Translate addresses after filtering so we don't waste effort. s.agent.TranslateAddresses(args.Datacenter, out.Nodes, dnsutil.TranslateAddressAcceptAny) @@ -290,25 +290,3 @@ func getBoolQueryParam(params url.Values, key string) (bool, error) { } return param, nil } - -// filterNonPassing is used to filter out any nodes that have check that are not passing -func filterNonPassing(nodes structs.CheckServiceNodes) structs.CheckServiceNodes { - n := len(nodes) - - // Make a copy of the cached nodes rather than operating on the cache directly - out := append(nodes[:0:0], nodes...) - -OUTER: - for i := 0; i < n; i++ { - node := out[i] - for _, check := range node.Checks { - if check.Status != api.HealthPassing { - out[i], out[n-1] = out[n-1], structs.CheckServiceNode{} - n-- - i-- - continue OUTER - } - } - } - return out[:n] -} diff --git a/agent/health_endpoint_test.go b/agent/health_endpoint_test.go index 86dd7be70f..4d7654bae3 100644 --- a/agent/health_endpoint_test.go +++ b/agent/health_endpoint_test.go @@ -9,7 +9,6 @@ import ( "net/http" "net/http/httptest" "net/url" - "reflect" "strconv" "strings" "testing" @@ -627,13 +626,54 @@ func TestHealthServiceChecks_DistanceSort(t *testing.T) { }) } +type queryBackendConfiguration struct { + name string + config string + cached bool + queryBackend string +} + +var queryBackendConfigs = []*queryBackendConfiguration{ + { + name: "blocking-query-without-cache", + config: `use_streaming_backend=false`, + cached: false, + queryBackend: "blocking-query", + }, + { + name: "blocking-query-with-cache", + config: `use_streaming_backend=false`, + cached: true, + queryBackend: "blocking-query", + }, + { + name: "streaming-with-cache-setting", + config: ` + rpc{ + enable_streaming=true + } + use_streaming_backend=true + `, + cached: true, + queryBackend: "streaming", + }, +} + func TestHealthServiceNodes(t *testing.T) { + for _, cfg := range queryBackendConfigs { + t.Run(cfg.name, func(t *testing.T) { + testHealthServiceNodes(t, cfg) + }) + } +} + +func testHealthServiceNodes(t *testing.T, backendCfg *queryBackendConfiguration) { if testing.Short() { t.Skip("too slow for testing.Short") } t.Parallel() - a := StartTestAgent(t, TestAgent{HCL: ``, Overrides: `peering = { test_allow_peer_registrations = true }`}) + a := StartTestAgent(t, TestAgent{HCL: backendCfg.config, Overrides: `peering = { test_allow_peer_registrations = true }`}) defer a.Shutdown() testrpc.WaitForTestAgent(t, a.RPC, "dc1") @@ -718,30 +758,44 @@ func TestHealthServiceNodes(t *testing.T) { // Test caching { // List instances with cache enabled - req, err := http.NewRequest("GET", "/v1/health/service/test?cached"+peerQuerySuffix(peerName), nil) + req, err := http.NewRequest("GET", "/v1/health/service/test?"+peerQuerySuffix(peerName), nil) require.NoError(t, err) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthServiceNodes(resp, req) require.NoError(t, err) nodes := obj.(structs.CheckServiceNodes) verify(t, peerName, nodes) - // Should be a cache miss - require.Equal(t, "MISS", resp.Header().Get("X-Cache")) + if backendCfg.cached { + // Should be a cache miss + require.Equal(t, "MISS", resp.Header().Get("X-Cache")) + } + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) } { // List instances with cache enabled - req, err := http.NewRequest("GET", "/v1/health/service/test?cached"+peerQuerySuffix(peerName), nil) + req, err := http.NewRequest("GET", "/v1/health/service/test?"+peerQuerySuffix(peerName), nil) require.NoError(t, err) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthServiceNodes(resp, req) require.NoError(t, err) nodes := obj.(structs.CheckServiceNodes) verify(t, peerName, nodes) - // Should be a cache HIT now! - require.Equal(t, "HIT", resp.Header().Get("X-Cache")) + if backendCfg.cached { + // Should be a cache HIT now! + require.Equal(t, "HIT", resp.Header().Get("X-Cache")) + } + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) } } @@ -761,8 +815,11 @@ func TestHealthServiceNodes(t *testing.T) { for _, peerName := range testingPeerNames { retry.Run(t, func(r *retry.R) { // List it again - req, err := http.NewRequest("GET", "/v1/health/service/test?cached"+peerQuerySuffix(peerName), nil) + req, err := http.NewRequest("GET", "/v1/health/service/test?"+peerQuerySuffix(peerName), nil) require.NoError(r, err) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthServiceNodes(resp, req) require.NoError(r, err) @@ -780,9 +837,15 @@ func TestHealthServiceNodes(t *testing.T) { // Should be a cache hit! The data should've updated in the cache // in the background so this should've been fetched directly from // the cache. - if resp.Header().Get("X-Cache") != "HIT" { - r.Fatalf("should be a cache hit") + if backendCfg.cached { + // Should be a cache hit! The data should've updated in the cache + // in the background so this should've been fetched directly from + // the cache. + if resp.Header().Get("X-Cache") != "HIT" { + r.Fatalf("should be a cache hit") + } } + require.Equal(r, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) } } @@ -1237,12 +1300,20 @@ func TestHealthServiceNodes_NodeMetaFilter(t *testing.T) { } func TestHealthServiceNodes_Filter(t *testing.T) { + for _, cfg := range queryBackendConfigs { + t.Run(cfg.name, func(t *testing.T) { + testHealthServiceNodes_Filter(t, cfg) + }) + } +} + +func testHealthServiceNodes_Filter(t *testing.T, backendCfg *queryBackendConfiguration) { if testing.Short() { t.Skip("too slow for testing.Short") } t.Parallel() - a := NewTestAgent(t, "") + a := NewTestAgent(t, backendCfg.config) defer a.Shutdown() testrpc.WaitForTestAgent(t, a.RPC, "dc1") @@ -1290,6 +1361,9 @@ func TestHealthServiceNodes_Filter(t *testing.T) { require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) req, _ = http.NewRequest("GET", "/v1/health/service/consul?dc=dc1&filter="+url.QueryEscape("Node.Node == `test-health-node`"), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp = httptest.NewRecorder() obj, err = a.srv.HealthServiceNodes(resp, req) require.NoError(t, err) @@ -1300,6 +1374,8 @@ func TestHealthServiceNodes_Filter(t *testing.T) { nodes = obj.(structs.CheckServiceNodes) require.Len(t, nodes, 1) require.Len(t, nodes[0].Checks, 1) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) } func TestHealthServiceNodes_DistanceSort(t *testing.T) { @@ -1386,12 +1462,20 @@ func TestHealthServiceNodes_DistanceSort(t *testing.T) { } func TestHealthServiceNodes_PassingFilter(t *testing.T) { + for _, cfg := range queryBackendConfigs { + t.Run(cfg.name, func(t *testing.T) { + testHealthServiceNodes_PassingFilter(t, cfg) + }) + } +} + +func testHealthServiceNodes_PassingFilter(t *testing.T, backendCfg *queryBackendConfiguration) { if testing.Short() { t.Skip("too slow for testing.Short") } t.Parallel() - a := NewTestAgent(t, "") + a := NewTestAgent(t, backendCfg.config) defer a.Shutdown() dc := "dc1" @@ -1417,6 +1501,9 @@ func TestHealthServiceNodes_PassingFilter(t *testing.T) { t.Run("bc_no_query_value", func(t *testing.T) { req, _ := http.NewRequest("GET", "/v1/health/service/consul?passing", nil) + if backendCfg.cached { + addQueryParam(req, "cached", "") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthServiceNodes(resp, req) if err != nil { @@ -1428,12 +1515,16 @@ func TestHealthServiceNodes_PassingFilter(t *testing.T) { // Should be 0 health check for consul nodes := obj.(structs.CheckServiceNodes) if len(nodes) != 0 { - t.Fatalf("bad: %v", obj) + t.Fatalf("bad: %v", nodes) } + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) t.Run("passing_true", func(t *testing.T) { req, _ := http.NewRequest("GET", "/v1/health/service/consul?passing=true", nil) + if backendCfg.cached { + addQueryParam(req, "cached", "") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthServiceNodes(resp, req) if err != nil { @@ -1447,10 +1538,14 @@ func TestHealthServiceNodes_PassingFilter(t *testing.T) { if len(nodes) != 0 { t.Fatalf("bad: %v", obj) } + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) t.Run("passing_false", func(t *testing.T) { req, _ := http.NewRequest("GET", "/v1/health/service/consul?passing=false", nil) + if backendCfg.cached { + addQueryParam(req, "cached", "") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthServiceNodes(resp, req) if err != nil { @@ -1465,16 +1560,21 @@ func TestHealthServiceNodes_PassingFilter(t *testing.T) { if len(nodes) != 1 { t.Fatalf("bad: %v", obj) } + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) t.Run("passing_bad", func(t *testing.T) { req, _ := http.NewRequest("GET", "/v1/health/service/consul?passing=nope-nope-nope", nil) + if backendCfg.cached { + addQueryParam(req, "cached", "") + } resp := httptest.NewRecorder() _, err := a.srv.HealthServiceNodes(resp, req) require.True(t, isHTTPBadRequest(err), fmt.Sprintf("Expected bad request HTTP error but got %v", err)) if !strings.Contains(err.Error(), "Invalid value for ?passing") { t.Errorf("bad %s", err.Error()) } + require.Equal(t, "", resp.Header().Get("X-Consul-Query-Backend")) }) } @@ -1626,13 +1726,21 @@ func TestHealthServiceNodes_WanTranslation(t *testing.T) { } func TestHealthConnectServiceNodes(t *testing.T) { + for _, cfg := range queryBackendConfigs { + t.Run(cfg.name, func(t *testing.T) { + testHealthConnectServiceNodes(t, cfg) + }) + } +} + +func testHealthConnectServiceNodes(t *testing.T, backendCfg *queryBackendConfiguration) { if testing.Short() { t.Skip("too slow for testing.Short") } t.Parallel() - a := NewTestAgent(t, "") + a := NewTestAgent(t, backendCfg.config) defer a.Shutdown() // Register @@ -1643,6 +1751,9 @@ func TestHealthConnectServiceNodes(t *testing.T) { // Request req, _ := http.NewRequest("GET", fmt.Sprintf( "/v1/health/connect/%s?dc=dc1", args.Service.Proxy.DestinationServiceName), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthConnectServiceNodes(resp, req) assert.Nil(t, err) @@ -1771,13 +1882,21 @@ func testHealthIngressServiceNodes(t *testing.T, agentHCL string) { } func TestHealthConnectServiceNodes_Filter(t *testing.T) { + for _, cfg := range queryBackendConfigs { + t.Run(cfg.name, func(t *testing.T) { + testHealthConnectServiceNodes_Filter(t, cfg) + }) + } +} + +func testHealthConnectServiceNodes_Filter(t *testing.T, backendCfg *queryBackendConfiguration) { if testing.Short() { t.Skip("too slow for testing.Short") } t.Parallel() - a := NewTestAgent(t, "") + a := NewTestAgent(t, backendCfg.config) defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") @@ -1788,6 +1907,12 @@ func TestHealthConnectServiceNodes_Filter(t *testing.T) { require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) args = structs.TestRegisterRequestProxy(t) + // when using streaming these come back as empty slices rather than nil. + // rather than changing structs.TestRegisterRequestProxy(t) and the many places + // it is referenced without using caching, we'll just set them to empty slices here. + args.Service.Proxy.EnvoyExtensions = []structs.EnvoyExtension{} + args.Service.Proxy.Expose.Paths = []structs.ExposePath{} + args.Service.Address = "127.0.0.55" args.Service.Meta = map[string]string{ "version": "2", @@ -1800,6 +1925,9 @@ func TestHealthConnectServiceNodes_Filter(t *testing.T) { "/v1/health/connect/%s?filter=%s", args.Service.Proxy.DestinationServiceName, url.QueryEscape("Service.Meta.version == 2")), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthConnectServiceNodes(resp, req) require.NoError(t, err) @@ -1810,16 +1938,26 @@ func TestHealthConnectServiceNodes_Filter(t *testing.T) { require.Equal(t, structs.ServiceKindConnectProxy, nodes[0].Service.Kind) require.Equal(t, args.Service.Address, nodes[0].Service.Address) require.Equal(t, args.Service.Proxy, nodes[0].Service.Proxy) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) } func TestHealthConnectServiceNodes_PassingFilter(t *testing.T) { + for _, cfg := range queryBackendConfigs { + t.Run(cfg.name, func(t *testing.T) { + testHealthConnectServiceNodes_PassingFilter(t, cfg) + }) + } +} + +func testHealthConnectServiceNodes_PassingFilter(t *testing.T, backendCfg *queryBackendConfiguration) { if testing.Short() { t.Skip("too slow for testing.Short") } t.Parallel() - a := NewTestAgent(t, "") + a := NewTestAgent(t, backendCfg.config) defer a.Shutdown() // Register @@ -1836,6 +1974,9 @@ func TestHealthConnectServiceNodes_PassingFilter(t *testing.T) { t.Run("bc_no_query_value", func(t *testing.T) { req, _ := http.NewRequest("GET", fmt.Sprintf( "/v1/health/connect/%s?passing", args.Service.Proxy.DestinationServiceName), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthConnectServiceNodes(resp, req) assert.Nil(t, err) @@ -1844,11 +1985,16 @@ func TestHealthConnectServiceNodes_PassingFilter(t *testing.T) { // Should be 0 health check for consul nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 0) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) t.Run("passing_true", func(t *testing.T) { req, _ := http.NewRequest("GET", fmt.Sprintf( "/v1/health/connect/%s?passing=true", args.Service.Proxy.DestinationServiceName), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthConnectServiceNodes(resp, req) assert.Nil(t, err) @@ -1857,11 +2003,16 @@ func TestHealthConnectServiceNodes_PassingFilter(t *testing.T) { // Should be 0 health check for consul nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 0) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) t.Run("passing_false", func(t *testing.T) { req, _ := http.NewRequest("GET", fmt.Sprintf( "/v1/health/connect/%s?passing=false", args.Service.Proxy.DestinationServiceName), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() obj, err := a.srv.HealthConnectServiceNodes(resp, req) assert.Nil(t, err) @@ -1870,57 +2021,26 @@ func TestHealthConnectServiceNodes_PassingFilter(t *testing.T) { // Should be 1 nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 1) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) t.Run("passing_bad", func(t *testing.T) { req, _ := http.NewRequest("GET", fmt.Sprintf( "/v1/health/connect/%s?passing=nope-nope", args.Service.Proxy.DestinationServiceName), nil) + if backendCfg.cached { + addQueryParam(req, "cached", "true") + } resp := httptest.NewRecorder() _, err := a.srv.HealthConnectServiceNodes(resp, req) assert.NotNil(t, err) assert.True(t, isHTTPBadRequest(err)) assert.True(t, strings.Contains(err.Error(), "Invalid value for ?passing")) + require.Equal(t, "", resp.Header().Get("X-Consul-Query-Backend")) }) } -func TestFilterNonPassing(t *testing.T) { - t.Parallel() - nodes := structs.CheckServiceNodes{ - structs.CheckServiceNode{ - Checks: structs.HealthChecks{ - &structs.HealthCheck{ - Status: api.HealthCritical, - }, - &structs.HealthCheck{ - Status: api.HealthCritical, - }, - }, - }, - structs.CheckServiceNode{ - Checks: structs.HealthChecks{ - &structs.HealthCheck{ - Status: api.HealthCritical, - }, - &structs.HealthCheck{ - Status: api.HealthCritical, - }, - }, - }, - structs.CheckServiceNode{ - Checks: structs.HealthChecks{ - &structs.HealthCheck{ - Status: api.HealthPassing, - }, - }, - }, - } - out := filterNonPassing(nodes) - if len(out) != 1 && reflect.DeepEqual(out[0], nodes[2]) { - t.Fatalf("bad: %v", out) - } -} - func TestListHealthyServiceNodes_MergeCentralConfig(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") diff --git a/agent/proxycfg-glue/health_blocking.go b/agent/proxycfg-glue/health_blocking.go index 8ed384f837..0b2bcba8b9 100644 --- a/agent/proxycfg-glue/health_blocking.go +++ b/agent/proxycfg-glue/health_blocking.go @@ -128,7 +128,8 @@ func (h *serverHealthBlocking) Notify(ctx context.Context, args *structs.Service if err != nil { return 0, nil, err } - thisReply.Nodes = raw.(structs.CheckServiceNodes) + filteredNodes := raw.(structs.CheckServiceNodes) + thisReply.Nodes = filteredNodes.Filter(structs.CheckServiceNodeFilterOptions{FilterType: args.HealthFilterType}) // Note: we filter the results with ACLs *after* applying the user-supplied // bexpr filter, to ensure QueryMeta.ResultsFilteredByACLs does not include diff --git a/agent/rpcclient/health/view.go b/agent/rpcclient/health/view.go index 8e08ba801e..2f5b43a4d0 100644 --- a/agent/rpcclient/health/view.go +++ b/agent/rpcclient/health/view.go @@ -46,10 +46,11 @@ func NewHealthView(req structs.ServiceSpecificRequest) (*HealthView, error) { return nil, err } return &HealthView{ - state: make(map[string]structs.CheckServiceNode), - filter: fe, - connect: req.Connect, - kind: req.ServiceKind, + state: make(map[string]structs.CheckServiceNode), + filter: fe, + connect: req.Connect, + kind: req.ServiceKind, + healthFilterType: req.HealthFilterType, }, nil } @@ -61,10 +62,11 @@ var _ submatview.View = (*HealthView)(nil) // (IndexedCheckServiceNodes) and update it in place for each event - that // involves re-sorting each time etc. though. type HealthView struct { - connect bool - kind structs.ServiceKind - state map[string]structs.CheckServiceNode - filter filterEvaluator + connect bool + kind structs.ServiceKind + state map[string]structs.CheckServiceNode + filter filterEvaluator + healthFilterType structs.HealthFilterType } // Update implements View @@ -87,6 +89,11 @@ func (s *HealthView) Update(events []*pbsubscribe.Event) error { return errors.New("check service node was unexpectedly nil") } + if csn.ExcludeBasedOnChecks(structs.CheckServiceNodeFilterOptions{FilterType: s.healthFilterType}) { + delete(s.state, id) + continue + } + // check if we intentionally need to skip the filter if s.skipFilter(csn) { s.state[id] = *csn diff --git a/agent/structs/structs.go b/agent/structs/structs.go index 0ac72b07fe..1a90d863ca 100644 --- a/agent/structs/structs.go +++ b/agent/structs/structs.go @@ -13,6 +13,7 @@ import ( "os" "reflect" "regexp" + "slices" "sort" "strconv" "strings" @@ -757,11 +758,12 @@ type ServiceSpecificRequest struct { ServiceKind ServiceKind // DEPRECATED (singular-service-tag) - remove this when backwards RPC compat // with 1.2.x is not required. - ServiceTag string - ServiceTags []string - ServiceAddress string - TagFilter bool // Controls tag filtering - Source QuerySource + ServiceTag string + ServiceTags []string + ServiceAddress string + TagFilter bool // Controls tag filtering + HealthFilterType HealthFilterType + Source QuerySource // Connect if true will only search for Connect-compatible services. Connect bool @@ -822,6 +824,7 @@ func (r *ServiceSpecificRequest) CacheInfo() cache.RequestInfo { r.Ingress, r.ServiceKind, r.MergeCentralConfig, + r.HealthFilterType, }, nil) if err == nil { // If there is an error, we don't set the key. A blank key forces @@ -2122,6 +2125,19 @@ func (csn *CheckServiceNode) Locality() *Locality { return nil } +func (csn *CheckServiceNode) ExcludeBasedOnChecks(opts CheckServiceNodeFilterOptions) bool { + for _, check := range csn.Checks { + if slices.Contains(opts.IgnoreCheckIDs, check.CheckID) { + // Skip this _check_ but keep looking at other checks for this node. + continue + } + if opts.FilterType.ExcludeBasedOnStatus(check.Status) { + return true + } + } + return false +} + type CheckServiceNodes []CheckServiceNode func (csns CheckServiceNodes) DeepCopy() CheckServiceNodes { @@ -2161,39 +2177,42 @@ func (nodes CheckServiceNodes) ShallowClone() CheckServiceNodes { return dup } +// HealthFilterType is used to filter nodes based on their health status. +type HealthFilterType int32 + +func (h HealthFilterType) ExcludeBasedOnStatus(status string) bool { + switch { + case h == HealthFilterExcludeCritical && status == api.HealthCritical: + return true + case h == HealthFilterIncludeOnlyPassing && status != api.HealthPassing: + return true + } + return false +} + +// These are listed from most to least inclusive. +const ( + HealthFilterIncludeAll HealthFilterType = 0 + HealthFilterExcludeCritical HealthFilterType = 1 + HealthFilterIncludeOnlyPassing HealthFilterType = 2 +) + +type CheckServiceNodeFilterOptions struct { + FilterType HealthFilterType + IgnoreCheckIDs []types.CheckID + disableReceiverModification bool +} + // Filter removes nodes that are failing health checks (and any non-passing // check if that option is selected). Note that this returns the filtered // results AND modifies the receiver for performance. -func (nodes CheckServiceNodes) Filter(onlyPassing bool) CheckServiceNodes { - return nodes.FilterIgnore(onlyPassing, nil) -} - -// FilterIgnore removes nodes that are failing health checks just like Filter. -// It also ignores the status of any check with an ID present in ignoreCheckIDs -// as if that check didn't exist. Note that this returns the filtered results -// AND modifies the receiver for performance. -func (nodes CheckServiceNodes) FilterIgnore(onlyPassing bool, - ignoreCheckIDs []types.CheckID) CheckServiceNodes { +func (nodes CheckServiceNodes) Filter(opts CheckServiceNodeFilterOptions) CheckServiceNodes { n := len(nodes) -OUTER: for i := 0; i < n; i++ { - node := nodes[i] - INNER: - for _, check := range node.Checks { - for _, ignore := range ignoreCheckIDs { - if check.CheckID == ignore { - // Skip this _check_ but keep looking at other checks for this node. - continue INNER - } - } - if check.Status == api.HealthCritical || - (onlyPassing && check.Status != api.HealthPassing) { - nodes[i], nodes[n-1] = nodes[n-1], CheckServiceNode{} - n-- - i-- - // Skip this _node_ now we've swapped it off the end of the list. - continue OUTER - } + if nodes[i].ExcludeBasedOnChecks(opts) { + nodes[i], nodes[n-1] = nodes[n-1], CheckServiceNode{} + n-- + i-- } } return nodes[:n] diff --git a/agent/structs/structs_test.go b/agent/structs/structs_test.go index bf909aa419..3f73e0cc28 100644 --- a/agent/structs/structs_test.go +++ b/agent/structs/structs_test.go @@ -1725,7 +1725,7 @@ func TestCheckServiceNodes_Filter(t *testing.T) { if n := copy(twiddle, nodes); n != len(nodes) { t.Fatalf("bad: %d", n) } - filtered := twiddle.Filter(false) + filtered := twiddle.Filter(CheckServiceNodeFilterOptions{FilterType: HealthFilterExcludeCritical}) expected := CheckServiceNodes{ nodes[0], nodes[1], @@ -1741,7 +1741,7 @@ func TestCheckServiceNodes_Filter(t *testing.T) { if n := copy(twiddle, nodes); n != len(nodes) { t.Fatalf("bad: %d", n) } - filtered := twiddle.Filter(true) + filtered := twiddle.Filter(CheckServiceNodeFilterOptions{FilterType: HealthFilterIncludeOnlyPassing}) expected := CheckServiceNodes{ nodes[1], } @@ -1757,7 +1757,7 @@ func TestCheckServiceNodes_Filter(t *testing.T) { if n := copy(twiddle, nodes); n != len(nodes) { t.Fatalf("bad: %d", n) } - filtered := twiddle.FilterIgnore(true, []types.CheckID{""}) + filtered := twiddle.Filter(CheckServiceNodeFilterOptions{FilterType: HealthFilterIncludeOnlyPassing, IgnoreCheckIDs: []types.CheckID{""}}) expected := CheckServiceNodes{ nodes[0], nodes[1], diff --git a/website/content/docs/upgrading/upgrade-specific.mdx b/website/content/docs/upgrading/upgrade-specific.mdx index 0adb8750c3..b731408f27 100644 --- a/website/content/docs/upgrading/upgrade-specific.mdx +++ b/website/content/docs/upgrading/upgrade-specific.mdx @@ -16,6 +16,11 @@ upgrade flow. ## Consul v1.19.x +### Health endpoint status filtering is now processed on the server side when using client agents +In previous versions of Consul, client agents responded to health queries by requesting all results from the Consul servers and then locally filtering out service nodes with a `critical` status. The client agent also processed the `?passing` parameter by filtering node results locally. This process was not resource efficient in large deployments because large numbers of services and health check results must propagate to many clients before Consul can return a healthy node. + +In this release, the Consul server is responsible for filtering services according to their health status before it sends the data to a client agent. When upgrading the version of Consul your deployment runs to this release, you must upgrade the Consul servers before you upgrade the client agents. We recommend this upgrade order to avoid a scenario where Consul returns results for an unhealthy service because the client agent no longer filters nodes but the servers do not yet understand the `?passing` query argument. + ### Metrics removal In previous versions, Consul emitted redundant state store usage metrics that contained two instances of `consul` in the metric name. As an example, config entry usage counts were emitted as both: From 9b2c1be0534e16a6a30a69e4c8c4f68b8fa45de7 Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 14 May 2024 07:32:49 -0600 Subject: [PATCH 027/185] NET-5879 - expose sameness group param on service health endpoint and move sameness group health fallback logic into HealthService RPC layer (#21096) * NET-5879 - move the filter for non-passing to occur in the health RPC layer rather than the callers of the RPC * fix import of slices * NET-5879 - expose sameness group param on service health endpoint and move sameness group health fallback logic into HealthService RPC layer * fixing deepcopy * fix license headers --- agent/consul/health_endpoint.go | 131 +++++++++++++---------- agent/consul/health_endpoint_ce.go | 38 +++++++ agent/discovery/query_fetcher_v1.go | 28 +---- agent/discovery/query_fetcher_v1_ce.go | 12 --- agent/discovery/query_fetcher_v1_test.go | 5 +- agent/dns.go | 112 ++++++++++--------- agent/dns_ce.go | 17 +-- agent/health_endpoint.go | 6 +- agent/health_endpoint_ce_test.go | 30 ++++++ agent/http.go | 11 +- agent/rpcclient/health/health.go | 7 +- agent/rpcclient/health/health_test.go | 20 ++++ agent/structs/deep-copy.sh | 1 + agent/structs/structs.deepcopy.go | 18 +++- agent/structs/structs.go | 4 + api/api.go | 13 +++ 16 files changed, 288 insertions(+), 165 deletions(-) create mode 100644 agent/consul/health_endpoint_ce.go create mode 100644 agent/health_endpoint_ce_test.go diff --git a/agent/consul/health_endpoint.go b/agent/consul/health_endpoint.go index 698d4c1ddb..6f00ec4b08 100644 --- a/agent/consul/health_endpoint.go +++ b/agent/consul/health_endpoint.go @@ -8,15 +8,15 @@ import ( "sort" "github.com/armon/go-metrics" - bexpr "github.com/hashicorp/go-bexpr" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-memdb" hashstructure_v2 "github.com/mitchellh/hashstructure/v2" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/consul/state" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/go-bexpr" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-memdb" ) // Health endpoint is used to query the health information @@ -250,69 +250,86 @@ func (h *Health) ServiceNodes(args *structs.ServiceSpecificRequest, reply *struc func(ws memdb.WatchSet, state *state.Store) error { var thisReply structs.IndexedCheckServiceNodes - index, nodes, err := f(ws, state, args) + sgIdx, sgArgs, err := h.getArgsForSamenessGroupMembers(args, ws, state) if err != nil { return err } - resolvedNodes := nodes - if args.MergeCentralConfig { - for _, node := range resolvedNodes { - ns := node.Service - if ns.IsSidecarProxy() || ns.IsGateway() { - cfgIndex, mergedns, err := configentry.MergeNodeServiceWithCentralConfig(ws, state, ns, h.logger) - if err != nil { - return err - } - if cfgIndex > index { - index = cfgIndex - } - *node.Service = *mergedns - } - } - - // Generate a hash of the resolvedNodes driving this response. - // Use it to determine if the response is identical to a prior wakeup. - newMergeHash, err := hashstructure_v2.Hash(resolvedNodes, hashstructure_v2.FormatV2, nil) + for _, arg := range sgArgs { + index, nodes, err := f(ws, state, arg) if err != nil { - return fmt.Errorf("error hashing reply for spurious wakeup suppression: %w", err) - } - if ranMergeOnce && priorMergeHash == newMergeHash { - // the below assignment is not required as the if condition already validates equality, - // but makes it more clear that prior value is being reset to the new hash on each run. - priorMergeHash = newMergeHash - reply.Index = index - // NOTE: the prior response is still alive inside of *reply, which is desirable - return errNotChanged - } else { - priorMergeHash = newMergeHash - ranMergeOnce = true + return err } + resolvedNodes := nodes + if arg.MergeCentralConfig { + for _, node := range resolvedNodes { + ns := node.Service + if ns.IsSidecarProxy() || ns.IsGateway() { + cfgIndex, mergedns, err := configentry.MergeNodeServiceWithCentralConfig(ws, state, ns, h.logger) + if err != nil { + return err + } + if cfgIndex > index { + index = cfgIndex + } + *node.Service = *mergedns + } + } + + // Generate a hash of the resolvedNodes driving this response. + // Use it to determine if the response is identical to a prior wakeup. + newMergeHash, err := hashstructure_v2.Hash(resolvedNodes, hashstructure_v2.FormatV2, nil) + if err != nil { + return fmt.Errorf("error hashing reply for spurious wakeup suppression: %w", err) + } + if ranMergeOnce && priorMergeHash == newMergeHash { + // the below assignment is not required as the if condition already validates equality, + // but makes it more clear that prior value is being reset to the new hash on each run. + priorMergeHash = newMergeHash + reply.Index = index + // NOTE: the prior response is still alive inside of *reply, which is desirable + return errNotChanged + } else { + priorMergeHash = newMergeHash + ranMergeOnce = true + } + + } + + thisReply.Index, thisReply.Nodes = index, resolvedNodes + + if len(arg.NodeMetaFilters) > 0 { + thisReply.Nodes = nodeMetaFilter(arg.NodeMetaFilters, thisReply.Nodes) + } + + raw, err := filter.Execute(thisReply.Nodes) + if err != nil { + return err + } + filteredNodes := raw.(structs.CheckServiceNodes) + thisReply.Nodes = filteredNodes.Filter(structs.CheckServiceNodeFilterOptions{FilterType: arg.HealthFilterType}) + + // Note: we filter the results with ACLs *after* applying the user-supplied + // bexpr filter, to ensure QueryMeta.ResultsFilteredByACLs does not include + // results that would be filtered out even if the user did have permission. + if err := h.srv.filterACL(arg.Token, &thisReply); err != nil { + return err + } + + if err := h.srv.sortNodesByDistanceFrom(arg.Source, thisReply.Nodes); err != nil { + return err + } + if len(thisReply.Nodes) > 0 { + break + } } - thisReply.Index, thisReply.Nodes = index, resolvedNodes - - if len(args.NodeMetaFilters) > 0 { - thisReply.Nodes = nodeMetaFilter(args.NodeMetaFilters, thisReply.Nodes) - } - - raw, err := filter.Execute(thisReply.Nodes) - if err != nil { - return err - } - filteredNodes := raw.(structs.CheckServiceNodes) - thisReply.Nodes = filteredNodes.Filter(structs.CheckServiceNodeFilterOptions{FilterType: args.HealthFilterType}) - - // Note: we filter the results with ACLs *after* applying the user-supplied - // bexpr filter, to ensure QueryMeta.ResultsFilteredByACLs does not include - // results that would be filtered out even if the user did have permission. - if err := h.srv.filterACL(args.Token, &thisReply); err != nil { - return err - } - - if err := h.srv.sortNodesByDistanceFrom(args.Source, thisReply.Nodes); err != nil { - return err + // If sameness group was used, evaluate the index of the sameness group + // and update the index of the response if it is greater. If sameness group is not + // used, the sgIdx will be 0 in this evaluation. + if sgIdx > thisReply.Index { + thisReply.Index = sgIdx } *reply = thisReply diff --git a/agent/consul/health_endpoint_ce.go b/agent/consul/health_endpoint_ce.go new file mode 100644 index 0000000000..1580054e5d --- /dev/null +++ b/agent/consul/health_endpoint_ce.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +//go:build !consulent + +package consul + +import ( + "errors" + + "github.com/hashicorp/go-memdb" + + "github.com/hashicorp/consul/agent/consul/state" + "github.com/hashicorp/consul/agent/structs" +) + +// getArgsForSamenessGroupMembers returns the arguments for the sameness group members if SamenessGroup +// field is set in the ServiceSpecificRequest. It returns the index of the sameness group, the arguments +// for the sameness group members and an error if any. +// If SamenessGroup is not set, it returns: +// - the index 0 +// - an array containing the original arguments +// - nil error +// If SamenessGroup is set on CE, it returns:: +// - the index of 0 +// - nil array +// - an error indicating that sameness groups are not supported in consul CE +// If SamenessGroup is set on ENT, it returns: +// - the index of the sameness group +// - an array containing the arguments for the sameness group members +// - nil error +func (h *Health) getArgsForSamenessGroupMembers(args *structs.ServiceSpecificRequest, + ws memdb.WatchSet, state *state.Store) (uint64, []*structs.ServiceSpecificRequest, error) { + if args.SamenessGroup != "" { + return 0, nil, errors.New("sameness groups are not supported in consul CE") + } + return 0, []*structs.ServiceSpecificRequest{args}, nil +} diff --git a/agent/discovery/query_fetcher_v1.go b/agent/discovery/query_fetcher_v1.go index e2d424242e..da76d744dd 100644 --- a/agent/discovery/query_fetcher_v1.go +++ b/agent/discovery/query_fetcher_v1.go @@ -5,7 +5,6 @@ package discovery import ( "context" - "errors" "fmt" "net" "strings" @@ -469,7 +468,7 @@ func (f *V1DataFetcher) buildResultsFromServiceNodes(nodes []structs.CheckServic Namespace: n.Service.NamespaceOrEmpty(), Partition: n.Service.PartitionOrEmpty(), Datacenter: n.Node.Datacenter, - PeerName: req.Tenancy.Peer, + PeerName: n.Service.PeerName, }, }) } @@ -542,23 +541,10 @@ RPC: return &out, nil } +// fetchService is used to look up a service in the Consul catalog. func (f *V1DataFetcher) fetchService(ctx Context, req *QueryPayload, cfg *V1DataFetcherDynamicConfig, lookupType LookupType) ([]*Result, error) { - f.logger.Trace("fetchService", "req", req) - if req.Tenancy.SamenessGroup == "" { - return f.fetchServiceBasedOnTenancy(ctx, req, cfg, lookupType) - } - - return f.fetchServiceFromSamenessGroup(ctx, req, cfg, lookupType) -} - -// fetchServiceBasedOnTenancy is used to look up a service in the Consul catalog based on its tenancy or default tenancy. -func (f *V1DataFetcher) fetchServiceBasedOnTenancy(ctx Context, req *QueryPayload, - cfg *V1DataFetcherDynamicConfig, lookupType LookupType) ([]*Result, error) { - f.logger.Trace(fmt.Sprintf("fetchServiceBasedOnTenancy - req: %+v", req)) - if req.Tenancy.SamenessGroup != "" { - return nil, errors.New("sameness groups are not allowed for service lookups based on tenancy") - } + f.logger.Trace(fmt.Sprintf("fetchService - req: %+v", req)) // If no datacenter is passed, default to our own datacenter := cfg.Datacenter @@ -573,14 +559,13 @@ func (f *V1DataFetcher) fetchServiceBasedOnTenancy(ctx Context, req *QueryPayloa if req.Tag != "" { serviceTags = []string{req.Tag} } - healthFilterType := structs.HealthFilterExcludeCritical if cfg.OnlyPassing { healthFilterType = structs.HealthFilterIncludeOnlyPassing } - args := structs.ServiceSpecificRequest{ PeerName: req.Tenancy.Peer, + SamenessGroup: req.Tenancy.SamenessGroup, Connect: lookupType == LookupTypeConnect, Ingress: lookupType == LookupTypeIngress, Datacenter: datacenter, @@ -611,11 +596,6 @@ func (f *V1DataFetcher) fetchServiceBasedOnTenancy(ctx Context, req *QueryPayloa return nil, ErrNotFound } - // If we have no nodes, return not found! - if len(out.Nodes) == 0 { - return nil, ErrNotFound - } - // Perform a random shuffle out.Nodes.Shuffle() return f.buildResultsFromServiceNodes(out.Nodes, req, nil), nil diff --git a/agent/discovery/query_fetcher_v1_ce.go b/agent/discovery/query_fetcher_v1_ce.go index 59d32e91e2..090db0e5f7 100644 --- a/agent/discovery/query_fetcher_v1_ce.go +++ b/agent/discovery/query_fetcher_v1_ce.go @@ -6,9 +6,6 @@ package discovery import ( - "errors" - "fmt" - "github.com/hashicorp/consul/acl" ) @@ -27,12 +24,3 @@ func validateEnterpriseTenancy(req QueryTenancy) error { func queryTenancyToEntMeta(_ QueryTenancy) acl.EnterpriseMeta { return acl.EnterpriseMeta{} } - -// fetchServiceFromSamenessGroup fetches a service from a sameness group. -func (f *V1DataFetcher) fetchServiceFromSamenessGroup(ctx Context, req *QueryPayload, cfg *V1DataFetcherDynamicConfig, lookupType LookupType) ([]*Result, error) { - f.logger.Trace(fmt.Sprintf("fetchServiceFromSamenessGroup - req: %+v", req)) - if req.Tenancy.SamenessGroup == "" { - return nil, errors.New("sameness groups must be provided for service lookups") - } - return f.fetchServiceBasedOnTenancy(ctx, req, cfg, lookupType) -} diff --git a/agent/discovery/query_fetcher_v1_test.go b/agent/discovery/query_fetcher_v1_test.go index 450b0cb13a..f56e1f61b8 100644 --- a/agent/discovery/query_fetcher_v1_test.go +++ b/agent/discovery/query_fetcher_v1_test.go @@ -182,8 +182,9 @@ func Test_FetchEndpoints(t *testing.T) { Node: "node-name", }, Service: &structs.NodeService{ - Address: "service-address", - Service: "service-name", + Address: "service-address", + Service: "service-name", + PeerName: "test-peer", }, }, }, diff --git a/agent/dns.go b/agent/dns.go index 8ddfcaca3f..92dcd273e0 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -92,6 +92,7 @@ type serviceLookup struct { PeerName string Datacenter string Service string + SamenessGroup string Tag string MaxRecursionLevel int Connect bool @@ -439,18 +440,11 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) { // server side to avoid transferring the entire node list. if err := d.agent.RPC(context.Background(), "Catalog.ListNodes", &args, &out); err == nil { for _, n := range out.Nodes { - lookup := serviceLookup{ - // Peering PTR lookups are currently not supported, so we don't - // need to populate that field for creating the node FQDN. - // PeerName: n.PeerName, - Datacenter: n.Datacenter, - EnterpriseMeta: *n.GetEnterpriseMeta(), - } arpa, _ := dns.ReverseAddr(n.Address) if arpa == qName { ptr := &dns.PTR{ Hdr: dns.RR_Header{Name: q.Name, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: 0}, - Ptr: nodeCanonicalDNSName(lookup, n.Node, d.domain), + Ptr: nodeCanonicalDNSName(n, d.domain), } m.Answer = append(m.Answer, ptr) break @@ -738,6 +732,10 @@ type queryLocality struct { // not be shared between datacenters. In all other cases, it should be considered a DC. peerOrDatacenter string + // samenessGroup is the samenessGroup name parsed from a label that has explicit parts. + // Example query: .service..sg.consul + samenessGroup string + acl.EnterpriseMeta } @@ -805,59 +803,56 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi return invalid() } - localities, err := d.parseSamenessGroupLocality(cfg, querySuffixes, invalid) + locality, err := d.parseSamenessGroupLocality(cfg, querySuffixes, invalid) if err != nil { return err } - // Loop over the localities and return as soon as a lookup is successful - for _, locality := range localities { - d.logger.Debug("labels", "querySuffixes", querySuffixes) + lookup := serviceLookup{ + Datacenter: locality.effectiveDatacenter(d.agent.config.Datacenter), + PeerName: locality.peer, + SamenessGroup: locality.samenessGroup, + Connect: false, + Ingress: false, + MaxRecursionLevel: maxRecursionLevel, + EnterpriseMeta: locality.EnterpriseMeta, + } - lookup := serviceLookup{ - Datacenter: locality.effectiveDatacenter(d.agent.config.Datacenter), - PeerName: locality.peer, - Connect: false, - Ingress: false, - MaxRecursionLevel: maxRecursionLevel, - EnterpriseMeta: locality.EnterpriseMeta, - } - // Only one of dc or peer can be used. - if lookup.PeerName != "" { - lookup.Datacenter = "" + // Only one of dc or peer can be used. + if lookup.PeerName != "" { + lookup.Datacenter = "" + } + + // Support RFC 2782 style syntax + if n == 2 && strings.HasPrefix(queryParts[1], "_") && strings.HasPrefix(queryParts[0], "_") { + // Grab the tag since we make nuke it if it's tcp + tag := queryParts[1][1:] + + // Treat _name._tcp.service.consul as a default, no need to filter on that tag + if tag == "tcp" { + tag = "" } - // Support RFC 2782 style syntax - if n == 2 && strings.HasPrefix(queryParts[1], "_") && strings.HasPrefix(queryParts[0], "_") { - // Grab the tag since we make nuke it if it's tcp - tag := queryParts[1][1:] - - // Treat _name._tcp.service.consul as a default, no need to filter on that tag - if tag == "tcp" { - tag = "" - } - - lookup.Tag = tag - lookup.Service = queryParts[0][1:] - // _name._tag.service.consul - } else { - // Consul 0.3 and prior format for SRV queries - // Support "." in the label, re-join all the parts - tag := "" - if n >= 2 { - tag = strings.Join(queryParts[:n-1], ".") - } - - lookup.Tag = tag - lookup.Service = queryParts[n-1] - // tag[.tag].name.service.consul + lookup.Tag = tag + lookup.Service = queryParts[0][1:] + // _name._tag.service.consul + } else { + // Consul 0.3 and prior format for SRV queries + // Support "." in the label, re-join all the parts + tag := "" + if n >= 2 { + tag = strings.Join(queryParts[:n-1], ".") } - err = d.handleServiceQuery(cfg, lookup, req, resp) - // Return if we are error free right away, otherwise loop again if we can - if err == nil { - return nil - } + lookup.Tag = tag + lookup.Service = queryParts[n-1] + // tag[.tag].name.service.consul + } + + err = d.handleServiceQuery(cfg, lookup, req, resp) + // Return if we are error free right away, otherwise loop again if we can + if err == nil { + return nil } // We've exhausted all DNS possibilities so return here @@ -1456,6 +1451,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st } args := structs.ServiceSpecificRequest{ PeerName: lookup.PeerName, + SamenessGroup: lookup.SamenessGroup, Connect: lookup.Connect, Ingress: lookup.Ingress, Datacenter: lookup.Datacenter, @@ -1758,20 +1754,20 @@ func findWeight(node structs.CheckServiceNode) int { } } -func (d *DNSServer) encodeIPAsFqdn(questionName string, lookup serviceLookup, ip net.IP) string { +func (d *DNSServer) encodeIPAsFqdn(questionName string, serviceNode structs.CheckServiceNode, ip net.IP) string { ipv4 := ip.To4() respDomain := d.getResponseDomain(questionName) ipStr := hex.EncodeToString(ip) if ipv4 != nil { ipStr = ipStr[len(ipStr)-(net.IPv4len*2):] } - if lookup.PeerName != "" { + if serviceNode.Service.PeerName != "" { // Exclude the datacenter from the FQDN on the addr for peers. // This technically makes no difference, since the addr endpoint ignores the DC // component of the request, but do it anyway for a less confusing experience. return fmt.Sprintf("%s.addr.%s", ipStr, respDomain) } - return fmt.Sprintf("%s.addr.%s.%s", ipStr, lookup.Datacenter, respDomain) + return fmt.Sprintf("%s.addr.%s.%s", ipStr, serviceNode.Node.Datacenter, respDomain) } // Craft dns records for a an A record for an IP address @@ -1860,7 +1856,7 @@ func (d *DNSServer) makeRecordFromServiceNode(lookup serviceLookup, serviceNode if q.Qtype == dns.TypeSRV { respDomain := d.getResponseDomain(q.Name) - nodeFQDN := nodeCanonicalDNSName(lookup, serviceNode.Node.Node, respDomain) + nodeFQDN := nodeCanonicalDNSName(serviceNode.Node, respDomain) answers := []dns.RR{ &dns.SRV{ Hdr: dns.RR_Header{ @@ -1895,7 +1891,7 @@ func (d *DNSServer) makeRecordFromIP(lookup serviceLookup, addr net.IP, serviceN } if q.Qtype == dns.TypeSRV { - ipFQDN := d.encodeIPAsFqdn(q.Name, lookup, addr) + ipFQDN := d.encodeIPAsFqdn(q.Name, serviceNode, addr) answers := []dns.RR{ &dns.SRV{ Hdr: dns.RR_Header{ @@ -2076,7 +2072,7 @@ func (d *DNSServer) addServiceSRVRecordsToMessage(cfg *dnsConfig, lookup service resp.Extra = append(resp.Extra, extra...) if cfg.NodeMetaTXT { - resp.Extra = append(resp.Extra, d.makeTXTRecordFromNodeMeta(nodeCanonicalDNSName(lookup, node.Node.Node, respDomain), node.Node, ttl)...) + resp.Extra = append(resp.Extra, d.makeTXTRecordFromNodeMeta(nodeCanonicalDNSName(node.Node, respDomain), node.Node, ttl)...) } } } diff --git a/agent/dns_ce.go b/agent/dns_ce.go index 4eb74442fa..171a789945 100644 --- a/agent/dns_ce.go +++ b/agent/dns_ce.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" + "github.com/hashicorp/consul/agent/structs" ) // NOTE: these functions have also been copied to agent/dns package for dns v2. @@ -63,27 +64,27 @@ func (d *DNSServer) parseLocality(labels []string, cfg *dnsConfig) (queryLocalit type querySameness struct{} // parseSamenessGroupLocality wraps parseLocality in CE -func (d *DNSServer) parseSamenessGroupLocality(cfg *dnsConfig, labels []string, errfnc func() error) ([]queryLocality, error) { +func (d *DNSServer) parseSamenessGroupLocality(cfg *dnsConfig, labels []string, errfnc func() error) (queryLocality, error) { locality, ok := d.parseLocality(labels, cfg) if !ok { - return nil, errfnc() + return queryLocality{}, errfnc() } - return []queryLocality{locality}, nil + return locality, nil } func serviceCanonicalDNSName(name, kind, datacenter, domain string, _ *acl.EnterpriseMeta) string { return fmt.Sprintf("%s.%s.%s.%s", name, kind, datacenter, domain) } -func nodeCanonicalDNSName(lookup serviceLookup, nodeName, respDomain string) string { - if lookup.PeerName != "" { +func nodeCanonicalDNSName(node *structs.Node, respDomain string) string { + if node.PeerName != "" { // We must return a more-specific DNS name for peering so // that there is no ambiguity with lookups. return fmt.Sprintf("%s.node.%s.peer.%s", - nodeName, - lookup.PeerName, + node.Node, + node.PeerName, respDomain) } // Return a simpler format for non-peering nodes. - return fmt.Sprintf("%s.node.%s.%s", nodeName, lookup.Datacenter, respDomain) + return fmt.Sprintf("%s.node.%s.%s", node.Node, node.Datacenter, respDomain) } diff --git a/agent/health_endpoint.go b/agent/health_endpoint.go index 9c3492faf1..0001c35a11 100644 --- a/agent/health_endpoint.go +++ b/agent/health_endpoint.go @@ -188,6 +188,10 @@ func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Re } s.parsePeerName(req, &args) + s.parseSamenessGroup(req, &args) + if args.SamenessGroup != "" && args.PeerName != "" { + return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "peer-name and sameness-group are mutually exclusive"} + } // Check for tags params := req.URL.Query() @@ -214,7 +218,7 @@ func (s *HTTPHandlers) healthServiceNodes(resp http.ResponseWriter, req *http.Re prefix = "/v1/health/service/" } - // Parse out the service name from the query params + // Parse the service name from the query params args.ServiceName = strings.TrimPrefix(req.URL.Path, prefix) if args.ServiceName == "" { return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing service name"} diff --git a/agent/health_endpoint_ce_test.go b/agent/health_endpoint_ce_test.go new file mode 100644 index 0000000000..fd02d5a553 --- /dev/null +++ b/agent/health_endpoint_ce_test.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +//go:build !consulent + +package agent + +import ( + "github.com/hashicorp/consul/testrpc" + "github.com/stretchr/testify/require" + "net/http" + "net/http/httptest" + "testing" +) + +func TestHealthServiceNodes_SamenessGroup_ErrorsOnCE(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + t.Parallel() + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") + + req, _ := http.NewRequest("GET", "/v1/health/service/consul?dc=dc1&sameness-group=foo", nil) + resp := httptest.NewRecorder() + _, err := a.srv.HealthServiceNodes(resp, req) + require.ErrorContains(t, err, "sameness groups are not supported in consul CE") +} diff --git a/agent/http.go b/agent/http.go index d828ed04c1..66c3a8bd36 100644 --- a/agent/http.go +++ b/agent/http.go @@ -739,7 +739,7 @@ func decodeBody(body io.Reader, out interface{}) error { return lib.DecodeJSON(body, out) } -// decodeBodyDeprecated is deprecated, please ues decodeBody above. +// decodeBodyDeprecated is deprecated, please use decodeBody above. // decodeBodyDeprecated is used to decode a JSON request body func decodeBodyDeprecated(req *http.Request, out interface{}, cb func(interface{}) error) error { // This generally only happens in tests since real HTTP requests set @@ -1208,6 +1208,15 @@ func (s *HTTPHandlers) parsePeerName(req *http.Request, args *structs.ServiceSpe } } +func (s *HTTPHandlers) parseSamenessGroup(req *http.Request, args *structs.ServiceSpecificRequest) { + if sg := req.URL.Query().Get("sg"); sg != "" { + args.SamenessGroup = sg + } + if sg := req.URL.Query().Get("sameness-group"); sg != "" { + args.SamenessGroup = sg + } +} + // parseMetaFilter is used to parse the ?node-meta=key:value query parameter, used for // filtering results to nodes with the given metadata key/value func (s *HTTPHandlers) parseMetaFilter(req *http.Request) map[string]string { diff --git a/agent/rpcclient/health/health.go b/agent/rpcclient/health/health.go index 6732b2f88e..c20daa2e82 100644 --- a/agent/rpcclient/health/health.go +++ b/agent/rpcclient/health/health.go @@ -105,7 +105,12 @@ func (c *Client) useStreaming(req structs.ServiceSpecificRequest) bool { // Streaming is incompatible with NearestN queries (due to lack of ordering), // so we can only use it if the NearestN would never work (Node == "") // or if we explicitly say to ignore the Node field for queries (agentless xDS). - (req.Source.Node == "" || req.Source.DisableNode) + (req.Source.Node == "" || req.Source.DisableNode) && + // Streaming is incompatible with SamenessGroup queries at the moment because + // the subscribe functionality maps to queries based on the service name and tenancy information + // it does not support the ability to subscribe to the same service in different partitions or peers + // and materialize the results into a single view with the first healthy sameness group member. + req.SamenessGroup == "" } func (c *Client) newServiceRequest(req structs.ServiceSpecificRequest) serviceRequest { diff --git a/agent/rpcclient/health/health_test.go b/agent/rpcclient/health/health_test.go index 30900bc04c..24c1de120f 100644 --- a/agent/rpcclient/health/health_test.go +++ b/agent/rpcclient/health/health_test.go @@ -98,6 +98,17 @@ func TestClient_ServiceNodes_BackendRouting(t *testing.T) { }, expected: useRPC, }, + { + name: "rpc if sameness group", + req: structs.ServiceSpecificRequest{ + Datacenter: "dc1", + ServiceName: "web1", + SamenessGroup: "sg1", + MergeCentralConfig: false, + QueryOptions: structs.QueryOptions{MinQueryIndex: 22}, + }, + expected: useRPC, + }, } for _, tc := range testCases { @@ -246,6 +257,15 @@ func TestClient_Notify_BackendRouting(t *testing.T) { }, expected: useCache, }, + { + name: "use cache for sameness group request", + req: structs.ServiceSpecificRequest{ + Datacenter: "dc1", + ServiceName: "web1", + SamenessGroup: "test-group", + }, + expected: useCache, + }, } for _, tc := range testCases { diff --git a/agent/structs/deep-copy.sh b/agent/structs/deep-copy.sh index 1bc4ededd6..242d4e5ab2 100755 --- a/agent/structs/deep-copy.sh +++ b/agent/structs/deep-copy.sh @@ -52,6 +52,7 @@ deep-copy \ -type ServiceRoute \ -type ServiceRouteDestination \ -type ServiceRouteMatch \ + -type ServiceSpecificRequest \ -type TCPRouteConfigEntry \ -type Upstream \ -type UpstreamConfiguration \ diff --git a/agent/structs/structs.deepcopy.go b/agent/structs/structs.deepcopy.go index 9c9a7c8bc9..7d26a76469 100644 --- a/agent/structs/structs.deepcopy.go +++ b/agent/structs/structs.deepcopy.go @@ -1,4 +1,4 @@ -// generated by deep-copy -pointer-receiver -o ./structs.deepcopy.go -type APIGatewayListener -type BoundAPIGatewayListener -type CARoot -type CheckServiceNode -type CheckType -type CompiledDiscoveryChain -type ConnectProxyConfig -type DiscoveryFailover -type DiscoveryGraphNode -type DiscoveryResolver -type DiscoveryRoute -type DiscoverySplit -type ExposeConfig -type ExportedServicesConfigEntry -type FileSystemCertificateConfigEntry -type GatewayService -type GatewayServiceTLSConfig -type HTTPHeaderModifiers -type HTTPRouteConfigEntry -type HashPolicy -type HealthCheck -type IndexedCARoots -type IngressListener -type InlineCertificateConfigEntry -type Intention -type IntentionPermission -type LoadBalancer -type MeshConfigEntry -type MeshDirectionalTLSConfig -type MeshTLSConfig -type Node -type NodeService -type PeeringServiceMeta -type ServiceConfigEntry -type ServiceConfigResponse -type ServiceConnect -type ServiceDefinition -type ServiceResolverConfigEntry -type ServiceResolverFailover -type ServiceRoute -type ServiceRouteDestination -type ServiceRouteMatch -type TCPRouteConfigEntry -type Upstream -type UpstreamConfiguration -type Status -type BoundAPIGatewayConfigEntry ./; DO NOT EDIT. +// generated by deep-copy -pointer-receiver -o ./structs.deepcopy.go -type APIGatewayListener -type BoundAPIGatewayListener -type CARoot -type CheckServiceNode -type CheckType -type CompiledDiscoveryChain -type ConnectProxyConfig -type DiscoveryFailover -type DiscoveryGraphNode -type DiscoveryResolver -type DiscoveryRoute -type DiscoverySplit -type ExposeConfig -type ExportedServicesConfigEntry -type FileSystemCertificateConfigEntry -type GatewayService -type GatewayServiceTLSConfig -type HTTPHeaderModifiers -type HTTPRouteConfigEntry -type HashPolicy -type HealthCheck -type IndexedCARoots -type IngressListener -type InlineCertificateConfigEntry -type Intention -type IntentionPermission -type LoadBalancer -type MeshConfigEntry -type MeshDirectionalTLSConfig -type MeshTLSConfig -type Node -type NodeService -type PeeringServiceMeta -type ServiceConfigEntry -type ServiceConfigResponse -type ServiceConnect -type ServiceDefinition -type ServiceResolverConfigEntry -type ServiceResolverFailover -type ServiceRoute -type ServiceRouteDestination -type ServiceRouteMatch -type ServiceSpecificRequest -type TCPRouteConfigEntry -type Upstream -type UpstreamConfiguration -type Status -type BoundAPIGatewayConfigEntry ./; DO NOT EDIT. package structs @@ -1197,6 +1197,22 @@ func (o *ServiceRouteMatch) DeepCopy() *ServiceRouteMatch { return &cp } +// DeepCopy generates a deep copy of *ServiceSpecificRequest +func (o *ServiceSpecificRequest) DeepCopy() *ServiceSpecificRequest { + var cp ServiceSpecificRequest = *o + if o.NodeMetaFilters != nil { + cp.NodeMetaFilters = make(map[string]string, len(o.NodeMetaFilters)) + for k2, v2 := range o.NodeMetaFilters { + cp.NodeMetaFilters[k2] = v2 + } + } + if o.ServiceTags != nil { + cp.ServiceTags = make([]string, len(o.ServiceTags)) + copy(cp.ServiceTags, o.ServiceTags) + } + return &cp +} + // DeepCopy generates a deep copy of *TCPRouteConfigEntry func (o *TCPRouteConfigEntry) DeepCopy() *TCPRouteConfigEntry { var cp TCPRouteConfigEntry = *o diff --git a/agent/structs/structs.go b/agent/structs/structs.go index 1a90d863ca..cae14af52b 100644 --- a/agent/structs/structs.go +++ b/agent/structs/structs.go @@ -753,6 +753,9 @@ type ServiceSpecificRequest struct { // The name of the peer that the requested service was imported from. PeerName string + // The name of the sameness group that should be the target of the query. + SamenessGroup string + NodeMetaFilters map[string]string ServiceName string ServiceKind ServiceKind @@ -821,6 +824,7 @@ func (r *ServiceSpecificRequest) CacheInfo() cache.RequestInfo { r.Filter, r.EnterpriseMeta, r.PeerName, + r.SamenessGroup, r.Ingress, r.ServiceKind, r.MergeCentralConfig, diff --git a/api/api.go b/api/api.go index 5c23ae8b76..b90a45d92b 100644 --- a/api/api.go +++ b/api/api.go @@ -117,6 +117,13 @@ type QueryOptions struct { // Note: Partitions are available only in Consul Enterprise Partition string + // SamenessGroup is used find the SamenessGroup in the given + // Partition and will find the failover order for the Service + // from the SamenessGroup Members, with the given Partition being + // the first member. + // Note: SamenessGroups are available only in Consul Enterprise + SamenessGroup string + // Providing a datacenter overwrites the DC provided // by the Config Datacenter string @@ -847,6 +854,12 @@ func (r *request) setQueryOptions(q *QueryOptions) { // rather than the alternative short-hand "ap" r.params.Set("partition", q.Partition) } + if q.SamenessGroup != "" { + // For backwards-compatibility with existing tests, + // use the long-hand query param name "sameness-group" + // rather than the alternative short-hand "sg" + r.params.Set("sameness-group", q.SamenessGroup) + } if q.Datacenter != "" { // For backwards-compatibility with existing tests, // use the short-hand query param name "dc" From 94791f76b523a964e3e664d443356144333d7968 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Tue, 14 May 2024 15:49:03 -0400 Subject: [PATCH 028/185] build: update gha to latest approved tsccr (#21061) * build: update gha to latest approved tsccr * chore: update hashicorp gha versions * fix: update upload artifact workload to have unique ids --- .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 | 18 +++--- .github/workflows/build.yml | 60 +++++++++---------- .github/workflows/changelog-checker.yml | 2 +- .github/workflows/embedded-asset-checker.yml | 2 +- .github/workflows/frontend.yml | 22 +++---- .github/workflows/go-tests.yml | 26 ++++---- .github/workflows/issue-comment-created.yml | 2 +- .github/workflows/jira-issues.yaml | 6 +- .github/workflows/jira-pr.yaml | 6 +- .github/workflows/nightly-test-1.14.x.yaml | 36 +++++------ .github/workflows/nightly-test-1.15.x.yaml | 36 +++++------ .github/workflows/nightly-test-1.16.x.yaml | 36 +++++------ .github/workflows/nightly-test-1.17.x.yaml | 36 +++++------ .../nightly-test-integ-peering_commontopo.yml | 10 ++-- .../nightly-test-integrations-1.15.x.yml | 24 ++++---- .../nightly-test-integrations-1.16.x.yml | 24 ++++---- .../nightly-test-integrations-1.17.x.yml | 30 +++++----- .../workflows/nightly-test-integrations.yml | 30 +++++----- .github/workflows/nightly-test-main.yaml | 36 +++++------ .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 | 6 +- .github/workflows/reusable-dev-build.yml | 8 +-- .github/workflows/reusable-get-go-version.yml | 2 +- .github/workflows/reusable-lint.yml | 6 +- .github/workflows/reusable-unit-split.yml | 28 +++++---- .github/workflows/reusable-unit.yml | 24 +++++--- .github/workflows/security-scan.yml | 12 ++-- .github/workflows/stale.yml | 2 +- .../workflows/test-integrations-windows.yml | 12 ++-- .github/workflows/test-integrations.yml | 44 +++++++------- .github/workflows/verify-envoy-version.yml | 2 +- 36 files changed, 316 insertions(+), 302 deletions(-) diff --git a/.github/workflows/bot-auto-approve.yaml b/.github/workflows/bot-auto-approve.yaml index 911fc27f46..5851dbb1cb 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@f0939ea97e9205ef24d872e76833fa908a770363 # v4.0.0 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 d3dddccae7..e9b82a22e3 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Run lychee link checker id: lychee - uses: lycheeverse/lychee-action@ec3ed119d4f44ad2673a7232460dc7dff59d2421 # v1.8.0 + uses: lycheeverse/lychee-action@2b973e86fc7b1f6b36a93795fe2c9c6ae1118621 # v1.10.0 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@24452a72d85239eacf1468b0f1982a9f3fec4c94 # v5.0.0 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 3c4fb7e669..3c8bb35fc9 100644 --- a/.github/workflows/build-artifacts.yml +++ b/.github/workflows/build-artifacts.yml @@ -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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -52,7 +52,7 @@ jobs: - name: Fetch Secrets if: ${{ endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -61,14 +61,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} @@ -83,17 +83,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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 # 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@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.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@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.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 4930d77e36..3b29a4e47c 100644 --- a/.github/workflows/build-distros.yml +++ b/.github/workflows/build-distros.yml @@ -31,7 +31,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -60,14 +60,14 @@ 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: Build @@ -85,14 +85,14 @@ 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: Build @@ -111,7 +111,7 @@ jobs: CGO_ENABLED: 1 GOOS: linux steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git @@ -119,7 +119,7 @@ jobs: 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: | @@ -138,13 +138,13 @@ jobs: - check-go-mod runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: Build diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8921557c88..0225ab28a9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,12 +30,12 @@ jobs: pre-version: ${{ steps.set-product-version.outputs.prerelease-product-version }} shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # action-set-product-version implicitly sets fields like 'product-version' using version/VERSION # https://github.com/hashicorp/actions-set-product-version - name: set product version id: set-product-version - uses: hashicorp/actions-set-product-version@v1 + uses: hashicorp/actions-set-product-version@v2 - name: get product version id: get-product-version run: | @@ -70,7 +70,7 @@ jobs: filepath: ${{ steps.generate-metadata-file.outputs.filepath }} steps: - name: 'Checkout directory' - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Generate metadata file id: generate-metadata-file uses: hashicorp/actions-generate-metadata@v1 @@ -78,7 +78,7 @@ jobs: version: ${{ needs.set-product-version.outputs.product-version }} product: ${{ env.PKG_NAME }} - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: metadata.json path: ${{ steps.generate-metadata-file.outputs.filepath }} @@ -104,10 +104,10 @@ jobs: name: Go ${{ needs.get-go-version.outputs.go-version }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Setup with node and yarn - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' cache: 'yarn' @@ -132,7 +132,7 @@ jobs: PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} CGO_ENABLED: "0" GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@v0.1.7 + uses: hashicorp/actions-go-build@v1 with: product_name: ${{ env.PKG_NAME }} product_version: ${{ needs.set-product-version.outputs.product-version }} @@ -178,13 +178,13 @@ jobs: echo "RPM_PACKAGE=$(basename out/*.rpm)" >> $GITHUB_ENV echo "DEB_PACKAGE=$(basename out/*.deb)" >> $GITHUB_ENV - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ matrix.goos == 'linux' }} with: name: ${{ env.RPM_PACKAGE }} path: out/${{ env.RPM_PACKAGE }} - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ matrix.goos == 'linux' }} with: name: ${{ env.DEB_PACKAGE }} @@ -204,10 +204,10 @@ jobs: name: Go ${{ needs.get-go-version.outputs.go-version }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Setup with node and yarn - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' cache: 'yarn' @@ -232,7 +232,7 @@ jobs: PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} CGO_ENABLED: "0" GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@v0.1.7 + uses: hashicorp/actions-go-build@v1 with: product_name: ${{ env.PKG_NAME }} product_version: ${{ needs.set-product-version.outputs.product-version }} @@ -257,10 +257,10 @@ jobs: name: Go ${{ needs.get-go-version.outputs.go-version }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Setup with node and yarn - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' cache: 'yarn' @@ -283,7 +283,7 @@ jobs: PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} CGO_ENABLED: "0" GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@v0.1.7 + uses: hashicorp/actions-go-build@v1 with: product_name: ${{ env.PKG_NAME }} product_version: ${{ needs.set-product-version.outputs.product-version }} @@ -313,7 +313,7 @@ jobs: version: ${{needs.set-product-version.outputs.product-version}} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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 @@ -325,7 +325,7 @@ jobs: echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" >> $GITHUB_ENV - name: Docker Build (Action) - uses: hashicorp/actions-docker-build@v1 + uses: hashicorp/actions-docker-build@v2 with: version: ${{env.version}} target: default @@ -351,7 +351,7 @@ jobs: version: ${{needs.set-product-version.outputs.product-version}} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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 @@ -362,7 +362,7 @@ jobs: echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" >> $GITHUB_ENV - - uses: hashicorp/actions-docker-build@v1 + - uses: hashicorp/actions-docker-build@v2 with: version: ${{env.version}} target: ubi @@ -397,17 +397,17 @@ jobs: name: Verify ${{ matrix.arch }} linux binary steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 if: ${{ endsWith(github.repository, '-enterprise') || matrix.arch != 's390x' }} - name: Download ${{ matrix.arch }} zip if: ${{ endsWith(github.repository, '-enterprise') || matrix.arch != 's390x' }} - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: ${{ env.zip_name }} - name: Set up QEMU - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 if: ${{ matrix.arch == 'arm' || matrix.arch == 'arm64' }} with: # this should be a comma-separated string as opposed to an array @@ -430,10 +430,10 @@ jobs: name: Verify amd64 darwin binary steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Download amd64 darwin zip - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: ${{ env.zip_name }} @@ -461,7 +461,7 @@ jobs: name: Verify ${{ matrix.arch }} debian package steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Set package version run: | @@ -472,12 +472,12 @@ jobs: echo "pkg_name=consul_${{ env.pkg_version }}-1_${{ matrix.arch }}.deb" >> $GITHUB_ENV - name: Download workflow artifacts - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: ${{ env.pkg_name }} - name: Set up QEMU - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Set package version run: | @@ -513,12 +513,12 @@ jobs: echo "pkg_name=consul-${{ env.pkg_version }}-1.${{ matrix.arch }}.rpm" >> $GITHUB_ENV - name: Download workflow artifacts - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: ${{ env.pkg_name }} - name: Set up QEMU - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 with: platforms: all diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index 62b906eda3..597e4751b4 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 38879945e2..c42ae65ba1 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 3fbab0d9cf..93f8ee0bd0 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -33,9 +33,9 @@ jobs: run: working-directory: ui steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' @@ -53,9 +53,9 @@ jobs: needs: setup runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' @@ -83,9 +83,9 @@ jobs: CONSUL_NSPACES_ENABLED: 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' @@ -93,7 +93,7 @@ jobs: run: corepack enable - name: Install Chrome - uses: browser-actions/setup-chrome@c485fa3bab6be59dce18dbc18ef6ab7cbc8ff5f1 # v1.2.0 + uses: browser-actions/setup-chrome@82b9ce628cc5595478a9ebadc480958a36457dc2 # v1.6.0 - name: Install dependencies working-directory: ui @@ -123,9 +123,9 @@ jobs: CONSUL_NSPACES_ENABLED: 1 # 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: '18' @@ -133,7 +133,7 @@ jobs: run: corepack enable - name: Install Chrome - uses: browser-actions/setup-chrome@c485fa3bab6be59dce18dbc18ef6ab7cbc8ff5f1 # v1.2.0 + uses: browser-actions/setup-chrome@82b9ce628cc5595478a9ebadc480958a36457dc2 # v1.6.0 - name: Install dependencies working-directory: ui diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 920a2ed5c5..10ee2325c5 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -36,7 +36,7 @@ jobs: outputs: skip-ci: ${{ steps.read-files.outputs.skip-ci }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 - name: Get changed files @@ -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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -80,12 +80,12 @@ jobs: - get-go-version runs-on: ${{ fromJSON(needs.setup.outputs.compute-medium) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: make proto-tools @@ -106,12 +106,12 @@ jobs: - get-go-version runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: make --always-make codegen @@ -127,12 +127,12 @@ jobs: - get-go-version runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go install github.com/reillywatson/enumcover/cmd/enumcover@master && enumcover ./... @@ -143,11 +143,11 @@ jobs: - get-go-version runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: make lint-container-test-deps @@ -158,12 +158,12 @@ jobs: - get-go-version runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: make lint-consul-retry @@ -598,7 +598,7 @@ jobs: # FAILED_TESTS must also be checked to avoid running this step on cancellation due to the summary check above if: ${{ failure() && env.FAILED_TESTS == 'true' && (github.ref_name == 'main' || startsWith(github.ref_name, 'release/')) }} id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: # Escape entire message string to ensure valid JSON. If invalid, the notification will fail silently in CI. payload: | diff --git a/.github/workflows/issue-comment-created.yml b/.github/workflows/issue-comment-created.yml index 42483d92b1..950dc65d60 100644 --- a/.github/workflows/issue-comment-created.yml +++ b/.github/workflows/issue-comment-created.yml @@ -11,7 +11,7 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.3.0 with: labels: | diff --git a/.github/workflows/jira-issues.yaml b/.github/workflows/jira-issues.yaml index d2cd04748c..6899781791 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@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -90,14 +90,14 @@ jobs: - 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@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # 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@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # 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 b245abebcb..3a1aa5d6f1 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@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -104,14 +104,14 @@ jobs: - 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@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # 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@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" diff --git a/.github/workflows/nightly-test-1.14.x.yaml b/.github/workflows/nightly-test-1.14.x.yaml index 11fb011d13..8e85e175c2 100644 --- a/.github/workflows/nightly-test-1.14.x.yaml +++ b/.github/workflows/nightly-test-1.14.x.yaml @@ -17,12 +17,12 @@ jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -49,12 +49,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -71,7 +71,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +88,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -105,7 +105,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +121,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -143,7 +143,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +160,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -177,7 +177,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +191,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -208,7 +208,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +224,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-1.15.x.yaml b/.github/workflows/nightly-test-1.15.x.yaml index a98eb73070..c25e25ac57 100644 --- a/.github/workflows/nightly-test-1.15.x.yaml +++ b/.github/workflows/nightly-test-1.15.x.yaml @@ -17,12 +17,12 @@ jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -49,12 +49,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -71,7 +71,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +88,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -105,7 +105,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +121,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -143,7 +143,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +160,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -177,7 +177,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +191,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -208,7 +208,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +224,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-1.16.x.yaml b/.github/workflows/nightly-test-1.16.x.yaml index b441eca5d0..6dff72150f 100644 --- a/.github/workflows/nightly-test-1.16.x.yaml +++ b/.github/workflows/nightly-test-1.16.x.yaml @@ -17,12 +17,12 @@ jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -49,12 +49,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -71,7 +71,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +88,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -105,7 +105,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +121,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -143,7 +143,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +160,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -177,7 +177,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +191,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 14 cache: 'yarn' @@ -208,7 +208,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +224,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-1.17.x.yaml b/.github/workflows/nightly-test-1.17.x.yaml index 9a063001e4..ad6e49684d 100644 --- a/.github/workflows/nightly-test-1.17.x.yaml +++ b/.github/workflows/nightly-test-1.17.x.yaml @@ -17,12 +17,12 @@ jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -49,12 +49,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -71,7 +71,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +88,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -105,7 +105,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +121,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -143,7 +143,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +160,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -177,7 +177,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +191,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -208,7 +208,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +224,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-integ-peering_commontopo.yml b/.github/workflows/nightly-test-integ-peering_commontopo.yml index afedb50a9f..ab6554dc12 100644 --- a/.github/workflows/nightly-test-integ-peering_commontopo.yml +++ b/.github/workflows/nightly-test-integ-peering_commontopo.yml @@ -31,7 +31,7 @@ jobs: enterprise: ${{ steps.runners.outputs.enterprise }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.branch }} - id: runners @@ -64,12 +64,12 @@ jobs: env: ENVOY_VERSION: "1.24.6" steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env @@ -117,7 +117,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -157,7 +157,7 @@ jobs: - name: Notify Slack if: ${{ failure() }} id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index 5fbda17814..ead264db26 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -34,7 +34,7 @@ jobs: enterprise: ${{ steps.runners.outputs.enterprise }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - id: runners @@ -65,7 +65,7 @@ jobs: envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - name: Generate Envoy Job Matrix @@ -118,22 +118,22 @@ jobs: AWS_LAMBDA_REGION: us-west-2 steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 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 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - name: Envoy Integration Tests @@ -167,7 +167,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -207,21 +207,21 @@ jobs: ENVOY_VERSION: "1.24.6" steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env # Get go binary from workspace - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: . @@ -275,7 +275,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -317,7 +317,7 @@ jobs: - name: Notify Slack if: ${{ failure() }} id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-integrations-1.16.x.yml b/.github/workflows/nightly-test-integrations-1.16.x.yml index 8795baf9f7..9f7cee6713 100644 --- a/.github/workflows/nightly-test-integrations-1.16.x.yml +++ b/.github/workflows/nightly-test-integrations-1.16.x.yml @@ -34,7 +34,7 @@ jobs: enterprise: ${{ steps.runners.outputs.enterprise }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - id: runners @@ -65,7 +65,7 @@ jobs: envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - name: Generate Envoy Job Matrix @@ -118,15 +118,15 @@ jobs: AWS_LAMBDA_REGION: us-west-2 steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: ./bin @@ -134,7 +134,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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin @@ -170,7 +170,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -210,21 +210,21 @@ jobs: ENVOY_VERSION: "1.24.6" steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env # Get go binary from workspace - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: . @@ -296,7 +296,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -339,7 +339,7 @@ jobs: - name: Notify Slack if: ${{ failure() }} id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index 46940e1215..dadbb94e02 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -34,7 +34,7 @@ jobs: enterprise: ${{ steps.runners.outputs.enterprise }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - id: runners @@ -65,7 +65,7 @@ jobs: envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - name: Generate Envoy Job Matrix @@ -118,15 +118,15 @@ jobs: AWS_LAMBDA_REGION: us-west-2 steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: ./bin @@ -134,7 +134,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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin @@ -170,7 +170,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -210,21 +210,21 @@ jobs: ENVOY_VERSION: "1.24.6" steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env # Get go binary from workspace - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: . @@ -296,7 +296,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -335,14 +335,14 @@ jobs: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env @@ -387,7 +387,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -430,7 +430,7 @@ jobs: - name: Notify Slack if: ${{ failure() }} id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index b15b7f239d..637dbdcf52 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -32,7 +32,7 @@ jobs: enterprise: ${{ steps.runners.outputs.enterprise }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.branch }} - id: runners @@ -62,7 +62,7 @@ jobs: envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.branch }} - name: Generate Envoy Job Matrix @@ -115,15 +115,15 @@ jobs: AWS_LAMBDA_REGION: us-west-2 steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.branch }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: ./bin @@ -131,7 +131,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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin @@ -167,7 +167,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -210,21 +210,21 @@ jobs: ENVOY_VERSION: "1.26.6" steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.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 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env # Get go binary from workspace - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: . @@ -296,7 +296,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -334,14 +334,14 @@ jobs: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.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 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env @@ -385,7 +385,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -428,7 +428,7 @@ jobs: - name: Notify Slack if: ${{ failure() }} id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/nightly-test-main.yaml b/.github/workflows/nightly-test-main.yaml index a089121cc8..a3ce2edbb5 100644 --- a/.github/workflows/nightly-test-main.yaml +++ b/.github/workflows/nightly-test-main.yaml @@ -17,12 +17,12 @@ jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -49,12 +49,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -71,7 +71,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +88,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -105,7 +105,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +121,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -143,7 +143,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +160,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -177,7 +177,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +191,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: 18 cache: 'yarn' @@ -208,7 +208,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +224,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 0d6b71c9f0..579e7cbb65 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@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 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 d0bdac04f7..f3f15719dc 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 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 a646aa0712..7afb296b5a 100644 --- a/.github/workflows/reusable-check-go-mod.yml +++ b/.github/workflows/reusable-check-go-mod.yml @@ -21,12 +21,12 @@ jobs: runs-on: ${{ fromJSON(inputs.runs-on) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} # Run on all go.mod (include submodules). diff --git a/.github/workflows/reusable-dev-build-windows.yml b/.github/workflows/reusable-dev-build-windows.yml index 1417d1dbae..430331608f 100644 --- a/.github/workflows/reusable-dev-build-windows.yml +++ b/.github/workflows/reusable-dev-build-windows.yml @@ -28,12 +28,12 @@ jobs: build: runs-on: 'windows-2019' steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} - name: Build @@ -41,7 +41,7 @@ jobs: GOARCH: ${{ inputs.goarch }} run: go build . # save dev build to pass to downstream jobs - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: ${{inputs.uploaded-binary-name}} path: consul.exe diff --git a/.github/workflows/reusable-dev-build.yml b/.github/workflows/reusable-dev-build.yml index 511ea7925c..ce0e33471f 100644 --- a/.github/workflows/reusable-dev-build.yml +++ b/.github/workflows/reusable-dev-build.yml @@ -34,18 +34,18 @@ jobs: 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 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ inputs.branch-name }} if: inputs.branch-name != '' - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 if: inputs.branch-name == '' # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} - name: Build @@ -53,7 +53,7 @@ jobs: GOARCH: ${{ inputs.goarch }} run: make dev # save dev build to pass to downstream jobs - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: ${{inputs.uploaded-binary-name}} path: ./bin/consul diff --git a/.github/workflows/reusable-get-go-version.yml b/.github/workflows/reusable-get-go-version.yml index ea2d6f5c8f..2fac43b9da 100644 --- a/.github/workflows/reusable-get-go-version.yml +++ b/.github/workflows/reusable-get-go-version.yml @@ -18,7 +18,7 @@ jobs: go-version: ${{ steps.get-go-version.outputs.go-version }} go-version-previous: ${{ steps.get-go-version.outputs.go-version-previous }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Determine Go version id: get-go-version # We use .go-version as our source of truth for current Go diff --git a/.github/workflows/reusable-lint.yml b/.github/workflows/reusable-lint.yml index b834d56491..836a0bd3f6 100644 --- a/.github/workflows/reusable-lint.yml +++ b/.github/workflows/reusable-lint.yml @@ -42,19 +42,19 @@ jobs: fail-fast: true name: lint ${{ matrix.directory }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} - run: go env - name: Set golangci-lint version run: echo "GOLANGCI_LINT_VERSION=$(make --no-print-directory print-GOLANGCI_LINT_VERSION)" >> $GITHUB_ENV - name: lint-${{ matrix.directory }} - uses: golangci/golangci-lint-action@639cd343e1d3b897ff35927a75193d57cfcba299 # v3.6.0 + uses: golangci/golangci-lint-action@82d40c283aeb1f2b6595839195e95c2d6a49081b # v5.0.0 with: working-directory: ${{ matrix.directory }} version: ${{ env.GOLANGCI_LINT_VERSION }} diff --git a/.github/workflows/reusable-unit-split.yml b/.github/workflows/reusable-unit-split.yml index ab16db368b..ba0e88bbf1 100644 --- a/.github/workflows/reusable-unit-split.yml +++ b/.github/workflows/reusable-unit-split.yml @@ -63,8 +63,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} - id: set-matrix @@ -86,12 +86,20 @@ jobs: ulimit -Sa echo "Hard limits" ulimit -Ha - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + # upload-artifact requires a unique ID per run. These steps will be repeated with the matrix run, and other unit tests + # will also overlap with the names here. We use a random string rather than trying to do trickery + # with the package matrix. + - id: generate-matrix-id + run: | + MATRIX_RUN_ID=$(head /dev/urandom | tr -dc A-Z | head -c8) + echo "The matrix run ID is $MATRIX_RUN_ID" + echo "matrix-run-id=$MATRIX_RUN_ID" >> "$GITHUB_OUTPUT" + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} - run: mkdir -p ${{env.TEST_RESULTS}} @@ -99,7 +107,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@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: ${{inputs.uploaded-binary-name}} path: ${{inputs.directory}} @@ -143,7 +151,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -164,15 +172,15 @@ 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@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ !cancelled() }} with: - name: test-results + name: ${{ steps.generate-matrix-id.outputs.matrix-run-id }}-test-results path: ${{env.TEST_RESULTS}} - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ !cancelled() }} with: - name: jsonfile + name: ${{ steps.generate-matrix-id.outputs.matrix-run-id }}-jsonfile path: /tmp/jsonfile - name: "Re-run fails report" if: ${{ !cancelled() }} diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index 072999d79e..db06329401 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -56,12 +56,12 @@ jobs: go-test: runs-on: ${{ fromJSON(inputs.runs-on) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ inputs.go-version }} - run: mkdir -p ${{env.TEST_RESULTS}} @@ -69,7 +69,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@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: ${{inputs.uploaded-binary-name}} path: ${{inputs.directory}} @@ -110,7 +110,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -130,16 +130,22 @@ jobs: env: 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 + # upload-artifact requires a unique ID per run. These steps will overlap with other users of the reusable workflow. + # We use a random string rather than trying to pass in some identifying information. + - id: generate-run-id + run: | + RUN_ID=$(head /dev/urandom | tr -dc A-Z | head -c8) + echo "The run ID is $RUN_ID" + echo "run-id=$RUN_ID" >> "$GITHUB_OUTPUT" + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ !cancelled() }} with: - name: test-results + name: ${{ steps.generate-run-id.outputs.run-id }}-test-results path: ${{env.TEST_RESULTS}} - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 if: ${{ !cancelled() }} with: - name: jsonfile + name: ${{ steps.generate-run-id.outputs.run-id }}-jsonfile path: /tmp/jsonfile - name: "Re-run fails report" if: ${{ !cancelled() }} diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 60c91baf90..8c7af7a4f9 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -22,7 +22,7 @@ jobs: outputs: skip-ci: ${{ steps.read-files.outputs.skip-ci }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 - name: Get changed files @@ -40,7 +40,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -59,15 +59,15 @@ jobs: && (github.actor != 'dependabot[bot]') && (github.actor != 'hc-github-team-consul-core') }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Set up Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: Clone Security Scanner repo - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: repository: hashicorp/security-scanner token: ${{ secrets.HASHIBOT_PRODSEC_GITHUB_TOKEN }} @@ -87,6 +87,6 @@ jobs: cat results.sarif | jq - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@46a6823b81f2d7c67ddf123851eea88365bc8a67 # codeql-bundle-v2.13.5 + uses: github/codeql-action/upload-sarif@c4fb451437765abf5018c6fbf22cce1a7da1e5cc # codeql-bundle-v2.17.1 with: sarif_file: results.sarif \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ff07a961a4..a24da99989 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@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0 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 index e19e2333fd..2ce980ae76 100644 --- a/.github/workflows/test-integrations-windows.yml +++ b/.github/workflows/test-integrations-windows.yml @@ -28,7 +28,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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: runners run: .github/scripts/get_runner_classes_windows.sh @@ -69,13 +69,13 @@ 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: Fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: ${{ github.workspace }} @@ -96,7 +96,7 @@ jobs: docker build -t envoy-tcpdump -f Dockerfile-tcpdump-windows . - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 + uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Docker build consul run: docker build -t windows/consul -f Dockerfile-windows . @@ -1181,7 +1181,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 5c653dd31e..1c9fbcb0ca 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -37,7 +37,7 @@ jobs: outputs: skip-ci: ${{ steps.read-files.outputs.skip-ci }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 - name: Get changed files @@ -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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - id: runners run: .github/scripts/get_runner_classes.sh @@ -89,19 +89,19 @@ jobs: nomad-version: ['v1.7.3', 'v1.6.6', 'v1.5.13'] steps: - name: Checkout Nomad - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: repository: hashicorp/nomad ref: ${{ matrix.nomad-version }} - name: Install Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: # Do not explicitly set Go version here, as it should depend on what Nomad declares. go-version-file: 'go.mod' - name: Fetch Consul binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: ./bin @@ -134,7 +134,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -171,14 +171,14 @@ jobs: env: VAULT_BINARY_VERSION: ${{ matrix.vault-version }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: # We use the current Consul Go version here since Vault is installed as a binary # and tests are run from the Consul repo. @@ -218,7 +218,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -263,7 +263,7 @@ jobs: outputs: envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: Generate Envoy Job Matrix id: set-matrix env: @@ -313,13 +313,13 @@ 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: ./bin @@ -327,7 +327,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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin @@ -363,7 +363,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -398,12 +398,12 @@ jobs: ENVOY_VERSION: "1.28.2" CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi" steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env @@ -412,7 +412,7 @@ jobs: docker version docker info - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' path: . @@ -476,7 +476,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} @@ -512,12 +512,12 @@ jobs: DEPLOYER_CONSUL_DATAPLANE_IMAGE: "docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev" steps: - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 with: go-version: ${{ needs.get-go-version.outputs.go-version }} - run: go env @@ -560,7 +560,7 @@ jobs: - name: Fetch Secrets if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} id: secrets - uses: hashicorp/vault-action@v2.5.0 + uses: hashicorp/vault-action@v3 with: url: ${{ steps.vault-auth.outputs.addr }} caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} diff --git a/.github/workflows/verify-envoy-version.yml b/.github/workflows/verify-envoy-version.yml index dafa9db6f2..d27ad195d8 100644 --- a/.github/workflows/verify-envoy-version.yml +++ b/.github/workflows/verify-envoy-version.yml @@ -21,7 +21,7 @@ jobs: verify-envoy-version: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches From 04940e2c78496639e535460cb76adad784e09d7f Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 14 May 2024 15:33:34 -0600 Subject: [PATCH 029/185] additional changes to ensure sameness groups without DefaultForFailover can be used for DNS (#21107) --- agent/dns.go | 7 +-- agent/dns/discovery_results_fetcher.go | 3 ++ agent/health_endpoint_test.go | 6 +-- agent/structs/errors.go | 68 +++++++++++++------------- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/agent/dns.go b/agent/dns.go index 92dcd273e0..5e0f54a1b7 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -1096,9 +1096,10 @@ func rCodeFromError(err error) int { return dns.RcodeSuccess case errors.Is(err, errECSNotGlobal): return rCodeFromError(errors.Unwrap(err)) - case errors.Is(err, errNameNotFound): - return dns.RcodeNameError - case structs.IsErrNoDCPath(err) || structs.IsErrQueryNotFound(err): + case errors.Is(err, errNameNotFound), + structs.IsErrNoDCPath(err), + structs.IsErrQueryNotFound(err), + structs.IsErrSamenessGroupMustBeDefaultForFailover(err): return dns.RcodeNameError default: return dns.RcodeServerFailure diff --git a/agent/dns/discovery_results_fetcher.go b/agent/dns/discovery_results_fetcher.go index 0a3b70a4bd..f0012b9f77 100644 --- a/agent/dns/discovery_results_fetcher.go +++ b/agent/dns/discovery_results_fetcher.go @@ -69,6 +69,9 @@ func (d discoveryResultsFetcher) getQueryResults(opts *getQueryOptions) ([]*disc if getErrorFromECSNotGlobalError(err) != nil { opts.logger.Error("error processing discovery query", "error", err) + if structs.IsErrSamenessGroupMustBeDefaultForFailover(err) { + return nil, query, errNameNotFound + } return nil, query, err } return results, query, err diff --git a/agent/health_endpoint_test.go b/agent/health_endpoint_test.go index 4d7654bae3..98f4eaa714 100644 --- a/agent/health_endpoint_test.go +++ b/agent/health_endpoint_test.go @@ -834,9 +834,6 @@ func testHealthServiceNodes(t *testing.T, backendCfg *queryBackendConfiguration) _, err = strconv.ParseUint(header, 10, 64) require.NoError(r, err) - // Should be a cache hit! The data should've updated in the cache - // in the background so this should've been fetched directly from - // the cache. if backendCfg.cached { // Should be a cache hit! The data should've updated in the cache // in the background so this should've been fetched directly from @@ -1763,6 +1760,8 @@ func testHealthConnectServiceNodes(t *testing.T, backendCfg *queryBackendConfigu nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 1) assert.Len(t, nodes[0].Checks, 0) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) } func TestHealthIngressServiceNodes(t *testing.T) { @@ -2021,7 +2020,6 @@ func testHealthConnectServiceNodes_PassingFilter(t *testing.T, backendCfg *query // Should be 1 nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 1) - require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) diff --git a/agent/structs/errors.go b/agent/structs/errors.go index 31a818bd62..b92731770c 100644 --- a/agent/structs/errors.go +++ b/agent/structs/errors.go @@ -9,38 +9,40 @@ import ( ) const ( - errNoLeader = "No cluster leader" - errNoDCPath = "No path to datacenter" - errDCNotAvailable = "Remote DC has no server currently reachable" - errNoServers = "No known Consul servers" - errNotReadyForConsistentReads = "Not ready to serve consistent reads" - errSegmentsNotSupported = "Network segments are not supported in this version of Consul" - errRPCRateExceeded = "RPC rate limit exceeded" - 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" + errNoLeader = "No cluster leader" + errNoDCPath = "No path to datacenter" + errDCNotAvailable = "Remote DC has no server currently reachable" + errNoServers = "No known Consul servers" + errNotReadyForConsistentReads = "Not ready to serve consistent reads" + errSegmentsNotSupported = "Network segments are not supported in this version of Consul" + errRPCRateExceeded = "RPC rate limit exceeded" + 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" + errSamenessGroupMustBeDefaultForFailover = "Sameness Group must have DefaultForFailover set to true in order to use this endpoint" ) var ( - ErrNoLeader = errors.New(errNoLeader) - ErrNoDCPath = errors.New(errNoDCPath) - ErrNoServers = errors.New(errNoServers) - ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) - ErrSegmentsNotSupported = errors.New(errSegmentsNotSupported) - ErrRPCRateExceeded = errors.New(errRPCRateExceeded) - 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) + ErrNoLeader = errors.New(errNoLeader) + ErrNoDCPath = errors.New(errNoDCPath) + ErrNoServers = errors.New(errNoServers) + ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) + ErrSegmentsNotSupported = errors.New(errSegmentsNotSupported) + ErrRPCRateExceeded = errors.New(errRPCRateExceeded) + 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) + ErrSamenessGroupMustBeDefaultForFailover = errors.New(errSamenessGroupMustBeDefaultForFailover) ) func IsErrNoDCPath(err error) bool { @@ -59,10 +61,10 @@ func IsErrRPCRateExceeded(err error) bool { return err != nil && strings.Contains(err.Error(), errRPCRateExceeded) } -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) } + +func IsErrSamenessGroupMustBeDefaultForFailover(err error) bool { + return err != nil && strings.Contains(err.Error(), errSamenessGroupMustBeDefaultForFailover) +} From 8c54eae70578deb9a94c7efb995d983c181cf0cc Mon Sep 17 00:00:00 2001 From: wangxinyi7 Date: Wed, 15 May 2024 10:19:29 -0700 Subject: [PATCH 030/185] Xw/update changelog main (#21108) * update changelog --- CHANGELOG.md | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de182d13eb..6834dd84a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,115 @@ +## 1.18.2 (May 14, 2024) + +**Enterprise LTS**: Consul Enterprise 1.18 is a Long-Term Support (LTS) release. + +SECURITY: + +* Bump Dockerfile base image to `alpine:3.19`. [[GH-20897](https://github.com/hashicorp/consul/issues/20897)] +* Update `vault/api` to v1.12.2 to address [CVE-2024-28180](https://nvd.nist.gov/vuln/detail/CVE-2024-28180) + (removes indirect dependency on impacted `go-jose.v2`) [[GH-20910](https://github.com/hashicorp/consul/issues/20910)] +* Upgrade Go to use 1.21.10. This addresses CVEs + [CVE-2024-24787](https://nvd.nist.gov/vuln/detail/CVE-2024-24787) and + [CVE-2024-24788](https://nvd.nist.gov/vuln/detail/CVE-2024-24788) [[GH-21074](https://github.com/hashicorp/consul/issues/21074)] +* Upgrade to support Envoy `1.26.8, 1.27.4, 1.27.5, 1.28.2 and 1.28.3`. This resolves CVEs + [CVE-2024-27919](https://nvd.nist.gov/vuln/detail/CVE-2024-27919) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] and [CVE-2024-32475](https://nvd.nist.gov/vuln/detail/CVE-2024-32475) (`auto_sni`). [[GH-21030](https://github.com/hashicorp/consul/issues/21030)] +* Upgrade to support k8s.io/apimachinery `v0.18.7 or higher`. This resolves CVE + [CVE-2020-8559](https://nvd.nist.gov/vuln/detail/CVE-2020-8559). [[GH-21034](https://github.com/hashicorp/consul/issues/21034)] +* Upgrade to use Go `1.21.9`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* Upgrade to use golang.org/x/net `v0.24.0`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`x/net`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] + +IMPROVEMENTS: + +* gateways: service defaults configuration entries can now be used to set default upstream limits for mesh-gateways [[GH-20945](https://github.com/hashicorp/consul/issues/20945)] +* connect: Add ability to disable Auto Host Header Rewrite on Terminating Gateway at the service level [[GH-20802](https://github.com/hashicorp/consul/issues/20802)] + +BUG FIXES: + +* dns: fix a bug with sameness group queries in DNS where responses did not respect [`DefaultForFailover`](/consul/docs/connect/config-entries/sameness-group#defaultforfailover). + DNS requests against sameness groups without this field set will now error as intended. +* error running consul server in 1.18.0: failed to configure SCADA provider user's home directory path: $HOME is not defined [[GH-20926](https://github.com/hashicorp/consul/issues/20926)] +* server: fix Ent snapshot restore on CE when CE downgrade is enabled [[GH-20977](https://github.com/hashicorp/consul/issues/20977)] +* xds: Make TCP external service registered with terminating gateway reachable from peered cluster [[GH-19881](https://github.com/hashicorp/consul/issues/19881)] + +## 1.17.5 Enterprise (May 14, 2024) + +SECURITY: + +* Bump Dockerfile base image to `alpine:3.19`. [[GH-20897](https://github.com/hashicorp/consul/issues/20897)] +* Update `vault/api` to v1.12.2 to address [CVE-2024-28180](https://nvd.nist.gov/vuln/detail/CVE-2024-28180) + (removes indirect dependency on impacted `go-jose.v2`) [[GH-20910](https://github.com/hashicorp/consul/issues/20910)] +* Upgrade Go to use 1.21.10. This addresses CVEs + [CVE-2024-24787](https://nvd.nist.gov/vuln/detail/CVE-2024-24787) and + [CVE-2024-24788](https://nvd.nist.gov/vuln/detail/CVE-2024-24788) [[GH-21074](https://github.com/hashicorp/consul/issues/21074)] +* Upgrade to support Envoy `1.26.8, 1.27.4, 1.27.5, 1.28.2 and 1.28.3`. This resolves CVEs + [CVE-2024-27919](https://nvd.nist.gov/vuln/detail/CVE-2024-27919) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] and [CVE-2024-32475](https://nvd.nist.gov/vuln/detail/CVE-2024-32475) (`auto_sni`). [[GH-21030](https://github.com/hashicorp/consul/issues/21030)] +* Upgrade to support k8s.io/apimachinery `v0.18.7 or higher`. This resolves CVE + [CVE-2020-8559](https://nvd.nist.gov/vuln/detail/CVE-2020-8559). [[GH-21033](https://github.com/hashicorp/consul/issues/21033)] +* Upgrade to use Go `1.21.9`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* Upgrade to use golang.org/x/net `v0.24.0`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`x/net`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* security: Remove `coredns/coredns` dependency to address [CVE-2024-0874](https://nvd.nist.gov/vuln/detail/CVE-2024-0874) [[GH-9243](https://github.com/hashicorp/consul/issues/9243)] + +BUG FIXES: + +* dns: fix a bug with sameness group queries in DNS where responses did not respect [`DefaultForFailover`](/consul/docs/connect/config-entries/sameness-group#defaultforfailover). + DNS requests against sameness groups without this field set will now error as intended. +* xds: Make TCP external service registered with terminating gateway reachable from peered cluster [[GH-19881](https://github.com/hashicorp/consul/issues/19881)] + +## 1.16.8 Enterprise (May 14, 2024) + +SECURITY: + +* Bump Dockerfile base image to `alpine:3.19`. [[GH-20897](https://github.com/hashicorp/consul/issues/20897)] +* Update `vault/api` to v1.12.2 to address [CVE-2024-28180](https://nvd.nist.gov/vuln/detail/CVE-2024-28180) + (removes indirect dependency on impacted `go-jose.v2`) [[GH-20910](https://github.com/hashicorp/consul/issues/20910)] +* Upgrade Go to use 1.21.10. This addresses CVEs + [CVE-2024-24787](https://nvd.nist.gov/vuln/detail/CVE-2024-24787) and + [CVE-2024-24788](https://nvd.nist.gov/vuln/detail/CVE-2024-24788) [[GH-21074](https://github.com/hashicorp/consul/issues/21074)] +* Upgrade to support Envoy `1.26.8, 1.27.4, 1.27.5, 1.28.2 and 1.28.3`. This resolves CVEs + [CVE-2024-27919](https://nvd.nist.gov/vuln/detail/CVE-2024-27919) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] and [CVE-2024-32475](https://nvd.nist.gov/vuln/detail/CVE-2024-32475) (`auto_sni`). [[GH-21030](https://github.com/hashicorp/consul/issues/21030)] +* Upgrade to support k8s.io/apimachinery `v0.18.7 or higher`. This resolves CVE + [CVE-2020-8559](https://nvd.nist.gov/vuln/detail/CVE-2020-8559). [[GH-21032](https://github.com/hashicorp/consul/issues/21032)] +* Upgrade to use Go `1.21.9`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* Upgrade to use golang.org/x/net `v0.24.0`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`x/net`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* security: Remove `coredns/coredns` dependency to address [CVE-2024-0874](https://nvd.nist.gov/vuln/detail/CVE-2024-0874) [[GH-9244](https://github.com/hashicorp/consul/issues/9244)] + +BUG FIXES: + +* dns: fix a bug with sameness group queries in DNS where responses did not respect [`DefaultForFailover`](/consul/docs/connect/config-entries/sameness-group#defaultforfailover). + DNS requests against sameness groups without this field set will now error as intended. +* xds: Make TCP external service registered with terminating gateway reachable from peered cluster [[GH-19881](https://github.com/hashicorp/consul/issues/19881)] + +## 1.15.12 Enterprise (May 14, 2024) + +**Enterprise LTS**: Consul Enterprise 1.15 is a Long-Term Support (LTS) release. + +SECURITY: + +* Bump Dockerfile base image to `alpine:3.19`. [[GH-20897](https://github.com/hashicorp/consul/issues/20897)] +* Update `vault/api` to v1.12.2 to address [CVE-2024-28180](https://nvd.nist.gov/vuln/detail/CVE-2024-28180) + (removes indirect dependency on impacted `go-jose.v2`) [[GH-20910](https://github.com/hashicorp/consul/issues/20910)] +* Upgrade Go to use 1.21.10. This addresses CVEs + [CVE-2024-24787](https://nvd.nist.gov/vuln/detail/CVE-2024-24787) and + [CVE-2024-24788](https://nvd.nist.gov/vuln/detail/CVE-2024-24788) [[GH-21074](https://github.com/hashicorp/consul/issues/21074)] +* Upgrade to support Envoy `1.26.8, 1.27.4, 1.27.5, 1.28.2 and 1.28.3`. This resolves CVEs + [CVE-2024-27919](https://nvd.nist.gov/vuln/detail/CVE-2024-27919) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] and [CVE-2024-32475](https://nvd.nist.gov/vuln/detail/CVE-2024-32475) (`auto_sni`). [[GH-21030](https://github.com/hashicorp/consul/issues/21030)] +* Upgrade to support k8s.io/apimachinery `v0.18.7 or higher`. This resolves CVE + [CVE-2020-8559](https://nvd.nist.gov/vuln/detail/CVE-2020-8559). [[GH-21030](https://github.com/hashicorp/consul/issues/21030)] +* Upgrade to use Go `1.21.9`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`http2`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* Upgrade to use golang.org/x/net `v0.24.0`. This resolves CVE + [CVE-2023-45288](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) (`x/net`). [[GH-20956](https://github.com/hashicorp/consul/issues/20956)] +* security: Remove `coredns/coredns` dependency to address [CVE-2024-0874](https://nvd.nist.gov/vuln/detail/CVE-2024-0874) [[GH-9245](https://github.com/hashicorp/consul/issues/9245)] + +BUG FIXES: + +* xds: Make TCP external service registered with terminating gateway reachable from peered cluster [[GH-19881](https://github.com/hashicorp/consul/issues/19881)] + ## 1.18.1 (March 26, 2024) Enterprise LTS: Consul Enterprise 1.18 is a Long-Term Support (LTS) release. From 3c24c4918dbdf91bbbb88189785affbe3ff34172 Mon Sep 17 00:00:00 2001 From: Becki Lee Date: Wed, 15 May 2024 14:40:32 -0400 Subject: [PATCH 031/185] docs: Fix two small typos in "What is Consul?" introduction (#21110) docs: Fix two typos in Consul introduction --- website/content/docs/intro/index.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/intro/index.mdx b/website/content/docs/intro/index.mdx index 9bf7989b44..1708f3d84b 100644 --- a/website/content/docs/intro/index.mdx +++ b/website/content/docs/intro/index.mdx @@ -7,7 +7,7 @@ description: >- # What is Consul? -HashiCorp Consul is a service networking solution that enables teams to manage secure network connectivity between services and across on-prem and multi-cloud environments and runtimes. Consul offers service discovery, service mesh, traffic management, and automated updates to network infrastructure device. You can use these features individually or together in a single Consul deployment. +HashiCorp Consul is a service networking solution that enables teams to manage secure network connectivity between services and across on-prem and multi-cloud environments and runtimes. Consul offers service discovery, service mesh, traffic management, and automated updates to network infrastructure devices. You can use these features individually or together in a single Consul deployment. > **Hands-on**: Complete the Getting Started tutorials to learn how to deploy Consul: - [Get Started on Kubernetes](/consul/tutorials/get-started-kubernetes) @@ -55,7 +55,7 @@ You can also schedule Consul workloads with [HashiCorp Nomad](https://www.nomadp ### Enable zero-trust network security -Microservice architectures are complex and difficult to secure against accidental discloser to malicious actors. Consul provides several mechanisms that enhance network security without any changes to your application code, including mutual transport layer security (mTLS) encryption on all traffic between services and Consul intentions, which are service-to-service permissions that you can manage through the Consul UI, API, and CLI. +Microservice architectures are complex and difficult to secure against accidental disclosure to malicious actors. Consul provides several mechanisms that enhance network security without any changes to your application code, including mutual transport layer security (mTLS) encryption on all traffic between services and Consul intentions, which are service-to-service permissions that you can manage through the Consul UI, API, and CLI. When you deploy Consul to Kubernetes clusters, you can also integrate with [HashiCorp Vault](https://www.vaultproject.io/) to manage sensitive data. By default, Consul on Kubernetes leverages Kubernetes secrets as the backend system. Kubernetes secrets are base64 encoded, unencrypted, and lack lease or time-to-live properties. By leveraging Vault as a secrets backend for Consul on Kubernetes, you can manage and store Consul related secrets within a centralized Vault cluster to use across one or many Consul on Kubernetes datacenters. Refer to [Vault as the Secrets Backend](/consul/docs/k8s/deployment-configurations/vault) for additional information. From 9b9c83691569bb9ee769774082aedb98d2b28a03 Mon Sep 17 00:00:00 2001 From: John Murret Date: Wed, 15 May 2024 17:52:11 -0600 Subject: [PATCH 032/185] latest ui files in main (#21119) --- ...css => chunk.143.514eb80cfd7d0554773a.css} | 2 +- ...b.js => chunk.143.514eb80cfd7d0554773a.js} | 8 +- ...f.js => chunk.178.6f0fd5b292c40b1ce063.js} | 6 +- ...routes-50ef0656ce15ca397f130b4f71463b3d.js | 1 - ...rvices-0f03ec98fed9bf2a0b847a11efca654f.js | 1 - ...ul-ui-6998e44e8a8ea2039fda574ce1ac1be5.css | 2 + ...ul-ui-a3d723b2486613aa25201645e617bbf2.js} | 288 ++++++++++-------- ...ul-ui-ebf15e0a88f8aa4b2e353442d718d20d.css | 2 - ...outes-447282731d763ac6ad60d55ed447a4a6.js} | 2 +- agent/uiserver/dist/index.html | 18 +- 10 files changed, 171 insertions(+), 159 deletions(-) rename agent/uiserver/dist/assets/{chunk.143.db9b393ab5086aec385b.css => chunk.143.514eb80cfd7d0554773a.css} (90%) rename agent/uiserver/dist/assets/{chunk.143.db9b393ab5086aec385b.js => chunk.143.514eb80cfd7d0554773a.js} (97%) rename agent/uiserver/dist/assets/{chunk.178.ee7822d83932910fd2ef.js => chunk.178.6f0fd5b292c40b1ce063.js} (91%) delete mode 100644 agent/uiserver/dist/assets/consul-hcp/routes-50ef0656ce15ca397f130b4f71463b3d.js delete mode 100644 agent/uiserver/dist/assets/consul-hcp/services-0f03ec98fed9bf2a0b847a11efca654f.js create mode 100644 agent/uiserver/dist/assets/consul-ui-6998e44e8a8ea2039fda574ce1ac1be5.css rename agent/uiserver/dist/assets/{consul-ui-88f8ddeb1f6a751c68c9f1de8978befa.js => consul-ui-a3d723b2486613aa25201645e617bbf2.js} (93%) delete mode 100644 agent/uiserver/dist/assets/consul-ui-ebf15e0a88f8aa4b2e353442d718d20d.css rename agent/uiserver/dist/assets/consul-ui/{routes-e47ed633758c4b43c40de4ae84cdf564.js => routes-447282731d763ac6ad60d55ed447a4a6.js} (97%) diff --git a/agent/uiserver/dist/assets/chunk.143.db9b393ab5086aec385b.css b/agent/uiserver/dist/assets/chunk.143.514eb80cfd7d0554773a.css similarity index 90% rename from agent/uiserver/dist/assets/chunk.143.db9b393ab5086aec385b.css rename to agent/uiserver/dist/assets/chunk.143.514eb80cfd7d0554773a.css index 0f89c12af7..792cf60b33 100644 --- a/agent/uiserver/dist/assets/chunk.143.db9b393ab5086aec385b.css +++ b/agent/uiserver/dist/assets/chunk.143.514eb80cfd7d0554773a.css @@ -1,3 +1,3 @@ .tippy-box[data-placement^=top]>.tippy-svg-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-svg-arrow:after,.tippy-box[data-placement^=top]>.tippy-svg-arrow>svg{top:16px;transform:rotate(180deg)}.tippy-box[data-placement^=bottom]>.tippy-svg-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-placement^=left]>.tippy-svg-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-svg-arrow:after,.tippy-box[data-placement^=left]>.tippy-svg-arrow>svg{transform:rotate(90deg);top:calc(50% - 3px);left:11px}.tippy-box[data-placement^=right]>.tippy-svg-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-svg-arrow:after,.tippy-box[data-placement^=right]>.tippy-svg-arrow>svg{transform:rotate(-90deg);top:calc(50% - 3px);right:11px}.tippy-svg-arrow{width:16px;height:16px;fill:#333;text-align:initial}.tippy-svg-arrow,.tippy-svg-arrow>svg{position:absolute} -/*# sourceMappingURL=chunk.143.db9b393ab5086aec385b.css-481e257b97fcf81c5a59ed89bec95f69.map*/ \ No newline at end of file +/*# sourceMappingURL=chunk.143.514eb80cfd7d0554773a.css-dab4810f7765b133c18bff2650e193b5.map*/ \ No newline at end of file diff --git a/agent/uiserver/dist/assets/chunk.143.db9b393ab5086aec385b.js b/agent/uiserver/dist/assets/chunk.143.514eb80cfd7d0554773a.js similarity index 97% rename from agent/uiserver/dist/assets/chunk.143.db9b393ab5086aec385b.js rename to agent/uiserver/dist/assets/chunk.143.514eb80cfd7d0554773a.js index 9e26ff5adc..401037dc38 100644 --- a/agent/uiserver/dist/assets/chunk.143.db9b393ab5086aec385b.js +++ b/agent/uiserver/dist/assets/chunk.143.514eb80cfd7d0554773a.js @@ -7,8 +7,8 @@ e.exports=require("@ember/modifier")},7219:e=>{"use strict" e.exports=require("@ember/object")},8773:e=>{"use strict" e.exports=require("@ember/runloop")},8574:e=>{"use strict" e.exports=require("@ember/service")},1866:e=>{"use strict" -e.exports=require("@ember/utils")},657:(e,r,t)=>{var n,o -e.exports=(n=_eai_d,o=_eai_r,window.emberAutoImportDynamic=function(e){return 1===arguments.length?o("_eai_dyn_"+e):o("_eai_dynt_"+e)(Array.prototype.slice.call(arguments,1))},window.emberAutoImportSync=function(e){return o("_eai_sync_"+e)(Array.prototype.slice.call(arguments,1))},n("@hashicorp/flight-icons/svg",[],(function(){return t(6604)})),n("@hashicorp/flight-icons/svg-sprite/svg-sprite-module",[],(function(){return t(2654)})),n("@lit/reactive-element",[],(function(){return t(8531)})),n("@xstate/fsm",[],(function(){return t(7440)})),n("a11y-dialog",[],(function(){return t(1413)})),n("base64-js",[],(function(){return t(8294)})),n("clipboard",[],(function(){return t(9079)})),n("d3-array",[],(function(){return t(5447)})),n("d3-scale",[],(function(){return t(5134)})),n("d3-scale-chromatic",[],(function(){return t(2331)})),n("d3-selection",[],(function(){return t(8740)})),n("d3-shape",[],(function(){return t(5043)})),n("dayjs",[],(function(){return t(2350)})),n("dayjs/plugin/calendar",[],(function(){return t(8888)})),n("dayjs/plugin/relativeTime",[],(function(){return t(2543)})),n("deepmerge",[],(function(){return t(3924)})),n("ember-focus-trap/modifiers/focus-trap.js",["@ember/modifier"],(function(){return t(3109)})),n("ember-keyboard/helpers/if-key.js",["@ember/component/helper","@ember/debug","@ember/utils"],(function(){return t(3481)})),n("ember-keyboard/helpers/on-key.js",["@ember/component/helper","@ember/debug","@ember/service"],(function(){return t(6415)})),n("ember-keyboard/modifiers/on-key.js",["@ember/application","@ember/modifier","@ember/destroyable","@ember/service","@ember/object","@ember/debug","@ember/utils"],(function(){return t(4146)})),n("ember-keyboard/services/keyboard.js",["@ember/service","@ember/application","@ember/object","@ember/runloop","@ember/debug","@ember/utils"],(function(){return t(9690)})),n("ember-modifier",["@ember/application","@ember/modifier","@ember/destroyable"],(function(){return t(2509)})),n("fast-memoize",[],(function(){return t(3276)})),n("flat",[],(function(){return t(2349)})),n("intl-messageformat",[],(function(){return t(5861)})),n("intl-messageformat-parser",[],(function(){return t(5011)})),n("mnemonist/multi-map",[],(function(){return t(5709)})),n("mnemonist/set",[],(function(){return t(2519)})),n("ngraph.graph",[],(function(){return t(6001)})),n("parse-duration",[],(function(){return t(89)})),n("pretty-ms",[],(function(){return t(9837)})),n("tippy.js",[],(function(){return t(9640)})),n("tippy.js/dist/svg-arrow.css",[],(function(){return t(2959)})),n("validated-changeset",[],(function(){return t(6885)})),n("wayfarer",[],(function(){return t(7116)})),n("_eai_dyn_dialog-polyfill",[],(function(){return t.e(121).then(t.bind(t,4121))})),void n("_eai_dyn_dialog-polyfill-css",[],(function(){return t.e(744).then(t.bind(t,7744))})))},1760:function(e,r){window._eai_r=require,window._eai_d=define}},o={} +e.exports=require("@ember/utils")},9357:(e,r,t)=>{var n,o +e.exports=(n=_eai_d,o=_eai_r,window.emberAutoImportDynamic=function(e){return 1===arguments.length?o("_eai_dyn_"+e):o("_eai_dynt_"+e)(Array.prototype.slice.call(arguments,1))},window.emberAutoImportSync=function(e){return o("_eai_sync_"+e)(Array.prototype.slice.call(arguments,1))},n("@hashicorp/flight-icons/svg",[],(function(){return t(6604)})),n("@hashicorp/flight-icons/svg-sprite/svg-sprite-module",[],(function(){return t(2654)})),n("@lit/reactive-element",[],(function(){return t(8531)})),n("@xstate/fsm",[],(function(){return t(7440)})),n("a11y-dialog",[],(function(){return t(1413)})),n("base64-js",[],(function(){return t(8294)})),n("clipboard",[],(function(){return t(9079)})),n("d3-array",[],(function(){return t(5447)})),n("d3-scale",[],(function(){return t(5134)})),n("d3-scale-chromatic",[],(function(){return t(2331)})),n("d3-selection",[],(function(){return t(8740)})),n("d3-shape",[],(function(){return t(5043)})),n("dayjs",[],(function(){return t(2350)})),n("dayjs/plugin/calendar",[],(function(){return t(8888)})),n("dayjs/plugin/relativeTime",[],(function(){return t(2543)})),n("deepmerge",[],(function(){return t(3924)})),n("ember-focus-trap/modifiers/focus-trap.js",["@ember/modifier"],(function(){return t(3109)})),n("ember-keyboard/helpers/if-key.js",["@ember/component/helper","@ember/debug","@ember/utils"],(function(){return t(3481)})),n("ember-keyboard/helpers/on-key.js",["@ember/component/helper","@ember/debug","@ember/service"],(function(){return t(6415)})),n("ember-keyboard/modifiers/on-key.js",["@ember/application","@ember/modifier","@ember/destroyable","@ember/service","@ember/object","@ember/debug","@ember/utils"],(function(){return t(4146)})),n("ember-keyboard/services/keyboard.js",["@ember/service","@ember/application","@ember/object","@ember/runloop","@ember/debug","@ember/utils"],(function(){return t(9690)})),n("ember-modifier",["@ember/application","@ember/modifier","@ember/destroyable"],(function(){return t(2509)})),n("fast-memoize",[],(function(){return t(3276)})),n("flat",[],(function(){return t(2349)})),n("intl-messageformat",[],(function(){return t(5861)})),n("intl-messageformat-parser",[],(function(){return t(5011)})),n("mnemonist/multi-map",[],(function(){return t(5709)})),n("mnemonist/set",[],(function(){return t(2519)})),n("ngraph.graph",[],(function(){return t(6001)})),n("parse-duration",[],(function(){return t(89)})),n("pretty-ms",[],(function(){return t(9837)})),n("tippy.js",[],(function(){return t(9640)})),n("tippy.js/dist/svg-arrow.css",[],(function(){return t(2959)})),n("validated-changeset",[],(function(){return t(6885)})),n("wayfarer",[],(function(){return t(7116)})),n("_eai_dyn_dialog-polyfill",[],(function(){return t.e(121).then(t.bind(t,4121))})),void n("_eai_dyn_dialog-polyfill-css",[],(function(){return t.e(744).then(t.bind(t,7744))})))},3404:function(e,r){window._eai_r=require,window._eai_d=define}},o={} function i(e){var r=o[e] if(void 0!==r)return r.exports var t=o[e]={exports:{}} @@ -47,6 +47,6 @@ var r=(r,t)=>{var n,o,[u,a,s]=t,c=0 if(u.some((r=>0!==e[r]))){for(n in a)i.o(a,n)&&(i.m[n]=a[n]) if(s)var l=s(i)}for(r&&r(t);ci(1760))) -var u=i.O(void 0,[924],(()=>i(657))) +t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),i.O(void 0,[924],(()=>i(3404))) +var u=i.O(void 0,[924],(()=>i(9357))) u=i.O(u),__ember_auto_import__=u})() diff --git a/agent/uiserver/dist/assets/chunk.178.ee7822d83932910fd2ef.js b/agent/uiserver/dist/assets/chunk.178.6f0fd5b292c40b1ce063.js similarity index 91% rename from agent/uiserver/dist/assets/chunk.178.ee7822d83932910fd2ef.js rename to agent/uiserver/dist/assets/chunk.178.6f0fd5b292c40b1ce063.js index 2c477d5653..fa8fae203c 100644 --- a/agent/uiserver/dist/assets/chunk.178.ee7822d83932910fd2ef.js +++ b/agent/uiserver/dist/assets/chunk.178.6f0fd5b292c40b1ce063.js @@ -1,4 +1,4 @@ -var __ember_auto_import__;(()=>{var r,e={9265:()=>{},3642:()=>{},1760:function(r,e){window._eai_r=require,window._eai_d=define},1471:(r,e,t)=>{var o,n +var __ember_auto_import__;(()=>{var r,e={9265:()=>{},3642:()=>{},3404:function(r,e){window._eai_r=require,window._eai_d=define},974:(r,e,t)=>{var o,n r.exports=(o=_eai_d,n=_eai_r,window.emberAutoImportDynamic=function(r){return 1===arguments.length?n("_eai_dyn_"+r):n("_eai_dynt_"+r)(Array.prototype.slice.call(arguments,1))},window.emberAutoImportSync=function(r){return n("_eai_sync_"+r)(Array.prototype.slice.call(arguments,1))},o("lodash.castarray",[],(function(){return t(9542)})),o("lodash.last",[],(function(){return t(9644)})),o("lodash.omit",[],(function(){return t(1609)})),o("qunit",[],(function(){return t(2053)})),void o("yadda",[],(function(){return t(2216)})))}},t={} function o(r){var n=t[r] if(void 0!==n)return n.exports @@ -16,6 +16,6 @@ var e=(e,t)=>{var n,i,[a,u,l]=t,_=0 if(a.some((e=>0!==r[e]))){for(n in u)o.o(u,n)&&(o.m[n]=u[n]) if(l)var c=l(o)}for(e&&e(t);_o(1760))) -var n=o.O(void 0,[778],(()=>o(1471))) +t.forEach(e.bind(null,0)),t.push=e.bind(null,t.push.bind(t))})(),o.O(void 0,[778],(()=>o(3404))) +var n=o.O(void 0,[778],(()=>o(974))) n=o.O(n),__ember_auto_import__=n})() diff --git a/agent/uiserver/dist/assets/consul-hcp/routes-50ef0656ce15ca397f130b4f71463b3d.js b/agent/uiserver/dist/assets/consul-hcp/routes-50ef0656ce15ca397f130b4f71463b3d.js deleted file mode 100644 index 703c187720..0000000000 --- a/agent/uiserver/dist/assets/consul-hcp/routes-50ef0656ce15ca397f130b4f71463b3d.js +++ /dev/null @@ -1 +0,0 @@ -((e,t=("undefined"!=typeof document?document.currentScript.dataset:module.exports))=>{t.routes=JSON.stringify(e)})({dc:{show:null}}) diff --git a/agent/uiserver/dist/assets/consul-hcp/services-0f03ec98fed9bf2a0b847a11efca654f.js b/agent/uiserver/dist/assets/consul-hcp/services-0f03ec98fed9bf2a0b847a11efca654f.js deleted file mode 100644 index dc99739254..0000000000 --- a/agent/uiserver/dist/assets/consul-hcp/services-0f03ec98fed9bf2a0b847a11efca654f.js +++ /dev/null @@ -1 +0,0 @@ -((e,o=("undefined"!=typeof document?document.currentScript.dataset:module.exports))=>{o.services=JSON.stringify(e)})({"component:consul/hcp/home":{class:"consul-ui/components/consul/hcp/home"}}) diff --git a/agent/uiserver/dist/assets/consul-ui-6998e44e8a8ea2039fda574ce1ac1be5.css b/agent/uiserver/dist/assets/consul-ui-6998e44e8a8ea2039fda574ce1ac1be5.css new file mode 100644 index 0000000000..ce065de1b5 --- /dev/null +++ b/agent/uiserver/dist/assets/consul-ui-6998e44e8a8ea2039fda574ce1ac1be5.css @@ -0,0 +1,2 @@ +@charset "UTF-8";/*! tailwindcss v3.2.7 | MIT License | https://tailwindcss.com + */.hds-table,table{border-spacing:0}input[type=checkbox],input[type=radio],progress,sub,sup{vertical-align:baseline}.hover\:scale-125:hover,.scale-100,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.ease-in-out,.transition{transition-timing-function:cubic-bezier(.4,0,.2,1)}*,::after,::before{border-width:0;border-style:solid;border-color:currentColor}html{line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-feature-settings:normal}a,hr{color:inherit}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto}[hidden]{display:none}*,::after,::backdrop,::before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scroll-snap-strictness:proximity;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.hds-side-nav,.sticky{position:sticky}.bottom-0{bottom:0}.isolate{isolation:isolate}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-4{margin-left:1rem}.mr-0{margin-right:0}.mr-0\.5{margin-right:.125rem}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mr-2\.5{margin-right:.625rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.contents{display:contents}.hidden{display:none}.h-12{height:3rem}.h-16{height:4rem}.h-24{height:6rem}.h-4{height:1rem}.h-48{height:12rem}.h-8{height:2rem}.h-full{height:100%}.h-screen{height:100vh}.\!w-80{width:20rem!important}.w-24{width:6rem}.w-4{width:1rem}.w-8{width:2rem}.w-full{width:100%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-col,.hds-accordion{flex-direction:column}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.cursor-pointer{cursor:pointer}.resize{resize:both}.flex-nowrap{flex-wrap:nowrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.space-x-12>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(3rem * var(--tw-space-x-reverse));margin-left:calc(3rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.overflow-x-auto{overflow-x:auto}.overflow-y-scroll{overflow-y:scroll}.hds-breadcrumb__text,.hds-card__container--overflow-hidden,.truncate{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.border{border-width:1px}.p-6{padding:1.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize,.type-source.popover-select li:not(.partition) button{text-transform:capitalize}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 rgb(0 0 0 / 0.1),0 1px 2px -1px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hds-elevation-inset,.hds-form-checkbox:not(:checked,:indeterminate){box-shadow:var(--token-elevation-inset-box-shadow)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:150ms}.consul-surface-nav{background:var(--token-color-palette-neutral-700)}:root{--token-color-palette-blue-500:#1c345f;--token-color-palette-blue-400:#0046d1;--token-color-palette-blue-300:#0c56e9;--token-color-palette-blue-200:#1060ff;--token-color-palette-blue-100:#cce3fe;--token-color-palette-blue-50:#f2f8ff;--token-color-palette-purple-500:#42215b;--token-color-palette-purple-400:#7b00db;--token-color-palette-purple-300:#911ced;--token-color-palette-purple-200:#a737ff;--token-color-palette-purple-100:#ead2fe;--token-color-palette-purple-50:#f9f2ff;--token-color-palette-green-500:#054220;--token-color-palette-green-400:#006619;--token-color-palette-green-300:#00781e;--token-color-palette-green-200:#008a22;--token-color-palette-green-100:#cceeda;--token-color-palette-green-50:#f2fbf6;--token-color-palette-amber-500:#542800;--token-color-palette-amber-400:#803d00;--token-color-palette-amber-300:#9e4b00;--token-color-palette-amber-200:#bb5a00;--token-color-palette-amber-100:#fbeabf;--token-color-palette-amber-50:#fff9e8;--token-color-palette-red-500:#51130a;--token-color-palette-red-400:#940004;--token-color-palette-red-300:#c00005;--token-color-palette-red-200:#e52228;--token-color-palette-red-100:#fbd4d4;--token-color-palette-red-50:#fff5f5;--token-color-palette-neutral-700:#0c0c0e;--token-color-palette-neutral-600:#3b3d45;--token-color-palette-neutral-500:#656a76;--token-color-palette-neutral-400:#8c909c;--token-color-palette-neutral-300:#c2c5cb;--token-color-palette-neutral-200:#dedfe3;--token-color-palette-neutral-100:#f1f2f3;--token-color-palette-neutral-50:#fafafa;--token-color-palette-neutral-0:#ffffff;--token-color-palette-alpha-300:#3b3d4566;--token-color-palette-alpha-200:#656a7633;--token-color-palette-alpha-100:#656a761a;--token-color-border-primary:#656a7633;--token-color-border-faint:#656a761a;--token-color-border-strong:#3b3d4566;--token-color-border-action:#cce3fe;--token-color-border-highlight:#ead2fe;--token-color-border-success:#cceeda;--token-color-border-warning:#fbeabf;--token-color-border-critical:#fbd4d4;--token-color-focus-action-internal:#0c56e9;--token-color-focus-action-external:#5990ff;--token-color-focus-critical-internal:#c00005;--token-color-focus-critical-external:#dd7578;--token-color-foreground-strong:#0c0c0e;--token-color-foreground-primary:#3b3d45;--token-color-foreground-faint:#656a76;--token-color-foreground-high-contrast:#ffffff;--token-color-foreground-disabled:#8c909c;--token-color-foreground-action:#1060ff;--token-color-foreground-action-hover:#0c56e9;--token-color-foreground-action-active:#0046d1;--token-color-foreground-highlight:#a737ff;--token-color-foreground-highlight-on-surface:#911ced;--token-color-foreground-highlight-high-contrast:#42215b;--token-color-foreground-success:#008a22;--token-color-foreground-success-on-surface:#00781e;--token-color-foreground-success-high-contrast:#054220;--token-color-foreground-warning:#bb5a00;--token-color-foreground-warning-on-surface:#9e4b00;--token-color-foreground-warning-high-contrast:#542800;--token-color-foreground-critical:#e52228;--token-color-foreground-critical-on-surface:#c00005;--token-color-foreground-critical-high-contrast:#51130a;--token-color-page-primary:#ffffff;--token-color-page-faint:#fafafa;--token-color-surface-primary:#ffffff;--token-color-surface-faint:#fafafa;--token-color-surface-strong:#f1f2f3;--token-color-surface-interactive:#ffffff;--token-color-surface-interactive-hover:#f1f2f3;--token-color-surface-interactive-active:#dedfe3;--token-color-surface-interactive-disabled:#fafafa;--token-color-surface-action:#f2f8ff;--token-color-surface-highlight:#f9f2ff;--token-color-surface-success:#f2fbf6;--token-color-surface-warning:#fff9e8;--token-color-surface-critical:#fff5f5;--token-color-hashicorp-brand:#000000;--token-color-boundary-brand:#f24c53;--token-color-boundary-foreground:#cf2d32;--token-color-boundary-surface:#ffecec;--token-color-boundary-border:#fbd7d8;--token-color-boundary-gradient-primary-start:#f97076;--token-color-boundary-gradient-primary-stop:#db363b;--token-color-boundary-gradient-faint-start:#fffafa;--token-color-boundary-gradient-faint-stop:#ffecec;--token-color-consul-brand:#e03875;--token-color-consul-foreground:#d01c5b;--token-color-consul-surface:#ffe9f1;--token-color-consul-border:#ffcede;--token-color-consul-gradient-primary-start:#ff99be;--token-color-consul-gradient-primary-stop:#da306e;--token-color-consul-gradient-faint-start:#fff9fb;--token-color-consul-gradient-faint-stop:#ffe9f1;--token-color-hcp-brand:#000000;--token-color-nomad-brand:#06d092;--token-color-nomad-foreground:#008661;--token-color-nomad-surface:#d3fdeb;--token-color-nomad-border:#bff3dd;--token-color-nomad-gradient-primary-start:#bff3dd;--token-color-nomad-gradient-primary-stop:#60dea9;--token-color-nomad-gradient-faint-start:#f3fff9;--token-color-nomad-gradient-faint-stop:#d3fdeb;--token-color-packer-brand:#02a8ef;--token-color-packer-foreground:#007eb4;--token-color-packer-surface:#d4f2ff;--token-color-packer-border:#b4e4ff;--token-color-packer-gradient-primary-start:#b4e4ff;--token-color-packer-gradient-primary-stop:#63d0ff;--token-color-packer-gradient-faint-start:#f3fcff;--token-color-packer-gradient-faint-stop:#d4f2ff;--token-color-terraform-brand:#7b42bc;--token-color-terraform-foreground:#773cb4;--token-color-terraform-surface:#f4ecff;--token-color-terraform-border:#ebdbfc;--token-color-terraform-gradient-primary-start:#bb8deb;--token-color-terraform-gradient-primary-stop:#844fba;--token-color-terraform-gradient-faint-start:#fcfaff;--token-color-terraform-gradient-faint-stop:#f4ecff;--token-color-vagrant-brand:#1868f2;--token-color-vagrant-foreground:#1c61d8;--token-color-vagrant-surface:#d6ebff;--token-color-vagrant-border:#c7dbfc;--token-color-vagrant-gradient-primary-start:#c7dbfc;--token-color-vagrant-gradient-primary-stop:#7dadff;--token-color-vagrant-gradient-faint-start:#f4faff;--token-color-vagrant-gradient-faint-stop:#d6ebff;--token-color-vault-secrets-brand:#ffd814;--token-color-vault-secrets-brand-alt:#000000;--token-color-vault-secrets-foreground:#9a6f00;--token-color-vault-secrets-surface:#fff9cf;--token-color-vault-secrets-border:#feec7b;--token-color-vault-secrets-gradient-primary-start:#feec7b;--token-color-vault-secrets-gradient-primary-stop:#ffe543;--token-color-vault-secrets-gradient-faint-start:#fffdf2;--token-color-vault-secrets-gradient-faint-stop:#fff9cf;--token-color-vault-brand:#ffd814;--token-color-vault-brand-alt:#000000;--token-color-vault-foreground:#9a6f00;--token-color-vault-surface:#fff9cf;--token-color-vault-border:#feec7b;--token-color-vault-gradient-primary-start:#feec7b;--token-color-vault-gradient-primary-stop:#ffe543;--token-color-vault-gradient-faint-start:#fffdf2;--token-color-vault-gradient-faint-stop:#fff9cf;--token-color-waypoint-brand:#14c6cb;--token-color-waypoint-foreground:#008196;--token-color-waypoint-surface:#e0fcff;--token-color-waypoint-border:#cbf1f3;--token-color-waypoint-gradient-primary-start:#cbf1f3;--token-color-waypoint-gradient-primary-stop:#62d4dc;--token-color-waypoint-gradient-faint-start:#f6feff;--token-color-waypoint-gradient-faint-stop:#e0fcff;--token-elevation-inset-box-shadow:inset 0px 1px 2px 1px #656a761a;--token-elevation-low-box-shadow:0px 1px 1px 0px #656a760d,0px 2px 2px 0px #656a760d;--token-elevation-mid-box-shadow:0px 2px 3px 0px #656a761a,0px 8px 16px -10px #656a7633;--token-elevation-high-box-shadow:0px 2px 3px 0px #656a7626,0px 16px 16px -10px #656a7633;--token-elevation-higher-box-shadow:0px 2px 3px 0px #656a761a,0px 12px 28px 0px #656a7640;--token-elevation-overlay-box-shadow:0px 2px 3px 0px #3b3d4540,0px 12px 24px 0px #3b3d4559;--token-surface-inset-box-shadow:inset 0 0 0 1px #656a764d,inset 0px 1px 2px 1px #656a761a;--token-surface-base-box-shadow:0 0 0 1px #656a7633;--token-surface-low-box-shadow:0 0 0 1px #656a7626,0px 1px 1px 0px #656a760d,0px 2px 2px 0px #656a760d;--token-surface-mid-box-shadow:0 0 0 1px #656a7626,0px 2px 3px 0px #656a761a,0px 8px 16px -10px #656a7633;--token-surface-high-box-shadow:0 0 0 1px #656a7640,0px 2px 3px 0px #656a7626,0px 16px 16px -10px #656a7633;--token-surface-higher-box-shadow:0 0 0 1px #656a7633,0px 2px 3px 0px #656a761a,0px 12px 28px 0px #656a7640;--token-surface-overlay-box-shadow:0 0 0 1px #3b3d4540,0px 2px 3px 0px #3b3d4540,0px 12px 24px 0px #3b3d4559;--token-focus-ring-action-box-shadow:inset 0 0 0 1px #0c56e9,0 0 0 3px #5990ff;--token-focus-ring-critical-box-shadow:inset 0 0 0 1px #c00005,0 0 0 3px #dd7578;--token-form-label-color:#0c0c0e;--token-form-legend-color:#0c0c0e;--token-form-helper-text-color:#656a76;--token-form-indicator-optional-color:#656a76;--token-form-error-color:#c00005;--token-form-error-icon-size:14px;--token-form-checkbox-size:16px;--token-form-checkbox-border-radius:3px;--token-form-checkbox-border-width:1px;--token-form-checkbox-background-image-size:12px;--token-form-checkbox-background-image-data-url:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%23FFF'/%3e%3c/svg%3e");--token-form-checkbox-background-image-data-url-indeterminate:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='m2.03125,6a0.66146,0.75 0 0 1 0.66146,-0.75l6.61458,0a0.66146,0.75 0 0 1 0,1.5l-6.61458,0a0.66146,0.75 0 0 1 -0.66146,-0.75z' fill='%23FFF'/%3e%3c/svg%3e");--token-form-checkbox-background-image-data-url-disabled:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%238C909C'/%3e%3c/svg%3e");--token-form-checkbox-background-image-data-url-indeterminate-disabled:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='m2.03125,6a0.66146,0.75 0 0 1 0.66146,-0.75l6.61458,0a0.66146,0.75 0 0 1 0,1.5l-6.61458,0a0.66146,0.75 0 0 1 -0.66146,-0.75z' fill='%238C909C'/%3e%3c/svg%3e");--token-form-control-base-foreground-value-color:#0c0c0e;--token-form-control-base-foreground-placeholder-color:#656a76;--token-form-control-base-surface-color-default:#ffffff;--token-form-control-base-surface-color-hover:#f1f2f3;--token-form-control-base-border-color-default:#8c909c;--token-form-control-base-border-color-hover:#656a76;--token-form-control-checked-foreground-color:#ffffff;--token-form-control-checked-surface-color-default:#1060ff;--token-form-control-checked-surface-color-hover:#0c56e9;--token-form-control-checked-border-color-default:#0c56e9;--token-form-control-checked-border-color-hover:#0046d1;--token-form-control-invalid-border-color-default:#c00005;--token-form-control-invalid-border-color-hover:#940004;--token-form-control-readonly-foreground-color:#3b3d45;--token-form-control-readonly-surface-color:#f1f2f3;--token-form-control-readonly-border-color:#656a761a;--token-form-control-disabled-foreground-color:#8c909c;--token-form-control-disabled-surface-color:#fafafa;--token-form-control-disabled-border-color:#656a7633;--token-form-control-padding:7px;--token-form-control-border-radius:5px;--token-form-control-border-width:1px;--token-form-radio-size:16px;--token-form-radio-border-width:1px;--token-form-radio-background-image-size:12px;--token-form-radio-background-image-data-url:url("data:image/svg+xml,%3csvg width='12' height='12' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='6' cy='6' r='2.5' fill='%23ffffff'/%3e%3c/svg%3e");--token-form-radio-background-image-data-url-disabled:url("data:image/svg+xml,%3csvg width='12' height='12' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='6' cy='6' r='2.5' fill='%238C909C'/%3e%3c/svg%3e");--token-form-radiocard-group-gap:16px;--token-form-radiocard-border-width:1px;--token-form-radiocard-border-radius:6px;--token-form-radiocard-content-padding:24px;--token-form-radiocard-control-padding:8px;--token-form-radiocard-transition-duration:0.2s;--token-form-select-background-image-size:16px;--token-form-select-background-image-position-right-x:7px;--token-form-select-background-image-position-top-y:9px;--token-form-select-background-image-data-url:url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.55 2.24a.75.75 0 0 0-1.1 0L4.2 5.74a.75.75 0 1 0 1.1 1.02L8 3.852l2.7 2.908a.75.75 0 1 0 1.1-1.02l-3.25-3.5Zm-1.1 11.52a.75.75 0 0 0 1.1 0l3.25-3.5a.75.75 0 1 0-1.1-1.02L8 12.148 5.3 9.24a.75.75 0 0 0-1.1 1.02l3.25 3.5Z' fill='%23656A76'/%3E%3C/svg%3E");--token-form-select-background-image-data-url-disabled:url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.55 2.24a.75.75 0 0 0-1.1 0L4.2 5.74a.75.75 0 1 0 1.1 1.02L8 3.852l2.7 2.908a.75.75 0 1 0 1.1-1.02l-3.25-3.5Zm-1.1 11.52a.75.75 0 0 0 1.1 0l3.25-3.5a.75.75 0 1 0-1.1-1.02L8 12.148 5.3 9.24a.75.75 0 0 0-1.1 1.02l3.25 3.5Z' fill='%238C909C'/%3E%3C/svg%3E");--token-form-text-input-background-image-size:16px;--token-form-text-input-background-image-position-x:7px;--token-form-text-input-background-image-data-url-date:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M11.5.75a.75.75 0 00-1.5 0V1H6V.75a.75.75 0 00-1.5 0V1H3.25A2.25 2.25 0 001 3.25v9.5A2.25 2.25 0 003.25 15h9.5A2.25 2.25 0 0015 12.75v-9.5A2.25 2.25 0 0012.75 1H11.5V.75zm-7 2.5V2.5H3.25a.75.75 0 00-.75.75V5h11V3.25a.75.75 0 00-.75-.75H11.5v.75a.75.75 0 01-1.5 0V2.5H6v.75a.75.75 0 01-1.5 0zm9 3.25h-11v6.25c0 .414.336.75.75.75h9.5a.75.75 0 00.75-.75V6.5z' fill-rule='evenodd' clip-rule='evenodd' fill='%233B3D45'/%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-time:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cg fill='%233B3D45'%3e%3cpath d='M8.5 3.75a.75.75 0 00-1.5 0V8c0 .284.16.544.415.67l2.5 1.25a.75.75 0 10.67-1.34L8.5 7.535V3.75z'/%3e%3cpath d='M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z' fill-rule='evenodd' clip-rule='evenodd'/%3e%3c/g%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-search:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cg fill='%23656A76'%3e%3cpath d='M7.25 2a5.25 5.25 0 103.144 9.455l2.326 2.325a.75.75 0 101.06-1.06l-2.325-2.326A5.25 5.25 0 007.25 2zM3.5 7.25a3.75 3.75 0 117.5 0 3.75 3.75 0 01-7.5 0z' fill-rule='evenodd' clip-rule='evenodd'/%3e%3c/g%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-search-cancel:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.78 4.28a.75.75 0 00-1.06-1.06L8 6.94 4.28 3.22a.75.75 0 00-1.06 1.06L6.94 8l-3.72 3.72a.75.75 0 101.06 1.06L8 9.06l3.72 3.72a.75.75 0 101.06-1.06L9.06 8l3.72-3.72z'/%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-search-loading:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg' %3e%3cg fill='%23656A76' fill-rule='evenodd' clip-rule='evenodd'%3e%3canimateTransform attributeName='transform' type='rotate' dur='0.9s' from='0 8 8' to='360 8 8' repeatCount='indefinite'/%3e%3cpath d='M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z' opacity='.2'/%3e%3cpath d='M7.25.75A.75.75 0 018 0a8 8 0 018 8 .75.75 0 01-1.5 0A6.5 6.5 0 008 1.5a.75.75 0 01-.75-.75z'/%3e%3c/g%3e%3c/svg%3e");--token-form-toggle-width:32px;--token-form-toggle-height:16px;--token-form-toggle-base-surface-color-default:#f1f2f3;--token-form-toggle-border-radius:3px;--token-form-toggle-border-width:1px;--token-form-toggle-background-image-size:12px;--token-form-toggle-background-image-position-x:2px;--token-form-toggle-background-image-data-url:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%23FFF'/%3e%3c/svg%3e");--token-form-toggle-background-image-data-url-disabled:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%238C909C'/%3e%3c/svg%3e");--token-form-toggle-transition-duration:0.2s;--token-form-toggle-transition-timing-function:cubic-bezier(0.68, -0.2, 0.265, 1.15);--token-form-toggle-thumb-size:16px;--token-pagination-nav-control-height:36px;--token-pagination-nav-control-padding-horizontal:12px;--token-pagination-nav-control-focus-inset:4px;--token-pagination-nav-control-icon-spacing:6px;--token-pagination-nav-indicator-height:2px;--token-pagination-nav-indicator-spacing:6px;--token-pagination-child-spacing-vertical:8px;--token-pagination-child-spacing-horizontal:20px;--token-side-nav-wrapper-border-width:1px;--token-side-nav-wrapper-border-color:#656a76;--token-side-nav-wrapper-padding-horizontal:16px;--token-side-nav-wrapper-padding-vertical:16px;--token-side-nav-wrapper-padding-horizontal-minimized:8px;--token-side-nav-wrapper-padding-vertical-minimized:22px;--token-side-nav-toggle-button-border-radius:5px;--token-side-nav-header-home-link-padding:4px;--token-side-nav-header-home-link-logo-size:48px;--token-side-nav-header-home-link-logo-size-minimized:32px;--token-side-nav-header-actions-spacing:8px;--token-side-nav-body-list-margin-vertical:24px;--token-side-nav-body-list-item-height:36px;--token-side-nav-body-list-item-padding-horizontal:8px;--token-side-nav-body-list-item-padding-vertical:4px;--token-side-nav-body-list-item-spacing-vertical:2px;--token-side-nav-body-list-item-content-spacing-horizontal:8px;--token-side-nav-body-list-item-border-radius:5px;--token-side-nav-color-foreground-primary:#dedfe3;--token-side-nav-color-foreground-strong:#fff;--token-side-nav-color-foreground-faint:#8c909c;--token-side-nav-color-surface-primary:#0c0c0e;--token-side-nav-color-surface-interactive-hover:#3b3d45;--token-side-nav-color-surface-interactive-active:#656a76;--token-tabs-tab-height:36px;--token-tabs-tab-padding-horizontal:12px;--token-tabs-tab-padding-vertical:0px;--token-tabs-tab-border-radius:5px;--token-tabs-tab-focus-inset:6px;--token-tabs-tab-gutter:6px;--token-tabs-indicator-height:3px;--token-tabs-indicator-transition-function:cubic-bezier(0.5, 1, 0.89, 1);--token-tabs-indicator-transition-duration:0.6s;--token-tabs-divider-height:1px;--token-tooltip-border-radius:5px;--token-tooltip-color-foreground-primary:var(--token-color-foreground-high-contrast);--token-tooltip-color-surface-primary:var(--token-color-palette-neutral-700);--token-tooltip-focus-offset:-2px;--token-tooltip-max-width:280px;--token-tooltip-padding-horizontal:12px;--token-tooltip-padding-vertical:8px;--token-tooltip-transition-function:cubic-bezier(0.54, 1.5, 0.38, 1.11);--token-typography-font-stack-display:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-font-stack-text:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-font-stack-code:ui-monospace,Menlo,Consolas,monospace;--token-typography-font-weight-regular:400;--token-typography-font-weight-medium:500;--token-typography-font-weight-semibold:600;--token-typography-font-weight-bold:700;--token-typography-display-500-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-500-font-size:1.875rem;--token-typography-display-500-line-height:1.2666;--token-typography-display-400-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-400-font-size:1.5rem;--token-typography-display-400-line-height:1.3333;--token-typography-display-300-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-300-font-size:1.125rem;--token-typography-display-300-line-height:1.3333;--token-typography-display-300-letter-spacing:-0.5px;--token-typography-display-200-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-200-font-size:1rem;--token-typography-display-200-line-height:1.5;--token-typography-display-200-letter-spacing:-0.5px;--token-typography-display-100-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-100-font-size:0.8125rem;--token-typography-display-100-line-height:1.3846;--token-typography-body-300-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-body-300-font-size:1rem;--token-typography-body-300-line-height:1.5;--token-typography-body-200-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-body-200-font-size:0.875rem;--token-typography-body-200-line-height:1.4286;--token-typography-body-100-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-body-100-font-size:0.8125rem;--token-typography-body-100-line-height:1.3846;--token-typography-code-100-font-family:ui-monospace,Menlo,Consolas,monospace;--token-typography-code-100-font-size:0.8125rem;--token-typography-code-100-line-height:1.23;--token-typography-code-200-font-family:ui-monospace,Menlo,Consolas,monospace;--token-typography-code-200-font-size:0.875rem;--token-typography-code-200-line-height:1.125;--token-typography-code-300-font-family:ui-monospace,Menlo,Consolas,monospace;--token-typography-code-300-font-size:1rem;--token-typography-code-300-line-height:1.25;--hds-app-desktop-breakpoint:1088px;--hds-app-sidenav-width-minimized:48px;--hds-app-sidenav-width-expanded:280px;--hds-app-sidenav-width-fixed:var(--hds-app-sidenav-width-expanded);--hds-app-sidenav-animation-duration:200ms;--hds-app-sidenav-animation-delay:var(--hds-app-sidenav-animation-duration);--hds-app-sidenav-animation-easing:cubic-bezier(0.65, 0, 0.35, 1);--decor-radius-000:0;--decor-radius-100:2px;--decor-radius-200:4px;--decor-radius-250:6px;--decor-radius-300:7px;--decor-radius-999:9999px;--decor-radius-full:100%;--decor-border-000:none;--decor-border-100:1px solid;--decor-border-200:2px solid;--decor-border-300:3px solid;--decor-border-400:4px solid;--icon-alert-triangle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-alert-triangle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-left-16:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-left-24:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-right-16:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-right-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-fill-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-fill-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-down-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-down-24:url('data:image/svg+xml;charset=UTF-8,');--icon-clipboard-copy-16:url('data:image/svg+xml;charset=UTF-8,');--icon-clipboard-copy-24:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-16:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-24:url('data:image/svg+xml;charset=UTF-8,');--icon-external-link-16:url('data:image/svg+xml;charset=UTF-8,');--icon-external-link-24:url('data:image/svg+xml;charset=UTF-8,');--icon-file-16:url('data:image/svg+xml;charset=UTF-8,');--icon-file-24:url('data:image/svg+xml;charset=UTF-8,');--icon-folder-16:url('data:image/svg+xml;charset=UTF-8,');--icon-folder-24:url('data:image/svg+xml;charset=UTF-8,');--icon-activity-16:url('data:image/svg+xml;charset=UTF-8,');--icon-activity-24:url('data:image/svg+xml;charset=UTF-8,');--icon-help-16:url('data:image/svg+xml;charset=UTF-8,');--icon-help-24:url('data:image/svg+xml;charset=UTF-8,');--icon-learn-16:url('data:image/svg+xml;charset=UTF-8,');--icon-learn-24:url('data:image/svg+xml;charset=UTF-8,');--icon-github-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-github-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-google-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-google-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-kubernetes-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-kubernetes-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-menu-16:url('data:image/svg+xml;charset=UTF-8,');--icon-menu-24:url('data:image/svg+xml;charset=UTF-8,');--icon-minus-square-16:url('data:image/svg+xml;charset=UTF-8,');--icon-minus-square-24:url('data:image/svg+xml;charset=UTF-8,');--icon-more-horizontal-16:url('data:image/svg+xml;charset=UTF-8,');--icon-more-horizontal-24:url('data:image/svg+xml;charset=UTF-8,');--icon-globe-16:url('data:image/svg+xml;charset=UTF-8,');--icon-globe-24:url('data:image/svg+xml;charset=UTF-8,');--icon-search-16:url('data:image/svg+xml;charset=UTF-8,');--icon-search-24:url('data:image/svg+xml;charset=UTF-8,');--icon-star-16:url('data:image/svg+xml;charset=UTF-8,');--icon-star-24:url('data:image/svg+xml;charset=UTF-8,');--icon-org-16:url('data:image/svg+xml;charset=UTF-8,');--icon-org-24:url('data:image/svg+xml;charset=UTF-8,');--icon-user-16:url('data:image/svg+xml;charset=UTF-8,');--icon-user-24:url('data:image/svg+xml;charset=UTF-8,');--icon-users-16:url('data:image/svg+xml;charset=UTF-8,');--icon-users-24:url('data:image/svg+xml;charset=UTF-8,');--icon-alert-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-alert-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-check-16:url('data:image/svg+xml;charset=UTF-8,');--icon-check-24:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-fill-16:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-fill-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-left-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-left-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-right-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-right-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-up-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-up-24:url('data:image/svg+xml;charset=UTF-8,');--icon-delay-16:url('data:image/svg+xml;charset=UTF-8,');--icon-delay-24:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-link-16:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-link-24:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-16:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-24:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-off-16:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-off-24:url('data:image/svg+xml;charset=UTF-8,');--icon-file-text-16:url('data:image/svg+xml;charset=UTF-8,');--icon-file-text-24:url('data:image/svg+xml;charset=UTF-8,');--icon-gateway-16:url('data:image/svg+xml;charset=UTF-8,');--icon-gateway-24:url('data:image/svg+xml;charset=UTF-8,');--icon-git-commit-16:url('data:image/svg+xml;charset=UTF-8,');--icon-git-commit-24:url('data:image/svg+xml;charset=UTF-8,');--icon-hexagon-16:url('data:image/svg+xml;charset=UTF-8,');--icon-hexagon-24:url('data:image/svg+xml;charset=UTF-8,');--icon-history-16:url('data:image/svg+xml;charset=UTF-8,');--icon-history-24:url('data:image/svg+xml;charset=UTF-8,');--icon-info-16:url('data:image/svg+xml;charset=UTF-8,');--icon-info-24:url('data:image/svg+xml;charset=UTF-8,');--icon-layers-16:url('data:image/svg+xml;charset=UTF-8,');--icon-layers-24:url('data:image/svg+xml;charset=UTF-8,');--icon-loading-16:url('data:image/svg+xml;charset=UTF-8,');--icon-loading-24:url('data:image/svg+xml;charset=UTF-8,');--icon-network-alt-16:url('data:image/svg+xml;charset=UTF-8,');--icon-network-alt-24:url('data:image/svg+xml;charset=UTF-8,');--icon-path-16:url('data:image/svg+xml;charset=UTF-8,');--icon-path-24:url('data:image/svg+xml;charset=UTF-8,');--icon-running-16:url('data:image/svg+xml;charset=UTF-8,');--icon-running-24:url('data:image/svg+xml;charset=UTF-8,');--icon-skip-16:url('data:image/svg+xml;charset=UTF-8,');--icon-skip-24:url('data:image/svg+xml;charset=UTF-8,');--icon-socket-16:url('data:image/svg+xml;charset=UTF-8,');--icon-socket-24:url('data:image/svg+xml;charset=UTF-8,');--icon-star-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-star-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-star-fill-16:url('data:image/svg+xml;charset=UTF-8,');--icon-star-fill-24:url('data:image/svg+xml;charset=UTF-8,');--icon-tag-16:url('data:image/svg+xml;charset=UTF-8,');--icon-tag-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-24:url('data:image/svg+xml;charset=UTF-8,');--icon-cloud-cross-16:url('data:image/svg+xml;charset=UTF-8,');--icon-loading-motion-16:url('data:image/svg+xml;charset=UTF-8,');--icon-auth0-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-auth0-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-ember-circle-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-glimmer-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-jwt-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-microsoft-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-microsoft-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-oidc-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-okta-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-okta-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-mesh-16:url('data:image/svg+xml;charset=UTF-8,');--icon-mesh-24:url('data:image/svg+xml;charset=UTF-8,');--icon-port-16:url('data:image/svg+xml;charset=UTF-8,');--icon-protocol-16:url('data:image/svg+xml;charset=UTF-8,');--icon-redirect-16:url('data:image/svg+xml;charset=UTF-8,');--icon-redirect-24:url('data:image/svg+xml;charset=UTF-8,');--icon-search-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-sort-desc-16:url('data:image/svg+xml;charset=UTF-8,');--icon-sort-desc-24:url('data:image/svg+xml;charset=UTF-8,');--icon-union-16:url('data:image/svg+xml;charset=UTF-8,');--chrome-width:280px;--chrome-height:64px;--typo-action:var(--token-color-foreground-action);--decor-error:var(--token-color-foreground-critical);--typo-contrast:var(--token-color-hashicorp-brand);--syntax-light-grey:#dde3e7;--syntax-light-gray:#a4a4a4;--syntax-light-grey-blue:#6c7b81;--syntax-dark-grey:#788290;--syntax-faded-gray:#eaeaea;--syntax-atlas:#127eff;--syntax-vagrant:#2f88f7;--syntax-consul:#69499a;--syntax-terraform:#822ff7;--syntax-serf:#dd4e58;--syntax-packer:#1ddba3;--syntax-gray:lighten(#000, 89%);--syntax-red:#ff3d3d;--syntax-green:#39b54a;--syntax-dark-gray:#535f73;--syntax-gutter-grey:#2a2f36;--syntax-yellow:var(--token-color-vault-brand);--horizontal-kv-list-separator-width:18px;--horizontal-kv-list-key-separator:":";--horizontal-kv-list-key-wrapper-start:"(";--horizontal-kv-list-key-wrapper-end:")";--csv-list-separator:",";--icon-loading:icon-loading-motion;--color-info:var(--token-color-foreground-action);--color-alert:var(--token-color-palette-amber-200)}.hds-border-primary{border:1px solid var(--token-color-border-primary)}.hds-border-faint{border:1px solid var(--token-color-border-faint)}.hds-border-strong{border:1px solid var(--token-color-border-strong)}.hds-border-action{border:1px solid var(--token-color-border-action)}.hds-border-highlight{border:1px solid var(--token-color-border-highlight)}.hds-border-success{border:1px solid var(--token-color-border-success)}.hds-border-warning{border:1px solid var(--token-color-border-warning)}.hds-border-critical{border:1px solid var(--token-color-border-critical)}.hds-foreground-strong{color:var(--token-color-foreground-strong)}.hds-foreground-primary{color:var(--token-color-foreground-primary)}.hds-foreground-faint{color:var(--token-color-foreground-faint)}.hds-foreground-high-contrast{color:var(--token-color-foreground-high-contrast)}.hds-foreground-disabled{color:var(--token-color-foreground-disabled)}.hds-foreground-action{color:var(--token-color-foreground-action)}.hds-foreground-action-hover{color:var(--token-color-foreground-action-hover)}.hds-foreground-action-active{color:var(--token-color-foreground-action-active)}.hds-foreground-highlight{color:var(--token-color-foreground-highlight)}.hds-foreground-highlight-on-surface{color:var(--token-color-foreground-highlight-on-surface)}.hds-foreground-highlight-high-contrast{color:var(--token-color-foreground-highlight-high-contrast)}.hds-foreground-success{color:var(--token-color-foreground-success)}.hds-foreground-success-on-surface{color:var(--token-color-foreground-success-on-surface)}.hds-foreground-success-high-contrast{color:var(--token-color-foreground-success-high-contrast)}.hds-foreground-warning{color:var(--token-color-foreground-warning)}.hds-foreground-warning-on-surface{color:var(--token-color-foreground-warning-on-surface)}.hds-foreground-warning-high-contrast{color:var(--token-color-foreground-warning-high-contrast)}.hds-foreground-critical{color:var(--token-color-foreground-critical)}.hds-foreground-critical-on-surface{color:var(--token-color-foreground-critical-on-surface)}.hds-foreground-critical-high-contrast{color:var(--token-color-foreground-critical-high-contrast)}.hds-page-primary{background-color:var(--token-color-page-primary)}.hds-page-faint{background-color:var(--token-color-page-faint)}.hds-surface-primary{background-color:var(--token-color-surface-primary)}.hds-surface-faint{background-color:var(--token-color-surface-faint)}.hds-badge--color-neutral.hds-badge--type-filled,.hds-surface-strong{background-color:var(--token-color-surface-strong)}.hds-surface-interactive{background-color:var(--token-color-surface-interactive)}.hds-surface-interactive-hover{background-color:var(--token-color-surface-interactive-hover)}.hds-surface-interactive-active{background-color:var(--token-color-surface-interactive-active)}.hds-surface-interactive-disabled{background-color:var(--token-color-surface-interactive-disabled)}.hds-surface-action{background-color:var(--token-color-surface-action)}.hds-surface-highlight{background-color:var(--token-color-surface-highlight)}.hds-surface-success{background-color:var(--token-color-surface-success)}.hds-surface-warning{background-color:var(--token-color-surface-warning)}.hds-surface-critical{background-color:var(--token-color-surface-critical)}.hds-elevation-low{box-shadow:var(--token-elevation-low-box-shadow)}.hds-elevation-mid{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-elevation-high{box-shadow:var(--token-elevation-high-box-shadow)}.hds-elevation-higher{box-shadow:var(--token-elevation-higher-box-shadow)}.consul-server-list a:hover div,.hds-elevation-overlay,.modal-dialog [role=document]{box-shadow:var(--token-elevation-overlay-box-shadow)}.hds-surface-inset{box-shadow:var(--token-surface-inset-box-shadow)}.hds-surface-base{box-shadow:var(--token-surface-base-box-shadow)}.hds-surface-low{box-shadow:var(--token-surface-low-box-shadow)}.hds-accordion-item.hds-accordion-item--does-not-contain-interactive,.hds-surface-mid{box-shadow:var(--token-surface-mid-box-shadow)}.hds-surface-high{box-shadow:var(--token-surface-high-box-shadow)}.hds-surface-higher{box-shadow:var(--token-surface-higher-box-shadow)}.hds-surface-overlay{box-shadow:var(--token-surface-overlay-box-shadow)}.hds-focus-ring-action-box-shadow{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-focus-ring-critical-box-shadow{box-shadow:var(--token-focus-ring-critical-box-shadow)}.hds-font-family-sans-display{font-family:var(--token-typography-font-stack-display)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive,.hds-badge-count,.hds-badge__text,.hds-breadcrumb__text,.hds-button,.hds-font-family-sans-text{font-family:var(--token-typography-font-stack-text)}.hds-font-family-mono-code{font-family:var(--token-typography-font-stack-code)}#metrics-container .sparkline-wrapper .tooltip,.app-view h1 span.kind-proxy,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.app-view>div form:not(.filter-bar) [role=radiogroup] label>strong,.auth-form em,.consul-auth-method-type,.consul-auth-method-view section,.consul-external-source,.consul-health-check-list .health-check-output dd em,.consul-health-check-list .health-check-output dl>dd,.consul-intention-fieldsets .permissions>button,.consul-intention-list td strong,.consul-intention-list td.destination em,.consul-intention-list td.permissions,.consul-intention-list td.source em,.consul-intention-permission-header-list>ul>li dd,.consul-intention-permission-list strong,.consul-intention-permission-list>ul>li dd,.consul-intention-search-bar li button span,.consul-kind,.consul-peer-search-bar li button span,.consul-server-card .health-status+dd,.consul-source,.consul-transparent-proxy,.disclosure-menu [aria-expanded]~*>div,.discovery-chain .resolvers>header>*,.discovery-chain .route-card header dt,.discovery-chain .route-card>header ul li,.discovery-chain .routes>header>*,.discovery-chain .splitters>header>*,.empty-state header :nth-child(2),.empty-state p,.empty-state>ul>li>*,.empty-state>ul>li>::before,.empty-state>ul>li>label>button,.empty-state>ul>li>label>button::before,.has-error>strong,.has-error>strong::before,.hds-font-weight-regular,.informed-action p,.leader,.menu-panel>div,.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-password>strong,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-select>strong,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] .type-text>strong,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] [role=radiogroup] label>strong,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] label a[rel*=help],.modal-dialog [role=document] p,.modal-dialog [role=document] table td,.modal-dialog [role=document] table td p,.modal-dialog [role=document] table th em,.more-popover-menu>[type=checkbox]+label+div>div,.oidc-select button.reset,.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.oidc-select label>em,.oidc-select label>span,.oidc-select label>strong,.popover-menu>[type=checkbox]+label+div>div,.search-bar-status li:not(.remove-all),.tippy-box[data-theme~=tooltip] .tippy-content,.topology-metrics-source-type,.topology-metrics-status-error,.topology-metrics-status-loader,.type-toggle [type=password],.type-toggle [type=text],.type-toggle textarea,.type-toggle>em,.type-toggle>span,.type-toggle>strong,body,html[data-route^="dc.acls.index"] main td strong,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-password>em,main .type-password>span,main .type-password>strong,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-select>em,main .type-select>span,main .type-select>strong,main .type-text [type=password],main .type-text [type=text],main .type-text textarea,main .type-text>em,main .type-text>span,main .type-text>strong,main form button+em,main label a[rel*=help],main p,main table td,main table td p,main table th em,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dt,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,section[data-route="dc.show.license"] .validity dl,span.label,span.policy-node-identity,span.policy-service-identity,table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div>div{font-weight:400}.app-view h1 em,.consul-exposed-path-list>ul>li .copy-button button,.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child) .copy-button button,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-peer-search-bar .value-active span,.consul-peer-search-bar .value-deleting span,.consul-peer-search-bar .value-establishing span,.consul-peer-search-bar .value-failing span,.consul-peer-search-bar .value-pending span,.consul-peer-search-bar .value-terminated span,.consul-upstream-instance-list li .copy-button button,.consul-upstream-instance-list li>.header,.disclosure-menu [aria-expanded]~* [role=separator],.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.hds-font-weight-medium,.informed-action>ul>li>*,.list-collection>ul>li:not(:first-child) .copy-button button,.list-collection>ul>li:not(:first-child)>.header,.menu-panel [role=separator],.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div [role=separator],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.peerings-badge .peerings-badge__text,.popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.tab-nav,main header nav:first-child ol li>*,table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{font-weight:500}#downstream-container .topology-metrics-card p,#metrics-container .sparkline-wrapper .tooltip .sparkline-time,#metrics-container div:first-child,#upstream-container .topology-metrics-card p,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.code-editor .toolbar-container .toolbar .title,.consul-auth-method-binding-list h2,.consul-auth-method-nspace-list thead td,.consul-auth-method-view section h2,.consul-auth-method-view section table thead td,.consul-bucket-list .service+dd,.consul-health-check-list .health-check-output dt,.consul-health-check-list .health-check-output header>*,.consul-intention-action-warn-modal button.dangerous,.consul-intention-list td.destination,.consul-intention-list td.source,.consul-intention-permission-form h2,.consul-intention-view h2,.consul-peer-form-generate li::after,.consul-server-card .name+dd,.copy-button button,.definition-table dt,.empty-state header :first-child,.hds-font-weight-semibold,.informed-action header,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] form h2,.modal-dialog [role=document] table caption,.modal-dialog [role=document] table td:first-child,.modal-dialog [role=document] table td:first-child p,.modal-dialog [role=document] table th,.modal-dialog [role=document]>header>:not(button),.modal-dialog-body h2,.oidc-select label>span,.popover-select label>*,.radio-card header,.sparkline-key h3,.topology-notices button,.type-sort.popover-select label>*,.type-toggle label span,.type-toggle>span,.warning.modal-dialog header>:not(label),fieldset>header,html[data-route^="dc.services.instance.metadata"] .tab-section section h2,html[data-route^="dc.kv.edit"] h2,main .type-password>span,main .type-select>span,main .type-text>span,main form h2,main table caption,main table td:first-child,main table td:first-child p,main table th,section[data-route="dc.show.serverstatus"] .redundancy-zones h3,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dd,section[data-route="dc.show.serverstatus"] h2,section[data-route="dc.show.serverstatus"] h3,section[data-route="dc.show.license"] aside header>:first-child,section[data-route="dc.show.license"] h2,span.label,strong{font-weight:600}.discovery-chain .route-card header:not(.short) dd,.discovery-chain .route-card section dt,.discovery-chain .splitter-card>header,.hds-font-weight-bold,h1{font-weight:700}.hds-typography-display-500,h1{font-family:var(--token-typography-display-500-font-family);font-size:var(--token-typography-display-500-font-size);line-height:var(--token-typography-display-500-line-height);margin:0;padding:0}.consul-auth-method-binding-list h2,.consul-auth-method-view section h2,.consul-intention-permission-form h2,.consul-intention-view h2,.empty-state header :first-child,.hds-typography-display-400,.modal-dialog [role=document] form h2,.modal-dialog [role=document]>header>:not(button),.modal-dialog-body h2,html[data-route^="dc.kv.edit"] h2,main form h2,section[data-route="dc.show.license"] h2{font-family:var(--token-typography-display-400-font-family);font-size:var(--token-typography-display-400-font-size);line-height:var(--token-typography-display-400-line-height);margin:0;padding:0}#downstream-container .topology-metrics-card p,#upstream-container .topology-metrics-card p,.consul-exposed-path-list>ul>li>.header,.consul-health-check-list .health-check-output header>*,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.header,.hds-typography-display-300,.list-collection>ul>li:not(:first-child)>.header,.sparkline-key h3,.warning.modal-dialog header>:not(label),html[data-route^="dc.services.instance.metadata"] .tab-section section h2,section[data-route="dc.show.serverstatus"] .redundancy-zones h3,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dd,section[data-route="dc.show.serverstatus"] h2,section[data-route="dc.show.serverstatus"] h3,section[data-route="dc.show.license"] aside header>:first-child{font-family:var(--token-typography-display-300-font-family);font-size:var(--token-typography-display-300-font-size);line-height:var(--token-typography-display-300-line-height);margin:0;padding:0}.consul-server-card .name+dd,.hds-side-nav .ember-a11y-refocus-skip-link,.hds-typography-display-200{font-size:var(--token-typography-display-200-font-size);line-height:var(--token-typography-display-200-line-height)}.consul-server-card .name+dd,.hds-typography-display-200{font-family:var(--token-typography-display-200-font-family);margin:0;padding:0}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.consul-intention-list td.destination,.consul-intention-list td.source,.definition-table dt,.hds-typography-display-100,.informed-action header,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] table caption,.modal-dialog [role=document] table th,.oidc-select label>span,.radio-card header,.type-toggle>span,fieldset>header,main .type-password>span,main .type-select>span,main .type-text>span,main table caption,main table th{font-family:var(--token-typography-display-100-font-family);font-size:var(--token-typography-display-100-font-size);line-height:var(--token-typography-display-100-line-height);margin:0;padding:0}#metrics-container div:first-child,.hds-typography-body-300,section[data-route="dc.show.license"] .validity dl{font-family:var(--token-typography-body-300-font-family);font-size:var(--token-typography-body-300-font-size);line-height:var(--token-typography-body-300-line-height);margin:0;padding:0}#metrics-container .sparkline-wrapper .tooltip,#metrics-container .sparkline-wrapper .tooltip .sparkline-time,.app-view h1 em,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.code-editor .toolbar-container .toolbar .title,.consul-auth-method-nspace-list thead td,.consul-auth-method-view section,.consul-auth-method-view section table thead td,.consul-external-source,.consul-health-check-list .health-check-output dl>dd,.consul-health-check-list .health-check-output dt,.consul-kind,.consul-peer-form-generate li::after,.consul-source,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.empty-state>ul>li>::before,.empty-state>ul>li>label>button::before,.has-error>strong::before,.hds-typography-body-200,.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.modal-dialog [role=document] table td,.modal-dialog [role=document] table td p,.modal-dialog [role=document] table td:first-child,.modal-dialog [role=document] table td:first-child p,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.tab-nav,.topology-metrics-status-error,.topology-metrics-status-loader,.type-toggle [type=password],.type-toggle [type=text],.type-toggle label span,.type-toggle textarea,body,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-text [type=password],main .type-text [type=text],main .type-text textarea,main header nav:first-child ol li>*,main table td,main table td p,main table td:first-child,main table td:first-child p,strong,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{font-family:var(--token-typography-body-200-font-family);font-size:var(--token-typography-body-200-font-size);line-height:var(--token-typography-body-200-line-height);margin:0;padding:0}.app-view h1 span.kind-proxy,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.auth-form em,.consul-exposed-path-list>ul>li .copy-button button,.consul-intention-action-warn-modal button.dangerous,.consul-intention-fieldsets .permissions>button,.consul-intention-list td.permissions,.consul-intention-permission-header-list>ul>li dd,.consul-intention-permission-list>ul>li dd,.consul-lock-session-list ul>li:not(:first-child) .copy-button button,.consul-server-card .health-status+dd,.consul-upstream-instance-list li .copy-button button,.copy-button button,.disclosure-menu [aria-expanded]~* [role=separator],.disclosure-menu [aria-expanded]~*>div,.discovery-chain .resolvers>header>*,.discovery-chain .routes>header>*,.discovery-chain .splitters>header>*,.empty-state header :nth-child(2),.empty-state p,.empty-state>ul>li>*,.empty-state>ul>li>label>button,.has-error>strong,.hds-typography-body-100,.informed-action p,.list-collection>ul>li:not(:first-child) .copy-button button,.menu-panel [role=separator],.menu-panel>div,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] p,.more-popover-menu>[type=checkbox]+label+div [role=separator],.more-popover-menu>[type=checkbox]+label+div>div,.oidc-select button.reset,.oidc-select label>em,.oidc-select label>span,.peerings-badge .peerings-badge__text,.popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div>div,.popover-select label>*,.tippy-box[data-theme~=tooltip] .tippy-content,.topology-notices button,.type-sort.popover-select label>*,.type-toggle>em,.type-toggle>span,main .type-password>em,main .type-password>span,main .type-select>em,main .type-select>span,main .type-text>em,main .type-text>span,main form button+em,main p,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dt,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,span.label,table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div>div{font-family:var(--token-typography-body-100-font-family);font-size:var(--token-typography-body-100-font-size);line-height:var(--token-typography-body-100-line-height);margin:0;padding:0}.hds-typography-code-100{font-family:var(--token-typography-code-100-font-family);font-size:var(--token-typography-code-100-font-size);line-height:var(--token-typography-code-100-line-height);margin:0;padding:0}.hds-typography-code-200{font-family:var(--token-typography-code-200-font-family);font-size:var(--token-typography-code-200-font-size);line-height:var(--token-typography-code-200-line-height);margin:0;padding:0}.hds-typography-code-300{font-family:var(--token-typography-code-300-font-family);font-size:var(--token-typography-code-300-font-size);line-height:var(--token-typography-code-300-line-height);margin:0;padding:0}.hds-accordion{display:flex;gap:12px}.hds-accordion-item{background:var(--token-color-surface-primary);border-radius:6px}.hds-accordion-item.hds-accordion-item--does-not-contain-interactive.mock-hover,.hds-accordion-item.hds-accordion-item--does-not-contain-interactive:hover{box-shadow:var(--token-surface-high-box-shadow)}.hds-accordion-item.hds-accordion-item--contains-interactive{box-shadow:var(--token-surface-base-box-shadow)}.hds-accordion-item__toggle{position:relative;display:flex;gap:12px;align-items:center;padding:16px 16px 16px 12px}.hds-accordion-item__button{padding:0}.hds-accordion-item__button:hover{cursor:pointer}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive{outline-style:solid;outline-color:transparent;isolation:isolate;position:static;margin:-1px 0;color:var(--token-color-foreground-primary);background:0 0;border:1px solid transparent}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive::before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:5px;content:""}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive.mock-focus::before,.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus:not(:focus-visible)::before{box-shadow:none}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus-visible::before,.hds-breadcrumb__link.mock-focus,.hds-breadcrumb__link:focus{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive.mock-focus.mock-active::before,.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus:active::before{box-shadow:none}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive::after{position:absolute;display:block;border-radius:6px;content:"";inset:0}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive{position:relative;display:flex;gap:.375rem;align-items:center;justify-content:center;font-weight:var(--token-typography-font-weight-regular);text-decoration:none;border:1px solid transparent;border-radius:5px;outline-style:solid;outline-color:transparent;isolation:isolate;width:24px;height:24px;color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong);box-shadow:var(--token-elevation-low-box-shadow)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-focus::before,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:focus::before{position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;z-index:-1;border:3px solid transparent;border-radius:8px;content:""}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-hover,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-focus,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:focus{box-shadow:none;color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-focus::before,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:focus::before{border-color:var(--token-color-focus-action-external)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-active,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-active::before,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:active::before{border-color:transparent}.hds-accordion-item__button.hds-accordion-item__button--is-open .flight-icon-chevron-down{transform:rotate(-180deg)}.hds-accordion-item__toggle-content{flex:1}.hds-accordion-item__content{padding:4px 16px 16px}.hds-alert{display:flex;align-items:flex-start}.hds-alert__icon{flex:none;width:20px;height:20px;margin-right:12px}.hds-alert__content{flex:1 1 auto}.hds-alert__text{display:flex;flex-direction:column;gap:4px;justify-content:center;color:var(--token-color-foreground-warning-on-surface)}.hds-alert__description{word-break:break-word}.hds-alert__description strong{font-weight:var(--token-typography-font-weight-semibold)}.hds-alert__description code,.hds-alert__description pre{display:inline;padding:1px 5px;font-size:.9em;font-family:var(--token-typography-code-100-font-family);line-height:1em;background-color:var(--token-color-surface-primary);border:1px solid var(--token-color-palette-neutral-200);border-radius:5px}.hds-alert__description a:not([class*=hds-]){color:var(--token-color-foreground-strong)}.hds-alert__description a:not([class*=hds-]):focus,.hds-alert__description a:not([class*=hds-]):focus-visible{text-decoration:none;outline:var(--token-color-focus-action-internal) solid 2px;outline-offset:1px}.hds-alert__description a:not([class*=hds-]):hover{color:var(--token-color-foreground-primary)}.hds-alert--color-neutral .hds-alert__icon,.hds-alert__description a:not([class*=hds-]):active{color:var(--token-color-foreground-faint)}.hds-alert__actions{display:flex;gap:16px;align-items:center}.hds-alert__actions>*{margin-top:16px}.hds-alert__dismiss{margin-top:2px;margin-left:16px}.hds-alert--type-compact .hds-alert__dismiss{margin-top:1px}.hds-alert--type-page{padding:16px 48px}.hds-alert--type-inline{padding:16px;border-style:solid;border-width:1px;border-radius:6px}.hds-alert--type-compact .hds-alert__icon{width:14px;height:14px;margin-top:2px;margin-right:8px}.hds-alert--type-compact .hds-alert__title{display:none}.hds-alert--type-compact .hds-alert__title+.hds-alert__description{margin-top:0}.hds-alert--color-neutral.hds-alert--type-page{background-color:var(--token-color-surface-faint);box-shadow:0 1px 0 0 var(--token-color-palette-alpha-300)}.hds-alert--color-neutral.hds-alert--type-inline{background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong)}.hds-alert--color-neutral .hds-alert__title{color:var(--token-color-foreground-primary)}.hds-alert--color-highlight.hds-alert--type-page{background-color:var(--token-color-surface-highlight);box-shadow:0 1px 0 0 var(--token-color-border-highlight)}.hds-alert--color-highlight.hds-alert--type-inline{background-color:var(--token-color-surface-highlight);border-color:var(--token-color-border-highlight)}.hds-alert--color-highlight .hds-alert__icon,.hds-alert--color-highlight .hds-alert__title{color:var(--token-color-foreground-highlight-on-surface)}.hds-alert--color-success.hds-alert--type-page{background-color:var(--token-color-surface-success);box-shadow:0 1px 0 0 var(--token-color-border-success)}.hds-alert--color-success.hds-alert--type-inline{background-color:var(--token-color-surface-success);border-color:var(--token-color-border-success)}.hds-alert--color-success .hds-alert__icon,.hds-alert--color-success .hds-alert__title{color:var(--token-color-foreground-success-on-surface)}.hds-alert--color-warning.hds-alert--type-page{background-color:var(--token-color-surface-warning);box-shadow:0 1px 0 0 var(--token-color-border-warning)}.hds-alert--color-warning.hds-alert--type-inline{background-color:var(--token-color-surface-warning);border-color:var(--token-color-border-warning)}.hds-alert--color-warning .hds-alert__icon,.hds-alert--color-warning .hds-alert__title{color:var(--token-color-foreground-warning-on-surface)}.hds-alert--color-critical.hds-alert--type-page{background-color:var(--token-color-surface-critical);box-shadow:0 1px 0 0 var(--token-color-border-critical)}.hds-alert--color-critical.hds-alert--type-inline{background-color:var(--token-color-surface-critical);border-color:var(--token-color-border-critical)}.hds-alert--color-critical .hds-alert__icon,.hds-alert--color-critical .hds-alert__title{color:var(--token-color-foreground-critical-on-surface)}.hds-app-footer{display:flex;flex-wrap:wrap;gap:24px;justify-content:flex-end;padding:24px;color:var(--app-footer-foreground-color);border-top:1px solid var(--app-footer-border-top-color)}.hds-app-footer__list:not(:has(li)){display:none}.hds-app-footer__legal-links,.hds-app-footer__list{display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:flex-end;width:-moz-fit-content;width:fit-content;min-width:0;margin:0;padding:0;list-style-type:none}.hds-app-footer__status-link.hds-link-inline--icon-leading>.hds-link-inline__icon{margin-right:6px}.hds-app-footer__status-link .flight-icon{fill:var(--hds-app-footer-status-icon-color,currentColor)}.hds-app-footer__status-link--operational .flight-icon{fill:var(--app-footer-status-link-icon-operational-color)}.hds-app-footer__status-link--degraded .flight-icon{fill:var(--app-footer-status-link-icon-degraded-color)}.hds-app-footer__status-link--maintenance .flight-icon{fill:var(--app-footer-status-link-icon-maintenance-color)}.hds-app-footer__status-link--critical .flight-icon{fill:var(--app-footer-status-link-icon-critical-color)}.hds-app-footer__link.hds-link-inline--color-secondary,.hds-app-footer__status-link{color:var(--app-footer-link-default-color);text-align:right}.hds-app-footer__link.hds-link-inline--color-secondary.mock-hover,.hds-app-footer__link.hds-link-inline--color-secondary:hover,.hds-app-footer__status-link.mock-hover,.hds-app-footer__status-link:hover{color:var(--app-footer-link-hover-color)}.hds-app-footer__link.hds-link-inline--color-secondary.mock-active,.hds-app-footer__link.hds-link-inline--color-secondary:active,.hds-app-footer__status-link.mock-active,.hds-app-footer__status-link:active{color:var(--app-footer-link-active-color)}.hds-app-footer__link.hds-link-inline--color-secondary.mock-focus,.hds-app-footer__link.hds-link-inline--color-secondary:focus,.hds-app-footer__link.hds-link-inline--color-secondary:focus-visible,.hds-app-footer__status-link.mock-focus,.hds-app-footer__status-link:focus,.hds-app-footer__status-link:focus-visible{color:var(--app-footer-link-focus-color);outline-color:var(--app-footer-link-focus-outline-color)}.hds-app-footer__list-item{display:flex;align-items:center}.hds-app-footer__copyright{display:flex;gap:6px;align-items:center;color:var(--app-footer-copyright-text-color)}.hds-app-footer__copyright .flight-icon{fill:var(--app-footer-copyright-icon-color)}.hds-app-footer--theme-light{--app-footer-foreground-color:var(--token-color-foreground-primary);--app-footer-border-top-color:var(--token-color-border-primary);--app-footer-link-default-color:var(--token-color-foreground-faint);--app-footer-link-hover-color:var(--token-color-palette-neutral-600);--app-footer-link-active-color:var(--token-color-palette-neutral-700);--app-footer-link-focus-color:var(--token-color-foreground-faint);--app-footer-link-focus-outline-color:var(--token-color-focus-action-internal);--app-footer-copyright-text-color:var(--token-color-foreground-primary);--app-footer-copyright-icon-color:var(--token-color-hashicorp-brand);--app-footer-status-link-icon-operational-color:var(--token-color-foreground-success);--app-footer-status-link-icon-degraded-color:var(--token-color-foreground-warning);--app-footer-status-link-icon-maintenance-color:var(--token-color-foreground-warning);--app-footer-status-link-icon-critical-color:var(--token-color-foreground-critical)}.hds-app-footer--theme-dark{--app-footer-foreground-color:#b2b6bd;--app-footer-border-top-color:#b2b6bd66;--app-footer-link-default-color:#b2b6bd;--app-footer-link-hover-color:#d5d7db;--app-footer-link-active-color:#efeff1;--app-footer-link-focus-color:#b2b6bd;--app-footer-link-focus-outline-color:#389aff;--app-footer-copyright-text-color:#b2b6bd;--app-footer-copyright-icon-color:#fff;--app-footer-status-link-icon-operational-color:#009241;--app-footer-status-link-icon-degraded-color:#e88c03;--app-footer-status-link-icon-maintenance-color:#e88c03;--app-footer-status-link-icon-critical-color:#ef3016}.hds-app-frame{display:grid;grid-template-areas:"header header" "sidebar main" "sidebar footer";grid-template-rows:auto 1fr auto;grid-template-columns:auto 1fr;min-height:100vh}.hds-app-frame__modals:empty,button.hds-button[href] .hds-button__text,button.hds-button[href]::before{display:none}.hds-app-frame__header{z-index:7;grid-area:header}.hds-app-frame__sidebar{z-index:6;grid-area:sidebar}.hds-app-frame__main{grid-area:main}.hds-app-frame__footer{grid-area:footer}.hds-app-frame__modals{position:fixed;top:0;left:0;z-index:100;width:100vw;height:100vh;pointer-events:none}.hds-application-state{width:19.5rem;max-width:100%;margin:0 auto}.hds-application-state__header{display:grid;grid-template-columns:min-content 1fr;align-items:start;color:var(--token-color-foreground-faint)}.hds-application-state__icon{margin-right:8px;padding-top:4px}.hds-application-state__error-code,.hds-application-state__title{grid-column-start:2}.hds-application-state__body{padding:12px 0;color:var(--token-color-foreground-faint)}.hds-application-state__footer{display:flex;gap:8px;justify-content:space-between}.hds-application-state__footer.hds-application-state__footer--has-divider{padding:12px 0;border-top:1px solid var(--token-color-border-strong)}.hds-avatar{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:32px;height:32px}.hds-avatar svg,.hds-dropdown--is-inline,.hds-form-toggle{display:inline-block}.hds-avatar img{width:inherit;height:inherit;border-radius:2px}.hds-badge{display:inline-flex;align-items:center;max-width:100%;vertical-align:middle;border:1px solid transparent;border-radius:5px}.hds-badge__icon{display:block;flex:0 0 auto}.hds-badge__text{flex:1 0 0;font-weight:var(--token-typography-font-weight-medium)}.hds-badge--size-small{gap:.25rem;min-height:1.25rem;padding:calc(.125rem - 1px) calc(.375rem - 1px)}.hds-badge--size-small .hds-badge__icon{width:.75rem;height:.75rem}.hds-badge--size-large .hds-badge__icon,.hds-badge--size-medium .hds-badge__icon{width:1rem;height:1rem}.hds-badge--size-small .hds-badge__text{font-size:.8125rem;line-height:1.2308}.hds-badge--size-medium{gap:.25rem;min-height:1.5rem;padding:calc(.25rem - 1px) calc(.5rem - 1px)}.hds-badge--size-medium .hds-badge__text{font-size:.8125rem;line-height:1.2308}.hds-badge--size-large{gap:.375rem;min-height:2rem;padding:calc(.25rem - 1px) calc(.5rem - 1px)}.hds-badge--size-large .hds-badge__text{font-size:1rem;line-height:1.5}.hds-badge--color-neutral.hds-badge--type-filled{color:var(--token-color-foreground-primary)}.hds-badge--color-neutral.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge--color-neutral.hds-badge--type-outlined{color:var(--token-color-foreground-primary);background-color:transparent;border-color:var(--token-color-foreground-faint)}.hds-badge--color-neutral-dark-mode.hds-badge--type-filled{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge--color-neutral-dark-mode.hds-badge--type-inverted{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint)}.hds-badge--color-neutral-dark-mode.hds-badge--type-outlined{color:var(--token-color-foreground-high-contrast);background-color:transparent;border-color:var(--token-color-palette-neutral-100)}.hds-badge--color-highlight.hds-badge--type-filled{color:var(--token-color-foreground-highlight-on-surface);background-color:var(--token-color-surface-highlight)}.hds-badge--color-highlight.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-highlight)}.hds-badge--color-highlight.hds-badge--type-outlined{color:var(--token-color-foreground-highlight);background-color:transparent;border-color:currentColor}.hds-badge--color-success.hds-badge--type-filled{color:var(--token-color-foreground-success-on-surface);background-color:var(--token-color-surface-success)}.hds-badge--color-success.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-success)}.hds-badge--color-success.hds-badge--type-outlined{color:var(--token-color-foreground-success);background-color:transparent;border-color:currentColor}.hds-badge--color-warning.hds-badge--type-filled{color:var(--token-color-foreground-warning-on-surface);background-color:var(--token-color-surface-warning)}.hds-badge--color-warning.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-warning)}.hds-badge--color-warning.hds-badge--type-outlined{color:var(--token-color-foreground-warning);background-color:transparent;border-color:currentColor}.hds-badge--color-critical.hds-badge--type-filled{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-surface-critical)}.hds-badge--color-critical.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-critical)}.hds-badge--color-critical.hds-badge--type-outlined{color:var(--token-color-foreground-critical);background-color:transparent;border-color:currentColor}.hds-badge-count{display:inline-flex;align-items:center;max-width:100%;font-weight:var(--token-typography-font-weight-medium);border:1px solid transparent}.hds-button,.hds-dropdown-toggle-button{font-weight:var(--token-typography-font-weight-regular)}.hds-badge-count--size-small{min-height:1.25rem;padding:calc(.125rem - 1px) calc(.5rem - 1px);font-size:.8125rem;line-height:1.2308;border-radius:.625rem}.hds-badge-count--size-medium{min-height:1.5rem;padding:calc(.25rem - 1px) calc(.75rem - 1px);font-size:.8125rem;line-height:1.2308;border-radius:.75rem}.hds-badge-count--size-large{min-height:2rem;padding:calc(.25rem - 1px) calc(.875rem - 1px);font-size:1rem;line-height:1.5;border-radius:1rem}.hds-breadcrumb__list,.hds-breadcrumb__sublist{margin:0;padding:0;list-style:none}.hds-badge-count--color-neutral.hds-badge-count--type-filled{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-strong)}.hds-badge-count--color-neutral.hds-badge-count--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge-count--color-neutral.hds-badge-count--type-outlined{color:var(--token-color-foreground-primary);background-color:transparent;border-color:var(--token-color-foreground-faint)}.hds-badge-count--color-neutral-dark-mode.hds-badge-count--type-filled{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge-count--color-neutral-dark-mode.hds-badge-count--type-inverted{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint)}.hds-badge-count--color-neutral-dark-mode.hds-badge-count--type-outlined{color:var(--token-color-foreground-high-contrast);background-color:transparent;border-color:var(--token-color-palette-neutral-100)}.hds-breadcrumb{position:relative}.hds-breadcrumb__list{display:flex}.hds-breadcrumb--items-can-wrap .hds-breadcrumb__list{flex-wrap:wrap}.hds-breadcrumb__item{position:relative;display:flex;flex-direction:row;align-items:center;min-width:0}.hds-breadcrumb__list>.hds-breadcrumb__item:not(:last-child)::after{padding:0 8px;color:var(--token-color-palette-neutral-300);content:"/"}.hds-breadcrumb__sublist>.hds-breadcrumb__item+.hds-breadcrumb__item{margin-top:4px}.hds-breadcrumb__current,.hds-breadcrumb__link{margin:0 -4px;padding:0 4px;display:flex;min-width:0}.hds-breadcrumb__item--is-truncation{flex:none}.hds-breadcrumb__link{flex-direction:row;align-items:center;color:var(--token-color-foreground-faint);border-radius:5px;text-decoration-color:transparent;outline-style:solid;outline-color:transparent}.hds-breadcrumb__link.mock-active>.hds-breadcrumb__text,.hds-breadcrumb__link.mock-hover>.hds-breadcrumb__text,.hds-breadcrumb__link:active>.hds-breadcrumb__text,.hds-breadcrumb__link:hover>.hds-breadcrumb__text{text-decoration-color:currentColor}.hds-breadcrumb__link.mock-hover,.hds-breadcrumb__link:hover{color:var(--token-color-palette-neutral-600)}.hds-breadcrumb__link:focus:not(:focus-visible){box-shadow:none}.hds-breadcrumb__link:focus-visible{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-breadcrumb__link.mock-focus.mock-active,.hds-breadcrumb__link:focus:active{box-shadow:none}.hds-breadcrumb__link.mock-active,.hds-breadcrumb__link:active{color:var(--token-color-foreground-secondary)}.hds-breadcrumb__current{flex-direction:row;align-items:center;color:var(--token-color-foreground-strong)}.hds-breadcrumb__icon{flex:none;width:13px;height:13px;margin-right:6px}.hds-breadcrumb__text{padding:calc((28px - 1rem)/ 2) 0;font-size:.8125rem;line-height:1rem;white-space:nowrap;text-decoration:underline;text-overflow:ellipsis;text-decoration-color:transparent}.hds-breadcrumb__sublist .hds-breadcrumb__text{white-space:normal}.hds-breadcrumb__truncation-toggle{display:flex;flex:none;align-items:center;justify-content:center;width:28px;height:28px;margin:0 -4px;padding:0;color:var(--token-color-foreground-faint);background-color:transparent;border:1px solid transparent;border-radius:5px;outline:transparent solid 0;cursor:pointer}.hds-button,.hds-copy-snippet{align-items:center;isolation:isolate}.hds-button,.hds-copy-snippet,.hds-dismiss-button,.hds-dropdown-toggle-button,.hds-dropdown-toggle-icon{outline-style:solid;outline-color:transparent}.hds-breadcrumb__truncation-toggle.mock-hover,.hds-breadcrumb__truncation-toggle:hover{color:var(--token-color-foreground-faint);border-color:var(--token-color-border-strong)}.hds-breadcrumb__truncation-toggle.mock-focus,.hds-breadcrumb__truncation-toggle:focus{box-shadow:var(--token-focus-ring-action-box-shadow);background-color:transparent;border:none}.hds-breadcrumb__truncation-toggle:focus:not(:focus-visible){box-shadow:none}.hds-breadcrumb__truncation-toggle:focus-visible,.hds-copy-snippet.mock-focus::before,.hds-copy-snippet:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-breadcrumb__truncation-toggle.mock-focus.mock-active,.hds-breadcrumb__truncation-toggle:focus:active{box-shadow:none}.hds-breadcrumb__truncation-toggle.mock-active,.hds-breadcrumb__truncation-toggle:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-breadcrumb__truncation-content{position:absolute;top:100%;left:-4px;z-index:300;width:-moz-max-content;width:max-content;max-width:200px;margin-top:4px;padding:6px 12px;background-color:var(--token-color-surface-primary);border-radius:6px;box-shadow:var(--token-surface-high-box-shadow)}.hds-button.hds-button--width-full,.hds-copy-snippet--is-truncated,.hds-copy-snippet--width-full,.hds-dropdown-toggle-button--width-full{max-width:100%;width:100%}.hds-button--size-small,.hds-dropdown-toggle-button--size-small{padding:.375rem .6875rem;min-height:1.75rem}.hds-button{position:relative;display:flex;gap:.375rem;justify-content:center;width:auto;text-decoration:none;border:1px solid transparent;border-radius:5px}a.hds-button{width:-moz-fit-content;width:fit-content}a.hds-button.mock-active,a.hds-button.mock-focus,a.hds-button.mock-hover,a.hds-button:active,a.hds-button:focus,a.hds-button:hover{text-decoration:underline}.hds-button.mock-disabled,.hds-button.mock-disabled:focus,.hds-button.mock-disabled:hover,.hds-button:disabled,.hds-button:disabled:focus,.hds-button:disabled:hover,.hds-button[disabled],.hds-button[disabled]:focus,.hds-button[disabled]:hover{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed}.hds-button.mock-disabled::before,.hds-button.mock-disabled:focus::before,.hds-button.mock-disabled:hover::before,.hds-button:disabled::before,.hds-button:disabled:focus::before,.hds-button:disabled:hover::before,.hds-button[disabled]::before,.hds-button[disabled]:focus::before,.hds-button[disabled]:hover::before{border-color:transparent}.hds-button.hds-button--width-full .hds-button__text{flex:0 0 auto}.hds-button__text,.hds-copy-snippet__text,.hds-form-group--radio-cards .hds-form-radio-card--has-fluid-width{flex:1 0 0}.hds-button.mock-focus,.hds-button:focus{box-shadow:none}.hds-button.mock-focus::before,.hds-button:focus::before{position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;z-index:-1;border:3px solid transparent;border-radius:8px;content:""}.hds-button__text{text-align:center}.hds-button--size-small .hds-button__icon{width:.75rem;height:.75rem}.hds-button--size-small .hds-button__text{font-size:.8125rem;line-height:.875rem}.hds-button--size-small.hds-button--is-icon-only{min-width:1.75rem;padding-right:.375rem;padding-left:.375rem}.hds-button--size-medium{min-height:2.25rem;padding:.5625rem .9375rem}.hds-button--size-medium .hds-button__icon{width:1rem;height:1rem}.hds-button--size-medium .hds-button__text{font-size:.875rem;line-height:1rem}.hds-button--size-medium.hds-button--is-icon-only{min-width:2.25rem;padding-right:.5625rem;padding-left:.5625rem}.hds-button--size-large{min-height:3rem;padding:.6875rem 1.1875rem}.hds-button--size-large .hds-button__icon{width:1.5rem;height:1.5rem}.hds-button--size-large .hds-button__text{font-size:1rem;line-height:1.5rem}.hds-button--size-large.hds-button--is-icon-only{min-width:3rem;padding-right:.6875rem;padding-left:.6875rem}.hds-button--color-primary{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-palette-blue-300);box-shadow:var(--token-elevation-low-box-shadow)}.hds-button--color-primary.mock-hover,.hds-button--color-primary:hover{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-300);border-color:var(--token-color-palette-blue-400);cursor:pointer}.hds-button--color-primary.mock-focus,.hds-button--color-primary:focus{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-focus-action-internal)}.hds-button--color-primary.mock-focus::before,.hds-button--color-primary:focus::before{top:-6px;right:-6px;bottom:-6px;left:-6px;border-color:var(--token-color-focus-action-external);border-radius:10px}.hds-button--color-primary.mock-active,.hds-button--color-primary:active{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-400);border-color:var(--token-color-palette-blue-400);box-shadow:none}.hds-button--color-primary.mock-active::before,.hds-button--color-primary:active::before{border-color:transparent}.hds-button--color-secondary{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong);box-shadow:var(--token-elevation-low-box-shadow)}.hds-button--color-secondary.mock-hover,.hds-button--color-secondary:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-button--color-secondary.mock-focus,.hds-button--color-secondary:focus{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal)}.hds-button--color-secondary.mock-focus::before,.hds-button--color-secondary:focus::before{border-color:var(--token-color-focus-action-external)}.hds-button--color-secondary.mock-active,.hds-button--color-secondary:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-button--color-secondary.mock-active::before,.hds-button--color-secondary:active::before{border-color:transparent}.hds-button--color-tertiary{color:var(--token-color-foreground-action);background-color:transparent;border-color:transparent}.hds-button--color-tertiary.mock-hover,.hds-button--color-tertiary:hover{color:var(--token-color-foreground-action-hover);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-button--color-tertiary.mock-focus,.hds-button--color-tertiary:focus{color:var(--token-color-foreground-action);border-color:var(--token-color-focus-action-internal)}.hds-button--color-tertiary.mock-focus::before,.hds-button--color-tertiary:focus::before{border-color:var(--token-color-focus-action-external)}.hds-button--color-tertiary.mock-active,.hds-button--color-tertiary:active{color:var(--token-color-foreground-action-active);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-button--color-tertiary.mock-active::before,.hds-button--color-tertiary:active::before{border-color:transparent}.hds-button--color-tertiary.mock-disabled,.hds-button--color-tertiary.mock-disabled:focus,.hds-button--color-tertiary.mock-disabled:hover,.hds-button--color-tertiary:disabled,.hds-button--color-tertiary:disabled:focus,.hds-button--color-tertiary:disabled:hover,.hds-button--color-tertiary[disabled],.hds-button--color-tertiary[disabled]:focus,.hds-button--color-tertiary[disabled]:hover{background-color:transparent;border-color:transparent}.hds-button--color-tertiary.mock-disabled::before,.hds-button--color-tertiary.mock-disabled:focus::before,.hds-button--color-tertiary.mock-disabled:hover::before,.hds-button--color-tertiary:disabled::before,.hds-button--color-tertiary:disabled:focus::before,.hds-button--color-tertiary:disabled:hover::before,.hds-button--color-tertiary[disabled]::before,.hds-button--color-tertiary[disabled]:focus::before,.hds-button--color-tertiary[disabled]:hover::before{border-color:transparent}.hds-button--color-critical{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-surface-critical);border-color:var(--token-color-foreground-critical-on-surface);box-shadow:var(--token-elevation-low-box-shadow)}.hds-button--color-critical.mock-hover,.hds-button--color-critical:hover{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-red-300);border-color:var(--token-color-palette-red-400);cursor:pointer}.hds-button--color-critical.mock-focus,.hds-button--color-critical:focus{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-surface-critical);border-color:var(--token-color-focus-critical-internal)}.hds-button--color-critical.mock-focus::before,.hds-button--color-critical:focus::before{border-color:var(--token-color-focus-critical-external)}.hds-button--color-critical.mock-active,.hds-button--color-critical:active{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-red-400);border-color:var(--token-color-palette-red-400);box-shadow:none}.hds-button--color-critical.mock-active::before,.hds-button--color-critical:active::before{border-color:transparent}button.hds-button[href]{color:#fff!important;background-color:red!important;border:none}button.hds-button[href]::after{content:' Attention: you’re passing a "href" attribute to the "Hds::Button" component, you should use an "@href" argument.'}.hds-button-set{display:flex;gap:16px}.hds-card__container{position:relative;background-color:#fff;border-radius:6px}.hds-card__container--level-surface-base{box-shadow:var(--token-surface-base-box-shadow)}.hds-card__container--level-surface-mid{box-shadow:var(--token-surface-mid-box-shadow)}.hds-card__container--level-surface-high{box-shadow:var(--token-surface-high-box-shadow)}.hds-card__container--hover-level-surface-base.mock-hover,.hds-card__container--hover-level-surface-base:hover{box-shadow:var(--token-surface-base-box-shadow)}.hds-card__container--hover-level-surface-mid.mock-hover,.hds-card__container--hover-level-surface-mid:hover{box-shadow:var(--token-surface-mid-box-shadow)}.hds-card__container--hover-level-surface-high.mock-hover,.hds-card__container--hover-level-surface-high:hover{box-shadow:var(--token-surface-high-box-shadow)}.hds-card__container--active-level-surface-base.mock-active,.hds-card__container--active-level-surface-base:active{box-shadow:var(--token-surface-base-box-shadow)}.hds-card__container--active-level-surface-mid.mock-active,.hds-card__container--active-level-surface-mid:active{box-shadow:var(--token-surface-mid-box-shadow)}.hds-card__container--active-level-surface-high.mock-active,.hds-card__container--active-level-surface-high:active{box-shadow:var(--token-surface-high-box-shadow)}.hds-card__container--level-elevation-base{box-shadow:var(--token-elevation-base-box-shadow)}.hds-card__container--level-elevation-mid{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-card__container--level-elevation-high{box-shadow:var(--token-elevation-high-box-shadow)}.hds-card__container--hover-level-elevation-base.mock-hover,.hds-card__container--hover-level-elevation-base:hover{box-shadow:var(--token-elevation-base-box-shadow)}.hds-card__container--hover-level-elevation-mid.mock-hover,.hds-card__container--hover-level-elevation-mid:hover{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-card__container--hover-level-elevation-high.mock-hover,.hds-card__container--hover-level-elevation-high:hover{box-shadow:var(--token-elevation-high-box-shadow)}.hds-card__container--active-level-elevation-base.mock-active,.hds-card__container--active-level-elevation-base:active{box-shadow:var(--token-elevation-base-box-shadow)}.hds-card__container--active-level-elevation-mid.mock-active,.hds-card__container--active-level-elevation-mid:active{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-card__container--active-level-elevation-high.mock-active,.hds-card__container--active-level-elevation-high:active{box-shadow:var(--token-elevation-high-box-shadow)}.hds-card__container--background-neutral-primary{background-color:var(--token-color-surface-primary)}.hds-card__container--background-neutral-secondary{background-color:var(--token-color-surface-faint)}.hds-card__container--overflow-visible{overflow:visible}.hds-copy-button{cursor:pointer}.hds-copy-button .hds-button__icon{color:var(--token-color-foreground-action)}.hds-copy-button.hds-copy-button--status-success .hds-button__icon{color:var(--token-color-foreground-success)}.hds-copy-button.hds-copy-button--status-error .hds-button__icon{color:var(--token-color-foreground-critical)}.hds-copy-snippet{position:relative;display:flex;gap:8px;justify-content:space-between;padding:6px 4px;text-align:left;border:1px solid transparent;border-radius:5px;cursor:pointer}.hds-copy-snippet::before,.hds-dismiss-button::before{position:absolute;z-index:-1;content:""}.hds-copy-snippet::before{top:0;right:0;bottom:0;left:0;border-radius:5px}.hds-copy-snippet:focus:not(:focus-visible)::before{box-shadow:none}.hds-copy-snippet:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-copy-snippet.mock-focus.mock-active::before,.hds-copy-snippet:focus:active::before{box-shadow:none}.hds-copy-snippet--color-primary{color:var(--token-color-foreground-action);background-color:transparent}.hds-copy-snippet--color-primary.mock-hover,.hds-copy-snippet--color-primary:hover{color:var(--token-color-foreground-action-hover);background-color:var(--token-color-surface-interactive);border-color:var(--token-color-border-strong)}.hds-copy-snippet--color-primary.mock-active,.hds-copy-snippet--color-primary:active{color:var(--token-color-foreground-action-active);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-copy-snippet--color-primary:focus{background-color:transparent}.hds-copy-snippet--color-secondary{color:var(--token-color-foreground-primary);background-color:transparent}.hds-copy-snippet--color-secondary.mock-hover,.hds-copy-snippet--color-secondary:hover{background-color:var(--token-color-surface-interactive);border-color:var(--token-color-border-strong)}.hds-copy-snippet--color-secondary.mock-active,.hds-copy-snippet--color-secondary:active{background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-copy-snippet--status-error,.hds-copy-snippet--status-success{background-color:var(--token-color-surface-interactive)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon{color:var(--token-color-foreground-action)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon:hover{color:var(--token-color-foreground-action-hover)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon:active{color:var(--token-color-foreground-action-active)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon:focus{color:var(--token-color-foreground-action)}.hds-copy-snippet--status-success .hds-copy-snippet__icon{color:var(--token-color-foreground-success)}.hds-copy-snippet--status-error .hds-copy-snippet__icon{color:var(--token-color-foreground-critical)}.hds-copy-snippet__icon{flex:none}.hds-copy-snippet--is-truncated .hds-copy-snippet__text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.hds-disclosure-primitive{position:relative}.hds-dismiss-button{flex:none;padding:0;color:var(--token-color-foreground-faint);background-color:transparent;border:none;cursor:pointer;position:relative;isolation:isolate}.hds-dismiss-button.mock-hover::before,.hds-dismiss-button:hover::before{background-color:rgba(222,223,227,.4)}.hds-dismiss-button::before{top:-4px;right:-4px;bottom:-4px;left:-4px;border-radius:5px}.hds-dismiss-button.mock-focus::before,.hds-dismiss-button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dismiss-button:focus:not(:focus-visible)::before{box-shadow:none}.hds-dismiss-button:focus-visible::before,.hds-dropdown-toggle-icon.mock-focus::before,.hds-dropdown-toggle-icon:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dismiss-button.mock-focus.mock-active::before,.hds-dismiss-button:focus:active::before{box-shadow:none}.hds-dismiss-button.mock-active,.hds-dismiss-button:active{color:var(--token-color-foreground-secondary)}.hds-dismiss-button.mock-active::before,.hds-dismiss-button:active::before{background-color:rgba(222,223,227,.4);border:1px solid var(--token-color-border-strong)}.hds-dropdown--is-inline .hds-dropdown-toggle-button,.hds-dropdown--is-inline .hds-dropdown-toggle-icon{display:inline-flex}.hds-dropdown-toggle-icon{display:flex;gap:2px;align-items:center;justify-content:center;padding:1px;background-color:var(--token-color-surface-faint);border:1px solid var(--token-color-border-strong);border-radius:5px;position:relative;isolation:isolate}.hds-dropdown-toggle-button,.hds-link-standalone{gap:.375rem;font-family:var(--token-typography-font-stack-text);isolation:isolate}.hds-dropdown-toggle-icon.mock-hover,.hds-dropdown-toggle-icon:hover{background-color:var(--token-color-surface-interactive);cursor:pointer}.hds-dropdown-toggle-icon::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-dropdown-toggle-icon:focus:not(:focus-visible)::before{box-shadow:none}.hds-dropdown-toggle-icon:focus-visible::before,.hds-link-standalone.mock-focus::before,.hds-link-standalone:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dropdown-toggle-icon.mock-focus.mock-active::before,.hds-dropdown-toggle-icon:focus:active::before{box-shadow:none}.hds-dropdown-toggle-icon.mock-active,.hds-dropdown-toggle-icon:active{background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-dropdown-toggle-icon.mock-disabled,.hds-dropdown-toggle-icon:disabled{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed}.hds-dropdown-toggle-icon.mock-disabled::before,.hds-dropdown-toggle-icon:disabled::before{border-color:transparent}.hds-dropdown-toggle-icon__wrapper{display:flex;align-items:center;justify-content:center;border-radius:3px}.hds-dropdown-toggle-icon__wrapper img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;border-radius:inherit}.hds-dropdown-toggle-icon--size-small .hds-dropdown-toggle-icon__wrapper{width:24px;height:24px}.hds-dropdown-toggle-icon--size-medium .hds-dropdown-toggle-icon__wrapper{width:32px;height:32px}.hds-dropdown-toggle-button{position:relative;display:flex;align-items:center;justify-content:center;width:auto;text-decoration:none;border:1px solid transparent;border-radius:5px}.hds-dropdown-toggle-button.mock-focus,.hds-dropdown-toggle-button:focus{box-shadow:none}.hds-dropdown-toggle-button.mock-focus::before,.hds-dropdown-toggle-button:focus::before{position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;z-index:-1;border:3px solid transparent;border-radius:8px;content:""}.hds-dropdown-toggle-button.mock-disabled,.hds-dropdown-toggle-button.mock-disabled:focus,.hds-dropdown-toggle-button.mock-disabled:hover,.hds-dropdown-toggle-button:disabled,.hds-dropdown-toggle-button:disabled:focus,.hds-dropdown-toggle-button:disabled:hover{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed}.hds-dropdown-toggle-button.mock-disabled::before,.hds-dropdown-toggle-button.mock-disabled:focus::before,.hds-dropdown-toggle-button.mock-disabled:hover::before,.hds-dropdown-toggle-button:disabled::before,.hds-dropdown-toggle-button:disabled:focus::before,.hds-dropdown-toggle-button:disabled:hover::before{border-color:transparent}.hds-dropdown-toggle-button.mock-disabled .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button.mock-disabled .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button.mock-disabled:focus .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button.mock-disabled:focus .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button.mock-disabled:hover .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button.mock-disabled:hover .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button:disabled .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button:disabled .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button:disabled:focus .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button:disabled:focus .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button:disabled:hover .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button:disabled:hover .hds-dropdown-toggle-button__count{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-strong)}.hds-dropdown-toggle-button--size-small .hds-dropdown-toggle-button__icon{width:.75rem;height:.75rem}.hds-dropdown-toggle-button--size-small .hds-dropdown-toggle-button__text{font-size:.8125rem;line-height:.875rem}.hds-dropdown-toggle-button--size-small.hds-dropdown-toggle-button--is-icon-only{min-width:1.75rem;padding-right:.375rem;padding-left:.375rem}.hds-dropdown-toggle-button--size-medium{min-height:2.25rem;padding:.5625rem .9375rem}.hds-dropdown-toggle-button--size-medium .hds-dropdown-toggle-button__icon{width:1rem;height:1rem}.hds-dropdown-toggle-button--size-medium .hds-dropdown-toggle-button__text{font-size:.875rem;line-height:1rem}.hds-dropdown-toggle-button--size-medium.hds-dropdown-toggle-button--is-icon-only{min-width:2.25rem;padding-right:.5625rem;padding-left:.5625rem}.hds-dropdown-toggle-button--size-large{min-height:3rem;padding:.6875rem 1.1875rem}.hds-dropdown-toggle-button--size-large .hds-dropdown-toggle-button__icon{width:1.5rem;height:1.5rem}.hds-dropdown-toggle-button--size-large .hds-dropdown-toggle-button__text{font-size:1rem;line-height:1.5rem}.hds-dropdown-toggle-button--size-large.hds-dropdown-toggle-button--is-icon-only{min-width:3rem;padding-right:.6875rem;padding-left:.6875rem}.hds-dropdown-toggle-button--size-small{padding-right:.375rem}.hds-dropdown-toggle-button--size-medium{padding-right:.5625rem}.hds-dropdown-toggle-button--color-primary{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-palette-blue-300);box-shadow:var(--token-elevation-low-box-shadow)}.hds-dropdown-toggle-button--color-primary.mock-hover,.hds-dropdown-toggle-button--color-primary:hover{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-300);border-color:var(--token-color-palette-blue-400);cursor:pointer}.hds-dropdown-toggle-button--color-primary.mock-focus,.hds-dropdown-toggle-button--color-primary:focus{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-focus-action-internal)}.hds-dropdown-toggle-button--color-primary.mock-focus::before,.hds-dropdown-toggle-button--color-primary:focus::before{top:-6px;right:-6px;bottom:-6px;left:-6px;border-color:var(--token-color-focus-action-external);border-radius:10px}.hds-dropdown-toggle-button--color-primary.mock-active,.hds-dropdown-toggle-button--color-primary:active{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-400);border-color:var(--token-color-palette-blue-400);box-shadow:none}.hds-dropdown-toggle-button--color-primary.mock-active::before,.hds-dropdown-toggle-button--color-primary:active::before{border-color:transparent}.hds-dropdown-toggle-button--color-secondary{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong);box-shadow:var(--token-elevation-low-box-shadow)}.hds-dropdown-toggle-button--color-secondary.mock-hover,.hds-dropdown-toggle-button--color-secondary:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-dropdown-toggle-button--color-secondary.mock-focus,.hds-dropdown-toggle-button--color-secondary:focus{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal)}.hds-dropdown-toggle-button--color-secondary.mock-focus::before,.hds-dropdown-toggle-button--color-secondary:focus::before{border-color:var(--token-color-focus-action-external)}.hds-dropdown-toggle-button--color-secondary.mock-active,.hds-dropdown-toggle-button--color-secondary:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-dropdown-toggle-button--color-secondary.mock-active::before,.hds-dropdown-toggle-button--color-secondary:active::before{border-color:transparent}.hds-dropdown-list-item--variant-separator::before,.hds-dropdown__header--with-divider{border-bottom:1px solid var(--token-color-border-primary)}.hds-dropdown-toggle-button--width-full{justify-content:space-between}.hds-dropdown-toggle-button__text{text-align:left}.hds-dropdown-toggle-button__icon{flex:none}.hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button__count{margin:-3px 0}.hds-dropdown-toggle-chevron{margin-left:auto;padding-left:2px}@media (prefers-reduced-motion:no-preference){.hds-accordion-item__button .flight-icon-chevron-down,.hds-dropdown-toggle-chevron .flight-icon-chevron-down{transition:transform .3s}}.hds-dropdown-toggle-button--is-open .hds-dropdown-toggle-chevron .flight-icon-chevron-down,.hds-dropdown-toggle-icon--is-open .hds-dropdown-toggle-chevron .flight-icon-chevron-down{transform:rotate(-180deg)}.hds-dropdown__content{display:flex;flex-direction:column;width:-moz-max-content;width:max-content;min-width:200px;max-width:400px;background-color:var(--token-color-surface-primary);border-radius:6px;box-shadow:var(--token-surface-high-box-shadow)}.hds-dropdown__content--fixed-width{min-width:initial;max-width:initial}.hds-dropdown__content--position-bottom-right{position:absolute;top:calc(100% + 4px);right:0;z-index:2}.hds-dropdown__content--position-bottom-left{position:absolute;top:calc(100% + 4px);left:0;z-index:2}.hds-dropdown__content--position-top-right{position:absolute;right:0;bottom:calc(100% + 4px);z-index:2}.hds-dropdown__content--position-top-left{position:absolute;bottom:calc(100% + 4px);left:0;z-index:2}.hds-dropdown__list{flex:1 1 auto;margin:0;padding:4px 0;overflow-y:auto;list-style:none;overscroll-behavior:contain}.hds-dropdown__footer,.hds-dropdown__header{position:relative;flex:none;padding:0 8px}.hds-dropdown__footer>.hds-link-standalone,.hds-dropdown__header>.hds-link-standalone{width:initial;margin:4px 0;padding:7px 8px}.hds-dropdown__footer>.hds-link-standalone::before,.hds-dropdown__header>.hds-link-standalone::before{top:0;bottom:0}.hds-dropdown__footer>.hds-button,.hds-dropdown__footer>.hds-form-text-input,.hds-dropdown__header>.hds-button,.hds-dropdown__header>.hds-form-text-input{margin:8px 0}.hds-dropdown__footer>.hds-button-set,.hds-dropdown__header>.hds-button-set{gap:8px;margin:8px 0}.hds-dropdown__footer--with-divider{border-top:1px solid var(--token-color-border-primary)}.hds-dropdown-list-item__copy-item-title{padding:2px 0 4px;color:var(--token-color-foreground-faint)}.hds-dropdown-list-item--variant-copy-item{width:100%;padding:10px 16px 12px}.hds-dropdown-list-item--variant-description{padding:2px 16px 4px;color:var(--token-color-foreground-faint)}.hds-dropdown-list-item--variant-generic{padding-right:16px;padding-left:16px}.hds-dropdown-list-item--variant-checkmark,.hds-dropdown-list-item--variant-interactive{position:relative;min-height:36px;isolation:isolate}.hds-dropdown-list-item--variant-checkmark button,.hds-dropdown-list-item--variant-interactive button{width:100%;background-color:transparent}.hds-dropdown-list-item--variant-checkmark button:hover,.hds-dropdown-list-item--variant-interactive button:hover{cursor:pointer}.hds-dropdown-list-item--variant-checkmark a,.hds-dropdown-list-item--variant-checkmark button,.hds-dropdown-list-item--variant-interactive a,.hds-dropdown-list-item--variant-interactive button{display:flex;align-items:flex-start;padding:7px 9px 7px 15px;text-decoration:none;border:1px solid transparent;outline-style:solid;outline-color:transparent}.hds-dropdown-list-item--variant-checkmark a::before,.hds-dropdown-list-item--variant-checkmark button::before,.hds-dropdown-list-item--variant-interactive a::before,.hds-dropdown-list-item--variant-interactive button::before{position:absolute;top:6px;bottom:6px;left:4px;z-index:-1;width:2px;border-radius:1px;content:""}.hds-dropdown-list-item--variant-checkmark a::after,.hds-dropdown-list-item--variant-checkmark button::after,.hds-dropdown-list-item--variant-interactive a::after,.hds-dropdown-list-item--variant-interactive button::after{position:absolute;top:0;right:4px;bottom:0;left:10px;z-index:-1;border-radius:5px;content:""}.hds-dropdown-list-item--variant-checkmark a.mock-hover,.hds-dropdown-list-item--variant-checkmark a:hover,.hds-dropdown-list-item--variant-checkmark button.mock-hover,.hds-dropdown-list-item--variant-checkmark button:hover,.hds-dropdown-list-item--variant-interactive a.mock-hover,.hds-dropdown-list-item--variant-interactive a:hover,.hds-dropdown-list-item--variant-interactive button.mock-hover,.hds-dropdown-list-item--variant-interactive button:hover{color:var(--current-color-hover)}.hds-dropdown-list-item--variant-checkmark a.mock-focus,.hds-dropdown-list-item--variant-checkmark a:focus,.hds-dropdown-list-item--variant-checkmark a:focus-visible,.hds-dropdown-list-item--variant-checkmark button.mock-focus,.hds-dropdown-list-item--variant-checkmark button:focus,.hds-dropdown-list-item--variant-checkmark button:focus-visible,.hds-dropdown-list-item--variant-interactive a.mock-focus,.hds-dropdown-list-item--variant-interactive a:focus,.hds-dropdown-list-item--variant-interactive a:focus-visible,.hds-dropdown-list-item--variant-interactive button.mock-focus,.hds-dropdown-list-item--variant-interactive button:focus,.hds-dropdown-list-item--variant-interactive button:focus-visible{color:var(--current-color-focus)}.hds-dropdown-list-item--variant-checkmark a.mock-hover::before,.hds-dropdown-list-item--variant-checkmark a:hover::before,.hds-dropdown-list-item--variant-checkmark button.mock-hover::before,.hds-dropdown-list-item--variant-checkmark button:hover::before,.hds-dropdown-list-item--variant-interactive a.mock-hover::before,.hds-dropdown-list-item--variant-interactive a:hover::before,.hds-dropdown-list-item--variant-interactive button.mock-hover::before,.hds-dropdown-list-item--variant-interactive button:hover::before{background-color:currentColor}.hds-dropdown-list-item--variant-checkmark a.mock-focus::after,.hds-dropdown-list-item--variant-checkmark a:focus::after,.hds-dropdown-list-item--variant-checkmark button.mock-focus::after,.hds-dropdown-list-item--variant-checkmark button:focus::after,.hds-dropdown-list-item--variant-interactive a.mock-focus::after,.hds-dropdown-list-item--variant-interactive a:focus::after,.hds-dropdown-list-item--variant-interactive button.mock-focus::after,.hds-dropdown-list-item--variant-interactive button:focus::after{left:4px;box-shadow:var(--current-focus-ring-box-shadow)}.hds-dropdown-list-item--variant-checkmark a:focus:not(:focus-visible)::after,.hds-dropdown-list-item--variant-checkmark button:focus:not(:focus-visible)::after,.hds-dropdown-list-item--variant-interactive a:focus:not(:focus-visible)::after,.hds-dropdown-list-item--variant-interactive button:focus:not(:focus-visible)::after{background-color:transparent;box-shadow:none}.hds-dropdown-list-item--variant-checkmark a:focus-visible::after,.hds-dropdown-list-item--variant-checkmark button:focus-visible::after,.hds-dropdown-list-item--variant-interactive a:focus-visible::after,.hds-dropdown-list-item--variant-interactive button:focus-visible::after{left:4px;box-shadow:var(--current-focus-ring-box-shadow)}.hds-dropdown-list-item--variant-checkmark a.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-checkmark a:focus-visible:active::after,.hds-dropdown-list-item--variant-checkmark a:focus:active::after,.hds-dropdown-list-item--variant-checkmark button.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-checkmark button:focus-visible:active::after,.hds-dropdown-list-item--variant-checkmark button:focus:active::after,.hds-dropdown-list-item--variant-interactive a.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-interactive a:focus-visible:active::after,.hds-dropdown-list-item--variant-interactive a:focus:active::after,.hds-dropdown-list-item--variant-interactive button.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-interactive button:focus-visible:active::after,.hds-dropdown-list-item--variant-interactive button:focus:active::after{left:10px;background-color:var(--current-background-color);box-shadow:none}.hds-dropdown-list-item--variant-checkmark a.mock-active,.hds-dropdown-list-item--variant-checkmark a:active,.hds-dropdown-list-item--variant-checkmark button.mock-active,.hds-dropdown-list-item--variant-checkmark button:active,.hds-dropdown-list-item--variant-interactive a.mock-active,.hds-dropdown-list-item--variant-interactive a:active,.hds-dropdown-list-item--variant-interactive button.mock-active,.hds-dropdown-list-item--variant-interactive button:active{color:var(--current-color-active)}.hds-dropdown-list-item--variant-checkmark a.mock-active::before,.hds-dropdown-list-item--variant-checkmark a:active::before,.hds-dropdown-list-item--variant-checkmark button.mock-active::before,.hds-dropdown-list-item--variant-checkmark button:active::before,.hds-dropdown-list-item--variant-interactive a.mock-active::before,.hds-dropdown-list-item--variant-interactive a:active::before,.hds-dropdown-list-item--variant-interactive button.mock-active::before,.hds-dropdown-list-item--variant-interactive button:active::before{background-color:currentColor}.hds-dropdown-list-item__interactive-icon{margin-top:2px;margin-right:8px}.hds-dropdown-list-item__interactive-text{flex:1;text-align:left}.hds-dropdown-list-item--color-action a,.hds-dropdown-list-item--color-action button{color:var(--token-color-foreground-primary);--current-color-hover:var(--token-color-foreground-action-hover);--current-color-focus:var(--token-color-foreground-action-active);--current-color-active:var(--token-color-foreground-action-active)}.hds-dropdown-list-item--color-action a::after,.hds-dropdown-list-item--color-action button::after{--current-focus-ring-box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dropdown-list-item--color-critical a,.hds-dropdown-list-item--color-critical button{color:var(--token-color-foreground-critical);--current-color-hover:var(--token-color-palette-red-300);--current-color-focus:var(--token-color-palette-red-400);--current-color-active:var(--token-color-palette-red-400)}.hds-dropdown-list-item--color-critical a::after,.hds-dropdown-list-item--color-critical button::after{--current-background-color:var(--token-color-surface-critical);--current-focus-ring-box-shadow:var(--token-focus-ring-critical-box-shadow)}.hds-dropdown-list-item__interactive-loading-wrapper{display:flex;align-items:center;padding:8px 10px 8px 16px}.hds-dropdown-list-item__interactive-loading-wrapper .hds-dropdown-list-item__interactive-text{color:var(--token-color-foreground-faint)}.hds-dropdown-list-item__interactive-loading-wrapper .hds-dropdown-list-item__interactive-icon{color:var(--token-color-foreground-primary)}.hds-dropdown-list-item--variant-separator{position:relative;width:100%;height:4px}.hds-dropdown-list-item--variant-separator::before{position:absolute;right:6px;bottom:0;left:6px;content:""}.hds-dropdown-list-item--variant-title{padding:10px 16px 4px;color:var(--token-color-foreground-strong)}.hds-dropdown-list-item--variant-checkmark-selected .hds-dropdown-list-item__interactive{color:var(--token-color-foreground-action)}.hds-dropdown-list-item__checkmark{display:flex;width:16px;height:20px;margin-left:8px}.hds-dropdown-list-item__checkmark-icon{align-self:center}.hds-dropdown-list-item__interactive[disabled],.hds-dropdown-list-item__interactive[disabled]:hover{color:var(--token-color-foreground-disabled);cursor:not-allowed}.hds-dropdown-list-item--variant-checkbox,.hds-dropdown-list-item--variant-radio{display:flex;align-items:self-start;padding:8px 16px}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control{flex-shrink:0;margin-top:2px;margin-right:8px}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__count,.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__icon,.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__text-content,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__count,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__icon,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__text-content{color:var(--token-color-foreground-disabled)}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__label,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__label{display:flex;flex-grow:1;align-items:flex-start;color:var(--token-color-foreground-primary)}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__icon,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__icon{margin-top:2px;margin-right:4px}.hds-dropdown-list-item__count{margin-left:auto;padding-left:8px;color:var(--token-color-foreground-faint);line-height:20px}.hds-dropdown-list-item--variant-checkbox .hds-badge,.hds-dropdown-list-item--variant-checkmark .hds-badge,.hds-dropdown-list-item--variant-radio .hds-badge{vertical-align:bottom}.hds-flyout{z-index:49;flex-direction:column;height:100vh;max-height:100vh;margin:0;padding:0;background:var(--token-color-surface-primary);border:none;box-shadow:0 2px 3px 0 rgba(59,61,69,.2509803922),0 12px 24px 0 rgba(59,61,69,.3490196078)}.hds-flyout__footer .hds-button-set .hds-button--color-tertiary,.hds-modal__footer .hds-button-set .hds-button--color-tertiary{margin-left:auto}.hds-flyout__body,.hds-flyout__footer{border-top:1px solid var(--token-color-border-primary)}.hds-flyout[open]{position:fixed;display:flex}.hds-flyout::backdrop{display:none}.hds-flyout__overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:49;background:var(--token-color-palette-neutral-700);opacity:.5}.hds-form-masked-input__toggle-button,.hds-form-text-input__visibility-toggle{right:calc(var(--token-form-control-padding) - var(--token-form-control-border-width))}.hds-flyout__header{display:flex;flex:none;gap:16px;align-items:flex-start;padding:16px 24px;color:var(--token-color-foreground-strong)}.hds-flyout__icon{flex:none;align-self:center}.hds-flyout__title{flex-grow:1}.hds-flyout__tagline{margin-bottom:4px}.hds-flyout__dismiss{align-self:center}.hds-flyout__description{padding:0 24px 16px}.hds-flyout__body{flex:1 1 auto;padding:24px;overflow-y:auto;overscroll-behavior:contain}.hds-flyout__footer{flex:none;padding:16px 24px;background:var(--token-color-surface-faint)}.hds-flyout--size-medium{width:min(480px,100vw - 40px);max-width:calc(100vw - 40px)}.hds-flyout--size-medium[open]{margin-left:calc(100% - min(480px,100vw - 40px))}.hds-flyout--size-large{width:min(720px,100vw - 40px);max-width:calc(100vw - 40px)}.hds-flyout--size-large[open]{margin-left:calc(100% - min(720px,100vw - 40px))}.hds-form-label{display:block;width:-moz-max-content;width:max-content;max-width:100%;color:var(--token-form-label-color)}.hds-form-label .hds-badge{vertical-align:initial}.hds-form-helper-text{display:block;color:var(--token-form-helper-text-color)}.hds-form-error{display:flex;gap:8px;align-items:flex-start;color:var(--token-form-error-color)}.hds-form-error__icon{flex:none;width:var(--token-form-error-icon-size);height:var(--token-form-error-icon-size);margin:2px 0}.hds-form-error__content{flex:1 1 auto}.hds-form-error__message{margin:0}.hds-form-field--layout-vertical{display:grid;justify-items:start;width:100%}.hds-form-field--layout-vertical .hds-form-field__label{width:-moz-fit-content;width:fit-content}.hds-form-field--layout-vertical .hds-form-field__helper-text:not(:first-child){margin-top:4px}.hds-form-field--layout-vertical .hds-form-field__helper-text+.hds-form-helper-text{margin-top:2px}.hds-form-field--layout-vertical .hds-form-field__control{display:flex;justify-self:stretch}.hds-form-field--layout-vertical .hds-form-field__control:not(:first-child){margin-top:8px}.hds-form-field--layout-vertical .hds-form-field__control:not(:last-child){margin-bottom:8px}.hds-form-field--layout-flag{display:grid;grid-auto-flow:row;grid-template-areas:"control label" "control helper-text" "control error";grid-template-rows:auto auto auto;grid-template-columns:auto 1fr;justify-items:start}.hds-form-field--layout-flag .hds-form-field__label{grid-area:label;width:-moz-fit-content;width:fit-content}.hds-form-field--layout-flag .hds-form-field__helper-text{grid-area:helper-text;margin-top:4px}.hds-form-field--layout-flag .hds-form-field__control{display:flex;grid-area:control}.hds-form-field--layout-flag .hds-form-field__control:not(:only-child){margin-top:2px;margin-right:8px}.hds-form-field--layout-flag .hds-form-field__error{grid-area:error;margin-top:4px}.hds-form-file-input{margin:-4px 0 -4px -4px;padding:3px 0 3px 3px;color:var(--token-color-foreground-primary)}.hds-form-file-input:focus,.hds-form-file-input:focus-visible{outline:0}.hds-form-file-input::file-selector-button{min-height:36px;margin-right:16px;padding:7px 16px 7px 37px;color:var(--token-color-foreground-primary);font:inherit;background-color:var(--token-color-surface-faint);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cg fill='%233b3d45'%3E%3Cpath d='M4.24 5.8a.75.75 0 001.06-.04l1.95-2.1v6.59a.75.75 0 001.5 0V3.66l1.95 2.1a.75.75 0 101.1-1.02l-3.25-3.5a.75.75 0 00-1.101.001L4.2 4.74a.75.75 0 00.04 1.06z'/%3E%3Cpath d='M1.75 9a.75.75 0 01.75.75v3c0 .414.336.75.75.75h9.5a.75.75 0 00.75-.75v-3a.75.75 0 011.5 0v3A2.25 2.25 0 0112.75 15h-9.5A2.25 2.25 0 011 12.75v-3A.75.75 0 011.75 9z'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:15px 50%;background-size:var(--token-form-text-input-background-image-size);border:1px solid var(--token-color-border-strong);border-radius:5px;box-shadow:var(--token-elevation-low-box-shadow);cursor:pointer}.hds-form-group__legend~.hds-form-group__control-fields-wrapper .hds-form-label,.hds-link-standalone{font-weight:var(--token-typography-font-weight-regular)}.hds-form-file-input.mock-hover::file-selector-button,.hds-form-file-input::file-selector-button:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong)}.hds-form-file-input.mock-focus::file-selector-button,.hds-form-file-input:focus-within::file-selector-button{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px}.hds-form-file-input:not(:focus,.mock-focus)::file-selector-button{border-color:var(--token-color-border-strong);outline:0}.hds-form-file-input.mock-active::file-selector-button,.hds-form-file-input::file-selector-button:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-form-file-input.mock-disabled,.hds-form-file-input.mock-disabled:focus,.hds-form-file-input.mock-disabled:hover,.hds-form-file-input:disabled,.hds-form-file-input:disabled:focus,.hds-form-file-input:disabled:hover,.hds-form-file-input[disabled],.hds-form-file-input[disabled]:focus,.hds-form-file-input[disabled]:hover{color:var(--token-color-foreground-disabled)}.hds-form-file-input.mock-disabled::file-selector-button,.hds-form-file-input.mock-disabled:focus::file-selector-button,.hds-form-file-input.mock-disabled:hover::file-selector-button,.hds-form-file-input:disabled::file-selector-button,.hds-form-file-input:disabled:focus::file-selector-button,.hds-form-file-input:disabled:hover::file-selector-button,.hds-form-file-input[disabled]::file-selector-button,.hds-form-file-input[disabled]:focus::file-selector-button,.hds-form-file-input[disabled]:hover::file-selector-button{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cg fill='%238c909c'%3E%3Cpath d='M4.24 5.8a.75.75 0 001.06-.04l1.95-2.1v6.59a.75.75 0 001.5 0V3.66l1.95 2.1a.75.75 0 101.1-1.02l-3.25-3.5a.75.75 0 00-1.101.001L4.2 4.74a.75.75 0 00.04 1.06z'/%3E%3Cpath d='M1.75 9a.75.75 0 01.75.75v3c0 .414.336.75.75.75h9.5a.75.75 0 00.75-.75v-3a.75.75 0 011.5 0v3A2.25 2.25 0 0112.75 15h-9.5A2.25 2.25 0 011 12.75v-3A.75.75 0 011.75 9z'/%3E%3C/g%3E%3C/svg%3E")}.hds-form-file-input.mock-disabled::file-selector-button::before,.hds-form-file-input.mock-disabled:focus::file-selector-button::before,.hds-form-file-input.mock-disabled:hover::file-selector-button::before,.hds-form-file-input:disabled::file-selector-button::before,.hds-form-file-input:disabled:focus::file-selector-button::before,.hds-form-file-input:disabled:hover::file-selector-button::before,.hds-form-file-input[disabled]::file-selector-button::before,.hds-form-file-input[disabled]:focus::file-selector-button::before,.hds-form-file-input[disabled]:hover::file-selector-button::before{border-color:transparent}.hds-form-legend{display:block;color:var(--token-form-legend-color)}.hds-form-legend .hds-badge{vertical-align:initial}.hds-form-group{display:block;margin:0;padding:0;border:none}.hds-form-checkbox,.hds-form-radio{background-position:center center;border-style:solid;-moz-appearance:none}.hds-form-group__legend{margin:0 0 4px;padding:0}.hds-form-group--layout-vertical .hds-form-group__control-fields-wrapper{display:flex;flex-direction:column}.hds-form-group--layout-vertical .hds-form-group__control-field+.hds-form-group__control-field{margin-top:12px}.hds-form-group--layout-horizontal .hds-form-group__control-fields-wrapper{display:flex;flex-wrap:wrap;margin-bottom:-4px}.hds-form-group--layout-horizontal .hds-form-group__control-field{margin-right:16px;margin-bottom:4px}.hds-form-group__helper-text{margin-bottom:8px}.hds-form-group__error{margin-top:8px}.hds-form-indicator--optional{color:var(--token-form-indicator-optional-color)}.hds-form-checkbox{width:var(--token-form-checkbox-size);height:var(--token-form-checkbox-size);margin:0;padding:0;background-size:var(--token-form-checkbox-background-image-size) var(--token-form-checkbox-background-image-size);border-width:var(--token-form-checkbox-border-width);border-radius:var(--token-form-checkbox-border-radius);cursor:pointer;-webkit-appearance:none;appearance:none}.hds-form-checkbox:not(:checked,:indeterminate){background-color:var(--token-form-control-base-surface-color-default);border-color:var(--token-form-control-base-border-color-default)}.hds-form-checkbox:checked,.hds-form-checkbox:indeterminate{background-color:var(--token-form-control-checked-surface-color-default);border-color:var(--token-form-control-checked-border-color-default)}.hds-form-checkbox:checked{background-image:var(--token-form-checkbox-background-image-data-url)}.hds-form-checkbox:indeterminate{background-image:var(--token-form-checkbox-background-image-data-url-indeterminate)}.hds-form-checkbox.mock-hover:not(:checked,:indeterminate),.hds-form-checkbox:hover:not(:checked,:indeterminate){background-color:var(--token-form-control-base-surface-color-hover);border-color:var(--token-form-control-base-border-color-hover)}.hds-form-checkbox.mock-hover:checked,.hds-form-checkbox.mock-hover:indeterminate,.hds-form-checkbox:hover:checked,.hds-form-checkbox:hover:indeterminate{background-color:var(--token-form-control-checked-border-color-default);border-color:var(--token-form-control-checked-border-color-hover)}.hds-form-checkbox:disabled:checked,.hds-form-checkbox:disabled:indeterminate,.hds-form-checkbox:disabled:not(:checked,:indeterminate){background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-checkbox.mock-focus,.hds-form-checkbox:focus{outline:var(--token-color-focus-action-external) solid 3px;outline-offset:1px}.hds-form-checkbox:disabled:checked{background-image:var(--token-form-checkbox-background-image-data-url-disabled)}.hds-form-checkbox:disabled:indeterminate{background-image:var(--token-form-checkbox-background-image-data-url-indeterminate-disabled);background-repeat:no-repeat}.hds-form-masked-input{position:relative;display:grid;grid-template-areas:"input copy-button";grid-template-columns:1fr auto;width:100%}.hds-form-masked-input .hds-form-masked-input__control{grid-area:input;padding-right:calc(var(--token-form-control-padding) + 24px)}.hds-form-masked-input--is-masked .hds-form-masked-input__control{-webkit-text-security:disc}.hds-form-masked-input--is-not-masked .hds-form-masked-input__control{-webkit-text-security:none}.hds-form-masked-input__toggle-button{position:absolute;top:calc(var(--token-form-control-padding) - var(--token-form-control-border-width));grid-area:input}.hds-form-masked-input__copy-button{grid-area:copy-button;align-self:flex-start;margin-left:8px}.hds-form-radio{width:var(--token-form-radio-size);height:var(--token-form-radio-size);margin:0;padding:0;background-size:var(--token-form-radio-background-image-size) var(--token-form-radio-background-image-size);border-width:var(--token-form-radio-border-width);border-radius:50%;cursor:pointer;-webkit-appearance:none;appearance:none}.hds-form-radio:not(:checked){background-color:var(--token-form-control-base-surface-color-default);border-color:var(--token-form-control-base-border-color-default);box-shadow:var(--token-elevation-inset-box-shadow)}.hds-form-radio:checked{background-color:var(--token-form-control-checked-surface-color-default);background-image:var(--token-form-radio-background-image-data-url);border-color:var(--token-form-control-checked-border-color-default)}.hds-form-radio.mock-hover:not(:checked),.hds-form-radio:hover:not(:checked){background-color:var(--token-form-control-base-surface-color-hover);border-color:var(--token-form-control-base-border-color-hover)}.hds-form-radio.mock-hover:checked,.hds-form-radio:hover:checked{background-color:var(--token-form-control-checked-border-color-default);border-color:var(--token-form-control-checked-border-color-hover)}.hds-form-radio:disabled:checked,.hds-form-radio:disabled:not(:checked){background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-radio.mock-focus,.hds-form-radio:focus{outline:var(--token-color-focus-action-external) solid 3px;outline-offset:1px}.hds-form-radio:disabled:checked{background-image:var(--token-form-radio-background-image-data-url-disabled)}.hds-form-group--radio-cards .hds-form-group__control-fields-wrapper{margin:calc(-1 * var(--token-form-radiocard-group-gap)/ 2)}.hds-form-group--radio-cards .hds-form-group__legend{margin-bottom:12px}.hds-form-group--radio-cards .hds-form-radio-card{margin:calc(var(--token-form-radiocard-group-gap)/ 2)}.hds-form-group--radio-cards .hds-form-radio-card--has-fixed-width{flex:1 0 100%}.hds-form-radio-card{display:flex;flex-direction:column;background-color:var(--token-color-surface-primary);border:var(--token-form-radiocard-border-width) solid var(--token-color-border-primary);border-radius:var(--token-form-radiocard-border-radius);box-shadow:var(--token-elevation-mid-box-shadow);cursor:pointer}.hds-form-radio-card .hds-form-radio-card__control{outline-color:transparent}.hds-form-radio-card.mock-hover,.hds-form-radio-card:hover{box-shadow:var(--token-elevation-high-box-shadow);transition:var(--token-form-radiocard-transition-duration)}.hds-form-radio-card.mock-focus,.hds-form-radio-card:focus-within{border-color:var(--token-color-focus-action-internal);box-shadow:0 0 0 3px var(--token-color-focus-action-external)}.hds-form-radio-card--checked,.hds-form-radio-card.mock-checked{border-color:var(--token-color-focus-action-internal)}.hds-form-radio-card--checked .hds-form-radio-card__control-wrapper,.hds-form-radio-card.mock-checked .hds-form-radio-card__control-wrapper{background-color:var(--token-color-surface-action);border-color:var(--token-color-border-action)}.hds-form-radio-card--disabled,.hds-form-radio-card--disabled .hds-form-radio-card__control-wrapper,.hds-form-radio-card.mock-disabled,.hds-form-radio-card.mock-disabled .hds-form-radio-card__control-wrapper{background-color:var(--token-color-surface-interactive-disabled);border-color:var(--token-color-border-primary)}.hds-form-radio-card--disabled,.hds-form-radio-card.mock-disabled{box-shadow:none;cursor:not-allowed}.hds-form-radio-card--align-left{text-align:left}.hds-form-radio-card--align-center{text-align:center}.hds-form-radio-card--align-center .flight-icon{margin:auto}.hds-form-radio-card--control-bottom .hds-form-radio-card__control-wrapper{border-top-width:var(--token-form-radiocard-border-width);border-top-style:solid;border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.hds-form-radio-card--control-left{flex-direction:row-reverse}.hds-form-radio-card--control-left .hds-form-radio-card__control-wrapper{display:flex;align-items:center;border-right-width:var(--token-form-radiocard-border-width);border-right-style:solid;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.hds-form-radio-card__content{flex:1;padding:var(--token-form-radiocard-content-padding)}.hds-form-radio-card__content .hds-badge{margin-bottom:12px}.hds-form-radio-card__label{display:block;margin:8px 0;color:var(--token-form-label-color);overflow-wrap:break-word}.hds-form-radio-card__label:first-child{margin-top:0}.hds-form-radio-card__description{display:block;color:var(--token-color-foreground-primary)}.hds-form-radio-card__control-wrapper{padding:var(--token-form-radiocard-control-padding);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary)}.hds-form-select,.hds-form-text-input{border:var(--token-form-control-border-width) solid var(--token-form-control-base-border-color-default)}.hds-form-radio-card__control{display:block;margin:auto}.hds-form-select{max-width:100%;padding:var(--token-form-control-padding);padding-right:calc(var(--token-form-control-padding) + 24px);color:var(--token-form-control-base-foreground-value-color);background-color:var(--token-form-control-base-surface-color-default);background-image:var(--token-form-select-background-image-data-url);background-repeat:no-repeat;background-position:right var(--token-form-select-background-image-position-right-x) top var(--token-form-select-background-image-position-top-y);background-size:var(--token-form-select-background-image-size) var(--token-form-select-background-image-size);border-radius:var(--token-form-control-border-radius);box-shadow:var(--token-elevation-low-box-shadow);-webkit-appearance:none;-moz-appearance:none;appearance:none}.hds-form-select.mock-hover,.hds-form-select:hover{border-color:var(--token-form-control-base-border-color-hover)}.hds-form-select.mock-focus,.hds-form-select:focus{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px;outline-offset:0}.hds-form-select:disabled{color:var(--token-form-control-disabled-foreground-color);background-color:var(--token-form-control-disabled-surface-color);background-image:var(--token-form-select-background-image-data-url-disabled);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-select.hds-form-select--is-invalid{border-color:var(--token-form-control-invalid-border-color-default)}.hds-form-select.hds-form-select--is-invalid.mock-hover,.hds-form-select.hds-form-select--is-invalid:hover{border-color:var(--token-form-control-invalid-border-color-hover)}.hds-form-select.hds-form-select--is-invalid.mock-focus,.hds-form-select.hds-form-select--is-invalid:focus{border-color:var(--token-color-focus-critical-internal);outline-color:var(--token-color-focus-critical-external)}.hds-form-select[multiple],.hds-form-select[size]{background:0 0}.hds-form-select[multiple] option,.hds-form-select[size] option{margin:2px auto;border-radius:3px}.hds-form-select[multiple] option:hover,.hds-form-select[size] option:hover{color:var(--token-color-foreground-action)}.hds-form-select[multiple] option:disabled,.hds-form-select[size] option:disabled{color:var(--token-color-foreground-disabled)}.hds-form-select[multiple] option:checked,.hds-form-select[size] option:checked{color:var(--token-color-foreground-high-contrast);background:var(--token-color-palette-blue-200)}.hds-form-text-input,.hds-form-textarea{background-color:var(--token-form-control-base-surface-color-default);max-width:100%}.hds-form-select[multiple] optgroup,.hds-form-select[size] optgroup{color:var(--token-color-foreground-strong);font-weight:var(--token-typography-font-weight-semibold);font-style:normal}.hds-form-text-input{width:100%;padding:var(--token-form-control-padding);color:var(--token-form-control-base-foreground-value-color);border-radius:var(--token-form-control-border-radius);box-shadow:var(--token-elevation-inset-box-shadow)}.hds-form-text-input ::-moz-placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-text-input ::placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-text-input.mock-hover,.hds-form-text-input:hover{border-color:var(--token-form-control-base-border-color-hover)}.hds-form-text-input.mock-focus,.hds-form-text-input:focus{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px;outline-offset:0}.hds-form-text-input:-moz-read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-text-input:read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-text-input:disabled{color:var(--token-form-control-disabled-foreground-color);background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-text-input.hds-form-text-input--is-invalid{border-color:var(--token-form-control-invalid-border-color-default)}.hds-form-text-input.hds-form-text-input--is-invalid.mock-hover,.hds-form-text-input.hds-form-text-input--is-invalid:hover{border-color:var(--token-form-control-invalid-border-color-hover)}.hds-form-text-input.hds-form-text-input--is-invalid.mock-focus,.hds-form-text-input.hds-form-text-input--is-invalid:focus{border-color:var(--token-color-focus-critical-internal);outline-color:var(--token-color-focus-critical-external)}.hds-form-text-input__wrapper{position:relative;width:100%}.hds-form-text-input--has-visibility-toggle{padding-right:calc(var(--token-form-control-padding) + 24px)}.hds-form-text-input__visibility-toggle{position:absolute;top:calc(var(--token-form-control-padding) - var(--token-form-control-border-width))}.hds-form-text-input[type=date],.hds-form-text-input[type=datetime-local],.hds-form-text-input[type=time]{width:initial}.hds-form-text-input[type=date]:disabled::-webkit-calendar-picker-indicator,.hds-form-text-input[type=datetime-local]:disabled::-webkit-calendar-picker-indicator,.hds-form-text-input[type=time]:disabled::-webkit-calendar-picker-indicator{visibility:visible;opacity:.5}.hds-form-text-input[type=date][readonly]::-webkit-calendar-picker-indicator,.hds-form-text-input[type=datetime-local][readonly]::-webkit-calendar-picker-indicator,.hds-form-text-input[type=time][readonly]::-webkit-calendar-picker-indicator{visibility:visible}.hds-form-text-input[type=date]::-webkit-calendar-picker-indicator,.hds-form-text-input[type=datetime-local]::-webkit-calendar-picker-indicator{background-image:var(--token-form-text-input-background-image-data-url-date);background-position:center center;background-size:var(--token-form-text-input-background-image-size)}.hds-form-text-input[type=time]::-webkit-calendar-picker-indicator{background-image:var(--token-form-text-input-background-image-data-url-time);background-position:center center;background-size:var(--token-form-text-input-background-image-size)}.hds-form-text-input[type=search]{padding-left:calc(var(--token-form-control-padding) + 24px);background-image:var(--token-form-text-input-background-image-data-url-search);background-repeat:no-repeat;background-position:var(--token-form-text-input-background-image-position-x) 50%;background-size:var(--token-form-text-input-background-image-size)}.hds-form-text-input[type=search]::-webkit-search-cancel-button{width:var(--token-form-text-input-background-image-size);height:var(--token-form-text-input-background-image-size);background-image:var(--token-form-text-input-background-image-data-url-search-cancel);background-position:center center;background-size:var(--token-form-text-input-background-image-size);-webkit-appearance:none}.hds-form-text-input[type=search].hds-form-text-input--is-loading{background-image:var(--token-form-text-input-background-image-data-url-search-loading)}.hds-form-textarea{width:100%;min-height:36px;padding:var(--token-form-control-padding);color:var(--token-form-control-base-foreground-value-color);border:var(--token-form-control-border-width) solid var(--token-form-control-base-border-color-default);border-radius:var(--token-form-control-border-radius);box-shadow:var(--token-elevation-inset-box-shadow);resize:vertical}.hds-form-textarea ::-moz-placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-textarea ::placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-textarea.mock-hover,.hds-form-textarea:hover{border-color:var(--token-form-control-base-border-color-hover)}.hds-form-textarea.mock-focus,.hds-form-textarea:focus{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px;outline-offset:0}.hds-form-textarea:-moz-read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-textarea:read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-textarea:disabled{color:var(--token-form-control-disabled-foreground-color);background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-textarea.hds-form-textarea--is-invalid{border-color:var(--token-form-control-invalid-border-color-default)}.hds-form-textarea.hds-form-textarea--is-invalid.mock-hover,.hds-form-textarea.hds-form-textarea--is-invalid:hover{border-color:var(--token-form-control-invalid-border-color-hover)}.hds-form-textarea.hds-form-textarea--is-invalid.mock-focus,.hds-form-textarea.hds-form-textarea--is-invalid:focus{border-color:var(--token-color-focus-critical-internal);outline-color:var(--token-color-focus-critical-external)}.hds-form-toggle{position:relative;isolation:isolate}.hds-form-toggle__control{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:block;height:100%;margin:0;padding:0;color:transparent;background-color:transparent;border:none;outline:0;cursor:pointer;opacity:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.hds-form-toggle__control:disabled{cursor:not-allowed}.hds-form-toggle__facade{position:relative;display:block;width:var(--token-form-toggle-width);height:var(--token-form-toggle-height);background-image:var(--token-form-toggle-background-image-data-url);background-repeat:no-repeat;background-position:var(--token-form-toggle-background-image-position-x) 50%;background-size:var(--token-form-toggle-background-image-size) var(--token-form-toggle-background-image-size);border:var(--token-form-radio-border-width) solid var(--border-color);border-radius:calc(var(--token-form-toggle-height)/ 2)}.hds-form-toggle__facade::after{position:absolute;top:calc(var(--token-form-radio-border-width) * -1);left:calc(var(--token-form-radio-border-width) * -1);width:var(--token-form-toggle-thumb-size);height:var(--token-form-toggle-thumb-size);background-color:var(--token-form-control-base-surface-color-default);border:var(--token-form-radio-border-width) solid var(--border-color);border-radius:50%;transform:translate3d(0,0,0);content:""}@media (prefers-reduced-motion:no-preference){.hds-form-toggle__facade,.hds-form-toggle__facade::after{transition-timing-function:var(--token-form-toggle-transition-timing-function);transition-duration:var(--token-form-toggle-transition-duration);transition-property:all}}.hds-form-toggle__facade::before{position:absolute;top:-5px;right:-5px;bottom:-5px;left:-5px;margin:auto;border-width:3px;border-radius:calc(var(--token-form-toggle-height)/ 2 + 3px + 1px);content:""}:not(:checked)+.hds-form-toggle__facade{--border-color:var(--token-form-control-base-border-color-default);background-color:var(--token-form-toggle-base-surface-color-default)}:checked+.hds-form-toggle__facade{--border-color:var(--token-form-control-checked-border-color-default);background-color:var(--token-form-control-checked-surface-color-default)}:checked+.hds-form-toggle__facade::after{transform:translate3d(calc(var(--token-form-toggle-width) - var(--token-form-toggle-thumb-size)),0,0)}.mock-hover:not(:checked)+.hds-form-toggle__facade,:hover:not(:checked)+.hds-form-toggle__facade{--border-color:var(--token-form-control-base-border-color-hover)}.mock-hover:checked+.hds-form-toggle__facade,:hover:checked+.hds-form-toggle__facade{--border-color:var(--token-form-control-checked-border-color-hover);background-color:var(--token-form-control-checked-border-color-default)}.mock-focus+.hds-form-toggle__facade::before,:focus+.hds-form-toggle__facade::before{border-color:var(--token-color-focus-action-external);border-style:solid}:disabled:checked+.hds-form-toggle__facade,:disabled:not(:checked)+.hds-form-toggle__facade{--border-color:var(--token-form-control-disabled-border-color);background-color:var(--token-form-control-disabled-surface-color);background-image:var(--token-form-toggle-background-image-data-url-disabled)}.hds-form-visibility-toggle{width:24px;height:24px;padding:2px;color:var(--token-color-foreground-primary);background-color:transparent;border-color:transparent;cursor:pointer}.hds-icon-tile--logo,.hds-icon-tile__extra{background-color:var(--token-color-surface-primary)}.hds-icon-tile{position:relative;display:flex;border:1px solid transparent;border-radius:4px;box-shadow:0 1px 1px rgba(101,106,118,.05)}.hds-icon-tile__icon,.hds-icon-tile__logo{display:flex;margin:auto}.hds-icon-tile__extra{position:absolute;right:-6px;bottom:-6px;display:flex;box-sizing:content-box;border:1px solid var(--token-color-border-primary);box-shadow:0 1px 1px rgba(101,106,118,.05)}.hds-icon-tile__extra-icon{display:flex;margin:auto;color:var(--token-color-foreground-strong)}.hds-icon-tile--size-small{width:1.75rem;height:1.75rem;border-radius:5px}.hds-icon-tile--size-small .hds-icon-tile__icon{width:1rem;height:1rem}.hds-icon-tile--size-small .hds-icon-tile__logo{width:1.125rem;height:1.125rem}.hds-icon-tile--size-small .hds-icon-tile__extra{width:1.125rem;height:1.125rem;border-radius:4px}.hds-icon-tile--size-small .hds-icon-tile__extra-icon{width:.75rem;height:.75rem}.hds-icon-tile--size-medium{width:2.5rem;height:2.5rem;border-radius:6px}.hds-icon-tile--size-medium .hds-icon-tile__icon{width:1.5rem;height:1.5rem}.hds-icon-tile--size-medium .hds-icon-tile__logo{width:1.75rem;height:1.75rem}.hds-icon-tile--size-medium .hds-icon-tile__extra{width:1.5rem;height:1.5rem;border-radius:5px}.hds-icon-tile--size-medium .hds-icon-tile__extra-icon{width:1rem;height:1rem}.hds-icon-tile--size-large{width:3rem;height:3rem;border-radius:6px}.hds-icon-tile--size-large .hds-icon-tile__icon{width:1.5rem;height:1.5rem}.hds-icon-tile--size-large .hds-icon-tile__logo{width:2rem;height:2rem}.hds-icon-tile--size-large .hds-icon-tile__extra{width:1.5rem;height:1.5rem;border-radius:5px}.hds-icon-tile--size-large .hds-icon-tile__extra-icon{width:1rem;height:1rem}.hds-icon-tile--logo{border-color:var(--token-color-border-primary)}.hds-icon-tile--icon.hds-icon-tile--color-neutral{color:var(--token-color-foreground-faint);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary)}.hds-icon-tile--icon.hds-icon-tile--color-boundary{color:var(--token-color-boundary-foreground);background:linear-gradient(135deg,var(--token-color-boundary-gradient-faint-start) 0,var(--token-color-boundary-gradient-faint-stop) 100%);border-color:var(--token-color-boundary-border)}.hds-icon-tile--icon.hds-icon-tile--color-consul{color:var(--token-color-consul-foreground);background:linear-gradient(135deg,var(--token-color-consul-gradient-faint-start) 0,var(--token-color-consul-gradient-faint-stop) 100%);border-color:var(--token-color-consul-border)}.hds-icon-tile--icon.hds-icon-tile--color-hcp{color:var(--token-color-palette-hcp-brand);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary)}.hds-icon-tile--icon.hds-icon-tile--color-nomad{color:var(--token-color-nomad-foreground);background:linear-gradient(135deg,var(--token-color-nomad-gradient-faint-start) 0,var(--token-color-nomad-gradient-faint-stop) 100%);border-color:var(--token-color-nomad-border)}.hds-icon-tile--icon.hds-icon-tile--color-packer{color:var(--token-color-packer-foreground);background:linear-gradient(135deg,var(--token-color-packer-gradient-faint-start) 0,var(--token-color-packer-gradient-faint-stop) 100%);border-color:var(--token-color-packer-border)}.hds-icon-tile--icon.hds-icon-tile--color-terraform{color:var(--token-color-terraform-foreground);background:linear-gradient(135deg,var(--token-color-terraform-gradient-faint-start) 0,var(--token-color-terraform-gradient-faint-stop) 100%);border-color:var(--token-color-terraform-border)}.hds-icon-tile--icon.hds-icon-tile--color-vagrant{color:var(--token-color-vagrant-foreground);background:linear-gradient(135deg,var(--token-color-vagrant-gradient-faint-start) 0,var(--token-color-vagrant-gradient-faint-stop) 100%);border-color:var(--token-color-vagrant-border)}.hds-icon-tile--icon.hds-icon-tile--color-vault{color:var(--token-color-vault-foreground);background:linear-gradient(135deg,var(--token-color-vault-gradient-faint-start) 0,var(--token-color-vault-gradient-faint-stop) 100%);border-color:var(--token-color-vault-border)}.hds-icon-tile--icon.hds-icon-tile--color-vault-secrets{color:var(--token-color-vault-secrets-foreground);background:linear-gradient(135deg,var(--token-color-vault-secrets-gradient-faint-start) 0,var(--token-color-vault-secrets-gradient-faint-stop) 100%);border-color:var(--token-color-vault-secrets-border)}.hds-icon-tile--icon.hds-icon-tile--color-waypoint{color:var(--token-color-waypoint-foreground);background:linear-gradient(135deg,var(--token-color-waypoint-gradient-faint-start) 0,var(--token-color-waypoint-gradient-faint-stop) 100%);border-color:var(--token-color-waypoint-border)}.hds-link-inline{border-radius:2px}.hds-link-inline.mock-focus,.hds-link-inline:focus,.hds-link-inline:focus-visible{text-decoration:none;outline:var(--token-color-focus-action-internal) solid 2px;outline-offset:1px}.hds-link-inline__icon{display:inline-block;width:1em;height:1em;vertical-align:text-bottom}.hds-link-inline--icon-leading>.hds-link-inline__icon{margin-right:.25em}.hds-link-inline--icon-trailing>.hds-link-inline__icon{margin-left:.25em}.hds-link-inline--color-primary{color:var(--token-color-foreground-action)}.hds-link-inline--color-primary.mock-hover,.hds-link-inline--color-primary:hover{color:var(--token-color-foreground-action-hover)}.hds-link-inline--color-primary.mock-active,.hds-link-inline--color-primary:active{color:var(--token-color-foreground-action-active)}.hds-link-inline--color-secondary{color:var(--token-color-foreground-strong)}.hds-link-inline--color-secondary.mock-hover,.hds-link-inline--color-secondary:hover{color:var(--token-color-foreground-primary)}.hds-link-inline--color-secondary.mock-active,.hds-link-inline--color-secondary:active{color:var(--token-color-foreground-faint)}.hds-link-standalone{display:flex;align-items:center;justify-content:center;width:-moz-fit-content;width:fit-content;padding-top:4px;padding-bottom:4px;background-color:transparent;border:1px solid transparent;text-decoration-color:transparent;position:relative;outline-style:solid;outline-color:transparent}.hds-link-standalone__text{flex:1 0 0;text-decoration:underline;text-decoration-color:transparent;transition:text-decoration-color .25s ease-in}#login-toggle+div footer button,.consul-intention-fieldsets .permissions>button,.empty-state>ul>li>*,.empty-state>ul>li>:active,.empty-state>ul>li>label>button,.empty-state>ul>li>label>button:active,.hds-pagination-nav__control,.hds-side-nav__list-item-link,.hds-tabs__tab,.modal-dialog [role=document] dd a,.modal-dialog [role=document] p a,.oidc-select button.reset,.search-bar-status .remove-all button,a,main dd a,main dd a:active,main p a,main p a:active{text-decoration:none}.hds-link-standalone--size-small .hds-link-standalone__icon{width:.75rem;height:.75rem}.hds-link-standalone--size-small .hds-link-standalone__text{font-size:.8125rem;line-height:1.231}.hds-link-standalone--size-medium .hds-link-standalone__icon{width:1rem;height:1rem}.hds-link-standalone--size-medium .hds-link-standalone__text{font-size:.875rem;line-height:1.143}.hds-link-standalone--size-large .hds-link-standalone__icon{width:1.5rem;height:1.5rem}.hds-link-standalone--size-large .hds-link-standalone__text{font-size:1rem;line-height:1.5}.hds-link-standalone--color-primary{color:var(--token-color-foreground-action)}.hds-link-standalone--color-primary.mock-hover,.hds-link-standalone--color-primary:hover{color:var(--token-color-foreground-action-hover)}.hds-link-standalone--color-primary.mock-hover .hds-link-standalone__text,.hds-link-standalone--color-primary:hover .hds-link-standalone__text{text-decoration-color:#4e81e8}.hds-link-standalone--color-primary.mock-active,.hds-link-standalone--color-primary:active{color:var(--token-color-foreground-action-active)}.hds-link-standalone--color-primary.mock-active .hds-link-standalone__text,.hds-link-standalone--color-primary:active .hds-link-standalone__text{text-decoration-color:#396ed6}.hds-link-standalone--color-primary.mock-active::before,.hds-link-standalone--color-primary:active::before{background-color:var(--token-color-surface-action)}.hds-link-standalone--color-secondary{color:var(--token-color-foreground-strong)}.hds-link-standalone--color-secondary.mock-hover .hds-link-standalone__text,.hds-link-standalone--color-secondary:hover .hds-link-standalone__text{text-decoration-color:#4d4d4f}.hds-link-standalone--color-secondary.mock-active,.hds-link-standalone--color-secondary:active{color:var(--token-color-foreground-primary)}.hds-link-standalone--color-secondary.mock-active .hds-link-standalone__text,.hds-link-standalone--color-secondary:active .hds-link-standalone__text{text-decoration-color:#6e7075}.hds-link-standalone--color-secondary.mock-active::before,.hds-link-standalone--color-secondary:active::before{background-color:var(--token-color-surface-interactive-active)}.hds-link-standalone::before{position:absolute;top:0;right:-5px;bottom:0;left:-5px;z-index:-1;border-radius:5px;content:""}.hds-link-standalone:focus:not(:focus-visible)::before{box-shadow:none}.hds-link-standalone:focus-visible::before,.hds-pagination-nav__control.mock-focus::before,.hds-pagination-nav__control:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-link-standalone.mock-focus.mock-active::before,.hds-link-standalone:focus:active::before{box-shadow:none}.hds-link-standalone.hds-link-standalone--icon-position-leading::before{right:-7px}.hds-link-standalone.hds-link-standalone--icon-position-trailing::before{left:-7px}.hds-menu-primitive{position:relative;width:-moz-fit-content;width:fit-content}.hds-modal{z-index:50;flex-direction:column;padding:0;background:var(--token-color-surface-primary);border:none;border-radius:8px;box-shadow:var(--token-surface-overlay-box-shadow)}.hds-modal[open]{position:fixed;display:flex}.hds-modal::backdrop{display:none}.hds-modal__overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:var(--token-color-palette-neutral-700);opacity:.5}.hds-modal__header{display:flex;flex:none;gap:16px;align-items:flex-start;padding:16px 24px;border-top-left-radius:inherit;border-top-right-radius:inherit}.hds-modal__icon{flex:none;align-self:center}.freetext-filter>label,.freetext-filter_input,.hds-modal__title{flex-grow:1}.hds-modal__tagline{margin-bottom:4px}.hds-modal__dismiss{align-self:center}.hds-modal__body{flex:1 1 auto;padding:24px;overflow-y:auto;overscroll-behavior:contain}.hds-modal__footer{flex:none;padding:16px 24px;background:var(--token-color-surface-faint);border-top:1px solid var(--token-color-border-primary);border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.hds-modal--size-small{width:min(400px,95vw)}.hds-modal--size-medium{width:min(600px,95vw)}.hds-modal--size-large{width:min(800px,95vw)}.hds-modal--color-neutral .hds-modal__header{color:var(--token-color-foreground-strong);background:var(--token-color-surface-faint);border-bottom:1px solid var(--token-color-border-primary)}.hds-modal--color-neutral .hds-modal__tagline{color:var(--token-color-foreground-faint)}.hds-modal--color-warning .hds-modal__header,.hds-modal--color-warning .hds-modal__tagline{color:var(--token-color-foreground-warning-on-surface)}.hds-modal--color-warning .hds-modal__header{background:var(--token-color-surface-warning);border-bottom:1px solid var(--token-color-border-warning)}.hds-modal--color-critical .hds-modal__header,.hds-modal--color-critical .hds-modal__tagline{color:var(--token-color-foreground-critical-on-surface)}.hds-modal--color-critical .hds-modal__header{background:var(--token-color-surface-critical);border-bottom:1px solid var(--token-color-border-critical)}.hds-page-header{position:relative;display:flex;flex-direction:column;gap:16px;container-type:inline-size}.hds-page-header__body{display:flex;flex-direction:column;gap:8px 16px}.hds-page-header__body .hds-icon-tile{flex-shrink:0}@container (min-width:400px){.hds-page-header__body{flex-direction:row}}.hds-page-header__main{display:flex;flex-direction:column;flex-grow:1;gap:16px;align-items:start;justify-content:start}@container (min-width:768px){.hds-page-header__main{flex-direction:row;justify-content:space-between;min-width:0}}.hds-page-header__content{display:flex;flex-direction:column;flex-grow:1;gap:8px;min-width:0;max-width:100%}.hds-page-header__title-wrapper{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px 16px;align-items:center}.hds-page-header__title{max-width:100%;overflow-wrap:break-word}.hds-page-header__badges-wrapper{display:flex;flex-wrap:wrap;gap:8px}.hds-page-header__metadata{display:flex;flex-direction:column;gap:4px}.hds-page-header__description,.hds-page-header__subtitle{overflow-wrap:break-word}.hds-page-header__actions{display:flex;flex-direction:row;flex-shrink:0;flex-wrap:wrap;gap:16px;align-items:center}.hds-pagination{display:grid;grid-template-areas:"info nav selector";grid-template-rows:auto;grid-template-columns:1fr auto 1fr;align-items:center;margin:0 auto}@media screen and (max-width:1000px){.hds-pagination{display:flex;flex-wrap:wrap;justify-content:center}.hds-pagination .hds-pagination-info{margin-top:var(--token-pagination-child-spacing-vertical);margin-left:var(--token-pagination-child-spacing-horizontal)}}.hds-pagination .hds-pagination-info{grid-area:info;justify-self:flex-start;margin-right:var(--token-pagination-child-spacing-horizontal)}.hds-pagination .hds-pagination-nav{grid-area:nav}@media screen and (max-width:1000px){.hds-pagination .hds-pagination-nav{justify-content:center;order:-1;width:100%}.hds-pagination .hds-pagination-size-selector{margin-top:var(--token-pagination-child-spacing-vertical);margin-right:var(--token-pagination-child-spacing-horizontal)}}.hds-pagination .hds-pagination-size-selector{grid-area:selector;justify-self:flex-end;margin-left:var(--token-pagination-child-spacing-horizontal)}.hds-pagination-info{white-space:nowrap}.hds-pagination-nav{display:flex}.hds-pagination-nav__page-list{display:flex;margin:0;padding:0}.hds-pagination-nav__page-item{list-style-type:none}.hds-pagination-nav__control{display:flex;align-items:center;height:var(--token-pagination-nav-control-height);padding:0 calc(var(--token-pagination-nav-control-padding-horizontal) - 1px);color:var(--token-color-foreground-primary);background-color:transparent;border:1px solid transparent;position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-pagination-nav__control::before{position:absolute;top:var(--token-pagination-nav-control-focus-inset);right:var(--token-pagination-nav-control-focus-inset);bottom:var(--token-pagination-nav-control-focus-inset);left:var(--token-pagination-nav-control-focus-inset);z-index:-1;border-radius:5px;content:""}.hds-pagination-nav__control:focus:not(:focus-visible)::before{box-shadow:none}.hds-pagination-nav__control:focus-visible::before,.hds-side-nav__home-link.mock-focus.mock-focus::before,.hds-side-nav__home-link.mock-focus:focus::before,.hds-side-nav__home-link:focus.mock-focus::before,.hds-side-nav__home-link:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-pagination-nav__control.mock-focus.mock-active::before,.hds-pagination-nav__control:focus:active::before{box-shadow:none}.hds-pagination-nav__control.mock-hover,.hds-pagination-nav__control:hover{color:var(--token-color-foreground-action-hover)}.hds-pagination-nav__control.mock-active,.hds-pagination-nav__control:active{color:var(--token-color-foreground-action-active)}.hds-pagination-nav__arrow{gap:var(--token-pagination-nav-control-icon-spacing)}.hds-pagination-nav__arrow.mock-disabled,.hds-pagination-nav__arrow:disabled{color:var(--token-color-foreground-disabled);cursor:not-allowed}.hds-pagination-nav__arrow--direction-prev{flex-direction:row;justify-content:flex-start}.hds-pagination-nav__arrow--direction-next{flex-direction:row-reverse;justify-content:flex-end}.hds-pagination-nav__number--is-selected{position:relative;color:var(--token-color-foreground-action)}.hds-pagination-nav__number--is-selected:hover{color:var(--token-color-foreground-action-hover)}.hds-pagination-nav__number--is-selected:active{color:var(--token-color-foreground-action-active)}.hds-pagination-nav__number--is-selected::after{position:absolute;right:calc(var(--token-pagination-nav-indicator-spacing) - 1px);bottom:-1px;left:calc(var(--token-pagination-nav-indicator-spacing) - 1px);height:var(--token-pagination-nav-indicator-height);margin:0 auto;background-color:currentColor;border-radius:2px;content:""}.hds-pagination-nav__ellipsis{display:flex;align-items:center;height:var(--token-pagination-nav-control-height);padding:0 var(--token-pagination-nav-control-padding-horizontal);color:var(--token-color-foreground-faint)}.hds-pagination-size-selector{display:flex;align-items:center}.hds-pagination-size-selector>label{white-space:nowrap}.hds-pagination-size-selector>select{height:28px;margin-left:12px;padding:0 24px 0 8px;font-size:var(--token-typography-body-100-font-size);font-family:var(--token-typography-body-100-font-family);line-height:var(--token-typography-body-100-line-height);background-position:center right 5px}.hds-reveal{width:-moz-fit-content;width:fit-content}.hds-reveal__toggle-button{min-height:1.75rem;padding:.313rem .313rem .313rem .188rem}@media (prefers-reduced-motion:no-preference){.hds-reveal__toggle-button .flight-icon-chevron-down{transition:transform .3s}}.hds-reveal__toggle-button--is-open .flight-icon-chevron-down{transform:rotate(-180deg)}.hds-reveal__content{margin-top:4px}.hds-segmented-group{display:inline-flex}.hds-side-nav--is-desktop .hds-side-nav__overlay,.hds-side-nav__toggle-button.mock-focus::after,.hds-side-nav__toggle-button.mock-focus::before,.hds-side-nav__toggle-button:focus-visible::after,.hds-side-nav__toggle-button:focus-visible::before{display:none}.hds-segmented-group>.hds-button:first-child,.hds-segmented-group>.hds-dropdown:first-child,.hds-segmented-group>.hds-form-select:first-child,.hds-segmented-group>.hds-form-text-input:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.hds-segmented-group>.hds-button:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-button:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-button:first-child::before,.hds-segmented-group>.hds-dropdown:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-dropdown:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-dropdown:first-child::before,.hds-segmented-group>.hds-form-select:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-select:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-select:first-child::before,.hds-segmented-group>.hds-form-text-input:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-text-input:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-text-input:first-child::before{border-top-right-radius:inherit;border-bottom-right-radius:inherit}.hds-segmented-group>.hds-button:last-child,.hds-segmented-group>.hds-dropdown:last-child,.hds-segmented-group>.hds-form-select:last-child,.hds-segmented-group>.hds-form-text-input:last-child{margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.hds-segmented-group>.hds-button:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-button:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-button:last-child::before,.hds-segmented-group>.hds-dropdown:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-dropdown:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-dropdown:last-child::before,.hds-segmented-group>.hds-form-select:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-select:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-select:last-child::before,.hds-segmented-group>.hds-form-text-input:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-text-input:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-text-input:last-child::before{border-top-left-radius:inherit;border-bottom-left-radius:inherit}.hds-segmented-group>.hds-button:not(:first-child,:last-child),.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child),.hds-segmented-group>.hds-form-select:not(:first-child,:last-child),.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child){margin-left:-1px;border-radius:0}.hds-segmented-group>.hds-button:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-button:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-button:not(:first-child,:last-child)::before,.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child)::before,.hds-segmented-group>.hds-form-select:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-select:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-select:not(:first-child,:last-child)::before,.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child)::before{border-radius:inherit}.hds-segmented-group>.hds-button .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-button.mock-focus,.hds-segmented-group>.hds-button:focus,.hds-segmented-group>.hds-dropdown .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-dropdown.mock-focus,.hds-segmented-group>.hds-dropdown:focus,.hds-segmented-group>.hds-form-select .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-form-select.mock-focus,.hds-segmented-group>.hds-form-select:focus,.hds-segmented-group>.hds-form-text-input .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-form-text-input.mock-focus,.hds-segmented-group>.hds-form-text-input:focus{z-index:1}.hds-separator{border:none;border-top:1px solid var(--token-color-border-primary)}.hds-separator--spacing-24{margin:24px 0}.hds-separator--spacing-0{margin:0}.hds-side-nav{top:0;z-index:20;width:var(--hds-app-sidenav-width-fixed);height:100vh;min-height:100vh;isolation:isolate}.hds-side-nav.hds-side-nav--is-responsive{transition:width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav.hds-side-nav--is-mobile{width:var(--hds-app-sidenav-width-minimized)}.hds-side-nav.hds-side-nav--is-desktop.hds-side-nav--is-not-minimized{width:var(--hds-app-sidenav-width-expanded)}.hds-side-nav--is-minimized .hds-side-nav__wrapper,.hds-side-nav.hds-side-nav--is-desktop.hds-side-nav--is-minimized{width:var(--hds-app-sidenav-width-minimized)}.hds-side-nav__overlay{position:fixed;z-index:-1;inset:0;background-color:var(--token-color-palette-neutral-700);opacity:.2;transition:opacity var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing) var(--hds-app-sidenav-animation-delay)}.hds-side-nav--is-minimized .hds-side-nav__overlay{opacity:0;pointer-events:none}.hds-side-nav__wrapper{display:flex;flex-direction:column;height:100%;color:var(--token-side-nav-color-foreground-primary);background:var(--token-side-nav-color-surface-primary);border-right:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color)}.hds-side-nav--is-responsive .hds-side-nav__wrapper{transition:width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav--is-not-minimized .hds-side-nav__wrapper{width:var(--hds-app-sidenav-width-expanded)}.hds-side-nav__wrapper-header{padding-top:var(--token-side-nav-wrapper-padding-vertical);padding-right:var(--token-side-nav-wrapper-padding-horizontal);padding-bottom:8px;padding-left:var(--token-side-nav-wrapper-padding-horizontal);transition:padding var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav--is-minimized .hds-side-nav__wrapper-header{padding-top:var(--token-side-nav-wrapper-padding-vertical-minimized);padding-right:var(--token-side-nav-wrapper-padding-horizontal-minimized);padding-left:var(--token-side-nav-wrapper-padding-horizontal-minimized)}.hds-side-nav__wrapper-body,.hds-side-nav__wrapper-footer{padding:var(--token-side-nav-wrapper-padding-vertical) var(--token-side-nav-wrapper-padding-horizontal)}.hds-side-nav__wrapper-body{flex:1;overflow-x:hidden;overflow-y:auto}.hds-side-nav--is-minimized .hds-side-nav-hide-when-minimized{visibility:hidden!important;opacity:0;pointer-events:none}.hds-side-nav--is-not-minimized .hds-side-nav-hide-when-minimized{visibility:visible;opacity:1;transition:opacity var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing) var(--hds-app-sidenav-animation-delay)}.hds-side-nav--is-animating .hds-side-nav-hide-when-minimized{pointer-events:none}.hds-side-nav-header{display:flex;align-items:center;justify-content:space-between}.hds-side-nav-header__logo-container{display:flex;flex:none;align-items:center;justify-content:center;width:var(--token-side-nav-header-home-link-logo-size);height:var(--token-side-nav-header-home-link-logo-size);transition:width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing),height var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav--is-minimized .hds-side-nav-header__logo-container{width:var(--token-side-nav-header-home-link-logo-size-minimized);height:var(--token-side-nav-header-home-link-logo-size-minimized)}.hds-side-nav__home-link{color:var(--token-side-nav-color-foreground-strong);background-color:transparent;border:1px solid transparent;border-radius:var(--token-side-nav-body-list-item-border-radius);cursor:pointer;display:block;width:100%;height:100%;padding:calc(var(--token-side-nav-header-home-link-padding) - 1px)}.hds-side-nav__home-link.mock-focus,.hds-side-nav__home-link:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__home-link.mock-focus::before,.hds-side-nav__home-link:focus::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-side-nav__home-link.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__home-link:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__home-link.mock-focus:focus-visible::before,.hds-side-nav__home-link:focus:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__home-link.mock-focus.mock-focus.mock-active::before,.hds-side-nav__home-link.mock-focus:focus:active::before,.hds-side-nav__home-link:focus.mock-focus.mock-active::before,.hds-side-nav__home-link:focus:focus:active::before{box-shadow:none}.hds-side-nav__home-link.mock-hover,.hds-side-nav__home-link:hover{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__home-link.mock-active,.hds-side-nav__home-link:active{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav-header__actions-container{display:flex;gap:var(--token-side-nav-header-actions-spacing)}.hds-side-nav__dropdown .hds-dropdown-toggle-button,.hds-side-nav__dropdown .hds-dropdown-toggle-icon{color:var(--token-side-nav-color-foreground-strong);background-color:transparent;border:1px solid transparent;border-radius:var(--token-side-nav-body-list-item-border-radius);cursor:pointer;border-color:var(--token-color-palette-neutral-500)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus:not(:focus-visible)::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus-visible::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus-visible::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus-visible::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus:active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus:active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus:active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus:active::before{box-shadow:none}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-hover,.hds-side-nav__dropdown .hds-dropdown-toggle-button:hover,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-hover,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:hover{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-active,.hds-side-nav__dropdown .hds-dropdown-toggle-button:active,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-active,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:active{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-active);border-color:var(--token-color-palette-neutral-400)}.hds-side-nav__icon-button{color:var(--token-side-nav-color-foreground-strong);background-color:transparent;border:1px solid transparent;border-radius:var(--token-side-nav-body-list-item-border-radius);cursor:pointer;border-color:var(--token-color-palette-neutral-500);display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:5px}.hds-side-nav__icon-button.mock-focus,.hds-side-nav__icon-button:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__icon-button.mock-focus::before,.hds-side-nav__icon-button:focus::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-side-nav__icon-button.mock-focus.mock-focus::before,.hds-side-nav__icon-button.mock-focus:focus::before,.hds-side-nav__icon-button:focus.mock-focus::before,.hds-side-nav__icon-button:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__icon-button.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__icon-button:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__icon-button.mock-focus:focus-visible::before,.hds-side-nav__icon-button:focus:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__icon-button.mock-focus.mock-focus.mock-active::before,.hds-side-nav__icon-button.mock-focus:focus:active::before,.hds-side-nav__icon-button:focus.mock-focus.mock-active::before,.hds-side-nav__icon-button:focus:focus:active::before{box-shadow:none}.hds-side-nav__icon-button.mock-hover,.hds-side-nav__icon-button:hover{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__icon-button.mock-active,.hds-side-nav__icon-button:active{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-active);border-color:var(--token-color-palette-neutral-400)}.hds-side-nav__content{margin:0 calc(var(--token-side-nav-wrapper-padding-horizontal) * -1)}.hds-side-nav__content-panels{display:grid;grid-template-columns:repeat(5,var(--hds-app-sidenav-width-expanded));width:100%}.hds-side-nav__content-panel{padding:0 var(--token-side-nav-wrapper-padding-horizontal)}.hds-side-nav__list-title{display:flex;align-items:center;min-height:var(--token-side-nav-body-list-item-height);margin-top:var(--token-side-nav-body-list-margin-vertical);padding:9px var(--token-side-nav-body-list-item-padding-horizontal);color:var(--token-side-nav-color-foreground-faint)}.hds-side-nav__list-wrapper:first-child .hds-side-nav__list-item:first-child>.hds-side-nav__list-title{margin-top:0}.hds-side-nav__list,.hds-side-nav__list-wrapper{margin:0;padding:0}.hds-side-nav__list-item{list-style-type:none}.hds-side-nav__list-item+.hds-side-nav__list-item{margin-top:var(--token-side-nav-body-list-item-spacing-vertical)}.hds-side-nav__list-item-link{display:flex;gap:var(--token-side-nav-body-list-item-content-spacing-horizontal);align-items:center;width:100%;min-height:var(--token-side-nav-body-list-item-height);padding:var(--token-side-nav-body-list-item-padding-vertical) var(--token-side-nav-body-list-item-padding-horizontal);color:var(--token-side-nav-color-foreground-primary);background:var(--token-side-nav-color-surface-primary);border-color:transparent;border-radius:var(--token-side-nav-body-list-item-border-radius)}.hds-side-nav__list-item-link.active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link.active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link.active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link.mock-active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link.mock-active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link.mock-active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link.mock-hover .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link.mock-hover .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link.mock-hover .hds-side-nav__list-item-text,.hds-side-nav__list-item-link:active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link:active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link:active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link:hover .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link:hover .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link:hover .hds-side-nav__list-item-text,.hds-side-nav__list-item-link:hover:focus .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link:hover:focus .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link:hover:focus .hds-side-nav__list-item-text{color:var(--token-side-nav-color-foreground-strong)}.hds-side-nav__list-item-link.mock-focus,.hds-side-nav__list-item-link:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__list-item-link.mock-focus::before,.hds-side-nav__list-item-link:focus::before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:5px;content:""}.hds-side-nav__list-item-link.mock-focus.mock-focus::before,.hds-side-nav__list-item-link.mock-focus:focus::before,.hds-side-nav__list-item-link:focus.mock-focus::before,.hds-side-nav__list-item-link:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__list-item-link.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__list-item-link:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__list-item-link.mock-focus:focus-visible::before,.hds-side-nav__list-item-link:focus:focus-visible::before,.hds-table__th-sort button.mock-focus::before,.hds-table__th-sort button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__list-item-link.mock-focus.mock-focus.mock-active::before,.hds-side-nav__list-item-link.mock-focus:focus:active::before,.hds-side-nav__list-item-link:focus.mock-focus.mock-active::before,.hds-side-nav__list-item-link:focus:focus:active::before{box-shadow:none}.hds-side-nav__list-item-link.mock-hover,.hds-side-nav__list-item-link:hover{background:var(--token-side-nav-color-surface-interactive-hover);border-color:transparent}.hds-side-nav__list-item-link.active,.hds-side-nav__list-item-link.mock-active,.hds-side-nav__list-item-link:active,.hds-side-nav__list-item-link:hover:focus{background:var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__list-item-link.active .hds-badge,.hds-side-nav__list-item-link.active .hds-badge-count,.hds-side-nav__list-item-link.mock-active .hds-badge,.hds-side-nav__list-item-link.mock-active .hds-badge-count,.hds-side-nav__list-item-link:active .hds-badge,.hds-side-nav__list-item-link:active .hds-badge-count,.hds-side-nav__list-item-link:hover:focus .hds-badge,.hds-side-nav__list-item-link:hover:focus .hds-badge-count{color:var(--token-color-foreground-primary);background:var(--token-color-surface-strong)}.hds-side-nav__list-item-link--back-link.mock-active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link--back-link.mock-active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link--back-link.mock-active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link--back-link:active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link--back-link:active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link--back-link:active .hds-side-nav__list-item-text,.hds-side-nav__list-item-text{color:var(--token-side-nav-color-foreground-primary)}.hds-side-nav__list-item-link--back-link.mock-active,.hds-side-nav__list-item-link--back-link:active{background:var(--token-side-nav-color-surface-primary)}.hds-side-nav__list-item-text{text-align:left}.hds-side-nav__list-item-icon-leading{flex:none}.hds-side-nav__list-item-icon-trailing{flex:none;margin-left:auto}.hds-side-nav__toggle-button{position:absolute;top:22px;left:calc(var(--token-side-nav-wrapper-border-width) * -1);z-index:1;display:flex;flex-direction:row-reverse;align-items:center;width:26px;height:36px;padding:0 4px;color:var(--token-color-foreground-high-contrast);background:0 0;background-color:var(--token-side-nav-color-surface-primary);border:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);border-left-color:transparent;border-top-right-radius:var(--token-side-nav-toggle-button-border-radius);border-bottom-right-radius:var(--token-side-nav-toggle-button-border-radius);transform:translateX(var(--hds-app-sidenav-width-expanded));cursor:pointer;transition:transform var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing),width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav__toggle-button::after,.hds-side-nav__toggle-button::before{position:absolute;left:calc(var(--token-side-nav-wrapper-border-width) * -1);width:calc(var(--token-side-nav-toggle-button-border-radius) * 2);height:calc(var(--token-side-nav-toggle-button-border-radius) * 2);border-left:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);box-sizing:border-box;content:""}.hds-side-nav__toggle-button::before{top:calc(var(--token-side-nav-toggle-button-border-radius) * -2);border-bottom:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);border-bottom-left-radius:var(--token-side-nav-toggle-button-border-radius);box-shadow:0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-primary)}.hds-side-nav__toggle-button::after{bottom:calc(var(--token-side-nav-toggle-button-border-radius) * -2);border-top:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);border-top-left-radius:var(--token-side-nav-toggle-button-border-radius);box-shadow:0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-primary)}.hds-side-nav__toggle-button.mock-hover,.hds-side-nav__toggle-button:hover{width:30px;background-color:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__toggle-button.mock-hover::before,.hds-side-nav__toggle-button:hover::before{box-shadow:0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__toggle-button.mock-hover::after,.hds-side-nav__toggle-button:hover::after{box-shadow:0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__toggle-button.mock-active,.hds-side-nav__toggle-button:active{background-color:var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__toggle-button.mock-active::before,.hds-side-nav__toggle-button:active::before{box-shadow:0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__toggle-button.mock-active::after,.hds-side-nav__toggle-button:active::after{box-shadow:0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__toggle-button.mock-focus,.hds-side-nav__toggle-button:focus-visible{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px}.hds-table__th-sort button,.hds-tabs__tab-button,.hds-tooltip-button{outline-color:transparent;outline-style:solid}.hds-side-nav--is-minimized .hds-side-nav__toggle-button{transform:translateX(var(--hds-app-sidenav-width-minimized))}.hds-side-nav .ember-a11y-refocus-skip-link{top:10px;left:10px;z-index:20;width:-moz-max-content;width:max-content;padding:2px 10px 4px;color:var(--token-color-foreground-action);font-family:var(--token-typography-display-200-font-family);background-color:var(--token-color-surface-faint);border-radius:3px;transform:translateY(-200%);transition:.6s ease-in-out}.hds-side-nav .ember-a11y-refocus-skip-link:focus{transform:translateY(0)}.hds-stepper-indicator-step{position:relative;width:24px;height:24px}.hds-stepper-indicator-step__svg-hexagon{width:100%;height:100%;filter:drop-shadow(0 1px 1px rgba(101, 106, 118, .05))}.hds-stepper-indicator-step__status{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center}.hds-stepper-indicator-step__icon{width:12px;height:12px}.hds-stepper-indicator-step__text{width:20px;overflow:hidden;white-space:nowrap;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__status{color:var(--token-color-foreground-strong)}.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__status{color:var(--token-color-foreground-high-contrast)}.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-faint);stroke:var(--token-color-foreground-strong)}.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-foreground-strong);stroke:var(--token-color-foreground-strong)}.hds-stepper-indicator-step--is-interactive{cursor:pointer}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__status{color:var(--token-color-foreground-primary)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__status{color:var(--token-color-foreground-high-contrast)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-interactive);stroke:var(--token-color-border-strong)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-interactive-hover)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete:active .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-interactive-active)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-200);stroke:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-300);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress:active .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-400);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-200);stroke:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-300);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing:active .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-400);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__status{color:var(--token-color-palette-blue-200)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-50);stroke:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-100);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-hover .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:hover .hds-stepper-indicator-step__status{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-active .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:active .hds-stepper-indicator-step__status{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task{position:relative;display:flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--token-color-foreground-strong)}.hds-stepper-indicator-task__icon{width:12px;height:12px}.hds-stepper-indicator-task--is-interactive{cursor:pointer}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete{color:var(--token-color-palette-neutral-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete:hover{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete:active{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress{color:var(--token-color-palette-blue-200)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress:hover{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress:active{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing{color:var(--token-color-palette-blue-200)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing:hover{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing:active{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete{color:var(--token-color-palette-green-200)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete:hover{color:var(--token-color-palette-green-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete:active{color:var(--token-color-palette-green-400)}.hds-table{width:100%;border:1px solid var(--token-color-border-primary);border-radius:6px}.hds-table--layout-fixed{table-layout:fixed}.hds-table__thead .hds-table__tr{color:var(--token-color-foreground-strong);background-color:var(--token-color-surface-strong)}.hds-table__thead .hds-table__tr:first-of-type th:first-child{border-top-left-radius:5px}.hds-table__thead .hds-table__tr:first-of-type th:last-child{border-top-right-radius:5px}.hds-table__thead .hds-table__th,.hds-table__thead .hds-table__th-sort{min-height:48px}.hds-table__th,.hds-table__th-sort{text-align:left;border-top:none;border-right:none;border-bottom:1px solid var(--token-color-border-primary);border-left:none}.hds-table__th{padding:14px 16px 13px}.hds-table__th-sort{padding:0}.hds-table__th-sort button{width:100%;height:100%;min-height:48px;margin:0;padding:14px 16px 13px;text-align:inherit;background-color:transparent;border:1px solid transparent;border-radius:inherit;position:relative;isolation:isolate}.hds-table__th-sort button .hds-table__th-sort--button-content{display:flex;align-items:center}.hds-table__th-sort button .hds-table__th-sort--button-content .flight-icon{flex:none;margin-left:8px;color:var(--token-color-foreground-action)}.hds-table__th-sort button.mock-hover,.hds-table__th-sort button:hover{color:var(--token-color-foreground-strong);background-color:var(--token-color-palette-neutral-200);cursor:pointer}.hds-table__th-sort button::before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:inherit;content:""}.hds-table__th-sort button:focus:not(:focus-visible)::before{box-shadow:none}.hds-table__th-sort button:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-table__th-sort button.mock-focus.mock-active::before,.hds-table__th-sort button:focus:active::before{box-shadow:none}.hds-table__th-sort button.mock-active,.hds-table__th-sort button:active{color:var(--token-color-foreground-strong);background-color:var(--token-color-palette-neutral-300)}.hds-table__tbody .hds-table__tr,.hds-tabs__tab,.hds-tag__dismiss-icon{color:var(--token-color-foreground-primary)}.hds-table--striped .hds-table__tbody .hds-table__tr:nth-child(even){background-color:var(--token-color-surface-faint)}.hds-table--density-short .hds-table__tbody td,.hds-table--density-short .hds-table__tbody th{padding:6px 16px 5px}.hds-table--density-medium .hds-table__tbody td,.hds-table--density-medium .hds-table__tbody th{padding:14px 16px 13px}.hds-table--density-tall .hds-table__tbody td,.hds-table--density-tall .hds-table__tbody th{padding:22px 16px 21px}.hds-table--valign-top .hds-table__tbody td,.hds-table--valign-top .hds-table__tbody th{vertical-align:top}.hds-table--valign-middle .hds-table__tbody td,.hds-table--valign-middle .hds-table__tbody th,.hds-tag{vertical-align:middle}.hds-table__td--text-right,.hds-table__th--text-right,.hds-table__th-sort--text-right{text-align:right}.hds-table__th-sort--text-right .hds-table__th-sort--button-content{justify-content:flex-end}.hds-table__td--text-center,.hds-table__th--text-center,.hds-table__th-sort--text-center{text-align:center}.hds-table__tbody .hds-table__tr{background-color:var(--token-color-surface-primary)}.hds-table__tbody .hds-table__tr td,.hds-table__tbody .hds-table__tr th{border-top:none;border-right:none;border-bottom:1px solid var(--token-color-border-primary);border-left:none}.hds-table__tbody .hds-table__tr:last-of-type td,.hds-table__tbody .hds-table__tr:last-of-type th{border-bottom:none}.hds-table__tbody .hds-table__tr:last-of-type td:first-child,.hds-table__tbody .hds-table__tr:last-of-type th:first-child{border-bottom-left-radius:5px}.hds-table__tbody .hds-table__tr:last-of-type td:last-child{border-bottom-right-radius:5px}.hds-tabs__tablist-wrapper{position:relative}.hds-tabs__tablist-wrapper::before{position:absolute;right:0;bottom:calc((var(--token-tabs-indicator-height) - var(--token-tabs-divider-height))/ 2);left:0;display:block;border-top:var(--token-tabs-divider-height) solid var(--token-color-border-primary);content:""}.hds-tabs__tablist{position:relative;display:flex;margin:0;padding:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.hds-tabs__tab{position:relative;display:flex;align-items:center;height:var(--token-tabs-tab-height);margin:0;padding:var(--token-tabs-tab-padding-vertical) var(--token-tabs-tab-padding-horizontal);white-space:nowrap;list-style:none}.hds-tabs__tab.hds-tabs__tab--is-selected,.hds-tabs__tab.mock-hover,.hds-tabs__tab:hover{color:var(--token-color-foreground-action)}.hds-tabs__tab.hds-tabs__tab--is-selected:hover{color:var(--token-color-foreground-action-hover)}.hds-tabs__tab.hds-tabs__tab--is-selected:hover~.hds-tabs__tab-indicator{background:var(--token-color-foreground-action-hover)}.hds-tabs__tab-button{isolation:isolate;position:static;display:flex;gap:var(--token-tabs-tab-gutter);align-items:center;padding:0;color:inherit;background-color:transparent;border:none;border-radius:var(--token-tabs-tab-border-radius);cursor:pointer}.hds-tabs__tab-button::before{position:absolute;top:var(--token-tabs-tab-focus-inset);right:var(--token-tabs-tab-focus-inset);bottom:var(--token-tabs-tab-focus-inset);left:var(--token-tabs-tab-focus-inset);z-index:-1;border-radius:5px;content:""}.hds-tabs__tab-button.mock-focus::before,.hds-tabs__tab-button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tabs__tab-button:focus:not(:focus-visible)::before{box-shadow:none}.hds-tabs__tab-button:focus-visible::before,.hds-tag__dismiss.mock-focus.mock-focus,.hds-tag__dismiss.mock-focus:focus,.hds-tag__dismiss:focus.mock-focus,.hds-tag__dismiss:focus:focus,.hds-tag__link.mock-focus.mock-focus,.hds-tag__link.mock-focus:focus,.hds-tag__link:focus.mock-focus,.hds-tag__link:focus:focus{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tabs__tab-button.mock-focus.mock-active::before,.hds-tabs__tab-button:focus:active::before{box-shadow:none}.hds-tabs__tab-button::after{position:absolute;content:"";inset:0}.hds-tabs__tab-indicator{position:absolute;right:0;bottom:0;left:var(--indicator-left-pos);z-index:10;display:block;width:var(--indicator-width);height:var(--token-tabs-indicator-height);background-color:var(--token-color-foreground-action);border-radius:var(--token-tabs-indicator-height)}.hds-tabs__panel[hidden],.readonly-codemirror .CodeMirror-cursors{display:none}.hds-tag,.hds-tag__dismiss,.hds-tag__link{background-color:var(--token-color-surface-interactive)}@media screen and (prefers-reduced-motion:no-preference){.hds-tabs__tab-indicator{transition-timing-function:var(--token-tabs-indicator-transition-function);transition-duration:var(--token-tabs-indicator-transition-duration);transition-property:left,width}}.tippy-box,.tippy-box[data-theme~=hds]{transition-property:transform,visibility,opacity}.hds-tag,:where(.hds-tooltip-button--is-inline){display:inline-flex}.hds-tag{align-items:stretch;line-height:1rem;border:1px solid var(--token-color-border-strong);border-radius:50px}.hds-tag__dismiss{flex:0 0 auto;margin:0;padding:6px 4px 6px 8px;border:none;border-radius:inherit;border-top-right-radius:0;border-bottom-right-radius:0}.hds-tag__dismiss-icon{width:12px;height:12px}.hds-tag__link,.hds-tag__text{flex:1 0 0;padding:3px 10px 5px;border-radius:inherit}.hds-tag__dismiss~.hds-tag__link,.hds-tag__dismiss~.hds-tag__text{padding:3px 8px 5px 6px;border-top-left-radius:0;border-bottom-left-radius:0}.hds-tag__dismiss,.hds-tag__link{cursor:pointer}.hds-tag__dismiss.mock-hover,.hds-tag__dismiss:hover,.hds-tag__link.mock-hover,.hds-tag__link:hover{background-color:var(--token-color-surface-interactive-hover)}.hds-tag__dismiss.mock-active,.hds-tag__dismiss:active,.hds-tag__link.mock-active,.hds-tag__link:active{background-color:var(--token-color-surface-interactive-active)}.hds-tag__dismiss.mock-focus,.hds-tag__dismiss:focus,.hds-tag__link.mock-focus,.hds-tag__link:focus{outline-style:solid;outline-color:transparent;z-index:1}.hds-tag__dismiss.mock-focus:focus:not(:focus-visible),.hds-tag__dismiss:focus:focus:not(:focus-visible),.hds-tag__link.mock-focus:focus:not(:focus-visible),.hds-tag__link:focus:focus:not(:focus-visible){box-shadow:none}.hds-tag__dismiss.mock-focus:focus-visible,.hds-tag__dismiss:focus:focus-visible,.hds-tag__link.mock-focus:focus-visible,.hds-tag__link:focus:focus-visible{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tag__dismiss.mock-focus.mock-focus.mock-active,.hds-tag__dismiss.mock-focus:focus:active,.hds-tag__dismiss:focus.mock-focus.mock-active,.hds-tag__dismiss:focus:focus:active,.hds-tag__link.mock-focus.mock-focus.mock-active,.hds-tag__link.mock-focus:focus:active,.hds-tag__link:focus.mock-focus.mock-active,.hds-tag__link:focus:focus:active{box-shadow:none}.hds-tag--color-primary .hds-tag__link{color:var(--token-color-foreground-action)}.hds-tag--color-primary .hds-tag__link.mock-hover,.hds-tag--color-primary .hds-tag__link:hover{color:var(--token-color-foreground-action-hover)}.hds-tag--color-primary .hds-tag__link.mock-active,.hds-tag--color-primary .hds-tag__link:active{color:var(--token-color-foreground-action-active)}.hds-tag--color-secondary .hds-tag__link{color:var(--token-color-foreground-strong)}.hds-text--align-left{text-align:left}.hds-text--align-center{text-align:center}.hds-text--align-right{text-align:right}.hds-toast{width:-moz-fit-content;width:fit-content;min-width:min(360px,80vw);max-width:min(500px,80vw);box-shadow:var(--token-elevation-higher-box-shadow)}.hds-tooltip-button{position:relative;isolation:isolate}.hds-tooltip-button::before{position:absolute;top:var(--token-tooltip-focus-offset);right:var(--token-tooltip-focus-offset);bottom:var(--token-tooltip-focus-offset);left:var(--token-tooltip-focus-offset);z-index:-1;border-radius:5px;content:""}.hds-tooltip-button.mock-focus::before,.hds-tooltip-button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tooltip-button:focus:not(:focus-visible)::before{box-shadow:none}.hds-tooltip-button:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tooltip-button.mock-focus.mock-active::before,.hds-tooltip-button:focus:active::before{box-shadow:none}:where(.hds-tooltip-button){margin:0;padding:0;color:inherit;font:inherit;text-align:inherit;background-color:inherit;border:none}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.menu-panel>ul>[role=treeitem],.menu-panel>ul>li,.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.modal-dialog [role=document] table caption,.modal-dialog [role=document] table thead th,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],main table caption,main table thead th,table td,table th,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],td,th{text-align:left}:where(.hds-tooltip-button--is-block){display:flex}article,aside,figure,footer,header,hgroup,hr,section{display:block}.tippy-box[data-theme~=hds]{padding:var(--token-tooltip-padding-vertical) var(--token-tooltip-padding-horizontal);color:var(--token-tooltip-color-foreground-primary);font-weight:var(--token-typography-font-weight-regular);font-size:var(--token-typography-body-200-font-size);font-family:var(--token-typography-body-200-font-family);line-height:var(--token-typography-body-200-line-height);overflow-wrap:break-word;background-color:var(--token-tooltip-color-surface-primary);border-radius:var(--token-tooltip-border-radius);box-shadow:var(--token-elevation-higher-box-shadow)}.tippy-box[data-theme~=hds][data-animation=fade][data-state=hidden]{opacity:0}.tippy-box[data-theme~=hds][data-inertia][data-state=visible]{transition-timing-function:var(--token-tooltip-transition-function)}.tippy-box[data-theme~=hds] .tippy-content{position:relative;z-index:1;max-width:var(--token-tooltip-max-width);white-space:normal}.tippy-box[data-theme~=hds] .tippy-svg-arrow{fill:var(--token-tooltip-color-surface-primary)}.sr-only{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;overflow:hidden!important;white-space:nowrap!important;border:0!important;clip:rect(1px,1px,1px,1px)!important;-webkit-clip-path:inset(50%)!important;clip-path:inset(50%)!important}fieldset,hr{border:none}blockquote,body,dd,dl,dt,fieldset,figure,hr,html,iframe,legend,li,ol,p,textarea,ul{margin:0;padding:0}ul{list-style:none}table td,table th{padding:0}audio,embed,img,object,video{height:auto;max-width:100%}.consul-intention-action-warn-modal button.dangerous,.copy-button button,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-select label>*,.topology-notices button,.type-sort.popover-select label>*,label span,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}a{color:var(--token-color-foreground-action)}span,strong,td,th{color:inherit}body{color:var(--token-color-foreground-strong)}html{background-color:var(--token-color-surface-primary);font-size:16px;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;overflow-x:hidden;overflow-y:scroll;box-sizing:border-box;min-width:300px}hr{background-color:var(--token-color-surface-interactive-active);height:1px;margin:1.5rem 0}body,input,select,textarea{font-family:var(--token-typography-font-stack-text)}strong{font-style:inherit}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}pre{-webkit-overflow-scrolling:touch;overflow-x:auto;white-space:pre;word-wrap:normal}*,::after,::before{box-sizing:inherit;animation-play-state:paused;animation-fill-mode:forwards}fieldset{width:100%}a,input[type=checkbox],input[type=radio]{cursor:pointer}td,th{vertical-align:top}button,input,select,textarea{margin:0}iframe{border:0}.consul-bucket-list .service,.consul-bucket-list:not([class]) dt:not([class]),.consul-exposed-path-list>ul>li>.detail dl:not([class]) dt:not([class]),.consul-instance-checks:not([class]) dt:not([class]),.consul-lock-session-list dl:not([class]) dt:not([class]),.consul-server-card dt:not(.name),.consul-upstream-instance-list dl.local-bind-address dt,.consul-upstream-instance-list dl.local-bind-socket-path dt,.consul-upstream-instance-list dl:not([class]) dt:not([class]),.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dt:not([class]),.route-title,.tag-list:not([class]) dt:not([class]),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dt:not([class]),section[data-route="dc.show.license"] .validity dl .expired+dd,section[data-route="dc.show.license"] .validity dl:not([class]) dt:not([class]),td.tags:not([class]) dt:not([class]){position:absolute;overflow:hidden;clip:rect(0 0 0 0);width:1px;height:1px;margin:-1px;padding:0;border:0}.consul-upstream-instance-list dl.local-bind-socket-mode dt,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dt{position:static!important;clip:unset!important;overflow:visible!important;width:auto!important;height:auto!important;margin:0!important;padding:0!important}.animatable.tab-nav ul::after,.consul-auth-method-type,.consul-external-source,.consul-intention-action-warn-modal button.dangerous,.consul-intention-action-warn-modal button.dangerous:hover:active,.consul-intention-action-warn-modal button.dangerous:hover:not(:disabled):not(:active),.consul-intention-list td.intent- strong,.consul-intention-permission-form button.type-submit,.consul-intention-permission-form button.type-submit:disabled,.consul-intention-permission-form button.type-submit:focus:not(:disabled),.consul-intention-permission-form button.type-submit:hover:not(:disabled),.consul-intention-search-bar .value- span,.consul-kind,.consul-source,.consul-transparent-proxy,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:first-child,.discovery-chain .route-card>header ul li,.informed-action>ul>.dangerous>*,.informed-action>ul>.dangerous>:focus,.informed-action>ul>.dangerous>:hover,.leader,.menu-panel>ul>li.dangerous>:first-child,.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.tab-nav .selected>*,.topology-metrics-source-type,html[data-route^="dc.acls.index"] main td strong,span.policy-node-identity,span.policy-service-identity,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child{border-style:solid}.ember-power-select-trigger,.ember-power-select-trigger--active,.ember-power-select-trigger:focus{border-top:1px solid #aaa;border-bottom:1px solid #aaa;border-right:1px solid #aaa;border-left:1px solid #aaa}.animatable.tab-nav ul::after,.app .notifications .app-notification,.tab-nav li>*{transition-duration:.15s;transition-timing-function:ease-out}html body>.brand-loader{transition-timing-function:cubic-bezier(.1,.1,.25,.9);transition-duration:.1s}html[data-state]:not(.ember-loading) body>.brand-loader{animation-timing-function:cubic-bezier(.1,.1,.25,.9);animation-duration:.1s;animation-name:remove-from-flow;animation-fill-mode:forwards}@keyframes remove-from-flow{100%{visibility:hidden;overflow:hidden;clip:rect(0 0 0 0)}}@keyframes typo-truncate{100%{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.CodeMirror-lint-tooltip,dd code,dd pre code{font-family:var(--token-typography-font-stack-code);font-size:var(--token-typography-code-100-font-size);line-height:var(--token-typography-code-100-line-height);font-weight:var(--token-typography-font-weight-regular)}.consul-health-check-list .health-check-output pre code,code,pre,pre code{font-family:var(--token-typography-font-stack-code);font-size:var(--token-typography-code-200-font-size);line-height:var(--token-typography-code-200-line-height);font-weight:var(--token-typography-font-weight-regular)}.informed-action header>*{font-size:inherit;font-weight:inherit;line-height:inherit;font-style:inherit}::after,::before{--tw-content:'';display:inline-block;vertical-align:text-top;background-repeat:no-repeat;background-position:center;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-position:center;-webkit-mask-position:center}::before{animation-name:var(--icon-name-start,var(--icon-name)),var(--icon-size-start,var(--icon-size,icon-000));background-color:var(--icon-color-start,var(--icon-color))}::after{animation-name:var(--icon-name-end,var(--icon-name)),var(--icon-size-end,var(--icon-size,icon-000));background-color:var(--icon-color-end,var(--icon-color))}[style*="--icon-color-start"]::before{color:var(--icon-color-start)}[style*="--icon-color-end"]::after{color:var(--icon-color-end)}[style*="--icon-name-start"]::before,[style*="--icon-name-end"]::after{content:""}@keyframes icon-000{100%{width:1.2em;height:1.2em}}@keyframes icon-100{100%{width:.625rem;height:.625rem}}@keyframes icon-200{100%{width:.75rem;height:.75rem}}@keyframes icon-300{100%{width:1rem;height:1rem}}@keyframes icon-400{100%{width:1.125rem;height:1.125rem}}@keyframes icon-500{100%{width:1.25rem;height:1.25rem}}@keyframes icon-600{100%{width:1.375rem;height:1.375rem}}@keyframes icon-700{100%{width:1.5rem;height:1.5rem}}@keyframes icon-800{100%{width:1.625rem;height:1.625rem}}@keyframes icon-900{100%{width:1.75rem;height:1.75rem}}@keyframes icon-999{100%{width:100%;height:100%}}.consul-intention-permission-header-list dt::before,.consul-intention-permission-list dt::before,.discovery-chain .resolver-card dt,.discovery-chain .route-card section header>::before{font-weight:var(--token-typography-font-weight-regular);background-color:var(--token-color-surface-strong);visibility:visible;padding:0 4px}#downstream-container .topology-metrics-card .details .group span::before,#downstream-container .topology-metrics-card div .critical::before,#downstream-container .topology-metrics-card div .empty::before,#downstream-container .topology-metrics-card div .health dt::before,#downstream-container .topology-metrics-card div .nspace dt::before,#downstream-container .topology-metrics-card div .partition dt::before,#downstream-container .topology-metrics-card div .passing::before,#downstream-container .topology-metrics-card div .warning::before,#downstream-container>div:first-child span::before,#login-toggle+div footer button::after,#metrics-container .link .config-link::before,#metrics-container .link .metrics-link::before,#metrics-container:hover .sparkline-key-link::before,#upstream-container .topology-metrics-card .details .group span::before,#upstream-container .topology-metrics-card div .critical::before,#upstream-container .topology-metrics-card div .empty::before,#upstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .partition dt::before,#upstream-container .topology-metrics-card div .passing::before,#upstream-container .topology-metrics-card div .warning::before,.animatable.tab-nav ul::after,.consul-auth-method-binding-list dl dt.type+dd span::before,.consul-auth-method-list ul .locality::before,.consul-auth-method-view dl dt.type+dd span::before,.consul-auth-method-view section dl dt.type+dd span::before,.consul-bucket-list .nspace::before,.consul-bucket-list .partition::before,.consul-bucket-list .peer::before,.consul-exposed-path-list>ul>li>.detail .policy-management::before,.consul-exposed-path-list>ul>li>.detail .policy::before,.consul-exposed-path-list>ul>li>.detail .role::before,.consul-exposed-path-list>ul>li>.detail dl.address dt::before,.consul-exposed-path-list>ul>li>.detail dl.behavior dt::before,.consul-exposed-path-list>ul>li>.detail dl.checks dt::before,.consul-exposed-path-list>ul>li>.detail dl.critical dt::before,.consul-exposed-path-list>ul>li>.detail dl.datacenter dt::before,.consul-exposed-path-list>ul>li>.detail dl.empty dt::before,.consul-exposed-path-list>ul>li>.detail dl.lock-delay dt::before,.consul-exposed-path-list>ul>li>.detail dl.mesh dt::before,.consul-exposed-path-list>ul>li>.detail dl.node dt::before,.consul-exposed-path-list>ul>li>.detail dl.nspace dt::before,.consul-exposed-path-list>ul>li>.detail dl.passing dt::before,.consul-exposed-path-list>ul>li>.detail dl.path dt::before,.consul-exposed-path-list>ul>li>.detail dl.port dt::before,.consul-exposed-path-list>ul>li>.detail dl.protocol dt::before,.consul-exposed-path-list>ul>li>.detail dl.socket dt::before,.consul-exposed-path-list>ul>li>.detail dl.ttl dt::before,.consul-exposed-path-list>ul>li>.detail dl.unknown dt::before,.consul-exposed-path-list>ul>li>.detail dl.warning dt::before,.consul-exposed-path-list>ul>li>.header .critical dd::before,.consul-exposed-path-list>ul>li>.header .empty dd::before,.consul-exposed-path-list>ul>li>.header .passing dd::before,.consul-exposed-path-list>ul>li>.header .policy-management dd::before,.consul-exposed-path-list>ul>li>.header .unknown dd::before,.consul-exposed-path-list>ul>li>.header .warning dd::before,.consul-exposed-path-list>ul>li>.header [rel=me] dd::before,.consul-external-source.jwt::before,.consul-external-source.oidc::before,.consul-health-check-list .health-check-output dd em.jwt::before,.consul-health-check-list .health-check-output dd em.oidc::before,.consul-health-check-list .health-check-output::before,.consul-instance-checks dt::before,.consul-intention-fieldsets .value->:last-child::before,.consul-intention-fieldsets .value-allow>:last-child::before,.consul-intention-fieldsets .value-deny>:last-child::before,.consul-intention-list em span::before,.consul-intention-list td strong.jwt::before,.consul-intention-list td strong.oidc::before,.consul-intention-list td.intent- strong::before,.consul-intention-list td.intent-allow strong::before,.consul-intention-list td.intent-deny strong::before,.consul-intention-permission-list .intent-allow::before,.consul-intention-permission-list .intent-deny::before,.consul-intention-permission-list strong.jwt::before,.consul-intention-permission-list strong.oidc::before,.consul-intention-search-bar .value- span::before,.consul-intention-search-bar .value-allow span::before,.consul-intention-search-bar .value-deny span::before,.consul-intention-search-bar li button span.jwt::before,.consul-intention-search-bar li button span.oidc::before,.consul-kind::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy-management::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .role::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.address dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.behavior dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.checks dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.datacenter dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.lock-delay dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.mesh dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.node dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.nspace dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.path dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.port dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.protocol dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.socket dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.ttl dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.unknown dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .critical dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .empty dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .passing dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .policy-management dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .unknown dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .warning dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header [rel=me] dd::before,.consul-peer-search-bar li button span.jwt::before,.consul-peer-search-bar li button span.oidc::before,.consul-server-card .health-status+dd.jwt::before,.consul-server-card .health-status+dd.oidc::before,.consul-upstream-instance-list dl.datacenter dt::before,.consul-upstream-instance-list dl.nspace dt::before,.consul-upstream-instance-list dl.partition dt::before,.consul-upstream-instance-list li>.detail .policy-management::before,.consul-upstream-instance-list li>.detail .policy::before,.consul-upstream-instance-list li>.detail .role::before,.consul-upstream-instance-list li>.detail dl.address dt::before,.consul-upstream-instance-list li>.detail dl.behavior dt::before,.consul-upstream-instance-list li>.detail dl.checks dt::before,.consul-upstream-instance-list li>.detail dl.critical dt::before,.consul-upstream-instance-list li>.detail dl.datacenter dt::before,.consul-upstream-instance-list li>.detail dl.empty dt::before,.consul-upstream-instance-list li>.detail dl.lock-delay dt::before,.consul-upstream-instance-list li>.detail dl.mesh dt::before,.consul-upstream-instance-list li>.detail dl.node dt::before,.consul-upstream-instance-list li>.detail dl.nspace dt::before,.consul-upstream-instance-list li>.detail dl.passing dt::before,.consul-upstream-instance-list li>.detail dl.path dt::before,.consul-upstream-instance-list li>.detail dl.port dt::before,.consul-upstream-instance-list li>.detail dl.protocol dt::before,.consul-upstream-instance-list li>.detail dl.socket dt::before,.consul-upstream-instance-list li>.detail dl.ttl dt::before,.consul-upstream-instance-list li>.detail dl.unknown dt::before,.consul-upstream-instance-list li>.detail dl.warning dt::before,.consul-upstream-instance-list li>.header .critical dd::before,.consul-upstream-instance-list li>.header .empty dd::before,.consul-upstream-instance-list li>.header .passing dd::before,.consul-upstream-instance-list li>.header .policy-management dd::before,.consul-upstream-instance-list li>.header .unknown dd::before,.consul-upstream-instance-list li>.header .warning dd::before,.consul-upstream-instance-list li>.header [rel=me] dd::before,.consul-upstream-list dl.partition dt::before,.copy-button button::before,.dangerous.informed-action header::before,.disclosure-menu [aria-expanded]~*>ul>li.is-active>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-checked]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-current]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-selected]>::after,.discovery-chain .resolvers>header span::after,.discovery-chain .route-card::before,.discovery-chain .route-card>header ul li.jwt::before,.discovery-chain .route-card>header ul li.oidc::before,.discovery-chain .routes>header span::after,.discovery-chain .splitter-card::before,.discovery-chain .splitters>header span::after,.empty-state li[class*=-link]>::after,.has-error>strong::before,.info.informed-action header::before,.jwt.consul-auth-method-type::before,.jwt.consul-external-source::before,.jwt.consul-kind::before,.jwt.consul-source::before,.jwt.consul-transparent-proxy::before,.jwt.leader::before,.jwt.topology-metrics-source-type::before,.leader::before,.list-collection>button::after,.list-collection>ul>li:not(:first-child)>.detail .policy-management::before,.list-collection>ul>li:not(:first-child)>.detail .policy::before,.list-collection>ul>li:not(:first-child)>.detail .role::before,.list-collection>ul>li:not(:first-child)>.detail dl.address dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.behavior dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.checks dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.critical dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.datacenter dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.empty dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.lock-delay dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.mesh dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.node dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.nspace dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.passing dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.path dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.port dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.protocol dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.socket dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.ttl dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.unknown dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.warning dt::before,.list-collection>ul>li:not(:first-child)>.header .critical dd::before,.list-collection>ul>li:not(:first-child)>.header .empty dd::before,.list-collection>ul>li:not(:first-child)>.header .passing dd::before,.list-collection>ul>li:not(:first-child)>.header .policy-management dd::before,.list-collection>ul>li:not(:first-child)>.header .unknown dd::before,.list-collection>ul>li:not(:first-child)>.header .warning dd::before,.list-collection>ul>li:not(:first-child)>.header [rel=me] dd::before,.menu-panel>ul>li.is-active>::after,.menu-panel>ul>li[aria-checked]>::after,.menu-panel>ul>li[aria-current]>::after,.menu-panel>ul>li[aria-selected]>::after,.modal-dialog [role=document] a[rel*=help]::after,.modal-dialog [role=document] table td.folder::before,.modal-dialog [role=document] table th span::after,.more-popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,.more-popover-menu>[type=checkbox]+label>::after,.oidc-select .auth0-oidc-provider::before,.oidc-select .google-oidc-provider::before,.oidc-select .microsoft-oidc-provider::before,.oidc-select .okta-oidc-provider::before,.oidc.consul-auth-method-type::before,.oidc.consul-external-source::before,.oidc.consul-kind::before,.oidc.consul-source::before,.oidc.consul-transparent-proxy::before,.oidc.leader::before,.oidc.topology-metrics-source-type::before,.popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,.popover-menu>[type=checkbox]+label>::after,.popover-select .jwt button::before,.popover-select .oidc button::before,.popover-select .value-critical button::before,.popover-select .value-empty button::before,.popover-select .value-passing button::before,.popover-select .value-unknown button::before,.popover-select .value-warning button::before,.search-bar-status li.jwt:not(.remove-all)::before,.search-bar-status li.oidc:not(.remove-all)::before,.search-bar-status li:not(.remove-all) button::before,.sparkline-key h3::before,.tag-list dt::before,.tooltip-panel dd>div::before,.topology-metrics-popover.deny .tippy-arrow::after,.topology-metrics-popover.deny>button::before,.topology-metrics-popover.l7 .tippy-arrow::after,.topology-metrics-popover.l7>button::before,.topology-metrics-popover.not-defined .tippy-arrow::after,.topology-metrics-popover.not-defined>button::before,.topology-metrics-status-error span::before,.topology-metrics-status-loader span::before,.topology-notices button::before,.type-sort.popover-select label>::before,.type-source.popover-select li.partition button::before,.warning.informed-action header::before,.warning.modal-dialog header::before,[class*=status-].empty-state header::before,a[rel*=external]::after,html[data-route^="dc.acls.index"] main td strong.jwt::before,html[data-route^="dc.acls.index"] main td strong.oidc::before,main a[rel*=help]::after,main header nav:first-child ol li:first-child a::before,main table td.folder::before,main table th span::after,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.jwt::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.oidc::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.jwt::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.oidc::before,span.jwt.policy-node-identity::before,span.jwt.policy-service-identity::before,span.oidc.policy-node-identity::before,span.oidc.policy-service-identity::before,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.has-actions tr>.actions>[type=checkbox]+label>::after,table.with-details td:only-child>div>label::before,table.with-details td>label::before,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.with-details tr>.actions>[type=checkbox]+label>::after,td.tags dt::before{content:""}@keyframes icon-alert-circle-outline{100%{-webkit-mask-image:var(--icon-alert-circle-16);mask-image:var(--icon-alert-circle-16);background-color:var(--icon-color,var(--color-alert-circle-outline-500,currentColor))}}[class*=status-].empty-state header::before{--icon-name:icon-alert-circle-outline;content:""}@keyframes icon-alert-triangle{100%{-webkit-mask-image:var(--icon-alert-triangle-16);mask-image:var(--icon-alert-triangle-16);background-color:var(--icon-color,var(--color-alert-triangle-500,currentColor))}}#downstream-container .topology-metrics-card div .warning::before,#upstream-container .topology-metrics-card div .warning::before,.consul-exposed-path-list>ul>li>.detail dl.warning dt::before,.consul-exposed-path-list>ul>li>.header .warning dd::before,.consul-health-check-list .warning.health-check-output::before,.consul-instance-checks.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .warning dd::before,.consul-upstream-instance-list li>.detail dl.warning dt::before,.consul-upstream-instance-list li>.header .warning dd::before,.dangerous.informed-action header::before,.list-collection>ul>li:not(:first-child)>.detail dl.warning dt::before,.list-collection>ul>li:not(:first-child)>.header .warning dd::before,.popover-select .value-warning button::before,.topology-metrics-popover.not-defined .tippy-arrow::after,.topology-metrics-popover.not-defined>button::before,.warning.informed-action header::before,.warning.modal-dialog header::before{--icon-name:icon-alert-triangle;content:""}@keyframes icon-arrow-left{100%{-webkit-mask-image:var(--icon-arrow-left-16);mask-image:var(--icon-arrow-left-16);background-color:var(--icon-color,var(--color-arrow-left-500,currentColor))}}@keyframes icon-arrow-right{100%{-webkit-mask-image:var(--icon-arrow-right-16);mask-image:var(--icon-arrow-right-16);background-color:var(--icon-color,var(--color-arrow-right-500,currentColor))}}@keyframes icon-cancel-plain{100%{-webkit-mask-image:var(--icon-x-16);mask-image:var(--icon-x-16);background-color:var(--icon-color,var(--color-cancel-plain-500,currentColor))}}.search-bar-status li:not(.remove-all) button::before{--icon-name:icon-cancel-plain;content:""}@keyframes icon-cancel-square-fill{100%{-webkit-mask-image:var(--icon-x-square-fill-16);mask-image:var(--icon-x-square-fill-16);background-color:var(--icon-color,var(--color-cancel-square-fill-500,currentColor))}}#downstream-container .topology-metrics-card div .critical::before,#upstream-container .topology-metrics-card div .critical::before,.consul-exposed-path-list>ul>li>.detail dl.critical dt::before,.consul-exposed-path-list>ul>li>.header .critical dd::before,.consul-health-check-list .critical.health-check-output::before,.consul-instance-checks.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .critical dd::before,.consul-upstream-instance-list li>.detail dl.critical dt::before,.consul-upstream-instance-list li>.header .critical dd::before,.has-error>strong::before,.list-collection>ul>li:not(:first-child)>.detail dl.critical dt::before,.list-collection>ul>li:not(:first-child)>.header .critical dd::before,.popover-select .value-critical button::before,.topology-metrics-popover.deny .tippy-arrow::after,.topology-metrics-popover.deny>button::before{--icon-name:icon-cancel-square-fill;content:""}@keyframes icon-check-plain{100%{-webkit-mask-image:var(--icon-check-16);mask-image:var(--icon-check-16);background-color:var(--icon-color,var(--color-check-plain-500,currentColor))}}.disclosure-menu [aria-expanded]~*>ul>li.is-active>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-checked]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-current]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-selected]>::after,.menu-panel>ul>li.is-active>::after,.menu-panel>ul>li[aria-checked]>::after,.menu-panel>ul>li[aria-current]>::after,.menu-panel>ul>li[aria-selected]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,.popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after{--icon-name:icon-check-plain;content:""}@keyframes icon-chevron-down{100%{-webkit-mask-image:var(--icon-chevron-down-16);mask-image:var(--icon-chevron-down-16);background-color:var(--icon-color,var(--color-chevron-down-500,currentColor))}}.list-collection>button.closed::after,.more-popover-menu>[type=checkbox]+label>::after,.popover-menu>[type=checkbox]+label>::after,.topology-notices button::before,table.has-actions tr>.actions>[type=checkbox]+label>::after,table.with-details td:only-child>div>label::before,table.with-details td>label::before,table.with-details tr>.actions>[type=checkbox]+label>::after{--icon-name:icon-chevron-down;content:""}@keyframes icon-copy-action{100%{-webkit-mask-image:var(--icon-clipboard-copy-16);mask-image:var(--icon-clipboard-copy-16);background-color:var(--icon-color,var(--color-copy-action-500,currentColor))}}.copy-button button::before{--icon-name:icon-copy-action;content:"";--icon-color:var(--token-color-foreground-faint)}@keyframes icon-deny-alt{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-deny-alt-500,currentColor))}}@keyframes icon-deny-default{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-deny-default-500,currentColor))}}@keyframes icon-disabled{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-disabled-500,currentColor))}}.status-403.empty-state header::before{--icon-name:icon-disabled;content:""}@keyframes icon-docs{100%{-webkit-mask-image:var(--icon-docs-16);mask-image:var(--icon-docs-16);background-color:var(--icon-color,var(--color-docs-500,currentColor))}}#metrics-container .link .config-link::before,.empty-state .docs-link>::after{--icon-name:icon-docs;content:""}@keyframes icon-exit{100%{-webkit-mask-image:var(--icon-external-link-16);mask-image:var(--icon-external-link-16);background-color:var(--icon-color,var(--color-exit-500,currentColor))}}#metrics-container .link .metrics-link::before,a[rel*=external]::after{--icon-name:icon-exit;content:""}@keyframes icon-file-fill{100%{-webkit-mask-image:var(--icon-file-16);mask-image:var(--icon-file-16);background-color:var(--icon-color,var(--color-file-fill-500,currentColor))}}@keyframes icon-folder-outline{100%{-webkit-mask-image:var(--icon-folder-16);mask-image:var(--icon-folder-16);background-color:var(--icon-color,var(--color-folder-outline-500,currentColor))}}#downstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .nspace dt::before,.consul-bucket-list .nspace::before,.consul-exposed-path-list>ul>li>.detail dl.nspace dt::before,.consul-intention-list span[class|=nspace]::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.nspace dt::before,.consul-upstream-instance-list dl.nspace dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.nspace dt::before,.modal-dialog [role=document] table td.folder::before,main table td.folder::before{--icon-name:icon-folder-outline;content:""}@keyframes icon-health{100%{-webkit-mask-image:var(--icon-activity-16);mask-image:var(--icon-activity-16);background-color:var(--icon-color,var(--color-health-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.checks dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.checks dt::before,.consul-upstream-instance-list li>.detail dl.checks dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.checks dt::before{--icon-name:icon-health;content:""}@keyframes icon-help-circle-outline{100%{-webkit-mask-image:var(--icon-help-16);mask-image:var(--icon-help-16);background-color:var(--icon-color,var(--color-help-circle-outline-500,currentColor))}}#downstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .health dt::before,.consul-exposed-path-list>ul>li>.detail dl.unknown dt::before,.consul-exposed-path-list>ul>li>.header .unknown dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.unknown dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .unknown dd::before,.consul-upstream-instance-list li>.detail dl.unknown dt::before,.consul-upstream-instance-list li>.header .unknown dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.unknown dt::before,.list-collection>ul>li:not(:first-child)>.header .unknown dd::before,.popover-select .value-unknown button::before,.status-404.empty-state header::before{--icon-name:icon-help-circle-outline;content:""}@keyframes icon-info-circle-fill{100%{-webkit-mask-image:var(--icon-info-16);mask-image:var(--icon-info-16);background-color:var(--icon-color,var(--color-info-circle-fill-500,currentColor))}}#metrics-container:hover .sparkline-key-link::before,.info.informed-action header::before,.sparkline-key h3::before{--icon-name:icon-info-circle-fill;content:""}@keyframes icon-info-circle-outline{100%{-webkit-mask-image:var(--icon-info-16);mask-image:var(--icon-info-16);background-color:var(--icon-color,var(--color-info-circle-outline-500,currentColor))}}#downstream-container>div:first-child span::before,.consul-auth-method-binding-list dl dt.type+dd span::before,.consul-auth-method-view dl dt.type+dd span::before,.consul-exposed-path-list>ul>li>.detail dl.behavior dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.behavior dt::before,.consul-upstream-instance-list li>.detail dl.behavior dt::before,.discovery-chain .resolvers>header span::after,.discovery-chain .routes>header span::after,.discovery-chain .splitters>header span::after,.list-collection>ul>li:not(:first-child)>.detail dl.behavior dt::before,.modal-dialog [role=document] a[rel*=help]::after,.modal-dialog [role=document] table th span::after,.topology-metrics-status-error span::before,.topology-metrics-status-loader span::before,main a[rel*=help]::after,main table th span::after{--icon-name:icon-info-circle-outline;content:""}@keyframes icon-learn{100%{-webkit-mask-image:var(--icon-learn-16);mask-image:var(--icon-learn-16);background-color:var(--icon-color,var(--color-learn-500,currentColor))}}.empty-state .learn-link>::after{--icon-name:icon-learn;content:""}@keyframes icon-logo-github-monochrome{100%{-webkit-mask-image:var(--icon-github-color-16);mask-image:var(--icon-github-color-16);background-color:var(--icon-color,var(--color-logo-github-monochrome-500,currentColor))}}@keyframes icon-logo-google-color{100%{background-image:var(--icon-google-color-16)}}.oidc-select .google-oidc-provider::before{--icon-name:icon-logo-google-color;content:""}@keyframes icon-logo-kubernetes-color{100%{background-image:var(--icon-kubernetes-color-16)}}@keyframes icon-menu{100%{-webkit-mask-image:var(--icon-menu-16);mask-image:var(--icon-menu-16);background-color:var(--icon-color,var(--color-menu-500,currentColor))}}@keyframes icon-minus-square-fill{100%{-webkit-mask-image:var(--icon-minus-square-16);mask-image:var(--icon-minus-square-16);background-color:var(--icon-color,var(--color-minus-square-fill-500,currentColor))}}#downstream-container .topology-metrics-card div .empty::before,#upstream-container .topology-metrics-card div .empty::before,.consul-exposed-path-list>ul>li>.detail dl.empty dt::before,.consul-exposed-path-list>ul>li>.header .empty dd::before,.consul-instance-checks.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .empty dd::before,.consul-upstream-instance-list li>.detail dl.empty dt::before,.consul-upstream-instance-list li>.header .empty dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.empty dt::before,.list-collection>ul>li:not(:first-child)>.header .empty dd::before,.popover-select .value-empty button::before{--icon-name:icon-minus-square-fill;content:""}@keyframes icon-more-horizontal{100%{-webkit-mask-image:var(--icon-more-horizontal-16);mask-image:var(--icon-more-horizontal-16);background-color:var(--icon-color,var(--color-more-horizontal-500,currentColor))}}@keyframes icon-public-default{100%{-webkit-mask-image:var(--icon-globe-16);mask-image:var(--icon-globe-16);background-color:var(--icon-color,var(--color-public-default-500,currentColor))}}.consul-auth-method-list ul .locality::before,.consul-exposed-path-list>ul>li>.detail dl.address dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.address dt::before,.consul-upstream-instance-list li>.detail dl.address dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.address dt::before{--icon-name:icon-public-default;content:""}@keyframes icon-search{100%{-webkit-mask-image:var(--icon-search-16);mask-image:var(--icon-search-16);background-color:var(--icon-color,var(--color-search-500,currentColor))}}@keyframes icon-star-outline{100%{-webkit-mask-image:var(--icon-star-16);mask-image:var(--icon-star-16);background-color:var(--icon-color,var(--color-star-outline-500,currentColor))}}.leader::before{--icon-name:icon-star-outline;content:""}@keyframes icon-user-organization{100%{-webkit-mask-image:var(--icon-org-16);mask-image:var(--icon-org-16);background-color:var(--icon-color,var(--color-user-organization-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.datacenter dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.datacenter dt::before,.consul-upstream-instance-list dl.datacenter dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.datacenter dt::before{--icon-name:icon-user-organization;content:""}@keyframes icon-user-plain{100%{-webkit-mask-image:var(--icon-user-16);mask-image:var(--icon-user-16);background-color:var(--icon-color,var(--color-user-plain-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail .role::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .role::before,.consul-upstream-instance-list li>.detail .role::before,.list-collection>ul>li:not(:first-child)>.detail .role::before{--icon-name:icon-user-plain;content:""}@keyframes icon-user-team{100%{-webkit-mask-image:var(--icon-users-16);mask-image:var(--icon-users-16);background-color:var(--icon-color,var(--color-user-team-500,currentColor))}}#downstream-container .topology-metrics-card div .partition dt::before,#upstream-container .topology-metrics-card div .partition dt::before,.consul-bucket-list .partition::before,.consul-intention-list span[class|=partition]::before,.consul-upstream-instance-list dl.partition dt::before,.consul-upstream-list dl.partition dt::before,.type-source.popover-select li.partition button::before{--icon-name:icon-user-team;content:""}@keyframes icon-alert-circle{100%{-webkit-mask-image:var(--icon-alert-circle-16);mask-image:var(--icon-alert-circle-16);background-color:var(--icon-color,var(--color-alert-circle-500,currentColor))}}@keyframes icon-check{100%{-webkit-mask-image:var(--icon-check-16);mask-image:var(--icon-check-16);background-color:var(--icon-color,var(--color-check-500,currentColor))}}@keyframes icon-check-circle{100%{-webkit-mask-image:var(--icon-check-circle-16);mask-image:var(--icon-check-circle-16);background-color:var(--icon-color,var(--color-check-circle-500,currentColor))}}@keyframes icon-check-circle-fill{100%{-webkit-mask-image:var(--icon-check-circle-fill-16);mask-image:var(--icon-check-circle-fill-16);background-color:var(--icon-color,var(--color-check-circle-fill-500,currentColor))}}#downstream-container .topology-metrics-card div .passing::before,#upstream-container .topology-metrics-card div .passing::before,.consul-exposed-path-list>ul>li>.detail dl.passing dt::before,.consul-exposed-path-list>ul>li>.header .passing dd::before,.consul-exposed-path-list>ul>li>.header [rel=me] dd::before,.consul-health-check-list .passing.health-check-output::before,.consul-instance-checks.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .passing dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header [rel=me] dd::before,.consul-upstream-instance-list li>.detail dl.passing dt::before,.consul-upstream-instance-list li>.header .passing dd::before,.consul-upstream-instance-list li>.header [rel=me] dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.passing dt::before,.list-collection>ul>li:not(:first-child)>.header .passing dd::before,.list-collection>ul>li:not(:first-child)>.header [rel=me] dd::before,.popover-select .value-passing button::before{--icon-name:icon-check-circle-fill;content:""}@keyframes icon-chevron-left{100%{-webkit-mask-image:var(--icon-chevron-left-16);mask-image:var(--icon-chevron-left-16);background-color:var(--icon-color,var(--color-chevron-left-500,currentColor))}}.empty-state .back-link>::after,main header nav:first-child ol li:first-child a::before{--icon-name:icon-chevron-left;content:""}@keyframes icon-chevron-right{100%{-webkit-mask-image:var(--icon-chevron-right-16);mask-image:var(--icon-chevron-right-16);background-color:var(--icon-color,var(--color-chevron-right-500,currentColor))}}#login-toggle+div footer button::after{--icon-name:icon-chevron-right;content:""}@keyframes icon-chevron-up{100%{-webkit-mask-image:var(--icon-chevron-up-16);mask-image:var(--icon-chevron-up-16);background-color:var(--icon-color,var(--color-chevron-up-500,currentColor))}}.list-collection>button::after,.more-popover-menu>[type=checkbox]:checked+label>::after,.popover-menu>[type=checkbox]:checked+label>::after,.topology-notices button[aria-expanded=true]::before,table.has-actions tr>.actions>[type=checkbox]:checked+label>::after,table.with-details tr>.actions>[type=checkbox]:checked+label>::after{--icon-name:icon-chevron-up;content:""}@keyframes icon-delay{100%{-webkit-mask-image:var(--icon-delay-16);mask-image:var(--icon-delay-16);background-color:var(--icon-color,var(--color-delay-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.lock-delay dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.lock-delay dt::before,.consul-upstream-instance-list li>.detail dl.lock-delay dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.lock-delay dt::before{--icon-name:icon-delay;content:""}@keyframes icon-docs-link{100%{-webkit-mask-image:var(--icon-docs-link-16);mask-image:var(--icon-docs-link-16);background-color:var(--icon-color,var(--color-docs-link-500,currentColor))}}@keyframes icon-eye{100%{-webkit-mask-image:var(--icon-eye-16);mask-image:var(--icon-eye-16);background-color:var(--icon-color,var(--color-eye-500,currentColor))}}@keyframes icon-eye-off{100%{-webkit-mask-image:var(--icon-eye-off-16);mask-image:var(--icon-eye-off-16);background-color:var(--icon-color,var(--color-eye-off-500,currentColor))}}@keyframes icon-file-text{100%{-webkit-mask-image:var(--icon-file-text-16);mask-image:var(--icon-file-text-16);background-color:var(--icon-color,var(--color-file-text-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail .policy::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy::before,.consul-upstream-instance-list li>.detail .policy::before,.list-collection>ul>li:not(:first-child)>.detail .policy::before{--icon-name:icon-file-text;content:""}@keyframes icon-gateway{100%{-webkit-mask-image:var(--icon-gateway-16);mask-image:var(--icon-gateway-16);background-color:var(--icon-color,var(--color-gateway-500,currentColor))}}.consul-kind::before{--icon-name:icon-gateway;content:""}@keyframes icon-git-commit{100%{-webkit-mask-image:var(--icon-git-commit-16);mask-image:var(--icon-git-commit-16);background-color:var(--icon-color,var(--color-git-commit-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.node dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.node dt::before,.consul-upstream-instance-list li>.detail dl.node dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.node dt::before{--icon-name:icon-git-commit;content:""}@keyframes icon-hexagon{100%{-webkit-mask-image:var(--icon-hexagon-16);mask-image:var(--icon-hexagon-16);background-color:var(--icon-color,var(--color-hexagon-500,currentColor))}}@keyframes icon-history{100%{-webkit-mask-image:var(--icon-history-16);mask-image:var(--icon-history-16);background-color:var(--icon-color,var(--color-history-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.ttl dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.ttl dt::before,.consul-upstream-instance-list li>.detail dl.ttl dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.ttl dt::before{--icon-name:icon-history;content:""}@keyframes icon-info{100%{-webkit-mask-image:var(--icon-info-16);mask-image:var(--icon-info-16);background-color:var(--icon-color,var(--color-info-500,currentColor))}}@keyframes icon-layers{100%{-webkit-mask-image:var(--icon-layers-16);mask-image:var(--icon-layers-16);background-color:var(--icon-color,var(--color-layers-500,currentColor))}}.topology-metrics-popover.l7 .tippy-arrow::after,.topology-metrics-popover.l7>button::before{--icon-name:icon-layers;content:"";--icon-color:var(--token-color-palette-neutral-300)}@keyframes icon-loading{100%{-webkit-mask-image:var(--icon-loading-16);mask-image:var(--icon-loading-16);background-color:var(--icon-color,var(--color-loading-500,currentColor))}}@keyframes icon-network-alt{100%{-webkit-mask-image:var(--icon-network-alt-16);mask-image:var(--icon-network-alt-16);background-color:var(--icon-color,var(--color-network-alt-500,currentColor))}}.consul-bucket-list .peer::before{--icon-name:icon-network-alt;content:""}@keyframes icon-path{100%{-webkit-mask-image:var(--icon-path-16);mask-image:var(--icon-path-16);background-color:var(--icon-color,var(--color-path-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.path dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.path dt::before,.consul-upstream-instance-list li>.detail dl.path dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.path dt::before{--icon-name:icon-path;content:""}@keyframes icon-running{100%{-webkit-mask-image:var(--icon-running-16);mask-image:var(--icon-running-16);background-color:var(--icon-color,var(--color-running-500,currentColor))}}@keyframes icon-skip{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-skip-500,currentColor))}}@keyframes icon-socket{100%{-webkit-mask-image:var(--icon-socket-16);mask-image:var(--icon-socket-16);background-color:var(--icon-color,var(--color-socket-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.socket dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.socket dt::before,.consul-upstream-instance-list li>.detail dl.socket dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.socket dt::before{--icon-name:icon-socket;content:""}@keyframes icon-star-circle{100%{-webkit-mask-image:var(--icon-star-circle-16);mask-image:var(--icon-star-circle-16);background-color:var(--icon-color,var(--color-star-circle-500,currentColor))}}@keyframes icon-star-fill{100%{-webkit-mask-image:var(--icon-star-fill-16);mask-image:var(--icon-star-fill-16);background-color:var(--icon-color,var(--color-star-fill-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail .policy-management::before,.consul-exposed-path-list>ul>li>.header .policy-management dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy-management::before,.consul-lock-session-list ul>li:not(:first-child)>.header .policy-management dd::before,.consul-upstream-instance-list li>.detail .policy-management::before,.consul-upstream-instance-list li>.header .policy-management dd::before,.list-collection>ul>li:not(:first-child)>.detail .policy-management::before,.list-collection>ul>li:not(:first-child)>.header .policy-management dd::before{--icon-name:icon-star-fill;content:"";--icon-color:var(--token-color-consul-brand)}@keyframes icon-tag{100%{-webkit-mask-image:var(--icon-tag-16);mask-image:var(--icon-tag-16);background-color:var(--icon-color,var(--color-tag-500,currentColor))}}.tag-list dt::before,td.tags dt::before{--icon-name:icon-tag;content:""}@keyframes icon-x{100%{-webkit-mask-image:var(--icon-x-16);mask-image:var(--icon-x-16);background-color:var(--icon-color,var(--color-x-500,currentColor))}}@keyframes icon-x-circle{100%{-webkit-mask-image:var(--icon-x-circle-16);mask-image:var(--icon-x-circle-16);background-color:var(--icon-color,var(--color-x-circle-500,currentColor))}}@keyframes icon-x-square{100%{-webkit-mask-image:var(--icon-x-square-16);mask-image:var(--icon-x-square-16);background-color:var(--icon-color,var(--color-x-square-500,currentColor))}}@keyframes icon-cloud-cross{100%{-webkit-mask-image:var(--icon-cloud-cross-16);mask-image:var(--icon-cloud-cross-16);background-color:var(--icon-color,var(--color-cloud-cross-500,currentColor))}}@keyframes icon-loading-motion{100%{-webkit-mask-image:var(--icon-loading-motion-16);mask-image:var(--icon-loading-motion-16);background-color:var(--icon-color,var(--color-loading-motion-500,currentColor))}}@keyframes icon-logo-auth0-color{100%{background-image:var(--icon-auth0-color-16)}}.oidc-select .auth0-oidc-provider::before{--icon-name:icon-logo-auth0-color;content:""}@keyframes icon-logo-ember-circle-color{100%{background-image:var(--icon-logo-ember-circle-color-16)}}@keyframes icon-logo-glimmer-color{100%{background-image:var(--icon-logo-glimmer-color-16)}}@keyframes icon-logo-jwt-color{100%{background-image:var(--icon-logo-jwt-color-16)}}.consul-external-source.jwt::before,.consul-health-check-list .health-check-output dd em.jwt::before,.consul-intention-list td strong.jwt::before,.consul-intention-permission-list strong.jwt::before,.consul-intention-search-bar li button span.jwt::before,.consul-peer-search-bar li button span.jwt::before,.consul-server-card .health-status+dd.jwt::before,.discovery-chain .route-card>header ul li.jwt::before,.jwt.consul-auth-method-type::before,.jwt.consul-kind::before,.jwt.consul-source::before,.jwt.consul-transparent-proxy::before,.jwt.leader::before,.jwt.topology-metrics-source-type::before,.popover-select .jwt button::before,.search-bar-status li.jwt:not(.remove-all)::before,html[data-route^="dc.acls.index"] main td strong.jwt::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.jwt::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.jwt::before,span.jwt.policy-node-identity::before,span.jwt.policy-service-identity::before{--icon-name:icon-logo-jwt-color;content:""}@keyframes icon-logo-microsoft-color{100%{background-image:var(--icon-microsoft-color-16)}}.oidc-select .microsoft-oidc-provider::before{--icon-name:icon-logo-microsoft-color;content:""}@keyframes icon-logo-oidc-color{100%{background-image:var(--icon-logo-oidc-color-16)}}.consul-external-source.oidc::before,.consul-health-check-list .health-check-output dd em.oidc::before,.consul-intention-list td strong.oidc::before,.consul-intention-permission-list strong.oidc::before,.consul-intention-search-bar li button span.oidc::before,.consul-peer-search-bar li button span.oidc::before,.consul-server-card .health-status+dd.oidc::before,.discovery-chain .route-card>header ul li.oidc::before,.oidc.consul-auth-method-type::before,.oidc.consul-kind::before,.oidc.consul-source::before,.oidc.consul-transparent-proxy::before,.oidc.leader::before,.oidc.topology-metrics-source-type::before,.popover-select .oidc button::before,.search-bar-status li.oidc:not(.remove-all)::before,html[data-route^="dc.acls.index"] main td strong.oidc::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.oidc::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.oidc::before,span.oidc.policy-node-identity::before,span.oidc.policy-service-identity::before{--icon-name:icon-logo-oidc-color;content:""}@keyframes icon-logo-okta-color{100%{background-image:var(--icon-okta-color-16)}}.oidc-select .okta-oidc-provider::before{--icon-name:icon-logo-okta-color;content:""}@keyframes icon-mesh{100%{-webkit-mask-image:var(--icon-mesh-16);mask-image:var(--icon-mesh-16);background-color:var(--icon-color,var(--color-mesh-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.mesh dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.mesh dt::before,.consul-upstream-instance-list li>.detail dl.mesh dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.mesh dt::before{--icon-name:icon-mesh;content:""}@keyframes icon-port{100%{-webkit-mask-image:var(--icon-port-16);mask-image:var(--icon-port-16);background-color:var(--icon-color,var(--color-port-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.port dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.port dt::before,.consul-upstream-instance-list li>.detail dl.port dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.port dt::before{--icon-name:icon-port;content:""}@keyframes icon-protocol{100%{-webkit-mask-image:var(--icon-protocol-16);mask-image:var(--icon-protocol-16);background-color:var(--icon-color,var(--color-protocol-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.protocol dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.protocol dt::before,.consul-upstream-instance-list li>.detail dl.protocol dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.protocol dt::before{--icon-name:icon-protocol;content:""}@keyframes icon-redirect{100%{-webkit-mask-image:var(--icon-redirect-16);mask-image:var(--icon-redirect-16);background-color:var(--icon-color,var(--color-redirect-500,currentColor))}}@keyframes icon-search-color{100%{background-image:var(--icon-search-color-16)}}[for=toolbar-toggle]{--icon-name:icon-search-color;content:""}@keyframes icon-sort{100%{-webkit-mask-image:var(--icon-sort-desc-16);mask-image:var(--icon-sort-desc-16);background-color:var(--icon-color,var(--color-sort-500,currentColor))}}.type-sort.popover-select label>::before{--icon-name:icon-sort;content:""}@keyframes icon-union{100%{-webkit-mask-image:var(--icon-union-16);mask-image:var(--icon-union-16);background-color:var(--icon-color,var(--color-union-500,currentColor))}}#downstream-container .topology-metrics-card .details .group span::before,#upstream-container .topology-metrics-card .details .group span::before{--icon-name:icon-union;content:""}.ember-basic-dropdown{position:relative}.ember-basic-dropdown,.ember-basic-dropdown-content,.ember-basic-dropdown-content *{box-sizing:border-box}.ember-basic-dropdown-content{position:absolute;width:auto;z-index:1000;background-color:#fff}.ember-basic-dropdown-content--left{left:0}.ember-basic-dropdown-content--right{right:0}.ember-basic-dropdown-overlay{position:fixed;background:rgba(0,0,0,.5);width:100%;height:100%;z-index:10;top:0;left:0;pointer-events:none}.ember-basic-dropdown-content-wormhole-origin{display:inline}.ember-power-select-dropdown *{box-sizing:border-box}.ember-power-select-trigger{position:relative;border-radius:4px;background-color:#fff;line-height:1.75;overflow-x:hidden;text-overflow:ellipsis;min-height:1.75em;-moz-user-select:none;user-select:none;-webkit-user-select:none;color:inherit}.ember-power-select-trigger:after{content:"";display:table;clear:both}.ember-power-select-trigger--active,.ember-power-select-trigger:focus{box-shadow:none}.ember-basic-dropdown-trigger--below.ember-power-select-trigger[aria-expanded=true],.ember-basic-dropdown-trigger--in-place.ember-power-select-trigger[aria-expanded=true]{border-bottom-left-radius:0;border-bottom-right-radius:0}.ember-basic-dropdown-trigger--above.ember-power-select-trigger[aria-expanded=true]{border-top-left-radius:0;border-top-right-radius:0}.ember-power-select-placeholder{color:#999;display:block;overflow-x:hidden;white-space:nowrap;text-overflow:ellipsis}.ember-power-select-status-icon{position:absolute;display:inline-block;width:0;height:0;top:0;bottom:0;margin:auto;border-style:solid;border-width:7px 4px 0;border-color:#aaa transparent transparent;right:5px}.ember-basic-dropdown-trigger[aria-expanded=true] .ember-power-select-status-icon{transform:rotate(180deg)}.ember-power-select-clear-btn{position:absolute;cursor:pointer;right:25px}.ember-power-select-trigger-multiple-input{font-family:inherit;font-size:inherit;border:none;display:inline-block;line-height:inherit;-webkit-appearance:none;outline:0;padding:0;float:left;background-color:transparent;text-indent:2px}.ember-power-select-trigger-multiple-input:disabled{background-color:#eee}.ember-power-select-trigger-multiple-input::placeholder{opacity:1;color:#999}.ember-power-select-trigger-multiple-input::-webkit-input-placeholder{opacity:1;color:#999}.ember-power-select-trigger-multiple-input::-moz-placeholder{opacity:1;color:#999}.ember-power-select-trigger-multiple-input::-ms-input-placeholder{opacity:1;color:#999}.active.discovery-chain [id*=":"],.discovery-chain path,.ember-power-select-multiple-remove-btn:not(:hover){opacity:.5}.ember-power-select-multiple-options{padding:0;margin:0}.ember-power-select-multiple-option{border:1px solid gray;border-radius:4px;color:#333;background-color:#e4e4e4;padding:0 4px;display:inline-block;line-height:1.45;float:left;margin:2px 0 2px 3px}.ember-power-select-multiple-remove-btn{cursor:pointer}.ember-power-select-search{padding:4px}.ember-power-select-search-input{border:1px solid #aaa;border-radius:0;width:100%;font-size:inherit;line-height:inherit;padding:0 5px}.ember-power-select-search-input:focus{border:1px solid #aaa;box-shadow:none}.ember-power-select-dropdown{border-left:1px solid #aaa;border-right:1px solid #aaa;line-height:1.75;border-radius:4px;box-shadow:none;overflow:hidden;color:inherit}.ember-power-select-dropdown.ember-basic-dropdown-content--above{border-top:1px solid #aaa;border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.ember-power-select-dropdown.ember-basic-dropdown-content--below,.ember-power-select-dropdown.ember-basic-dropdown-content--in-place{border-top:none;border-bottom:1px solid #aaa;border-top-left-radius:0;border-top-right-radius:0}.ember-power-select-dropdown.ember-basic-dropdown-content--in-place{width:100%}.ember-power-select-options{list-style:none;margin:0;padding:0;-moz-user-select:none;user-select:none;-webkit-user-select:none}.ember-power-select-placeholder,.ember-power-select-selected-item,a[rel*=external]::after{margin-left:8px}.ember-power-select-options[role=listbox]{overflow-y:auto;-webkit-overflow-scrolling:touch;max-height:12.25em}.ember-power-select-option{cursor:pointer;padding:0 8px}.ember-power-select-group[aria-disabled=true]{color:#999;cursor:not-allowed}.ember-power-select-group[aria-disabled=true] .ember-power-select-option,.ember-power-select-option[aria-disabled=true]{color:#999;pointer-events:none;cursor:not-allowed}.ember-power-select-option[aria-selected=true]{background-color:#ddd}.ember-power-select-option[aria-current=true]{background-color:#5897fb;color:#fff}.ember-power-select-group-name{cursor:default;font-weight:700}.ember-power-select-trigger[aria-disabled=true]{background-color:#eee}.ember-power-select-trigger{padding:0 16px 0 0}.ember-power-select-group .ember-power-select-group .ember-power-select-group-name{padding-left:24px}.ember-power-select-group .ember-power-select-group .ember-power-select-option{padding-left:40px}.ember-power-select-group .ember-power-select-option{padding-left:24px}.ember-power-select-group .ember-power-select-group-name{padding-left:8px}.ember-power-select-trigger[dir=rtl]{padding:0 0 0 16px}.ember-power-select-trigger[dir=rtl] .ember-power-select-placeholder,.ember-power-select-trigger[dir=rtl] .ember-power-select-selected-item{margin-right:8px}.ember-power-select-trigger[dir=rtl] .ember-power-select-multiple-option,.ember-power-select-trigger[dir=rtl] .ember-power-select-trigger-multiple-input{float:right}.ember-power-select-trigger[dir=rtl] .ember-power-select-status-icon{left:5px;right:initial}.ember-power-select-trigger[dir=rtl] .ember-power-select-clear-btn{left:25px;right:initial}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-group .ember-power-select-group-name{padding-right:24px}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-group .ember-power-select-option{padding-right:40px}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-option{padding-right:24px}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-group-name{padding-right:8px}#login-toggle+div footer button:focus,#login-toggle+div footer button:hover,.consul-intention-fieldsets .permissions>button:focus,.consul-intention-fieldsets .permissions>button:hover,.empty-state>ul>li>:focus,.empty-state>ul>li>:hover,.empty-state>ul>li>label>button:focus,.empty-state>ul>li>label>button:hover,.modal-dialog [role=document] dd a:focus,.modal-dialog [role=document] dd a:hover,.modal-dialog [role=document] p a:focus,.modal-dialog [role=document] p a:hover,.oidc-select button.reset:focus,.oidc-select button.reset:hover,.search-bar-status .remove-all button:focus,.search-bar-status .remove-all button:hover,main dd a:focus,main dd a:hover,main p a:focus,main p a:hover{text-decoration:underline}#login-toggle+div footer button,.consul-intention-fieldsets .permissions>button,.empty-state>ul>li>*,.empty-state>ul>li>:active,.empty-state>ul>li>:focus,.empty-state>ul>li>:hover,.empty-state>ul>li>label>button,.empty-state>ul>li>label>button:active,.empty-state>ul>li>label>button:focus,.empty-state>ul>li>label>button:hover,.modal-dialog [role=document] dd a,.modal-dialog [role=document] p a,.oidc-select button.reset,.search-bar-status .remove-all button,main dd a,main dd a:active,main dd a:focus,main dd a:hover,main p a,main p a:active,main p a:focus,main p a:hover{color:var(--token-color-foreground-action)}.modal-dialog [role=document] label a[rel*=help],div.with-confirmation p,main label a[rel*=help]{color:var(--token-color-foreground-disabled)}#login-toggle+div footer button,.consul-intention-fieldsets .permissions>button,.empty-state>ul>li>*,.empty-state>ul>li>label>button,.modal-dialog [role=document] dd a,.modal-dialog [role=document] p a,.oidc-select button.reset,.search-bar-status .remove-all button,main dd a,main p a{cursor:pointer;background-color:transparent}#login-toggle+div footer button:active,.consul-intention-fieldsets .permissions>button:active,.empty-state>ul>li>:active,.empty-state>ul>li>label>button:active,.modal-dialog [role=document] dd a:active,.modal-dialog [role=document] p a:active,.oidc-select button.reset:active,.search-bar-status .remove-all button:active,main dd a:active,main p a:active{outline:0}.modal-dialog [role=document] a[rel*=help]::after,main a[rel*=help]::after{opacity:.4}.modal-dialog [role=document] h2 a,main h2 a{color:var(--token-color-foreground-strong)}.auth-form em,.empty-state,main header nav:first-child ol li a,main header nav:first-child ol li:not(:first-child) a::before{color:var(--token-color-foreground-faint)}.modal-dialog [role=document] h2 a[rel*=help]::after,main h2 a[rel*=help]::after{font-size:.65em;margin-top:.2em;margin-left:.2em}.tab-section>p:only-child [rel*=help]::after{content:none}.auth-form{width:320px;margin:-20px 25px 0}.auth-form em{font-style:normal;display:inline-block;margin-top:1em}.auth-form .oidc-select,.auth-form form{padding-top:1em}.auth-form form{margin-bottom:0!important}.auth-form .ember-basic-dropdown-trigger,.auth-form button:not(.reset){width:100%}.auth-form .progress{margin:0 auto}#login-toggle+div footer button::after{font-size:120%;position:relative;top:-1px;left:-3px}#login-toggle+div footer{border-top:0;background-color:transparent;padding:10px 42px 20px}#login-toggle+div>div>div>div{padding-bottom:0}main header nav:first-child ol li a{text-decoration:none}main header nav:first-child ol li a:hover{color:var(--token-color-foreground-action);text-decoration:underline}main header nav:first-child ol li a::before{text-decoration:none}main header nav:first-child ol{display:grid;grid-auto-flow:column;white-space:nowrap;overflow:hidden}main header nav:first-child ol>li{list-style-type:none;display:inline-flex;overflow:hidden}main header nav:first-child ol li:first-child a::before{background-color:var(--token-color-foreground-faint);margin-right:4px;display:inline-block}main header nav:first-child ol li:not(:first-child) a{margin-left:6px;overflow:hidden;text-overflow:ellipsis}main header nav:first-child ol li:not(:first-child) a::before{content:"/";margin-right:8px;display:inline-block}main header nav:first-child{position:absolute;top:12px}.consul-intention-action-warn-modal button.dangerous,.copy-button button,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-select label>*,.topology-notices button,.type-sort.popover-select label>*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{cursor:pointer;white-space:nowrap;text-decoration:none}.consul-intention-action-warn-modal button.dangerous:disabled,.copy-button button:disabled,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]:disabled,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]:disabled,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]:disabled,.informed-action>ul>li>:disabled,.menu-panel>ul>[role=treeitem]:disabled,.menu-panel>ul>li>[role=menuitem]:disabled,.menu-panel>ul>li>[role=option]:disabled,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:disabled,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:disabled,.popover-select label>:disabled,.topology-notices button:disabled,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:disabled,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:disabled{cursor:default;box-shadow:none}.checkbox-group label,.more-popover-menu>[type=checkbox]~label,.popover-menu>[type=checkbox]~label,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label,table.has-actions tr>.actions>[type=checkbox]~label,table.with-details tr>.actions>[type=checkbox]~label{cursor:pointer}.consul-intention-action-warn-modal button.dangerous{border-width:1px;border-radius:var(--decor-radius-100);box-shadow:var(--token-elevation-high-box-shadow)}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{color:var(--token-color-foreground-strong);background-color:var(--token-color-surface-primary)}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]:focus,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]:hover,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]:focus,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]:hover,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]:focus,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]:hover,.informed-action>ul>li>:focus,.informed-action>ul>li>:hover,.menu-panel>ul>[role=treeitem]:focus,.menu-panel>ul>[role=treeitem]:hover,.menu-panel>ul>li>[role=menuitem]:focus,.menu-panel>ul>li>[role=menuitem]:hover,.menu-panel>ul>li>[role=option]:focus,.menu-panel>ul>li>[role=option]:hover,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:focus,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:hover,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:focus,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:hover,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:focus,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:hover,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:focus,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:hover,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:focus,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:hover,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:focus,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:hover,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:focus,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:hover,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:focus,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:hover{background-color:var(--token-color-surface-strong)}.type-sort.popover-select label>::before{position:relative;width:16px;height:16px}.type-sort.popover-select label>::after{top:0!important}.consul-intention-action-warn-modal button.dangerous,.copy-button button,.popover-select label>*,.topology-notices button,.type-sort.popover-select label>*{position:relative}.consul-intention-action-warn-modal button.dangerous .progress.indeterminate,.copy-button button .progress.indeterminate,.popover-select label>* .progress.indeterminate,.topology-notices button .progress.indeterminate{position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px}.consul-intention-action-warn-modal button.dangerous:disabled .progress+*,.copy-button button:disabled .progress+*,.popover-select label>:disabled .progress+*,.topology-notices button:disabled .progress+*{visibility:hidden}.consul-intention-action-warn-modal button.dangerous:empty,.copy-button button:empty,.popover-select label>:empty,.topology-notices button:empty{padding-right:0!important;padding-left:18px!important;margin-right:5px}.consul-intention-action-warn-modal button.dangerous:empty::before,.copy-button button:empty::before,.popover-select label>:empty::before,.topology-notices button:empty::before{left:1px}.consul-intention-action-warn-modal button.dangerous:not(:empty),.copy-button button:not(:empty),.popover-select label>:not(:empty),.topology-notices button:not(:empty){display:inline-flex;text-align:center;justify-content:center;align-items:center;padding:calc(.5em - 1px) calc(2.2em - 1px);min-width:100px}.consul-intention-action-warn-modal button.dangerous:not(:last-child),.copy-button button:not(:last-child),.popover-select label>:not(:last-child),.topology-notices button:not(:last-child){margin-right:8px}.app-view>header .actions a{padding-top:calc(.4em - 1px)!important;padding-bottom:calc(.4em - 1px)!important}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{padding:.9em 1em;text-align:center;display:inline-block;box-sizing:border-box}.type-sort.popover-select label>*{height:35px!important}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card{border:var(--decor-border-100);border-radius:var(--decor-radius-100);background-color:var(--token-color-surface-faint);display:block;position:relative}.discovery-chain .resolver-card>section,.discovery-chain .resolver-card>ul>li,.discovery-chain .route-card>section,.discovery-chain .route-card>ul>li,.discovery-chain .splitter-card>section,.discovery-chain .splitter-card>ul>li{border-top:var(--decor-border-100)}.discovery-chain .resolver-card,.discovery-chain .resolver-card>section,.discovery-chain .resolver-card>ul>li,.discovery-chain .route-card,.discovery-chain .route-card>section,.discovery-chain .route-card>ul>li,.discovery-chain .splitter-card,.discovery-chain .splitter-card>section,.discovery-chain .splitter-card>ul>li{border-color:var(--token-color-surface-interactive-active)}.discovery-chain .resolver-card:focus,.discovery-chain .resolver-card:hover,.discovery-chain .route-card:focus,.discovery-chain .route-card:hover,.discovery-chain .splitter-card:focus,.discovery-chain .splitter-card:hover{box-shadow:var(--token-surface-mid-box-shadow)}.discovery-chain .resolver-card>header,.discovery-chain .route-card>header,.discovery-chain .splitter-card>header{padding:10px}.discovery-chain .resolver-card>section,.discovery-chain .resolver-card>ul>li,.discovery-chain .route-card>section,.discovery-chain .route-card>ul>li,.discovery-chain .splitter-card>section,.discovery-chain .splitter-card>ul>li{padding:5px 10px}.discovery-chain .resolver-card ul,.discovery-chain .route-card ul,.discovery-chain .splitter-card ul{list-style-type:none;margin:0;padding:0}.checkbox-group label{margin-right:10px;white-space:nowrap}.checkbox-group span{display:inline-block;margin-left:10px;min-width:50px}.CodeMirror{max-width:1260px;min-height:300px;height:auto;padding-bottom:20px}.CodeMirror-scroll{overflow-x:hidden!important}.CodeMirror-lint-tooltip{background-color:#f9f9fa;border:1px solid var(--syntax-light-gray);border-radius:0;color:#212121;padding:7px 8px 9px}.cm-s-hashi.CodeMirror{width:100%;background-color:var(--token-color-hashicorp-brand)!important;color:#cfd2d1!important;border:none;font-family:var(--token-typography-font-stack-code);-webkit-font-smoothing:auto;line-height:1.4}.cm-s-hashi .CodeMirror-gutters{color:var(--syntax-dark-grey);background-color:var(--syntax-gutter-grey);border:none}.cm-s-hashi .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-hashi .CodeMirror-linenumber{color:#6d8a88}.cm-s-hashi.CodeMirror-focused div.CodeMirror-selected{background:#214283}.cm-s-hashi .CodeMirror-line::selection,.cm-s-hashi .CodeMirror-line>span::selection,.cm-s-hashi .CodeMirror-line>span>span::selection{background:#214283}.cm-s-hashi .CodeMirror-line::-moz-selection,.cm-s-hashi .CodeMirror-line>span::-moz-selection,.cm-s-hashi .CodeMirror-line>span>span::-moz-selection{background:var(--token-color-surface-interactive)}.cm-s-hashi span.cm-comment{color:var(--syntax-light-grey)}.cm-s-hashi span.cm-string,.cm-s-hashi span.cm-string-2{color:var(--syntax-packer)}.cm-s-hashi span.cm-number{color:var(--syntax-serf)}.cm-s-hashi span.cm-variable,.cm-s-hashi span.cm-variable-2{color:#9e84c5}.cm-s-hashi span.cm-def{color:var(--syntax-packer)}.cm-s-hashi span.cm-operator{color:var(--syntax-gray)}.cm-s-hashi span.cm-keyword{color:var(--syntax-yellow)}.cm-s-hashi span.cm-atom{color:var(--syntax-serf)}.cm-s-hashi span.cm-meta,.cm-s-hashi span.cm-tag{color:var(--syntax-packer)}.cm-s-hashi span.cm-error{color:var(--syntax-red)}.cm-s-hashi span.cm-attribute,.cm-s-hashi span.cm-qualifier{color:#9fca56}.cm-s-hashi span.cm-property{color:#9e84c5}.cm-s-hashi span.cm-builtin,.cm-s-hashi span.cm-variable-3{color:#9fca56}.cm-s-hashi .CodeMirror-activeline-background{background:#101213}.cm-s-hashi .CodeMirror-matchingbracket{text-decoration:underline;color:var(--token-color-surface-primary)!important}.readonly-codemirror .cm-s-hashi span{color:var(--syntax-light-grey)}.readonly-codemirror .cm-s-hashi span.cm-string,.readonly-codemirror .cm-s-hashi span.cm-string-2{color:var(--syntax-faded-gray)}.readonly-codemirror .cm-s-hashi span.cm-number{color:#a3acbc}.readonly-codemirror .cm-s-hashi span.cm-property,.tippy-box[data-theme~=tooltip]{color:var(--token-color-surface-primary)}.readonly-codemirror .cm-s-hashi span.cm-variable-2{color:var(--syntax-light-grey-blue)}.code-editor .toolbar-container{background:var(--token-color-surface-strong);background:linear-gradient(180deg,var(--token-color-surface-strong) 50%,var(--token-color-surface-interactive-active) 100%);border:1px solid var(--token-color-surface-interactive-active);border-bottom-color:var(--token-color-foreground-faint);border-top-color:var(--token-color-foreground-disabled)}.code-editor .toolbar-container .toolbar .title{color:var(--token-color-foreground-strong);padding:0 8px}.code-editor .toolbar-container .toolbar .toolbar-separator{border-right:1px solid var(--token-color-palette-neutral-300)}.code-editor .toolbar-container .ember-power-select-trigger{background-color:var(--token-color-surface-primary);color:var(--token-color-hashicorp-brand);border-radius:var(--decor-radius-100);border:var(--decor-border-100);border-color:var(--token-color-foreground-faint)}.code-editor{display:block;border:10px;overflow:hidden;position:relative;clear:both}.code-editor::after{position:absolute;bottom:0;width:100%;height:25px;background-color:var(--token-color-hashicorp-brand);content:"";display:block}.code-editor>pre{display:none}.code-editor .toolbar-container,.code-editor .toolbar-container .toolbar{align-items:center;justify-content:space-between;display:flex}.code-editor .toolbar-container{position:relative;margin-top:4px;height:44px}.code-editor .toolbar-container .toolbar{flex:1;white-space:nowrap}.code-editor .toolbar-container .toolbar .toolbar-separator{height:32px;margin:0 4px;width:0}.code-editor .toolbar-container .toolbar .tools{display:flex;flex-direction:row;margin:0 10px;align-items:center}.code-editor .toolbar-container .toolbar .tools .copy-button{margin-left:10px}.code-editor .toolbar-container .ember-basic-dropdown-trigger{margin:0 8px;width:120px;height:32px;display:flex;align-items:center;flex-direction:row}.consul-exposed-path-list>ul>li,.consul-lock-session-list ul>li:not(:first-child),.consul-upstream-instance-list li,.list-collection>ul>li:not(:first-child){display:grid;grid-template-columns:1fr auto;grid-template-rows:50% 50%;grid-template-areas:"header actions" "detail actions"}.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.header,.list-collection>ul>li:not(:first-child)>.header{grid-area:header;align-self:start}.consul-exposed-path-list>ul>li>.detail,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-upstream-instance-list li>.detail,.list-collection>ul>li:not(:first-child)>.detail{grid-area:detail;align-self:end}.consul-exposed-path-list>ul>li>.detail *,.consul-lock-session-list ul>li:not(:first-child)>.detail *,.consul-upstream-instance-list li>.detail *,.list-collection>ul>li:not(:first-child)>.detail *{flex-wrap:nowrap!important}.consul-exposed-path-list>ul>li>.actions,.consul-lock-session-list ul>li:not(:first-child)>.actions,.consul-upstream-instance-list li>.actions,.list-collection>ul>li:not(:first-child)>.actions{grid-area:actions;display:inline-flex}.consul-nspace-list>ul>li:not(:first-child) dt,.consul-policy-list>ul li:not(:first-child) dl:not(.datacenter) dt,.consul-role-list>ul>li:not(:first-child) dt,.consul-service-instance-list .port dt,.consul-service-instance-list .port dt::before,.consul-token-list>ul>li:not(:first-child) dt{display:none}.consul-exposed-path-list>ul>li>.header:nth-last-child(2),.consul-lock-session-list ul>li:not(:first-child)>.header:nth-last-child(2),.consul-upstream-instance-list li>.header:nth-last-child(2),.list-collection>ul>li:not(:first-child)>.header:nth-last-child(2){grid-column-start:header;grid-column-end:actions}.consul-exposed-path-list>ul>li>.detail:last-child,.consul-lock-session-list ul>li:not(:first-child)>.detail:last-child,.consul-upstream-instance-list li>.detail:last-child,.list-collection>ul>li:not(:first-child)>.detail:last-child{grid-column-start:detail;grid-column-end:actions}.consul-nspace-list>ul>li:not(:first-child) dt+dd,.consul-policy-list>ul li:not(:first-child) dl:not(.datacenter) dt+dd,.consul-role-list>ul>li:not(:first-child) dt+dd,.consul-token-list>ul>li:not(:first-child) dt+dd{margin-left:0!important}.consul-policy-list dl.datacenter dt,.consul-service-list li>div:first-child>dl:first-child dd{margin-top:1px}.consul-service-instance-list .detail,.consul-service-list .detail{overflow-x:visible!important}.consul-intention-permission-list>ul{border-top:1px solid var(--token-color-surface-interactive-active)}.consul-service-instance-list .port .copy-button{margin-right:0}.consul-exposed-path-list>ul>li .copy-button,.consul-lock-session-list ul>li:not(:first-child) .copy-button,.consul-upstream-instance-list li .copy-button,.list-collection>ul>li:not(:first-child) .copy-button{display:inline-flex}.consul-exposed-path-list>ul>li>.header .copy-button,.consul-lock-session-list ul>li:not(:first-child)>.header .copy-button,.consul-upstream-instance-list li>.header .copy-button,.list-collection>ul>li:not(:first-child)>.header .copy-button{margin-left:4px}.consul-exposed-path-list>ul>li>.detail .copy-button,.consul-lock-session-list ul>li:not(:first-child)>.detail .copy-button,.consul-upstream-instance-list li>.detail .copy-button,.list-collection>ul>li:not(:first-child)>.detail .copy-button{margin-top:2px}.consul-exposed-path-list>ul>li .copy-button button,.consul-lock-session-list ul>li:not(:first-child) .copy-button button,.consul-upstream-instance-list li .copy-button button,.list-collection>ul>li:not(:first-child) .copy-button button{padding:0!important;margin:0!important}.consul-exposed-path-list>ul>li>.header .copy-button button,.consul-lock-session-list ul>li:not(:first-child)>.header .copy-button button,.consul-upstream-instance-list li>.header .copy-button button,.list-collection>ul>li:not(:first-child)>.header .copy-button button{display:none}.consul-exposed-path-list>ul>li>.header:hover .copy-button button,.consul-lock-session-list ul>li:not(:first-child)>.header:hover .copy-button button,.consul-upstream-instance-list li>.header:hover .copy-button button,.list-collection>ul>li:not(:first-child)>.header:hover .copy-button button{display:block}.consul-exposed-path-list>ul>li .copy-button button:hover,.consul-lock-session-list ul>li:not(:first-child) .copy-button button:hover,.consul-upstream-instance-list li .copy-button button:hover,.list-collection>ul>li:not(:first-child) .copy-button button:hover{background-color:transparent!important}.consul-exposed-path-list>ul>li>.detail>.consul-external-source:first-child,.consul-exposed-path-list>ul>li>.detail>.consul-kind:first-child,.consul-lock-session-list ul>li:not(:first-child)>.detail>.consul-external-source:first-child,.consul-lock-session-list ul>li:not(:first-child)>.detail>.consul-kind:first-child,.consul-upstream-instance-list li>.detail>.consul-external-source:first-child,.consul-upstream-instance-list li>.detail>.consul-kind:first-child,.list-collection>ul>li:not(:first-child)>.detail>.consul-external-source:first-child,.list-collection>ul>li:not(:first-child)>.detail>.consul-kind:first-child{margin-left:-5px}.consul-exposed-path-list>ul>li>.detail .policy-management::before,.consul-exposed-path-list>ul>li>.detail .policy::before,.consul-exposed-path-list>ul>li>.detail .role::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy-management::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .role::before,.consul-upstream-instance-list li>.detail .policy-management::before,.consul-upstream-instance-list li>.detail .policy::before,.consul-upstream-instance-list li>.detail .role::before,.list-collection>ul>li:not(:first-child)>.detail .policy-management::before,.list-collection>ul>li:not(:first-child)>.detail .policy::before,.list-collection>ul>li:not(:first-child)>.detail .role::before{margin-right:3px}table div.with-confirmation.confirming{background-color:var(--token-color-surface-primary)}div.with-confirmation p{margin-right:12px;padding-left:12px;margin-bottom:0!important}div.with-confirmation{justify-content:end;width:100%;display:flex;align-items:center}table td>div.with-confirmation.confirming{position:absolute;right:0}@media (max-width:420px){div.with-confirmation{float:none;margin-top:1em;display:block}div.with-confirmation p{margin-bottom:1em}}.copy-button button{color:var(--token-color-foreground-action);--icon-color:transparent;min-height:17px}.copy-button button::after{--icon-color:var(--token-color-surface-strong)}.copy-button button:focus,.copy-button button:hover:not(:disabled):not(:active){color:var(--token-color-foreground-action);--icon-color:var(--token-color-surface-strong)}.copy-button button:hover::before{--icon-color:var(--token-color-foreground-action)}.copy-button button:active{--icon-color:var(--token-color-surface-interactive-active)}.copy-button button:empty{padding:0!important;margin-right:0;top:-1px}.copy-button button:empty::after{content:"";display:none;position:absolute;top:-2px;left:-3px;width:20px;height:22px}.copy-button button:empty:hover::after{display:block}.copy-button button:empty::before{position:relative;z-index:1}.copy-button button:not(:empty)::before{margin-right:4px}.consul-bucket-list .copy-button,.consul-exposed-path-list>ul>li>.detail dl .copy-button,.consul-instance-checks .copy-button,.consul-lock-session-list dl .copy-button,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .copy-button,.consul-upstream-instance-list dl .copy-button,.list-collection>ul>li:not(:first-child)>.detail dl .copy-button,.tag-list .copy-button,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .copy-button,section[data-route="dc.show.license"] .validity dl .copy-button,td.tags .copy-button{margin-top:0!important}.consul-bucket-list .copy-btn,.consul-exposed-path-list>ul>li>.detail dl .copy-btn,.consul-instance-checks .copy-btn,.consul-lock-session-list dl .copy-btn,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .copy-btn,.consul-upstream-instance-list dl .copy-btn,.list-collection>ul>li:not(:first-child)>.detail dl .copy-btn,.tag-list .copy-btn,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .copy-btn,section[data-route="dc.show.license"] .validity dl .copy-btn,td.tags .copy-btn{top:0!important}.consul-bucket-list .copy-btn:empty::before,.consul-exposed-path-list>ul>li>.detail dl .copy-btn:empty::before,.consul-instance-checks .copy-btn:empty::before,.consul-lock-session-list dl .copy-btn:empty::before,.consul-upstream-instance-list dl .copy-btn:empty::before,.list-collection>ul>li:not(:first-child)>.detail dl .copy-btn:empty::before,.tag-list .copy-btn:empty::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .copy-btn:empty::before,section[data-route="dc.show.license"] .validity dl .copy-btn:empty::before,td.tags .copy-btn:empty::before{left:0!important}.definition-table>dl{display:grid;grid-template-columns:140px auto;grid-gap:.4em 20px;margin-bottom:1.4em}.disclosure-menu{position:relative}.disclosure-menu [aria-expanded]~*{overflow-y:auto!important;will-change:scrollPosition}.more-popover-menu>[type=checkbox],.more-popover-menu>[type=checkbox]~:not(.animating):not(label),.popover-menu>[type=checkbox],.popover-menu>[type=checkbox]~:not(.animating):not(label),table.has-actions tr>.actions>[type=checkbox],table.has-actions tr>.actions>[type=checkbox]~:not(.animating):not(label),table.with-details tr>.actions>[type=checkbox],table.with-details tr>.actions>[type=checkbox]~:not(.animating):not(label){display:none}.more-popover-menu>[type=checkbox]:checked~:not(label),.popover-menu>[type=checkbox]:checked~:not(label),table.has-actions tr>.actions>[type=checkbox]:checked~:not(label),table.with-details tr>.actions>[type=checkbox]:checked~:not(label){display:block}table.dom-recycling{position:relative}table.dom-recycling tr>*{overflow:hidden}.list-collection-scroll-virtual>ul,table.dom-recycling tbody{overflow-x:hidden!important}table.dom-recycling dd{flex-wrap:nowrap}table.dom-recycling dd>*{margin-bottom:0}.empty-state,.empty-state>div{display:flex;flex-direction:column}.empty-state header :first-child{padding:0;margin:0}.empty-state{margin-top:0!important;padding-bottom:2.8em;background-color:var(--token-color-surface-faint)}.empty-state>*{width:370px;margin:0 auto}.empty-state button{margin:0 auto;display:inline}.empty-state header :first-child{margin-bottom:-3px;border-bottom:none}.empty-state header{margin-top:1.8em;margin-bottom:.5em}.empty-state>ul{display:flex;justify-content:space-between;margin-top:1em}.empty-state>ul>li>*,.empty-state>ul>li>label>button{display:inline-flex;align-items:center}.empty-state>div:only-child{padding:50px 0 10px;text-align:center}.empty-state header::before{font-size:2.6em;position:relative;top:-3px;float:left;margin-right:10px}.oidc-select button.reset,.type-dialog{float:right}.empty-state>ul>li>::before,.empty-state>ul>li>label>button::before{margin-top:-1px;margin-right:.5em}.empty-state li[class*=-link]>::after{margin-left:5px}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup]{border:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300);border-radius:var(--decor-radius-100)}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]:checked+*,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]:focus+*,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]:hover+*{box-shadow:var(--token-elevation-high-box-shadow);background-color:var(--token-color-surface-primary)}@media (min-width:996px){html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup]{display:flex}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label{flex-grow:1}}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]{display:none}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] .type-password,.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select,.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text,.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label textarea,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] form button+em,.oidc-select label,.oidc-select label textarea,.oidc-select label>em,.oidc-select label>span,.type-toggle,.type-toggle textarea,.type-toggle>em,.type-toggle>span,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label span,main .type-password,main .type-password textarea,main .type-password>em,main .type-password>span,main .type-select,main .type-select textarea,main .type-select>em,main .type-select>span,main .type-text,main .type-text textarea,main .type-text>em,main .type-text>span,main form button+em,span.label{display:block}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup],html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label span{height:100%}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label span{padding:5px 14px}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.type-toggle [type=password],.type-toggle [type=text],.type-toggle textarea,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-text [type=password],main .type-text [type=text],main .type-text textarea{-moz-appearance:none;-webkit-appearance:none;box-shadow:var(--token-surface-inset-box-shadow);border-radius:var(--decor-radius-100);border:var(--decor-border-100);outline:0}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:-moz-read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:-moz-read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:-moz-read-only,.modal-dialog [role=document] .type-password [type=password]:-moz-read-only,.modal-dialog [role=document] .type-password [type=text]:-moz-read-only,.modal-dialog [role=document] .type-password textarea:-moz-read-only,.modal-dialog [role=document] .type-select [type=password]:-moz-read-only,.modal-dialog [role=document] .type-select [type=text]:-moz-read-only,.modal-dialog [role=document] .type-select textarea:-moz-read-only,.modal-dialog [role=document] .type-text [type=password]:-moz-read-only,.modal-dialog [role=document] .type-text [type=text]:-moz-read-only,.modal-dialog [role=document] .type-text textarea:-moz-read-only,.modal-dialog [role=document] [role=radiogroup] label [type=password]:-moz-read-only,.modal-dialog [role=document] [role=radiogroup] label [type=text]:-moz-read-only,.modal-dialog [role=document] [role=radiogroup] label textarea:-moz-read-only,.oidc-select label [type=password]:-moz-read-only,.oidc-select label [type=text]:-moz-read-only,.oidc-select label textarea:-moz-read-only,.type-toggle [type=password]:-moz-read-only,.type-toggle [type=text]:-moz-read-only,.type-toggle textarea:-moz-read-only,main .type-password [type=password]:-moz-read-only,main .type-password [type=text]:-moz-read-only,main .type-password textarea:-moz-read-only,main .type-select [type=password]:-moz-read-only,main .type-select [type=text]:-moz-read-only,main .type-select textarea:-moz-read-only,main .type-text [type=password]:-moz-read-only,main .type-text [type=text]:-moz-read-only,main .type-text textarea:-moz-read-only{cursor:not-allowed}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:disabled,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:disabled,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:disabled,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:read-only,.modal-dialog [role=document] .type-password [type=password]:disabled,.modal-dialog [role=document] .type-password [type=password]:read-only,.modal-dialog [role=document] .type-password [type=text]:disabled,.modal-dialog [role=document] .type-password [type=text]:read-only,.modal-dialog [role=document] .type-password textarea:disabled,.modal-dialog [role=document] .type-password textarea:read-only,.modal-dialog [role=document] .type-select [type=password]:disabled,.modal-dialog [role=document] .type-select [type=password]:read-only,.modal-dialog [role=document] .type-select [type=text]:disabled,.modal-dialog [role=document] .type-select [type=text]:read-only,.modal-dialog [role=document] .type-select textarea:disabled,.modal-dialog [role=document] .type-select textarea:read-only,.modal-dialog [role=document] .type-text [type=password]:disabled,.modal-dialog [role=document] .type-text [type=password]:read-only,.modal-dialog [role=document] .type-text [type=text]:disabled,.modal-dialog [role=document] .type-text [type=text]:read-only,.modal-dialog [role=document] .type-text textarea:disabled,.modal-dialog [role=document] .type-text textarea:read-only,.modal-dialog [role=document] [role=radiogroup] label [type=password]:disabled,.modal-dialog [role=document] [role=radiogroup] label [type=password]:read-only,.modal-dialog [role=document] [role=radiogroup] label [type=text]:disabled,.modal-dialog [role=document] [role=radiogroup] label [type=text]:read-only,.modal-dialog [role=document] [role=radiogroup] label textarea:disabled,.modal-dialog [role=document] [role=radiogroup] label textarea:read-only,.oidc-select label [type=password]:disabled,.oidc-select label [type=password]:read-only,.oidc-select label [type=text]:disabled,.oidc-select label [type=text]:read-only,.oidc-select label textarea:disabled,.oidc-select label textarea:read-only,.type-toggle [type=password]:disabled,.type-toggle [type=password]:read-only,.type-toggle [type=text]:disabled,.type-toggle [type=text]:read-only,.type-toggle textarea:disabled,.type-toggle textarea:read-only,main .type-password [type=password]:disabled,main .type-password [type=password]:read-only,main .type-password [type=text]:disabled,main .type-password [type=text]:read-only,main .type-password textarea:disabled,main .type-password textarea:read-only,main .type-select [type=password]:disabled,main .type-select [type=password]:read-only,main .type-select [type=text]:disabled,main .type-select [type=text]:read-only,main .type-select textarea:disabled,main .type-select textarea:read-only,main .type-text [type=password]:disabled,main .type-text [type=password]:read-only,main .type-text [type=text]:disabled,main .type-text [type=text]:read-only,main .type-text textarea:disabled,main .type-text textarea:read-only,textarea:disabled+.CodeMirror{cursor:not-allowed}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]::-moz-placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]::-moz-placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea::-moz-placeholder,.modal-dialog [role=document] .type-password [type=password]::-moz-placeholder,.modal-dialog [role=document] .type-password [type=text]::-moz-placeholder,.modal-dialog [role=document] .type-password textarea::-moz-placeholder,.modal-dialog [role=document] .type-select [type=password]::-moz-placeholder,.modal-dialog [role=document] .type-select [type=text]::-moz-placeholder,.modal-dialog [role=document] .type-select textarea::-moz-placeholder,.modal-dialog [role=document] .type-text [type=password]::-moz-placeholder,.modal-dialog [role=document] .type-text [type=text]::-moz-placeholder,.modal-dialog [role=document] .type-text textarea::-moz-placeholder,.modal-dialog [role=document] [role=radiogroup] label [type=password]::-moz-placeholder,.modal-dialog [role=document] [role=radiogroup] label [type=text]::-moz-placeholder,.modal-dialog [role=document] [role=radiogroup] label textarea::-moz-placeholder,.oidc-select label [type=password]::-moz-placeholder,.oidc-select label [type=text]::-moz-placeholder,.oidc-select label textarea::-moz-placeholder,.type-toggle [type=password]::-moz-placeholder,.type-toggle [type=text]::-moz-placeholder,.type-toggle textarea::-moz-placeholder,main .type-password [type=password]::-moz-placeholder,main .type-password [type=text]::-moz-placeholder,main .type-password textarea::-moz-placeholder,main .type-select [type=password]::-moz-placeholder,main .type-select [type=text]::-moz-placeholder,main .type-select textarea::-moz-placeholder,main .type-text [type=password]::-moz-placeholder,main .type-text [type=text]::-moz-placeholder,main .type-text textarea::-moz-placeholder{color:var(--token-color-foreground-disabled)}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]::placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]::placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea::placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.modal-dialog [role=document] .type-password [type=password]::placeholder,.modal-dialog [role=document] .type-password [type=text]::placeholder,.modal-dialog [role=document] .type-password textarea::placeholder,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-select [type=password]::placeholder,.modal-dialog [role=document] .type-select [type=text]::placeholder,.modal-dialog [role=document] .type-select textarea::placeholder,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-text [type=password]::placeholder,.modal-dialog [role=document] .type-text [type=text]::placeholder,.modal-dialog [role=document] .type-text textarea::placeholder,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] [role=radiogroup] label [type=password]::placeholder,.modal-dialog [role=document] [role=radiogroup] label [type=text]::placeholder,.modal-dialog [role=document] [role=radiogroup] label textarea::placeholder,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] form fieldset>p,.oidc-select label [type=password]::placeholder,.oidc-select label [type=text]::placeholder,.oidc-select label textarea::placeholder,.oidc-select label>em,.type-toggle [type=password]::placeholder,.type-toggle [type=text]::placeholder,.type-toggle textarea::placeholder,.type-toggle>em,main .type-password [type=password]::placeholder,main .type-password [type=text]::placeholder,main .type-password textarea::placeholder,main .type-password>em,main .type-select [type=password]::placeholder,main .type-select [type=text]::placeholder,main .type-select textarea::placeholder,main .type-select>em,main .type-text [type=password]::placeholder,main .type-text [type=text]::placeholder,main .type-text textarea::placeholder,main .type-text>em,main form button+em,main form fieldset>p{color:var(--token-color-foreground-disabled)}.has-error>input,.has-error>textarea{border-color:var(--decor-error,var(--token-color-foreground-critical))!important}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.type-toggle [type=password],.type-toggle [type=text],.type-toggle textarea,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-text [type=password],main .type-text [type=text],main .type-text textarea{color:var(--token-color-foreground-faint);border-color:var(--token-color-palette-neutral-300)}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:hover,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:hover,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:hover,.modal-dialog [role=document] .type-password [type=password]:hover,.modal-dialog [role=document] .type-password [type=text]:hover,.modal-dialog [role=document] .type-password textarea:hover,.modal-dialog [role=document] .type-select [type=password]:hover,.modal-dialog [role=document] .type-select [type=text]:hover,.modal-dialog [role=document] .type-select textarea:hover,.modal-dialog [role=document] .type-text [type=password]:hover,.modal-dialog [role=document] .type-text [type=text]:hover,.modal-dialog [role=document] .type-text textarea:hover,.modal-dialog [role=document] [role=radiogroup] label [type=password]:hover,.modal-dialog [role=document] [role=radiogroup] label [type=text]:hover,.modal-dialog [role=document] [role=radiogroup] label textarea:hover,.oidc-select label [type=password]:hover,.oidc-select label [type=text]:hover,.oidc-select label textarea:hover,.type-toggle [type=password]:hover,.type-toggle [type=text]:hover,.type-toggle textarea:hover,main .type-password [type=password]:hover,main .type-password [type=text]:hover,main .type-password textarea:hover,main .type-select [type=password]:hover,main .type-select [type=text]:hover,main .type-select textarea:hover,main .type-text [type=password]:hover,main .type-text [type=text]:hover,main .type-text textarea:hover{border-color:var(--token-color-foreground-faint)}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:focus,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:focus,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:focus,.modal-dialog [role=document] .type-password [type=password]:focus,.modal-dialog [role=document] .type-password [type=text]:focus,.modal-dialog [role=document] .type-password textarea:focus,.modal-dialog [role=document] .type-select [type=password]:focus,.modal-dialog [role=document] .type-select [type=text]:focus,.modal-dialog [role=document] .type-select textarea:focus,.modal-dialog [role=document] .type-text [type=password]:focus,.modal-dialog [role=document] .type-text [type=text]:focus,.modal-dialog [role=document] .type-text textarea:focus,.modal-dialog [role=document] [role=radiogroup] label [type=password]:focus,.modal-dialog [role=document] [role=radiogroup] label [type=text]:focus,.modal-dialog [role=document] [role=radiogroup] label textarea:focus,.oidc-select label [type=password]:focus,.oidc-select label [type=text]:focus,.oidc-select label textarea:focus,.type-toggle [type=password]:focus,.type-toggle [type=text]:focus,.type-toggle textarea:focus,main .type-password [type=password]:focus,main .type-password [type=text]:focus,main .type-password textarea:focus,main .type-select [type=password]:focus,main .type-select [type=text]:focus,main .type-select textarea:focus,main .type-text [type=password]:focus,main .type-text [type=text]:focus,main .type-text textarea:focus{border-color:var(--typo-action,var(--token-color-foreground-action))}.app-view>div form:not(.filter-bar) [role=radiogroup] label a,.modal-dialog [role=document] .type-password a,.modal-dialog [role=document] .type-select a,.modal-dialog [role=document] .type-text a,.modal-dialog [role=document] [role=radiogroup] label a,.oidc-select label a,.type-toggle a,main .type-password a,main .type-select a,main .type-text a{display:inline}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.oidc-select label [type=password],.oidc-select label [type=text],.type-toggle [type=password],.type-toggle [type=text],main .type-password [type=password],main .type-password [type=text],main .type-select [type=password],main .type-select [type=text],main .type-text [type=password],main .type-text [type=text]{display:inline-flex;justify-content:flex-start;max-width:100%;width:100%;height:0;padding:17px 13px}.consul-exposed-path-list>ul>li>.header dt,.consul-lock-session-list ul>li:not(:first-child)>.header dt,.consul-upstream-instance-list li>.header dt,.list-collection>ul>li:not(:first-child)>.header dt,.type-toggle input{display:none}.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label textarea,.oidc-select label textarea,.type-toggle textarea,main .type-password textarea,main .type-select textarea,main .type-text textarea{resize:vertical;max-width:100%;min-width:100%;min-height:70px;padding:6px 13px}.app-view>div form:not(.filter-bar) [role=radiogroup],.app-view>div form:not(.filter-bar) [role=radiogroup] label,.checkbox-group,.modal-dialog [role=document] .type-password,.modal-dialog [role=document] .type-select,.modal-dialog [role=document] .type-text,.modal-dialog [role=document] [role=radiogroup],.modal-dialog [role=document] [role=radiogroup] label,.modal-dialog [role=document] form table,.oidc-select label,.type-toggle,main .type-password,main .type-select,main .type-text,main form table{margin-bottom:1.4em}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>span,.oidc-select label>span,.type-toggle>span,main .type-password>span,main .type-select>span,main .type-text>span,span.label{color:var(--typo-contrast,inherit);margin-bottom:.3em}.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] form button+em,.oidc-select label>em,.type-toggle>em,main .type-password>em,main .type-select>em,main .type-text>em,main form button+em{margin-top:2px}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span+em,.modal-dialog [role=document] .type-password>span+em,.modal-dialog [role=document] .type-select>span+em,.modal-dialog [role=document] .type-text>span+em,.modal-dialog [role=document] [role=radiogroup] label>span+em,.oidc-select label>span+em,.type-toggle>span+em,main .type-password>span+em,main .type-select>span+em,main .type-text>span+em,span.label+em{margin-top:-.5em;margin-bottom:.5em}.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] label.type-text>span,main .type-password>span,main .type-select>span,main label.type-text>span{line-height:2.2em}.type-toggle+.checkbox-group{margin-top:-1em}.consul-exposed-path-list>ul>li,.consul-intention-permission-header-list>ul>li,.consul-intention-permission-list>ul>li,.consul-lock-session-list ul>li:not(:first-child),.consul-upstream-instance-list li,.list-collection>ul>li:not(:first-child){list-style-type:none;border:var(--decor-border-100);border-top-color:transparent;border-bottom-color:var(--token-color-surface-interactive-active);border-right-color:transparent;border-left-color:transparent;--horizontal-padding:12px;--vertical-padding:10px;padding:var(--vertical-padding) 0;padding-left:var(--horizontal-padding)}.consul-auth-method-list>ul>li:active:not(:first-child),.consul-auth-method-list>ul>li:focus:not(:first-child),.consul-auth-method-list>ul>li:hover:not(:first-child),.consul-exposed-path-list>ul>li.linkable:active,.consul-exposed-path-list>ul>li.linkable:focus,.consul-exposed-path-list>ul>li.linkable:hover,.consul-intention-permission-list:not(.readonly)>ul>li:active,.consul-intention-permission-list:not(.readonly)>ul>li:focus,.consul-intention-permission-list:not(.readonly)>ul>li:hover,.consul-lock-session-list ul>li.linkable:active:not(:first-child),.consul-lock-session-list ul>li.linkable:focus:not(:first-child),.consul-lock-session-list ul>li.linkable:hover:not(:first-child),.consul-node-list>ul>li:active:not(:first-child),.consul-node-list>ul>li:focus:not(:first-child),.consul-node-list>ul>li:hover:not(:first-child),.consul-policy-list>ul>li:active:not(:first-child),.consul-policy-list>ul>li:focus:not(:first-child),.consul-policy-list>ul>li:hover:not(:first-child),.consul-role-list>ul>li:active:not(:first-child),.consul-role-list>ul>li:focus:not(:first-child),.consul-role-list>ul>li:hover:not(:first-child),.consul-service-instance-list>ul>li:active:not(:first-child),.consul-service-instance-list>ul>li:focus:not(:first-child),.consul-service-instance-list>ul>li:hover:not(:first-child),.consul-token-list>ul>li:active:not(:first-child),.consul-token-list>ul>li:focus:not(:first-child),.consul-token-list>ul>li:hover:not(:first-child),.consul-upstream-instance-list li.linkable:active,.consul-upstream-instance-list li.linkable:focus,.consul-upstream-instance-list li.linkable:hover,.list-collection>ul>li.linkable:active:not(:first-child),.list-collection>ul>li.linkable:focus:not(:first-child),.list-collection>ul>li.linkable:hover:not(:first-child){border-color:var(--token-color-surface-interactive-active);box-shadow:var(--token-elevation-high-box-shadow);border-top-color:transparent;cursor:pointer}.radio-card,.tippy-box{box-shadow:var(--token-surface-mid-box-shadow)}.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.header,.list-collection>ul>li:not(:first-child)>.header{color:var(--token-color-hashicorp-brand)}.consul-exposed-path-list>ul>li>.header *,.consul-lock-session-list ul>li:not(:first-child)>.header *,.consul-upstream-instance-list li>.header *,.list-collection>ul>li:not(:first-child)>.header *{color:inherit}.consul-exposed-path-list>ul>li>.detail,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-upstream-instance-list li>.detail,.list-collection>ul>li:not(:first-child)>.detail,.radio-card{color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul>li>.detail a,.consul-lock-session-list ul>li:not(:first-child)>.detail a,.consul-upstream-instance-list li>.detail a,.list-collection>ul>li:not(:first-child)>.detail a{color:inherit}.consul-exposed-path-list>ul>li>.detail a:hover,.consul-lock-session-list ul>li:not(:first-child)>.detail a:hover,.consul-upstream-instance-list li>.detail a:hover,.list-collection>ul>li:not(:first-child)>.detail a:hover{color:var(--token-color-foreground-action);text-decoration:underline}.consul-exposed-path-list>ul>li>.detail,.consul-exposed-path-list>ul>li>.header>dl:first-child,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-lock-session-list ul>li:not(:first-child)>.header>dl:first-child,.consul-upstream-instance-list li>.detail,.consul-upstream-instance-list li>.header>dl:first-child,.list-collection>ul>li:not(:first-child)>.detail,.list-collection>ul>li:not(:first-child)>.header>dl:first-child{margin-right:6px}.consul-exposed-path-list>ul>li>.header dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header dd::before,.consul-upstream-instance-list li>.header dd::before,.list-collection>ul>li:not(:first-child)>.header dd::before{font-size:.9em}.consul-exposed-path-list>ul>li>.detail,.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.detail,.consul-upstream-instance-list li>.header,.list-collection>ul>li:not(:first-child)>.detail,.list-collection>ul>li:not(:first-child)>.header{display:flex;flex-wrap:nowrap;overflow-x:hidden}.consul-exposed-path-list>ul>li>.detail *,.consul-exposed-path-list>ul>li>.header *,.consul-lock-session-list ul>li:not(:first-child)>.detail *,.consul-lock-session-list ul>li:not(:first-child)>.header *,.consul-upstream-instance-list li>.detail *,.consul-upstream-instance-list li>.header *,.list-collection>ul>li:not(:first-child)>.detail *,.list-collection>ul>li:not(:first-child)>.header *{white-space:nowrap;flex-wrap:nowrap}.consul-exposed-path-list>ul>li>.detail>span,.consul-lock-session-list ul>li:not(:first-child)>.detail>span,.consul-upstream-instance-list li>.detail>span,.list-collection>ul>li:not(:first-child)>.detail>span{margin-right:18px}.consul-intention-permission-header-list>ul>li,.consul-intention-permission-list>ul>li{padding-top:0!important;padding-bottom:0!important}.consul-intention-permission-header-list>ul>li .detail,.consul-intention-permission-list>ul>li .detail{grid-row-start:header!important;grid-row-end:detail!important;align-self:center!important;padding:5px 0}.consul-intention-permission-header-list>ul>li .popover-menu>[type=checkbox]+label,.consul-intention-permission-list>ul>li .popover-menu>[type=checkbox]+label{padding:0}.consul-intention-permission-header-list>ul>li .popover-menu>[type=checkbox]+label+div:not(.above),.consul-intention-permission-list>ul>li .popover-menu>[type=checkbox]+label+div:not(.above){top:30px}.has-error>strong{font-style:normal;font-weight:var(--token-typography-font-weight-regular);color:inherit;color:var(--token-color-foreground-critical);position:relative;padding-left:20px}.has-error>strong::before{color:var(--token-color-foreground-critical);position:absolute;top:50%;left:0;margin-top:-8px}.more-popover-menu .popover-menu>[type=checkbox]+label,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label,table.with-details tr>.actions .popover-menu>[type=checkbox]+label{padding:7px}.more-popover-menu .popover-menu>[type=checkbox]+label>*,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>*,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>*{background-color:transparent;border-radius:var(--decor-radius-100);width:30px;height:30px;font-size:0}.more-popover-menu .popover-menu>[type=checkbox]+label>:active,.more-popover-menu .popover-menu>[type=checkbox]+label>:focus,.more-popover-menu .popover-menu>[type=checkbox]+label>:hover,.radio-card>:first-child,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>:active,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>:focus,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>:hover,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>:active,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>:focus,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>:hover{background-color:var(--token-color-surface-strong)}.more-popover-menu .popover-menu>[type=checkbox]+label>::after,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>::after,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>::after{--icon-name:icon-more-horizontal;--icon-color:var(--token-color-foreground-strong);--icon-size:icon-300;content:"";position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.oidc-select [class$=-oidc-provider]::before{width:22px;height:22px;flex:0 0 auto;margin-right:10px}.oidc-select .ember-power-select-trigger,.oidc-select li{margin-bottom:1em}.informed-action header,.radio-card header{margin-bottom:.5em}.oidc-select .ember-power-select-trigger{width:100%}.radio-card{border:var(--decor-border-100);border-radius:var(--decor-radius-100);border-color:var(--token-color-surface-interactive-active);cursor:pointer;float:none!important;margin-right:0!important;display:flex!important}.checked.radio-card{border-color:var(--token-color-foreground-action)}.checked.radio-card>:first-child{background-color:var(--token-color-surface-action)}.radio-card header{color:var(--token-color-hashicorp-brand)}.consul-intention-fieldsets .radio-card>:last-child{padding-left:47px;position:relative}.consul-intention-fieldsets .radio-card>:last-child::before{position:absolute;left:14px;font-size:1rem}.radio-card>:first-child{padding:10px;display:grid;align-items:center;justify-items:center}.radio-card>:last-child{padding:18px}.consul-server-card,.disclosure-menu [aria-expanded]~*,.menu-panel,.more-popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div,section[data-route="dc.show.serverstatus"] .server-failure-tolerance,section[data-route="dc.show.license"] aside,table.has-actions tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div{--tone-border:var(--token-color-palette-neutral-300);border:var(--decor-border-100);border-radius:var(--decor-radius-200);box-shadow:var(--token-surface-high-box-shadow);color:var(--token-color-foreground-strong);background-color:var(--token-color-surface-primary);--padding-x:14px;--padding-y:14px;position:relative}.disclosure-menu [aria-expanded]~* [role=separator],.menu-panel [role=separator],.more-popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]{border-top:var(--decor-border-100);margin:0}.consul-server-card,.disclosure-menu [aria-expanded]~*,.disclosure-menu [aria-expanded]~* [role=separator],.menu-panel,.menu-panel [role=separator],.more-popover-menu>[type=checkbox]+label+div,.more-popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div [role=separator],section[data-route="dc.show.serverstatus"] .server-failure-tolerance,section[data-route="dc.show.license"] aside,table.has-actions tr>.actions>[type=checkbox]+label+div,table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]{border-color:var(--tone-border)}.paged-collection-scroll,[style*="--paged-row-height"]{overflow-y:auto!important;will-change:scrollPosition}[style*="--paged-start"]::before{content:"";display:block;height:var(--paged-start)}.consul-auth-method-type,.consul-external-source,.consul-health-check-list .health-check-output dd em,.consul-intention-list td strong,.consul-intention-permission-list strong,.consul-intention-search-bar li button span,.consul-kind,.consul-peer-search-bar li button span,.consul-server-card .health-status+dd,.consul-source,.consul-transparent-proxy,.discovery-chain .route-card>header ul li,.leader,.search-bar-status li:not(.remove-all),.topology-metrics-source-type,html[data-route^="dc.acls.index"] main td strong,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,span.policy-node-identity,span.policy-service-identity{border-radius:var(--decor-radius-100);display:inline-flex;position:relative;align-items:center;white-space:nowrap}.consul-auth-method-type::before,.consul-external-source::before,.consul-health-check-list .health-check-output dd em::before,.consul-intention-list td strong::before,.consul-intention-permission-list strong::before,.consul-intention-search-bar li button span::before,.consul-kind::before,.consul-peer-search-bar li button span::before,.consul-server-card .health-status+dd::before,.consul-source::before,.consul-transparent-proxy::before,.discovery-chain .route-card>header ul li::before,.leader::before,.search-bar-status li:not(.remove-all)::before,.topology-metrics-source-type::before,html[data-route^="dc.acls.index"] main td strong::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em::before,span.policy-node-identity::before,span.policy-service-identity::before{margin-right:4px;--icon-size:icon-300}.consul-auth-method-type,.consul-external-source,.consul-kind,.consul-server-card .health-status+dd,.consul-source,.consul-transparent-proxy,.leader,.search-bar-status li:not(.remove-all),.topology-metrics-source-type,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,span.policy-node-identity,span.policy-service-identity{padding:0 8px;--icon-size:icon-200}.consul-intention-permission-list strong,.consul-peer-search-bar li button span,.discovery-chain .route-card>header ul li,html[data-route^="dc.acls.index"] main td strong,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl{padding:1px 5px}.consul-intention-list td strong,.consul-intention-search-bar li button span{padding:4px 8px}span.policy-node-identity::before,span.policy-service-identity::before{vertical-align:unset}span.policy-node-identity::before{content:"Node Identity: "}span.policy-service-identity::before{content:"Service Identity: "}.more-popover-menu>[type=checkbox]+label>*,.popover-menu>[type=checkbox]+label>*,table.has-actions tr>.actions>[type=checkbox]+label>*,table.with-details tr>.actions>[type=checkbox]+label>*{cursor:pointer}.more-popover-menu>[type=checkbox]+label>::after,.popover-menu>[type=checkbox]+label>::after,table.has-actions tr>.actions>[type=checkbox]+label>::after,table.with-details tr>.actions>[type=checkbox]+label>::after{width:16px;height:16px;position:relative}.more-popover-menu,.popover-menu,table.has-actions tr>.actions,table.with-details tr>.actions{position:relative}.more-popover-menu>[type=checkbox]+label,.popover-menu>[type=checkbox]+label,table.has-actions tr>.actions>[type=checkbox]+label,table.with-details tr>.actions>[type=checkbox]+label{display:block}.more-popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div,table.has-actions tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div{min-width:192px}.more-popover-menu>[type=checkbox]+label+div:not(.above),.popover-menu>[type=checkbox]+label+div:not(.above),table.has-actions tr>.actions>[type=checkbox]+label+div:not(.above),table.with-details tr>.actions>[type=checkbox]+label+div:not(.above){top:38px}.more-popover-menu>[type=checkbox]+label+div:not(.left),.popover-menu>[type=checkbox]+label+div:not(.left),table.has-actions tr>.actions>[type=checkbox]+label+div:not(.left),table.with-details tr>.actions>[type=checkbox]+label+div:not(.left){right:5px}.popover-menu .menu-panel{position:absolute!important}.popover-select label{height:100%}.popover-select label>*{padding:0 8px!important;height:100%!important;justify-content:space-between!important;min-width:auto!important}.popover-select label>::after{margin-left:6px}.popover-select button::before{margin-right:10px}.popover-select .value-passing button::before{color:var(--token-color-foreground-success)}.popover-select .value-warning button::before{color:var(--token-color-foreground-warning)}.popover-select .value-critical button::before{color:var(--token-color-foreground-critical)}.popover-select .value-empty button::before{color:var(--token-color-foreground-disabled)}.popover-select .value-unknown button::before,.type-source.popover-select li.partition button::before{color:var(--token-color-foreground-faint)}.type-source.popover-select li.aws button{text-transform:uppercase}.progress.indeterminate{width:100%;display:flex;align-items:center;justify-content:center;--icon-size:icon-700;--icon-name:var(--icon-loading);--icon-color:var(--token-color-foreground-faint)}.progress.indeterminate::before{content:""}.app-view>div form:not(.filter-bar) [role=radiogroup],.modal-dialog [role=document] [role=radiogroup]{overflow:hidden;padding-left:1px}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label{float:left}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] [role=radiogroup] label>span{float:right;margin-left:1em}.app-view>div form:not(.filter-bar) [role=radiogroup] label:not(:last-child),.modal-dialog [role=document] [role=radiogroup] label:not(:last-child){margin-right:25px}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label>span{margin-bottom:0!important}.type-toggle label span{cursor:pointer}.type-toggle label span::after{border-radius:var(--decor-radius-full)}.type-toggle label span::before{border-radius:7px;left:0;width:24px;height:12px;margin-top:-5px}.type-negative.type-toggle{border:0}.app-view>header .title,.modal-dialog [role=document] table td,.modal-dialog [role=document] table th,main table td,main table th{border-bottom:var(--decor-border-100)}.type-toggle label span::after{background-color:var(--token-color-surface-primary);margin-top:-3px;width:8px;height:8px}.type-negative.type-toggle label input+span::before,.type-toggle label input:checked+span::before{background-color:var(--token-color-foreground-action)}.type-negative.type-toggle label input:checked+span::before,.type-toggle label span::before{background-color:var(--token-color-palette-neutral-300)}.type-toggle label{position:relative}.type-toggle label span{color:var(--token-color-foreground-strong);display:inline-block;padding-left:34px}.type-toggle label span::after,.type-toggle label span::before{position:absolute;display:block;content:"";top:50%}.type-negative.type-toggle label input+span::after,.type-toggle label input:checked+span::after{left:14px}.type-negative.type-toggle label input:checked+span::after,.type-toggle label span::after{left:2px}.consul-intention-list td.destination,.consul-intention-list td.source,.modal-dialog [role=document] table th,main table th{border-color:var(--token-color-palette-neutral-300)}.modal-dialog [role=document] table td,main table td{border-color:var(--token-color-palette-neutral-300);color:var(--token-color-foreground-faint);height:50px;vertical-align:middle}.modal-dialog [role=document] table td strong,.modal-dialog [role=document] table th,main table td strong,main table th{color:var(--token-color-foreground-faint)}.modal-dialog [role=document] table a,.tomography-graph .tick text,main table a{color:var(--token-color-foreground-strong)}.modal-dialog [role=document] table,main table{width:100%;border-collapse:collapse}table.dom-recycling tr{display:flex}table.dom-recycling tr>*{flex:1 1 auto;display:inline-flex;align-items:center}.modal-dialog [role=document] table th.actions input,main table th.actions input{display:none}.modal-dialog [role=document] table th.actions,main table th.actions{text-align:right}.modal-dialog [role=document] table td a,main table td a{display:block}.modal-dialog [role=document] table td.no-actions~.actions,main table td.no-actions~.actions{display:none}.modal-dialog [role=document] table td:not(.actions)>:only-child,main table td:not(.actions)>:only-child{overflow:hidden;text-overflow:ellipsis}.modal-dialog [role=document] table td:not(.actions)>*,main table td:not(.actions)>*{white-space:nowrap}.modal-dialog [role=document] table caption,main table caption{margin-bottom:.8em}.modal-dialog [role=document] table th,main table th{padding:.6em 0}.modal-dialog [role=document] table td a,.modal-dialog [role=document] table td:not(.actions),.modal-dialog [role=document] table th:not(.actions),main table td a,main table td:not(.actions),main table th:not(.actions){padding-right:.9em}.modal-dialog [role=document] table tbody td em,main table tbody td em{display:block;font-style:normal;font-weight:var(--token-typography-font-weight-regular);color:var(--token-color-foreground-faint)}table.has-actions tr>.actions,table.with-details tr>.actions{width:60px!important;overflow:visible}table.has-actions tr>.actions>[type=checkbox]+label,table.with-details tr>.actions>[type=checkbox]+label{position:absolute;right:5px}table.consul-metadata-list tbody tr{cursor:default}table.consul-metadata-list tbody tr:hover{box-shadow:none}.modal-dialog [role=document] table th span::after,main table th span::after{color:var(--token-color-foreground-faint);margin-left:4px}.modal-dialog [role=document] table tbody tr,main table tbody tr{cursor:pointer}.modal-dialog [role=document] table td:first-child,main table td:first-child{padding:0}.modal-dialog [role=document] table tbody tr:hover,main table tbody tr:hover{box-shadow:var(--token-elevation-high-box-shadow)}.modal-dialog [role=document] table td.folder::before,main table td.folder::before{background-color:var(--token-color-palette-neutral-300);margin-top:1px;margin-right:5px}@media (max-width:420px){.consul-intention-list tr>:nth-last-child(2),.modal-dialog [role=document] table tr>.actions,main table tr>.actions{display:none}}.voting-status-leader.consul-server-card .name{width:var(--tile-size,3rem);height:var(--tile-size,3rem)}.voting-status-leader.consul-server-card .name::before{display:block;content:"";width:100%;height:100%;border-radius:var(--decor-radius-250);border:var(--decor-border-100);background-image:linear-gradient(135deg,var(--token-color-consul-surface) 0,var(--token-color-consul-border) 100%);border-color:var(--token-color-border-faint)}.voting-status-leader.consul-server-card .name::after{content:"";position:absolute;top:calc(var(--tile-size,3rem)/ 4);left:calc(var(--tile-size,3rem)/ 4);--icon-name:icon-star-fill;--icon-size:icon-700;color:var(--token-color-consul-brand)}table.with-details td:only-child>div>label,table.with-details td>label{border-radius:var(--decor-radius-100);cursor:pointer;min-width:30px;min-height:30px;display:inline-flex;align-items:center;justify-content:center}table.with-details td:only-child>div>label:active,table.with-details td:only-child>div>label:focus,table.with-details td:only-child>div>label:hover,table.with-details td>label:active,table.with-details td>label:focus,table.with-details td>label:hover{background-color:var(--token-color-surface-strong)}table.dom-recycling tbody{top:33px!important;width:100%}table.dom-recycling caption~tbody{top:57px!important}table tr>:nth-last-child(2):first-child,table tr>:nth-last-child(2):first-child~*{width:50%}table tr>:nth-last-child(3):first-child,table tr>:nth-last-child(3):first-child~*{width:33.3333333333%}table tr>:nth-last-child(4):first-child,table tr>:nth-last-child(4):first-child~*{width:25%}table tr>:nth-last-child(5):first-child,table tr>:nth-last-child(5):first-child~*{width:20%}table.has-actions tr>:nth-last-child(2):first-child,table.has-actions tr>:nth-last-child(2):first-child~*{width:calc(100% - 60px)}table.has-actions tr>:nth-last-child(3):first-child,table.has-actions tr>:nth-last-child(3):first-child~*{width:calc(50% - 30px)}table.has-actions tr>:nth-last-child(4):first-child,table.has-actions tr>:nth-last-child(4):first-child~*{width:calc(33% - 20px)}table.has-actions tr>:nth-last-child(5):first-child,table.has-actions tr>:nth-last-child(5):first-child~*{width:calc(25% - 15px)}html[data-route^="dc.acls.policies"] [role=dialog] table tr>:not(last-child),html[data-route^="dc.acls.policies"] table tr>:not(last-child),html[data-route^="dc.acls.roles"] [role=dialog] table tr>:not(last-child),html[data-route^="dc.acls.roles"] main table.token-list tr>:not(last-child){width:120px}html[data-route^="dc.acls.policies"] table tr>:last-child,html[data-route^="dc.acls.roles"] [role=dialog] table tr>:last-child,html[data-route^="dc.acls.roles"] main table.token-list tr>:last-child{width:calc(100% - 240px)!important}table.with-details td:only-child{cursor:default;border:0}table.with-details td:only-child>div::before,table.with-details td:only-child>div>div,table.with-details td:only-child>div>label{background-color:var(--token-color-surface-primary)}table.with-details td:only-child>div>label::before{transform:rotate(180deg)}table.with-details td:only-child>div::before{background:var(--token-color-surface-interactive-active);content:"";display:block;height:1px;position:absolute;bottom:-20px;left:10px;width:calc(100% - 20px)}table.with-details tr>.actions{position:relative}table.with-details td:only-child>div>label,table.with-details td>label{pointer-events:auto;position:absolute;top:8px}table.with-details td:only-child>div>label span,table.with-details td>label span{display:none}table.with-details td>label{right:2px}table.with-details tr:nth-child(even) td{height:auto;position:relative;display:table-cell}table.with-details tr:nth-child(even) td>*{display:none}table.with-details td:only-child>div>label{right:11px}table.with-details tr:nth-child(even) td>input:checked+*{display:block}table.with-details td:only-child{overflow:visible;width:100%}table.with-details td:only-child>div{border:1px solid var(--token-color-palette-neutral-300);border-radius:var(--decor-radius-100);box-shadow:var(--token-surface-high-box-shadow);margin-bottom:20px;position:relative;left:-10px;right:-10px;width:calc(100% + 20px);margin-top:-51px;pointer-events:none;padding:10px}table.with-details td:only-child>div::after{content:"";display:block;clear:both}table.with-details td:only-child>div>div{pointer-events:auto;margin-top:36px}.consul-auth-method-binding-list dl,.consul-auth-method-view dl,.consul-auth-method-view section dl{display:flex;flex-wrap:wrap}.consul-auth-method-binding-list dl dd,.consul-auth-method-binding-list dl dt,.consul-auth-method-view dl dd,.consul-auth-method-view dl dt{padding:12px 0;margin:0;border-top:1px solid!important}.consul-auth-method-binding-list dl dt,.consul-auth-method-view dl dt{width:20%;font-weight:var(--token-typography-font-weight-bold)}.consul-auth-method-binding-list dl dd,.consul-auth-method-view dl dd{margin-left:auto;width:80%;display:flex}.consul-auth-method-binding-list dl dd>ul li,.consul-auth-method-view dl dd>ul li{display:flex}.consul-auth-method-binding-list dl dd>ul li:not(:last-of-type),.consul-auth-method-view dl dd>ul li:not(:last-of-type){padding-bottom:12px}.consul-auth-method-binding-list dl dt.check+dd,.consul-auth-method-view dl dt.check+dd{padding-top:16px}.consul-auth-method-binding-list dl>dd:last-of-type,.consul-auth-method-binding-list dl>dt:last-of-type,.consul-auth-method-view dl>dd:last-of-type,.consul-auth-method-view dl>dt:last-of-type{border-bottom:1px solid!important;border-color:var(--token-color-palette-neutral-300)!important}.consul-auth-method-binding-list dl dd,.consul-auth-method-binding-list dl dt,.consul-auth-method-view dl dd,.consul-auth-method-view dl dt{border-color:var(--token-color-palette-neutral-300)!important;color:var(--token-color-hashicorp-brand)!important}.consul-auth-method-binding-list dl dd .copy-button button::before,.consul-auth-method-view dl dd .copy-button button::before{background-color:var(--token-color-hashicorp-brand)}.consul-auth-method-binding-list dl dt.type+dd span::before,.consul-auth-method-view dl dt.type+dd span::before{margin-left:4px;background-color:var(--token-color-foreground-faint)}.tooltip-panel dt{cursor:pointer}.tooltip-panel dd>div::before{width:12px;height:12px;background-color:var(--token-color-surface-primary);border-top:1px solid var(--token-color-palette-neutral-300);border-right:1px solid var(--token-color-palette-neutral-300);transform:rotate(-45deg);position:absolute;left:16px;top:-7px}.tooltip-panel,.tooltip-panel dt{display:flex;flex-direction:column}.tooltip-panel dd>div.menu-panel{top:auto;overflow:visible}.tooltip-panel dd{display:none;position:relative;z-index:1;padding-top:10px;margin-bottom:-10px}.tooltip-panel:hover dd{display:block}.tooltip-panel dd>div{width:250px}.app-view>header .title{display:grid;grid-template-columns:1fr auto;grid-template-areas:"title actions";position:relative;z-index:5;padding-bottom:1.4em}.app-view>div form:not(.filter-bar) fieldset{border-bottom:var(--decor-border-200)}.app-view>header h1>em{color:var(--token-color-foreground-faint)}.app-view>header dd>a{color:var(--token-color-hashicorp-brand)}.app-view>div div>dl>dd{color:var(--token-color-foreground-disabled)}.app-view>div form:not(.filter-bar) fieldset,.app-view>header .title{border-color:var(--token-color-surface-interactive-active)}.app-view>header .title .title-left-container{grid-area:title;display:flex;flex-wrap:wrap;align-items:center;white-space:normal}.app-view>header .title .title-left-container>:first-child{flex-basis:100%}.app-view>header .title .title-left-container>:not(:first-child){margin-right:8px}.app-view>header .actions{grid-area:actions;align-self:end;display:flex;align-items:flex-start;margin-left:auto;margin-top:9px}.app-view>div form:not(.filter-bar) fieldset{padding-bottom:.3em;margin-bottom:2em}[for=toolbar-toggle]{background-position:0 4px;display:inline-block;width:26px;height:26px;cursor:pointer;color:var(--token-color-foreground-action)}#toolbar-toggle{display:none}@media (max-width:849px){.app-view>header .actions{margin-top:9px}}@media (min-width:996px){[for=toolbar-toggle]{display:none}}@media (max-width:995px){.app-view>header h1{display:inline-block}html[data-route$="dc.services.instance.show"] h1{display:block}#toolbar-toggle+*{display:none}#toolbar-toggle:checked+*{display:flex}}.brand-loader{position:absolute;top:50%;margin-top:-26px;left:50%}.app .notifications{position:fixed;z-index:100;bottom:2rem;left:1.5rem;pointer-events:none}.app .notifications .app-notification>*{min-width:400px}.app .notifications .app-notification{transition-property:opacity;width:-moz-fit-content;width:fit-content;max-width:80%;pointer-events:auto}.hashicorp-consul .consul-side-nav li.consul-disabled-nav{width:100%;min-height:var(--token-side-nav-body-list-item-height);padding:var(--token-side-nav-body-list-item-padding-vertical) var(--token-side-nav-body-list-item-padding-horizontal);color:var(--token-color-foreground-disabled)}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .consul-side-nav__selector-toggle{min-width:15.5rem}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .consul-side-nav__selector-toggle:disabled{color:var(--token-color-foreground-disabled);border-color:var(--token-color-border-primary)}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .consul-side-nav__selector-toggle:disabled:hover{background-color:transparent}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .hds-dropdown__content{min-width:15.5rem;max-height:500px}.hashicorp-consul .consul-side-nav .hds-side-nav__wrapper-body{overflow-y:unset;overflow-x:unset}.hashicorp-consul .consul-side-nav li.consul-side-nav__datacenter{display:flex;gap:.5rem;align-items:center;padding-left:.5rem}.hashicorp-consul .consul-side-nav .consul-side-nav__selector-group{margin-bottom:1.5rem}.hashicorp-consul .consul-side-nav .consul-datacenter-selector__dc-name{display:flex;align-items:center;gap:.5rem}.hashicorp-consul .consul-side-nav .consul-datacenter-selector__dc-name .consul-datacenter-selector__badges{display:flex;gap:.25rem}.hashicorp-consul .consul-side-nav .consul-side-nav__selector-title{margin-top:.5rem}.hashicorp-consul .consul-side-nav .consul-side-nav__selector-description{padding-top:.5rem}.disclosure-menu [aria-expanded]~*>div+ul,.menu-panel>div+ul,.more-popover-menu>[type=checkbox]+label+div>div+ul,.popover-menu>[type=checkbox]+label+div>div+ul,table.has-actions tr>.actions>[type=checkbox]+label+div>div+ul,table.with-details tr>.actions>[type=checkbox]+label+div>div+ul{border-top:var(--decor-border-100);border-color:var(--token-form--base-border-color-default)}.disclosure-menu [aria-expanded]~* [role=separator]:first-child:not(:empty),.menu-panel [role=separator]:first-child:not(:empty),.more-popover-menu>[type=checkbox]+label+div [role=separator]:first-child:not(:empty),.popover-menu>[type=checkbox]+label+div [role=separator]:first-child:not(:empty),table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator]:first-child:not(:empty),table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]:first-child:not(:empty){border:none}.disclosure-menu [aria-expanded]~*>ul>li,.menu-panel>ul>li,.more-popover-menu>[type=checkbox]+label+div>ul>li,.popover-menu>[type=checkbox]+label+div>ul>li,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li{list-style-type:none}.disclosure-menu [aria-expanded]~*>ul .informed-action,.menu-panel>ul .informed-action,.more-popover-menu>[type=checkbox]+label+div>ul .informed-action,.popover-menu>[type=checkbox]+label+div>ul .informed-action,table.has-actions tr>.actions>[type=checkbox]+label+div>ul .informed-action,table.with-details tr>.actions>[type=checkbox]+label+div>ul .informed-action{border:0!important}.disclosure-menu [aria-expanded]~*>div,.menu-panel>div,.more-popover-menu>[type=checkbox]+label+div>div,.popover-menu>[type=checkbox]+label+div>div,table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div>div{padding:.625rem var(--padding-x);white-space:normal;max-width:-moz-fit-content;max-width:fit-content}@supports not ((max-width:-moz-fit-content) or (max-width:fit-content)){.disclosure-menu [aria-expanded]~*>div,.menu-panel>div,.more-popover-menu>[type=checkbox]+label+div>div,.popover-menu>[type=checkbox]+label+div>div,table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div>div{max-width:200px}}.disclosure-menu [aria-expanded]~*>div::before,.menu-panel>div::before,.more-popover-menu>[type=checkbox]+label+div>div::before,.popover-menu>[type=checkbox]+label+div>div::before,table.has-actions tr>.actions>[type=checkbox]+label+div>div::before,table.with-details tr>.actions>[type=checkbox]+label+div>div::before{position:absolute;left:15px;top:calc(10px + .1em)}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]+*,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]+*,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]+*,.menu-panel-deprecated>ul>li>div[role=menu],.menu-panel>ul>[role=treeitem]+*,.menu-panel>ul>li>[role=menuitem]+*,.menu-panel>ul>li>[role=option]+*,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]+*,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]+*,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]+*,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]+*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]+*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]+*,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]+*,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]+*{position:absolute;top:0;left:calc(100% + 10px)}.disclosure-menu [aria-expanded]~*>ul,.menu-panel>ul,.more-popover-menu>[type=checkbox]+label+div>ul,.popover-menu>[type=checkbox]+label+div>ul,table.has-actions tr>.actions>[type=checkbox]+label+div>ul,table.with-details tr>.actions>[type=checkbox]+label+div>ul{margin:0;padding:calc(var(--padding-y) - .625rem) 0;transition:transform 150ms}.disclosure-menu [aria-expanded]~*>ul,.disclosure-menu [aria-expanded]~*>ul>li,.disclosure-menu [aria-expanded]~*>ul>li>*,.menu-panel>ul,.menu-panel>ul>li,.menu-panel>ul>li>*,.more-popover-menu>[type=checkbox]+label+div>ul,.more-popover-menu>[type=checkbox]+label+div>ul>li,.more-popover-menu>[type=checkbox]+label+div>ul>li>*,.popover-menu>[type=checkbox]+label+div>ul,.popover-menu>[type=checkbox]+label+div>ul>li,.popover-menu>[type=checkbox]+label+div>ul>li>*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>*,table.with-details tr>.actions>[type=checkbox]+label+div>ul,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>*{width:100%}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{display:flex}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]::after,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]::after,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]::after,.menu-panel>ul>[role=treeitem]::after,.menu-panel>ul>li>[role=menuitem]::after,.menu-panel>ul>li>[role=option]::after,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]::after,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]::after,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]::after,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]::after{margin-left:auto;padding-right:var(--padding-x);transform:translate(calc(var(--padding-x)/ 2),0)}.disclosure-menu [aria-expanded]~* [role=separator],.menu-panel [role=separator],.more-popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]{text-transform:uppercase;color:var(--token-color-foreground-faint);padding-top:.375rem}.disclosure-menu [aria-expanded]~* [role=separator]:not(:first-child),.menu-panel [role=separator]:not(:first-child),.more-popover-menu>[type=checkbox]+label+div [role=separator]:not(:first-child),.popover-menu>[type=checkbox]+label+div [role=separator]:not(:first-child),table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator]:not(:first-child),table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]:not(:first-child){margin-top:.275rem}.disclosure-menu [aria-expanded]~* [role=separator]:not(:empty),.menu-panel [role=separator]:not(:empty),.more-popover-menu>[type=checkbox]+label+div [role=separator]:not(:empty),.popover-menu>[type=checkbox]+label+div [role=separator]:not(:empty),table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator]:not(:empty),table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]:not(:empty){padding-left:var(--padding-x);padding-right:var(--padding-x);padding-bottom:.125rem}.disclosure-menu [aria-expanded]~.menu-panel-confirming,.menu-panel-confirming.menu-panel,.more-popover-menu>[type=checkbox]+label+div.menu-panel-confirming,.popover-menu>[type=checkbox]+label+div.menu-panel-confirming,table.has-actions tr>.actions>[type=checkbox]+label+div.menu-panel-confirming,table.with-details tr>.actions>[type=checkbox]+label+div.menu-panel-confirming{overflow:hidden}.disclosure-menu [aria-expanded]~.menu-panel-confirming>ul,.menu-panel-confirming.menu-panel>ul,.more-popover-menu>[type=checkbox]+label+div.menu-panel-confirming>ul,.popover-menu>[type=checkbox]+label+div.menu-panel-confirming>ul,table.has-actions tr>.actions>[type=checkbox]+label+div.menu-panel-confirming>ul,table.with-details tr>.actions>[type=checkbox]+label+div.menu-panel-confirming>ul{transform:translateX(calc(-100% - 10px))}.disclosure-menu [aria-expanded]~*,.menu-panel,.more-popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div,table.has-actions tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div{overflow:hidden}.menu-panel-deprecated{position:absolute;transition:max-height 150ms;transition:min-height 150ms,max-height 150ms;min-height:0}.menu-panel-deprecated [type=checkbox]{display:none}.menu-panel-deprecated:not(.confirmation) [type=checkbox]~*{transition:transform 150ms}.confirmation.menu-panel-deprecated [role=menu]{min-height:205px!important}.menu-panel-deprecated [type=checkbox]:checked~*{transform:translateX(calc(-100% - 10px));min-height:143px;max-height:143px}.menu-panel-deprecated [id$="-"]:first-child:checked~ul label[for$="-"] * [role=menu],.menu-panel-deprecated [id$="-"]:first-child:checked~ul>li>[role=menu]{display:block}.menu-panel-deprecated>ul>li>:not(div[role=menu]),.tippy-box{position:relative}.menu-panel-deprecated:not(.left){right:0!important;left:auto!important}.left.menu-panel-deprecated{left:0}.menu-panel-deprecated:not(.above){top:28px}.above.menu-panel-deprecated{bottom:42px}.consul-upstream-instance-list dl.local-bind-socket-mode dt::after{display:inline;content:var(--horizontal-kv-list-key-separator)}.consul-bucket-list,.consul-exposed-path-list>ul>li>.detail dl,.consul-instance-checks,.consul-lock-session-list dl,.consul-lock-session-list ul>li:not(:first-child)>.detail dl,.consul-upstream-instance-list dl,.consul-upstream-instance-list li>.detail dl,.list-collection>ul>li:not(:first-child)>.detail dl,.tag-list,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl,section[data-route="dc.show.license"] .validity dl,td.tags{display:inline-flex;flex-wrap:nowrap;align-items:center}.consul-bucket-list:empty,.consul-exposed-path-list>ul>li>.detail dl:empty,.consul-instance-checks:empty,.consul-lock-session-list dl:empty,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:empty,.consul-upstream-instance-list dl:empty,.list-collection>ul>li:not(:first-child)>.detail dl:empty,.tag-list:empty,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:empty,section[data-route="dc.show.license"] .validity dl:empty,td.tags:empty{display:none}.consul-bucket-list>*>*,.consul-exposed-path-list>ul>li>.detail dl>*>*,.consul-instance-checks>*>*,.consul-lock-session-list dl>*>*,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>*>*,.consul-upstream-instance-list dl>*>*,.consul-upstream-instance-list li>.detail dl>*>*,.list-collection>ul>li:not(:first-child)>.detail dl>*>*,.tag-list>*>*,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl>*>*,section[data-route="dc.show.license"] .validity dl>*>*,td.tags>*>*{display:inline-block}.consul-bucket-list>*,.consul-exposed-path-list>ul>li>.detail dl>*,.consul-instance-checks>*,.consul-lock-session-list dl>*,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>*,.consul-upstream-instance-list dl>*,.consul-upstream-instance-list li>.detail dl>*,.list-collection>ul>li:not(:first-child)>.detail dl>*,.tag-list>*,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl>*,section[data-route="dc.show.license"] .validity dl>*,td.tags>*{white-space:nowrap}.consul-bucket-list>dd,.consul-exposed-path-list>ul>li>.detail dl>dd,.consul-instance-checks>dd,.consul-lock-session-list dl>dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>dd,.consul-upstream-instance-list dl>dd,.consul-upstream-instance-list li>.detail dl>dd,.list-collection>ul>li:not(:first-child)>.detail dl>dd,.tag-list>dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl>dd,section[data-route="dc.show.license"] .validity dl>dd,td.tags>dd{flex-wrap:wrap}.consul-upstream-instance-list dl.local-bind-socket-mode dt{display:inline-flex;min-width:18px;overflow:hidden}.consul-lock-session-list .checks dd,.discovery-chain .resolver-card ol,.filter-bar,.filter-bar>div,.modal-dialog,.tag-list dd,td.tags dd{display:flex}.consul-bucket-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-bucket-list .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-bucket-list .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .tag-list:not([class]) dd+dt:not([class])+dd,.consul-bucket-list dd+dt,.consul-bucket-list td.tags:not([class]) dd+dt:not([class])+dd,.consul-bucket-list+.consul-bucket-list:not(:first-of-type),.consul-bucket-list+.consul-instance-checks:not(:first-of-type),.consul-bucket-list+.tag-list:not(:first-of-type),.consul-bucket-list+td.tags:not(:first-of-type),.consul-bucket-list:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .tag-list dd+dt:not([class])+dd,.consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-bucket-list:not([class]) td.tags dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail .consul-bucket-list+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-instance-checks+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-lock-session-list dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-exposed-path-list>ul>li>.detail .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-exposed-path-list>ul>li>.detail .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail .tag-list+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl dd+dt,.consul-exposed-path-list>ul>li>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl+.consul-bucket-list:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+.consul-instance-checks:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+.tag-list:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+td.tags:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail td.tags+dl:not(:first-of-type),.consul-instance-checks .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-instance-checks .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-instance-checks .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .tag-list:not([class]) dd+dt:not([class])+dd,.consul-instance-checks dd+dt,.consul-instance-checks td.tags:not([class]) dd+dt:not([class])+dd,.consul-instance-checks+.consul-bucket-list:not(:first-of-type),.consul-instance-checks+.consul-instance-checks:not(:first-of-type),.consul-instance-checks+.tag-list:not(:first-of-type),.consul-instance-checks+td.tags:not(:first-of-type),.consul-instance-checks:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .tag-list dd+dt:not([class])+dd,.consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-instance-checks:not([class]) td.tags dd+dt:not([class])+dd,.consul-lock-session-list .consul-bucket-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-bucket-list+dl:not(:first-of-type),.consul-lock-session-list .consul-bucket-list:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-instance-checks ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-instance-checks+dl:not(:first-of-type),.consul-lock-session-list .consul-instance-checks:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-lock-session-list .consul-upstream-instance-list dl.local-bind-address dl dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list dl.local-bind-socket-path dl dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl.local-bind-address dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl.local-bind-socket-path dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .tag-list dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .tag-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .tag-list+dl:not(:first-of-type),.consul-lock-session-list .tag-list:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .tag-list:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-lock-session-list dl .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-lock-session-list dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl dd+dt,.consul-lock-session-list dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl+.consul-bucket-list:not(:first-of-type),.consul-lock-session-list dl+.consul-instance-checks:not(:first-of-type),.consul-lock-session-list dl+.tag-list:not(:first-of-type),.consul-lock-session-list dl+dl:not(:first-of-type),.consul-lock-session-list dl+td.tags:not(:first-of-type),.consul-lock-session-list dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-lock-session-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.license"] .validity dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-lock-session-list section[data-route="dc.show.license"] .validity dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list td.tags dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list td.tags ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list td.tags+dl:not(:first-of-type),.consul-lock-session-list td.tags:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list td.tags:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-bucket-list+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-instance-checks+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .tag-list+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt,.consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl+.consul-bucket-list:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+.consul-instance-checks:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+.tag-list:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+td.tags:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail td.tags+dl:not(:first-of-type),.consul-upstream-instance-list .consul-bucket-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-bucket-list+dl:not(:first-of-type),.consul-upstream-instance-list .consul-bucket-list:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-instance-checks li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-instance-checks+dl:not(:first-of-type),.consul-upstream-instance-list .consul-instance-checks:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list dl+dl:not(:first-of-type),.consul-upstream-instance-list .consul-lock-session-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list+dl:not(:first-of-type),.consul-upstream-instance-list .tag-list:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl dd+dt,.consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl+.consul-bucket-list:not(:first-of-type),.consul-upstream-instance-list dl+.consul-instance-checks:not(:first-of-type),.consul-upstream-instance-list dl+.tag-list:not(:first-of-type),.consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-upstream-instance-list dl+td.tags:not(:first-of-type),.consul-upstream-instance-list dl.local-bind-address .consul-bucket-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address .consul-instance-checks dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address .consul-lock-session-list dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address .tag-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address section[data-route="dc.show.license"] .validity dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address td.tags dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .consul-bucket-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .consul-instance-checks dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .consul-lock-session-list dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .tag-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path section[data-route="dc.show.license"] .validity dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path td.tags dd+dt+dd,.consul-upstream-instance-list dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail .consul-bucket-list+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail .consul-instance-checks+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail .consul-lock-session-list dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail .tag-list+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl dd+dt,.consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl+.consul-bucket-list:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+.consul-instance-checks:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+.tag-list:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+td.tags:not(:first-of-type),.consul-upstream-instance-list li>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list li>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail td.tags+dl:not(:first-of-type),.consul-upstream-instance-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-upstream-instance-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list section[data-route="dc.show.license"] .validity dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-upstream-instance-list section[data-route="dc.show.license"] .validity dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags+dl:not(:first-of-type),.consul-upstream-instance-list td.tags:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags:not([class]) li>.detail dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-bucket-list+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-instance-checks+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-lock-session-list dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .tag-list+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl dd+dt,.list-collection>ul>li:not(:first-child)>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl+.consul-bucket-list:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+.consul-instance-checks:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+.tag-list:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+td.tags:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail td.tags+dl:not(:first-of-type),.tag-list .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.tag-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.tag-list .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.tag-list .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.tag-list .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list dd+dt,.tag-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.tag-list section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.tag-list td.tags:not([class]) dd+dt:not([class])+dd,.tag-list+.consul-bucket-list:not(:first-of-type),.tag-list+.consul-instance-checks:not(:first-of-type),.tag-list+.tag-list:not(:first-of-type),.tag-list+td.tags:not(:first-of-type),.tag-list:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.tag-list:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.tag-list:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) dd+dt:not([class])+dd,.tag-list:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.tag-list:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.tag-list:not([class]) td.tags dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-bucket-list+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-instance-checks+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl.local-bind-address dl dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl.local-bind-socket-path dl dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .tag-list dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .tag-list+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .tag-list:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .tag-list:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl td.tags:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+.consul-bucket-list:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+.consul-instance-checks:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+.tag-list:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+td.tags:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .tag-list dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) td.tags dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header td.tags dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header td.tags+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header td.tags:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section[data-route="dc.show.license"] .validity header dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section[data-route="dc.show.license"] header .validity dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-bucket-list+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-instance-checks+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-lock-session-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-lock-session-list dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-lock-session-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl.local-bind-address dl dd+dt+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl.local-bind-socket-path dl dd+dt+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .tag-list dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .tag-list+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .tag-list:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,section[data-route="dc.show.license"] .validity dl .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,section[data-route="dc.show.license"] .validity dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .tag-list:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl dd+dt,section[data-route="dc.show.license"] .validity dl td.tags:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl+.consul-bucket-list:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+.consul-instance-checks:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+.tag-list:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+td.tags:not(:first-of-type),section[data-route="dc.show.license"] .validity dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .tag-list dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) td.tags dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity td.tags dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity td.tags+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity td.tags:not([class]) dl dd+dt:not([class])+dd,td.tags .consul-bucket-list:not([class]) dd+dt:not([class])+dd,td.tags .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-instance-checks:not([class]) dd+dt:not([class])+dd,td.tags .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,td.tags .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,td.tags .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .tag-list:not([class]) dd+dt:not([class])+dd,td.tags dd+dt,td.tags section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,td.tags section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,td.tags+.consul-bucket-list:not(:first-of-type),td.tags+.consul-instance-checks:not(:first-of-type),td.tags+.tag-list:not(:first-of-type),td.tags+td.tags:not(:first-of-type),td.tags:not([class]) .consul-bucket-list dd+dt:not([class])+dd,td.tags:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-instance-checks dd+dt:not([class])+dd,td.tags:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .tag-list dd+dt:not([class])+dd,td.tags:not([class]) dd+dt:not([class])+dd,td.tags:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,td.tags:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd{margin-left:var(--horizontal-kv-list-separator-width)}.consul-bucket-list dt+dd,.consul-exposed-path-list>ul>li>.detail dl dt+dd,.consul-instance-checks dt+dd,.consul-lock-session-list dl dt+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl dt+dd,.consul-upstream-instance-list dl dt+dd,.consul-upstream-instance-list li>.detail dl dt+dd,.list-collection>ul>li:not(:first-child)>.detail dl dt+dd,.tag-list dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dt+dd,section[data-route="dc.show.license"] .validity dl dt+dd,td.tags dt+dd{margin-left:4px}.consul-bucket-list:not([class]) dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) dt:not([class])+dd,.consul-instance-checks:not([class]) dt:not([class])+dd,.consul-lock-session-list dl:not([class]) dt:not([class])+dd,.consul-upstream-instance-list dl.local-bind-address dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path dt+dd,.consul-upstream-instance-list dl:not([class]) dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dt:not([class])+dd,.tag-list:not([class]) dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) dt:not([class])+dd,td.tags:not([class]) dt:not([class])+dd{margin-left:0!important}.consul-lock-session-list .checks dd>:not(:last-child)::after,.discovery-chain .resolver-card ol>:not(:last-child)::after,.tag-list dd>:not(:last-child)::after,td.tags dd>:not(:last-child)::after{display:inline;content:var(--csv-list-separator);vertical-align:initial;margin-right:.3em}.freetext-filter_label::after,.tippy-box .tippy-arrow::before{content:"";position:absolute}.tag-list dt::before,td.tags dt::before{color:inherit;color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul>li>.detail dl>dt>*,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>dt>*,.consul-upstream-instance-list li>.detail dl>dt>*,.list-collection>ul>li:not(:first-child)>.detail dl>dt>*{display:none}.consul-exposed-path-list>ul>li>.detail dl.passing dt::before,.consul-exposed-path-list>ul>li>.header .passing dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .passing dd::before,.consul-upstream-instance-list li>.detail dl.passing dt::before,.consul-upstream-instance-list li>.header .passing dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.passing dt::before,.list-collection>ul>li:not(:first-child)>.header .passing dd::before{color:var(--token-color-foreground-success)}.consul-exposed-path-list>ul>li>.detail dl.warning dt::before,.consul-exposed-path-list>ul>li>.header .warning dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .warning dd::before,.consul-upstream-instance-list li>.detail dl.warning dt::before,.consul-upstream-instance-list li>.header .warning dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.warning dt::before,.list-collection>ul>li:not(:first-child)>.header .warning dd::before{color:var(--token-color-foreground-warning)}.consul-exposed-path-list>ul>li>.detail dl.critical dt::before,.consul-exposed-path-list>ul>li>.header .critical dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .critical dd::before,.consul-upstream-instance-list li>.detail dl.critical dt::before,.consul-upstream-instance-list li>.header .critical dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.critical dt::before,.list-collection>ul>li:not(:first-child)>.header .critical dd::before{color:var(--token-color-foreground-critical)}.consul-exposed-path-list>ul>li>.detail dl.empty dt::before,.consul-exposed-path-list>ul>li>.detail dl.unknown dt::before,.consul-exposed-path-list>ul>li>.header .empty dd::before,.consul-exposed-path-list>ul>li>.header .unknown dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.unknown dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .empty dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .unknown dd::before,.consul-upstream-instance-list li>.detail dl.empty dt::before,.consul-upstream-instance-list li>.detail dl.unknown dt::before,.consul-upstream-instance-list li>.header .empty dd::before,.consul-upstream-instance-list li>.header .unknown dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.empty dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.unknown dt::before,.list-collection>ul>li:not(:first-child)>.header .empty dd::before,.list-collection>ul>li:not(:first-child)>.header .unknown dd::before{color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul>li>.header [rel=me] dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header [rel=me] dd::before,.consul-upstream-instance-list li>.header [rel=me] dd::before,.list-collection>ul>li:not(:first-child)>.header [rel=me] dd::before{color:var(--token-color-foreground-action)}.app-view>div form:not(.filter-bar) [role=radiogroup] label>em>code,.modal-dialog [role=document] .type-password>em>code,.modal-dialog [role=document] .type-select>em>code,.modal-dialog [role=document] .type-text>em>code,.modal-dialog [role=document] [role=radiogroup] label>em>code,.modal-dialog [role=document] form button+em>code,.modal-dialog [role=document] p code,.oidc-select label>em>code,.type-toggle>em>code,main .type-password>em>code,main .type-select>em>code,main .type-text>em>code,main form button+em>code,main p code{border:1px solid;color:var(--token-color-consul-brand);background-color:var(--token-color-surface-strong);border-color:var(--token-color-surface-interactive-active);display:inline-block;padding:0 4px}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{outline:0;background-color:var(--token-color-surface-primary);border-radius:var(--decor-radius-100)}[data-animation=fade][data-state=hidden].tippy-box{opacity:0}[data-inertia][data-state=visible].tippy-box{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-box .tippy-arrow{--size:5px}[data-placement^=top].tippy-box>.tippy-arrow{bottom:0}[data-placement^=top].tippy-box>.tippy-arrow::before{left:0;bottom:calc(0px - var(--size));transform-origin:center top}[data-placement^=bottom].tippy-box>.tippy-arrow{top:0}[data-placement^=bottom].tippy-box>.tippy-arrow::before{left:0;top:calc(0px - var(--size));transform-origin:center bottom}[data-placement^=left].tippy-box>.tippy-arrow{right:0}[data-placement^=left].tippy-box>.tippy-arrow::before{right:calc(0px - var(--size));transform-origin:center left}[data-placement^=right].tippy-box>.tippy-arrow{left:0}[data-placement^=right].tippy-box>.tippy-arrow::before{left:calc(0px - var(--size));transform-origin:center right}[data-theme~=square-tail] .tippy-arrow{--size:18px;left:calc(0px - var(--size)/ 2)!important}[data-theme~=square-tail] .tippy-arrow::before{background-color:var(--token-color-surface-primary);width:calc(1px + var(--size));height:calc(1px + var(--size));border:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300)}[data-theme~=square-tail] .tippy-arrow::after{position:absolute;left:1px}[data-theme~=square-tail][data-placement^=top]{bottom:-10px}[data-theme~=square-tail][data-placement^=top] .informed-action{border-bottom-left-radius:0!important}[data-theme~=square-tail][data-placement^=top] .tippy-arrow::before{border-bottom-left-radius:var(--decor-radius-200);border-bottom-right-radius:var(--decor-radius-200);border-top:0!important}[data-theme~=square-tail][data-placement^=top] .tippy-arrow::after{bottom:calc(0px - var(--size))}[data-theme~=square-tail][data-placement^=bottom]{top:-10px}[data-theme~=square-tail][data-placement^=bottom] .informed-action{border-top-left-radius:0!important}[data-theme~=square-tail][data-placement^=bottom] .tippy-arrow::before{border-top-left-radius:var(--decor-radius-200);border-top-right-radius:var(--decor-radius-200);border-bottom:0!important}[data-theme~=square-tail][data-placement^=bottom] .tippy-arrow::after{top:calc(0px - var(--size))}.tippy-box[data-theme~=tooltip] .tippy-content{padding:12px;max-width:224px;position:relative;z-index:1}.tippy-box[data-theme~=tooltip]{background-color:var(--token-color-foreground-faint)}.tippy-box[data-theme~=tooltip] .tippy-arrow{--size:5px;color:var(--token-color-foreground-faint);width:calc(var(--size) * 2);height:calc(var(--size) * 2)}.tippy-box[data-theme~=tooltip] .tippy-arrow::before{border-color:transparent;border-style:solid}.tippy-box[data-theme~=tooltip][data-placement^=top]>.tippy-arrow::before{border-width:var(--size) var(--size) 0;border-top-color:initial}.tippy-box[data-theme~=tooltip][data-placement^=bottom]>.tippy-arrow::before{border-width:0 var(--size) var(--size);border-bottom-color:initial}.tippy-box[data-theme~=tooltip][data-placement^=left]>.tippy-arrow::before{border-width:var(--size) 0 var(--size) var(--size);border-left-color:initial}.tippy-box[data-theme~=tooltip][data-placement^=right]>.tippy-arrow::before{border-width:var(--size) var(--size) var(--size) 0;border-right-color:initial}.warning.modal-dialog header{background-color:var(--token-color-vault-gradient-faint-start);border-color:var(--token-color-vault-brand);color:var(--token-color-vault-foreground)}.warning.modal-dialog header::before{color:var(--token-color-vault-brand);float:left;margin-top:2px;margin-right:3px}.modal-dialog>div:first-child{background-color:var(--token-color-surface-interactive);opacity:.9}.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,.modal-dialog-body{border-color:var(--token-color-palette-neutral-300)}.modal-dialog-body{border-style:solid;border-left-width:1px;border-right-width:1px}.modal-layer{height:0}.modal-dialog [role=document] table{height:150px!important}.modal-dialog [role=document] tbody{max-height:100px}.modal-dialog table{min-height:149px}.modal-dialog,.modal-dialog>div:first-child{position:fixed;top:0;right:0;bottom:0;left:0}.modal-dialog{z-index:500;align-items:center;justify-content:center;height:100%}[aria-hidden=true].modal-dialog{display:none}.modal-dialog [role=document]{background-color:var(--token-color-surface-primary);margin:auto;z-index:2;max-width:855px;position:relative}.modal-dialog [role=document]>*{padding-left:15px;padding-right:15px}.modal-dialog [role=document]>div{overflow-y:auto;max-height:80vh;padding:20px 23px}.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header{border-width:1px;padding-top:12px;padding-bottom:10px}.modal-dialog [role=document]>header{position:relative}.modal-dialog [role=document]>header button{float:right;margin-top:-3px}.list-collection>ul{border-top:1px solid;border-color:var(--token-color-surface-interactive-active)}.list-collection>button{cursor:pointer;background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-action);width:100%;padding:15px}.list-collection-scroll-virtual,.list-collection>ul>li{position:relative}.list-collection-scroll-virtual{height:500px}.filter-bar{background-color:var(--token-color-foreground-high-contrast);border-bottom:var(--decor-border-100);border-color:var(--token-color-surface-interactive-active);padding:4px 8px}.filter-bar .filters .popover-menu>[type=checkbox]:checked+label button,.filter-bar .sort .popover-menu>[type=checkbox]:checked+label button{color:var(--token-color-foreground-action);background-color:var(--token-color-foreground-high-contrast)}.filter-bar .sort{margin-left:auto}.filter-bar .popover-select{position:relative;z-index:3}.filter-bar .popover-menu>[type=checkbox]+label button{padding-left:1.5rem!important;padding-right:1.5rem!important}.filter-bar .popover-menu [role=menuitem]{justify-content:normal!important}@media (max-width:1379px){.filter-bar,.filter-bar>div{flex-wrap:wrap}.filter-bar .search{position:relative;z-index:4;width:100%;margin-bottom:.3rem}}@media (max-width:995px){.filter-bar .filters,.filter-bar .sort{display:none}}html[data-route^="dc.acls.index"] .filter-bar{color:inherit}.freetext-filter{border:var(--decor-border-100);border-radius:var(--decor-radius-100);background-color:var(--token-color-surface-primary);border-color:var(--token-color-surface-interactive-active);color:var(--token-color-foreground-disabled)}.freetext-filter:hover,.freetext-filter:hover *{border-color:var(--token-color-foreground-disabled)}.freetext-filter_input::-moz-placeholder{cursor:inherit;color:inherit;border-color:inherit}.freetext-filter *,.freetext-filter_input::placeholder{cursor:inherit;color:inherit;border-color:inherit}.freetext-filter_input{-webkit-appearance:none;border:none}.freetext-filter_label::after{visibility:visible;--icon-name:icon-search;top:50%;left:50%;width:16px;height:16px;margin-left:-8px;margin-top:-8px}.freetext-filter .popover-menu{background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-primary);border-left:1px solid;border-color:inherit}.freetext-filter .popover-menu>[type=checkbox]:checked+label button{background-color:var(--token-color-surface-interactive-active)}.freetext-filter{--height:2.2rem;display:flex;position:relative;height:var(--height);width:100%}.freetext-filter_input,.freetext-filter_label{height:100%}.freetext-filter_input{padding:8px 10px;padding-left:var(--height);min-width:12.7rem;width:100%}.freetext-filter_label{visibility:hidden;position:absolute;z-index:1;width:var(--height)}.informed-action{border-radius:var(--decor-radius-200);border:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300);background-color:var(--token-color-surface-primary);min-width:190px}.informed-action>div{border-top-left-radius:var(--decor-radius-200);border-top-right-radius:var(--decor-radius-200);cursor:default;padding:1rem}.informed-action p{color:var(--token-color-hashicorp-brand)}.informed-action>ul>li>:focus,.informed-action>ul>li>:hover{background-color:var(--token-color-surface-strong)}.info.informed-action header{color:var(--token-color-foreground-action-active)}.info.informed-action header::before{background-color:var(--token-color-foreground-action);margin-right:5px}.info.informed-action>div{background-color:var(--token-color-surface-action)}.dangerous.informed-action header{color:var(--token-color-palette-red-400)}.dangerous.informed-action header::before{background-color:var(--token-color-foreground-critical)}.dangerous.informed-action>div{background-color:var(--token-color-surface-critical)}.warning.informed-action header{color:var(--token-color-foreground-warning-on-surface)}.warning.informed-action header::before{background-color:var(--token-color-vault-brand);margin-right:5px}.warning.informed-action>div{background-color:var(--token-color-vault-gradient-faint-start)}.copyable-code::after,.tab-nav li:not(.selected)>:active,.tab-nav li:not(.selected)>:focus,.tab-nav li:not(.selected)>:hover{background-color:var(--token-color-surface-strong)}.informed-action>ul>.action>*{color:var(--token-color-foreground-action)}.documentation.informed-action{min-width:270px}.informed-action header::before{float:left;margin-right:5px}.informed-action>ul{list-style:none;display:flex;margin:0;padding:4px}.informed-action>ul>li{width:50%}.informed-action>ul>li>*{width:100%}.tab-nav ul{list-style-type:none;display:inline-flex;align-items:center;position:relative;padding:0;margin:0}.tab-nav li>:not(:disabled){cursor:pointer}.tab-nav{border-bottom:var(--decor-border-100)}.animatable.tab-nav ul::after,.tab-nav li>*{border-bottom:var(--decor-border-300)}.tab-nav{border-color:var(--token-color-surface-interactive-active);clear:both;overflow:auto}.tab-nav li>*{white-space:nowrap;text-decoration:none;transition-property:background-color,border-color;border-color:transparent;color:var(--token-color-foreground-faint);display:inline-block;padding:16px 13px}.tab-nav li:not(.selected)>:focus,.tab-nav li:not(.selected)>:hover{border-color:var(--token-color-palette-neutral-300)}.animatable.tab-nav .selected a{border-color:transparent!important}.animatable.tab-nav ul::after{position:absolute;bottom:0;height:0;border-top:0;width:calc(var(--selected-width,0) * 1px);transform:translate(calc(var(--selected-left,0) * 1px),0);transition-property:transform,width}.search-bar-status{border-bottom:var(--decor-border-100);border-bottom-color:var(--token-color-surface-interactive-active);padding:.5rem 0 .5rem .5rem}.search-bar-status li:not(.remove-all) button::before{color:var(--token-color-foreground-faint);margin-top:1px;margin-right:.2rem}.search-bar-status dt::after{content:":";padding-right:.3rem}.search-bar-status>dl>dt{float:left}.search-bar-status dt{white-space:nowrap}.search-bar-status li{display:inline-flex}.search-bar-status li:not(:last-child){margin-right:.3rem;margin-bottom:.3rem}.search-bar-status li:not(.remove-all){border:var(--decor-border-100);border-color:var(--token-color-surface-interactive-active);color:var(--token-color-foreground-faint);padding:0 .2rem}.search-bar-status li:not(.remove-all) dl{display:flex}.search-bar-status li:not(.remove-all) button{cursor:pointer;padding:0}.copyable-code{display:flex;align-items:flex-start;position:relative;width:100%;padding:8px 14px 3px;border:var(--decor-border-100);border-color:var(--token-color-surface-interactive-active);border-radius:var(--decor-radius-200)}.copyable-code.obfuscated{padding-left:4px}.copyable-code::after{position:absolute;top:0;right:0;width:40px;height:100%;display:block;content:""}.copyable-code .copy-button{position:absolute;top:0;right:0;z-index:1}.copyable-code .copy-button button{width:40px;height:40px}.copyable-code .copy-button button:empty::after{display:none}.copyable-code button[aria-expanded]{margin-top:1px;margin-right:4px;cursor:pointer}.copyable-code button[aria-expanded]::before{content:"";--icon-size:icon-000;--icon-color:var(--token-color-foreground-faint)}.copyable-code button[aria-expanded=true]::before{--icon-name:icon-eye-off}.copyable-code button[aria-expanded=false]::before{--icon-name:icon-eye}.copyable-code pre{padding-right:30px}.copyable-code code{display:inline-block;overflow:hidden;text-overflow:ellipsis;width:100%}.copyable-code hr{width:calc(100% - 80px);margin:8px 0 13px;border:3px dashed var(--token-color-palette-neutral-300);background-color:var(--token-color-surface-primary)}.consul-loader circle{fill:var(--token-color-consul-gradient-faint-stop);animation:loader-animation 1.5s infinite ease-in-out;transform-origin:50% 50%}.consul-loader g:nth-last-child(2) circle{animation-delay:.2s}.consul-loader g:nth-last-child(3) circle{animation-delay:.3s}.consul-loader g:nth-last-child(4) circle{animation-delay:.4s}.consul-loader g:nth-last-child(5) circle{animation-delay:.5s}@keyframes loader-animation{0%,100%{transform:scale3D(1,1,1)}33%{transform:scale3D(0,0,1)}}.consul-loader{display:flex;align-items:center;justify-content:center;height:100%;position:absolute;width:100%;top:0;margin-top:0!important}.tomography-graph .background{fill:var(--token-color-surface-strong)}.tomography-graph .axis{fill:none;stroke:var(--token-color-palette-neutral-300);stroke-dasharray:4 4}.tomography-graph .border{fill:none;stroke:var(--token-color-palette-neutral-300)}.tomography-graph .point{stroke:var(--token-color-foreground-disabled);fill:var(--token-color-consul-foreground)}.tomography-graph .lines rect{fill:var(--token-color-consul-foreground);stroke:transparent;stroke-width:5px}.tomography-graph .lines rect:hover{fill:var(--token-color-palette-neutral-300);height:3px;y:-1px}.tomography-graph .tick line{stroke:var(--token-color-palette-neutral-300)}.tomography-graph .tick text{text-anchor:start}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card,.discovery-chain path{transition-duration:.1s;transition-timing-function:linear;cursor:pointer}.discovery-chain path{transition-property:stroke;fill:none;stroke:var(--token-color-foreground-disabled);stroke-width:2;vector-effect:non-scaling-stroke}#downstream-lines svg circle,#upstream-lines svg circle,.discovery-chain circle{fill:var(--token-color-surface-primary)}.discovery-chain .resolver-card,.discovery-chain .resolver-card a,.discovery-chain .route-card,.discovery-chain .route-card a,.discovery-chain .splitter-card,.discovery-chain .splitter-card a{color:var(--token-color-foreground-strong)!important}.discovery-chain path:focus,.discovery-chain path:hover{stroke:var(--token-color-foreground-strong)}.discovery-chain .resolvers,.discovery-chain .routes,.discovery-chain .splitters{border-radius:var(--decor-radius-100);border:1px solid;border-color:var(--token-color-surface-interactive-active);background-color:var(--token-color-surface-strong);pointer-events:none}.discovery-chain .resolver-card,.discovery-chain .resolvers>header span,.discovery-chain .route-card,.discovery-chain .routes>header span,.discovery-chain .splitter-card,.discovery-chain .splitters>header span{pointer-events:all}.discovery-chain .resolvers>header>*,.discovery-chain .routes>header>*,.discovery-chain .splitters>header>*{text-transform:uppercase}.discovery-chain .resolvers>header span::after,.discovery-chain .routes>header span::after,.discovery-chain .splitters>header span::after{width:1.2em;height:1.2em;opacity:.6}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card{transition-property:opacity background-color border-color;margin-top:0!important}.discovery-chain [id*=":"]:not(path):hover{opacity:1;background-color:var(--token-color-surface-primary);border-color:var(--token-color-foreground-faint)}.discovery-chain .route-card header:not(.short) dd{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.discovery-chain .route-card section header>*{visibility:hidden}.discovery-chain .route-card .match-headers header ::before{content:"H"}.discovery-chain .route-card .match-queryparams header>::before{content:"Q"}.discovery-chain .resolver-card dt::before{content:"";--icon-size:icon-999}.discovery-chain .resolver-card dl.failover dt::before{--icon-name:icon-cloud-cross}.discovery-chain .resolver-card dl.redirect dt::before{--icon-name:icon-redirect}.discovery-chain circle{stroke-width:2;stroke:var(--token-color-foreground-disabled)}.discovery-chain{position:relative;display:flex;justify-content:space-between}.discovery-chain svg{position:absolute}.discovery-chain .resolvers,.discovery-chain .routes,.discovery-chain .splitters{padding:10px 1%;width:32%}.discovery-chain .resolvers>header,.discovery-chain .routes>header,.discovery-chain .splitters>header{height:18px}.discovery-chain .resolvers>header span,.discovery-chain .routes>header span,.discovery-chain .splitters>header span{position:relative;z-index:1;margin-left:2px}.discovery-chain .resolvers [role=group],.discovery-chain .routes [role=group],.discovery-chain .splitters [role=group]{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:space-around;height:100%}.discovery-chain .resolver-card dl,.discovery-chain .route-card dl,.discovery-chain .splitter-card dl{margin:0;float:none}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card{margin-bottom:20px}.discovery-chain .route-card header.short dl{display:flex}.discovery-chain .route-card header.short dt::after{content:" ";display:inline-block}.discovery-chain .route-card>header ul{float:right;margin-top:-2px}.discovery-chain .route-card>header ul li{margin-left:5px}.discovery-chain .route-card section{display:flex}.discovery-chain .route-card section header{display:block;width:19px;margin-right:14px}.discovery-chain .resolver-card a{display:block}.discovery-chain .resolver-card dl{display:flex;flex-wrap:wrap;margin-top:5px}.discovery-chain .resolver-card dt{font-size:0;margin-right:6px;margin-top:1px;width:23px;height:20px}.discovery-chain .resolver-card ol{display:flex;flex-wrap:wrap;list-style-type:none}.discovery-chain .route-card,.discovery-chain .splitter-card{position:relative}.discovery-chain .route-card::before,.discovery-chain .splitter-card::before{background-color:var(--token-color-surface-primary);border-radius:var(--decor-radius-full);border:2px solid;border-color:var(--token-color-foreground-disabled);position:absolute;z-index:1;right:-5px;top:50%;margin-top:-5px;width:10px;height:10px}.discovery-chain .resolver-inlets,.discovery-chain .splitter-inlets{width:10px;height:100%;z-index:1}.discovery-chain .splitter-inlets{left:50%;margin-left:calc(-15% - 3px)}.discovery-chain .resolver-inlets{right:calc(31% - 7px)}.consul-bucket-list dd:not(:last-child)::after{display:inline-block;content:"/";margin:0 6px 0 3px}.consul-bucket-list .service+dd,.consul-bucket-list dd+dt{margin-left:0!important}.consul-upstream-instance-list dl.local-bind-socket-mode dt{text-transform:lowercase;font-weight:var(--token-typography-font-weight-semibold)}.consul-health-check-list .health-check-output::before{min-width:20px;min-height:20px;margin-right:15px}@media (max-width:650px){.consul-health-check-list .health-check-output::before{min-width:18px;min-height:18px;margin-right:8px}}.consul-health-check-list .health-check-output dd em{background-color:var(--token-color-surface-strong);cursor:default;font-style:normal;margin-top:-2px;margin-left:.5em}.consul-health-check-list .passing.health-check-output::before{color:var(--token-color-foreground-success)}.consul-health-check-list .warning.health-check-output::before{color:var(--token-color-foreground-warning)}.consul-health-check-list .critical.health-check-output::before{color:var(--token-color-foreground-critical)}.consul-health-check-list .health-check-output,.consul-health-check-list .health-check-output pre{border-radius:var(--decor-radius-100)}.consul-health-check-list .health-check-output dd:first-of-type{color:var(--token-color-foreground-disabled)}.consul-health-check-list .health-check-output pre{background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-faint)}.consul-health-check-list .health-check-output{border-width:1px 1px 1px 4px;color:var(--token-color-foreground-strong);border-color:var(--token-color-surface-interactive-active);border-style:solid;display:flex;padding:20px 24px 20px 16px}.consul-health-check-list .passing.health-check-output{border-left-color:var(--token-color-foreground-success)}.consul-health-check-list .warning.health-check-output{border-left-color:var(--token-color-vault-brand)}.consul-health-check-list .critical.health-check-output{border-left-color:var(--token-color-foreground-critical)}.consul-health-check-list .health-check-output:not(:last-child){margin-bottom:24px}.consul-health-check-list .health-check-output dl:last-of-type,.consul-health-check-list .health-check-output header{width:100%}.consul-health-check-list .health-check-output header{margin-bottom:.9em}.consul-health-check-list .health-check-output>div{flex:1 1 auto;width:calc(100% - 26px);display:flex;flex-wrap:wrap;justify-content:space-between}.consul-health-check-list .health-check-output dl{min-width:110px}.consul-health-check-list .health-check-output dl>*{display:block;width:auto;position:static;padding-left:0}.consul-health-check-list .health-check-output dt{margin-bottom:0}.consul-health-check-list .health-check-output dd{position:relative}.consul-health-check-list .health-check-output dl:nth-last-of-type(2){width:50%}.consul-health-check-list .health-check-output dl:last-of-type{margin-top:1em;margin-bottom:0}.consul-health-check-list .health-check-output dl:last-of-type dt{margin-bottom:.3em}.consul-health-check-list .health-check-output pre{padding:12px 40px 12px 12px;white-space:pre-wrap;position:relative}.consul-health-check-list .health-check-output pre code{word-wrap:break-word}.consul-health-check-list .health-check-output .copy-button{position:absolute;right:.5em;top:.7em}@media (max-width:650px){.consul-health-check-list .health-check-output{padding:15px 19px 15px 14px}.consul-health-check-list .health-check-output::before{margin-right:8px}.consul-health-check-list .health-check-output dl:nth-last-of-type(2){width:100%}.consul-health-check-list .health-check-output dl:not(:last-of-type){margin-right:0}}.consul-instance-checks.passing dt::before{color:var(--token-color-foreground-success)}.consul-instance-checks.warning dt::before{color:var(--token-color-foreground-warning)}.consul-instance-checks.critical dt::before{color:var(--token-color-foreground-critical)}.consul-instance-checks.empty dt::before{color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul{border-top:1px solid var(--token-color-surface-interactive-active)}.consul-external-source::before,.consul-kind::before{--icon-size:icon-300}.consul-intention-list td.intent- strong::before,.consul-intention-list td.intent-allow strong::before,.consul-intention-list td.intent-deny strong::before,.consul-intention-permission-list .intent-allow::before,.consul-intention-permission-list .intent-deny::before,.consul-intention-search-bar .value- span::before,.consul-intention-search-bar .value-allow span::before,.consul-intention-search-bar .value-deny span::before{margin-right:5px}.consul-intention-list td.intent- strong,.consul-intention-list td.intent-allow strong,.consul-intention-list td.intent-deny strong,.consul-intention-permission-list .intent-allow,.consul-intention-permission-list .intent-deny,.consul-intention-search-bar .value- span,.consul-intention-search-bar .value-allow span,.consul-intention-search-bar .value-deny span{font-weight:var(--token-typography-font-weight-regular);font-size:var(--token-typography-body-200-font-size);display:inline-block}.consul-intention-list td.intent-allow strong,.consul-intention-permission-list .intent-allow,.consul-intention-search-bar .value-allow span{color:var(--token-color-foreground-success-on-surface);background-color:var(--token-color-border-success)}.consul-intention-list td.intent-deny strong,.consul-intention-permission-list .intent-deny,.consul-intention-search-bar .value-deny span{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-border-critical)}.consul-intention-list td.permissions{color:var(--token-color-foreground-action)}.consul-intention-list em{--word-spacing:0.25rem}.consul-intention-list em span::before,.consul-intention-list em span:first-child{margin-right:var(--word-spacing)}.consul-intention-list em span:last-child{margin-left:var(--word-spacing)}.consul-intention-list td{height:59px}.consul-intention-list tr>:nth-child(1){width:calc(30% - 50px)}.consul-intention-list tr>:nth-child(2){width:120px}.consul-intention-list tr>:nth-child(3){width:calc(30% - 50px)}.consul-intention-list tr>:nth-child(4){width:calc(40% - 240px)}.consul-intention-list tr>:nth-child(5){width:160px}.consul-intention-list tr>:last-child{width:60px}.consul-intention-list .menu-panel.confirmation{width:200px}@media (max-width:849px){.consul-intention-list tr>:not(.source):not(.destination):not(.intent){display:none}}.consul-intention-action-warn-modal .modal-dialog-window{max-width:450px}.consul-intention-fieldsets [role=radiogroup]{overflow:visible!important;display:grid;grid-gap:12px;grid-template-columns:repeat(auto-fit,minmax(270px,auto))}.consul-intention-fieldsets .radio-card header>*{display:inline}.consul-intention-fieldsets .permissions>button{float:right}.consul-intention-permission-modal [role=dialog]{width:100%}.consul-intention-permission-list dl.permission-methods dt::before{content:"M"}.consul-intention-permission-list dl.permission-path dt::before{content:"P"}.consul-intention-permission-header-list dt::before,.consul-intention-permission-list dl.permission-header dt::before{content:"H"}.consul-intention-permission-list .detail>div{display:flex;width:100%}.consul-intention-permission-list strong{margin-right:8px}.consul-intention-permission-form h2{border-top:1px solid var(--token-color-foreground-action);padding-top:1.4em;margin-top:.2em;margin-bottom:.6em}.consul-intention-permission-form .consul-intention-permission-header-form{margin-top:10px}.consul-intention-permission-form .consul-intention-permission-header-form fieldset>div,.consul-intention-permission-form fieldset:nth-child(2)>div{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));grid-gap:12px}.consul-intention-permission-form fieldset:nth-child(2)>div label:last-child{grid-column:span 2}.consul-intention-permission-form .ember-basic-dropdown-trigger{padding:5px}.consul-intention-permission-form .checkbox-group{flex-direction:column}.consul-intention-permission-header-list{max-height:200px;overflow:auto}.consul-lock-session-list button{margin-right:var(--horizontal-padding)}.consul-lock-session-form{overflow:hidden}.consul-server-list ul{display:grid;grid-template-columns:repeat(4,minmax(215px,25%));gap:12px}.consul-server-list a:hover div{--tone-border:var(--token-color-foreground-faint)}.consul-server-card .name+dd{color:var(--token-color-hashicorp-brand);animation-name:typo-truncate}.voting-status-non-voter.consul-server-card .health-status+dd{background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-faint)}.consul-server-card:not(.voting-status-non-voter) .health-status.healthy+dd{background-color:var(--token-color-surface-success);color:var(--token-color-palette-green-400)}.consul-server-card:not(.voting-status-non-voter) .health-status:not(.healthy)+dd{background-color:var(--token-color-surface-critical);color:var(--token-color-foreground-critical)}.consul-server-card .health-status+dd::before{--icon-size:icon-000;content:""}.consul-server-card .health-status.healthy+dd::before{--icon-name:icon-check}.consul-server-card .health-status:not(.healthy)+dd::before{--icon-name:icon-x}.consul-server-card{position:relative;overflow:hidden;--padding-x:24px;--padding-y:24px;padding:var(--padding-y) var(--padding-x);--tile-size:3rem}.consul-auth-method-binding-list h2,.consul-auth-method-view section h2{padding-bottom:12px}.voting-status-leader.consul-server-card .name{position:absolute!important}.consul-server-card dd:not(:last-of-type){margin-bottom:calc(var(--padding-y)/ 2)}.voting-status-leader.consul-server-card dd{margin-left:calc(var(--tile-size) + 1rem)}.consul-auth-method-list ul .locality::before{margin-right:4px}.consul-auth-method-view{margin-bottom:32px}.consul-auth-method-view section{width:100%;position:relative;overflow-y:auto}.consul-auth-method-view section table thead td{color:var(--token-color-foreground-faint)}.consul-auth-method-view section table tbody td{color:var(--token-color-hashicorp-brand)}.consul-auth-method-view section table tbody tr{cursor:default}.consul-auth-method-view section table tbody tr:hover{box-shadow:none}.consul-auth-method-view section dt{width:30%}.consul-auth-method-view section dd{width:70%}.consul-auth-method-binding-list p{margin-bottom:4px!important}.consul-auth-method-binding-list code{background-color:var(--token-color-surface-strong);padding:0 12px}.consul-auth-method-nspace-list thead td{color:var(--token-color-foreground-faint)!important}.consul-auth-method-nspace-list tbody td{color:var(--token-color-hashicorp-brand)}.consul-auth-method-nspace-list tbody tr{cursor:default}.consul-auth-method-nspace-list tbody tr:hover{box-shadow:none}.role-selector [name="role[state]"],.role-selector [name="role[state]"]+*{display:none}.role-selector [name="role[state]"]:checked+*{display:block}.topology-notices button{color:var(--token-color-foreground-action);float:right;margin-top:16px;margin-bottom:32px}#metrics-container .link a,.topology-container{color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card:not(:last-child),#upstream-column #upstream-container:not(:last-child),#upstream-container .topology-metrics-card:not(:last-child){margin-bottom:8px}#downstream-container,#metrics-container,#upstream-container{border-radius:var(--decor-radius-100);border:1px solid;border-color:var(--token-color-surface-interactive-active)}#downstream-container,#upstream-container{background-color:var(--token-color-surface-strong);padding:12px}#downstream-container>div:first-child{display:inline-flex}#downstream-container>div:first-child span::before{background-color:var(--token-color-foreground-faint)}#metrics-container div:first-child{background-color:var(--token-color-surface-primary);padding:12px;border:none}#metrics-container .link{background-color:var(--token-color-surface-strong);padding:18px}#metrics-container .link a:hover{color:var(--token-color-foreground-action)}#downstream-lines svg path,#upstream-lines svg path{fill:transparent}#downstream-lines svg .allow-arrow,#upstream-lines svg .allow-arrow{fill:var(--token-color-palette-neutral-300);stroke-linejoin:round}#downstream-lines svg .allow-arrow,#downstream-lines svg .allow-dot,#downstream-lines svg path,#upstream-lines svg .allow-arrow,#upstream-lines svg .allow-dot,#upstream-lines svg path{stroke:var(--token-color-palette-neutral-300);stroke-width:2}#downstream-lines svg path[data-permission=empty],#downstream-lines svg path[data-permission=not-defined],#upstream-lines svg path[data-permission=empty],#upstream-lines svg path[data-permission=not-defined]{stroke-dasharray:4}#downstream-lines svg path[data-permission=deny],#upstream-lines svg path[data-permission=deny]{stroke:var(--token-color-foreground-critical)}#downstream-lines svg .deny-dot,#upstream-lines svg .deny-dot{stroke:var(--token-color-foreground-critical);stroke-width:2}#downstream-lines svg .deny-arrow,#upstream-lines svg .deny-arrow{fill:var(--token-color-foreground-critical);stroke:var(--token-color-foreground-critical);stroke-linejoin:round}.topology-notices{display:flow-root}.topology-container{display:grid;height:100%;align-items:start;grid-template-columns:2fr 1fr 2fr 1fr 2fr;grid-template-rows:50px 1fr 50px;grid-template-areas:"down-cards down-lines . up-lines up-cards" "down-cards down-lines metrics up-lines up-cards" "down-cards down-lines . up-lines up-cards"}#downstream-container{grid-area:down-cards}#downstream-lines{grid-area:down-lines;margin-left:-20px}#upstream-lines{grid-area:up-lines;margin-right:-20px}#upstream-column{grid-area:up-cards}#downstream-lines,#upstream-lines{position:relative}#metrics-container{grid-area:metrics}#metrics-container .link a::before{background-color:var(--token-color-foreground-faint);margin-right:4px}#downstream-container .topology-metrics-card,#upstream-container .topology-metrics-card{display:block;color:var(--token-color-foreground-faint);overflow:hidden;background-color:var(--token-color-surface-primary);border-radius:var(--decor-radius-100);border:1px solid;border-color:var(--token-color-surface-interactive-active)}#downstream-container .topology-metrics-card p,#upstream-container .topology-metrics-card p{padding:12px 12px 0;margin-bottom:0!important}#downstream-container .topology-metrics-card p.empty,#upstream-container .topology-metrics-card p.empty{padding:12px!important}#downstream-container .topology-metrics-card div dl,#upstream-container .topology-metrics-card div dl{display:inline-flex;margin-right:8px}#downstream-container .topology-metrics-card div dd,#upstream-container .topology-metrics-card div dd{color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card div span,#upstream-container .topology-metrics-card div span{margin-right:8px}#downstream-container .topology-metrics-card div dt::before,#downstream-container .topology-metrics-card div span::before,#upstream-container .topology-metrics-card div dt::before,#upstream-container .topology-metrics-card div span::before{margin-right:4px}#downstream-container .topology-metrics-card div .health dt::before,#downstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .nspace dt::before{margin-top:2px}#downstream-container .topology-metrics-card div .health dt::before,#downstream-container .topology-metrics-card div .nspace dt::before,#downstream-container .topology-metrics-card div .partition dt::before,#upstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .partition dt::before{--icon-color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card div .passing::before,#upstream-container .topology-metrics-card div .passing::before{--icon-color:var(--token-color-foreground-success)}#downstream-container .topology-metrics-card div .warning::before,#upstream-container .topology-metrics-card div .warning::before{--icon-color:var(--token-color-foreground-warning)}#downstream-container .topology-metrics-card div .critical::before,#upstream-container .topology-metrics-card div .critical::before{--icon-color:var(--token-color-foreground-critical)}#downstream-container .topology-metrics-card div .empty::before,#upstream-container .topology-metrics-card div .empty::before{--icon-color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card .details,#upstream-container .topology-metrics-card .details{padding:0 12px 12px}#downstream-container .topology-metrics-card .details>:not(:last-child),#upstream-container .topology-metrics-card .details>:not(:last-child){padding-bottom:6px}#downstream-container .topology-metrics-card .details .group,#upstream-container .topology-metrics-card .details .group{display:grid;grid-template-columns:20px 1fr;grid-template-rows:repeat(2,1fr);grid-template-areas:"partition partition" "union namespace"}#downstream-container .topology-metrics-card .details .group span,#upstream-container .topology-metrics-card .details .group span{display:inline-block;grid-area:union;padding-left:7px;margin-right:0}#downstream-container .topology-metrics-card .details .group span::before,#upstream-container .topology-metrics-card .details .group span::before{margin-right:0;--icon-color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card .details .group dl:first-child,#upstream-container .topology-metrics-card .details .group dl:first-child{grid-area:partition;padding-bottom:6px}#downstream-container .topology-metrics-card .details .group dl:nth-child(2),#upstream-container .topology-metrics-card .details .group dl:nth-child(2){grid-area:namespace}.topology-metrics-source-type{margin:6px 0 6px 12px;display:table}.topology-metrics-popover>button{position:absolute;transform:translate(-50%,-50%);background-color:var(--token-color-surface-primary);padding:1px}.topology-metrics-popover>button:hover{cursor:pointer}.topology-metrics-popover>button:disabled,html[data-route^="dc.nodes.show.metadata"] table tr{cursor:default}.topology-metrics-popover>button:active,.topology-metrics-popover>button:focus{outline:0}.topology-metrics-popover.deny .informed-action header::before{display:none}.topology-metrics-popover.deny .tippy-arrow::after,.topology-metrics-popover.deny>button::before{--icon-color:var(--token-color-foreground-critical)}.topology-metrics-popover.not-defined .tippy-arrow::after,.topology-metrics-popover.not-defined>button::before{--icon-color:var(--token-color-vault-brand)}#metrics-container .sparkline-wrapper svg path{stroke-width:0}#metrics-container .sparkline-wrapper .tooltip{padding:0 0 10px;border:1px solid var(--token-color-palette-neutral-300);background:#fff;border-radius:2px;box-sizing:border-box;box-shadow:var(--token-elevation-higher-box-shadow)}#metrics-container .sparkline-wrapper .tooltip .sparkline-time{padding:8px 10px;color:#000;border-bottom:1px solid var(--token-color-surface-interactive-active);margin-bottom:4px;text-align:center}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-legend,#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-sum{border:0;padding:3px 10px 0}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-sum{border-top:1px solid var(--token-color-surface-interactive-active);margin-top:4px;padding:8px 10px 0}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-legend-color{width:12px;height:12px;border-radius:2px;margin:0 5px 0 0;padding:0}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-legend-value,#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-sum-value{float:right}#metrics-container .sparkline-wrapper div.tooltip:before{content:"";display:block;position:absolute;width:12px;height:12px;left:15px;bottom:-7px;border:1px solid var(--token-color-palette-neutral-300);border-top:0;border-left:0;background:#fff;transform:rotate(45deg)}.sparkline-key h3::before{margin:2px 3px 0 0;font-size:var(--token-typography-body-200-font-size)}.sparkline-key h3{color:var(--token-color-foreground-strong)}.sparkline-key .sparkline-key-content dd,.sparkline-key-link{color:var(--token-color-foreground-faint)}.sparkline-key-link:hover{color:var(--token-color-foreground-action)}#metrics-container:hover .sparkline-key-link::before{margin:1px 3px 0 0;font-size:12px}#metrics-container div .sparkline-wrapper,#metrics-container div .sparkline-wrapper svg.sparkline{width:100%;height:70px;padding:0;margin:0}#metrics-container div .sparkline-wrapper{position:relative}#metrics-container div .sparkline-wrapper .tooltip{visibility:hidden;position:absolute;z-index:10;bottom:78px;width:217px}#metrics-container div .sparkline-wrapper .sparkline-tt-legend-color{display:inline-block}#metrics-container div .sparkline-wrapper .topology-metrics-error,#metrics-container div .sparkline-wrapper .topology-metrics-loader{padding-top:15px}.sparkline-key .sparkline-key-content{width:500px;min-height:100px}.sparkline-key .sparkline-key-content dl{padding:10px 0 0}.sparkline-key .sparkline-key-content dt{font-weight:var(--token-typography-font-weight-semibold);width:125px;float:left}.sparkline-key .sparkline-key-content dd{margin:0 0 12px 135px}.sparkline-key-link{visibility:hidden;float:right;margin-top:-35px;margin-right:12px}#metrics-container:hover .sparkline-key-link{visibility:visible}.topology-metrics-stats{padding:12px 12px 0;display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;width:100%;border-top:1px solid var(--token-color-surface-interactive-active)}.topology-metrics-stats dl{display:flex;padding-bottom:12px}.topology-metrics-stats dt{margin-right:5px;line-height:1.5em!important}.topology-metrics-stats dd{color:var(--token-color-foreground-disabled)!important}.topology-metrics-stats span{padding-bottom:12px}.topology-metrics-status-error,.topology-metrics-status-loader{color:var(--token-color-foreground-faint);text-align:center;margin:0 auto!important;display:block}.topology-metrics-status-error span::before,.topology-metrics-status-loader span::before{background-color:var(--token-color-foreground-faint)}span.topology-metrics-status-loader::after{--icon-name:var(--icon-loading);content:"";margin-left:.5rem}.consul-node-peer-info .consul-node-peer-info__name,.consul-peer-info .consul-peer-info__description{margin-left:4px}.consul-intention-list-table__meta-info{display:flex}.consul-intention-list-table__meta-info .consul-intention-list-table__meta-info__peer{display:flex;align-items:center}.consul-node-peer-info,.peerings-badge{align-items:center;display:flex}.consul-peer-search-bar .value-active span::before,.consul-peer-search-bar .value-deleting span::before,.consul-peer-search-bar .value-establishing span::before,.consul-peer-search-bar .value-failing span::before,.consul-peer-search-bar .value-pending span::before,.consul-peer-search-bar .value-terminated span::before{--icon-size:icon-000;content:""}.consul-peer-search-bar .value-active span,.consul-peer-search-bar .value-deleting span,.consul-peer-search-bar .value-establishing span,.consul-peer-search-bar .value-failing span,.consul-peer-search-bar .value-pending span,.consul-peer-search-bar .value-terminated span{font-size:var(--token-typography-body-200-font-size)}.consul-peer-search-bar .value-pending span::before{--icon-name:icon-running;--icon-color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-pending span{background-color:var(--token-color-consul-surface);color:var(--token-color-consul-foreground)}.consul-peer-search-bar .value-establishing span::before{--icon-name:icon-running;--icon-color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-establishing span{background-color:var(--token-color-palette-blue-50);color:var(--token-color-palette-blue-200)}.consul-peer-search-bar .value-active span::before{--icon-name:icon-check;--icon-color:var(--token-color-palette-green-400)}.consul-peer-search-bar .value-active span{background-color:var(--token-color-palette-green-50);color:var(--token-color-palette-green-200)}.consul-peer-search-bar .value-failing span::before{--icon-name:icon-x;--icon-color:var(--token-color-palette-red-200)}.consul-peer-search-bar .value-failing span{background-color:var(--token-color-palette-red-50);color:var(--token-color-palette-red-200)}.consul-peer-search-bar .value-terminated span::before{--icon-name:icon-x-square;--icon-color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-terminated span{background-color:var(--token-color-palette-neutral-200);color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-deleting span::before{--icon-name:icon-loading;--icon-color:var(--token-color-foreground-warning-on-surface)}.consul-peer-search-bar .value-deleting span{background-color:var(--token-color-surface-warning);color:var(--token-color-foreground-warning-on-surface)}.peers__list__peer-detail{display:flex;align-content:center;gap:18px}.border-bottom-primary{border-bottom:1px solid var(--token-color-border-primary)}.peerings-badge{justify-content:center;padding:2px 8px;border-radius:5px;gap:4px}.peerings-badge.active{background:var(--token-color-surface-success);color:var(--token-color-foreground-success)}.peerings-badge.pending{background:var(--token-color-consul-surface);color:var(--token-color-consul-brand)}.peerings-badge.establishing{background:var(--token-color-surface-action);color:var(--token-color-foreground-action)}.peerings-badge.failing{background:var(--token-color-surface-critical);color:var(--token-color-foreground-critical)}.peerings-badge.deleting{background:var(--token-color-surface-warning);color:var(--token-color-foreground-warning-on-surface)}.peerings-badge.terminated,.peerings-badge.undefined{background:var(--token-color-surface-interactive-active);color:var(--token-color-foreground-primary)}.consul-peer-info,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dt{color:var(--token-color-foreground-faint)}.consul-peer-info{background:var(--token-color-surface-faint);padding:0 8px;border-radius:2px;display:flex;align-items:center}.consul-peer-form{width:416px}.consul-peer-form nav{margin-bottom:20px}.consul-peer-form-generate{width:416px;min-height:200px}.consul-peer-form-generate ol{list-style-position:outside;list-style-type:none;counter-reset:hexagonal-counter;position:relative}.consul-peer-form-generate ol::before{content:"";border-left:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300);height:100%;position:absolute;left:2rem}.consul-peer-form-generate li{counter-increment:hexagonal-counter;position:relative;margin-left:60px;margin-bottom:1rem}.consul-peer-form-generate li .copyable-code{margin-top:1rem}.consul-peer-form-generate li::before{--icon-name:icon-hexagon;--icon-size:icon-600;content:"";position:absolute;z-index:2}.consul-peer-form-generate li::after{content:counter(hexagonal-counter);position:absolute;top:0;background-color:var(--token-color-palette-neutral-0);z-index:1;text-align:center}.consul-peer-form-generate li::after,.consul-peer-form-generate li::before{left:-2.4rem;width:20px;height:20px}.agentless-node-notice .hds-alert__title{display:flex;justify-content:space-between}.definition-table dt{line-height:var(--token-typography-body-300-line-height)}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label{line-height:var(--token-typography-body-100-line-height)}.app-view h1 em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.consul-intention-list td.destination em,.consul-intention-list td.source em,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] table th em,.oidc-select label>em,.type-toggle>em,main .type-password>em,main .type-select>em,main .type-text>em,main form button+em,main table th em{font-style:normal}.consul-exposed-path-list>ul>li>.header :not(button),.consul-lock-session-list ul>li:not(:first-child)>.header :not(button),.consul-upstream-instance-list li>.header :not(button),.list-collection>ul>li:not(:first-child)>.header :not(button){font-size:inherit;font-weight:inherit}@media (max-width:420px) and (-webkit-min-device-pixel-ratio:0){input{font-size:var(--token-typography-body-300-font-size)!important}}#wrapper,#wrapper>footer>*,.modal-dialog>*,main>*{box-sizing:border-box}html[data-route$=create] main,html[data-route$=edit] main{max-width:1260px}fieldset [role=group]{display:flex;flex-wrap:wrap;flex-direction:row}.outlet[data-state=loading],html.ember-loading .view-loader,html:not(.has-nspaces) [class*=nspace-],html:not(.has-partitions) [class*=partition-],html[data-state=idle] .view-loader{display:none}[role=group] fieldset{width:50%}[role=group] fieldset:not(:first-of-type){padding-left:20px;border-left:1px solid;border-left:var(--token-color-foreground-faint)}[role=group] fieldset:not(:last-of-type){padding-right:20px}.app-view{margin-top:50px}@media (max-width:849px){html:not(.with-breadcrumbs) .app-view{margin-top:10px}}html body>.brand-loader{transition-property:transform,opacity;transform:translate(0,0);opacity:1}html[data-state]:not(.ember-loading) body>.brand-loader{opacity:0}@media (min-width:900px){html[data-state] body>.brand-loader{transform:translate(calc(var(--chrome-width)/ 2),0)}}html[data-route$=create] .app-view>header+div>:first-child,html[data-route$=edit] .app-view>header+div>:first-child{margin-top:1.8em}.app-view>div .container,.app-view>div .tab-section .consul-health-check-list,.app-view>div .tab-section>.search-bar+p,.app-view>div .tab-section>:first-child:not(.filter-bar):not(table){margin-top:1.25em}.consul-upstream-instance-list,html[data-route^="dc.nodes.show.sessions"] .consul-lock-session-list{margin-top:0!important}.consul-auth-method-list ul,.consul-node-list ul,.consul-nspace-list ul,.consul-peer-list ul,.consul-policy-list ul,.consul-role-list ul,.consul-service-instance-list ul,.consul-token-list ul,html[data-route="dc.services.index"] .consul-service-list ul,html[data-route^="dc.nodes.show.sessions"] .consul-lock-session-list ul{border-top-width:0!important}#wrapper{display:flex;min-height:100vh}main{padding:0 48px;position:relative;flex:1}html:not([data-route$=index]):not([data-route$=instances]) main{margin-bottom:2em}@media (max-width:849px){.actions button.copy-btn{margin-top:-56px;padding:0}}.modal-dialog [role=document] p:not(:last-child),main p:not(:last-child){margin-bottom:1em}.modal-dialog [role=document] form+div .with-confirmation,.modal-dialog [role=document] form:not(.filter-bar),main form+div .with-confirmation,main form:not(.filter-bar){margin-bottom:2em}@media (max-width:420px){main form [type=reset]{float:right;margin-right:0!important}}html[data-route^="dc.services.show"] .app-view .actions .external-dashboard{position:absolute;top:50px;right:0}html[data-route^="dc.services.instance"] .app-view>header dl{float:left;margin-top:19px;margin-bottom:23px;margin-right:50px}html[data-route^="dc.services.instance"] .app-view>header dt{font-weight:var(--token-typography-font-weight-bold)}html[data-route^="dc.services.instance"] .tab-nav{border-top:var(--decor-border-100)}html[data-route^="dc.services.instance"] .tab-section section:not(:last-child){border-bottom:var(--decor-border-100);padding-bottom:24px}html[data-route^="dc.services.instance"] .tab-nav,html[data-route^="dc.services.instance"] .tab-section section:not(:last-child){border-color:var(--token-color-surface-interactive-active)}html[data-route^="dc.services.instance.metadata"] .tab-section section h2{margin:24px 0 12px}html[data-route^="dc.kv"] .type-toggle{float:right;margin-bottom:0!important}html[data-route^="dc.kv.edit"] h2{border-bottom:var(--decor-border-200);border-color:var(--token-color-surface-interactive-active);padding-bottom:.2em;margin-bottom:.5em}html[data-route^="dc.acls.index"] main td strong{margin-right:3px}@media (max-width:420px){html[data-route^="dc.acls.create"] main header .actions,html[data-route^="dc.acls.edit"] main header .actions{float:none;display:flex;justify-content:space-between;margin-bottom:1em}html[data-route^="dc.acls.create"] main header .actions .with-feedback,html[data-route^="dc.acls.edit"] main header .actions .with-feedback{position:absolute;right:0}html[data-route^="dc.acls.create"] main header .actions .with-confirmation,html[data-route^="dc.acls.edit"] main header .actions .with-confirmation{margin-top:0}}html[data-route^="dc.intentions.edit"] .definition-table{margin-bottom:1em}section[data-route="dc.show.serverstatus"] .server-failure-tolerance{box-shadow:none;padding:var(--padding-y) var(--padding-x);max-width:770px;display:flex;flex-wrap:wrap}section[data-route="dc.show.serverstatus"] .server-failure-tolerance>header{width:100%;display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding-bottom:.5rem;margin-bottom:1rem;border-bottom:var(--decor-border-100);border-color:var(--tone-border)}section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em{background-color:var(--token-color-surface-interactive-active);text-transform:uppercase;font-style:normal}section[data-route="dc.show.serverstatus"] .server-failure-tolerance>section{width:50%}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dl,section[data-route="dc.show.serverstatus"] .server-failure-tolerance>section{display:flex;flex-direction:column}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dl{flex-grow:1;justify-content:space-between}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dl.warning dd::before{--icon-name:icon-alert-circle;--icon-size:icon-800;--icon-color:var(--token-color-foreground-warning);content:"";margin-right:.5rem}section[data-route="dc.show.serverstatus"] .server-failure-tolerance section:first-of-type dl{padding-right:1.5rem}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dd{display:flex;align-items:center;color:var(--token-color-hashicorp-brand)}section[data-route="dc.show.serverstatus"] .server-failure-tolerance header span::before{--icon-name:icon-info;--icon-size:icon-300;--icon-color:var(--token-color-foreground-faint);vertical-align:unset;content:""}section[data-route="dc.show.serverstatus"] section:not([class*=-tolerance]) h2{margin-top:1.5rem;margin-bottom:1.5rem}section[data-route="dc.show.serverstatus"] section:not([class*=-tolerance]) header{margin-top:18px;margin-bottom:18px}section[data-route="dc.show.serverstatus"] .redundancy-zones section header{display:flow-root}section[data-route="dc.show.serverstatus"] .redundancy-zones section header h3{float:left;margin-right:.5rem}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not(.warning){background-color:var(--token-color-surface-strong)}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.warning{background-color:var(--token-color-border-warning);color:var(--token-color-palette-amber-400)}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.warning::before{--icon-name:icon-alert-circle;--icon-size:icon-000;margin-right:.312rem;content:""}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dt::after{content:":";display:inline-block;vertical-align:revert;background-color:transparent}section[data-route="dc.show.license"] .validity p{color:var(--token-color-foreground-faint)}section[data-route="dc.show.license"] .validity dl dt::before{content:"";margin-right:.25rem}section[data-route="dc.show.license"] .validity dl .expired::before{--icon-name:icon-x-circle;--icon-color:var(--token-color-foreground-critical)}section[data-route="dc.show.license"] .validity dl .warning::before{--icon-name:icon-alert-circle;--icon-color:var(--token-color-foreground-warning)}section[data-route="dc.show.license"] .validity dl .valid:not(.warning)::before{--icon-name:icon-check-circle;--icon-color:var(--token-color-foreground-success)}section[data-route="dc.show.license"] aside{box-shadow:none;padding:var(--padding-y) var(--padding-x);width:40%;min-width:413px;margin-top:1rem}section[data-route="dc.show.license"] aside header{margin-bottom:1rem}.prefers-reduced-motion{--icon-loading:icon-loading}@media (prefers-reduced-motion){:root{--hds-app-sidenav-animation-duration:0;--icon-loading:icon-loading}}.consul-intention-fieldsets .value->:last-child::before,.consul-intention-fieldsets .value-allow>:last-child::before,.consul-intention-fieldsets .value-deny>:last-child::before{--icon-size:icon-500;--icon-resolution:0.5}.consul-intention-fieldsets .value-allow>:last-child::before,.consul-intention-list td.intent-allow strong::before,.consul-intention-permission-list .intent-allow::before,.consul-intention-search-bar .value-allow span::before{--icon-name:icon-arrow-right;--icon-color:var(--token-color-foreground-success-on-surface)}.consul-intention-fieldsets .value-deny>:last-child::before,.consul-intention-list td.intent-deny strong::before,.consul-intention-permission-list .intent-deny::before,.consul-intention-search-bar .value-deny span::before{--icon-name:icon-skip;--icon-color:var(--token-color-foreground-critical-on-surface)}.consul-intention-fieldsets .value->:last-child::before,.consul-intention-list td.intent- strong::before,.consul-intention-search-bar .value- span::before{--icon-name:icon-layers}*{border-width:0}.animatable.tab-nav ul::after,.consul-auth-method-type,.consul-external-source,.consul-intention-action-warn-modal button.dangerous,.consul-intention-action-warn-modal button.dangerous:disabled,.consul-intention-action-warn-modal button.dangerous:focus,.consul-intention-action-warn-modal button.dangerous:hover:active,.consul-intention-action-warn-modal button.dangerous:hover:not(:disabled):not(:active),.consul-intention-list td.intent- strong,.consul-intention-permission-form button.type-submit,.consul-intention-permission-form button.type-submit:disabled,.consul-intention-permission-form button.type-submit:focus:not(:disabled),.consul-intention-permission-form button.type-submit:hover:not(:disabled),.consul-intention-search-bar .value- span,.consul-kind,.consul-source,.consul-transparent-proxy,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:first-child,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:focus:first-child,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:hover:first-child,.discovery-chain .route-card>header ul li,.informed-action>ul>.dangerous>*,.informed-action>ul>.dangerous>:focus,.informed-action>ul>.dangerous>:hover,.leader,.menu-panel>ul>li.dangerous>:first-child,.menu-panel>ul>li.dangerous>:focus:first-child,.menu-panel>ul>li.dangerous>:hover:first-child,.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,.tab-nav .selected>*,.topology-metrics-source-type,html[data-route^="dc.acls.index"] main td strong,span.policy-node-identity,span.policy-service-identity,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child{border-style:solid}.consul-auth-method-type,.consul-external-source,.consul-kind,.consul-source,.consul-transparent-proxy,.leader,.topology-metrics-source-type,span.policy-node-identity,span.policy-service-identity{background-color:var(--token-color-surface-strong);border-color:var(--token-color-foreground-faint);color:var(--token-color-foreground-primary)}.consul-intention-list td.intent- strong,.consul-intention-search-bar .value- span,.discovery-chain .route-card>header ul li,.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,html[data-route^="dc.acls.index"] main td strong{background-color:var(--token-color-surface-strong);border-color:var(--token-color-palette-neutral-300);color:var(--token-color-foreground-strong)}.animatable.tab-nav ul::after,.consul-intention-permission-form button.type-submit,.consul-intention-permission-form button.type-submit:disabled,.tab-nav .selected>*{background-color:var(--token-color-surface-primary);border-color:var(--token-color-foreground-action);color:var(--token-color-foreground-action)}.consul-intention-permission-form button.type-submit:focus:not(:disabled),.consul-intention-permission-form button.type-submit:hover:not(:disabled){background-color:var(--token-color-surface-action);border-color:var(--token-color-foreground-action);color:var(--token-color-palette-blue-500)}.consul-intention-action-warn-modal button.dangerous,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:first-child,.informed-action>ul>.dangerous>*,.menu-panel>ul>li.dangerous>:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child{background-color:transparent;border-color:var(--token-color-foreground-critical);color:var(--token-color-foreground-critical)}.consul-intention-action-warn-modal button.dangerous:disabled{background-color:var(--token-color-border-critical);border-color:var(--token-color-foreground-disabled);color:var(--token-color-surface-primary)}.consul-intention-action-warn-modal button.dangerous:focus,.consul-intention-action-warn-modal button.dangerous:hover:not(:disabled):not(:active),.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:focus:first-child,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:hover:first-child,.informed-action>ul>.dangerous>:focus,.informed-action>ul>.dangerous>:hover,.menu-panel>ul>li.dangerous>:focus:first-child,.menu-panel>ul>li.dangerous>:hover:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child{background-color:var(--token-color-foreground-critical);border-color:var(--token-color-foreground-critical-high-contrast);color:var(--token-color-surface-primary)}.consul-intention-action-warn-modal button.dangerous:hover:active{background-color:var(--token-color-palette-red-400);border-color:var(--token-color-foreground-critical-high-contrast);color:var(--token-color-surface-primary)}.hover\:scale-125:hover{--tw-scale-x:1.25;--tw-scale-y:1.25}.group:hover .group-hover\:opacity-100{opacity:1} \ No newline at end of file diff --git a/agent/uiserver/dist/assets/consul-ui-88f8ddeb1f6a751c68c9f1de8978befa.js b/agent/uiserver/dist/assets/consul-ui-a3d723b2486613aa25201645e617bbf2.js similarity index 93% rename from agent/uiserver/dist/assets/consul-ui-88f8ddeb1f6a751c68c9f1de8978befa.js rename to agent/uiserver/dist/assets/consul-ui-a3d723b2486613aa25201645e617bbf2.js index 15e96ebf2e..0a6ee6ad76 100644 --- a/agent/uiserver/dist/assets/consul-ui-88f8ddeb1f6a751c68c9f1de8978befa.js +++ b/agent/uiserver/dist/assets/consul-ui-a3d723b2486613aa25201645e617bbf2.js @@ -771,7 +771,7 @@ var s,c,d,p,f,m e.default=u,(0,t.setComponentTemplate)(a,u)})),define("consul-ui/components/consul/datacenter/selector/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/object","@glimmer/tracking"],(function(e,t,n,l,r,i){var o,a function u(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const s=(0,n.createTemplateFactory)({id:"5vaQzlVR",block:'[[[1,"\\n"],[44,[[30,1]],[[[41,[28,[37,2],[[30,3,["length"]],1],null],[[[1," "],[8,[30,2,["Title"]],[[24,0,"consul-side-nav__selector-title"]],null,[["default"],[[[[1,[28,[35,3],["components.hashicorp-consul.side-nav.datacenters.title"],null]]],[]]]]],[1,"\\n "],[8,[39,4],[[24,0,"consul-datacenter-selector"]],[["@list","@items","@item","@key","@icon","@placeholder","@description"],[[30,2],[28,[37,5],["Primary:desc","Local:desc","Name:asc",[30,3]],null],[30,4],"Name","server-cluster",[28,[37,3],["components.hashicorp-consul.side-nav.datacenters.placeholder"],null],[28,[37,3],["components.hashicorp-consul.side-nav.datacenters.description"],null]]],[["default"],[[[[1,"\\n "],[8,[30,5,["Checkmark"]],[[24,0,"consul-datacenter-selector__item"]],[["@selected","@href","@isHrefExternal"],[[28,[37,6],[[30,4,["Name"]],[30,6,["Name"]]],null],[28,[37,7],["."],[["params"],[[28,[37,8],null,[["dc","partition","nspace"],[[30,6,["Name"]],[27],[52,[28,[37,2],[[30,7,["length"]],0],null],[30,7],[27]]]]]]]],false]],[["default"],[[[[1,"\\n "],[10,1],[14,0,"consul-datacenter-selector__dc-name"],[12],[1,"\\n "],[1,[30,6,["Name"]]],[1,"\\n\\n"],[41,[28,[37,9],[[30,6,["Local"]],[30,6,["Primary"]]],null],[[[1," "],[10,1],[14,0,"consul-datacenter-selector__badges"],[12],[1,"\\n"],[41,[30,6,["Primary"]],[[[1," "],[8,[39,10],null,[["@text"],["Primary"]],null],[1,"\\n"]],[]],null],[41,[30,6,["Local"]],[[[1," "],[8,[39,10],null,[["@text"],["Local"]],null],[1,"\\n"]],[]],null],[1," "],[13],[1,"\\n"]],[]],null],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[5,6]]]]],[1,"\\n"]],[]],[[[1," "],[8,[30,2,["Item"]],[[24,0,"consul-side-nav__datacenter"]],null,[["default"],[[[[1,"\\n "],[8,[39,11],null,[["@name","@color"],["server-cluster","var(--token-form-control-disabled-foreground-color)"]],null],[1,"\\n "],[8,[39,12],null,[["@size","@color"],["200","disabled"]],[["default"],[[[[1,[30,4,["Name"]]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]]],[2]]]],["@list","SNL","@dcs","@dc","Dropdown","item","@nspace"],false,["let","if","gt","t","nav-selector","sort-by","eq","href-to","hash","or","hds/badge","flight-icon","hds/text/display"]]',moduleName:"consul-ui/components/consul/datacenter/selector/index.hbs",isStrictMode:!1}) +const s=(0,n.createTemplateFactory)({id:"xS/PrPr6",block:'[[[1,"\\n"],[44,[[30,1]],[[[41,[28,[37,2],[[30,3,["length"]],1],null],[[[1," "],[8,[30,2,["Title"]],[[24,0,"consul-side-nav__selector-title"]],null,[["default"],[[[[1,[28,[35,3],["components.hashicorp-consul.side-nav.datacenters.title"],null]]],[]]]]],[1,"\\n "],[8,[39,4],[[24,0,"consul-datacenter-selector"]],[["@list","@items","@item","@key","@icon","@placeholder","@description"],[[30,2],[28,[37,5],["Primary:desc","Local:desc","Name:asc",[30,3]],null],[30,4],"Name","server-cluster",[28,[37,3],["components.hashicorp-consul.side-nav.datacenters.placeholder"],null],[28,[37,3],["components.hashicorp-consul.side-nav.datacenters.description"],null]]],[["default"],[[[[1,"\\n "],[8,[30,5,["Dropdown","Checkmark"]],[[24,0,"consul-datacenter-selector__item"]],[["@selected","@href","@isHrefExternal"],[[28,[37,6],[[30,4,["Name"]],[30,5,["item","Name"]]],null],[28,[37,7],["."],[["params"],[[28,[37,8],null,[["dc","partition","nspace"],[[30,5,["item","Name"]],[27],[52,[28,[37,2],[[30,6,["length"]],0],null],[30,6],[27]]]]]]]],false]],[["default"],[[[[1,"\\n "],[10,1],[14,0,"consul-datacenter-selector__dc-name"],[12],[1,"\\n "],[1,[30,5,["item","Name"]]],[1,"\\n\\n"],[41,[28,[37,9],[[30,5,["item","Local"]],[30,5,["item","Primary"]]],null],[[[1," "],[10,1],[14,0,"consul-datacenter-selector__badges"],[12],[1,"\\n"],[41,[30,5,["item","Primary"]],[[[1," "],[8,[39,10],null,[["@text"],["Primary"]],null],[1,"\\n"]],[]],null],[41,[30,5,["item","Local"]],[[[1," "],[8,[39,10],null,[["@text"],["Local"]],null],[1,"\\n"]],[]],null],[1," "],[13],[1,"\\n"]],[]],null],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[5]]]]],[1,"\\n"]],[]],[[[1," "],[8,[30,2,["Item"]],[[24,0,"consul-side-nav__datacenter"]],null,[["default"],[[[[1,"\\n "],[8,[39,11],null,[["@name","@color"],["server-cluster","var(--token-form-control-disabled-foreground-color)"]],null],[1,"\\n "],[8,[39,12],null,[["@size","@color"],["200","disabled"]],[["default"],[[[[1,[30,4,["Name"]]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]]],[2]]]],["@list","SNL","@dcs","@dc","Selector","@nspace"],false,["let","if","gt","t","nav-selector","sort-by","eq","href-to","hash","or","hds/badge","flight-icon","hds/text/display"]]',moduleName:"consul-ui/components/consul/datacenter/selector/index.hbs",isStrictMode:!1}) let c=(o=class extends l.default{constructor(){var e,t,n,l super(...arguments),e=this,t="search",l=this,(n=a)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}get filteredItems(){const e=this.search.toLowerCase() return this.args.dcs.filter((t=>t.Name.toLowerCase().includes(e)))}onSearchInput(e){this.search=e.target.value}},a=u(o.prototype,"search",[i.tracked],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return""}}),u(o.prototype,"onSearchInput",[r.action],Object.getOwnPropertyDescriptor(o.prototype,"onSearchInput"),o.prototype),o) @@ -836,14 +836,11 @@ var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/external-source/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"uG5lBIhe",block:'[[[1,"\\n"],[41,[30,1],[[[44,[[28,[37,2],[[30,1]],null]],[[[41,[28,[37,3],[[30,3],[28,[37,4],[[30,2],"consul-api-gateway"],null]],null],[[[1," "],[10,"dl"],[14,0,"tooltip-panel"],[12],[1,"\\n "],[10,"dt"],[12],[1,"\\n "],[11,1],[24,0,"consul-external-source"],[17,4],[12],[1,"\\n "],[8,[39,5],[[24,0,"mr-1.5 w-4 h-4"]],[["@name"],[[28,[37,6],[[30,2]],null]]],null],[1,"\\n Registered via "],[1,[28,[35,7],[[28,[37,8],["common.brand.",[30,2]],null]],null]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[8,[39,9],null,[["@position","@menu"],["left",false]],[["default"],[[[[1,"\\n "],[8,[39,10],null,[["@name"],["header"]],[["default"],[[[[1,"\\n API Gateways manage north-south traffic from external services to services in the Datacenter. For more information, read our documentation.\\n "]],[]]]]],[1,"\\n "],[8,[39,10],null,[["@name"],["menu"]],[["default"],[[[[1,"\\n "],[10,"li"],[14,"role","separator"],[12],[1,"\\n About "],[1,[28,[35,7],[[28,[37,8],["common.brand.",[30,2]],null]],null]],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[14,"role","none"],[14,0,"learn-link"],[12],[1,"\\n "],[10,3],[14,"tabindex","-1"],[14,"role","menuitem"],[15,6,[28,[37,8],[[28,[37,11],["CONSUL_DOCS_LEARN_URL"],null]],null]],[14,"rel","noopener noreferrer"],[14,"target","_blank"],[12],[1,"\\n Learn guides\\n "],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"]],[]],[[[41,[30,2],[[[1," "],[11,1],[24,0,"consul-external-source"],[17,4],[12],[1,"\\n "],[8,[39,5],[[24,0,"mr-1.5 h-4 w-4"]],[["@name","@color"],[[28,[37,6],[[30,2]],null],"var(--token-color-hashicorp-brand)"]],null],[1,"\\n"],[41,[30,5],[[[1," "],[1,[30,5]],[1,"\\n"]],[]],[[[1," Registered via "],[1,[28,[35,7],[[28,[37,8],["common.brand.",[30,2]],null]],null]],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n "]],[]],null]],[]]]],[2]]]],[]],null]],["@item","externalSource","@withInfo","&attrs","@label"],false,["if","let","service/external-source","and","eq","flight-icon","icon-mapping","t","concat","menu-panel","block-slot","env"]]',moduleName:"consul-ui/components/consul/external-source/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})),define("consul-ui/components/consul/hcp/home/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const r=(0,n.createTemplateFactory)({id:"HbjP3hiy",block:'[[[1,"\\n"],[44,[[30,1],[28,[37,1],["CONSUL_HCP_URL"],null]],[[[1," "],[1,[54,[[30,3]]]],[1,"\\n"],[41,[28,[37,4],[[30,2],[30,3]],null],[[[1," "],[8,[30,2,["BackLink"]],null,[["@text","@href","@isHrefExternal"],[[28,[37,5],["components.hashicorp-consul.side-nav.hcp"],null],[30,3],true]],null],[1,"\\n"]],[]],null]],[2,3]]]],["@list","SNL","hcpUrl"],false,["let","env","log","if","and","t"]]',moduleName:"consul-ui/components/consul/hcp/home/index.hbs",isStrictMode:!1}) -var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})) -define("consul-ui/components/consul/health-check/list/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})),define("consul-ui/components/consul/health-check/list/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"1WWZf50M",block:'[[[1,"\\n"],[11,0],[24,0,"consul-health-check-list"],[17,1],[12],[1,"\\n "],[10,"ul"],[12],[1,"\\n"],[42,[28,[37,1],[[28,[37,1],[[30,2]],null]],null],null,[[[1," "],[10,"li"],[15,0,[28,[37,2],["health-check-output ",[30,3,["Status"]]],null]],[12],[1,"\\n "],[10,0],[12],[1,"\\n "],[10,"header"],[12],[1,"\\n "],[10,"h2"],[12],[1,[30,3,["Name"]]],[13],[1,"\\n "],[13],[1,"\\n "],[10,"dl"],[12],[1,"\\n"],[41,[28,[37,4],[[30,3,["Kind"]],"node"],null],[[[1," "],[10,"dt"],[12],[1,"NodeName"],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,3,["Node"]]],[13],[1,"\\n"]],[]],[[[1," "],[10,"dt"],[12],[1,"ServiceName"],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,3,["ServiceName"]]],[13],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"CheckID"],[13],[1,"\\n "],[10,"dd"],[12],[1,[28,[35,5],[[30,3,["CheckID"]],"-"],null]],[13],[1,"\\n "],[13],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Type"],[13],[1,"\\n "],[10,"dd"],[14,"data-health-check-type",""],[12],[1,"\\n "],[1,[30,3,["Type"]]],[1,"\\n"],[41,[30,3,["Exposed"]],[[[1," "],[11,"em"],[4,[38,6],["Expose.checks is set to true, so all registered HTTP and gRPC check paths are exposed through Envoy for the Consul agent."],null],[12],[1,"Exposed"],[13],[1,"\\n"]],[]],null],[1," "],[13],[1,"\\n "],[13],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Notes"],[13],[1,"\\n "],[10,"dd"],[12],[1,[28,[35,5],[[30,3,["Notes"]],"-"],null]],[13],[1,"\\n "],[13],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Output"],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[10,"pre"],[12],[10,"code"],[12],[1,[30,3,["Output"]]],[13],[13],[1,"\\n "],[8,[39,7],null,[["@value","@name"],[[30,3,["Output"]],"output"]],null],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"]],[3]],null],[1," "],[13],[1,"\\n"],[13],[1,"\\n"]],["&attrs","@items","item"],false,["each","-track-array","concat","if","eq","or","tooltip","consul-copy-button"]]',moduleName:"consul-ui/components/consul/health-check/list/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})),define("consul-ui/components/consul/health-check/search-bar/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})) +define("consul-ui/components/consul/health-check/search-bar/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"vj3AOTz9",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-healthcheck-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","filter","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.health-check.search-bar.",[30,3,["status","key"]],".name"],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[28,[37,2],[[28,[37,3],["components.consul.health-check.search-bar.",[30,3,["status","key"]],".options.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null]],null]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,5]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,5],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n"],[41,[30,2,["searchproperty"]],[[[1," "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Optgroup"]],[30,9,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,11],null,[["@value","@selected"],[[30,12],[28,[37,10],[[30,12],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,11],[[30,12]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[12]],null]],[10,11]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-status"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["status","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.consul.status"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,14,["Optgroup"]],[30,14,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[28,[37,4],["passing","warning","critical","empty"],null]],null]],null],null,[[[1," "],[8,[30,16],[[16,0,[29,["value-",[30,17]]]]],[["@value","@selected"],[[30,17],[28,[37,10],[[30,17],[30,2,["status","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[30,17]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,17]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[17]],null]],[15,16]]],[1," "]],[]]]]],[1,"\\n "]],[14]]]]],[1,"\\n"],[41,[30,2,["kind"]],[[[1," "],[8,[30,13,["Select"]],[[24,0,"type-kind"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["kind","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["components.consul.health-check.search-bar.kind.name"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,18,["Optgroup"]],[30,18,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[28,[37,4],["service","node"],null]],null]],null],null,[[[1," "],[8,[30,20],null,[["@value","@selected"],[[30,21],[28,[37,10],[[30,21],[30,2,["kind","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["components.consul.health-check.search-bar.kind.options.",[30,21]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,21]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[21]],null]],[19,20]]],[1," "]],[]]]]],[1,"\\n "]],[18]]]]],[1,"\\n"]],[]],null],[1," "],[8,[30,13,["Select"]],[[24,0,"type-check"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["check","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["components.consul.health-check.search-bar.check.name"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,22,["Optgroup"]],[30,22,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[28,[37,4],["alias","docker","grpc","http","script","serf","tcp","ttl"],null]],null]],null],null,[[[1," "],[8,[30,24],null,[["@value","@selected"],[[30,25],[28,[37,10],[[30,25],[30,2,["check","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["components.consul.health-check.search-bar.check.options.",[30,25]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,25]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[25]],null]],[23,24]]],[1," "]],[]]]]],[1,"\\n "]],[22]]]]],[1,"\\n "]],[13]],[[[1,"\\n "],[8,[30,26,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,27,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,12],[[28,[37,4],[[28,[37,4],["Name:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Name:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null],[28,[37,4],["Status:asc",[28,[37,2],["common.sort.status.asc"],null]],null],[28,[37,4],["Status:desc",[28,[37,2],["common.sort.status.desc"],null]],null],[28,[37,4],["Kind:asc",[28,[37,2],["components.consul.health-check.search-bar.sort.kind.asc"],null]],null],[28,[37,4],["Kind:desc",[28,[37,2],["components.consul.health-check.search-bar.sort.kind.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,13],[[30,29],[30,27,["value"]]],null]],[1,"\\n"]],[29]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,28,["Optgroup"]],[30,28,["Option"]]],[[[1," "],[8,[30,30],null,[["@label"],[[28,[37,2],["common.consul.status"],null]]],[["default"],[[[[1,"\\n "],[8,[30,31],null,[["@value","@selected"],["Status:asc",[28,[37,14],["Status:asc",[30,27,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,31],null,[["@value","@selected"],["Status:desc",[28,[37,14],["Status:desc",[30,27,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,30],null,[["@label"],[[28,[37,2],["components.consul.health-check.search-bar.sort.name.name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,31],null,[["@value","@selected"],["Name:asc",[28,[37,14],["Name:asc",[30,27,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,31],null,[["@value","@selected"],["Name:desc",[28,[37,14],["Name:desc",[30,27,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,30],null,[["@label"],[[28,[37,2],["components.consul.health-check.search-bar.sort.kind.name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,31],null,[["@value","@selected"],["Kind:asc",[28,[37,14],["Kind:asc",[30,27]],null]]],[["default"],[[[[1,"Service to Node"]],[]]]]],[1,"\\n "],[8,[30,31],null,[["@value","@selected"],["Kind:desc",[28,[37,14],["Kind:desc",[30,27]],null]]],[["default"],[[[[1,"Node to Service"]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[30,31]]],[1," "]],[]]]]],[1,"\\n "]],[28]]]]],[1,"\\n "]],[26]]]]]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Optgroup","Option","prop","search","components","Optgroup","Option","state","components","Optgroup","Option","item","components","Optgroup","Option","item","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","action","if","block-slot","each","-track-array","includes","lowercase","from-entries","get","eq"]]',moduleName:"consul-ui/components/consul/health-check/search-bar/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/instance-checks/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -988,11 +985,11 @@ var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/node/peer-info/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"ufFBkLZx",block:'[[[1,"\\n"],[41,[30,1,["PeerName"]],[[[1," "],[10,1],[14,0,"consul-node-peer-info"],[12],[1,"\\n "],[11,"svg"],[24,"width","16"],[24,"height","16"],[24,"viewBox","0 0 16 16"],[24,"fill","none"],[24,"xmlns","http://www.w3.org/2000/svg","http://www.w3.org/2000/xmlns/"],[4,[38,1],["Peer"],null],[12],[1,"\\n "],[10,"path"],[14,"d","M16 8C16 7.80109 15.921 7.61032 15.7803 7.46967L12.2803 3.96967C11.9874 3.67678 11.5126 3.67678 11.2197 3.96967C10.9268 4.26256 10.9268 4.73744 11.2197 5.03033L14.1893 8L11.2197 10.9697C10.9268 11.2626 10.9268 11.7374 11.2197 12.0303C11.5126 12.3232 11.9874 12.3232 12.2803 12.0303L15.7803 8.53033C15.921 8.38968 16 8.19891 16 8Z"],[14,"fill","#77838A"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M0.21967 8.53033C-0.0732233 8.23744 -0.0732233 7.76256 0.21967 7.46967L3.71967 3.96967C4.01256 3.67678 4.48744 3.67678 4.78033 3.96967C5.07322 4.26256 5.07322 4.73744 4.78033 5.03033L1.81066 8L4.78033 10.9697C5.07322 11.2626 5.07322 11.7374 4.78033 12.0303C4.48744 12.3232 4.01256 12.3232 3.71967 12.0303L0.21967 8.53033Z"],[14,"fill","#77838A"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M5 7C4.44772 7 4 7.44772 4 8C4 8.55229 4.44772 9 5 9H5.01C5.56228 9 6.01 8.55229 6.01 8C6.01 7.44772 5.56228 7 5.01 7H5Z"],[14,"fill","#77838A"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M7 8C7 7.44772 7.44772 7 8 7H8.01C8.56228 7 9.01 7.44772 9.01 8C9.01 8.55229 8.56228 9 8.01 9H8C7.44772 9 7 8.55229 7 8Z"],[14,"fill","#77838A"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M11 7C10.4477 7 10 7.44772 10 8C10 8.55229 10.4477 9 11 9H11.01C11.5623 9 12.01 8.55229 12.01 8C12.01 7.44772 11.5623 7 11.01 7H11Z"],[14,"fill","#77838A"],[12],[13],[1,"\\n "],[13],[1,"\\n "],[10,1],[14,0,"consul-node-peer-info__name"],[12],[1,[30,1,["PeerName"]]],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null]],["@item"],false,["if","tooltip"]]',moduleName:"consul-ui/components/consul/node/peer-info/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})) -define("consul-ui/components/consul/node/search-bar/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})),define("consul-ui/components/consul/node/search-bar/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"XAC5AQJw",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-node-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","filter","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.node.search-bar.",[30,3,["status","key"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[52,[30,3,["status","value"]],[30,3,["status","value"]],[28,[37,2],[[28,[37,3],["components.consul.node.search-bar.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null],[28,[37,3],["common.brand.",[30,3,["status","value"]]],null]],null]]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,5]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,6],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,6],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Optgroup"]],[30,9,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,11],null,[["@value","@selected"],[[30,12],[28,[37,10],[[30,12],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,11],[[30,12]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[12]],null]],[10,11]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-status"]],[["@position","@onchange","@multiple"],["left",[28,[37,6],[[30,0],[30,2,["status","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.consul.status"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,14,["Optgroup"]],[30,14,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[28,[37,4],["passing","warning","critical"],null]],null]],null],null,[[[1," "],[8,[30,16],[[16,0,[29,["value-",[30,17]]]]],[["@value","@selected"],[[30,17],[28,[37,10],[[30,17],[30,2,["status","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[30,17]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,17]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[17]],null]],[15,16]]],[1," "]],[]]]]],[1,"\\n "]],[14]]]]],[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-version"]],[["@position","@onchange","@multiple"],["left",[28,[37,6],[[30,0],[30,2,["version","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.consul.version"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,18,["Optgroup"]],[30,18,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[30,21]],null]],null],null,[[[1," "],[8,[30,20],null,[["@value","@selected"],[[30,22],[28,[37,10],[[30,22],[30,2,["version","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,3],[[30,22],".x"],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[22]],null]],[19,20]]],[1," "]],[]]]]],[1,"\\n "]],[18]]]]],[1,"\\n "]],[13]],[[[1,"\\n "],[8,[30,23,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,6],[[30,0],[30,24,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,12],[[28,[37,4],[[28,[37,4],["Node:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Node:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null],[28,[37,4],["Status:asc",[28,[37,2],["common.sort.status.asc"],null]],null],[28,[37,4],["Status:desc",[28,[37,2],["common.sort.status.desc"],null]],null],[28,[37,4],["Version:asc",[28,[37,2],["common.sort.version.asc"],null]],null],[28,[37,4],["Version:desc",[28,[37,2],["common.sort.version.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,13],[[30,26],[30,24,["value"]]],null]],[1,"\\n"]],[26]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,25,["Optgroup"]],[30,25,["Option"]]],[[[1," "],[8,[30,27],null,[["@label"],[[28,[37,2],["common.consul.status"],null]]],[["default"],[[[[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Status:asc",[28,[37,14],["Status:asc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Status:desc",[28,[37,14],["Status:desc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,27],null,[["@label"],[[28,[37,2],["common.consul.node-name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Node:asc",[28,[37,14],["Node:asc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Node:desc",[28,[37,14],["Node:desc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,27],null,[["@label"],[[28,[37,2],["common.consul.version"],null]]],[["default"],[[[[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Version:asc",[28,[37,14],["Version:asc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.version.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Version:desc",[28,[37,14],["Version:desc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.version.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[27,28]]],[1," "]],[]]]]],[1,"\\n "]],[25]]]]],[1,"\\n "]],[23]]]]]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Optgroup","Option","prop","search","components","Optgroup","Option","state","components","Optgroup","Option","@versions","version","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","if","action","block-slot","each","-track-array","includes","lowercase","from-entries","get","eq"]]',moduleName:"consul-ui/components/consul/node/search-bar/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})),define("consul-ui/components/consul/nspace/form/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/object"],(function(e,t,n,l,r){var i +e.default=i})) +define("consul-ui/components/consul/nspace/form/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/object"],(function(e,t,n,l,r){var i function o(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const a=(0,n.createTemplateFactory)({id:"0A+rYSOU",block:'[[[1,"\\n"],[11,0],[24,0,"consul-nspace-form"],[17,1],[12],[1,"\\n "],[8,[39,0],null,[["@sink","@type","@label","@ondelete","@onchange"],[[28,[37,1],["/${partition}/${nspace}/${dc}/nspace",[28,[37,2],null,[["partition","nspace","dc"],["","",[30,2,["Datacenter"]]]]]],null],"nspace","Namespace",[28,[37,3],[[30,0,["onDelete"]],[30,2]],null],[28,[37,3],[[30,0,["onSubmit"]],[30,2]],null]]],[["default"],[[[[1,"\\n "],[8,[39,4],null,[["@name"],["removed"]],[["default"],[[[[1,"\\n "],[8,[39,5],[[4,[38,6],null,[["after"],[[28,[37,7],[[30,0],[30,4]],null]]]]],[["@type"],["remove"]],null],[1,"\\n "]],[4]]]]],[1,"\\n\\n "],[8,[39,4],null,[["@name"],["content"]],[["default"],[[[[1,"\\n\\n"],[44,[[28,[37,9],[[28,[37,10],["write nspaces"],null]],null],[30,2],[28,[37,2],null,[["help","Name"],["Must be a valid DNS hostname. Must contain 1-64 characters (numbers, letters, and hyphens), and must begin with a letter. Once created, this cannot be changed.",[28,[37,11],[[28,[37,2],null,[["test","error"],["^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$","Name must be a valid DNS hostname."]]]],null]]]],[28,[37,2],null,[["Description"],[[28,[37,11],null,null]]]]],[[[1," "],[11,"form"],[4,[38,12],["submit",[28,[37,3],[[30,3,["persist"]],[30,6]],null]],null],[4,[38,13],[[30,5]],null],[12],[1,"\\n\\n "],[8,[39,14],null,[["@src"],[[28,[37,14],["validate"],null]]],[["default"],[[[[1,"\\n\\n "],[10,"fieldset"],[12],[1,"\\n"],[41,[28,[37,16],["new nspace"],[["item"],[[30,6]]]],[[[1," "],[8,[39,17],null,[["@name","@placeholder","@item","@validations","@chart"],["Name","Name",[30,6],[30,7],[28,[37,2],null,[["state","dispatch"],[[30,13],[30,12]]]]]],null],[1,"\\n"]],[]],null],[1," "],[8,[39,17],null,[["@expanded","@name","@label","@item","@validations","@chart"],[true,"Description","Description (Optional)",[30,6],[30,8],[28,[37,2],null,[["state","dispatch"],[[30,13],[30,12]]]]]],null],[1,"\\n "],[13],[1,"\\n"],[41,[28,[37,10],["use acls"],null],[[[1," "],[10,"fieldset"],[14,1,"roles"],[12],[1,"\\n "],[10,"h2"],[12],[1,"Roles"],[13],[1,"\\n "],[10,2],[12],[1,"\\n"],[41,[28,[37,10],["write nspace"],[["item"],[[30,6]]]],[[[1," By adding roles to this namespaces, you will apply them to\\n all tokens created within this namespace.\\n"]],[]],[[[1," The following roles are applied to all tokens created within\\n this namespace.\\n"]],[]]],[1," "],[13],[1,"\\n "],[8,[39,18],null,[["@dc","@nspace","@partition","@disabled","@items"],[[30,14],"default",[30,15],[30,5],[30,6,["ACLs","RoleDefaults"]]]],null],[1,"\\n "],[13],[1,"\\n "],[10,"fieldset"],[14,1,"policies"],[12],[1,"\\n "],[10,"h2"],[12],[1,"Policies"],[13],[1,"\\n "],[10,2],[12],[1,"\\n"],[41,[28,[37,9],[[30,5]],null],[[[1," By adding policies to this namespace, you will apply them to\\n all tokens created within this namespace.\\n"]],[]],[[[1," The following policies are applied to all tokens created\\n within this namespace.\\n"]],[]]],[1," "],[13],[1,"\\n "],[8,[39,19],null,[["@dc","@nspace","@partition","@disabled","@allowIdentity","@items"],[[30,14],"default",[30,15],[30,5],false,[30,6,["ACLs","PolicyDefaults"]]]],null],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "],[10,0],[12],[1,"\\n "],[8,[39,20],null,null,[["default"],[[[[1,"\\n"],[41,[28,[37,21],[[28,[37,16],["new nspace"],[["item"],[[30,6]]]],[28,[37,10],["create nspaces"],null]],null],[[[1," "],[8,[39,22],[[16,"disabled",[28,[37,23],[[28,[37,16],["pristine nspace"],[["item"],[[30,6]]]],[28,[37,24],[[30,13],"error"],null]],null]],[24,4,"submit"]],[["@text"],["Save"]],null],[1,"\\n"]],[]],[[[41,[28,[37,10],["write nspace"],[["item"],[[30,6]]]],[[[1," "],[8,[39,22],[[24,4,"submit"]],[["@text"],["Save"]],null],[1,"\\n "]],[]],null]],[]]],[1,"\\n "],[8,[39,22],[[24,4,"reset"],[4,[38,12],["click",[28,[37,3],[[30,0,["onCancel"]],[30,6]],null]],null]],[["@color","@text"],["secondary","Cancel"]],null],[1,"\\n\\n"],[41,[28,[37,21],[[28,[37,9],[[28,[37,16],["new nspace"],[["item"],[[30,6]]]]],null],[28,[37,10],["delete nspace"],[["item"],[[30,6]]]]],null],[[[1," "],[8,[39,25],null,[["@message"],["Are you sure you want to delete this Namespace?"]],[["default"],[[[[1,"\\n "],[8,[39,4],null,[["@name"],["action"]],[["default"],[[[[1,"\\n "],[8,[39,22],[[4,[38,12],["click",[28,[37,3],[[30,16],[28,[37,3],[[30,3,["delete"]],[30,6]],null]],null]],null]],[["@color","@text"],["critical","Delete"]],null],[1,"\\n "]],[16]]]]],[1,"\\n "],[8,[39,4],null,[["@name"],["dialog"]],[["default"],[[[[1,"\\n "],[8,[39,26],null,[["@message","@execute","@cancel"],[[30,19],[30,17],[30,18]]],null],[1,"\\n "]],[17,18,19]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[13],[1,"\\n "]],[9,10,11,12,13]]]]],[1,"\\n "],[13],[1,"\\n"]],[5,6,7,8]]],[1," "]],[]]]]],[1,"\\n "]],[3]]]]],[1,"\\n"],[13]],["&attrs","@item","writer","after","readOnly","item","Name","Description","State","Guard","ChartAction","dispatch","state","@dc","@partition","confirm","execute","cancel","message"],false,["data-writer","uri","hash","fn","block-slot","consul/nspace/notifications","notification","action","let","not","can","array","on","disabled","state-chart","if","is","text-input","role-selector","policy-selector","hds/button-set","and","hds/button","or","state-matches","confirmation-dialog","delete-confirmation"]]',moduleName:"consul-ui/components/consul/nspace/form/index.hbs",isStrictMode:!1}) @@ -1010,7 +1007,7 @@ e.default=i})),define("consul-ui/components/consul/nspace/search-bar/index",["ex const r=(0,n.createTemplateFactory)({id:"DelkwCZ4",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-nspace-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.nspace.search-bar.",[30,3,["status","key"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[28,[37,2],[[28,[37,3],["components.consul.nspace.search-bar.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null],[28,[37,3],["common.brand.",[30,3,["status","value"]]],null]],null]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,5]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,5],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Optgroup"]],[30,9,["Option"]]],[[[42,[28,[37,8],[[28,[37,8],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,11],null,[["@value","@selected"],[[30,12],[28,[37,9],[[30,12],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,10],[[30,12]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[12]],null]],[10,11]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,14,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,11],[[28,[37,4],[[28,[37,4],["Name:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Name:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,12],[[30,16],[30,14,["value"]]],null]],[1,"\\n"]],[16]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,15,["Optgroup"]],[30,15,["Option"]]],[[[1," "],[8,[30,17],null,[["@label"],[[28,[37,2],["common.consul.name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,18],null,[["@value","@selected"],["Name:asc",[28,[37,13],["Name:asc",[30,14,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,18],null,[["@value","@selected"],["Name:desc",[28,[37,13],["Name:desc",[30,14,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[17,18]]],[1," "]],[]]]]],[1,"\\n "]],[15]]]]],[1,"\\n "]],[13]]]]]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Optgroup","Option","prop","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","action","block-slot","each","-track-array","includes","lowercase","from-entries","get","eq"]]',moduleName:"consul-ui/components/consul/nspace/search-bar/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/nspace/selector/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const r=(0,n.createTemplateFactory)({id:"5UTTzYK/",block:'[[[1,"\\n"],[41,[28,[37,1],[[28,[37,2],["use nspaces"],null],[28,[37,2],["choose nspaces"],null]],null],[[[1," "],[8,[39,3],null,[["@src","@onchange"],[[28,[37,4],["/${partition}/*/${dc}/namespaces",[28,[37,5],null,[["partition","dc"],[[30,1],[30,2,["Name"]]]]]],null],[28,[37,6],[[28,[37,7],[[30,3]],null]],null]]],null],[1,"\\n"],[44,[[30,4],[52,[30,5],[28,[37,5],null,[["Name"],[[30,5]]]],[28,[37,5],null,[["Name"],["default"]]]],[28,[37,9],["dc.nspaces",[30,2,["Name"]]],null]],[[[1," "],[8,[30,6,["Title"]],[[24,0,"consul-side-nav__selector-title"]],null,[["default"],[[[[1,[28,[35,10],["components.hashicorp-consul.side-nav.nspaces.title"],null]]],[]]]]],[1,"\\n "],[8,[39,11],null,[["@list","@items","@item","@key","@icon","@placeholder","@footerLink","@footerLinkText"],[[30,4],[28,[37,12],["Name:asc",[28,[37,13],["DeletedAt",[30,9]],null]],null],[30,7],"Name","folder",[28,[37,10],["components.hashicorp-consul.side-nav.nspaces.placeholder"],null],[28,[37,14],["dc.nspaces",[30,2,["Name"]]],null],[28,[37,10],["components.hashicorp-consul.side-nav.nspaces.footer"],null]]],[["default"],[[[[1,"\\n "],[8,[30,10,["Checkmark"]],null,[["@selected","@href","@isHrefExternal"],[[28,[37,15],[[30,7,["Name"]],[30,11,["Name"]]],null],[52,[30,8],[28,[37,14],["dc.services.index"],[["params"],[[28,[37,5],null,[["partition","nspace","dc"],[[52,[28,[37,16],[[30,1,["length"]],0],null],[30,1],[27]],[30,11,["Name"]],[30,2,["Name"]]]]]]]],[28,[37,14],["."],[["params"],[[28,[37,5],null,[["partition","nspace"],[[52,[28,[37,16],[[30,1,["length"]],0],null],[30,1],[27]],[30,11,["Name"]]]]]]]]],false]],[["default"],[[[[1,"\\n "],[1,[30,11,["Name"]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[10,11]]]]],[1,"\\n"]],[6,7,8]]]],[]],null]],["@partition","@dc","@onchange","@list","@nspace","SNL","nspace","isManaging","@nspaces","Dropdown","item"],false,["if","and","can","data-source","uri","hash","fn","optional","let","is-href","t","nav-selector","sort-by","reject-by","href-to","eq","gt"]]',moduleName:"consul-ui/components/consul/nspace/selector/index.hbs",isStrictMode:!1}) +const r=(0,n.createTemplateFactory)({id:"ZHMEj55d",block:'[[[1,"\\n"],[41,[28,[37,1],[[28,[37,2],["use nspaces"],null],[28,[37,2],["choose nspaces"],null]],null],[[[44,[[30,1],[52,[30,2],[28,[37,4],null,[["Name"],[[30,2]]]],[28,[37,4],null,[["Name"],["default"]]]],[28,[37,5],["dc.nspaces",[30,3,["Name"]]],null]],[[[1," "],[8,[30,4,["Title"]],[[24,0,"consul-side-nav__selector-title"]],null,[["default"],[[[[1,[28,[35,6],["components.hashicorp-consul.side-nav.nspaces.title"],null]]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@list","@items","@item","@key","@icon","@placeholder","@footerLink","@footerLinkText"],[[30,1],[28,[37,8],["Name:asc",[28,[37,9],["DeletedAt",[30,7]],null]],null],[30,5],"Name","folder",[28,[37,6],["components.hashicorp-consul.side-nav.nspaces.placeholder"],null],[28,[37,10],["dc.nspaces",[30,3,["Name"]]],null],[28,[37,6],["components.hashicorp-consul.side-nav.nspaces.footer"],null]]],[["default"],[[[[1,"\\n "],[8,[30,8,["Data"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,11],null,[["@src","@loading","@onchange"],[[28,[37,12],["/${partition}/*/${dc}/namespaces",[28,[37,4],null,[["partition","dc"],[[30,9],[30,3,["Name"]]]]]],null],"lazy",[28,[37,13],[[28,[37,14],[[30,10]],null]],null]]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,8,["Dropdown","Checkmark"]],null,[["@selected","@href","@isHrefExternal"],[[28,[37,15],[[30,5,["Name"]],[30,8,["item","Name"]]],null],[28,[37,10],["dc.services.index"],[["params"],[[28,[37,4],null,[["partition","nspace","peer","dc"],[[52,[28,[37,16],[[30,9,["length"]],0],null],[30,9],[27]],[30,8,["item","Name"]],[27],[30,3,["Name"]]]]]]]],false]],[["default"],[[[[1,"\\n "],[1,[30,8,["item","Name"]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[8]]]]],[1,"\\n"]],[4,5,6]]]],[]],null]],["@list","@nspace","@dc","SNL","nspace","isManaging","@nspaces","Selector","@partition","@onchange"],false,["if","and","can","let","hash","is-href","t","nav-selector","sort-by","reject-by","href-to","data-source","uri","fn","optional","eq","gt"]]',moduleName:"consul-ui/components/consul/nspace/selector/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/partition/form/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"IFfwt6JG",block:'[[[1,"\\n"],[11,0],[24,0,"consul-partition-form"],[17,1],[12],[1,"\\n "],[8,[39,0],null,[["@sink","@type","@label","@ondelete","@onchange"],[[28,[37,1],["/${partition}/${nspace}/${dc}/partition",[28,[37,2],null,[["partition","nspace","dc"],["","",[30,2,["Datacenter"]]]]]],null],"partition","Partition",[28,[37,3],[[52,[30,3],[30,3],[30,4]],[30,2]],null],[28,[37,3],[[28,[37,5],[[30,4]],null],[30,2]],null]]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["removed"]],[["default"],[[[[1,"\\n "],[8,[39,7],[[4,[38,8],null,[["after"],[[28,[37,9],[[30,0],[30,6]],null]]]]],[["@type"],["remove"]],null],[1,"\\n "]],[6]]]]],[1,"\\n\\n "],[8,[39,6],null,[["@name"],["content"]],[["default"],[[[[1,"\\n\\n"],[44,[[28,[37,11],[[28,[37,12],["write partition"],null]],null],[30,2],[28,[37,2],null,[["help","Name"],["Must be a valid DNS hostname. Must contain 1-64 characters (numbers, letters, and hyphens), and must begin with a letter. Once created, this cannot be changed.",[28,[37,13],[[28,[37,2],null,[["test","error"],["^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$","Name must be a valid DNS hostname."]]]],null]]]],[28,[37,2],null,[["Description"],[[28,[37,13],null,null]]]]],[[[11,"form"],[4,[38,14],["submit",[28,[37,3],[[30,5,["persist"]],[30,8]],null]],null],[4,[38,15],[[30,7]],null],[12],[1,"\\n\\n"],[8,[39,16],null,[["@src"],[[28,[37,16],["validate"],null]]],[["default"],[[[[1,"\\n\\n "],[10,"fieldset"],[12],[1,"\\n"],[41,[28,[37,17],["new partition"],[["item"],[[30,8]]]],[[[1," "],[8,[39,18],null,[["@name","@placeholder","@item","@validations","@chart"],["Name","Name",[30,8],[30,9],[28,[37,2],null,[["state","dispatch"],[[30,15],[30,14]]]]]],null],[1,"\\n"]],[]],null],[1," "],[8,[39,18],null,[["@expanded","@name","@label","@item","@validations","@chart"],[true,"Description","Description (Optional)",[30,8],[30,10],[28,[37,2],null,[["state","dispatch"],[[30,15],[30,14]]]]]],null],[1,"\\n "],[13],[1,"\\n\\n "],[10,0],[12],[1,"\\n "],[8,[39,19],null,null,[["default"],[[[[1,"\\n\\n\\n"],[41,[28,[37,20],[[28,[37,17],["new partition"],[["item"],[[30,8]]]],[28,[37,12],["create partitions"],null]],null],[[[1," "],[8,[39,21],[[16,"disabled",[28,[37,22],[[28,[37,17],["pristine partition"],[["item"],[[30,8]]]],[28,[37,23],[[30,15],"error"],null]],null]],[24,4,"submit"]],[["@text"],["Save"]],null],[1,"\\n"]],[]],[[[41,[28,[37,11],[[30,7]],null],[[[1," "],[8,[39,21],[[24,4,"submit"]],[["@text"],["Save"]],null],[1,"\\n"]],[]],null]],[]]],[1," "],[8,[39,21],[[24,4,"reset"],[4,[38,14],["click",[52,[30,16],[28,[37,3],[[28,[37,5],[[30,16],[30,8]],null]],null],[28,[37,3],[[28,[37,5],[[30,4],[30,8]],null]],null]]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n\\n"],[41,[28,[37,20],[[28,[37,11],[[28,[37,17],["new partition"],[["item"],[[30,8]]]]],null],[28,[37,12],["delete partition"],[["item"],[[30,8]]]]],null],[[[1," "],[8,[39,24],null,[["@message"],["Are you sure you want to delete this Partition?"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["action"]],[["default"],[[[[1,"\\n "],[8,[39,21],[[4,[38,14],["click",[28,[37,3],[[30,17],[28,[37,3],[[30,5,["delete"]],[30,8]],null]],null]],null]],[["@text","@color"],["Delete","critical"]],null],[1,"\\n "]],[17]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["dialog"]],[["default"],[[[[1,"\\n "],[8,[39,25],null,[["@message","@execute","@cancel"],[[30,20],[30,18],[30,19]]],null],[1,"\\n "]],[18,19,20]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[13],[1,"\\n\\n"]],[11,12,13,14,15]]]]],[1,"\\n"],[13],[1,"\\n\\n"]],[7,8,9,10]]],[1," "]],[]]]]],[1,"\\n"]],[5]]]]],[1,"\\n"],[13],[1,"\\n"]],["&attrs","@item","@ondelete","@onsubmit","writer","after","readOnly","item","Name","Description","State","Guard","ChartAction","dispatch","state","@oncancel","confirm","execute","cancel","message"],false,["data-writer","uri","hash","fn","if","optional","block-slot","consul/partition/notifications","notification","action","let","not","can","array","on","disabled","state-chart","is","text-input","hds/button-set","and","hds/button","or","state-matches","confirmation-dialog","delete-confirmation"]]',moduleName:"consul-ui/components/consul/partition/form/index.hbs",isStrictMode:!1}) @@ -1025,7 +1022,7 @@ e.default=i})),define("consul-ui/components/consul/partition/search-bar/index",[ const r=(0,n.createTemplateFactory)({id:"IuHkFeus",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-partition-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.nspace.search-bar.",[30,3,["status","key"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[28,[37,2],[[28,[37,3],["components.consul.nspace.search-bar.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null],[28,[37,3],["common.brand.",[30,3,["status","value"]]],null]],null]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,5]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,5],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Optgroup"]],[30,9,["Option"]]],[[[42,[28,[37,8],[[28,[37,8],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,11],null,[["@value","@selected"],[[30,12],[28,[37,9],[[30,12],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,10],[[30,12]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[12]],null]],[10,11]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,14,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,11],[[28,[37,4],[[28,[37,4],["Name:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Name:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,12],[[30,16],[30,14,["value"]]],null]],[1,"\\n"]],[16]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,15,["Optgroup"]],[30,15,["Option"]]],[[[1," "],[8,[30,17],null,[["@label"],[[28,[37,2],["common.consul.name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,18],null,[["@value","@selected"],["Name:asc",[28,[37,13],["Name:asc",[30,14,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,18],null,[["@value","@selected"],["Name:desc",[28,[37,13],["Name:desc",[30,14,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[17,18]]],[1," "]],[]]]]],[1,"\\n "]],[15]]]]],[1,"\\n "]],[13]]]]]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Optgroup","Option","prop","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","action","block-slot","each","-track-array","includes","lowercase","from-entries","get","eq"]]',moduleName:"consul-ui/components/consul/partition/search-bar/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/partition/selector/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const r=(0,n.createTemplateFactory)({id:"2skwmygl",block:'[[[1,"\\n"],[44,[[30,1],[52,[30,2],[28,[37,2],null,[["Name"],[[30,2]]]],[28,[37,2],null,[["Name"],["default"]]]],[28,[37,3],["dc.partitions",[30,3,["Name"]]],null],[28,[37,4],["choose partitions"],[["dc"],[[30,3]]]]],[[[1," "],[8,[39,5],null,[["@src","@onchange"],[[28,[37,6],["/*/*/${dc}/partitions",[28,[37,2],null,[["dc"],[[30,3,["Name"]]]]]],null],[28,[37,7],[[28,[37,8],[[30,8]],null]],null]]],null],[1,"\\n "],[8,[30,4,["Title"]],[[24,0,"consul-side-nav__selector-title"]],null,[["default"],[[[[1,[28,[35,9],["components.hashicorp-consul.side-nav.partitions.title"],null]]],[]]]]],[1,"\\n "],[8,[39,10],null,[["@list","@items","@item","@key","@icon","@placeholder","@footerLink","@footerLinkText","@disabled"],[[30,1],[28,[37,11],["Name:asc",[28,[37,12],["DeletedAt",[30,9]],null]],null],[30,5],"Name","users",[28,[37,9],["components.hashicorp-consul.side-nav.partitions.placeholder"],null],[28,[37,13],["dc.partitions",[30,3,["Name"]]],null],[28,[37,9],["components.hashicorp-consul.side-nav.partitions.footer"],null],[28,[37,14],[[30,7]],null]]],[["default"],[[[[1,"\\n"],[41,[30,7],[[[1," "],[8,[30,10,["Checkmark"]],null,[["@selected","@href","@isHrefExternal"],[[28,[37,15],[[30,5,["Name"]],[30,11,["Name"]]],null],[52,[30,11,["href"]],[30,11,["href"]],[52,[30,6],[28,[37,13],["dc.services.index"],[["params"],[[28,[37,2],null,[["partition","nspace","dc"],[[30,11,["Name"]],[27],[30,3,["Name"]]]]]]]],[28,[37,13],["."],[["params"],[[28,[37,2],null,[["partition","nspace"],[[30,11,["Name"]],[27]]]]]]]]],false]],[["default"],[[[[1,"\\n "],[1,[30,11,["Name"]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[10,11]]]]],[1,"\\n"]],[4,5,6,7]]]],["@list","@partition","@dc","SNL","partition","isManaging","canChoose","@onchange","@partitions","Dropdown","item"],false,["let","if","hash","is-href","can","data-source","uri","fn","optional","t","nav-selector","sort-by","reject-by","href-to","not","eq"]]',moduleName:"consul-ui/components/consul/partition/selector/index.hbs",isStrictMode:!1}) +const r=(0,n.createTemplateFactory)({id:"kdZOlgGd",block:'[[[1,"\\n"],[44,[[30,1],[52,[30,2],[28,[37,2],null,[["Name"],[[30,2]]]],[28,[37,2],null,[["Name"],["default"]]]],[28,[37,3],["dc.partitions",[30,3,["Name"]]],null],[28,[37,4],["choose partitions"],[["dc"],[[30,3]]]]],[[[1," "],[8,[30,4,["Title"]],[[24,0,"consul-side-nav__selector-title"]],null,[["default"],[[[[1,[28,[35,5],["components.hashicorp-consul.side-nav.partitions.title"],null]]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@list","@items","@item","@key","@icon","@placeholder","@footerLink","@footerLinkText","@disabled"],[[30,1],[28,[37,7],["Name:asc",[28,[37,8],["DeletedAt",[30,8]],null]],null],[30,5],"Name","users",[28,[37,5],["components.hashicorp-consul.side-nav.partitions.placeholder"],null],[28,[37,9],["dc.partitions",[30,3,["Name"]]],null],[28,[37,5],["components.hashicorp-consul.side-nav.partitions.footer"],null],[28,[37,10],[[30,7]],null]]],[["default"],[[[[1,"\\n "],[8,[30,9,["Data"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,11],null,[["@src","@loading","@onchange"],[[28,[37,12],["/*/*/${dc}/partitions",[28,[37,2],null,[["dc"],[[30,3,["Name"]]]]]],null],"lazy",[28,[37,13],[[28,[37,14],[[30,10]],null]],null]]],null],[1,"\\n "]],[]]]]],[1,"\\n"],[41,[30,7],[[[1," "],[8,[30,9,["Dropdown","Checkmark"]],null,[["@selected","@href","@isHrefExternal"],[[28,[37,15],[[30,5,["Name"]],[30,9,["item","Name"]]],null],[52,[30,9,["item","href"]],[30,9,["item","href"]],[28,[37,9],["dc.services.index"],[["params"],[[28,[37,2],null,[["partition","nspace","peer","dc"],[[30,9,["item","Name"]],[27],[27],[30,3,["Name"]]]]]]]]],false]],[["default"],[[[[1,"\\n "],[1,[30,9,["item","Name"]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[9]]]]],[1,"\\n"]],[4,5,6,7]]]],["@list","@partition","@dc","SNL","partition","isManaging","canChoose","@partitions","Selector","@onchange"],false,["let","if","hash","is-href","can","t","nav-selector","sort-by","reject-by","href-to","not","data-source","uri","fn","optional","eq"]]',moduleName:"consul-ui/components/consul/partition/selector/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/peer/address/list/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"TNoxeoLi",block:'[[[1,"\\n"],[8,[39,0],null,null,[["default"],[[[[1,"\\n"],[41,[30,1,["data","height"]],[[[1," "],[10,0],[15,5,[30,1,["data","fillRemainingHeightStyle"]]],[14,0,"overflow-y-scroll"],[12],[1,"\\n "],[8,[39,2],null,[["@tagName","@estimateHeight","@items"],["ul",[30,1,["data","height"]],[30,2]]],[["default"],[[[[1,"\\n "],[10,"li"],[14,0,"px-3 h-12 border-bottom-primary flex items-center justify-between group"],[12],[1,"\\n "],[10,0],[14,0,"hds-typography-display-300 text-hds-foreground-strong hds-font-weight-semibold"],[12],[1,[30,3]],[13],[1,"\\n "],[8,[39,3],[[24,0,"opacity-0 group-hover:opacity-100"]],[["@value","@name"],[[30,3],"Address"]],null],[1,"\\n "],[13],[1,"\\n "]],[3,4]]]]],[1,"\\n "],[13],[1,"\\n"]],[]],null]],[1]]]]]],["p","@items","address","index"],false,["providers/dimension","if","vertical-collection","consul-copy-button"]]',moduleName:"consul-ui/components/consul/peer/address/list/index.hbs",isStrictMode:!1}) @@ -1082,11 +1079,11 @@ var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/policy/list/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"62bUfTFp",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-policy-list"]],[["@items"],[[30,1]]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["header"]],[["default"],[[[[1,"\\n"],[41,[28,[37,3],[[28,[37,4],[[28,[37,5],[[30,2]],null],"policy-management"],null],[28,[37,4],[[28,[37,5],[[30,2]],null],"read-only"],null]],null],[[[1," "],[10,"dl"],[14,0,"policy-management"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Type"],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n"],[41,[28,[37,4],[[28,[37,5],[[30,2]],null],"policy-management"],null],[[[1," "],[8,[39,6],null,null,[["default"],[[[[1,"\\n Global Management Policy\\n "]],[]]]]],[1,"\\n"]],[]],[[[1," "],[8,[39,6],null,null,[["default"],[[[[1,"\\n Global Read-only Policy\\n "]],[]]]]],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "],[10,3],[15,6,[28,[37,7],["dc.acls.policies.edit",[30,2,["ID"]]],null]],[15,0,[52,[28,[37,4],[[28,[37,5],[[30,2]],null],"policy-management"],null],"is-management"]],[12],[1,[30,2,["Name"]]],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["details"]],[["default"],[[[[1,"\\n "],[10,"dl"],[14,0,"datacenter"],[12],[1,"\\n "],[10,"dt"],[12],[1,"\\n "],[8,[39,6],null,null,[["default"],[[[[1,"Datacenters"]],[]]]]],[1,"\\n "],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[1,[28,[35,8],[", ",[28,[37,9],[[30,2]],null]],null]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[10,"dl"],[14,0,"description"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Description"],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[1,[30,2,["Description"]]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[30,3],null,null,[["default"],[[[[1,"\\n "],[8,[30,4],null,[["@href"],[[28,[37,7],["dc.acls.policies.edit",[30,2,["ID"]]],null]]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["label"]],[["default"],[[[[1,"\\n"],[41,[28,[37,10],["write policy"],[["item"],[[30,2]]]],[[[1," Edit\\n"]],[]],[[[1," View\\n"]],[]]],[1," "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"],[41,[28,[37,10],["delete policy"],[["item"],[[30,2]]]],[[[1," "],[8,[30,4],[[24,0,"dangerous"]],[["@onclick"],[[28,[37,11],[[30,0],[30,5],[30,2]],null]]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["label"]],[["default"],[[[[1,"\\n Delete\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["confirmation"]],[["default"],[[[[1,"\\n "],[8,[30,6],[[24,0,"warning"]],null,[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["header"]],[["default"],[[[[1,"\\n Confirm delete\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[10,2],[12],[1,"\\n Are you sure you want to delete this policy?\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["confirm"]],[["default"],[[[[1,"\\n "],[8,[30,7],null,null,[["default"],[[[[1,"Delete"]],[]]]]],[1,"\\n "]],[7]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[4]]]]],[1,"\\n "]],[3]]]]],[1,"\\n"]],[2]]]]]],["@items","item","Actions","Action","@ondelete","Confirmation","Confirm"],false,["list-collection","block-slot","if","or","eq","policy/typeof","tooltip","href-to","join","policy/datacenters","can","action"]]',moduleName:"consul-ui/components/consul/policy/list/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})) -define("consul-ui/components/consul/policy/notifications/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})),define("consul-ui/components/consul/policy/notifications/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"sUAOpVES",block:'[[[1,"\\n"],[41,[28,[37,1],[[30,1],"create"],null],[[[41,[28,[37,1],[[30,2],"success"],null],[[[1," Your policy has been added.\\n"]],[]],[[[1," There was an error adding your policy.\\n"]],[]]]],[]],[[[41,[28,[37,1],[[30,1],"update"],null],[[[41,[28,[37,1],[[30,2],"success"],null],[[[1," Your policy has been saved.\\n"]],[]],[[[1," There was an error saving your policy.\\n"]],[]]]],[]],[[[41,[28,[37,1],[[30,1],"delete"],null],[[[41,[28,[37,1],[[30,2],"success"],null],[[[1," Your policy was deleted.\\n"]],[]],[[[1," There was an error deleting your policy.\\n"]],[]]]],[]],null]],[]]]],[]]],[44,[[30,3,["errors","firstObject"]]],[[[41,[30,4,["detail"]],[[[1," "],[10,"br"],[12],[13],[1,[28,[35,3],["(",[52,[30,4,["status"]],[28,[37,3],[[30,4,["status"]],": "],null]],[30,4,["detail"]],")"],null]],[1,"\\n"]],[]],null]],[4]]]],["@type","@status","@error","error"],false,["if","eq","let","concat"]]',moduleName:"consul-ui/components/consul/policy/notifications/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})),define("consul-ui/components/consul/policy/search-bar/index",["exports","@ember/component","@ember/template-factory","@glimmer/component"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})) +define("consul-ui/components/consul/policy/search-bar/index",["exports","@ember/component","@ember/template-factory","@glimmer/component"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"Idci/62E",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-policy-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","filter","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.policy.search-bar.",[30,3,["status","key"]],".name"],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[28,[37,2],[[28,[37,3],["components.consul.policy.search-bar.",[30,3,["status","key"]],".options.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null],[28,[37,3],["common.brand.",[30,3,["status","value"]]],null]],null]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[52,[28,[37,6],[[30,3,["status","key"]],"datacenter"],null],[30,3,["status","value"]],[30,5]]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,7],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,7],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,8],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,8],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Optgroup"]],[30,9,["Option"]]],[[[42,[28,[37,10],[[28,[37,10],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,11],null,[["@value","@selected"],[[30,12],[28,[37,11],[[30,12],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,12],[[30,12]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[12]],null]],[10,11]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-datacenter"]],[["@position","@onchange","@multiple"],["left",[28,[37,7],[[30,0],[30,2,["datacenter","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,8],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.consul.datacenter"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,8],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,14,["Optgroup"]],[30,14,["Option"]]],[[[42,[28,[37,10],[[28,[37,10],[[33,13]],null]],null],null,[[[1," "],[8,[30,16],null,[["@value","@selected"],[[30,17,["Name"]],[28,[37,11],[[30,17,["Name"]],[30,2,["datacenter","value"]]],null]]],[["default"],[[[[1,[30,17,["Name"]]]],[]]]]],[1,"\\n"]],[17]],null],[1," "],[8,[39,14],null,[["@src","@loading","@onchange"],[[28,[37,15],["/${partition}/*/*/datacenters",[28,[37,16],null,[["partition"],[[30,18]]]]],null],"lazy",[28,[37,7],[[30,0],[28,[37,17],[[30,0,["dcs"]]],null]],[["value"],["data"]]]]],null],[1,"\\n"]],[15,16]]],[1," "]],[]]]]],[1,"\\n "]],[14]]]]],[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-kind"]],[["@position","@onchange","@multiple"],["left",[28,[37,7],[[30,0],[30,2,["kind","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,8],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["components.consul.policy.search-bar.kind.name"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,8],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,19,["Optgroup"]],[30,19,["Option"]]],[[[42,[28,[37,10],[[28,[37,10],[[28,[37,4],["global-management","standard"],null]],null]],null],null,[[[1," "],[8,[30,21],[[16,0,[29,["value-",[30,22]]]]],[["@value","@selected"],[[30,22],[28,[37,11],[[30,22],[30,2,["kind","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["components.consul.policy.search-bar.kind.options.",[30,22]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,22]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[22]],null]],[20,21]]],[1," "]],[]]]]],[1,"\\n "]],[19]]]]],[1,"\\n "]],[13]],[[[1,"\\n "],[8,[30,23,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,7],[[30,0],[30,24,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,8],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,18],[[28,[37,4],[[28,[37,4],["Name:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Name:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,19],[[30,26],[30,24,["value"]]],null]],[1,"\\n"]],[26]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,8],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,25,["Optgroup"]],[30,25,["Option"]]],[[[1," "],[8,[30,27],null,[["@label"],[[28,[37,2],["common.ui.name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Name:asc",[28,[37,6],["Name:asc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,28],null,[["@value","@selected"],["Name:desc",[28,[37,6],["Name:desc",[30,24,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[27,28]]],[1," "]],[]]]]],[1,"\\n "]],[25]]]]],[1,"\\n "]],[23]]]]],[1,"\\n"]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Optgroup","Option","prop","search","components","Optgroup","Option","dc","@partition","components","Optgroup","Option","state","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","if","eq","action","block-slot","each","-track-array","includes","lowercase","dcs","data-source","uri","hash","mut","from-entries","get"]]',moduleName:"consul-ui/components/consul/policy/search-bar/index.hbs",isStrictMode:!1}) class i extends l.default{}e.default=i,(0,t.setComponentTemplate)(r,i)})),define("consul-ui/components/consul/role/list/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"B3WXmBeq",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-role-list"],[17,1]],[["@items"],[[30,2]]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,3],[15,6,[28,[37,2],["dc.acls.roles.edit",[30,3,["ID"]]],null]],[12],[1,[30,3,["Name"]]],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["details"]],[["default"],[[[[1,"\\n "],[8,[39,3],null,[["@item"],[[30,3]]],null],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Description"],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[1,[30,3,["Description"]]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[30,4],null,null,[["default"],[[[[1,"\\n "],[8,[30,5],null,[["@href"],[[28,[37,2],["dc.acls.roles.edit",[30,3,["ID"]]],null]]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["label"]],[["default"],[[[[1,"\\n"],[41,[28,[37,5],["write role"],[["item"],[[30,3]]]],[[[1," Edit\\n"]],[]],[[[1," View\\n"]],[]]],[1," "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"],[41,[28,[37,5],["delete role"],[["item"],[[30,3]]]],[[[1," "],[8,[30,5],[[24,0,"dangerous"]],[["@onclick"],[[28,[37,6],[[30,0],[30,6],[30,3]],null]]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["label"]],[["default"],[[[[1,"\\n Delete\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["confirmation"]],[["default"],[[[[1,"\\n "],[8,[30,7],[[24,0,"warning"]],null,[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["header"]],[["default"],[[[[1,"\\n Confirm delete\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[10,2],[12],[1,"\\n Are you sure you want to delete this role?\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["confirm"]],[["default"],[[[[1,"\\n "],[8,[30,8],null,null,[["default"],[[[[1,"Delete"]],[]]]]],[1,"\\n "]],[8]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[7]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[5]]]]],[1,"\\n "]],[4]]]]],[1,"\\n"]],[3]]]]]],["&attrs","@items","item","Actions","Action","@ondelete","Confirmation","Confirm"],false,["list-collection","block-slot","href-to","consul/token/ruleset/list","if","can","action"]]',moduleName:"consul-ui/components/consul/role/list/index.hbs",isStrictMode:!1}) @@ -1115,9 +1112,12 @@ return(null===(t=e.Service)||void 0===t||null===(n=t.Meta)||void 0===n?void 0:n[ const r=(0,n.createTemplateFactory)({id:"VjdzBiZi",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-service-instance-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","filter","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.service-instance.search-bar.",[30,3,["status","key"]],".name"],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[28,[37,2],[[28,[37,3],["components.consul.service-instance.search-bar.",[30,3,["status","key"]],".options.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null],[28,[37,3],["common.brand.",[30,3,["status","value"]]],null]],null]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,5]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,5],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n"],[41,[30,2,["searchproperty"]],[[[1," "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,10],null,[["@value","@selected"],[[30,11],[28,[37,10],[[30,11],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,11],[[30,11]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[11]],null]],[10]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,12,["Select"]],[[24,0,"type-status"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["status","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.consul.status"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,13,["Optgroup"]],[30,13,["Option"]]],[[[42,[28,[37,9],[[28,[37,9],[[28,[37,4],["passing","warning","critical","empty"],null]],null]],null],null,[[[1," "],[8,[30,15],[[16,0,[29,["value-",[30,16]]]]],[["@value","@selected"],[[30,16],[28,[37,10],[[30,16],[30,2,["status","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[30,16]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,16]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[16]],null]],[14,15]]],[1," "]],[]]]]],[1,"\\n "]],[13]]]]],[1,"\\n"],[41,[28,[37,12],[[30,17,["length"]],0],null],[[[1," "],[8,[30,12,["Select"]],[[24,0,"type-source"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["source","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,13],null,[["@components","@filter","@sources"],[[30,18],[30,2],[30,17]]],null],[1,"\\n "]],[18]]]]],[1,"\\n"]],[]],null],[1," "]],[12]],[[[1,"\\n "],[8,[30,19,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,20,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,14],[[28,[37,4],[[28,[37,4],["Name:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Name:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null],[28,[37,4],["Status:asc",[28,[37,2],["common.sort.status.asc"],null]],null],[28,[37,4],["Status:desc",[28,[37,2],["common.sort.status.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,15],[[30,22],[30,20,["value"]]],null]],[1,"\\n"]],[22]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,21,["Optgroup"]],[30,21,["Option"]]],[[[1," "],[8,[30,23],null,[["@label"],[[28,[37,2],["common.consul.status"],null]]],[["default"],[[[[1,"\\n "],[8,[30,24],null,[["@value","@selected"],["Status:asc",[28,[37,16],["Status:asc",[30,20,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,24],null,[["@value","@selected"],["Status:desc",[28,[37,16],["Status:desc",[30,20,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,23],null,[["@label"],[[28,[37,2],["components.consul.service-instance.search-bar.sort.name.name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,24],null,[["@value","@selected"],["Name:asc",[28,[37,16],["Name:asc",[30,20,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,24],null,[["@value","@selected"],["Name:desc",[28,[37,16],["Name:desc",[30,20,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[23,24]]],[1," "]],[]]]]],[1,"\\n "]],[21]]]]],[1,"\\n "]],[19]]]]],[1,"\\n"]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Option","prop","search","components","Optgroup","Option","state","@sources","components","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","action","if","block-slot","each","-track-array","includes","lowercase","gt","consul/sources-select","from-entries","get","eq"]]',moduleName:"consul-ui/components/consul/service-instance/search-bar/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/consul/service/list/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const r=(0,n.createTemplateFactory)({id:"DY2ljV0F",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-service-list"],[17,1]],[["@items","@linkable"],[[30,2],"linkable service"]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"dl"],[15,0,[30,3,["MeshStatus"]]],[12],[1,"\\n "],[10,"dt"],[12],[1,"\\n Health\\n "],[13],[1,"\\n "],[11,"dd"],[4,[38,2],[[30,3,["healthTooltipText"]]],null],[12],[13],[1,"\\n "],[13],[1,"\\n"],[41,[28,[37,4],[[30,3,["InstanceCount"]],0],null],[[[1," "],[10,3],[15,6,[28,[37,5],["dc.services.show.index",[30,3,["Name"]]],[["params"],[[52,[28,[37,6],[[30,3,["Partition"]],[30,5]],null],[28,[37,7],null,[["partition","nspace","peer"],[[30,3,["Partition"]],[30,3,["Namespace"]],[30,3,["PeerName"]]]]],[28,[37,7],null,[["peer"],[[30,3,["PeerName"]]]]]]]]]],[12],[1,"\\n "],[1,[30,3,["Name"]]],[1,"\\n "],[13],[1,"\\n"]],[]],[[[1," "],[10,2],[12],[1,"\\n "],[1,[30,3,["Name"]]],[1,"\\n "],[13],[1,"\\n"]],[]]],[1," "]],[]]]]],[1,"\\n "],[8,[39,1],null,[["@name"],["details"]],[["default"],[[[[1,"\\n "],[8,[39,8],null,[["@item"],[[30,3]]],null],[1,"\\n "],[8,[39,9],null,[["@item"],[[30,3]]],null],[1,"\\n"],[41,[28,[37,10],[[28,[37,6],[[30,3,["InstanceCount"]],0],null],[28,[37,10],[[28,[37,6],[[30,3,["Kind"]],"terminating-gateway"],null],[28,[37,6],[[30,3,["Kind"]],"ingress-gateway"],null]],null]],null],[[[1," "],[10,1],[12],[1,"\\n "],[1,[28,[35,11],[[30,3,["InstanceCount"]]],null]],[1,"\\n "],[1,[28,[35,12],[[30,3,["InstanceCount"]],"instance"],[["without-count"],[true]]]],[1,"\\n "],[13],[1,"\\n"]],[]],null],[41,[51,[30,6]],[[[1," "],[8,[39,14],null,[["@item","@nspace","@partition"],[[30,3],[30,7],[30,5]]],null],[1,"\\n"]],[]],null],[41,[28,[37,15],[[30,3,["Kind"]],"terminating-gateway"],null],[[[1," "],[10,1],[12],[1,"\\n "],[1,[28,[35,11],[[30,3,["GatewayConfig","AssociatedServiceCount"]]],null]],[1,"\\n "],[1,[28,[35,12],[[30,3,["GatewayConfig","AssociatedServiceCount"]],"linked service"],[["without-count"],[true]]]],[1,"\\n "],[13],[1,"\\n"]],[]],[[[41,[28,[37,15],[[30,3,["Kind"]],"ingress-gateway"],null],[[[1," "],[10,1],[12],[1,"\\n "],[1,[28,[35,11],[[30,3,["GatewayConfig","AssociatedServiceCount"]]],null]],[1,"\\n "],[1,[28,[35,12],[[30,3,["GatewayConfig","AssociatedServiceCount"]],"upstream"],[["without-count"],[true]]]],[1,"\\n "],[13],[1,"\\n "]],[]],null]],[]]],[41,[28,[37,16],[[30,3,["ConnectedWithGateway"]],[30,3,["ConnectedWithProxy"]]],null],[[[1," "],[10,"dl"],[14,0,"mesh"],[12],[1,"\\n "],[10,"dt"],[12],[1,"\\n "],[8,[39,2],null,null,[["default"],[[[[1,"\\n This service uses a proxy for the Consul service mesh\\n "]],[]]]]],[1,"\\n "],[13],[1,"\\n"],[41,[28,[37,10],[[30,3,["ConnectedWithGateway"]],[30,3,["ConnectedWithProxy"]]],null],[[[1," "],[10,"dd"],[12],[1,"\\n in service mesh with proxy and gateway\\n "],[13],[1,"\\n"]],[]],[[[41,[30,3,["ConnectedWithProxy"]],[[[1," "],[10,"dd"],[12],[1,"\\n in service mesh with proxy\\n "],[13],[1,"\\n"]],[]],[[[41,[30,3,["ConnectedWithGateway"]],[[[1," "],[10,"dd"],[12],[1,"\\n in service mesh with gateway\\n "],[13],[1,"\\n "]],[]],null]],[]]]],[]]],[1," "],[13],[1,"\\n"]],[]],null],[1," "],[8,[39,17],null,[["@item"],[[30,3]]],null],[1,"\\n "]],[]]]]],[1,"\\n"]],[3,4]]]]],[1,"\\n"]],["&attrs","@items","item","index","@partition","@isPeerDetail","@nspace"],false,["list-collection","block-slot","tooltip","if","gt","href-to","not-eq","hash","consul/kind","consul/external-source","and","format-number","pluralize","unless","consul/bucket/list","eq","or","tag-list"]]',moduleName:"consul-ui/components/consul/service/list/index.hbs",isStrictMode:!1}) +const r=(0,n.createTemplateFactory)({id:"xPCwneUJ",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-service-list"],[17,1]],[["@items","@linkable"],[[30,2],"linkable service"]],[["default"],[[[[1,"\\n "],[8,[39,1],null,[["@item","@partition","@nspace"],[[30,3],[30,5],[30,6]]],null],[1,"\\n"]],[3,4]]]]],[1,"\\n"]],["&attrs","@items","item","index","@partition","@nspace"],false,["list-collection","consul/service/list/item"]]',moduleName:"consul-ui/components/consul/service/list/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) -e.default=i})),define("consul-ui/components/consul/service/search-bar/index",["exports","@ember/component","@ember/template-factory","@glimmer/component"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})),define("consul-ui/components/consul/service/list/item/index",["exports","@ember/component","@ember/template-factory","@glimmer/component"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +const r=(0,n.createTemplateFactory)({id:"cAe7geUl",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"dl"],[15,0,[30,1,["MeshStatus"]]],[12],[1,"\\n "],[10,"dt"],[12],[1,"\\n Health\\n "],[13],[1,"\\n "],[11,"dd"],[4,[38,1],[[30,1,["healthTooltipText"]]],null],[12],[13],[1,"\\n "],[13],[1,"\\n"],[41,[28,[37,3],[[30,1,["InstanceCount"]],0],null],[[[1," "],[10,3],[15,6,[28,[37,4],["dc.services.show.index",[30,1,["Name"]]],[["params"],[[30,0,["linkParams"]]]]]],[12],[1,"\\n "],[1,[30,1,["Name"]]],[1,"\\n "],[13],[1,"\\n"]],[]],[[[1," "],[10,2],[12],[1,"\\n "],[1,[30,1,["Name"]]],[1,"\\n "],[13],[1,"\\n"]],[]]]],[]]]]],[1,"\\n"],[8,[39,0],null,[["@name"],["details"]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@item"],[[30,1]]],null],[1,"\\n "],[8,[39,6],null,[["@item"],[[30,1]]],null],[1,"\\n"],[41,[28,[37,7],[[28,[37,8],[[30,1,["InstanceCount"]],0],null],[28,[37,7],[[28,[37,8],[[30,1,["Kind"]],"terminating-gateway"],null],[28,[37,8],[[30,1,["Kind"]],"ingress-gateway"],null]],null]],null],[[[1," "],[10,1],[12],[1,"\\n "],[1,[28,[35,9],[[30,1,["InstanceCount"]]],null]],[1,"\\n "],[1,[28,[35,10],[[30,1,["InstanceCount"]],"instance"],[["without-count"],[true]]]],[1,"\\n "],[13],[1,"\\n"]],[]],null],[41,[51,[30,2]],[[[1," "],[8,[39,12],null,[["@item","@nspace","@partition"],[[30,1],[30,3],[30,4]]],null],[1,"\\n"]],[]],null],[41,[28,[37,13],[[30,1,["Kind"]],"terminating-gateway"],null],[[[1," "],[10,1],[12],[1,"\\n "],[1,[28,[35,9],[[30,1,["GatewayConfig","AssociatedServiceCount"]]],null]],[1,"\\n "],[1,[28,[35,10],[[30,1,["GatewayConfig","AssociatedServiceCount"]],"linked service"],[["without-count"],[true]]]],[1,"\\n "],[13],[1,"\\n"]],[]],[[[41,[28,[37,13],[[30,1,["Kind"]],"ingress-gateway"],null],[[[1," "],[10,1],[12],[1,"\\n "],[1,[28,[35,9],[[30,1,["GatewayConfig","AssociatedServiceCount"]]],null]],[1,"\\n "],[1,[28,[35,10],[[30,1,["GatewayConfig","AssociatedServiceCount"]],"upstream"],[["without-count"],[true]]]],[1,"\\n "],[13],[1,"\\n "]],[]],null]],[]]],[41,[28,[37,14],[[30,1,["ConnectedWithGateway"]],[30,1,["ConnectedWithProxy"]]],null],[[[1," "],[10,"dl"],[14,0,"mesh"],[12],[1,"\\n "],[10,"dt"],[12],[1,"\\n "],[8,[39,1],null,null,[["default"],[[[[1,"\\n This service uses a proxy for the Consul service mesh\\n "]],[]]]]],[1,"\\n "],[13],[1,"\\n"],[41,[28,[37,7],[[30,1,["ConnectedWithGateway"]],[30,1,["ConnectedWithProxy"]]],null],[[[1," "],[10,"dd"],[12],[1,"\\n in service mesh with proxy and gateway\\n "],[13],[1,"\\n"]],[]],[[[41,[30,1,["ConnectedWithProxy"]],[[[1," "],[10,"dd"],[12],[1,"\\n in service mesh with proxy\\n "],[13],[1,"\\n"]],[]],[[[41,[30,1,["ConnectedWithGateway"]],[[[1," "],[10,"dd"],[12],[1,"\\n in service mesh with gateway\\n "],[13],[1,"\\n "]],[]],null]],[]]]],[]]],[1," "],[13],[1,"\\n"]],[]],null],[1," "],[8,[39,15],null,[["@item"],[[30,1]]],null],[1,"\\n"]],[]]]]]],["@item","@isPeerDetail","@nspace","@partition"],false,["block-slot","tooltip","if","gt","href-to","consul/kind","consul/external-source","and","not-eq","format-number","pluralize","unless","consul/bucket/list","eq","or","tag-list"]]',moduleName:"consul-ui/components/consul/service/list/item/index.hbs",isStrictMode:!1}) +class i extends l.default{get linkParams(){const e={} +return this.args.item.Partition&&this.args.partition!==this.args.item.Partition?(e.partition=this.args.item.Partition,e.nspace=this.args.Namespace):this.args.item.Namespace&&this.args.nspace!==this.args.item.Namespace&&(e.nspace=this.args.item.Namespace),this.args.item.PeerName&&(e.peer=this.args.item.PeerName),e}}e.default=i,(0,t.setComponentTemplate)(r,i)})),define("consul-ui/components/consul/service/search-bar/index",["exports","@ember/component","@ember/template-factory","@glimmer/component"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"4sJ6oMs1",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"consul-service-search-bar"],[17,1]],[["@filter"],[[30,2]]],[["status","search","filter","sort"],[[[[1,"\\n\\n"],[44,[[28,[37,2],[[28,[37,3],["components.consul.service.search-bar.",[30,3,["status","key"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","key"]]],null],[28,[37,3],["common.consul.",[30,3,["status","key"]]],null]],null]]]],[28,[37,2],[[28,[37,3],["components.consul.service.search-bar.",[30,3,["status","value"]]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,3,["status","value"]]],null],[28,[37,3],["common.consul.",[30,3,["status","value"]]],null],[28,[37,3],["common.brand.",[30,3,["status","value"]]],null]],null]]]]],[[[1," "],[8,[30,3,["RemoveFilter"]],[[16,"aria-label",[28,[37,2],["common.ui.remove"],[["item"],[[28,[37,3],[[30,4]," ",[30,5]],null]]]]]],null,[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,[30,4]],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,5]],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[4,5]]],[1,"\\n "]],[3]],[[[1,"\\n "],[8,[30,6,["Search"]],null,[["@onsearch","@value","@placeholder"],[[28,[37,5],[[30,0],[30,7]],null],[30,8],[28,[37,2],["common.search.search"],null]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Select"]],[[24,0,"type-search-properties"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,2,["searchproperty","change"]]],null],true,true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.search.searchproperty"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,9,["Optgroup"]],[30,9,["Option"]]],[[[42,[28,[37,8],[[28,[37,8],[[30,2,["searchproperty","default"]]],null]],null],null,[[[1," "],[8,[30,11],null,[["@value","@selected"],[[30,12],[28,[37,9],[[30,12],[30,2,["searchproperty","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[28,[37,10],[[30,12]],null]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[12]],null]],[10,11]]],[1," "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]],[[[1,"\\n "],[8,[30,13,["Select"]],[[24,0,"type-status"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["status","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["common.consul.status"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,14,["Optgroup"]],[30,14,["Option"]]],[[[42,[28,[37,8],[[28,[37,8],[[30,0,["healthStates"]]],null]],null],null,[[[1," "],[8,[30,16],[[16,0,[29,["value-",[30,17]]]]],[["@value","@selected"],[[30,17],[28,[37,9],[[30,17],[30,2,["status","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[30,17]],null]],[["default"],[[28,[37,4],[[28,[37,3],["common.search.",[30,17]],null]],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[17]],null]],[15,16]]],[1," "]],[]]]]],[1,"\\n "]],[14]]]]],[1,"\\n "],[8,[30,13,["Select"]],null,[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["kind","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n "],[1,[28,[35,2],["components.consul.service.search-bar.kind"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,18,["Optgroup"]],[30,18,["Option"]]],[[[1," "],[8,[30,20],null,[["@value","@selected"],["service",[28,[37,9],["service",[30,2,["kind","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],["common.consul.service"],null]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,19],null,[["@label"],[[28,[37,2],["common.consul.gateway"],null]]],[["default"],[[[[1,"\\n"],[42,[28,[37,8],[[28,[37,8],[[28,[37,4],["api-gateway","ingress-gateway","terminating-gateway","mesh-gateway"],null]],null]],null],null,[[[1," "],[8,[30,20],null,[["@value","@selected"],[[30,21],[28,[37,9],[[30,21],[30,2,["kind","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.consul.",[30,21]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[21]],null],[1," "]],[]]]]],[1,"\\n "],[8,[30,19],null,[["@label"],[[28,[37,2],["common.consul.mesh"],null]]],[["default"],[[[[1,"\\n"],[42,[28,[37,8],[[28,[37,8],[[28,[37,4],["in-mesh","not-in-mesh"],null]],null]],null],null,[[[1," "],[8,[30,20],null,[["@value","@selected"],[[30,22],[28,[37,9],[[30,22],[30,2,["kind","value"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["common.search.",[30,22]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n"]],[22]],null],[1," "]],[]]]]],[1,"\\n"]],[19,20]]],[1," "]],[]]]]],[1,"\\n "]],[18]]]]],[1,"\\n"],[41,[28,[37,12],[[30,23,["length"]],0],null],[[[1," "],[8,[30,13,["Select"]],[[24,0,"type-source"]],[["@position","@onchange","@multiple"],["left",[28,[37,5],[[30,0],[30,2,["source","change"]]],null],true]],[["default"],[[[[1,"\\n "],[8,[39,13],null,[["@components","@filter","@sources"],[[30,24],[30,2],[30,0,["sortedSources"]]]],null],[1,"\\n "]],[24]]]]],[1,"\\n"]],[]],null],[1," "]],[13]],[[[1,"\\n "],[8,[30,25,["Select"]],[[24,0,"type-sort"]],[["@position","@onchange","@multiple","@required"],["right",[28,[37,5],[[30,0],[30,26,["change"]]],null],false,true]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["selected"]],[["default"],[[[[1,"\\n "],[10,1],[12],[1,"\\n"],[44,[[28,[37,14],[[28,[37,4],[[28,[37,4],["Name:asc",[28,[37,2],["common.sort.alpha.asc"],null]],null],[28,[37,4],["Name:desc",[28,[37,2],["common.sort.alpha.desc"],null]],null],[28,[37,4],["Status:asc",[28,[37,2],["common.sort.status.asc"],null]],null],[28,[37,4],["Status:desc",[28,[37,2],["common.sort.status.desc"],null]],null]],null]],null]],[[[1," "],[1,[28,[35,15],[[30,28],[30,26,["value"]]],null]],[1,"\\n"]],[28]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["options"]],[["default"],[[[[1,"\\n"],[44,[[30,27,["Optgroup"]],[30,27,["Option"]]],[[[1," "],[8,[30,29],null,[["@label"],[[28,[37,2],["common.consul.status"],null]]],[["default"],[[[[1,"\\n "],[8,[30,30],null,[["@value","@selected"],["Status:asc",[28,[37,16],["Status:asc",[30,26,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,30],null,[["@value","@selected"],["Status:desc",[28,[37,16],["Status:desc",[30,26,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.status.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,29],null,[["@label"],[[28,[37,2],["common.consul.service-name"],null]]],[["default"],[[[[1,"\\n "],[8,[30,30],null,[["@value","@selected"],["Name:asc",[28,[37,16],["Name:asc",[30,26,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.asc"],null]]],[]]]]],[1,"\\n "],[8,[30,30],null,[["@value","@selected"],["Name:desc",[28,[37,16],["Name:desc",[30,26,["value"]]],null]]],[["default"],[[[[1,[28,[35,2],["common.sort.alpha.desc"],null]]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[29,30]]],[1," "]],[]]]]],[1,"\\n "]],[27]]]]],[1,"\\n "]],[25]]]]],[1,"\\n"]],["&attrs","@filter","search","key","value","search","@onsearch","@search","components","Optgroup","Option","prop","search","components","Optgroup","Option","state","components","Optgroup","Option","kind","state","@sources","components","search","@sort","components","selectable","Optgroup","Option"],false,["search-bar","let","t","concat","array","action","block-slot","each","-track-array","includes","lowercase","if","gt","consul/sources-select","from-entries","get","eq"]]',moduleName:"consul-ui/components/consul/service/search-bar/index.hbs",isStrictMode:!1}) class i extends l.default{get healthStates(){return this.args.peer?["passing","warning","critical","unknown","empty"]:["passing","warning","critical","empty"]}get sortedSources(){const e=this.args.sources||[] return e.unshift(["consul"]),e.includes("consul-api-gateway")?[...e.filter((e=>"consul-api-gateway"!==e)),"consul-api-gateway"]:e}}e.default=i,(0,t.setComponentTemplate)(r,i)})),define("consul-ui/components/consul/source/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -1311,18 +1311,25 @@ function o(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const a=(0,n.createTemplateFactory)({id:"QsBvWU14",block:'[[[1,"\\n"],[11,0],[24,0,"freetext-filter"],[17,1],[12],[1,"\\n "],[10,"label"],[14,0,"type-search"],[12],[1,"\\n "],[10,1],[14,0,"freetext-filter_label"],[12],[1,"Search"],[13],[1,"\\n "],[10,"input"],[14,0,"freetext-filter_input"],[15,"onsearch",[28,[37,0],[[30,0],[30,0,["change"]]],null]],[15,"oninput",[28,[37,0],[[30,0],[30,0,["change"]]],null]],[15,"onkeydown",[28,[37,0],[[30,0],[30,0,["keydown"]]],null]],[14,3,"s"],[15,2,[30,2]],[15,"placeholder",[30,0,["placeholder"]]],[14,"autofocus","autofocus"],[14,4,"search"],[12],[13],[1,"\\n "],[13],[1,"\\n "],[18,3,null],[1,"\\n"],[13]],["&attrs","@value","&default"],false,["action","yield"]]',moduleName:"consul-ui/components/freetext-filter/index.hbs",isStrictMode:!1}) let u=(o((i=class extends l.default{get placeholder(){return this.args.placeholder||"Search"}get onsearch(){return this.args.onsearch||(()=>{})}change(e){this.onsearch(e)}keydown(e){13===e.keyCode&&e.preventDefault()}}).prototype,"change",[r.action],Object.getOwnPropertyDescriptor(i.prototype,"change"),i.prototype),o(i.prototype,"keydown",[r.action],Object.getOwnPropertyDescriptor(i.prototype,"keydown"),i.prototype),i) -e.default=u,(0,t.setComponentTemplate)(a,u)})),define("consul-ui/components/hashicorp-consul/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/service"],(function(e,t,n,l,r){var i,o,a +e.default=u,(0,t.setComponentTemplate)(a,u)})),define("consul-ui/components/hashicorp-consul/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/service"],(function(e,t,n,l,r){var i,o,a,u,s +function c(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function d(e,t,n,l,r){var i={} +return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +const p=(0,n.createTemplateFactory)({id:"dpUxCs9Y",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"hashicorp-consul"],[17,1]],null,[["notifications","side-nav","main"],[[[[1,"\\n"],[42,[28,[37,2],[[28,[37,2],[[33,3,["queue"]]],null]],null],null,[[[1," "],[8,[30,2,["Notification"]],null,[["@delay","@sticky"],[[28,[37,4],[[30,3,["timeout"]],[30,3,["extendedTimeout"]]],null],[30,3,["sticky"]]]],[["default"],[[[[1,"\\n"],[41,[30,3,["dom"]],[[[1," "],[2,[30,3,["dom"]]],[1,"\\n"]],[]],[[[44,[[28,[37,7],[[30,3,["type"]]],null],[28,[37,7],[[30,3,["action"]]],null]],[[[1," "],[8,[39,8],[[24,"data-notification",""]],[["@color"],[[52,[28,[37,9],[[30,4],"error"],null],"critical",[30,4]]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Title"]],null,null,[["default"],[[[[1,[28,[35,10],[[30,4]],null]],[1,"!"]],[]]]]],[1,"\\n "],[8,[30,6,["Description"]],null,null,[["default"],[[[[1,"\\n"],[41,[28,[37,9],[[30,5],"logout"],null],[[[41,[28,[37,9],[[30,4],"success"],null],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-out"],null]],[1,"\\n"]],[]],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-out-error"],null]],[1,"\\n"]],[]]]],[]],[[[41,[28,[37,9],[[30,5],"authorize"],null],[[[41,[28,[37,9],[[30,4],"success"],null],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-in"],null]],[1,"\\n"]],[]],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-in-error"],null]],[1,"\\n"]],[]]]],[]],[[[41,[28,[37,12],[[28,[37,9],[[30,5],"use"],null],[28,[37,9],[[30,3,["model"]],"token"],null]],null],[[[1," "],[8,[39,13],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n"]],[]],[[[41,[28,[37,9],[[30,3,["model"]],"intention"],null],[[[1," "],[8,[39,14],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n"]],[]],[[[41,[28,[37,9],[[30,3,["model"]],"role"],null],[[[1," "],[8,[39,15],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n"]],[]],[[[41,[28,[37,9],[[30,3,["model"]],"policy"],null],[[[1," "],[8,[39,16],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n "]],[]],null]],[]]]],[]]]],[]]],[1," "]],[]]]],[]]],[1," "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n\\n"]],[4,5]]]],[]]],[1," "]],[]]]]],[1,"\\n"]],[3]],null],[1,"\\n "]],[2]],[[[1,"\\n "],[8,[39,17],[[24,0,"consul-side-nav"]],[["@hasA11yRefocus","@isResponsive"],[false,false]],[["header","body","footer"],[[[[1,"\\n "],[8,[39,18],null,null,[["logo","actions"],[[[[1,"\\n "],[8,[39,19],null,[["@icon","@ariaLabel","@href","@isHrefExternal"],["consul-color","Consul",[28,[37,20],["index"],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false]],null],[1,"\\n "]],[]],[[[1,"\\n "],[8,[39,22],[[24,0,"hds-side-nav__dropdown"]],[["@listPosition"],["bottom-left"]],[["default"],[[[[1,"\\n "],[8,[30,7,["ToggleIcon"]],null,[["@icon","@text"],["help","Help & Support menu"]],null],[1,"\\n "],[8,[39,23],null,[["@dropdown"],[[30,7]]],null],[1,"\\n "],[8,[30,7,["Interactive"]],null,[["@href","@isHrefExternal","@text"],[[28,[37,24],["CONSUL_DOCS_URL"],null],true,[28,[37,11],["components.hashicorp-consul.side-nav.support-menu.docs"],null]]],null],[1,"\\n "],[8,[30,7,["Interactive"]],null,[["@href","@isHrefExternal","@text"],[[28,[37,25],[[28,[37,24],["CONSUL_DOCS_LEARN_URL"],null],"/consul"],null],true,[28,[37,11],["components.hashicorp-consul.side-nav.support-menu.tutorials"],null]]],null],[1,"\\n "],[8,[30,7,["Interactive"]],null,[["@href","@isHrefExternal","@text"],[[28,[37,24],["CONSUL_REPO_ISSUES_URL"],null],true,[28,[37,11],["components.hashicorp-consul.side-nav.support-menu.feedback"],null]]],null],[1,"\\n "]],[7]]]]],[1,"\\n\\n "],[8,[39,26],null,[["@dc","@partition","@nspace","@onchange"],[[30,8],[30,9],[30,10],[30,11]]],[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@target","@name","@value"],[[30,0],"tokenSelector",[30,12]]],null],[1,"\\n "]],[12]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]],[[[1,"\\n "],[8,[39,28],[[24,0,"hds-side-nav-hide-when-minimized consul-side-nav__selector-group"]],null,[["default"],[[[[1,"\\n "],[8,[39,29],null,[["@list"],[[30,13]]],null],[1,"\\n "],[8,[39,30],null,[["@list","@dc","@partition","@nspace","@dcs"],[[30,13],[30,8],[30,9],[30,10],[30,14]]],null],[1,"\\n\\n "],[8,[39,31],null,[["@dc","@partition","@nspace","@partitions","@list","@onchange"],[[30,8],[30,9],[30,10],[30,0,["partitions"]],[30,13],[28,[37,32],[[30,0],[28,[37,33],[[30,0,["partitions"]]],null]],[["value"],["data"]]]]],null],[1,"\\n "],[8,[39,34],null,[["@list","@dc","@partition","@nspace","@nspaces","@onchange"],[[30,13],[30,8],[30,9],[30,10],[30,0,["nspaces"]],[28,[37,32],[[30,0],[28,[37,33],[[30,0,["nspaces"]]],null]],[["value"],["data"]]]]],null],[1,"\\n "]],[13]]]]],[1,"\\n "],[8,[39,28],[[24,0,"hds-side-nav-hide-when-minimized"]],null,[["default"],[[[[1,"\\n"],[41,[28,[37,35],["access overview"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@route","@models","@query","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.overview"],null],"dc.show",[28,[37,36],[[30,8,["Name"]]],null],[28,[37,21],null,[["peer"],[[27]]]],[28,[37,37],["dc.show",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read services"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.services"],null],[28,[37,20],["dc.services",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.services",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read nodes"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.nodes"],null],[28,[37,20],["dc.nodes",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.nodes",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read kv"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.kv"],null],[28,[37,20],["dc.kv",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.kv",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read intentions"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.intentions"],null],[28,[37,20],["dc.intentions",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.intentions",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[1,"\\n "],[8,[39,38],null,[["@dc","@partition","@nspace","@list"],[[30,8],[30,9],[30,10],[30,15]]],null],[1,"\\n "],[8,[39,39],null,[["@dc","@partition","@nspace","@list"],[[30,8],[30,9],[30,10],[30,15]]],null],[1,"\\n "]],[15]]]]],[1,"\\n "]],[]],[[[1,"\\n "],[10,"footer"],[14,"role","contentinfo"],[12],[1,"\\n "],[8,[39,40],[[24,0,"hds-side-nav-hide-when-minimized"]],[["@size","@color"],["100","disabled"]],[["default"],[[[[1,"\\n "],[1,[28,[35,11],["components.hashicorp-consul.side-nav.footer"],[["version"],[[30,0,["consulVersion"]]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[2,[28,[37,25],["\x3c!-- ",[28,[37,24],["CONSUL_GIT_SHA"],null],"--\x3e"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]],[[[1,"\\n "],[18,16,[[28,[37,21],null,[["login"],[[52,[30,0,["tokenSelector"]],[30,0,["tokenSelector"]],[28,[37,21],null,[["open","close"],[[27],[27]]]]]]]]]],[1,"\\n "]],[]]]]]],["&attrs","app","flash","status","type","T","dd","@dc","@partition","@nspace","@onchange","selector","SNL","@dcs","SNL","&default"],false,["app","each","-track-array","flashMessages","sub","if","let","lowercase","hds/toast","eq","capitalize","t","or","consul/token/notifications","consul/intention/notifications","consul/role/notifications","consul/policy/notifications","hds/side-nav","hds/side-nav/header","hds/side-nav/header/home-link","href-to","hash","hds/dropdown","debug/navigation","env","concat","consul/token/selector","ref","hds/side-nav/list","hcp-nav-item","consul/datacenter/selector","consul/partition/selector","action","mut","consul/nspace/selector","can","array","is-href","consul/acl/selector","consul/peer/selector","hds/text/display","yield"]]',moduleName:"consul-ui/components/hashicorp-consul/index.hbs",isStrictMode:!1}) +let f=(i=(0,r.inject)("flashMessages"),o=(0,r.inject)("env"),a=class extends l.default{constructor(){super(...arguments),c(this,"flashMessages",u,this),c(this,"env",s,this)}get consulVersion(){const e=["","oss"].includes(this.env.var("CONSUL_BINARY_TYPE"))?"":"+ent" +return`${this.env.var("CONSUL_VERSION")}${e}`}},u=d(a.prototype,"flashMessages",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),s=d(a.prototype,"env",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),a) +e.default=f,(0,t.setComponentTemplate)(p,f)})) +define("consul-ui/components/hcp-nav-item/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/service"],(function(e,t,n,l,r){var i,o Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const u=(0,n.createTemplateFactory)({id:"xnhilElo",block:'[[[1,"\\n"],[8,[39,0],[[24,0,"hashicorp-consul"],[17,1]],null,[["notifications","side-nav","main"],[[[[1,"\\n"],[42,[28,[37,2],[[28,[37,2],[[33,3,["queue"]]],null]],null],null,[[[1," "],[8,[30,2,["Notification"]],null,[["@delay","@sticky"],[[28,[37,4],[[30,3,["timeout"]],[30,3,["extendedTimeout"]]],null],[30,3,["sticky"]]]],[["default"],[[[[1,"\\n"],[41,[30,3,["dom"]],[[[1," "],[2,[30,3,["dom"]]],[1,"\\n"]],[]],[[[44,[[28,[37,7],[[30,3,["type"]]],null],[28,[37,7],[[30,3,["action"]]],null]],[[[1," "],[8,[39,8],[[24,"data-notification",""]],[["@color"],[[52,[28,[37,9],[[30,4],"error"],null],"critical",[30,4]]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Title"]],null,null,[["default"],[[[[1,[28,[35,10],[[30,4]],null]],[1,"!"]],[]]]]],[1,"\\n "],[8,[30,6,["Description"]],null,null,[["default"],[[[[1,"\\n"],[41,[28,[37,9],[[30,5],"logout"],null],[[[41,[28,[37,9],[[30,4],"success"],null],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-out"],null]],[1,"\\n"]],[]],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-out-error"],null]],[1,"\\n"]],[]]]],[]],[[[41,[28,[37,9],[[30,5],"authorize"],null],[[[41,[28,[37,9],[[30,4],"success"],null],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-in"],null]],[1,"\\n"]],[]],[[[1," "],[1,[28,[35,11],["components.hashicorp-consul.notifications.logged-in-error"],null]],[1,"\\n"]],[]]]],[]],[[[41,[28,[37,12],[[28,[37,9],[[30,5],"use"],null],[28,[37,9],[[30,3,["model"]],"token"],null]],null],[[[1," "],[8,[39,13],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n"]],[]],[[[41,[28,[37,9],[[30,3,["model"]],"intention"],null],[[[1," "],[8,[39,14],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n"]],[]],[[[41,[28,[37,9],[[30,3,["model"]],"role"],null],[[[1," "],[8,[39,15],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n"]],[]],[[[41,[28,[37,9],[[30,3,["model"]],"policy"],null],[[[1," "],[8,[39,16],null,[["@type","@status","@item","@error"],[[30,5],[30,4],[30,3,["item"]],[30,3,["error"]]]],null],[1,"\\n "]],[]],null]],[]]]],[]]]],[]]],[1," "]],[]]]],[]]],[1," "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n\\n"]],[4,5]]]],[]]],[1," "]],[]]]]],[1,"\\n"]],[3]],null],[1,"\\n "]],[2]],[[[1,"\\n "],[8,[39,17],[[24,0,"consul-side-nav"]],[["@isResponsive"],[false]],[["header","body","footer"],[[[[1,"\\n "],[8,[39,18],null,null,[["logo","actions"],[[[[1,"\\n "],[8,[39,19],null,[["@icon","@ariaLabel","@href","@isHrefExternal"],["consul-color","Consul",[28,[37,20],["index"],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false]],null],[1,"\\n "]],[]],[[[1,"\\n "],[8,[39,22],[[24,0,"hds-side-nav__dropdown"]],[["@listPosition"],["bottom-left"]],[["default"],[[[[1,"\\n "],[8,[30,7,["ToggleIcon"]],null,[["@icon","@text"],["help","Help & Support menu"]],null],[1,"\\n "],[8,[39,23],null,[["@dropdown"],[[30,7]]],null],[1,"\\n "],[8,[30,7,["Interactive"]],null,[["@href","@isHrefExternal","@text"],[[28,[37,24],["CONSUL_DOCS_URL"],null],true,[28,[37,11],["components.hashicorp-consul.side-nav.support-menu.docs"],null]]],null],[1,"\\n "],[8,[30,7,["Interactive"]],null,[["@href","@isHrefExternal","@text"],[[28,[37,25],[[28,[37,24],["CONSUL_DOCS_LEARN_URL"],null],"/consul"],null],true,[28,[37,11],["components.hashicorp-consul.side-nav.support-menu.tutorials"],null]]],null],[1,"\\n "],[8,[30,7,["Interactive"]],null,[["@href","@isHrefExternal","@text"],[[28,[37,24],["CONSUL_REPO_ISSUES_URL"],null],true,[28,[37,11],["components.hashicorp-consul.side-nav.support-menu.feedback"],null]]],null],[1,"\\n "]],[7]]]]],[1,"\\n\\n "],[8,[39,26],null,[["@dc","@partition","@nspace","@onchange"],[[30,8],[30,9],[30,10],[30,11]]],[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@target","@name","@value"],[[30,0],"tokenSelector",[30,12]]],null],[1,"\\n "]],[12]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]],[[[1,"\\n "],[8,[39,28],[[24,0,"hds-side-nav-hide-when-minimized consul-side-nav__selector-group"]],null,[["default"],[[[[1,"\\n "],[8,[39,29],null,[["@list"],[[30,13]]],null],[1,"\\n "],[8,[39,30],null,[["@list","@dc","@partition","@nspace","@dcs"],[[30,13],[30,8],[30,9],[30,10],[30,14]]],null],[1,"\\n\\n "],[8,[39,31],null,[["@dc","@partition","@nspace","@partitions","@list","@onchange"],[[30,8],[30,9],[30,10],[30,0,["partitions"]],[30,13],[28,[37,32],[[30,0],[28,[37,33],[[30,0,["partitions"]]],null]],[["value"],["data"]]]]],null],[1,"\\n "],[8,[39,34],null,[["@list","@dc","@partition","@nspace","@nspaces","@onchange"],[[30,13],[30,8],[30,9],[30,10],[30,0,["nspaces"]],[28,[37,32],[[30,0],[28,[37,33],[[30,0,["nspaces"]]],null]],[["value"],["data"]]]]],null],[1,"\\n "]],[13]]]]],[1,"\\n "],[8,[39,28],[[24,0,"hds-side-nav-hide-when-minimized"]],null,[["default"],[[[[1,"\\n"],[41,[28,[37,35],["access overview"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@route","@models","@query","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.overview"],null],"dc.show",[28,[37,36],[[30,8,["Name"]]],null],[28,[37,21],null,[["peer"],[[27]]]],[28,[37,37],["dc.show",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read services"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.services"],null],[28,[37,20],["dc.services",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.services",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read nodes"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.nodes"],null],[28,[37,20],["dc.nodes",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.nodes",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read kv"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.kv"],null],[28,[37,20],["dc.kv",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.kv",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[41,[28,[37,35],["read intentions"],null],[[[1," "],[8,[30,15,["Link"]],null,[["@text","@href","@isHrefExternal","@isActive"],[[28,[37,11],["components.hashicorp-consul.side-nav.intentions"],null],[28,[37,20],["dc.intentions",[30,8,["Name"]]],[["params"],[[28,[37,21],null,[["peer"],[[27]]]]]]],false,[28,[37,37],["dc.intentions",[30,8,["Name"]]],null]]],null],[1,"\\n"]],[]],null],[1,"\\n "],[8,[39,38],null,[["@dc","@partition","@nspace","@list"],[[30,8],[30,9],[30,10],[30,15]]],null],[1,"\\n "],[8,[39,39],null,[["@dc","@partition","@nspace","@list"],[[30,8],[30,9],[30,10],[30,15]]],null],[1,"\\n "]],[15]]]]],[1,"\\n "]],[]],[[[1,"\\n "],[10,"footer"],[14,"role","contentinfo"],[12],[1,"\\n "],[8,[39,40],[[24,0,"hds-side-nav-hide-when-minimized"]],[["@size","@color"],["100","disabled"]],[["default"],[[[[1,"\\n "],[1,[28,[35,11],["components.hashicorp-consul.side-nav.footer"],[["version"],[[28,[37,24],["CONSUL_VERSION"],null]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[2,[28,[37,25],["\x3c!-- ",[28,[37,24],["CONSUL_GIT_SHA"],null],"--\x3e"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]],[[[1,"\\n "],[18,16,[[28,[37,21],null,[["login"],[[52,[30,0,["tokenSelector"]],[30,0,["tokenSelector"]],[28,[37,21],null,[["open","close"],[[27],[27]]]]]]]]]],[1,"\\n "]],[]]]]]],["&attrs","app","flash","status","type","T","dd","@dc","@partition","@nspace","@onchange","selector","SNL","@dcs","SNL","&default"],false,["app","each","-track-array","flashMessages","sub","if","let","lowercase","hds/toast","eq","capitalize","t","or","consul/token/notifications","consul/intention/notifications","consul/role/notifications","consul/policy/notifications","hds/side-nav","hds/side-nav/header","hds/side-nav/header/home-link","href-to","hash","hds/dropdown","debug/navigation","env","concat","consul/token/selector","ref","hds/side-nav/list","consul/hcp/home","consul/datacenter/selector","consul/partition/selector","action","mut","consul/nspace/selector","can","array","is-href","consul/acl/selector","consul/peer/selector","hds/text/display","yield"]]',moduleName:"consul-ui/components/hashicorp-consul/index.hbs",isStrictMode:!1}) -let s=(i=(0,r.inject)("flashMessages"),o=class extends l.default{constructor(){var e,t,n,l -super(...arguments),e=this,t="flashMessages",l=this,(n=a)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}},c=o.prototype,d="flashMessages",p=[i],f={configurable:!0,enumerable:!0,writable:!0,initializer:null},h={},Object.keys(f).forEach((function(e){h[e]=f[e]})),h.enumerable=!!h.enumerable,h.configurable=!!h.configurable,("value"in h||h.initializer)&&(h.writable=!0),h=p.slice().reverse().reduce((function(e,t){return t(c,d,e)||e}),h),m&&void 0!==h.initializer&&(h.value=h.initializer?h.initializer.call(m):void 0,h.initializer=void 0),void 0===h.initializer&&(Object.defineProperty(c,d,h),h=null),a=h,o) -var c,d,p,f,m,h -e.default=s,(0,t.setComponentTemplate)(u,s)})) -define("consul-ui/components/hds/accordion/index",["exports","@hashicorp/design-system-components/components/hds/accordion/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/accordion/item/button",["exports","@hashicorp/design-system-components/components/hds/accordion/item/button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/accordion/item/index",["exports","@hashicorp/design-system-components/components/hds/accordion/item/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/alert/description",["exports","@hashicorp/design-system-components/components/hds/alert/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/alert/index",["exports","@hashicorp/design-system-components/components/hds/alert/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/alert/title",["exports","@hashicorp/design-system-components/components/hds/alert/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/copyright",["exports","@hashicorp/design-system-components/components/hds/app-footer/copyright"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/index",["exports","@hashicorp/design-system-components/components/hds/app-footer/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/item",["exports","@hashicorp/design-system-components/components/hds/app-footer/item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/legal-links",["exports","@hashicorp/design-system-components/components/hds/app-footer/legal-links"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/link",["exports","@hashicorp/design-system-components/components/hds/app-footer/link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/status-link",["exports","@hashicorp/design-system-components/components/hds/app-footer/status-link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/index",["exports","@hashicorp/design-system-components/components/hds/app-frame/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/footer",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/header",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/main",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/main"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/modals",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/modals"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/sidebar",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/sidebar"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/body",["exports","@hashicorp/design-system-components/components/hds/application-state/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/footer",["exports","@hashicorp/design-system-components/components/hds/application-state/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/header",["exports","@hashicorp/design-system-components/components/hds/application-state/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/index",["exports","@hashicorp/design-system-components/components/hds/application-state/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/avatar/index",["exports","@hashicorp/design-system-components/components/hds/avatar/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/badge-count/index",["exports","@hashicorp/design-system-components/components/hds/badge-count/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/badge/index",["exports","@hashicorp/design-system-components/components/hds/badge/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/breadcrumb/index",["exports","@hashicorp/design-system-components/components/hds/breadcrumb/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/breadcrumb/item",["exports","@hashicorp/design-system-components/components/hds/breadcrumb/item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/breadcrumb/truncation",["exports","@hashicorp/design-system-components/components/hds/breadcrumb/truncation"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/button-set/index",["exports","@hashicorp/design-system-components/components/hds/button-set/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/button/index",["exports","@hashicorp/design-system-components/components/hds/button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/components/hds/card/container",["exports","@hashicorp/design-system-components/components/hds/card/container"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/copy/button/index",["exports","@hashicorp/design-system-components/components/hds/copy/button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/copy/snippet/index",["exports","@hashicorp/design-system-components/components/hds/copy/snippet/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/disclosure-primitive/index",["exports","@hashicorp/design-system-components/components/hds/disclosure-primitive/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dismiss-button/index",["exports","@hashicorp/design-system-components/components/hds/dismiss-button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/footer",["exports","@hashicorp/design-system-components/components/hds/dropdown/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/header",["exports","@hashicorp/design-system-components/components/hds/dropdown/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/index",["exports","@hashicorp/design-system-components/components/hds/dropdown/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/checkbox",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/checkbox"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/checkmark",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/checkmark"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/copy-item",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/copy-item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/description",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/generic",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/generic"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/interactive",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/interactive"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/radio",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/radio"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/separator",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/separator"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/title",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/toggle/button",["exports","@hashicorp/design-system-components/components/hds/dropdown/toggle/button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/toggle/chevron",["exports","@hashicorp/design-system-components/components/hds/dropdown/toggle/chevron"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/toggle/icon",["exports","@hashicorp/design-system-components/components/hds/dropdown/toggle/icon"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/body",["exports","@hashicorp/design-system-components/components/hds/flyout/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/description",["exports","@hashicorp/design-system-components/components/hds/flyout/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/footer",["exports","@hashicorp/design-system-components/components/hds/flyout/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/header",["exports","@hashicorp/design-system-components/components/hds/flyout/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/index",["exports","@hashicorp/design-system-components/components/hds/flyout/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/checkbox/base",["exports","@hashicorp/design-system-components/components/hds/form/checkbox/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/checkbox/field",["exports","@hashicorp/design-system-components/components/hds/form/checkbox/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/checkbox/group",["exports","@hashicorp/design-system-components/components/hds/form/checkbox/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/error/index",["exports","@hashicorp/design-system-components/components/hds/form/error/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/error/message",["exports","@hashicorp/design-system-components/components/hds/form/error/message"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/components/hds/form/field/index",["exports","@hashicorp/design-system-components/components/hds/form/field/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/fieldset/index",["exports","@hashicorp/design-system-components/components/hds/form/fieldset/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/file-input/base",["exports","@hashicorp/design-system-components/components/hds/form/file-input/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/file-input/field",["exports","@hashicorp/design-system-components/components/hds/form/file-input/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/helper-text/index",["exports","@hashicorp/design-system-components/components/hds/form/helper-text/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/indicator/index",["exports","@hashicorp/design-system-components/components/hds/form/indicator/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/label/index",["exports","@hashicorp/design-system-components/components/hds/form/label/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/legend/index",["exports","@hashicorp/design-system-components/components/hds/form/legend/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/masked-input/base",["exports","@hashicorp/design-system-components/components/hds/form/masked-input/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/masked-input/field",["exports","@hashicorp/design-system-components/components/hds/form/masked-input/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/description",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/group",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/index",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/label",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/label"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio/base",["exports","@hashicorp/design-system-components/components/hds/form/radio/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio/field",["exports","@hashicorp/design-system-components/components/hds/form/radio/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio/group",["exports","@hashicorp/design-system-components/components/hds/form/radio/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/select/base",["exports","@hashicorp/design-system-components/components/hds/form/select/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/select/field",["exports","@hashicorp/design-system-components/components/hds/form/select/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/text-input/base",["exports","@hashicorp/design-system-components/components/hds/form/text-input/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/text-input/field",["exports","@hashicorp/design-system-components/components/hds/form/text-input/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/textarea/base",["exports","@hashicorp/design-system-components/components/hds/form/textarea/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/textarea/field",["exports","@hashicorp/design-system-components/components/hds/form/textarea/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/toggle/base",["exports","@hashicorp/design-system-components/components/hds/form/toggle/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/toggle/field",["exports","@hashicorp/design-system-components/components/hds/form/toggle/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/toggle/group",["exports","@hashicorp/design-system-components/components/hds/form/toggle/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/visibility-toggle/index",["exports","@hashicorp/design-system-components/components/hds/form/visibility-toggle/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/icon-tile/index",["exports","@hashicorp/design-system-components/components/hds/icon-tile/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/interactive/index",["exports","@hashicorp/design-system-components/components/hds/interactive/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/link/inline",["exports","@hashicorp/design-system-components/components/hds/link/inline"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/components/hds/link/standalone",["exports","@hashicorp/design-system-components/components/hds/link/standalone"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/menu-primitive/index",["exports","@hashicorp/design-system-components/components/hds/menu-primitive/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/body",["exports","@hashicorp/design-system-components/components/hds/modal/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/footer",["exports","@hashicorp/design-system-components/components/hds/modal/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/header",["exports","@hashicorp/design-system-components/components/hds/modal/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/index",["exports","@hashicorp/design-system-components/components/hds/modal/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/actions",["exports","@hashicorp/design-system-components/components/hds/page-header/actions"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/badges",["exports","@hashicorp/design-system-components/components/hds/page-header/badges"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/description",["exports","@hashicorp/design-system-components/components/hds/page-header/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/index",["exports","@hashicorp/design-system-components/components/hds/page-header/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/subtitle",["exports","@hashicorp/design-system-components/components/hds/page-header/subtitle"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/title",["exports","@hashicorp/design-system-components/components/hds/page-header/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/compact/index",["exports","@hashicorp/design-system-components/components/hds/pagination/compact/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/info",["exports","@hashicorp/design-system-components/components/hds/pagination/info"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/nav/arrow",["exports","@hashicorp/design-system-components/components/hds/pagination/nav/arrow"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/nav/ellipsis",["exports","@hashicorp/design-system-components/components/hds/pagination/nav/ellipsis"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/nav/number",["exports","@hashicorp/design-system-components/components/hds/pagination/nav/number"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/numbered/index",["exports","@hashicorp/design-system-components/components/hds/pagination/numbered/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/size-selector",["exports","@hashicorp/design-system-components/components/hds/pagination/size-selector"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/reveal/index",["exports","@hashicorp/design-system-components/components/hds/reveal/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/reveal/toggle/button",["exports","@hashicorp/design-system-components/components/hds/reveal/toggle/button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/segmented-group/index",["exports","@hashicorp/design-system-components/components/hds/segmented-group/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/separator/index",["exports","@hashicorp/design-system-components/components/hds/separator/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/base",["exports","@hashicorp/design-system-components/components/hds/side-nav/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/header/home-link",["exports","@hashicorp/design-system-components/components/hds/side-nav/header/home-link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/header/icon-button",["exports","@hashicorp/design-system-components/components/hds/side-nav/header/icon-button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/header/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/back-link",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/back-link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/components/hds/side-nav/list/item",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/link",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/title",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/portal/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/portal/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/portal/target",["exports","@hashicorp/design-system-components/components/hds/side-nav/portal/target"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/toggle-button",["exports","@hashicorp/design-system-components/components/hds/side-nav/toggle-button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/stepper/step/indicator",["exports","@hashicorp/design-system-components/components/hds/stepper/step/indicator"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/stepper/task/indicator",["exports","@hashicorp/design-system-components/components/hds/stepper/task/indicator"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/index",["exports","@hashicorp/design-system-components/components/hds/table/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/td",["exports","@hashicorp/design-system-components/components/hds/table/td"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/th-sort",["exports","@hashicorp/design-system-components/components/hds/table/th-sort"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/th",["exports","@hashicorp/design-system-components/components/hds/table/th"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/tr",["exports","@hashicorp/design-system-components/components/hds/table/tr"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tabs/index",["exports","@hashicorp/design-system-components/components/hds/tabs/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tabs/panel",["exports","@hashicorp/design-system-components/components/hds/tabs/panel"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tabs/tab",["exports","@hashicorp/design-system-components/components/hds/tabs/tab"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tag/index",["exports","@hashicorp/design-system-components/components/hds/tag/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/body",["exports","@hashicorp/design-system-components/components/hds/text/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/code",["exports","@hashicorp/design-system-components/components/hds/text/code"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/display",["exports","@hashicorp/design-system-components/components/hds/text/display"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/index",["exports","@hashicorp/design-system-components/components/hds/text/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/toast/index",["exports","@hashicorp/design-system-components/components/hds/toast/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tooltip-button/index",["exports","@hashicorp/design-system-components/components/hds/tooltip-button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/yield/index",["exports","@hashicorp/design-system-components/components/hds/yield/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/informed-action/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +const a=(0,n.createTemplateFactory)({id:"l8c9YROO",block:'[[[1,"\\n"],[44,[[30,1],[28,[37,1],["CONSUL_HCP_URL"],null]],[[[41,[30,0,["shouldShowBackToHcpItem"]],[[[1," "],[8,[30,2,["BackLink"]],null,[["@text","@href","@isHrefExternal"],[[28,[37,3],["components.hashicorp-consul.side-nav.hcp"],null],[30,3],true]],null],[1,"\\n"]],[]],null]],[2,3]]]],["@list","SNL","hcpUrl"],false,["let","env","if","t"]]',moduleName:"consul-ui/components/hcp-nav-item/index.hbs",isStrictMode:!1}) +let u=(i=class extends l.default{constructor(){var e,t,n,l +super(...arguments),e=this,t="env",l=this,(n=o)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}get shouldShowBackToHcpItem(){const e=!!this.env.var("CONSUL_HCP_URL") +return!!this.env.var("CONSUL_HCP_ENABLED")&&e}},s=i.prototype,c="env",d=[r.inject],p={configurable:!0,enumerable:!0,writable:!0,initializer:null},m={},Object.keys(p).forEach((function(e){m[e]=p[e]})),m.enumerable=!!m.enumerable,m.configurable=!!m.configurable,("value"in m||m.initializer)&&(m.writable=!0),m=d.slice().reverse().reduce((function(e,t){return t(s,c,e)||e}),m),f&&void 0!==m.initializer&&(m.value=m.initializer?m.initializer.call(f):void 0,m.initializer=void 0),void 0===m.initializer&&(Object.defineProperty(s,c,m),m=null),o=m,i) +var s,c,d,p,f,m +e.default=u,(0,t.setComponentTemplate)(a,u)})),define("consul-ui/components/hds/accordion/index",["exports","@hashicorp/design-system-components/components/hds/accordion/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/accordion/item/button",["exports","@hashicorp/design-system-components/components/hds/accordion/item/button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/accordion/item/index",["exports","@hashicorp/design-system-components/components/hds/accordion/item/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/alert/description",["exports","@hashicorp/design-system-components/components/hds/alert/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/alert/index",["exports","@hashicorp/design-system-components/components/hds/alert/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/alert/title",["exports","@hashicorp/design-system-components/components/hds/alert/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/copyright",["exports","@hashicorp/design-system-components/components/hds/app-footer/copyright"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/index",["exports","@hashicorp/design-system-components/components/hds/app-footer/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/item",["exports","@hashicorp/design-system-components/components/hds/app-footer/item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/legal-links",["exports","@hashicorp/design-system-components/components/hds/app-footer/legal-links"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/link",["exports","@hashicorp/design-system-components/components/hds/app-footer/link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-footer/status-link",["exports","@hashicorp/design-system-components/components/hds/app-footer/status-link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/index",["exports","@hashicorp/design-system-components/components/hds/app-frame/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/footer",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/header",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/main",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/main"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/modals",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/modals"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/app-frame/parts/sidebar",["exports","@hashicorp/design-system-components/components/hds/app-frame/parts/sidebar"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/body",["exports","@hashicorp/design-system-components/components/hds/application-state/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/footer",["exports","@hashicorp/design-system-components/components/hds/application-state/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/header",["exports","@hashicorp/design-system-components/components/hds/application-state/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/application-state/index",["exports","@hashicorp/design-system-components/components/hds/application-state/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/avatar/index",["exports","@hashicorp/design-system-components/components/hds/avatar/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/badge-count/index",["exports","@hashicorp/design-system-components/components/hds/badge-count/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/badge/index",["exports","@hashicorp/design-system-components/components/hds/badge/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/breadcrumb/index",["exports","@hashicorp/design-system-components/components/hds/breadcrumb/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/breadcrumb/item",["exports","@hashicorp/design-system-components/components/hds/breadcrumb/item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/breadcrumb/truncation",["exports","@hashicorp/design-system-components/components/hds/breadcrumb/truncation"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/button-set/index",["exports","@hashicorp/design-system-components/components/hds/button-set/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/components/hds/button/index",["exports","@hashicorp/design-system-components/components/hds/button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/card/container",["exports","@hashicorp/design-system-components/components/hds/card/container"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/copy/button/index",["exports","@hashicorp/design-system-components/components/hds/copy/button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/copy/snippet/index",["exports","@hashicorp/design-system-components/components/hds/copy/snippet/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/disclosure-primitive/index",["exports","@hashicorp/design-system-components/components/hds/disclosure-primitive/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dismiss-button/index",["exports","@hashicorp/design-system-components/components/hds/dismiss-button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/footer",["exports","@hashicorp/design-system-components/components/hds/dropdown/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/header",["exports","@hashicorp/design-system-components/components/hds/dropdown/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/index",["exports","@hashicorp/design-system-components/components/hds/dropdown/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/checkbox",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/checkbox"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/checkmark",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/checkmark"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/copy-item",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/copy-item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/description",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/generic",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/generic"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/interactive",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/interactive"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/radio",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/radio"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/separator",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/separator"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/list-item/title",["exports","@hashicorp/design-system-components/components/hds/dropdown/list-item/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/toggle/button",["exports","@hashicorp/design-system-components/components/hds/dropdown/toggle/button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/toggle/chevron",["exports","@hashicorp/design-system-components/components/hds/dropdown/toggle/chevron"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/dropdown/toggle/icon",["exports","@hashicorp/design-system-components/components/hds/dropdown/toggle/icon"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/body",["exports","@hashicorp/design-system-components/components/hds/flyout/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/description",["exports","@hashicorp/design-system-components/components/hds/flyout/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/footer",["exports","@hashicorp/design-system-components/components/hds/flyout/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/header",["exports","@hashicorp/design-system-components/components/hds/flyout/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/flyout/index",["exports","@hashicorp/design-system-components/components/hds/flyout/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/checkbox/base",["exports","@hashicorp/design-system-components/components/hds/form/checkbox/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/checkbox/field",["exports","@hashicorp/design-system-components/components/hds/form/checkbox/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/checkbox/group",["exports","@hashicorp/design-system-components/components/hds/form/checkbox/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/error/index",["exports","@hashicorp/design-system-components/components/hds/form/error/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/components/hds/form/error/message",["exports","@hashicorp/design-system-components/components/hds/form/error/message"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/field/index",["exports","@hashicorp/design-system-components/components/hds/form/field/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/fieldset/index",["exports","@hashicorp/design-system-components/components/hds/form/fieldset/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/file-input/base",["exports","@hashicorp/design-system-components/components/hds/form/file-input/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/file-input/field",["exports","@hashicorp/design-system-components/components/hds/form/file-input/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/helper-text/index",["exports","@hashicorp/design-system-components/components/hds/form/helper-text/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/indicator/index",["exports","@hashicorp/design-system-components/components/hds/form/indicator/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/label/index",["exports","@hashicorp/design-system-components/components/hds/form/label/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/legend/index",["exports","@hashicorp/design-system-components/components/hds/form/legend/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/masked-input/base",["exports","@hashicorp/design-system-components/components/hds/form/masked-input/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/masked-input/field",["exports","@hashicorp/design-system-components/components/hds/form/masked-input/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/description",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/group",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/index",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio-card/label",["exports","@hashicorp/design-system-components/components/hds/form/radio-card/label"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio/base",["exports","@hashicorp/design-system-components/components/hds/form/radio/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio/field",["exports","@hashicorp/design-system-components/components/hds/form/radio/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/radio/group",["exports","@hashicorp/design-system-components/components/hds/form/radio/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/select/base",["exports","@hashicorp/design-system-components/components/hds/form/select/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/select/field",["exports","@hashicorp/design-system-components/components/hds/form/select/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/text-input/base",["exports","@hashicorp/design-system-components/components/hds/form/text-input/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/text-input/field",["exports","@hashicorp/design-system-components/components/hds/form/text-input/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/textarea/base",["exports","@hashicorp/design-system-components/components/hds/form/textarea/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/textarea/field",["exports","@hashicorp/design-system-components/components/hds/form/textarea/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/toggle/base",["exports","@hashicorp/design-system-components/components/hds/form/toggle/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/toggle/field",["exports","@hashicorp/design-system-components/components/hds/form/toggle/field"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/toggle/group",["exports","@hashicorp/design-system-components/components/hds/form/toggle/group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/form/visibility-toggle/index",["exports","@hashicorp/design-system-components/components/hds/form/visibility-toggle/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/icon-tile/index",["exports","@hashicorp/design-system-components/components/hds/icon-tile/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/interactive/index",["exports","@hashicorp/design-system-components/components/hds/interactive/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/components/hds/link/inline",["exports","@hashicorp/design-system-components/components/hds/link/inline"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/link/standalone",["exports","@hashicorp/design-system-components/components/hds/link/standalone"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/menu-primitive/index",["exports","@hashicorp/design-system-components/components/hds/menu-primitive/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/body",["exports","@hashicorp/design-system-components/components/hds/modal/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/footer",["exports","@hashicorp/design-system-components/components/hds/modal/footer"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/header",["exports","@hashicorp/design-system-components/components/hds/modal/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/modal/index",["exports","@hashicorp/design-system-components/components/hds/modal/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/actions",["exports","@hashicorp/design-system-components/components/hds/page-header/actions"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/badges",["exports","@hashicorp/design-system-components/components/hds/page-header/badges"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/description",["exports","@hashicorp/design-system-components/components/hds/page-header/description"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/index",["exports","@hashicorp/design-system-components/components/hds/page-header/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/subtitle",["exports","@hashicorp/design-system-components/components/hds/page-header/subtitle"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/page-header/title",["exports","@hashicorp/design-system-components/components/hds/page-header/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/compact/index",["exports","@hashicorp/design-system-components/components/hds/pagination/compact/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/info",["exports","@hashicorp/design-system-components/components/hds/pagination/info"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/nav/arrow",["exports","@hashicorp/design-system-components/components/hds/pagination/nav/arrow"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/nav/ellipsis",["exports","@hashicorp/design-system-components/components/hds/pagination/nav/ellipsis"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/nav/number",["exports","@hashicorp/design-system-components/components/hds/pagination/nav/number"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/numbered/index",["exports","@hashicorp/design-system-components/components/hds/pagination/numbered/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/pagination/size-selector",["exports","@hashicorp/design-system-components/components/hds/pagination/size-selector"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/reveal/index",["exports","@hashicorp/design-system-components/components/hds/reveal/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/reveal/toggle/button",["exports","@hashicorp/design-system-components/components/hds/reveal/toggle/button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/segmented-group/index",["exports","@hashicorp/design-system-components/components/hds/segmented-group/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/separator/index",["exports","@hashicorp/design-system-components/components/hds/separator/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/base",["exports","@hashicorp/design-system-components/components/hds/side-nav/base"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/header/home-link",["exports","@hashicorp/design-system-components/components/hds/side-nav/header/home-link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/header/icon-button",["exports","@hashicorp/design-system-components/components/hds/side-nav/header/icon-button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/header/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/header"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/back-link",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/back-link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/components/hds/side-nav/list/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/item",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/item"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/link",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/link"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/list/title",["exports","@hashicorp/design-system-components/components/hds/side-nav/list/title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/portal/index",["exports","@hashicorp/design-system-components/components/hds/side-nav/portal/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/portal/target",["exports","@hashicorp/design-system-components/components/hds/side-nav/portal/target"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/side-nav/toggle-button",["exports","@hashicorp/design-system-components/components/hds/side-nav/toggle-button"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/stepper/step/indicator",["exports","@hashicorp/design-system-components/components/hds/stepper/step/indicator"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/stepper/task/indicator",["exports","@hashicorp/design-system-components/components/hds/stepper/task/indicator"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/index",["exports","@hashicorp/design-system-components/components/hds/table/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/td",["exports","@hashicorp/design-system-components/components/hds/table/td"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/th-sort",["exports","@hashicorp/design-system-components/components/hds/table/th-sort"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/th",["exports","@hashicorp/design-system-components/components/hds/table/th"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/table/tr",["exports","@hashicorp/design-system-components/components/hds/table/tr"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tabs/index",["exports","@hashicorp/design-system-components/components/hds/tabs/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tabs/panel",["exports","@hashicorp/design-system-components/components/hds/tabs/panel"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tabs/tab",["exports","@hashicorp/design-system-components/components/hds/tabs/tab"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tag/index",["exports","@hashicorp/design-system-components/components/hds/tag/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/body",["exports","@hashicorp/design-system-components/components/hds/text/body"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/code",["exports","@hashicorp/design-system-components/components/hds/text/code"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/display",["exports","@hashicorp/design-system-components/components/hds/text/display"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/text/index",["exports","@hashicorp/design-system-components/components/hds/text/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/toast/index",["exports","@hashicorp/design-system-components/components/hds/toast/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/tooltip-button/index",["exports","@hashicorp/design-system-components/components/hds/tooltip-button/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/hds/yield/index",["exports","@hashicorp/design-system-components/components/hds/yield/index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/informed-action/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"OpUoOs2J",block:'[[[1,"\\n"],[11,0],[24,0,"informed-action"],[17,1],[12],[1,"\\n "],[10,0],[12],[1,"\\n "],[10,"header"],[12],[1,"\\n "],[18,2,null],[1,"\\n "],[13],[1,"\\n "],[18,3,null],[1,"\\n "],[13],[1,"\\n "],[10,"ul"],[12],[1,"\\n "],[18,4,[[28,[37,1],null,[["Action"],[[50,"anonymous",0,null,[["tagName"],["li"]]]]]]]],[1,"\\n "],[13],[1,"\\n"],[13]],["&attrs","&header","&body","&actions"],false,["yield","hash","component"]]',moduleName:"consul-ui/components/informed-action/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/ivy-codemirror",["exports","ivy-codemirror/components/ivy-codemirror"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/jwt-source/index",["exports","@glimmer/component","@ember/service","consul-ui/utils/dom/event-source"],(function(e,t,n,l){var r,i,o,a,u @@ -1340,14 +1347,14 @@ this.set("height",Math.max(0,r)),this.updateItems(),this.updateScrollPosition()} if(t.target.checked&&e!==this.checked){(0,r.set)(this,"checked",parseInt(e)),this.$row=this.dom.closest("li",t.target),this.$row.style.zIndex=1 const n=this.dom.sibling(t.target,"div") n.getBoundingClientRect().top+n.clientHeight>this.dom.element('footer[role="contentinfo"]').getBoundingClientRect().top?n.classList.add("above"):n.classList.remove("above")}else{this.dom.sibling(t.target,"div").classList.remove("above"),(0,r.set)(this,"checked",null),this.$row.style.zIndex=null}}}})) -e.default=c})),define("consul-ui/components/maybe-in-element",["exports","ember-maybe-in-element/components/maybe-in-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/menu-panel/index",["exports","@ember/component","@ember/template-factory","@ember/service","@ember/runloop","@ember/object","block-slots"],(function(e,t,n,l,r,i,o){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=c})),define("consul-ui/components/maybe-in-element",["exports","ember-maybe-in-element/components/maybe-in-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/components/menu-panel/index",["exports","@ember/component","@ember/template-factory","@ember/service","@ember/runloop","@ember/object","block-slots"],(function(e,t,n,l,r,i,o){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const a=(0,n.createTemplateFactory)({id:"AUkkhvKM",block:'[[[1,"\\n"],[18,3,null],[1,"\\n"],[44,[[28,[37,2],null,[["change"],[[28,[37,3],[[30,0],"change"],null]]]]],[[[11,0],[16,0,[28,[37,4],[[28,[37,5],["menu-panel"],null],[28,[37,5],["menu-panel-deprecated"],null],[28,[37,5],[[33,6]],null],[28,[37,5],[[33,7],"confirmation"],null]],null]],[4,[38,8],[[28,[37,3],[[30,0],"connect"],null]],null],[12],[1,"\\n "],[8,[39,9],null,[["@name"],["controls"]],[["default"],[[[[1,"\\n "],[18,3,[[30,1]]],[1,"\\n "]],[]]]]],[1,"\\n"],[6,[39,9],null,[["name"],["header"]],[["default","else"],[[[[1," "],[10,0],[12],[1,"\\n "],[18,3,[[30,1]]],[1,"\\n "],[13],[1,"\\n"]],[]],[[],[]]]]],[1," "],[11,"ul"],[24,"role","menu"],[17,2],[12],[1,"\\n "],[8,[39,9],null,[["@name"],["menu"]],[["default"],[[[[1,"\\n "],[18,3,[[30,1]]],[1,"\\n "]],[]]]]],[1,"\\n "],[13],[1,"\\n"],[13],[1,"\\n"]],[1]]]],["api","&attrs","&default"],false,["yield","let","hash","action","class-map","array","position","isConfirmation","did-insert","yield-slot"]]',moduleName:"consul-ui/components/menu-panel/index.hbs",isStrictMode:!1}) var u=(0,t.setComponentTemplate)(a,t.default.extend(o.default,{tagName:"",dom:(0,l.inject)("dom"),isConfirmation:!1,actions:{connect:function(e){(0,r.next)((()=>{if(!this.isDestroyed){const t=this.dom.element('li:only-child > [role="menu"]:first-child',e);(0,i.set)(this,"isConfirmation",void 0!==t)}}))},change:function(e){const t=e.target.getAttribute("id"),n=this.dom.element(`[for='${t}']`),l=this.dom.element("[role=menu]",n.parentElement),r=this.dom.closest(".menu-panel",l) if(e.target.checked){l.style.display="block" const e=l.offsetHeight+2 r.style.maxHeight=r.style.minHeight=`${e}px`}else l.style.display=null,r.style.maxHeight=null,r.style.minHeight="0"}}})) -e.default=u})) -define("consul-ui/components/menu/action/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=u})),define("consul-ui/components/menu/action/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"JOnhu+Ze",block:'[[[1,"\\n"],[8,[39,0],[[24,"role","menuitem"],[17,1],[4,[38,1],["click",[52,[30,2],[30,4,["close"]],[28,[37,3],null,null]]],null]],[["@href","@external"],[[30,2],[30,3]]],[["default"],[[[[1,"\\n "],[18,5,null],[1,"\\n"]],[]]]]],[1,"\\n"]],["&attrs","@href","@external","@disclosure","&default"],false,["action","on","if","noop","yield"]]',moduleName:"consul-ui/components/menu/action/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/menu/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -1368,10 +1375,13 @@ var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/more-popover-menu/index",["exports","@ember/component","@ember/template-factory"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const l=(0,n.createTemplateFactory)({id:"aLK3TSIx",block:'[[[1,"\\n"],[11,0],[24,0,"more-popover-menu"],[17,1],[12],[1,"\\n "],[8,[39,0],null,[["@expanded","@onchange","@keyboardAccess"],[[99,1,["@expanded"]],[28,[37,2],[[30,0],[33,3]],null],false]],[["default"],[[[[1,"\\n "],[8,[39,4],null,[["@name"],["trigger"]],[["default"],[[[[1,"\\n More\\n "]],[]]]]],[1,"\\n "],[8,[39,4],null,[["@name"],["menu"]],[["default"],[[[[1,"\\n "],[18,4,[[30,2,["MenuItem"]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[2,3]]]]],[1,"\\n"],[13],[1,"\\n"]],["&attrs","components","api","&default"],false,["popover-menu","expanded","action","onchange","block-slot","yield"]]',moduleName:"consul-ui/components/more-popover-menu/index.hbs",isStrictMode:!1}) var r=(0,t.setComponentTemplate)(l,t.default.extend({tagName:""})) -e.default=r})),define("consul-ui/components/nav-selector/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/object","@glimmer/tracking"],(function(e,t,n,l,r,i){var o,a +e.default=r})),define("consul-ui/components/nav-selector/generic",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +const r=(0,n.createTemplateFactory)({id:"J8OHquCr",block:'[[[1,"\\n"],[18,1,null]],["&default"],false,["yield"]]',moduleName:"consul-ui/components/nav-selector/generic.hbs",isStrictMode:!1}) +var i=(0,t.setComponentTemplate)(r,(0,l.default)()) +e.default=i})),define("consul-ui/components/nav-selector/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@ember/object","@glimmer/tracking"],(function(e,t,n,l,r,i){var o,a function u(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -const s=(0,n.createTemplateFactory)({id:"gV2Cd+sK",block:'[[[1,"\\n"],[44,[[30,1]],[[[1," "],[8,[30,2,["Item"]],[[24,0,"consul-side-nav__selector"]],null,[["default"],[[[[1,"\\n "],[8,[39,1],[[24,0,"hds-side-nav__dropdown"],[17,3]],[["@listPosition","@width","@isInline"],["bottom-left","15.5rem",true]],[["default"],[[[[1,"\\n "],[8,[30,4,["ToggleButton"]],[[24,0,"consul-side-nav__selector-toggle"],[16,"disabled",[28,[37,2],[[30,5],true],null]]],[["@icon","@text"],[[30,6],[28,[37,3],[[30,7],[30,8]],null]]],null],[1,"\\n "],[8,[30,4,["Header"]],null,[["@hasDivider"],[true]],[["default"],[[[[1,"\\n"],[41,[30,9],[[[1," "],[10,0],[14,0,"consul-side-nav__selector-description"],[12],[1,"\\n "],[8,[39,5],null,[["@size","@color"],["100","faint"]],[["default"],[[[[1,[30,9]]],[]]]]],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "],[8,[39,6],[[16,"placeholder",[30,10]],[16,"aria-label",[30,10]],[4,[38,7],["input",[30,0,["onSearchInput"]]],null]],[["@type","@value"],["search",[30,0,["search"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n"],[41,[28,[37,2],[[30,0,["filteredItems","length"]],0],null],[[[1," "],[8,[30,4,["Description"]],null,[["@text"],["No results"]],null],[1,"\\n"]],[]],[[[42,[28,[37,9],[[28,[37,9],[[30,0,["filteredItems"]]],null]],null],null,[[[1," "],[18,14,[[30,4],[30,11]]],[1,"\\n"]],[11]],null]],[]]],[41,[30,12],[[[1," "],[8,[30,4,["Footer"]],null,[["@hasDivider"],[true]],[["default"],[[[[1,"\\n "],[8,[39,11],null,[["@href","@isHrefExternal","@text","@iconPosition","@icon","@color"],[[30,12],false,[30,13],"trailing","arrow-right","secondary"]],null],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[4]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[2]]]],["@list","SNL","&attrs","DD","@disabled","@icon","@item","@key","@description","@placeholder","item","@footerLink","@footerLinkText","&default"],false,["let","hds/dropdown","eq","get","if","hds/text/body","hds/form/text-input/base","on","each","-track-array","yield","hds/link/standalone"]]',moduleName:"consul-ui/components/nav-selector/index.hbs",isStrictMode:!1}) +const s=(0,n.createTemplateFactory)({id:"JCYQiQJP",block:'[[[1,"\\n"],[44,[[30,1]],[[[1," "],[8,[30,2,["Item"]],[[24,0,"consul-side-nav__selector"]],null,[["default"],[[[[1,"\\n "],[8,[39,1],[[24,0,"hds-side-nav__dropdown"],[17,3]],[["@listPosition","@width","@isInline"],["bottom-left","15.5rem",true]],[["default"],[[[[1,"\\n "],[8,[30,4,["ToggleButton"]],[[24,0,"consul-side-nav__selector-toggle"],[16,"disabled",[28,[37,2],[[30,5],true],null]]],[["@icon","@text"],[[30,6],[28,[37,3],[[30,7],[30,8]],null]]],null],[1,"\\n "],[8,[30,4,["Header"]],null,[["@hasDivider"],[true]],[["default"],[[[[1,"\\n "],[18,14,[[28,[37,5],null,[["Data"],[[50,"nav-selector/generic",0,null,null]]]]]],[1,"\\n"],[41,[30,9],[[[1," "],[10,0],[14,0,"consul-side-nav__selector-description"],[12],[1,"\\n "],[8,[39,8],null,[["@size","@color"],["100","faint"]],[["default"],[[[[1,[30,9]]],[]]]]],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "],[8,[39,9],[[16,"placeholder",[30,10]],[16,"aria-label",[30,10]],[4,[38,10],["input",[30,0,["onSearchInput"]]],null]],[["@type","@value"],["search",[30,0,["search"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n"],[41,[28,[37,2],[[30,0,["filteredItems","length"]],0],null],[[[1," "],[8,[30,4,["Description"]],null,[["@text"],["No results"]],null],[1,"\\n"]],[]],[[[42,[28,[37,12],[[28,[37,12],[[30,0,["filteredItems"]]],null]],null],null,[[[1," "],[18,14,[[28,[37,5],null,[["Dropdown","item"],[[30,4],[30,11]]]]]],[1,"\\n"]],[11]],null]],[]]],[41,[30,12],[[[1," "],[8,[30,4,["Footer"]],null,[["@hasDivider"],[true]],[["default"],[[[[1,"\\n "],[8,[39,13],null,[["@href","@isHrefExternal","@text","@iconPosition","@icon","@color"],[[30,12],false,[30,13],"trailing","arrow-right","secondary"]],null],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[4]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[2]]]],["@list","SNL","&attrs","DD","@disabled","@icon","@item","@key","@description","@placeholder","item","@footerLink","@footerLinkText","&default"],false,["let","hds/dropdown","eq","get","yield","hash","component","if","hds/text/body","hds/form/text-input/base","on","each","-track-array","hds/link/standalone"]]',moduleName:"consul-ui/components/nav-selector/index.hbs",isStrictMode:!1}) let c=(o=class extends l.default{constructor(){var e,t,n,l super(...arguments),e=this,t="search",l=this,(n=a)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}get filteredItems(){const e=this.search.toLowerCase() return e?this.args.items.filter((t=>t[this.args.key].toLowerCase().includes(e))):this.args.items}onSearchInput(e){this.search=e.target.value}},a=u(o.prototype,"search",[i.tracked],{configurable:!0,enumerable:!0,writable:!0,initializer:function(){return""}}),u(o.prototype,"onSearchInput",[r.action],Object.getOwnPropertyDescriptor(o.prototype,"onSearchInput"),o.prototype),o) @@ -1495,8 +1505,8 @@ return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumera const s=(0,n.createTemplateFactory)({id:"SC5oIKM/",block:'[[[1,"\\n"],[44,[[30,1,["MenuItem"]]],[[[1," "],[8,[30,2],[[16,0,[52,[30,0,["selected"]],"is-active"]],[17,3],[4,[38,3],[[30,0,["connect"]]],null],[4,[38,3],[[28,[37,4],[[30,0],"selected",[30,5]],null]],null],[4,[38,5],[[28,[37,4],[[30,0],"selected",[30,5]],null]],null],[4,[38,6],[[30,0,["disconnect"]]],null]],[["@onclick","@selected"],[[28,[37,2],[[30,0],[30,4],[30,0]],null],[30,0,["selected"]]]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["label"]],[["default"],[[[[1,"\\n "],[18,6,null],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[2]]]],["@components","MenuItem","&attrs","@onclick","@selected","&default"],false,["let","if","action","did-insert","set","did-update","will-destroy","block-slot","yield"]]',moduleName:"consul-ui/components/popover-select/option/index.hbs",isStrictMode:!1}) let c=(o=class extends l.default{constructor(){var e,t,n,l super(...arguments),e=this,t="selected",l=this,(n=a)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}connect(){this.args.select.addOption(this)}disconnect(){this.args.select.removeOption(this)}},a=u(o.prototype,"selected",[r.tracked],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),u(o.prototype,"connect",[i.action],Object.getOwnPropertyDescriptor(o.prototype,"connect"),o.prototype),u(o.prototype,"disconnect",[i.action],Object.getOwnPropertyDescriptor(o.prototype,"disconnect"),o.prototype),o) -e.default=c,(0,t.setComponentTemplate)(s,c)})),define("consul-ui/components/portal-target",["exports","ember-stargate/components/portal-target"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/portal",["exports","ember-stargate/components/portal"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-multiple-with-create",["exports","ember-power-select-with-create/components/power-select-multiple-with-create"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-multiple",["exports","ember-power-select/components/power-select-multiple"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/components/power-select-multiple/trigger",["exports","ember-power-select/components/power-select-multiple/trigger"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-with-create",["exports","ember-power-select-with-create/components/power-select-with-create"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-with-create/suggested-option",["exports","ember-power-select-with-create/components/power-select-with-create/suggested-option"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select",["exports","ember-power-select/components/power-select"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/before-options",["exports","ember-power-select/components/power-select/before-options"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/no-matches-message",["exports","ember-power-select/components/power-select/no-matches-message"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/options",["exports","ember-power-select/components/power-select/options"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/placeholder",["exports","ember-power-select/components/power-select/placeholder"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/power-select-group",["exports","ember-power-select/components/power-select/power-select-group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/search-message",["exports","ember-power-select/components/power-select/search-message"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/trigger",["exports","ember-power-select/components/power-select/trigger"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/progress/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=c,(0,t.setComponentTemplate)(s,c)})),define("consul-ui/components/portal-target",["exports","ember-stargate/components/portal-target"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/portal",["exports","ember-stargate/components/portal"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/components/power-select-multiple-with-create",["exports","ember-power-select-with-create/components/power-select-multiple-with-create"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-multiple",["exports","ember-power-select/components/power-select-multiple"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-multiple/trigger",["exports","ember-power-select/components/power-select-multiple/trigger"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-with-create",["exports","ember-power-select-with-create/components/power-select-with-create"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select-with-create/suggested-option",["exports","ember-power-select-with-create/components/power-select-with-create/suggested-option"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select",["exports","ember-power-select/components/power-select"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/before-options",["exports","ember-power-select/components/power-select/before-options"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/no-matches-message",["exports","ember-power-select/components/power-select/no-matches-message"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/options",["exports","ember-power-select/components/power-select/options"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/placeholder",["exports","ember-power-select/components/power-select/placeholder"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/power-select-group",["exports","ember-power-select/components/power-select/power-select-group"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/search-message",["exports","ember-power-select/components/power-select/search-message"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/power-select/trigger",["exports","ember-power-select/components/power-select/trigger"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/components/progress/index",["exports","@ember/component","@ember/template-factory","@ember/component/template-only"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const r=(0,n.createTemplateFactory)({id:"v8Ti52Dh",block:'[[[1,"\\n"],[11,0],[24,0,"progress indeterminate"],[24,"role","progressbar"],[17,1],[12],[13],[1,"\\n"]],["&attrs"],false,[]]',moduleName:"consul-ui/components/progress/index.hbs",isStrictMode:!1}) var i=(0,t.setComponentTemplate)(r,(0,l.default)()) e.default=i})),define("consul-ui/components/providers/dimension/index",["exports","@ember/component","@ember/template-factory","@glimmer/component","@glimmer/tracking","@ember/object","ember-ref-bucket","@ember/template"],(function(e,t,n,l,r,i,o,a){var u,s,c,d @@ -1572,7 +1582,8 @@ var o=(0,t.setComponentTemplate)(i,t.default.extend({chart:(0,l.inject)("state") void 0!==this.machine&&this.machine.stop(),void 0!==this.initial&&(this.src.initial=this.initial),this.machine=this.chart.interpret(this.src,{onTransition:e=>{const t=new CustomEvent("transition",{detail:e}) this.ontransition(t),t.defaultPrevented||e.actions.forEach((t=>{"function"==typeof this._actions[t.type]&&this._actions[t.type](t.type,e.context,e.event)})),(0,r.set)(this,"state",e)},onGuard:function(t){for(var n=arguments.length,l=new Array(n>1?n-1:0),r=1;ro!==this.router.currentRouteName||void 0!==t.nspace?a.transitionTo(...(0,i.default)(this.router.currentRoute,t,n)):e))}),e.type,(function(e,t){return e}),{})}},c=m(s.prototype,"router",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),d=m(s.prototype,"store",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),p=m(s.prototype,"feedback",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),m(s.prototype,"reauthorize",[r.action],Object.getOwnPropertyDescriptor(s.prototype,"reauthorize"),s.prototype),s) e.default=h})),define("consul-ui/controllers/dc/acls/policies/create",["exports","consul-ui/controllers/dc/acls/policies/edit"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -class n extends t.default{}e.default=n})),define("consul-ui/controllers/dc/acls/policies/edit",["exports","@ember/service","@ember/controller"],(function(e,t,n){var l,r,i +class n extends t.default{}e.default=n})) +define("consul-ui/controllers/dc/acls/policies/edit",["exports","@ember/service","@ember/controller"],(function(e,t,n){var l,r,i Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let o=(l=(0,t.inject)("form"),r=class extends n.default{constructor(){var e,t,n,l super(...arguments),e=this,t="builder",l=this,(n=i)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}init(){super.init(...arguments),this.form=this.builder.form("policy")}setProperties(e){super.setProperties(Object.keys(e).reduce(((e,t,n)=>{if("item"===t)e[t]=this.form.setData(e[t]).getData() return e}),e))}},a=r.prototype,u="builder",s=[l],c={configurable:!0,enumerable:!0,writable:!0,initializer:null},p={},Object.keys(c).forEach((function(e){p[e]=c[e]})),p.enumerable=!!p.enumerable,p.configurable=!!p.configurable,("value"in p||p.initializer)&&(p.writable=!0),p=s.slice().reverse().reduce((function(e,t){return t(a,u,e)||e}),p),d&&void 0!==p.initializer&&(p.value=p.initializer?p.initializer.call(d):void 0,p.initializer=void 0),void 0===p.initializer&&(Object.defineProperty(a,u,p),p=null),i=p,r) var a,u,s,c,d,p e.default=o})),define("consul-ui/controllers/dc/acls/roles/create",["exports","consul-ui/controllers/dc/acls/roles/edit"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -class n extends t.default{}e.default=n})) -define("consul-ui/controllers/dc/acls/roles/edit",["exports","@ember/service","@ember/controller"],(function(e,t,n){var l,r,i +class n extends t.default{}e.default=n})),define("consul-ui/controllers/dc/acls/roles/edit",["exports","@ember/service","@ember/controller"],(function(e,t,n){var l,r,i Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let o=(l=(0,t.inject)("form"),r=class extends n.default{constructor(){var e,t,n,l super(...arguments),e=this,t="builder",l=this,(n=i)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}init(){super.init(...arguments),this.form=this.builder.form("role")}setProperties(e){super.setProperties(Object.keys(e).reduce(((e,t,n)=>{if("item"===t)e[t]=this.form.setData(e[t]).getData() @@ -1840,20 +1850,20 @@ const l=(0,n.default)()})),define("consul-ui/forms/kv",["exports","consul-ui/val return i(n,{}).setValidators(r)} const l=(0,n.default)()})),define("consul-ui/forms/policy",["exports","consul-ui/validations/policy","consul-ui/utils/form/builder"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"policy",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.default,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:l return i(n,{Datacenters:{type:"array"}}).setValidators(r)} -const l=(0,n.default)()})),define("consul-ui/forms/role",["exports","consul-ui/validations/role","consul-ui/utils/form/builder"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"role",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.default,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:l +const l=(0,n.default)()})) +define("consul-ui/forms/role",["exports","consul-ui/validations/role","consul-ui/utils/form/builder"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"role",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.default,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:l return i(n,{}).setValidators(r).add(e.form("policy"))} const l=(0,n.default)()})),define("consul-ui/forms/token",["exports","consul-ui/validations/token","consul-ui/utils/form/builder"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.default,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:l return i(n,{}).setValidators(r).add(e.form("policy")).add(e.form("role"))} -const l=(0,n.default)()})) -define("consul-ui/helpers/-element",["exports","ember-element-helper/helpers/-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/abs",["exports","ember-math-helpers/helpers/abs"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"abs",{enumerable:!0,get:function(){return t.abs}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/acos",["exports","ember-math-helpers/helpers/acos"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"acos",{enumerable:!0,get:function(){return t.acos}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/acosh",["exports","ember-math-helpers/helpers/acosh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"acosh",{enumerable:!0,get:function(){return t.acosh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/add",["exports","ember-math-helpers/helpers/add"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"add",{enumerable:!0,get:function(){return t.add}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/adopt-styles",["exports","@ember/component/helper","@ember/debug","@lit/reactive-element"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +const l=(0,n.default)()})),define("consul-ui/helpers/-element",["exports","ember-element-helper/helpers/-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/abs",["exports","ember-math-helpers/helpers/abs"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"abs",{enumerable:!0,get:function(){return t.abs}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/acos",["exports","ember-math-helpers/helpers/acos"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"acos",{enumerable:!0,get:function(){return t.acos}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/acosh",["exports","ember-math-helpers/helpers/acosh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"acosh",{enumerable:!0,get:function(){return t.acosh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/add",["exports","ember-math-helpers/helpers/add"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"add",{enumerable:!0,get:function(){return t.add}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/adopt-styles",["exports","@ember/component/helper","@ember/debug","@lit/reactive-element"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 class r extends t.default{compute(e,t){let[n,r]=e Array.isArray(r)||(r=[r]),(0,l.adoptStyles)(n,r)}}e.default=r})),define("consul-ui/helpers/and",["exports","ember-truth-helpers/helpers/and"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"and",{enumerable:!0,get:function(){return t.and}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/app-version",["exports","@ember/component/helper","consul-ui/config/environment","ember-cli-app-version/utils/regexp"],(function(e,t,n,l){function r(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{} const r=n.default.APP.version let i=t.versionOnly||t.hideSha,o=t.shaOnly||t.hideVersion,a=null return i&&(t.showExtended&&(a=r.match(l.versionExtendedRegExp)),a||(a=r.match(l.versionRegExp))),o&&(a=r.match(l.shaRegExp)),a?a[0]:r}Object.defineProperty(e,"__esModule",{value:!0}),e.appVersion=r,e.default=void 0 var i=(0,t.helper)(r) -e.default=i})),define("consul-ui/helpers/append",["exports","ember-composable-helpers/helpers/append"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"append",{enumerable:!0,get:function(){return t.append}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-concat",["exports","ember-array-fns/helpers/array-concat"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayConcat",{enumerable:!0,get:function(){return t.arrayConcat}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-every",["exports","ember-array-fns/helpers/array-every"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayEvery",{enumerable:!0,get:function(){return t.arrayEvery}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-filter",["exports","ember-array-fns/helpers/array-filter"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayFilter",{enumerable:!0,get:function(){return t.arrayFilter}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-find-index",["exports","ember-array-fns/helpers/array-find-index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayFindIndex",{enumerable:!0,get:function(){return t.arrayFindIndex}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-find",["exports","ember-array-fns/helpers/array-find"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayFind",{enumerable:!0,get:function(){return t.arrayFind}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-includes",["exports","ember-array-fns/helpers/array-includes"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIncludes",{enumerable:!0,get:function(){return t.arrayIncludes}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-index-of",["exports","ember-array-fns/helpers/array-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIndexOf",{enumerable:!0,get:function(){return t.arrayIndexOf}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-is-array",["exports","ember-array-fns/helpers/array-is-array"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIsArray",{enumerable:!0,get:function(){return t.arrayIsArray}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-is-first-element",["exports","ember-array-fns/helpers/array-is-first-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIsFirstElement",{enumerable:!0,get:function(){return t.arrayIsFirstElement}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-is-last-element",["exports","ember-array-fns/helpers/array-is-last-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIsLastElement",{enumerable:!0,get:function(){return t.arrayIsLastElement}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-join",["exports","ember-array-fns/helpers/array-join"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayJoin",{enumerable:!0,get:function(){return t.arrayJoin}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-last-index-of",["exports","ember-array-fns/helpers/array-last-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayLastIndexOf",{enumerable:!0,get:function(){return t.arrayLastIndexOf}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-map",["exports","ember-array-fns/helpers/array-map"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayMap",{enumerable:!0,get:function(){return t.arrayMap}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-reduce",["exports","ember-array-fns/helpers/array-reduce"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayReduce",{enumerable:!0,get:function(){return t.arrayReduce}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-reverse",["exports","ember-array-fns/helpers/array-reverse"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayReverse",{enumerable:!0,get:function(){return t.arrayReverse}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-slice",["exports","ember-array-fns/helpers/array-slice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySlice",{enumerable:!0,get:function(){return t.arraySlice}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-some",["exports","ember-array-fns/helpers/array-some"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySome",{enumerable:!0,get:function(){return t.arraySome}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-sort",["exports","ember-array-fns/helpers/array-sort"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySort",{enumerable:!0,get:function(){return t.arraySort}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-splice",["exports","ember-array-fns/helpers/array-splice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySplice",{enumerable:!0,get:function(){return t.arraySplice}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/asin",["exports","ember-math-helpers/helpers/asin"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"asin",{enumerable:!0,get:function(){return t.asin}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/asinh",["exports","ember-math-helpers/helpers/asinh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"asinh",{enumerable:!0,get:function(){return t.asinh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/helpers/assign",["exports","ember-assign-helper/helpers/assign"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"assign",{enumerable:!0,get:function(){return t.assign}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atan",["exports","ember-math-helpers/helpers/atan"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"atan",{enumerable:!0,get:function(){return t.atan}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atan2",["exports","ember-math-helpers/helpers/atan2"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"atan2",{enumerable:!0,get:function(){return t.atan2}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atanh",["exports","ember-math-helpers/helpers/atanh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"atanh",{enumerable:!0,get:function(){return t.atanh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atob",["exports","@ember/component/helper","consul-ui/utils/atob"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=i})),define("consul-ui/helpers/append",["exports","ember-composable-helpers/helpers/append"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"append",{enumerable:!0,get:function(){return t.append}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-concat",["exports","ember-array-fns/helpers/array-concat"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayConcat",{enumerable:!0,get:function(){return t.arrayConcat}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-every",["exports","ember-array-fns/helpers/array-every"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayEvery",{enumerable:!0,get:function(){return t.arrayEvery}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-filter",["exports","ember-array-fns/helpers/array-filter"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayFilter",{enumerable:!0,get:function(){return t.arrayFilter}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-find-index",["exports","ember-array-fns/helpers/array-find-index"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayFindIndex",{enumerable:!0,get:function(){return t.arrayFindIndex}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-find",["exports","ember-array-fns/helpers/array-find"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayFind",{enumerable:!0,get:function(){return t.arrayFind}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-includes",["exports","ember-array-fns/helpers/array-includes"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIncludes",{enumerable:!0,get:function(){return t.arrayIncludes}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-index-of",["exports","ember-array-fns/helpers/array-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIndexOf",{enumerable:!0,get:function(){return t.arrayIndexOf}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-is-array",["exports","ember-array-fns/helpers/array-is-array"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIsArray",{enumerable:!0,get:function(){return t.arrayIsArray}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-is-first-element",["exports","ember-array-fns/helpers/array-is-first-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIsFirstElement",{enumerable:!0,get:function(){return t.arrayIsFirstElement}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-is-last-element",["exports","ember-array-fns/helpers/array-is-last-element"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayIsLastElement",{enumerable:!0,get:function(){return t.arrayIsLastElement}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-join",["exports","ember-array-fns/helpers/array-join"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayJoin",{enumerable:!0,get:function(){return t.arrayJoin}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-last-index-of",["exports","ember-array-fns/helpers/array-last-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayLastIndexOf",{enumerable:!0,get:function(){return t.arrayLastIndexOf}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-map",["exports","ember-array-fns/helpers/array-map"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayMap",{enumerable:!0,get:function(){return t.arrayMap}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-reduce",["exports","ember-array-fns/helpers/array-reduce"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayReduce",{enumerable:!0,get:function(){return t.arrayReduce}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-reverse",["exports","ember-array-fns/helpers/array-reverse"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arrayReverse",{enumerable:!0,get:function(){return t.arrayReverse}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-slice",["exports","ember-array-fns/helpers/array-slice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySlice",{enumerable:!0,get:function(){return t.arraySlice}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-some",["exports","ember-array-fns/helpers/array-some"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySome",{enumerable:!0,get:function(){return t.arraySome}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-sort",["exports","ember-array-fns/helpers/array-sort"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySort",{enumerable:!0,get:function(){return t.arraySort}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/array-splice",["exports","ember-array-fns/helpers/array-splice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"arraySplice",{enumerable:!0,get:function(){return t.arraySplice}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/helpers/asin",["exports","ember-math-helpers/helpers/asin"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"asin",{enumerable:!0,get:function(){return t.asin}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/asinh",["exports","ember-math-helpers/helpers/asinh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"asinh",{enumerable:!0,get:function(){return t.asinh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/assign",["exports","ember-assign-helper/helpers/assign"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"assign",{enumerable:!0,get:function(){return t.assign}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atan",["exports","ember-math-helpers/helpers/atan"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"atan",{enumerable:!0,get:function(){return t.atan}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atan2",["exports","ember-math-helpers/helpers/atan2"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"atan2",{enumerable:!0,get:function(){return t.atan2}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atanh",["exports","ember-math-helpers/helpers/atanh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"atanh",{enumerable:!0,get:function(){return t.atanh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/atob",["exports","@ember/component/helper","consul-ui/utils/atob"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var l=(0,t.helper)((function(e){let[t=""]=e return(0,n.default)(t)})) e.default=l})),define("consul-ui/helpers/block-params",["exports","block-slots/helpers/block-params"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/cached-model",["exports","@ember/component/helper","@ember/application"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -1867,10 +1877,10 @@ class o{}class a extends t.default{compute(e,t){let[l,r]=e if(l.length>0){const e=(0,n.get)(l,"firstObject")._internalModel.modelName return new(0,i[e])(l)}return new o}}e.default=a})),define("consul-ui/helpers/compact",["exports","ember-composable-helpers/helpers/compact"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/compute",["exports","ember-composable-helpers/helpers/compute"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"compute",{enumerable:!0,get:function(){return t.compute}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/contains",["exports","ember-composable-helpers/helpers/contains"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"contains",{enumerable:!0,get:function(){return t.contains}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/cos",["exports","ember-math-helpers/helpers/cos"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"cos",{enumerable:!0,get:function(){return t.cos}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/cosh",["exports","ember-math-helpers/helpers/cosh"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"cosh",{enumerable:!0,get:function(){return t.cosh}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/css-map",["exports","@ember/component/helper","@lit/reactive-element"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var l=(0,t.helper)((e=>e.filter((e=>e instanceof n.CSSResult||e[e.length-1])).map((e=>e instanceof n.CSSResult?e:e[0])))) -e.default=l})),define("consul-ui/helpers/css",["exports","@ember/component/helper","@lit/reactive-element"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=l})) +define("consul-ui/helpers/css",["exports","@ember/component/helper","@lit/reactive-element"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 class l extends t.default{compute(e,t){let[l]=e -return(0,n.css)([l])}}e.default=l})),define("consul-ui/helpers/dec",["exports","ember-composable-helpers/helpers/dec"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"dec",{enumerable:!0,get:function(){return t.dec}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/helpers/did-insert",["exports","ember-render-helpers/helpers/did-insert"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/did-update",["exports","ember-render-helpers/helpers/did-update"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/div",["exports","ember-math-helpers/helpers/div"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"div",{enumerable:!0,get:function(){return t.div}})})),define("consul-ui/helpers/document-attrs",["exports","@ember/component/helper","@ember/service","@ember/debug","mnemonist/multi-map"],(function(e,t,n,l,r){var i,o,a +return(0,n.css)([l])}}e.default=l})),define("consul-ui/helpers/dec",["exports","ember-composable-helpers/helpers/dec"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"dec",{enumerable:!0,get:function(){return t.dec}}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/did-insert",["exports","ember-render-helpers/helpers/did-insert"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/did-update",["exports","ember-render-helpers/helpers/did-update"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/div",["exports","ember-math-helpers/helpers/div"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"div",{enumerable:!0,get:function(){return t.div}})})),define("consul-ui/helpers/document-attrs",["exports","@ember/component/helper","@ember/service","@ember/debug","mnemonist/multi-map"],(function(e,t,n,l,r){var i,o,a Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const u=new Map,s=new WeakMap let c=(i=(0,n.inject)("-document"),o=class extends t.default{constructor(){var e,t,n,l @@ -1917,8 +1927,8 @@ switch(!0){case 0!==a:return a+"d" case 0!==u:return u+"h" case 0!==s:return s+"m" default:return c+"s"}})) -e.default=n})),define("consul-ui/helpers/format-time",["exports","ember-intl/helpers/format-time"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/from-entries",["exports","ember-composable-helpers/helpers/from-entries"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"fromEntries",{enumerable:!0,get:function(){return t.fromEntries}})})) -define("consul-ui/helpers/fround",["exports","ember-math-helpers/helpers/fround"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"fround",{enumerable:!0,get:function(){return t.fround}})})),define("consul-ui/helpers/gcd",["exports","ember-math-helpers/helpers/gcd"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gcd",{enumerable:!0,get:function(){return t.gcd}})})),define("consul-ui/helpers/group-by",["exports","ember-composable-helpers/helpers/group-by"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/gt",["exports","ember-truth-helpers/helpers/gt"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gt",{enumerable:!0,get:function(){return t.gt}})})),define("consul-ui/helpers/gte",["exports","ember-truth-helpers/helpers/gte"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gte",{enumerable:!0,get:function(){return t.gte}})})),define("consul-ui/helpers/has-next",["exports","ember-composable-helpers/helpers/has-next"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"hasNext",{enumerable:!0,get:function(){return t.hasNext}})})),define("consul-ui/helpers/has-previous",["exports","ember-composable-helpers/helpers/has-previous"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"hasPrevious",{enumerable:!0,get:function(){return t.hasPrevious}})})),define("consul-ui/helpers/hds-link-to-models",["exports","@hashicorp/design-system-components/helpers/hds-link-to-models"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/hds-link-to-query",["exports","@hashicorp/design-system-components/helpers/hds-link-to-query"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/href-to",["exports","@ember/component/helper","@ember/service","@ember/object","@ember/application","consul-ui/utils/routing/transitionable","consul-ui/utils/routing/wildcard","consul-ui/router"],(function(e,t,n,l,r,i,o,a){var u,s,c +e.default=n})) +define("consul-ui/helpers/format-time",["exports","ember-intl/helpers/format-time"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/from-entries",["exports","ember-composable-helpers/helpers/from-entries"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"fromEntries",{enumerable:!0,get:function(){return t.fromEntries}})})),define("consul-ui/helpers/fround",["exports","ember-math-helpers/helpers/fround"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"fround",{enumerable:!0,get:function(){return t.fround}})})),define("consul-ui/helpers/gcd",["exports","ember-math-helpers/helpers/gcd"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gcd",{enumerable:!0,get:function(){return t.gcd}})})),define("consul-ui/helpers/group-by",["exports","ember-composable-helpers/helpers/group-by"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/gt",["exports","ember-truth-helpers/helpers/gt"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gt",{enumerable:!0,get:function(){return t.gt}})})),define("consul-ui/helpers/gte",["exports","ember-truth-helpers/helpers/gte"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gte",{enumerable:!0,get:function(){return t.gte}})})),define("consul-ui/helpers/has-next",["exports","ember-composable-helpers/helpers/has-next"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"hasNext",{enumerable:!0,get:function(){return t.hasNext}})})),define("consul-ui/helpers/has-previous",["exports","ember-composable-helpers/helpers/has-previous"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"hasPrevious",{enumerable:!0,get:function(){return t.hasPrevious}})})),define("consul-ui/helpers/hds-link-to-models",["exports","@hashicorp/design-system-components/helpers/hds-link-to-models"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/hds-link-to-query",["exports","@hashicorp/design-system-components/helpers/hds-link-to-query"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/href-to",["exports","@ember/component/helper","@ember/service","@ember/object","@ember/application","consul-ui/utils/routing/transitionable","consul-ui/utils/routing/wildcard","consul-ui/router"],(function(e,t,n,l,r,i,o,a){var u,s,c function d(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.hrefTo=e.default=void 0 const p=(0,o.default)(a.routes),f=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{} @@ -1946,11 +1956,11 @@ e.is=r class i extends t.default{compute(e,t){let[n,l]=e return r(this,[n,l],t)}}e.default=i})),define("consul-ui/helpers/join",["exports","ember-composable-helpers/helpers/join"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/json-stringify",["exports","@ember/component/helper"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.helper)((function(e,t){try{return JSON.stringify(...e)}catch(n){return e[0].map((t=>JSON.stringify(t,e[1],e[2])))}})) -e.default=n})),define("consul-ui/helpers/keys",["exports","ember-composable-helpers/helpers/keys"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"keys",{enumerable:!0,get:function(){return t.keys}})})),define("consul-ui/helpers/last",["exports","@ember/component/helper"],(function(e,t){function n(e,t){let[n=""]=e +e.default=n})),define("consul-ui/helpers/keys",["exports","ember-composable-helpers/helpers/keys"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"keys",{enumerable:!0,get:function(){return t.keys}})})) +define("consul-ui/helpers/last",["exports","@ember/component/helper"],(function(e,t){function n(e,t){let[n=""]=e if(!0==("string"==typeof n))return n.substr(-1)}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,e.last=n var l=(0,t.helper)(n) -e.default=l})),define("consul-ui/helpers/lcm",["exports","ember-math-helpers/helpers/lcm"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lcm",{enumerable:!0,get:function(){return t.lcm}})})) -define("consul-ui/helpers/left-trim",["exports","@ember/component/helper","consul-ui/utils/left-trim"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=l})),define("consul-ui/helpers/lcm",["exports","ember-math-helpers/helpers/lcm"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lcm",{enumerable:!0,get:function(){return t.lcm}})})),define("consul-ui/helpers/left-trim",["exports","@ember/component/helper","consul-ui/utils/left-trim"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var l=(0,t.helper)((function(e,t){let[l="",r=""]=e return(0,n.default)(l,r)})) e.default=l})),define("consul-ui/helpers/log-e",["exports","ember-math-helpers/helpers/log-e"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"logE",{enumerable:!0,get:function(){return t.logE}})})),define("consul-ui/helpers/log10",["exports","ember-math-helpers/helpers/log10"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"log10",{enumerable:!0,get:function(){return t.log10}})})),define("consul-ui/helpers/log1p",["exports","ember-math-helpers/helpers/log1p"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"log1p",{enumerable:!0,get:function(){return t.log1p}})})),define("consul-ui/helpers/log2",["exports","ember-math-helpers/helpers/log2"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"log2",{enumerable:!0,get:function(){return t.log2}})})),define("consul-ui/helpers/lowercase",["exports","ember-cli-string-helpers/helpers/lowercase"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lowercase",{enumerable:!0,get:function(){return t.lowercase}})})),define("consul-ui/helpers/lt",["exports","ember-truth-helpers/helpers/lt"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lt",{enumerable:!0,get:function(){return t.lt}})})),define("consul-ui/helpers/lte",["exports","ember-truth-helpers/helpers/lte"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lte",{enumerable:!0,get:function(){return t.lte}})})),define("consul-ui/helpers/map-by",["exports","ember-composable-helpers/helpers/map-by"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/map",["exports","ember-composable-helpers/helpers/map"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/max",["exports","ember-math-helpers/helpers/max"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"max",{enumerable:!0,get:function(){return t.max}})})),define("consul-ui/helpers/merge-checks",["exports","@ember/component/helper","consul-ui/utils/merge-checks"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -1960,14 +1970,14 @@ e.default=l})),define("consul-ui/helpers/min",["exports","ember-math-helpers/hel var l=(0,t.helper)((function(e){return new n.default(e[0])})) e.default=l})),define("consul-ui/helpers/mod",["exports","ember-math-helpers/helpers/mod"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"mod",{enumerable:!0,get:function(){return t.mod}})})),define("consul-ui/helpers/mult",["exports","ember-math-helpers/helpers/mult"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"mult",{enumerable:!0,get:function(){return t.mult}})})),define("consul-ui/helpers/next",["exports","ember-composable-helpers/helpers/next"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"next",{enumerable:!0,get:function(){return t.next}})})),define("consul-ui/helpers/noop",["exports","ember-composable-helpers/helpers/noop"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"noop",{enumerable:!0,get:function(){return t.noop}})})),define("consul-ui/helpers/not-eq",["exports","ember-truth-helpers/helpers/not-eq"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"notEqualHelper",{enumerable:!0,get:function(){return t.notEqualHelper}})})),define("consul-ui/helpers/not",["exports","ember-truth-helpers/helpers/not"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"not",{enumerable:!0,get:function(){return t.not}})})),define("consul-ui/helpers/object-at",["exports","ember-composable-helpers/helpers/object-at"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"objectAt",{enumerable:!0,get:function(){return t.objectAt}})})),define("consul-ui/helpers/on-document",["exports","ember-on-helper/helpers/on-document"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/on-key",["exports","ember-keyboard/helpers/on-key.js"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/on-window",["exports","ember-on-helper/helpers/on-window"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/on",["exports","ember-on-helper/helpers/on"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/optional",["exports","ember-composable-helpers/helpers/optional"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"optional",{enumerable:!0,get:function(){return t.optional}})})),define("consul-ui/helpers/or",["exports","ember-truth-helpers/helpers/or"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"or",{enumerable:!0,get:function(){return t.or}})})),define("consul-ui/helpers/page-title",["exports","ember-page-title/helpers/page-title"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=t.default -e.default=n})),define("consul-ui/helpers/percentage-columns-layout",["exports","@ember/component/helper","ember-collection/layouts/percentage-columns"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})) +define("consul-ui/helpers/percentage-columns-layout",["exports","@ember/component/helper","ember-collection/layouts/percentage-columns"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var l=(0,t.helper)((function(e){return new n.default(e[0],e[1],e[2])})) e.default=l})),define("consul-ui/helpers/percentage-of",["exports","@ember/component/helper"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.helper)((function(e,t){let[n,l]=e const r=n/l*100 return isNaN(r)?0:r.toFixed(2)})) -e.default=n})) -define("consul-ui/helpers/perform",["exports","ember-concurrency/helpers/perform"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/pick",["exports","ember-composable-helpers/helpers/pick"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"pick",{enumerable:!0,get:function(){return t.pick}})})),define("consul-ui/helpers/pipe-action",["exports","ember-composable-helpers/helpers/pipe-action"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/pipe",["exports","ember-composable-helpers/helpers/pipe"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"pipe",{enumerable:!0,get:function(){return t.pipe}})})),define("consul-ui/helpers/pluralize",["exports","ember-inflector/lib/helpers/pluralize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})),define("consul-ui/helpers/perform",["exports","ember-concurrency/helpers/perform"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/pick",["exports","ember-composable-helpers/helpers/pick"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"pick",{enumerable:!0,get:function(){return t.pick}})})),define("consul-ui/helpers/pipe-action",["exports","ember-composable-helpers/helpers/pipe-action"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/pipe",["exports","ember-composable-helpers/helpers/pipe"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"pipe",{enumerable:!0,get:function(){return t.pipe}})})),define("consul-ui/helpers/pluralize",["exports","ember-inflector/lib/helpers/pluralize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=t.default e.default=n})),define("consul-ui/helpers/policy/datacenters",["exports","@ember/component/helper","@ember/object"],(function(e,t,n){function l(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{} const l=(0,n.get)(e[0],"Datacenters") @@ -2030,7 +2040,8 @@ switch(!0){case e:return"allow" case!n&&!e:return"deny" case n&&l:return"not-defined" default:return"allow"}}})) -e.default=n})),define("consul-ui/helpers/service/external-source",["exports","@ember/component/helper","@ember/object"],(function(e,t,n){function l(e,t){let l=(0,n.get)(e[0],"ExternalSources.firstObject") +e.default=n})) +define("consul-ui/helpers/service/external-source",["exports","@ember/component/helper","@ember/object"],(function(e,t,n){function l(e,t){let l=(0,n.get)(e[0],"ExternalSources.firstObject") l||(l=(0,n.get)(e[0],"Meta.external-source")) const r=void 0===t.prefix?"":t.prefix if(l&&["consul-api-gateway","vault","kubernetes","terraform","nomad","consul","aws","lambda"].includes(l))return`${r}${l}`}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,e.serviceExternalSource=l @@ -2039,8 +2050,7 @@ e.default=r})),define("consul-ui/helpers/service/health-percentage",["exports"," var n=(0,t.helper)((function(e){let[t]=e const n=t.ChecksCritical+t.ChecksPassing+t.ChecksWarning return 0===n?"":{passing:Math.round(t.ChecksPassing/n*100),warning:Math.round(t.ChecksWarning/n*100),critical:Math.round(t.ChecksCritical/n*100)}})) -e.default=n})) -define("consul-ui/helpers/set",["exports","ember-set-helper/helpers/set"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/shuffle",["exports","ember-composable-helpers/helpers/shuffle"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"shuffle",{enumerable:!0,get:function(){return t.shuffle}})})),define("consul-ui/helpers/sign",["exports","ember-math-helpers/helpers/sign"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"sign",{enumerable:!0,get:function(){return t.sign}})})),define("consul-ui/helpers/sin",["exports","ember-math-helpers/helpers/sin"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"sin",{enumerable:!0,get:function(){return t.sin}})})),define("consul-ui/helpers/singularize",["exports","ember-inflector/lib/helpers/singularize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})),define("consul-ui/helpers/set",["exports","ember-set-helper/helpers/set"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/shuffle",["exports","ember-composable-helpers/helpers/shuffle"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"shuffle",{enumerable:!0,get:function(){return t.shuffle}})})),define("consul-ui/helpers/sign",["exports","ember-math-helpers/helpers/sign"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"sign",{enumerable:!0,get:function(){return t.sign}})})),define("consul-ui/helpers/sin",["exports","ember-math-helpers/helpers/sin"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"sin",{enumerable:!0,get:function(){return t.sin}})})),define("consul-ui/helpers/singularize",["exports","ember-inflector/lib/helpers/singularize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=t.default e.default=n})),define("consul-ui/helpers/slice",["exports","ember-composable-helpers/helpers/slice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/helpers/slugify",["exports","@ember/component/helper"],(function(e,t){function n(e,t){let[n=""]=e return n.replace(/ /g,"-").toLowerCase()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,e.slugify=n @@ -2070,8 +2080,8 @@ var a,u,s,c,d,p e.default=o})),define("consul-ui/helpers/string-char-at",["exports","ember-string-fns/helpers/string-char-at"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringCharAt",{enumerable:!0,get:function(){return t.stringCharAt}})})),define("consul-ui/helpers/string-char-code-at",["exports","ember-string-fns/helpers/string-char-code-at"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringCharCodeAt",{enumerable:!0,get:function(){return t.stringCharCodeAt}})})),define("consul-ui/helpers/string-code-point-at",["exports","ember-string-fns/helpers/string-code-point-at"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringCodePointAt",{enumerable:!0,get:function(){return t.stringCodePointAt}})})),define("consul-ui/helpers/string-concat",["exports","ember-string-fns/helpers/string-concat"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringConcat",{enumerable:!0,get:function(){return t.stringConcat}})})),define("consul-ui/helpers/string-ends-with",["exports","ember-string-fns/helpers/string-ends-with"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringEndsWith",{enumerable:!0,get:function(){return t.stringEndsWith}})})),define("consul-ui/helpers/string-equals",["exports","ember-string-fns/helpers/string-equals"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringEquals",{enumerable:!0,get:function(){return t.stringEquals}})})),define("consul-ui/helpers/string-from-char-code",["exports","ember-string-fns/helpers/string-from-char-code"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringFromCharCode",{enumerable:!0,get:function(){return t.stringFromCharCode}})})),define("consul-ui/helpers/string-from-code-point",["exports","ember-string-fns/helpers/string-from-code-point"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringFromCodePoint",{enumerable:!0,get:function(){return t.stringFromCodePoint}})})),define("consul-ui/helpers/string-html-safe",["exports","@ember/component/helper","@ember/string"],(function(e,t,n){function l(e){let[t=""]=e return(0,n.htmlSafe)(t)}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,e.stringHtmlSafe=l var r=(0,t.helper)(l) -e.default=r})),define("consul-ui/helpers/string-includes",["exports","ember-string-fns/helpers/string-includes"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringIncludes",{enumerable:!0,get:function(){return t.stringIncludes}})})),define("consul-ui/helpers/string-index-of",["exports","ember-string-fns/helpers/string-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringIndexOf",{enumerable:!0,get:function(){return t.stringIndexOf}})})),define("consul-ui/helpers/string-last-index-of",["exports","ember-string-fns/helpers/string-last-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringLastIndexOf",{enumerable:!0,get:function(){return t.stringLastIndexOf}})})),define("consul-ui/helpers/string-not-equals",["exports","ember-string-fns/helpers/string-not-equals"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringNotEquals",{enumerable:!0,get:function(){return t.stringNotEquals}})})),define("consul-ui/helpers/string-pad-end",["exports","ember-string-fns/helpers/string-pad-end"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringPadEnd",{enumerable:!0,get:function(){return t.stringPadEnd}})})),define("consul-ui/helpers/string-pad-start",["exports","ember-string-fns/helpers/string-pad-start"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringPadStart",{enumerable:!0,get:function(){return t.stringPadStart}})})),define("consul-ui/helpers/string-repeat",["exports","ember-string-fns/helpers/string-repeat"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringRepeat",{enumerable:!0,get:function(){return t.stringRepeat}})})),define("consul-ui/helpers/string-replace-all",["exports","ember-string-fns/helpers/string-replace-all"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringReplaceAll",{enumerable:!0,get:function(){return t.stringReplaceAll}})})) -define("consul-ui/helpers/string-replace",["exports","ember-string-fns/helpers/string-replace"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringReplace",{enumerable:!0,get:function(){return t.stringReplace}})})),define("consul-ui/helpers/string-slice",["exports","ember-string-fns/helpers/string-slice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringSlice",{enumerable:!0,get:function(){return t.stringSlice}})})),define("consul-ui/helpers/string-split",["exports","ember-string-fns/helpers/string-split"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringSplit",{enumerable:!0,get:function(){return t.stringSplit}})})),define("consul-ui/helpers/string-starts-with",["exports","ember-string-fns/helpers/string-starts-with"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringStartsWith",{enumerable:!0,get:function(){return t.stringStartsWith}})})),define("consul-ui/helpers/string-substring",["exports","ember-string-fns/helpers/string-substring"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringSubstring",{enumerable:!0,get:function(){return t.stringSubstring}})})),define("consul-ui/helpers/string-to-camel-case",["exports","ember-string-fns/helpers/string-to-camel-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToCamelCase",{enumerable:!0,get:function(){return t.stringToCamelCase}})})),define("consul-ui/helpers/string-to-kebab-case",["exports","ember-string-fns/helpers/string-to-kebab-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToKebabCase",{enumerable:!0,get:function(){return t.stringToKebabCase}})})),define("consul-ui/helpers/string-to-lower-case",["exports","ember-string-fns/helpers/string-to-lower-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToLowerCase",{enumerable:!0,get:function(){return t.stringToLowerCase}})})),define("consul-ui/helpers/string-to-pascal-case",["exports","ember-string-fns/helpers/string-to-pascal-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToPascalCase",{enumerable:!0,get:function(){return t.stringToPascalCase}})})),define("consul-ui/helpers/string-to-sentence-case",["exports","ember-string-fns/helpers/string-to-sentence-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToSentenceCase",{enumerable:!0,get:function(){return t.stringToSentenceCase}})})),define("consul-ui/helpers/string-to-snake-case",["exports","ember-string-fns/helpers/string-to-snake-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToSnakeCase",{enumerable:!0,get:function(){return t.stringToSnakeCase}})})),define("consul-ui/helpers/string-to-title-case",["exports","ember-string-fns/helpers/string-to-title-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToTitleCase",{enumerable:!0,get:function(){return t.stringToTitleCase}})})),define("consul-ui/helpers/string-to-upper-case",["exports","ember-string-fns/helpers/string-to-upper-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToUpperCase",{enumerable:!0,get:function(){return t.stringToUpperCase}})})),define("consul-ui/helpers/string-trim-end",["exports","ember-string-fns/helpers/string-trim-end"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringTrimEnd",{enumerable:!0,get:function(){return t.stringTrimEnd}})})),define("consul-ui/helpers/string-trim-start",["exports","ember-string-fns/helpers/string-trim-start"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringTrimStart",{enumerable:!0,get:function(){return t.stringTrimStart}})})),define("consul-ui/helpers/string-trim",["exports","ember-string-fns/helpers/string-trim"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringTrim",{enumerable:!0,get:function(){return t.stringTrim}})})),define("consul-ui/helpers/style-map",["exports","@ember/component/helper"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=r})),define("consul-ui/helpers/string-includes",["exports","ember-string-fns/helpers/string-includes"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringIncludes",{enumerable:!0,get:function(){return t.stringIncludes}})})),define("consul-ui/helpers/string-index-of",["exports","ember-string-fns/helpers/string-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringIndexOf",{enumerable:!0,get:function(){return t.stringIndexOf}})})),define("consul-ui/helpers/string-last-index-of",["exports","ember-string-fns/helpers/string-last-index-of"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringLastIndexOf",{enumerable:!0,get:function(){return t.stringLastIndexOf}})})),define("consul-ui/helpers/string-not-equals",["exports","ember-string-fns/helpers/string-not-equals"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringNotEquals",{enumerable:!0,get:function(){return t.stringNotEquals}})})),define("consul-ui/helpers/string-pad-end",["exports","ember-string-fns/helpers/string-pad-end"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringPadEnd",{enumerable:!0,get:function(){return t.stringPadEnd}})})),define("consul-ui/helpers/string-pad-start",["exports","ember-string-fns/helpers/string-pad-start"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringPadStart",{enumerable:!0,get:function(){return t.stringPadStart}})})) +define("consul-ui/helpers/string-repeat",["exports","ember-string-fns/helpers/string-repeat"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringRepeat",{enumerable:!0,get:function(){return t.stringRepeat}})})),define("consul-ui/helpers/string-replace-all",["exports","ember-string-fns/helpers/string-replace-all"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringReplaceAll",{enumerable:!0,get:function(){return t.stringReplaceAll}})})),define("consul-ui/helpers/string-replace",["exports","ember-string-fns/helpers/string-replace"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringReplace",{enumerable:!0,get:function(){return t.stringReplace}})})),define("consul-ui/helpers/string-slice",["exports","ember-string-fns/helpers/string-slice"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringSlice",{enumerable:!0,get:function(){return t.stringSlice}})})),define("consul-ui/helpers/string-split",["exports","ember-string-fns/helpers/string-split"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringSplit",{enumerable:!0,get:function(){return t.stringSplit}})})),define("consul-ui/helpers/string-starts-with",["exports","ember-string-fns/helpers/string-starts-with"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringStartsWith",{enumerable:!0,get:function(){return t.stringStartsWith}})})),define("consul-ui/helpers/string-substring",["exports","ember-string-fns/helpers/string-substring"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringSubstring",{enumerable:!0,get:function(){return t.stringSubstring}})})),define("consul-ui/helpers/string-to-camel-case",["exports","ember-string-fns/helpers/string-to-camel-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToCamelCase",{enumerable:!0,get:function(){return t.stringToCamelCase}})})),define("consul-ui/helpers/string-to-kebab-case",["exports","ember-string-fns/helpers/string-to-kebab-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToKebabCase",{enumerable:!0,get:function(){return t.stringToKebabCase}})})),define("consul-ui/helpers/string-to-lower-case",["exports","ember-string-fns/helpers/string-to-lower-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToLowerCase",{enumerable:!0,get:function(){return t.stringToLowerCase}})})),define("consul-ui/helpers/string-to-pascal-case",["exports","ember-string-fns/helpers/string-to-pascal-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToPascalCase",{enumerable:!0,get:function(){return t.stringToPascalCase}})})),define("consul-ui/helpers/string-to-sentence-case",["exports","ember-string-fns/helpers/string-to-sentence-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToSentenceCase",{enumerable:!0,get:function(){return t.stringToSentenceCase}})})),define("consul-ui/helpers/string-to-snake-case",["exports","ember-string-fns/helpers/string-to-snake-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToSnakeCase",{enumerable:!0,get:function(){return t.stringToSnakeCase}})})),define("consul-ui/helpers/string-to-title-case",["exports","ember-string-fns/helpers/string-to-title-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToTitleCase",{enumerable:!0,get:function(){return t.stringToTitleCase}})})),define("consul-ui/helpers/string-to-upper-case",["exports","ember-string-fns/helpers/string-to-upper-case"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringToUpperCase",{enumerable:!0,get:function(){return t.stringToUpperCase}})})),define("consul-ui/helpers/string-trim-end",["exports","ember-string-fns/helpers/string-trim-end"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringTrimEnd",{enumerable:!0,get:function(){return t.stringTrimEnd}})})),define("consul-ui/helpers/string-trim-start",["exports","ember-string-fns/helpers/string-trim-start"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringTrimStart",{enumerable:!0,get:function(){return t.stringTrimStart}})})),define("consul-ui/helpers/string-trim",["exports","ember-string-fns/helpers/string-trim"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"stringTrim",{enumerable:!0,get:function(){return t.stringTrim}})})),define("consul-ui/helpers/style-map",["exports","@ember/component/helper"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.helper)((function(e){const t=e.reduce(((e,t)=>{let[n,l,r=""]=t return null==l?e:`${e}${n}:${l.toString()}${r};`}),"") return t.length>0?t:void 0})) @@ -2096,11 +2106,11 @@ Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let o=(l=(0,n.inject)("temporal"),r=class extends t.default{constructor(){var e,t,n,l super(...arguments),e=this,t="temporal",l=this,(n=i)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}compute(e,t){return this.temporal.within(e,t)}},a=r.prototype,u="temporal",s=[l],c={configurable:!0,enumerable:!0,writable:!0,initializer:null},p={},Object.keys(c).forEach((function(e){p[e]=c[e]})),p.enumerable=!!p.enumerable,p.configurable=!!p.configurable,("value"in p||p.initializer)&&(p.writable=!0),p=s.slice().reverse().reduce((function(e,t){return t(a,u,e)||e}),p),d&&void 0!==p.initializer&&(p.value=p.initializer?p.initializer.call(d):void 0,p.initializer=void 0),void 0===p.initializer&&(Object.defineProperty(a,u,p),p=null),i=p,r) var a,u,s,c,d,p -e.default=o})),define("consul-ui/helpers/test",["exports","consul-ui/helpers/can","consul-ui/helpers/is"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=o})) +define("consul-ui/helpers/test",["exports","consul-ui/helpers/can","consul-ui/helpers/is"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 class l extends t.default{compute(e,t){let[l,r]=e switch(!0){case l.startsWith("can "):return super.compute([l.substr(4),r],t) -case l.startsWith("is "):return(0,n.is)(this,[l.substr(3),r],t)}throw new Error(`${l} is not supported by the 'test' helper.`)}}e.default=l})),define("consul-ui/helpers/titleize",["exports","ember-cli-string-helpers/helpers/titleize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"titleize",{enumerable:!0,get:function(){return t.titleize}})})) -define("consul-ui/helpers/to-hash",["exports","@ember/component/helper","@ember/object"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +case l.startsWith("is "):return(0,n.is)(this,[l.substr(3),r],t)}throw new Error(`${l} is not supported by the 'test' helper.`)}}e.default=l})),define("consul-ui/helpers/titleize",["exports","ember-cli-string-helpers/helpers/titleize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"titleize",{enumerable:!0,get:function(){return t.titleize}})})),define("consul-ui/helpers/to-hash",["exports","@ember/component/helper","@ember/object"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var l=(0,t.helper)(((e,t)=>{let[l=[],r]=e return Array.isArray(l)||(l=l.toArray()),l.reduce(((e,t,l)=>(e[(0,n.get)(t,r)]=t,e)),{})})) e.default=l})),define("consul-ui/helpers/to-route",["exports","@ember/component/helper","@ember/service"],(function(e,t,n){var l,r,i,o,a @@ -2163,12 +2173,12 @@ e.default=l})),define("consul-ui/initializers/initialize-torii-session",["export var l={name:"torii-session",after:"torii",initialize(e){arguments[1]&&(e=arguments[1]) const l=(0,n.getConfiguration)() l.sessionServiceName&&(0,t.default)(e,l.sessionServiceName)}} -e.default=l})),define("consul-ui/initializers/initialize-torii",["exports","torii/bootstrap/torii","torii/configuration","consul-ui/config/environment"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=l})) +define("consul-ui/initializers/initialize-torii",["exports","torii/bootstrap/torii","torii/configuration","consul-ui/config/environment"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var r={name:"torii",initialize(e){arguments[1]&&(e=arguments[1]),(0,n.configure)(l.default.torii||{}),(0,t.default)(e)}},i=r e.default=i})),define("consul-ui/initializers/model-fragments",["exports","ember-data-model-fragments","ember-data-model-fragments/ext"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var l={name:"fragmentTransform",after:"ember-data",initialize(){}} -e.default=l})) -define("consul-ui/initializers/setup-ember-can",["exports","ember-can/initializers/setup-ember-can"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"initialize",{enumerable:!0,get:function(){return t.initialize}})})),define("consul-ui/instance-initializers/container",["exports","@ember/debug","require","deepmerge"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.services=e.default=void 0 +e.default=l})),define("consul-ui/initializers/setup-ember-can",["exports","ember-can/initializers/setup-ember-can"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"initialize",{enumerable:!0,get:function(){return t.initialize}})})),define("consul-ui/instance-initializers/container",["exports","@ember/debug","require","deepmerge"],(function(e,t,n,l){Object.defineProperty(e,"__esModule",{value:!0}),e.services=e.default=void 0 const r=document,i=l.default.all([...r.querySelectorAll("script[data-services]")].map((e=>JSON.parse(e.dataset.services)))) e.services=i var o={name:"container",initialize(e){(function(e,t){Object.entries(t).forEach((t=>{let[l,r]=t @@ -2253,7 +2263,7 @@ e.default=class{static create(){return new this(...arguments)}constructor(e,t,n) const l=this.doc.querySelector("base[href]") null!==l&&(this.baseURL=l.getAttribute("href"))}initState(){this.location=this.location||this.doc.defaultView.location,this.machine=this.machine||this.doc.defaultView.history,this.doc.defaultView.addEventListener("popstate",this.route) const e=this.machine.state,t=this.getURL(),n=this.formatURL(t) -e&&e.path===n?(this._previousPath=n,this._previousURL=t):this.dispatch("replace",n)}getURLFrom(e){return e=e||this.location.pathname,this.rootURL=this.rootURL.replace(o,""),this.baseURL=this.baseURL.replace(o,""),e.replace(new RegExp(`^${this.baseURL}(?=/|$)`),"").replace(new RegExp(`^${this.rootURL}(?=/|$)`),"")}getURLForTransition(e){return this.optional={},e=this.getURLFrom(e).split("/").filter(((e,t)=>{if(t<3){let t=!1 +e&&e.path===n?(this._previousPath=n,this._previousURL=t):this.dispatch("replace",n)}getURLFrom(e){return e=e||this.location.pathname,this.rootURL=this.rootURL.replace(o,""),this.baseURL=this.baseURL.replace(o,""),e.replace(new RegExp(`^${this.baseURL}(?=/|$)`),"").replace(new RegExp(`^${this.rootURL}(?=/|$)`),"")}getURLForTransition(e){return this.optional={},e=this.getURLFrom(e).split("/").filter(((e,t)=>{if(t<4){let t=!1 return Object.entries(i).reduce(((n,l)=>{let[r,i]=l const o=i.exec(e) return null!==o&&(n[r]={value:e,match:o[1]},t=!0),n}),this.optional),!t}return!0})).join("/")}optionalParams(){let e=this.optional||{} @@ -2320,8 +2330,8 @@ function U(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,config return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uid" e.SLUG_KEY="Name" -let K=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string",{defaultValue:()=>""}),d=(0,t.attr)("string",{defaultValue:()=>""}),p=(0,t.attr)("string",{defaultValue:()=>"local"}),f=(0,t.attr)("string"),m=(0,t.attr)(),h=(0,n.or)("DisplayName","Name"),b=(0,t.attr)(),y=(0,t.attr)("string"),v=(0,t.attr)("number"),g=(0,t.attr)("number"),O=(0,t.attr)(),P=(0,t.attr)(),w=(0,r.computed)("MaxTokenTTL"),x=class extends t.default{constructor(){super(...arguments),U(this,"uid",j,this),U(this,"Name",_,this),U(this,"Datacenter",S,this),U(this,"Namespace",k,this),U(this,"Partition",N,this),U(this,"Description",C,this),U(this,"DisplayName",z,this),U(this,"TokenLocality",M,this),U(this,"Type",D,this),U(this,"NamespaceRules",T,this),U(this,"MethodName",E,this),U(this,"Config",L,this),U(this,"MaxTokenTTL",A,this),U(this,"CreateIndex",R,this),U(this,"ModifyIndex",I,this),U(this,"Datacenters",$,this),U(this,"meta",F,this)}get TokenTTL(){return(0,l.default)(this.MaxTokenTTL)}},j=B(x.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),_=B(x.prototype,"Name",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),S=B(x.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),k=B(x.prototype,"Namespace",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),N=B(x.prototype,"Partition",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),C=B(x.prototype,"Description",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=B(x.prototype,"DisplayName",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=B(x.prototype,"TokenLocality",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=B(x.prototype,"Type",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=B(x.prototype,"NamespaceRules",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=B(x.prototype,"MethodName",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=B(x.prototype,"Config",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=B(x.prototype,"MaxTokenTTL",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=B(x.prototype,"CreateIndex",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=B(x.prototype,"ModifyIndex",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=B(x.prototype,"Datacenters",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=B(x.prototype,"meta",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B(x.prototype,"TokenTTL",[w],Object.getOwnPropertyDescriptor(x.prototype,"TokenTTL"),x.prototype),x) -e.default=K})),define("consul-ui/models/binding-rule",["exports","@ember-data/model"],(function(e,t){var n,l,r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S +let q=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string",{defaultValue:()=>""}),d=(0,t.attr)("string",{defaultValue:()=>""}),p=(0,t.attr)("string",{defaultValue:()=>"local"}),f=(0,t.attr)("string"),m=(0,t.attr)(),h=(0,n.or)("DisplayName","Name"),b=(0,t.attr)(),y=(0,t.attr)("string"),v=(0,t.attr)("number"),g=(0,t.attr)("number"),O=(0,t.attr)(),P=(0,t.attr)(),w=(0,r.computed)("MaxTokenTTL"),x=class extends t.default{constructor(){super(...arguments),U(this,"uid",j,this),U(this,"Name",_,this),U(this,"Datacenter",S,this),U(this,"Namespace",k,this),U(this,"Partition",N,this),U(this,"Description",C,this),U(this,"DisplayName",z,this),U(this,"TokenLocality",M,this),U(this,"Type",D,this),U(this,"NamespaceRules",T,this),U(this,"MethodName",E,this),U(this,"Config",L,this),U(this,"MaxTokenTTL",A,this),U(this,"CreateIndex",R,this),U(this,"ModifyIndex",I,this),U(this,"Datacenters",$,this),U(this,"meta",F,this)}get TokenTTL(){return(0,l.default)(this.MaxTokenTTL)}},j=B(x.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),_=B(x.prototype,"Name",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),S=B(x.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),k=B(x.prototype,"Namespace",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),N=B(x.prototype,"Partition",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),C=B(x.prototype,"Description",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=B(x.prototype,"DisplayName",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=B(x.prototype,"TokenLocality",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=B(x.prototype,"Type",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=B(x.prototype,"NamespaceRules",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=B(x.prototype,"MethodName",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=B(x.prototype,"Config",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=B(x.prototype,"MaxTokenTTL",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=B(x.prototype,"CreateIndex",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=B(x.prototype,"ModifyIndex",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=B(x.prototype,"Datacenters",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=B(x.prototype,"meta",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B(x.prototype,"TokenTTL",[w],Object.getOwnPropertyDescriptor(x.prototype,"TokenTTL"),x.prototype),x) +e.default=q})),define("consul-ui/models/binding-rule",["exports","@ember-data/model"],(function(e,t){var n,l,r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S function k(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function N(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uid" @@ -2373,35 +2383,35 @@ return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumera const d={Action:{defaultValue:"allow",allowedValues:["allow","deny"]}} e.schema=d let p=(r=(0,l.attr)("string",{defaultValue:()=>d.Action.defaultValue}),i=(0,n.fragment)("intention-permission-http"),o=class extends t.default{constructor(){super(...arguments),s(this,"Action",a,this),s(this,"HTTP",u,this)}},a=c(o.prototype,"Action",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),u=c(o.prototype,"HTTP",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),o) -e.default=p})),define("consul-ui/models/intention",["exports","@ember-data/model","@ember/object","ember-data-model-fragments/attributes","consul-ui/decorators/replace"],(function(e,t,n,l,r){var i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,K,q,H,Y,G,V,W,Z,Q,J,X,ee,te,ne +e.default=p})) +define("consul-ui/models/intention",["exports","@ember-data/model","@ember/object","ember-data-model-fragments/attributes","consul-ui/decorators/replace"],(function(e,t,n,l,r){var i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,q,K,H,Y,G,V,W,Z,Q,J,X,ee,te,ne function le(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function re(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uid" e.SLUG_KEY="ID" -let ie=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,r.default)("",void 0),c=(0,t.attr)("string"),d=(0,t.attr)("string",{defaultValue:()=>"*"}),p=(0,t.attr)("string",{defaultValue:()=>"*"}),f=(0,t.attr)("string",{defaultValue:()=>"default"}),m=(0,t.attr)("string",{defaultValue:()=>"default"}),h=(0,t.attr)("string",{defaultValue:()=>"default"}),b=(0,t.attr)("string",{defaultValue:()=>"default"}),y=(0,t.attr)("number"),v=(0,t.attr)("string",{defaultValue:()=>"consul"}),g=(0,r.nullValue)(void 0),O=(0,t.attr)("string"),P=(0,t.attr)("string"),w=(0,t.attr)("boolean",{defaultValue:()=>!0}),x=(0,t.attr)("number"),j=(0,t.attr)("date"),_=(0,t.attr)("date"),S=(0,t.attr)("number"),k=(0,t.attr)("number"),N=(0,t.attr)(),C=(0,t.attr)({defaultValue:()=>[]}),z=(0,l.fragmentArray)("intention-permission"),M=(0,n.computed)("Meta"),D=class extends t.default{constructor(){super(...arguments),le(this,"uid",T,this),le(this,"ID",E,this),le(this,"Datacenter",L,this),le(this,"Description",A,this),le(this,"SourcePeer",R,this),le(this,"SourceName",I,this),le(this,"DestinationName",$,this),le(this,"SourceNS",F,this),le(this,"DestinationNS",U,this),le(this,"SourcePartition",B,this),le(this,"DestinationPartition",K,this),le(this,"Precedence",q,this),le(this,"SourceType",H,this),le(this,"Action",Y,this),le(this,"LegacyID",G,this),le(this,"Legacy",V,this),le(this,"SyncTime",W,this),le(this,"CreatedAt",Z,this),le(this,"UpdatedAt",Q,this),le(this,"CreateIndex",J,this),le(this,"ModifyIndex",X,this),le(this,"Meta",ee,this),le(this,"Resources",te,this),le(this,"Permissions",ne,this)}get IsManagedByCRD(){return void 0!==Object.entries(this.Meta||{}).find((e=>{let[t,n]=e -return"external-source"===t&&"kubernetes"===n}))}},T=re(D.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=re(D.prototype,"ID",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=re(D.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=re(D.prototype,"Description",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=re(D.prototype,"SourcePeer",[s,c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=re(D.prototype,"SourceName",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=re(D.prototype,"DestinationName",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=re(D.prototype,"SourceNS",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=re(D.prototype,"DestinationNS",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=re(D.prototype,"SourcePartition",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=re(D.prototype,"DestinationPartition",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=re(D.prototype,"Precedence",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=re(D.prototype,"SourceType",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=re(D.prototype,"Action",[g,O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=re(D.prototype,"LegacyID",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=re(D.prototype,"Legacy",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=re(D.prototype,"SyncTime",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=re(D.prototype,"CreatedAt",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Q=re(D.prototype,"UpdatedAt",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J=re(D.prototype,"CreateIndex",[S],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),X=re(D.prototype,"ModifyIndex",[k],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ee=re(D.prototype,"Meta",[N],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),te=re(D.prototype,"Resources",[C],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ne=re(D.prototype,"Permissions",[z],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),re(D.prototype,"IsManagedByCRD",[M],Object.getOwnPropertyDescriptor(D.prototype,"IsManagedByCRD"),D.prototype),D) +let ie=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,r.default)("",void 0),c=(0,t.attr)("string"),d=(0,t.attr)("string",{defaultValue:()=>"*"}),p=(0,t.attr)("string",{defaultValue:()=>"*"}),f=(0,t.attr)("string",{defaultValue:()=>"default"}),m=(0,t.attr)("string",{defaultValue:()=>"default"}),h=(0,t.attr)("string",{defaultValue:()=>"default"}),b=(0,t.attr)("string",{defaultValue:()=>"default"}),y=(0,t.attr)("number"),v=(0,t.attr)("string",{defaultValue:()=>"consul"}),g=(0,r.nullValue)(void 0),O=(0,t.attr)("string"),P=(0,t.attr)("string"),w=(0,t.attr)("boolean",{defaultValue:()=>!0}),x=(0,t.attr)("number"),j=(0,t.attr)("date"),_=(0,t.attr)("date"),S=(0,t.attr)("number"),k=(0,t.attr)("number"),N=(0,t.attr)(),C=(0,t.attr)({defaultValue:()=>[]}),z=(0,l.fragmentArray)("intention-permission"),M=(0,n.computed)("Meta"),D=class extends t.default{constructor(){super(...arguments),le(this,"uid",T,this),le(this,"ID",E,this),le(this,"Datacenter",L,this),le(this,"Description",A,this),le(this,"SourcePeer",R,this),le(this,"SourceName",I,this),le(this,"DestinationName",$,this),le(this,"SourceNS",F,this),le(this,"DestinationNS",U,this),le(this,"SourcePartition",B,this),le(this,"DestinationPartition",q,this),le(this,"Precedence",K,this),le(this,"SourceType",H,this),le(this,"Action",Y,this),le(this,"LegacyID",G,this),le(this,"Legacy",V,this),le(this,"SyncTime",W,this),le(this,"CreatedAt",Z,this),le(this,"UpdatedAt",Q,this),le(this,"CreateIndex",J,this),le(this,"ModifyIndex",X,this),le(this,"Meta",ee,this),le(this,"Resources",te,this),le(this,"Permissions",ne,this)}get IsManagedByCRD(){return void 0!==Object.entries(this.Meta||{}).find((e=>{let[t,n]=e +return"external-source"===t&&"kubernetes"===n}))}},T=re(D.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=re(D.prototype,"ID",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=re(D.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=re(D.prototype,"Description",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=re(D.prototype,"SourcePeer",[s,c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=re(D.prototype,"SourceName",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=re(D.prototype,"DestinationName",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=re(D.prototype,"SourceNS",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=re(D.prototype,"DestinationNS",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=re(D.prototype,"SourcePartition",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=re(D.prototype,"DestinationPartition",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=re(D.prototype,"Precedence",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=re(D.prototype,"SourceType",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=re(D.prototype,"Action",[g,O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=re(D.prototype,"LegacyID",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=re(D.prototype,"Legacy",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=re(D.prototype,"SyncTime",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=re(D.prototype,"CreatedAt",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Q=re(D.prototype,"UpdatedAt",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J=re(D.prototype,"CreateIndex",[S],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),X=re(D.prototype,"ModifyIndex",[k],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ee=re(D.prototype,"Meta",[N],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),te=re(D.prototype,"Resources",[C],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ne=re(D.prototype,"Permissions",[z],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),re(D.prototype,"IsManagedByCRD",[M],Object.getOwnPropertyDescriptor(D.prototype,"IsManagedByCRD"),D.prototype),D) e.default=ie})),define("consul-ui/models/kv",["exports","@ember-data/model","@ember/object","consul-ui/utils/isFolder","consul-ui/decorators/replace"],(function(e,t,n,l,r){var i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A function R(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function I(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uid" e.SLUG_KEY="Key" let $=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("number"),u=(0,t.attr)(),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("string"),p=(0,t.attr)("number"),f=(0,t.attr)("number"),m=(0,r.nullValue)(void 0),h=(0,t.attr)("string"),b=(0,t.attr)("number"),y=(0,t.attr)("number"),v=(0,t.attr)("string"),g=(0,t.attr)({defaultValue:()=>[]}),O=(0,n.computed)("isFolder"),P=(0,n.computed)("Key"),w=class extends t.default{constructor(){super(...arguments),R(this,"uid",x,this),R(this,"Key",j,this),R(this,"SyncTime",_,this),R(this,"meta",S,this),R(this,"Datacenter",k,this),R(this,"Namespace",N,this),R(this,"Partition",C,this),R(this,"LockIndex",z,this),R(this,"Flags",M,this),R(this,"Value",D,this),R(this,"CreateIndex",T,this),R(this,"ModifyIndex",E,this),R(this,"Session",L,this),R(this,"Resources",A,this)}get Kind(){return this.isFolder?"folder":"key"}get isFolder(){return(0,l.default)(this.Key||"")}},x=I(w.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),j=I(w.prototype,"Key",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),_=I(w.prototype,"SyncTime",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),S=I(w.prototype,"meta",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),k=I(w.prototype,"Datacenter",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),N=I(w.prototype,"Namespace",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),C=I(w.prototype,"Partition",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=I(w.prototype,"LockIndex",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=I(w.prototype,"Flags",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=I(w.prototype,"Value",[m,h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=I(w.prototype,"CreateIndex",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=I(w.prototype,"ModifyIndex",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=I(w.prototype,"Session",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=I(w.prototype,"Resources",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I(w.prototype,"Kind",[O],Object.getOwnPropertyDescriptor(w.prototype,"Kind"),w.prototype),I(w.prototype,"isFolder",[P],Object.getOwnPropertyDescriptor(w.prototype,"isFolder"),w.prototype),w) -e.default=$})) -define("consul-ui/models/license",["exports","@ember-data/model"],(function(e,t){var n,l,r,i,o,a,u,s,c,d,p,f,m,h,b,y,v +e.default=$})),define("consul-ui/models/license",["exports","@ember-data/model"],(function(e,t){var n,l,r,i,o,a,u,s,c,d,p,f,m,h,b,y,v function g(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function O(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uri" let P=(n=(0,t.attr)("string"),l=(0,t.attr)("boolean"),r=(0,t.attr)("number"),i=(0,t.attr)(),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)(),c=class extends t.default{constructor(){super(...arguments),g(this,"uri",d,this),g(this,"Valid",p,this),g(this,"SyncTime",f,this),g(this,"meta",m,this),g(this,"Datacenter",h,this),g(this,"Namespace",b,this),g(this,"Partition",y,this),g(this,"License",v,this)}},d=O(c.prototype,"uri",[n],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),p=O(c.prototype,"Valid",[l],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),f=O(c.prototype,"SyncTime",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),m=O(c.prototype,"meta",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),h=O(c.prototype,"Datacenter",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),b=O(c.prototype,"Namespace",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),y=O(c.prototype,"Partition",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),v=O(c.prototype,"License",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),c) -e.default=P})),define("consul-ui/models/node",["exports","@ember-data/model","@ember/object","@ember/object/computed","ember-data-model-fragments/attributes"],(function(e,t,n,l,r){var i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,K,q,H,Y,G,V +e.default=P})),define("consul-ui/models/node",["exports","@ember-data/model","@ember/object","@ember/object/computed","ember-data-model-fragments/attributes"],(function(e,t,n,l,r){var i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,q,K,H,Y,G,V function W(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function Z(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uid" e.SLUG_KEY="ID" -let Q=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("string"),p=(0,t.attr)("number"),f=(0,t.attr)("number"),m=(0,t.attr)("number"),h=(0,t.attr)(),b=(0,t.attr)(),y=(0,t.attr)(),v=(0,t.attr)({defaultValue:()=>[]}),g=(0,t.hasMany)("service-instance"),O=(0,r.fragmentArray)("health-check"),P=(0,l.filter)("Services",(e=>"connect-proxy"!==e.Service.Kind)),w=(0,l.filter)("Services",(e=>"connect-proxy"===e.Service.Kind)),x=(0,l.filter)("Checks",(e=>""===e.ServiceID)),j=(0,n.computed)("ChecksCritical","ChecksPassing","ChecksWarning"),_=(0,n.computed)("NodeChecks.[]"),S=(0,n.computed)("NodeChecks.[]"),k=(0,n.computed)("NodeChecks.[]"),N=(0,n.computed)("Meta"),C=class extends t.default{constructor(){super(...arguments),W(this,"uid",z,this),W(this,"ID",M,this),W(this,"Datacenter",D,this),W(this,"PeerName",T,this),W(this,"Partition",E,this),W(this,"Address",L,this),W(this,"Node",A,this),W(this,"SyncTime",R,this),W(this,"CreateIndex",I,this),W(this,"ModifyIndex",$,this),W(this,"meta",F,this),W(this,"Meta",U,this),W(this,"TaggedAddresses",B,this),W(this,"Resources",K,this),W(this,"Services",q,this),W(this,"Checks",H,this),W(this,"MeshServiceInstances",Y,this),W(this,"ProxyServiceInstances",G,this),W(this,"NodeChecks",V,this)}get Status(){switch(!0){case 0!==this.ChecksCritical:return"critical" +let Q=(i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("string"),p=(0,t.attr)("number"),f=(0,t.attr)("number"),m=(0,t.attr)("number"),h=(0,t.attr)(),b=(0,t.attr)(),y=(0,t.attr)(),v=(0,t.attr)({defaultValue:()=>[]}),g=(0,t.hasMany)("service-instance"),O=(0,r.fragmentArray)("health-check"),P=(0,l.filter)("Services",(e=>"connect-proxy"!==e.Service.Kind)),w=(0,l.filter)("Services",(e=>"connect-proxy"===e.Service.Kind)),x=(0,l.filter)("Checks",(e=>""===e.ServiceID)),j=(0,n.computed)("ChecksCritical","ChecksPassing","ChecksWarning"),_=(0,n.computed)("NodeChecks.[]"),S=(0,n.computed)("NodeChecks.[]"),k=(0,n.computed)("NodeChecks.[]"),N=(0,n.computed)("Meta"),C=class extends t.default{constructor(){super(...arguments),W(this,"uid",z,this),W(this,"ID",M,this),W(this,"Datacenter",D,this),W(this,"PeerName",T,this),W(this,"Partition",E,this),W(this,"Address",L,this),W(this,"Node",A,this),W(this,"SyncTime",R,this),W(this,"CreateIndex",I,this),W(this,"ModifyIndex",$,this),W(this,"meta",F,this),W(this,"Meta",U,this),W(this,"TaggedAddresses",B,this),W(this,"Resources",q,this),W(this,"Services",K,this),W(this,"Checks",H,this),W(this,"MeshServiceInstances",Y,this),W(this,"ProxyServiceInstances",G,this),W(this,"NodeChecks",V,this)}get Status(){switch(!0){case 0!==this.ChecksCritical:return"critical" case 0!==this.ChecksWarning:return"warning" case 0!==this.ChecksPassing:return"passing" default:return"empty"}}get ChecksCritical(){return this.NodeChecks.filter((e=>"critical"===e.Status)).length}get ChecksPassing(){return this.NodeChecks.filter((e=>"passing"===e.Status)).length}get ChecksWarning(){return this.NodeChecks.filter((e=>"warning"===e.Status)).length}get Version(){var e,t -return null!==(e=null===(t=this.Meta)||void 0===t?void 0:t["consul-version"])&&void 0!==e?e:""}},z=Z(C.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=Z(C.prototype,"ID",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=Z(C.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=Z(C.prototype,"PeerName",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=Z(C.prototype,"Partition",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=Z(C.prototype,"Address",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=Z(C.prototype,"Node",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=Z(C.prototype,"SyncTime",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=Z(C.prototype,"CreateIndex",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=Z(C.prototype,"ModifyIndex",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=Z(C.prototype,"meta",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=Z(C.prototype,"Meta",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=Z(C.prototype,"TaggedAddresses",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=Z(C.prototype,"Resources",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=Z(C.prototype,"Services",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=Z(C.prototype,"Checks",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=Z(C.prototype,"MeshServiceInstances",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=Z(C.prototype,"ProxyServiceInstances",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=Z(C.prototype,"NodeChecks",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z(C.prototype,"Status",[j],Object.getOwnPropertyDescriptor(C.prototype,"Status"),C.prototype),Z(C.prototype,"ChecksCritical",[_],Object.getOwnPropertyDescriptor(C.prototype,"ChecksCritical"),C.prototype),Z(C.prototype,"ChecksPassing",[S],Object.getOwnPropertyDescriptor(C.prototype,"ChecksPassing"),C.prototype),Z(C.prototype,"ChecksWarning",[k],Object.getOwnPropertyDescriptor(C.prototype,"ChecksWarning"),C.prototype),Z(C.prototype,"Version",[N],Object.getOwnPropertyDescriptor(C.prototype,"Version"),C.prototype),C) +return null!==(e=null===(t=this.Meta)||void 0===t?void 0:t["consul-version"])&&void 0!==e?e:""}},z=Z(C.prototype,"uid",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=Z(C.prototype,"ID",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=Z(C.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=Z(C.prototype,"PeerName",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=Z(C.prototype,"Partition",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=Z(C.prototype,"Address",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=Z(C.prototype,"Node",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=Z(C.prototype,"SyncTime",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=Z(C.prototype,"CreateIndex",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=Z(C.prototype,"ModifyIndex",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=Z(C.prototype,"meta",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=Z(C.prototype,"Meta",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=Z(C.prototype,"TaggedAddresses",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=Z(C.prototype,"Resources",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=Z(C.prototype,"Services",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=Z(C.prototype,"Checks",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=Z(C.prototype,"MeshServiceInstances",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=Z(C.prototype,"ProxyServiceInstances",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=Z(C.prototype,"NodeChecks",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z(C.prototype,"Status",[j],Object.getOwnPropertyDescriptor(C.prototype,"Status"),C.prototype),Z(C.prototype,"ChecksCritical",[_],Object.getOwnPropertyDescriptor(C.prototype,"ChecksCritical"),C.prototype),Z(C.prototype,"ChecksPassing",[S],Object.getOwnPropertyDescriptor(C.prototype,"ChecksPassing"),C.prototype),Z(C.prototype,"ChecksWarning",[k],Object.getOwnPropertyDescriptor(C.prototype,"ChecksWarning"),C.prototype),Z(C.prototype,"Version",[N],Object.getOwnPropertyDescriptor(C.prototype,"Version"),C.prototype),C) e.default=Q})),define("consul-ui/models/nspace",["exports","@ember-data/model"],(function(e,t){var n,l,r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w function x(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function j(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=e.NSPACE_KEY=void 0 @@ -2451,7 +2461,7 @@ return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumera e.PRIMARY_KEY="uid" e.SLUG_KEY="ID" let R=(n=(0,t.attr)("string"),l=(0,t.attr)("string"),r=(0,t.attr)("string"),i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string",{defaultValue:()=>""}),u=(0,t.attr)("string",{defaultValue:()=>""}),s=(0,t.attr)({defaultValue:()=>[]}),c=(0,t.attr)({defaultValue:()=>[]}),d=(0,t.attr)({defaultValue:()=>[]}),p=(0,t.attr)("number"),f=(0,t.attr)("number"),m=(0,t.attr)("number"),h=(0,t.attr)("number"),b=(0,t.attr)(),y=(0,t.attr)("string"),v=class extends t.default{constructor(){super(...arguments),L(this,"uid",g,this),L(this,"ID",O,this),L(this,"Datacenter",P,this),L(this,"Namespace",w,this),L(this,"Partition",x,this),L(this,"Name",j,this),L(this,"Description",_,this),L(this,"Policies",S,this),L(this,"ServiceIdentities",k,this),L(this,"NodeIdentities",N,this),L(this,"SyncTime",C,this),L(this,"CreateIndex",z,this),L(this,"ModifyIndex",M,this),L(this,"CreateTime",D,this),L(this,"Datacenters",T,this),L(this,"Hash",E,this)}},g=A(v.prototype,"uid",[n],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),O=A(v.prototype,"ID",[l],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),P=A(v.prototype,"Datacenter",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),w=A(v.prototype,"Namespace",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),x=A(v.prototype,"Partition",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),j=A(v.prototype,"Name",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),_=A(v.prototype,"Description",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),S=A(v.prototype,"Policies",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),k=A(v.prototype,"ServiceIdentities",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),N=A(v.prototype,"NodeIdentities",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),C=A(v.prototype,"SyncTime",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=A(v.prototype,"CreateIndex",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=A(v.prototype,"ModifyIndex",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=A(v.prototype,"CreateTime",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=A(v.prototype,"Datacenters",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=A(v.prototype,"Hash",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),v) -e.default=R})),define("consul-ui/models/service-instance",["exports","@ember-data/model","ember-data-model-fragments/attributes","@ember/object","@ember/object/computed","@glimmer/tracking"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,K,q,H,Y,G,V,W,Z,Q,J,X,ee,te,ne,le +e.default=R})),define("consul-ui/models/service-instance",["exports","@ember-data/model","ember-data-model-fragments/attributes","@ember/object","@ember/object/computed","@glimmer/tracking"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,q,K,H,Y,G,V,W,Z,Q,J,X,ee,te,ne,le function re(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function ie(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=e.Collection=void 0 e.PRIMARY_KEY="uid" @@ -2459,14 +2469,14 @@ e.SLUG_KEY="Node.Node,Service.ID" const oe=(a=ie((o=class{constructor(e){re(this,"items",a,this),this.items=e}get ExternalSources(){const e=this.items.reduce((function(e,t){return e.concat(t.ExternalSources||[])}),[]) return[...new Set(e)].filter(Boolean).sort()}}).prototype,"items",[i.tracked],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),o) e.Collection=oe -let ae=(u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)(),d=(0,t.attr)(),p=(0,t.attr)(),f=(0,n.fragmentArray)("health-check"),m=(0,t.attr)("number"),h=(0,t.attr)(),b=(0,t.attr)({defaultValue:()=>[]}),y=(0,r.alias)("Service.Service"),v=(0,r.or)("Service.{ID,Service}"),g=(0,r.or)("Service.Address","Node.Service"),O=(0,t.attr)("string"),P=(0,r.alias)("Service.Tags"),w=(0,r.alias)("Service.Meta"),x=(0,r.alias)("Service.Namespace"),j=(0,r.alias)("Service.Partition"),_=(0,r.filter)("Checks.@each.Kind",((e,t,n)=>"service"===e.Kind)),S=(0,r.filter)("Checks.@each.Kind",((e,t,n)=>"node"===e.Kind)),k=(0,l.computed)("Service.Meta"),N=(0,l.computed)("Service.Kind"),C=(0,l.computed)("Service.Kind"),z=(0,l.computed)("IsOrigin"),M=(0,l.computed)("ChecksPassing","ChecksWarning","ChecksCritical"),D=(0,l.computed)("Checks.[]"),T=(0,l.computed)("Checks.[]"),E=(0,l.computed)("Checks.[]"),L=(0,l.computed)("Checks.[]","ChecksPassing"),A=(0,l.computed)("Checks.[]","ChecksWarning"),R=(0,l.computed)("Checks.[]","ChecksCritical"),I=class extends t.default{constructor(){super(...arguments),re(this,"uid",$,this),re(this,"Datacenter",F,this),re(this,"Proxy",U,this),re(this,"Node",B,this),re(this,"Service",K,this),re(this,"Checks",q,this),re(this,"SyncTime",H,this),re(this,"meta",Y,this),re(this,"Resources",G,this),re(this,"Name",V,this),re(this,"ID",W,this),re(this,"Address",Z,this),re(this,"SocketPath",Q,this),re(this,"Tags",J,this),re(this,"Meta",X,this),re(this,"Namespace",ee,this),re(this,"Partition",te,this),re(this,"ServiceChecks",ne,this),re(this,"NodeChecks",le,this)}get ExternalSources(){const e=Object.entries(this.Service.Meta||{}).filter((e=>{let[t,n]=e +let ae=(u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)(),d=(0,t.attr)(),p=(0,t.attr)(),f=(0,n.fragmentArray)("health-check"),m=(0,t.attr)("number"),h=(0,t.attr)(),b=(0,t.attr)({defaultValue:()=>[]}),y=(0,r.alias)("Service.Service"),v=(0,r.or)("Service.{ID,Service}"),g=(0,r.or)("Service.Address","Node.Service"),O=(0,t.attr)("string"),P=(0,r.alias)("Service.Tags"),w=(0,r.alias)("Service.Meta"),x=(0,r.alias)("Service.Namespace"),j=(0,r.alias)("Service.Partition"),_=(0,r.filter)("Checks.@each.Kind",((e,t,n)=>"service"===e.Kind)),S=(0,r.filter)("Checks.@each.Kind",((e,t,n)=>"node"===e.Kind)),k=(0,l.computed)("Service.Meta"),N=(0,l.computed)("Service.Kind"),C=(0,l.computed)("Service.Kind"),z=(0,l.computed)("IsOrigin"),M=(0,l.computed)("ChecksPassing","ChecksWarning","ChecksCritical"),D=(0,l.computed)("Checks.[]"),T=(0,l.computed)("Checks.[]"),E=(0,l.computed)("Checks.[]"),L=(0,l.computed)("Checks.[]","ChecksPassing"),A=(0,l.computed)("Checks.[]","ChecksWarning"),R=(0,l.computed)("Checks.[]","ChecksCritical"),I=class extends t.default{constructor(){super(...arguments),re(this,"uid",$,this),re(this,"Datacenter",F,this),re(this,"Proxy",U,this),re(this,"Node",B,this),re(this,"Service",q,this),re(this,"Checks",K,this),re(this,"SyncTime",H,this),re(this,"meta",Y,this),re(this,"Resources",G,this),re(this,"Name",V,this),re(this,"ID",W,this),re(this,"Address",Z,this),re(this,"SocketPath",Q,this),re(this,"Tags",J,this),re(this,"Meta",X,this),re(this,"Namespace",ee,this),re(this,"Partition",te,this),re(this,"ServiceChecks",ne,this),re(this,"NodeChecks",le,this)}get ExternalSources(){const e=Object.entries(this.Service.Meta||{}).filter((e=>{let[t,n]=e return"external-source"===t})).map((e=>{let[t,n]=e return n})) return[...new Set(e)]}get IsProxy(){return["connect-proxy","mesh-gateway","ingress-gateway","terminating-gateway","api-gateway"].includes(this.Service.Kind)}get IsOrigin(){return!["connect-proxy","mesh-gateway"].includes(this.Service.Kind)}get IsMeshOrigin(){return this.IsOrigin&&!["terminating-gateway"].includes(this.Service.Kind)}get Status(){switch(!0){case 0!==this.ChecksCritical.length:return"critical" case 0!==this.ChecksWarning.length:return"warning" case 0!==this.ChecksPassing.length:return"passing" -default:return"empty"}}get ChecksPassing(){return this.Checks.filter((e=>"passing"===e.Status))}get ChecksWarning(){return this.Checks.filter((e=>"warning"===e.Status))}get ChecksCritical(){return this.Checks.filter((e=>"critical"===e.Status))}get PercentageChecksPassing(){return this.ChecksPassing.length/this.Checks.length*100}get PercentageChecksWarning(){return this.ChecksWarning.length/this.Checks.length*100}get PercentageChecksCritical(){return this.ChecksCritical.length/this.Checks.length*100}},$=ie(I.prototype,"uid",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=ie(I.prototype,"Datacenter",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=ie(I.prototype,"Proxy",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=ie(I.prototype,"Node",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=ie(I.prototype,"Service",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=ie(I.prototype,"Checks",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=ie(I.prototype,"SyncTime",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=ie(I.prototype,"meta",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=ie(I.prototype,"Resources",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=ie(I.prototype,"Name",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=ie(I.prototype,"ID",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=ie(I.prototype,"Address",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Q=ie(I.prototype,"SocketPath",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J=ie(I.prototype,"Tags",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),X=ie(I.prototype,"Meta",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ee=ie(I.prototype,"Namespace",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),te=ie(I.prototype,"Partition",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ne=ie(I.prototype,"ServiceChecks",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),le=ie(I.prototype,"NodeChecks",[S],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ie(I.prototype,"ExternalSources",[k],Object.getOwnPropertyDescriptor(I.prototype,"ExternalSources"),I.prototype),ie(I.prototype,"IsProxy",[N],Object.getOwnPropertyDescriptor(I.prototype,"IsProxy"),I.prototype),ie(I.prototype,"IsOrigin",[C],Object.getOwnPropertyDescriptor(I.prototype,"IsOrigin"),I.prototype),ie(I.prototype,"IsMeshOrigin",[z],Object.getOwnPropertyDescriptor(I.prototype,"IsMeshOrigin"),I.prototype),ie(I.prototype,"Status",[M],Object.getOwnPropertyDescriptor(I.prototype,"Status"),I.prototype),ie(I.prototype,"ChecksPassing",[D],Object.getOwnPropertyDescriptor(I.prototype,"ChecksPassing"),I.prototype),ie(I.prototype,"ChecksWarning",[T],Object.getOwnPropertyDescriptor(I.prototype,"ChecksWarning"),I.prototype),ie(I.prototype,"ChecksCritical",[E],Object.getOwnPropertyDescriptor(I.prototype,"ChecksCritical"),I.prototype),ie(I.prototype,"PercentageChecksPassing",[L],Object.getOwnPropertyDescriptor(I.prototype,"PercentageChecksPassing"),I.prototype),ie(I.prototype,"PercentageChecksWarning",[A],Object.getOwnPropertyDescriptor(I.prototype,"PercentageChecksWarning"),I.prototype),ie(I.prototype,"PercentageChecksCritical",[R],Object.getOwnPropertyDescriptor(I.prototype,"PercentageChecksCritical"),I.prototype),I) -e.default=ae})),define("consul-ui/models/service",["exports","@ember-data/model","@ember/object","@glimmer/tracking","ember-data-model-fragments/attributes","consul-ui/decorators/replace"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,K,q,H,Y,G,V,W,Z,Q,J,X,ee,te,ne,le,re,ie,oe,ae,ue,se,ce,de,pe,fe,me,he,be,ye,ve +default:return"empty"}}get ChecksPassing(){return this.Checks.filter((e=>"passing"===e.Status))}get ChecksWarning(){return this.Checks.filter((e=>"warning"===e.Status))}get ChecksCritical(){return this.Checks.filter((e=>"critical"===e.Status))}get PercentageChecksPassing(){return this.ChecksPassing.length/this.Checks.length*100}get PercentageChecksWarning(){return this.ChecksWarning.length/this.Checks.length*100}get PercentageChecksCritical(){return this.ChecksCritical.length/this.Checks.length*100}},$=ie(I.prototype,"uid",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=ie(I.prototype,"Datacenter",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=ie(I.prototype,"Proxy",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=ie(I.prototype,"Node",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=ie(I.prototype,"Service",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=ie(I.prototype,"Checks",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=ie(I.prototype,"SyncTime",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=ie(I.prototype,"meta",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=ie(I.prototype,"Resources",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=ie(I.prototype,"Name",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=ie(I.prototype,"ID",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=ie(I.prototype,"Address",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Q=ie(I.prototype,"SocketPath",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J=ie(I.prototype,"Tags",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),X=ie(I.prototype,"Meta",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ee=ie(I.prototype,"Namespace",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),te=ie(I.prototype,"Partition",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ne=ie(I.prototype,"ServiceChecks",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),le=ie(I.prototype,"NodeChecks",[S],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ie(I.prototype,"ExternalSources",[k],Object.getOwnPropertyDescriptor(I.prototype,"ExternalSources"),I.prototype),ie(I.prototype,"IsProxy",[N],Object.getOwnPropertyDescriptor(I.prototype,"IsProxy"),I.prototype),ie(I.prototype,"IsOrigin",[C],Object.getOwnPropertyDescriptor(I.prototype,"IsOrigin"),I.prototype),ie(I.prototype,"IsMeshOrigin",[z],Object.getOwnPropertyDescriptor(I.prototype,"IsMeshOrigin"),I.prototype),ie(I.prototype,"Status",[M],Object.getOwnPropertyDescriptor(I.prototype,"Status"),I.prototype),ie(I.prototype,"ChecksPassing",[D],Object.getOwnPropertyDescriptor(I.prototype,"ChecksPassing"),I.prototype),ie(I.prototype,"ChecksWarning",[T],Object.getOwnPropertyDescriptor(I.prototype,"ChecksWarning"),I.prototype),ie(I.prototype,"ChecksCritical",[E],Object.getOwnPropertyDescriptor(I.prototype,"ChecksCritical"),I.prototype),ie(I.prototype,"PercentageChecksPassing",[L],Object.getOwnPropertyDescriptor(I.prototype,"PercentageChecksPassing"),I.prototype),ie(I.prototype,"PercentageChecksWarning",[A],Object.getOwnPropertyDescriptor(I.prototype,"PercentageChecksWarning"),I.prototype),ie(I.prototype,"PercentageChecksCritical",[R],Object.getOwnPropertyDescriptor(I.prototype,"PercentageChecksCritical"),I.prototype),I) +e.default=ae})),define("consul-ui/models/service",["exports","@ember-data/model","@ember/object","@glimmer/tracking","ember-data-model-fragments/attributes","consul-ui/decorators/replace"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,q,K,H,Y,G,V,W,Z,Q,J,X,ee,te,ne,le,re,ie,oe,ae,ue,se,ce,de,pe,fe,me,he,be,ye,ve function ge(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function Oe(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=e.Collection=void 0 e.PRIMARY_KEY="uid" @@ -2474,7 +2484,7 @@ e.SLUG_KEY="Name,PeerName" const Pe=(a=Oe((o=class{constructor(e){ge(this,"items",a,this),this.items=e}get ExternalSources(){const e=this.items.reduce((function(e,t){return e.concat(t.ExternalSources||[])}),[]) return[...new Set(e)].filter(Boolean).sort()}get Partitions(){return[...new Set(this.items.map((e=>e.Partition)))].sort()}}).prototype,"items",[l.tracked],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),o) e.Collection=Pe -let we=(u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("string"),p=(0,t.attr)("string"),f=(0,t.attr)("string"),m=(0,i.default)("",void 0),h=(0,t.attr)("string"),b=(0,t.attr)("number"),y=(0,t.attr)("number"),v=(0,t.attr)("number"),g=(0,t.attr)("number"),O=(0,t.attr)("boolean"),P=(0,t.attr)("boolean"),w=(0,t.attr)({defaultValue:()=>[]}),x=(0,t.attr)("number"),j=(0,t.attr)("number"),_=(0,t.attr)("number"),S=(0,i.nullValue)([]),k=(0,t.attr)({defaultValue:()=>[]}),N=(0,t.attr)(),C=(0,t.attr)(),z=(0,r.fragment)("gateway-config"),M=(0,i.nullValue)([]),D=(0,t.attr)(),T=(0,t.attr)(),E=(0,t.attr)(),L=(0,t.belongsTo)({async:!1}),A=(0,n.computed)("peer","InstanceCount"),R=(0,n.computed)("peer.State"),I=(0,n.computed)("ChecksPassing","ChecksWarning","ChecksCritical"),$=(0,n.computed)("MeshChecksPassing","MeshChecksWarning","MeshChecksCritical"),F=(0,n.computed)("ConnectedWithProxy","ConnectedWithGateway"),U=(0,n.computed)("MeshEnabled","Kind"),B=(0,n.computed)("MeshChecksPassing","MeshChecksWarning","MeshChecksCritical","isZeroCountButPeered","peerIsFailing"),K=(0,n.computed)("isZeroCountButPeered","peerIsFailing","MeshStatus"),q=(0,n.computed)("ChecksPassing","Proxy.ChecksPassing"),H=(0,n.computed)("ChecksWarning","Proxy.ChecksWarning"),Y=(0,n.computed)("ChecksCritical","Proxy.ChecksCritical"),G=class extends t.default{constructor(){super(...arguments),ge(this,"uid",V,this),ge(this,"Name",W,this),ge(this,"Datacenter",Z,this),ge(this,"Namespace",Q,this),ge(this,"Partition",J,this),ge(this,"Kind",X,this),ge(this,"PeerName",ee,this),ge(this,"ChecksPassing",te,this),ge(this,"ChecksCritical",ne,this),ge(this,"ChecksWarning",le,this),ge(this,"InstanceCount",re,this),ge(this,"ConnectedWithGateway",ie,this),ge(this,"ConnectedWithProxy",oe,this),ge(this,"Resources",ae,this),ge(this,"SyncTime",ue,this),ge(this,"CreateIndex",se,this),ge(this,"ModifyIndex",ce,this),ge(this,"Tags",de,this),ge(this,"Nodes",pe,this),ge(this,"Proxy",fe,this),ge(this,"GatewayConfig",me,this),ge(this,"ExternalSources",he,this),ge(this,"Meta",be,this),ge(this,"meta",ye,this),ge(this,"peer",ve,this)}get isZeroCountButPeered(){return this.peer&&0===this.InstanceCount}get peerIsFailing(){return this.peer&&"FAILING"===this.peer.State}get ChecksTotal(){return this.ChecksPassing+this.ChecksWarning+this.ChecksCritical}get MeshChecksTotal(){return this.MeshChecksPassing+this.MeshChecksWarning+this.MeshChecksCritical}get MeshEnabled(){return this.ConnectedWithProxy||this.ConnectedWithGateway}get InMesh(){return this.MeshEnabled||(this.Kind||"").length>0}get MeshStatus(){switch(!0){case this.isZeroCountButPeered:case this.peerIsFailing:return"unknown" +let we=(u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("string"),p=(0,t.attr)("string"),f=(0,t.attr)("string"),m=(0,i.default)("",void 0),h=(0,t.attr)("string"),b=(0,t.attr)("number"),y=(0,t.attr)("number"),v=(0,t.attr)("number"),g=(0,t.attr)("number"),O=(0,t.attr)("boolean"),P=(0,t.attr)("boolean"),w=(0,t.attr)({defaultValue:()=>[]}),x=(0,t.attr)("number"),j=(0,t.attr)("number"),_=(0,t.attr)("number"),S=(0,i.nullValue)([]),k=(0,t.attr)({defaultValue:()=>[]}),N=(0,t.attr)(),C=(0,t.attr)(),z=(0,r.fragment)("gateway-config"),M=(0,i.nullValue)([]),D=(0,t.attr)(),T=(0,t.attr)(),E=(0,t.attr)(),L=(0,t.belongsTo)({async:!1}),A=(0,n.computed)("peer","InstanceCount"),R=(0,n.computed)("peer.State"),I=(0,n.computed)("ChecksPassing","ChecksWarning","ChecksCritical"),$=(0,n.computed)("MeshChecksPassing","MeshChecksWarning","MeshChecksCritical"),F=(0,n.computed)("ConnectedWithProxy","ConnectedWithGateway"),U=(0,n.computed)("MeshEnabled","Kind"),B=(0,n.computed)("MeshChecksPassing","MeshChecksWarning","MeshChecksCritical","isZeroCountButPeered","peerIsFailing"),q=(0,n.computed)("isZeroCountButPeered","peerIsFailing","MeshStatus"),K=(0,n.computed)("ChecksPassing","Proxy.ChecksPassing"),H=(0,n.computed)("ChecksWarning","Proxy.ChecksWarning"),Y=(0,n.computed)("ChecksCritical","Proxy.ChecksCritical"),G=class extends t.default{constructor(){super(...arguments),ge(this,"uid",V,this),ge(this,"Name",W,this),ge(this,"Datacenter",Z,this),ge(this,"Namespace",Q,this),ge(this,"Partition",J,this),ge(this,"Kind",X,this),ge(this,"PeerName",ee,this),ge(this,"ChecksPassing",te,this),ge(this,"ChecksCritical",ne,this),ge(this,"ChecksWarning",le,this),ge(this,"InstanceCount",re,this),ge(this,"ConnectedWithGateway",ie,this),ge(this,"ConnectedWithProxy",oe,this),ge(this,"Resources",ae,this),ge(this,"SyncTime",ue,this),ge(this,"CreateIndex",se,this),ge(this,"ModifyIndex",ce,this),ge(this,"Tags",de,this),ge(this,"Nodes",pe,this),ge(this,"Proxy",fe,this),ge(this,"GatewayConfig",me,this),ge(this,"ExternalSources",he,this),ge(this,"Meta",be,this),ge(this,"meta",ye,this),ge(this,"peer",ve,this)}get isZeroCountButPeered(){return this.peer&&0===this.InstanceCount}get peerIsFailing(){return this.peer&&"FAILING"===this.peer.State}get ChecksTotal(){return this.ChecksPassing+this.ChecksWarning+this.ChecksCritical}get MeshChecksTotal(){return this.MeshChecksPassing+this.MeshChecksWarning+this.MeshChecksCritical}get MeshEnabled(){return this.ConnectedWithProxy||this.ConnectedWithGateway}get InMesh(){return this.MeshEnabled||(this.Kind||"").length>0}get MeshStatus(){switch(!0){case this.isZeroCountButPeered:case this.peerIsFailing:return"unknown" case 0!==this.MeshChecksCritical:return"critical" case 0!==this.MeshChecksWarning:return"warning" case 0!==this.MeshChecksPassing:return"passing" @@ -2482,7 +2492,7 @@ default:return"empty"}}get healthTooltipText(){const{MeshStatus:e,isZeroCountBut return t?"This service currently has 0 instances. Check with the operator of its peer to make sure this is expected behavior.":n?"This peer is out of sync, so the current health statuses of its services are unknown.":"critical"===e?"At least one health check on one instance is failing.":"warning"===e?"At least one health check on one instance has a warning.":"passing"==e?"All health checks are passing.":"There are no health checks"}get MeshChecksPassing(){let e=0 return void 0!==this.Proxy&&(e=this.Proxy.ChecksPassing),this.ChecksPassing+e}get MeshChecksWarning(){let e=0 return void 0!==this.Proxy&&(e=this.Proxy.ChecksWarning),this.ChecksWarning+e}get MeshChecksCritical(){let e=0 -return void 0!==this.Proxy&&(e=this.Proxy.ChecksCritical),this.ChecksCritical+e}},V=Oe(G.prototype,"uid",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=Oe(G.prototype,"Name",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=Oe(G.prototype,"Datacenter",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Q=Oe(G.prototype,"Namespace",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J=Oe(G.prototype,"Partition",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),X=Oe(G.prototype,"Kind",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ee=Oe(G.prototype,"PeerName",[m,h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),te=Oe(G.prototype,"ChecksPassing",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ne=Oe(G.prototype,"ChecksCritical",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),le=Oe(G.prototype,"ChecksWarning",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),re=Oe(G.prototype,"InstanceCount",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ie=Oe(G.prototype,"ConnectedWithGateway",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),oe=Oe(G.prototype,"ConnectedWithProxy",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ae=Oe(G.prototype,"Resources",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ue=Oe(G.prototype,"SyncTime",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),se=Oe(G.prototype,"CreateIndex",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ce=Oe(G.prototype,"ModifyIndex",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),de=Oe(G.prototype,"Tags",[S,k],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),pe=Oe(G.prototype,"Nodes",[N],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),fe=Oe(G.prototype,"Proxy",[C],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),me=Oe(G.prototype,"GatewayConfig",[z],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),he=Oe(G.prototype,"ExternalSources",[M,D],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),be=Oe(G.prototype,"Meta",[T],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ye=Oe(G.prototype,"meta",[E],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ve=Oe(G.prototype,"peer",[L],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Oe(G.prototype,"isZeroCountButPeered",[A],Object.getOwnPropertyDescriptor(G.prototype,"isZeroCountButPeered"),G.prototype),Oe(G.prototype,"peerIsFailing",[R],Object.getOwnPropertyDescriptor(G.prototype,"peerIsFailing"),G.prototype),Oe(G.prototype,"ChecksTotal",[I],Object.getOwnPropertyDescriptor(G.prototype,"ChecksTotal"),G.prototype),Oe(G.prototype,"MeshChecksTotal",[$],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksTotal"),G.prototype),Oe(G.prototype,"MeshEnabled",[F],Object.getOwnPropertyDescriptor(G.prototype,"MeshEnabled"),G.prototype),Oe(G.prototype,"InMesh",[U],Object.getOwnPropertyDescriptor(G.prototype,"InMesh"),G.prototype),Oe(G.prototype,"MeshStatus",[B],Object.getOwnPropertyDescriptor(G.prototype,"MeshStatus"),G.prototype),Oe(G.prototype,"healthTooltipText",[K],Object.getOwnPropertyDescriptor(G.prototype,"healthTooltipText"),G.prototype),Oe(G.prototype,"MeshChecksPassing",[q],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksPassing"),G.prototype),Oe(G.prototype,"MeshChecksWarning",[H],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksWarning"),G.prototype),Oe(G.prototype,"MeshChecksCritical",[Y],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksCritical"),G.prototype),G) +return void 0!==this.Proxy&&(e=this.Proxy.ChecksCritical),this.ChecksCritical+e}},V=Oe(G.prototype,"uid",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=Oe(G.prototype,"Name",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=Oe(G.prototype,"Datacenter",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Q=Oe(G.prototype,"Namespace",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J=Oe(G.prototype,"Partition",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),X=Oe(G.prototype,"Kind",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ee=Oe(G.prototype,"PeerName",[m,h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),te=Oe(G.prototype,"ChecksPassing",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ne=Oe(G.prototype,"ChecksCritical",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),le=Oe(G.prototype,"ChecksWarning",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),re=Oe(G.prototype,"InstanceCount",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ie=Oe(G.prototype,"ConnectedWithGateway",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),oe=Oe(G.prototype,"ConnectedWithProxy",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ae=Oe(G.prototype,"Resources",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ue=Oe(G.prototype,"SyncTime",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),se=Oe(G.prototype,"CreateIndex",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ce=Oe(G.prototype,"ModifyIndex",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),de=Oe(G.prototype,"Tags",[S,k],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),pe=Oe(G.prototype,"Nodes",[N],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),fe=Oe(G.prototype,"Proxy",[C],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),me=Oe(G.prototype,"GatewayConfig",[z],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),he=Oe(G.prototype,"ExternalSources",[M,D],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),be=Oe(G.prototype,"Meta",[T],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ye=Oe(G.prototype,"meta",[E],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),ve=Oe(G.prototype,"peer",[L],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Oe(G.prototype,"isZeroCountButPeered",[A],Object.getOwnPropertyDescriptor(G.prototype,"isZeroCountButPeered"),G.prototype),Oe(G.prototype,"peerIsFailing",[R],Object.getOwnPropertyDescriptor(G.prototype,"peerIsFailing"),G.prototype),Oe(G.prototype,"ChecksTotal",[I],Object.getOwnPropertyDescriptor(G.prototype,"ChecksTotal"),G.prototype),Oe(G.prototype,"MeshChecksTotal",[$],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksTotal"),G.prototype),Oe(G.prototype,"MeshEnabled",[F],Object.getOwnPropertyDescriptor(G.prototype,"MeshEnabled"),G.prototype),Oe(G.prototype,"InMesh",[U],Object.getOwnPropertyDescriptor(G.prototype,"InMesh"),G.prototype),Oe(G.prototype,"MeshStatus",[B],Object.getOwnPropertyDescriptor(G.prototype,"MeshStatus"),G.prototype),Oe(G.prototype,"healthTooltipText",[q],Object.getOwnPropertyDescriptor(G.prototype,"healthTooltipText"),G.prototype),Oe(G.prototype,"MeshChecksPassing",[K],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksPassing"),G.prototype),Oe(G.prototype,"MeshChecksWarning",[H],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksWarning"),G.prototype),Oe(G.prototype,"MeshChecksCritical",[Y],Object.getOwnPropertyDescriptor(G.prototype,"MeshChecksCritical"),G.prototype),G) e.default=we})),define("consul-ui/models/session",["exports","@ember-data/model","@ember/object","consul-ui/decorators/replace"],(function(e,t,n,l){var r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$ function F(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function U(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 @@ -2490,12 +2500,12 @@ e.PRIMARY_KEY="uid" e.SLUG_KEY="ID" let B=(r=(0,t.attr)("string"),i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("string"),p=(0,t.attr)("string"),f=(0,t.attr)("number"),m=(0,t.attr)("number"),h=(0,t.attr)("number"),b=(0,t.attr)("number"),y=(0,l.nullValue)([]),v=(0,t.attr)({defaultValue:()=>[]}),g=(0,l.nullValue)([]),O=(0,t.attr)({defaultValue:()=>[]}),P=(0,t.attr)({defaultValue:()=>[]}),w=(0,n.computed)("NodeChecks","ServiceChecks"),x=class extends t.default{constructor(){super(...arguments),F(this,"uid",j,this),F(this,"ID",_,this),F(this,"Name",S,this),F(this,"Datacenter",k,this),F(this,"Namespace",N,this),F(this,"Partition",C,this),F(this,"Node",z,this),F(this,"Behavior",M,this),F(this,"TTL",D,this),F(this,"LockDelay",T,this),F(this,"SyncTime",E,this),F(this,"CreateIndex",L,this),F(this,"ModifyIndex",A,this),F(this,"NodeChecks",R,this),F(this,"ServiceChecks",I,this),F(this,"Resources",$,this)}get checks(){return[...this.NodeChecks,...this.ServiceChecks.map((e=>{let{ID:t}=e return t}))]}},j=U(x.prototype,"uid",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),_=U(x.prototype,"ID",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),S=U(x.prototype,"Name",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),k=U(x.prototype,"Datacenter",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),N=U(x.prototype,"Namespace",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),C=U(x.prototype,"Partition",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=U(x.prototype,"Node",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=U(x.prototype,"Behavior",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=U(x.prototype,"TTL",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=U(x.prototype,"LockDelay",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=U(x.prototype,"SyncTime",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=U(x.prototype,"CreateIndex",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=U(x.prototype,"ModifyIndex",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=U(x.prototype,"NodeChecks",[y,v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=U(x.prototype,"ServiceChecks",[g,O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=U(x.prototype,"Resources",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U(x.prototype,"checks",[w],Object.getOwnPropertyDescriptor(x.prototype,"checks"),x.prototype),x) -e.default=B})),define("consul-ui/models/token",["exports","@ember-data/model","@ember/object","consul-ui/models/policy"],(function(e,t,n,l){var r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,K,q,H,Y,G,V,W,Z +e.default=B})),define("consul-ui/models/token",["exports","@ember-data/model","@ember/object","consul-ui/models/policy"],(function(e,t,n,l){var r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z,M,D,T,E,L,A,R,I,$,F,U,B,q,K,H,Y,G,V,W,Z function Q(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function J(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 e.PRIMARY_KEY="uid" e.SLUG_KEY="AccessorID" -let X=(r=(0,t.attr)("string"),i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("boolean"),p=(0,t.attr)("boolean"),f=(0,t.attr)("string",{defaultValue:()=>""}),m=(0,t.attr)(),h=(0,t.attr)({defaultValue:()=>[]}),b=(0,t.attr)({defaultValue:()=>[]}),y=(0,t.attr)({defaultValue:()=>[]}),v=(0,t.attr)({defaultValue:()=>[]}),g=(0,t.attr)("date"),O=(0,t.attr)("string"),P=(0,t.attr)("number"),w=(0,t.attr)("number"),x=(0,t.attr)("string"),j=(0,t.attr)("string",{defaultValue:()=>""}),_=(0,t.attr)("string"),S=(0,n.computed)("Policies.[]"),k=(0,n.computed)("SecretID"),N=class extends t.default{constructor(){super(...arguments),Q(this,"uid",C,this),Q(this,"AccessorID",z,this),Q(this,"Datacenter",M,this),Q(this,"Namespace",D,this),Q(this,"Partition",T,this),Q(this,"IDPName",E,this),Q(this,"SecretID",L,this),Q(this,"Legacy",A,this),Q(this,"Local",R,this),Q(this,"Description",I,this),Q(this,"meta",$,this),Q(this,"Policies",F,this),Q(this,"Roles",U,this),Q(this,"ServiceIdentities",B,this),Q(this,"NodeIdentities",K,this),Q(this,"CreateTime",q,this),Q(this,"Hash",H,this),Q(this,"CreateIndex",Y,this),Q(this,"ModifyIndex",G,this),Q(this,"Type",V,this),Q(this,"Name",W,this),Q(this,"Rules",Z,this)}get isGlobalManagement(){return(this.Policies||[]).find((e=>e.ID===l.MANAGEMENT_ID))}get hasSecretID(){return""!==this.SecretID&&""!==this.SecretID}},C=J(N.prototype,"uid",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=J(N.prototype,"AccessorID",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=J(N.prototype,"Datacenter",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=J(N.prototype,"Namespace",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=J(N.prototype,"Partition",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=J(N.prototype,"IDPName",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=J(N.prototype,"SecretID",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=J(N.prototype,"Legacy",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=J(N.prototype,"Local",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=J(N.prototype,"Description",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=J(N.prototype,"meta",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=J(N.prototype,"Policies",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=J(N.prototype,"Roles",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=J(N.prototype,"ServiceIdentities",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=J(N.prototype,"NodeIdentities",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=J(N.prototype,"CreateTime",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=J(N.prototype,"Hash",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=J(N.prototype,"CreateIndex",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=J(N.prototype,"ModifyIndex",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=J(N.prototype,"Type",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=J(N.prototype,"Name",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=J(N.prototype,"Rules",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J(N.prototype,"isGlobalManagement",[S],Object.getOwnPropertyDescriptor(N.prototype,"isGlobalManagement"),N.prototype),J(N.prototype,"hasSecretID",[k],Object.getOwnPropertyDescriptor(N.prototype,"hasSecretID"),N.prototype),N) +let X=(r=(0,t.attr)("string"),i=(0,t.attr)("string"),o=(0,t.attr)("string"),a=(0,t.attr)("string"),u=(0,t.attr)("string"),s=(0,t.attr)("string"),c=(0,t.attr)("string"),d=(0,t.attr)("boolean"),p=(0,t.attr)("boolean"),f=(0,t.attr)("string",{defaultValue:()=>""}),m=(0,t.attr)(),h=(0,t.attr)({defaultValue:()=>[]}),b=(0,t.attr)({defaultValue:()=>[]}),y=(0,t.attr)({defaultValue:()=>[]}),v=(0,t.attr)({defaultValue:()=>[]}),g=(0,t.attr)("date"),O=(0,t.attr)("string"),P=(0,t.attr)("number"),w=(0,t.attr)("number"),x=(0,t.attr)("string"),j=(0,t.attr)("string",{defaultValue:()=>""}),_=(0,t.attr)("string"),S=(0,n.computed)("Policies.[]"),k=(0,n.computed)("SecretID"),N=class extends t.default{constructor(){super(...arguments),Q(this,"uid",C,this),Q(this,"AccessorID",z,this),Q(this,"Datacenter",M,this),Q(this,"Namespace",D,this),Q(this,"Partition",T,this),Q(this,"IDPName",E,this),Q(this,"SecretID",L,this),Q(this,"Legacy",A,this),Q(this,"Local",R,this),Q(this,"Description",I,this),Q(this,"meta",$,this),Q(this,"Policies",F,this),Q(this,"Roles",U,this),Q(this,"ServiceIdentities",B,this),Q(this,"NodeIdentities",q,this),Q(this,"CreateTime",K,this),Q(this,"Hash",H,this),Q(this,"CreateIndex",Y,this),Q(this,"ModifyIndex",G,this),Q(this,"Type",V,this),Q(this,"Name",W,this),Q(this,"Rules",Z,this)}get isGlobalManagement(){return(this.Policies||[]).find((e=>e.ID===l.MANAGEMENT_ID))}get hasSecretID(){return""!==this.SecretID&&""!==this.SecretID}},C=J(N.prototype,"uid",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),z=J(N.prototype,"AccessorID",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),M=J(N.prototype,"Datacenter",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),D=J(N.prototype,"Namespace",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),T=J(N.prototype,"Partition",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),E=J(N.prototype,"IDPName",[s],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),L=J(N.prototype,"SecretID",[c],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),A=J(N.prototype,"Legacy",[d],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),R=J(N.prototype,"Local",[p],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),I=J(N.prototype,"Description",[f],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),$=J(N.prototype,"meta",[m],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),F=J(N.prototype,"Policies",[h],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),U=J(N.prototype,"Roles",[b],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),B=J(N.prototype,"ServiceIdentities",[y],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),q=J(N.prototype,"NodeIdentities",[v],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),K=J(N.prototype,"CreateTime",[g],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),H=J(N.prototype,"Hash",[O],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Y=J(N.prototype,"CreateIndex",[P],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),G=J(N.prototype,"ModifyIndex",[w],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),V=J(N.prototype,"Type",[x],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),W=J(N.prototype,"Name",[j],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),Z=J(N.prototype,"Rules",[_],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),J(N.prototype,"isGlobalManagement",[S],Object.getOwnPropertyDescriptor(N.prototype,"isGlobalManagement"),N.prototype),J(N.prototype,"hasSecretID",[k],Object.getOwnPropertyDescriptor(N.prototype,"hasSecretID"),N.prototype),N) e.default=X})),define("consul-ui/models/topology",["exports","@ember-data/model","@ember/object"],(function(e,t,n){var l,r,i,o,a,u,s,c,d,p,f,m,h,b,y,v,g,O,P,w,x,j,_,S,k,N,C,z function M(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function D(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=e.SLUG_KEY=e.PRIMARY_KEY=void 0 @@ -2558,15 +2568,15 @@ const r=function(e){for(var t=1;tr.after())).catch((e=>{if("TransitionAborted"!==e.name)throw e})).then((e=>{this.notify.add(r)})):this.notify.add(r),(0,l.registerDestructor)(this,s)}},d=i.prototype,p="notify",f=[r],m={configurable:!0,enumerable:!0,writable:!0,initializer:null},b={},Object.keys(m).forEach((function(e){b[e]=m[e]})),b.enumerable=!!b.enumerable,b.configurable=!!b.configurable,("value"in b||b.initializer)&&(b.writable=!0),b=f.slice().reverse().reduce((function(e,t){return t(d,p,e)||e}),b),h&&void 0!==b.initializer&&(b.value=b.initializer?b.initializer.call(h):void 0,b.initializer=void 0),void 0===b.initializer&&(Object.defineProperty(d,p,b),b=null),o=b,i) var d,p,f,m,h,b -e.default=c})),define("consul-ui/modifiers/on-key",["exports","ember-keyboard/modifiers/on-key.js"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/modifiers/on-outside",["exports","ember-modifier","@ember/object","@ember/service","@ember/destroyable"],(function(e,t,n,l,r){var i,o,a +e.default=c})),define("consul-ui/modifiers/on-key",["exports","ember-keyboard/modifiers/on-key.js"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) +define("consul-ui/modifiers/on-outside",["exports","ember-modifier","@ember/object","@ember/service","@ember/destroyable"],(function(e,t,n,l,r){var i,o,a function u(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}function s(e){var t e&&(null===(t=e.doc)||void 0===t||t.removeEventListener("click",e.listen))}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let c=(i=(0,l.inject)("dom"),o=class extends t.default{constructor(e,t){var n,l,i,o super(e,t),n=this,l="dom",o=this,(i=a)&&Object.defineProperty(n,l,{enumerable:i.enumerable,configurable:i.configurable,writable:i.writable,value:i.initializer?i.initializer.call(o):void 0}),this.doc=this.dom.document(),(0,r.registerDestructor)(this,s)}async modify(e,t,n){s.call(this),this.params=t,this.options=n,this.element=e,await new Promise((e=>setTimeout(e,0))) try{this.doc.addEventListener(t[0],this.listen)}catch(l){}}listen(e){if(this.element&&this.dom.isOutside(this.element,e.target)){("function"==typeof this.params[1]?this.params[1]:e=>{}).apply(this.element,[e])}}},a=u(o.prototype,"dom",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),u(o.prototype,"listen",[n.action],Object.getOwnPropertyDescriptor(o.prototype,"listen"),o.prototype),o) -e.default=c})),define("consul-ui/modifiers/on-resize",["exports","ember-on-resize-modifier/modifiers/on-resize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})) -define("consul-ui/modifiers/style",["exports","ember-modifier","@ember/debug"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=c})),define("consul-ui/modifiers/on-resize",["exports","ember-on-resize-modifier/modifiers/on-resize"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/modifiers/style",["exports","ember-modifier","@ember/debug"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 class l extends t.default{setStyles(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[] const t=this._oldStyles||new Set Array.isArray(e)||(e=Object.entries(e)),e.forEach((e=>{let[n,l]=e,r="" @@ -2664,18 +2674,18 @@ e.callback(t),function e(t,n){"/"!==n.name&&(t=t[n.name]={_options:{path:n.name} t||(t="data:,%s") const n=(0,o.dump)(c) t.startsWith("data:,")?(e=window.open("","_blank"),e.document.write(`
${n}
`)):e=window.open(t.replace("%s",encodeURIComponent(n)),"_blank"),e.focus()}})) -class d extends t.default{constructor(){super(...arguments),a(this,"location",(0,i.env)("locationType")),a(this,"rootURL",(0,i.env)("rootURL"))}}e.default=d,d.map((0,o.default)(c))})),define("consul-ui/routes/application",["exports","consul-ui/routing/route","@ember/object","@ember/service","consul-ui/mixins/with-blocking-actions"],(function(e,t,n,l,r){var i,o,a,u,s,c,d -function p(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function f(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e +class d extends t.default{constructor(){super(...arguments),a(this,"location",(0,i.env)("locationType")),a(this,"rootURL",(0,i.env)("rootURL"))}}e.default=d,d.map((0,o.default)(c))})),define("consul-ui/routes/application",["exports","consul-ui/routing/route","@ember/object","@ember/service","consul-ui/mixins/with-blocking-actions"],(function(e,t,n,l,r){var i,o,a,u,s,c,d,p,f +function m(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function h(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e var n=e[Symbol.toPrimitive] if(void 0!==n){var l=n.call(e,t||"default") if("object"!=typeof l)return l throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string") -return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function m(e,t,n,l,r){var i={} +return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function b(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -let h=(i=(0,l.inject)("client/http"),o=(0,l.inject)("env"),a=(0,l.inject)(),u=class extends(t.default.extend(r.default)){constructor(){super(...arguments),p(this,"client",s,this),p(this,"env",c,this),p(this,"hcp",d,this),f(this,"data",void 0)}async model(){return this.env.var("CONSUL_ACLS_ENABLED")&&await this.hcp.updateTokenIfNecessary(this.env.var("CONSUL_HTTP_TOKEN")),{}}onClientChanged(e){let t=e.data +let y=(i=(0,l.inject)("client/http"),o=(0,l.inject)("env"),a=(0,l.inject)(),u=(0,l.inject)(),s=class extends(t.default.extend(r.default)){constructor(){super(...arguments),m(this,"client",c,this),m(this,"env",d,this),m(this,"hcp",p,this),m(this,"router",f,this),h(this,"data",void 0)}beforeModel(){this.env.var("CONSUL_V2_CATALOG_ENABLED")&&this.router.replaceWith("unavailable")}async model(){return this.env.var("CONSUL_ACLS_ENABLED")&&await this.hcp.updateTokenIfNecessary(this.env.var("CONSUL_HTTP_TOKEN")),{}}onClientChanged(e){let t=e.data ""===t&&(t={blocking:!0}),void 0!==this.data?(!0===this.data.blocking&&!1===t.blocking&&this.client.abort(),this.data=Object.assign({},t)):this.data=Object.assign({},t)}error(e,t){let n={status:e.code||e.statusCode||"",message:e.message||e.detail||"Error"} -return e.errors&&e.errors[0]&&(n=e.errors[0],n.message=n.message||n.title||n.detail||"Error"),""===n.status&&(n.message="Error"),this.controllerFor("application").setProperties({error:n}),!0}},s=m(u.prototype,"client",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),c=m(u.prototype,"env",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),d=m(u.prototype,"hcp",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),m(u.prototype,"onClientChanged",[n.action],Object.getOwnPropertyDescriptor(u.prototype,"onClientChanged"),u.prototype),m(u.prototype,"error",[n.action],Object.getOwnPropertyDescriptor(u.prototype,"error"),u.prototype),u) -e.default=h})),define("consul-ui/routes/dc",["exports","@ember/service","consul-ui/routing/route"],(function(e,t,n){var l,r,i +return e.errors&&e.errors[0]&&(n=e.errors[0],n.message=n.message||n.title||n.detail||"Error"),""===n.status&&(n.message="Error"),this.controllerFor("application").setProperties({error:n}),!0}},c=b(s.prototype,"client",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),d=b(s.prototype,"env",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),p=b(s.prototype,"hcp",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),f=b(s.prototype,"router",[u],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),b(s.prototype,"onClientChanged",[n.action],Object.getOwnPropertyDescriptor(s.prototype,"onClientChanged"),s.prototype),b(s.prototype,"error",[n.action],Object.getOwnPropertyDescriptor(s.prototype,"error"),s.prototype),s) +e.default=y})),define("consul-ui/routes/dc",["exports","@ember/service","consul-ui/routing/route"],(function(e,t,n){var l,r,i Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let o=(l=(0,t.inject)("repository/permission"),r=class extends n.default{constructor(){var e,t,n,l super(...arguments),e=this,t="permissionsRepo",l=this,(n=i)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}async model(e){const t=await this.permissionsRepo.findAll({dc:e.dc,ns:this.optionalParams().nspace,partition:this.optionalParams().partition}) @@ -2779,7 +2789,11 @@ let b=(r=(0,n.inject)("data-source/service"),i=(0,n.inject)("repository/intentio try{let r=(await this.intentions).find((n=>n.Datacenter===e.Datacenter&&n.SourceName===e.Name&&n.SourceNS===e.Namespace&&n.SourcePartition===e.Partition&&n.DestinationName===t.Name&&n.DestinationNS===t.Namespace&&n.DestinationPartition===t.Partition)) void 0===r?r=this.repo.create({Datacenter:e.Datacenter,SourceName:e.Name,SourceNS:e.Namespace||"default",SourcePartition:e.Partition||"default",DestinationName:t.Name,DestinationNS:t.Namespace||"default",DestinationPartition:t.Partition||"default"}):n=this.feedback.notification("update","intention"),(0,l.set)(r,"Action","allow"),await this.repo.persist(r),n.success(r)}catch(r){n.error(r)}this.refresh()}afterModel(e,t){const n=p(p(p({},this.optionalParams()),this.paramsFor("dc")),this.paramsFor("dc.services.show")) this.intentions=this.data.source((e=>e`/${n.partition}/${n.nspace}/${n.dc}/intentions/for-service/${n.name}`))}async deactivate(e){(await this.intentions).destroy()}},u=h(a.prototype,"data",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),s=h(a.prototype,"repo",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),c=h(a.prototype,"feedback",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),h(a.prototype,"createIntention",[l.action],Object.getOwnPropertyDescriptor(a.prototype,"createIntention"),a.prototype),a) -e.default=b})),define("consul-ui/routing/route",["exports","@ember/routing/route","@ember/object","@ember/service","consul-ui/utils/path/resolve","consul-ui/router"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m,h,b +e.default=b})),define("consul-ui/routes/unavailable",["exports","consul-ui/routing/route","@ember/service"],(function(e,t,n){var l,r,i,o,a +function u(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function s(e,t,n,l,r){var i={} +return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +let c=(l=(0,n.inject)("env"),r=(0,n.inject)(),i=class extends t.default{constructor(){super(...arguments),u(this,"env",o,this),u(this,"router",a,this)}beforeModel(){this.env.var("CONSUL_V2_CATALOG_ENABLED")||this.router.replaceWith("index")}},o=s(i.prototype,"env",[l],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),a=s(i.prototype,"router",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),i) +e.default=c})),define("consul-ui/routing/route",["exports","@ember/routing/route","@ember/object","@ember/service","consul-ui/utils/path/resolve","consul-ui/router"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m,h,b function y(e,t){var n=Object.keys(e) if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e) t&&(l=l.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,l)}return n}function v(e){for(var t=1;te.ID,Name:e=>e.Name}})),define("consul-ui/search/predicates/auth-method",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default={ID:e=>e.ID,Name:e=>e.Name}})) +define("consul-ui/search/predicates/auth-method",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 e.default={Name:e=>e.Name,DisplayName:e=>e.DisplayName}})),define("consul-ui/search/predicates/health-check",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var t={Name:e=>e.Name,Node:e=>e.Node,Service:e=>e.ServiceName,CheckID:e=>e.CheckID||"",ID:e=>e.Service.ID||"",Notes:e=>e.Notes,Output:e=>e.Output,ServiceTags:e=>{return t=e.ServiceTags,Array.isArray(t)?t:t.toArray() var t}} e.default=t})),define("consul-ui/search/predicates/intention",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const t="All Services (*)" var n={SourceName:e=>[e.SourceName,"*"===e.SourceName?t:void 0].filter(Boolean),DestinationName:e=>[e.DestinationName,"*"===e.DestinationName?t:void 0].filter(Boolean)} -e.default=n})) -define("consul-ui/search/predicates/kv",["exports","consul-ui/utils/right-trim"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})),define("consul-ui/search/predicates/kv",["exports","consul-ui/utils/right-trim"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n={Key:e=>(0,t.default)(e.Key.toLowerCase()).split("/").filter((e=>Boolean(e))).pop()} e.default=n})),define("consul-ui/search/predicates/node",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var t={Node:e=>e.Node,Address:e=>e.Address,PeerName:e=>e.PeerName,Meta:e=>Object.entries(e.Meta||{}).reduce(((e,t)=>e.concat(t)),[])} @@ -2956,7 +2970,8 @@ if(void 0!==n){var l=n.call(e,t||"default") if("object"!=typeof l)return l throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string") return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -class r extends t.default{constructor(){super(...arguments),l(this,"primaryKey",n.PRIMARY_KEY),l(this,"slugKey",n.SLUG_KEY)}}e.default=r})),define("consul-ui/serializers/proxy",["exports","consul-ui/serializers/application","consul-ui/models/proxy"],(function(e,t,n){function l(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e +class r extends t.default{constructor(){super(...arguments),l(this,"primaryKey",n.PRIMARY_KEY),l(this,"slugKey",n.SLUG_KEY)}}e.default=r})) +define("consul-ui/serializers/proxy",["exports","consul-ui/serializers/application","consul-ui/models/proxy"],(function(e,t,n){function l(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e var n=e[Symbol.toPrimitive] if(void 0!==n){var l=n.call(e,t||"default") if("object"!=typeof l)return l @@ -2984,8 +2999,7 @@ break case"critical":e.ChecksCritical.push(t)}return e}),{ChecksPassing:[],ChecksWarning:[],ChecksCritical:[]}),o=r(r({},i),{},{Service:t,Checks:l,Node:{Datacenter:e.Datacenter,Namespace:e.Namespace,Partition:e.Partition,ID:e.ID,Node:e.Node,Address:e.Address,TaggedAddresses:e.TaggedAddresses,Meta:e.Meta}}) return o.uid=this.extractUid(o),o}respondForQuery(e,t){return super.respondForQuery((n=>e(((e,l)=>{if(0===l.length){const e=new Error throw e.errors=[{status:"404",title:"Not found"}],e}return l.forEach((e=>{e.Datacenter=t.dc,e.Namespace=t.ns||"default",e.Partition=t.partition||"default",e.uid=this.extractUid(e)})),n(e,l)}))),t)}respondForQueryRecord(e,t){return super.respondForQueryRecord((n=>e(((e,l)=>{if(l.forEach((e=>{e.Datacenter=t.dc,e.Namespace=t.ns||"default",e.Partition=t.partition||"default",e.uid=this.extractUid(e)})),void 0===(l=l.find((function(e){return e.Node.Node===t.node&&e.Service.ID===t.serviceId})))){const e=new Error -throw e.errors=[{status:"404",title:"Not found"}],e}return l.Namespace=l.Service.Namespace,l.Partition=l.Service.Partition,n(e,l)}))),t)}}e.default=o})) -define("consul-ui/serializers/service",["exports","consul-ui/serializers/application","consul-ui/models/service","@ember/object","consul-ui/utils/http/consul"],(function(e,t,n,l,r){function i(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e +throw e.errors=[{status:"404",title:"Not found"}],e}return l.Namespace=l.Service.Namespace,l.Partition=l.Service.Partition,n(e,l)}))),t)}}e.default=o})),define("consul-ui/serializers/service",["exports","consul-ui/serializers/application","consul-ui/models/service","@ember/object","consul-ui/utils/http/consul"],(function(e,t,n,l,r){function i(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e var n=e[Symbol.toPrimitive] if(void 0!==n){var l=n.call(e,t||"default") if("object"!=typeof l)return l @@ -3161,7 +3175,8 @@ let o=(l=(0,t.inject)("settings"),r=class extends t.default{constructor(){var e, super(...arguments),e=this,t="repo",l=this,(n=i)&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}source(e,t){const l=e.split(":").pop() return new n.StorageEventSource((e=>this.repo.findBySlug(l)),{key:e,uri:t.uri})}},a=r.prototype,u="repo",s=[l],c={configurable:!0,enumerable:!0,writable:!0,initializer:null},p={},Object.keys(c).forEach((function(e){p[e]=c[e]})),p.enumerable=!!p.enumerable,p.configurable=!!p.configurable,("value"in p||p.initializer)&&(p.writable=!0),p=s.slice().reverse().reduce((function(e,t){return t(a,u,e)||e}),p),d&&void 0!==p.initializer&&(p.value=p.initializer?p.initializer.call(d):void 0,p.initializer=void 0),void 0===p.initializer&&(Object.defineProperty(a,u,p),p=null),i=p,r) var a,u,s,c,d,p -e.default=o})),define("consul-ui/services/data-source/service",["exports","@ember/service","@ember/debug","consul-ui/utils/dom/event-source","@ember/runloop","mnemonist/multi-map"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m +e.default=o})) +define("consul-ui/services/data-source/service",["exports","@ember/service","@ember/debug","consul-ui/utils/dom/event-source","@ember/runloop","mnemonist/multi-map"],(function(e,t,n,l,r,i){var o,a,u,s,c,d,p,f,m function h(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function b(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let y=null,v=null,g=null @@ -3202,8 +3217,7 @@ let l=new IntersectionObserver(((e,t)=>{e.map((e=>{const t=y.get(e.target) "function"==typeof t&&t(e.isIntersecting)}))}),{rootMargin:"0px",threshold:n}) return l.observe(e),()=>{l.unobserve(e),y&&y.delete(e),l.disconnect(),l=null}}},O=p.prototype,P="doc",w=[d],x={configurable:!0,enumerable:!0,writable:!0,initializer:null},_={},Object.keys(x).forEach((function(e){_[e]=x[e]})),_.enumerable=!!_.enumerable,_.configurable=!!_.configurable,("value"in _||_.initializer)&&(_.writable=!0),_=w.slice().reverse().reduce((function(e,t){return t(O,P,e)||e}),_),j&&void 0!==_.initializer&&(_.value=_.initializer?_.initializer.call(j):void 0,_.initializer=void 0),void 0===_.initializer&&(Object.defineProperty(O,P,_),_=null),f=_,p) var O,P,w,x,j,_ -e.default=g})) -define("consul-ui/services/encoder",["exports","@ember/service","@ember/object","@ember/debug","consul-ui/utils/atob","consul-ui/utils/btoa"],(function(e,t,n,l,r,i){function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e +e.default=g})),define("consul-ui/services/encoder",["exports","@ember/service","@ember/object","@ember/debug","consul-ui/utils/atob","consul-ui/utils/btoa"],(function(e,t,n,l,r,i){function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e var n=e[Symbol.toPrimitive] if(void 0!==n){var l=n.call(e,t||"default") if("object"!=typeof l)return l @@ -3291,7 +3305,7 @@ throw e.errors=[{status:"403"}],e}}const l=await e(n.resources) return(0,r.get)(l,"Resources")&&(0,r.set)(l,"Resources",n.resources),l}shouldReconcile(e,t){if((0,r.get)(e,"Datacenter")!==t.dc)return!1 if(this.env.var("CONSUL_NSPACES_ENABLED")){const n=(0,r.get)(e,"Namespace") if(void 0!==n&&n!==t.ns)return!1}if(this.env.var("CONSUL_PARTITIONS_ENABLED")){const n=(0,r.get)(e,"Partition") -if(void 0!==n&&n!==t.partition)return!1}return!0}reconcile(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{} +if(void 0!==n&&n!==t.partition)return!1}return!this.env.var("CONSUL_PEERINGS_ENABLED")||"service"!==this.getModelName()}reconcile(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{} void 0!==e.date&&this.store.peekAll(this.getModelName()).forEach((n=>{const l=(0,r.get)(n,"SyncTime") !n.isDeleted&&void 0!==l&&l!=e.date&&this.shouldReconcile(n,t)&&this.store.unloadRecord(n)}))}peekOne(e){return this.store.peekRecord(this.getModelName(),e)}peekAll(){return this.store.peekAll(this.getModelName())}cached(e){const t=Object.entries(e) return this.store.peekAll(this.getModelName()).filter((e=>t.every((t=>{let[n,l]=t @@ -3439,7 +3453,8 @@ t.fetch=(e,t)=>this.client.fetchWithToken(`/v1/internal/ui/metrics-proxy${e}`,t) try{this.provider=window.consul.getMetricsProvider(n,t)}catch(l){this.error=new Error(`metrics provider not initialized: ${l}`),console.error(this.error)}}findServiceSummary(e){if(this.error)return Promise.reject(this.error) const t=[this.provider.serviceRecentSummarySeries(e.slug,e.dc,e.ns,e.protocol,{}),this.provider.serviceRecentSummaryStats(e.slug,e.dc,e.ns,e.protocol,{})] return Promise.all(t).then((e=>({meta:{interval:this.env.var("CONSUL_METRICS_POLL_INTERVAL")||1e4},series:e[0],stats:e[1].stats})))}findUpstreamSummary(e){return this.error?Promise.reject(this.error):this.provider.upstreamRecentSummaryStats(e.slug,e.dc,e.ns,{}).then((e=>(e.meta={interval:this.env.var("CONSUL_METRICS_POLL_INTERVAL")||1e4},e)))}findDownstreamSummary(e){return this.error?Promise.reject(this.error):this.provider.downstreamRecentSummaryStats(e.slug,e.dc,e.ns,{}).then((e=>(e.meta={interval:this.env.var("CONSUL_METRICS_POLL_INTERVAL")||1e4},e)))}},d=b(c.prototype,"config",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),p=b(c.prototype,"env",[i],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),f=b(c.prototype,"client",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),b(c.prototype,"findServiceSummary",[a],Object.getOwnPropertyDescriptor(c.prototype,"findServiceSummary"),c.prototype),b(c.prototype,"findUpstreamSummary",[u],Object.getOwnPropertyDescriptor(c.prototype,"findUpstreamSummary"),c.prototype),b(c.prototype,"findDownstreamSummary",[s],Object.getOwnPropertyDescriptor(c.prototype,"findDownstreamSummary"),c.prototype),c) -e.default=y})),define("consul-ui/services/repository/node",["exports","consul-ui/services/repository","consul-ui/decorators/data-source"],(function(e,t,n){var l,r,i,o +e.default=y})) +define("consul-ui/services/repository/node",["exports","consul-ui/services/repository","consul-ui/decorators/data-source"],(function(e,t,n){var l,r,i,o function a(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let u=(l=(0,n.default)("/:partition/:ns/:dc/nodes"),r=(0,n.default)("/:partition/:ns/:dc/node/:id/:peer"),i=(0,n.default)("/:partition/:ns/:dc/leader"),o=class extends t.default{getModelName(){return"node"}async findAllByDatacenter(){return super.findAllByDatacenter(...arguments)}async findBySlug(){return super.findBySlug(...arguments)}findLeader(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{} @@ -3465,8 +3480,7 @@ return this.store.logout(this.getModelName(),i)}close(){this.manager.close(b)}fi if(!0===e.message.startsWith("remote was closed"))t=new Error("Remote was closed"),t.statusCode=499 else t=new Error(e.message),t.statusCode=500 this.store.adapterFor(this.getModelName()).error(t)}))}},p=h(d.prototype,"manager",[o],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),f=h(d.prototype,"settings",[a],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),h(d.prototype,"findAllByDatacenter",[u],Object.getOwnPropertyDescriptor(d.prototype,"findAllByDatacenter"),d.prototype),h(d.prototype,"findBySlug",[s],Object.getOwnPropertyDescriptor(d.prototype,"findBySlug"),d.prototype),h(d.prototype,"authorize",[c],Object.getOwnPropertyDescriptor(d.prototype,"authorize"),d.prototype),d) -e.default=y})) -define("consul-ui/services/repository/partition",["exports","@ember/service","@ember/debug","consul-ui/services/repository","consul-ui/models/partition","consul-ui/decorators/data-source","consul-ui/utils/form/builder"],(function(e,t,n,l,r,i,o){var a,u,s,c,d,p,f,m,h +e.default=y})),define("consul-ui/services/repository/partition",["exports","@ember/service","@ember/debug","consul-ui/services/repository","consul-ui/models/partition","consul-ui/decorators/data-source","consul-ui/utils/form/builder"],(function(e,t,n,l,r,i,o){var a,u,s,c,d,p,f,m,h function b(e,t,n,l){n&&Object.defineProperty(e,t,{enumerable:n.enumerable,configurable:n.configurable,writable:n.writable,value:n.initializer?n.initializer.call(l):void 0})}function y(e,t,n,l,r){var i={} return Object.keys(l).forEach((function(e){i[e]=l[e]})),i.enumerable=!!i.enumerable,i.configurable=!!i.configurable,("value"in i||i.initializer)&&(i.writable=!0),i=n.slice().reverse().reduce((function(n,l){return l(e,t,n)||n}),i),r&&void 0!==i.initializer&&(i.value=i.initializer?i.initializer.call(r):void 0,i.initializer=void 0),void 0===i.initializer&&(Object.defineProperty(e,t,i),i=null),i}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 let v=(a=(0,t.inject)("settings"),u=(0,t.inject)("form"),s=(0,t.inject)("repository/permission"),c=(0,i.default)("/:partition/:ns/:dc/partitions"),d=(0,i.default)("/:partition/:ns/:dc/partition/:id"),p=class extends l.default{constructor(){super(...arguments),b(this,"settings",f,this),b(this,"form",m,this),b(this,"permissions",h,this)}getModelName(){return"partition"}getPrimaryKey(){return r.PRIMARY_KEY}getSlugKey(){return r.SLUG_KEY}async findAll(){return this.permissions.can("use partitions")?super.findAll(...arguments).catch((()=>[])):[]}async findBySlug(e){let t @@ -3708,7 +3722,8 @@ break case t.startsWith("_"):e.partition=t.substr(1) break case void 0===e.dc:e.dc=t}return e}),{})}async get(){return this.env.var("CONSUL_UI_CONFIG")}getSync(){return this.env.var("CONSUL_UI_CONFIG")}},s=c(u.prototype,"env",[r],{configurable:!0,enumerable:!0,writable:!0,initializer:null}),c(u.prototype,"findByPath",[i],Object.getOwnPropertyDescriptor(u.prototype,"findByPath"),u.prototype),c(u.prototype,"parsePath",[o],Object.getOwnPropertyDescriptor(u.prototype,"parsePath"),u.prototype),c(u.prototype,"get",[a],Object.getOwnPropertyDescriptor(u.prototype,"get"),u.prototype),u) -e.default=d})),define("consul-ui/sort/comparators/auth-method",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=d})) +define("consul-ui/sort/comparators/auth-method",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 e.default=e=>{let{properties:t}=e return function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"MethodName:asc" return t(["MethodName","TokenTTL"])(e)}}})),define("consul-ui/sort/comparators/health-check",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -3723,8 +3738,7 @@ case"critical":return"critical"===a?0:-1 case"warning":switch(a){case"passing":return-1 case"critical":return 1 default:return 0}}return 0}:t(["Name","Kind"])(e)}}})),define("consul-ui/sort/comparators/intention",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -e.default=()=>e=>[e]})) -define("consul-ui/sort/comparators/kv",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=()=>e=>[e]})),define("consul-ui/sort/comparators/kv",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 e.default=e=>{let{properties:t}=e return e=>t(["Key","Kind"])(e)}})),define("consul-ui/sort/comparators/node",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 e.default=e=>{let{properties:t}=e @@ -3892,7 +3906,7 @@ e.default=e=>e` } } `})),define("consul-ui/templates/application",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -var n=(0,t.createTemplateFactory)({id:"p3hjSYtO",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n\\n"],[1," "],[8,[30,1,["Announcer"]],null,[["@title"],["Consul"]],null],[1,"\\n"],[41,[28,[37,3],["use acls"],null],[[[1," "],[1,[28,[35,4],null,[["class"],["has-acls"]]]],[1,"\\n"]],[]],null],[41,[28,[37,3],["use nspaces"],null],[[[1," "],[1,[28,[35,4],null,[["class"],["has-nspaces"]]]],[1,"\\n"]],[]],null],[41,[28,[37,3],["use partitions"],null],[[[1," "],[1,[28,[35,4],null,[["class"],["has-partitions"]]]],[1,"\\n"]],[]],null],[1,"\\n"],[1," "],[8,[39,5],null,[["@src","@onchange"],[[28,[37,6],["settings://consul:client"],null],[28,[37,7],["onClientChanged"],null]]],null],[1,"\\n\\n"],[1," "],[8,[39,5],null,[["@src"],[[28,[37,6],["settings://consul:theme"],null]]],[["default"],[[[[1,"\\n"],[42,[28,[37,9],[[30,2,["data"]]],null],null,[[[41,[28,[37,10],[[30,3],[28,[37,11],[[30,4],[28,[37,12],["color-scheme","contrast"],null]],null]],null],[[[1," "],[1,[28,[35,4],null,[["class"],[[28,[37,13],["prefers-",[30,4],"-",[30,3]],null]]]]],[1,"\\n"]],[]],null]],[3,4]],null],[1," "]],[2]]]]],[1,"\\n\\n"],[41,[28,[37,3],["use acls"],null],[[[1," "],[8,[39,5],null,[["@src","@onchange"],[[28,[37,6],["settings://consul:token"],null],[28,[37,14],[[30,0],[28,[37,15],[[33,16]],null]],[["value"],["data"]]]]],null],[1,"\\n"]],[]],null],[1,"\\n"],[41,[28,[37,17],[[30,1,["currentName"]],"oauth-provider-debug"],null],[[[1,"\\n"],[41,[28,[37,18],[[30,1,["currentName"]],"index"],null],[[[1,"\\n"],[1," "],[1,[28,[35,19],[[28,[37,7],["replaceWith","dc.services.index",[28,[37,20],null,[["dc"],[[28,[37,21],["CONSUL_DATACENTER_LOCAL"],null]]]]],null]],null]],[1,"\\n"]],[]],[[[41,[28,[37,18],[[30,1,["currentName"]],"notfound"],null],[[[1," "],[8,[39,5],null,[["@src","@onchange"],[[28,[37,6],["/*/*/*/notfound/${path}",[28,[37,20],null,[["path"],[[30,1,["params","notfound"]]]]]],null],[28,[37,14],[[30,0],[28,[37,15],[[33,22]],null]],[["value"],["data"]]]]],null],[1,"\\n"]],[]],null],[1,"\\n"],[44,[[52,[28,[37,3],["use partitions"],null],[28,[37,24],[[30,1,["params","partition"]],[33,22,["partition"]],[33,16,["Partition"]],""],null],""],[52,[28,[37,3],["use nspaces"],null],[28,[37,24],[[30,1,["params","nspace"]],[33,22,["nspace"]],[33,16,["Namespace"]],""],null],""]],[[[1,"\\n"],[1," "],[8,[39,5],null,[["@src"],[[28,[37,6],["/*/*/*/datacenters"],null]]],[["default"],[[[[1,"\\n"],[44,[[28,[37,24],[[52,[33,25,["dc"]],[28,[37,26],[0,[28,[37,27],["dc",[28,[37,20],null,[["Name"],[[33,22,["dc"]]]]]],null]],null]],[28,[37,26],[0,[28,[37,27],["dc",[28,[37,20],null,[["Name"],[[30,1,["params","dc"]]]]]],null]],null],[28,[37,20],null,[["Name"],[[28,[37,21],["CONSUL_DATACENTER_LOCAL"],null]]]]],null],[30,7,["data"]]],[[[41,[28,[37,10],[[28,[37,28],[[30,8,["Name","length"]],0],null],[30,9]],null],[[[1,"\\n"],[1," "],[8,[39,5],null,[["@src"],[[28,[37,6],["/${partition}/*/${dc}/datacenter-cache/${name}",[28,[37,20],null,[["dc","partition","name"],[[30,8,["Name"]],[30,5],[30,8,["Name"]]]]]],null]]],[["default"],[[[[1,"\\n"],[41,[30,10,["data"]],[[[1," "],[8,[39,29],[[24,1,"wrapper"]],[["@dcs","@dc","@partition","@nspace","@user","@onchange"],[[30,9],[30,10,["data"]],[30,5],[30,6],[28,[37,20],null,[["token"],[[33,16]]]],[28,[37,14],[[30,0],"reauthorize"],null]]],[["default"],[[[[1,"\\n\\n"],[41,[33,30],[[[1," "],[8,[39,31],null,[["@error","@login"],[[99,30,["@error"]],[30,11,["login","open"]]]],null],[1,"\\n"]],[]],[[[1," "],[8,[39,32],null,[["@name","@model"],["application",[28,[37,20],null,[["app","user","dc","dcs"],[[30,11],[28,[37,20],null,[["token"],[[33,16]]]],[30,10,["data"]],[30,9]]]]]],[["default"],[[[[1,"\\n "],[46,[28,[37,34],null,null],null,null,null],[1,"\\n "]],[12]]]]],[1,"\\n\\n"],[1," "],[8,[39,35],[[24,0,"view-loader"]],null,null],[1,"\\n"]],[]]],[1,"\\n "]],[11]]]]],[1,"\\n"]],[]],null],[1," "]],[10]]]]],[1,"\\n"]],[]],null]],[8,9]]],[1," "]],[7]]]]],[1,"\\n"]],[5,6]]]],[]]]],[]],[[[1," "],[8,[39,32],null,[["@name","@model"],["application",[28,[37,20],null,[["user"],[[28,[37,20],null,[["token"],[[33,16]]]]]]]]],[["default"],[[[[1,"\\n "],[46,[28,[37,34],null,null],null,null,null],[1,"\\n "]],[13]]]]],[1,"\\n"]],[]]]],[1]]]]],[1,"\\n"]],["route","source","value","key","partition","nspace","dcs","dc","dcs","dc","consul","o","o"],false,["route","routeName","if","can","document-attrs","data-source","uri","route-action","each","-each-in","and","includes","array","concat","action","mut","token","not-eq","eq","did-insert","hash","env","notfound","let","or","nofound","object-at","cached-model","gt","hashicorp-consul","error","app-error","outlet","component","-outlet","consul/loader"]]',moduleName:"consul-ui/templates/application.hbs",isStrictMode:!1}) +var n=(0,t.createTemplateFactory)({id:"Srw5qTey",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n\\n"],[1," "],[8,[30,1,["Announcer"]],null,[["@title"],["Consul"]],null],[1,"\\n\\n"],[41,[51,[28,[37,3],["CONSUL_V2_CATALOG_ENABLED"],null]],[[[41,[28,[37,5],["use acls"],null],[[[1," "],[1,[28,[35,6],null,[["class"],["has-acls"]]]],[1,"\\n"]],[]],null],[41,[28,[37,5],["use nspaces"],null],[[[1," "],[1,[28,[35,6],null,[["class"],["has-nspaces"]]]],[1,"\\n"]],[]],null],[41,[28,[37,5],["use partitions"],null],[[[1," "],[1,[28,[35,6],null,[["class"],["has-partitions"]]]],[1,"\\n"]],[]],null],[1,"\\n"],[1," "],[8,[39,7],null,[["@src","@onchange"],[[28,[37,8],["settings://consul:client"],null],[28,[37,9],["onClientChanged"],null]]],null],[1,"\\n\\n"],[1," "],[8,[39,7],null,[["@src"],[[28,[37,8],["settings://consul:theme"],null]]],[["default"],[[[[1,"\\n"],[42,[28,[37,11],[[30,2,["data"]]],null],null,[[[41,[28,[37,12],[[30,3],[28,[37,13],[[30,4],[28,[37,14],["color-scheme","contrast"],null]],null]],null],[[[1," "],[1,[28,[35,6],null,[["class"],[[28,[37,15],["prefers-",[30,4],"-",[30,3]],null]]]]],[1,"\\n"]],[]],null]],[3,4]],null],[1," "]],[2]]]]],[1,"\\n\\n"],[41,[28,[37,5],["use acls"],null],[[[1," "],[8,[39,7],null,[["@src","@onchange"],[[28,[37,8],["settings://consul:token"],null],[28,[37,16],[[30,0],[28,[37,17],[[33,18]],null]],[["value"],["data"]]]]],null],[1,"\\n"]],[]],null]],[]],null],[1,"\\n"],[41,[28,[37,12],[[28,[37,19],[[28,[37,3],["CONSUL_V2_CATALOG_ENABLED"],null]],null],[28,[37,20],[[30,1,["currentName"]],"oauth-provider-debug"],null]],null],[[[1,"\\n"],[41,[28,[37,21],[[30,1,["currentName"]],"index"],null],[[[1,"\\n"],[1," "],[1,[28,[35,22],[[28,[37,9],["replaceWith","dc.services.index",[28,[37,23],null,[["dc"],[[28,[37,3],["CONSUL_DATACENTER_LOCAL"],null]]]]],null]],null]],[1,"\\n"]],[]],[[[41,[28,[37,21],[[30,1,["currentName"]],"notfound"],null],[[[1," "],[8,[39,7],null,[["@src","@onchange"],[[28,[37,8],["/*/*/*/notfound/${path}",[28,[37,23],null,[["path"],[[30,1,["params","notfound"]]]]]],null],[28,[37,16],[[30,0],[28,[37,17],[[33,24]],null]],[["value"],["data"]]]]],null],[1,"\\n"]],[]],null],[1,"\\n"],[44,[[52,[28,[37,5],["use partitions"],null],[28,[37,26],[[30,1,["params","partition"]],[33,24,["partition"]],[33,18,["Partition"]],""],null],""],[52,[28,[37,5],["use nspaces"],null],[28,[37,26],[[30,1,["params","nspace"]],[33,24,["nspace"]],[33,18,["Namespace"]],""],null],""]],[[[1,"\\n"],[1," "],[8,[39,7],null,[["@src"],[[28,[37,8],["/*/*/*/datacenters"],null]]],[["default"],[[[[1,"\\n"],[44,[[28,[37,26],[[52,[33,27,["dc"]],[28,[37,28],[0,[28,[37,29],["dc",[28,[37,23],null,[["Name"],[[33,24,["dc"]]]]]],null]],null]],[28,[37,28],[0,[28,[37,29],["dc",[28,[37,23],null,[["Name"],[[30,1,["params","dc"]]]]]],null]],null],[28,[37,23],null,[["Name"],[[28,[37,3],["CONSUL_DATACENTER_LOCAL"],null]]]]],null],[30,7,["data"]]],[[[41,[28,[37,12],[[28,[37,30],[[30,8,["Name","length"]],0],null],[30,9]],null],[[[1,"\\n"],[1," "],[8,[39,7],null,[["@src"],[[28,[37,8],["/${partition}/*/${dc}/datacenter-cache/${name}",[28,[37,23],null,[["dc","partition","name"],[[30,8,["Name"]],[30,5],[30,8,["Name"]]]]]],null]]],[["default"],[[[[1,"\\n"],[41,[30,10,["data"]],[[[1," "],[8,[39,31],[[24,1,"wrapper"]],[["@dcs","@dc","@partition","@nspace","@user","@onchange"],[[30,9],[30,10,["data"]],[30,5],[30,6],[28,[37,23],null,[["token"],[[33,18]]]],[28,[37,16],[[30,0],"reauthorize"],null]]],[["default"],[[[[1,"\\n\\n"],[41,[33,32],[[[1," "],[8,[39,33],null,[["@error","@login"],[[99,32,["@error"]],[30,11,["login","open"]]]],null],[1,"\\n"]],[]],[[[1," "],[8,[39,34],null,[["@name","@model"],["application",[28,[37,23],null,[["app","user","dc","dcs"],[[30,11],[28,[37,23],null,[["token"],[[33,18]]]],[30,10,["data"]],[30,9]]]]]],[["default"],[[[[1,"\\n "],[46,[28,[37,36],null,null],null,null,null],[1,"\\n "]],[12]]]]],[1,"\\n\\n"],[1," "],[8,[39,37],[[24,0,"view-loader"]],null,null],[1,"\\n"]],[]]],[1,"\\n "]],[11]]]]],[1,"\\n"]],[]],null],[1," "]],[10]]]]],[1,"\\n"]],[]],null]],[8,9]]],[1," "]],[7]]]]],[1,"\\n"]],[5,6]]]],[]]]],[]],[[[1," "],[8,[39,34],null,[["@name","@model"],["application",[28,[37,23],null,[["user"],[[28,[37,23],null,[["token"],[[33,18]]]]]]]]],[["default"],[[[[1,"\\n "],[46,[28,[37,36],null,null],null,null,null],[1,"\\n "]],[13]]]]],[1,"\\n"]],[]]]],[1]]]]]],["route","source","value","key","partition","nspace","dcs","dc","dcs","dc","consul","o","o"],false,["route","routeName","unless","env","if","can","document-attrs","data-source","uri","route-action","each","-each-in","and","includes","array","concat","action","mut","token","not","not-eq","eq","did-insert","hash","notfound","let","or","nofound","object-at","cached-model","gt","hashicorp-consul","error","app-error","outlet","component","-outlet","consul/loader"]]',moduleName:"consul-ui/templates/application.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/components/basic-dropdown-content",["exports","ember-basic-dropdown/templates/components/basic-dropdown-content"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/templates/components/basic-dropdown-optional-tag",["exports","ember-basic-dropdown/templates/components/basic-dropdown-optional-tag"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/templates/components/basic-dropdown-trigger",["exports","ember-basic-dropdown/templates/components/basic-dropdown-trigger"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/templates/components/basic-dropdown",["exports","ember-basic-dropdown/templates/components/basic-dropdown"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})),define("consul-ui/templates/dc",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"ex21k2WB",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@name","@model"],[[99,1,["@name"]],[30,1,["model"]]]],[["default"],[[[[1,"\\n "],[46,[28,[37,4],null,null],null,null,null],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","o"],false,["route","routeName","outlet","component","-outlet"]]',moduleName:"consul-ui/templates/dc.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -3907,17 +3921,17 @@ e.default=n})),define("consul-ui/templates/dc/acls/auth-methods/show/binding-rul var n=(0,t.createTemplateFactory)({id:"lp1F+P1r",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/binding-rules/for-auth-method/${name}",[28,[37,4],null,[["partition","nspace","dc","name"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["params","id"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[30,2,["data"]]],[[[1,"\\n "],[10,0],[14,0,"tab-section"],[12],[1,"\\n"],[41,[28,[37,9],[[30,3,["length"]],0],null],[[[1," "],[10,2],[12],[1,"\\n Binding rules allow an operator to express a systematic way of automatically linking roles and service identities to newly created tokens without operator intervention.\\n "],[13],[1,"\\n "],[10,2],[12],[1,"\\n Successful authentication with an auth method returns a set of trusted identity attributes corresponding to the authenticated identity. Those attributes are matched against all configured binding rules for that auth method to determine what privileges to grant the Consul ACL token it will ultimately create.\\n "],[13],[1,"\\n "],[10,"hr"],[12],[13],[1,"\\n"],[42,[28,[37,11],[[28,[37,11],[[30,3]],null]],null],null,[[[1," "],[8,[39,12],null,[["@item"],[[30,4]]],null],[1,"\\n "],[10,"hr"],[12],[13],[1,"\\n"]],[4]],null]],[]],[[[1," "],[8,[39,13],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,14],["routes.dc.acls.auth-methods.show.binding-rules.index.empty.header"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,14],["routes.dc.acls.auth-methods.show.binding-rules.index.empty.body"],[["htmlSafe"],[true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[14,0,"docs-link"],[12],[1,"\\n "],[10,3],[15,6,[29,[[28,[37,15],["CONSUL_DOCS_API_URL"],null],"/acl/binding-rules"]]],[14,"rel","noopener noreferrer"],[14,"target","_blank"],[12],[1,"Read the documentation"],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n"]],[3]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","loader","items","item"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","if","gt","each","-track-array","consul/auth-method/binding-list","empty-state","t","env"]]',moduleName:"consul-ui/templates/dc/acls/auth-methods/show/binding-rules.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls/auth-methods/show/nspace-rules",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"B9VyTw0K",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n"],[44,[[30,1,["model","item"]]],[[[1," "],[10,0],[14,0,"tab-section"],[12],[1,"\\n"],[41,[28,[37,4],[[30,2,["NamespaceRules","length"]],0],null],[[[1," "],[10,2],[12],[1,"\\n A set of rules that can control which namespace tokens created via this auth method will be created within. Unlike binding rules, the first matching namespace rule wins.\\n "],[13],[1,"\\n "],[8,[39,5],null,[["@items"],[[30,2,["NamespaceRules"]]]],null],[1,"\\n"]],[]],[[[1," "],[8,[39,6],null,null,[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,8],[[28,[37,9],[[30,1,["t"]],"empty.header"],null]],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,8],[[28,[37,9],[[30,1,["t"]],"empty.body",[28,[37,10],null,[["htmlSafe"],[true]]]],null]],null]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[14,0,"docs-link"],[12],[1,"\\n "],[10,3],[15,6,[29,[[28,[37,11],["CONSUL_DOCS_API_URL"],null],"/acl/auth-methods#namespacerules"]]],[14,"rel","noopener noreferrer"],[14,"target","_blank"],[12],[1,"Read the documentation"],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n"]],[2]]]],[1]]]]],[1,"\\n"]],["route","item"],false,["route","routeName","let","if","gt","consul/auth-method/nspace-list","empty-state","block-slot","compute","fn","hash","env"]]',moduleName:"consul-ui/templates/dc/acls/auth-methods/show/nspace-rules.hbs",isStrictMode:!1}) -e.default=n})),define("consul-ui/templates/dc/acls/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})) +define("consul-ui/templates/dc/acls/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"u49Giiy6",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[28,[37,3],["replaceWith","dc.acls.tokens"],null]],null]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route"],false,["route","routeName","did-insert","route-action"]]',moduleName:"consul-ui/templates/dc/acls/index.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls/policies/-form",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"HeHpiPG6",block:'[[[1,"\\n"],[10,"form"],[12],[1,"\\n "],[8,[39,0],null,[["@form","@partition","@nspace","@item"],[[99,1,["@form"]],[99,2,["@partition"]],[99,3,["@nspace"]],[99,4,["@item"]]]],[["default"],[[[[1,"\\n"],[1," "],[8,[39,5],null,[["@name"],["template"]],null],[1,"\\n "]],[]]]]],[1,"\\n"],[41,[28,[37,7],[[33,8]],null],[[[1," "],[8,[39,9],null,[["@src","@onchange"],[[28,[37,10],["/${partition}/${nspace}/${dc}/tokens/for-policy/${id}",[28,[37,11],null,[["partition","nspace","dc","id"],[[33,2],[33,3],[33,12],[28,[37,13],[[33,14],""],null]]]]],null],[28,[37,15],[[30,0],[28,[37,16],[[33,17]],null]],[["value"],["data"]]]]],null],[1,"\\n"],[41,[28,[37,18],[[33,17,["length"]],0],null],[[[1," "],[8,[39,19],null,[["@caption","@items"],["Applied to the following tokens:",[99,17,["@items"]]]],null],[1,"\\n"]],[]],null]],[]],null],[1," "],[10,0],[12],[1,"\\n "],[8,[39,20],null,null,[["default"],[[[[1,"\\n"],[41,[28,[37,21],[[33,8],[28,[37,22],["create tokens"],null]],null],[[[1," "],[8,[39,23],[[16,"disabled",[52,[28,[37,13],[[33,4,["isPristine"]],[33,4,["isInvalid"]],[28,[37,24],[[33,4,["Name"]],""],null]],null],"disabled"]],[24,4,"submit"],[4,[38,25],["click",[28,[37,26],["create",[33,4]],null]],null]],[["@text"],["Save"]],null],[1,"\\n"]],[]],[[[41,[28,[37,22],["write policy"],[["item"],[[33,4]]]],[[[1," "],[8,[39,23],[[16,"disabled",[52,[33,4,["isInvalid"]],"disabled"]],[24,4,"submit"],[4,[38,25],["click",[28,[37,26],["update",[33,4]],null]],null]],[["@text"],["Save"]],null],[1,"\\n"]],[]],null]],[]]],[1," "],[8,[39,23],[[24,4,"reset"],[4,[38,15],[[30,0],"cancel",[33,4]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n"],[41,[28,[37,21],[[28,[37,7],[[33,8]],null],[28,[37,22],["delete policy"],[["item"],[[33,4]]]]],null],[[[1," "],[8,[39,27],null,[["@message"],["Are you sure you want to delete this Policy?"]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["action"]],[["default"],[[[[1,"\\n "],[8,[39,23],[[4,[38,15],[[30,0],[30,1],"delete",[33,4]],null]],[["@text","@color"],["Delete","critical"]],null],[1,"\\n "]],[1]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["dialog"]],[["default"],[[[[1,"\\n"],[41,[28,[37,18],[[33,17,["length"]],0],null],[[[1," "],[8,[39,28],null,[["@onclose","@open","@aria"],[[28,[37,15],[[30,0],[30,3]],null],true,[28,[37,11],null,[["label"],["Policy in Use"]]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"Policy in Use"],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[10,2],[12],[1,"\\n This Policy is currently in use. If you choose to delete this Policy, it will be removed from the\\n following "],[10,"strong"],[12],[1,[33,17,["length"]]],[1," Tokens"],[13],[1,":\\n "],[13],[1,"\\n "],[8,[39,19],null,[["@items","@target"],[[99,17,["@items"]],"_blank"]],null],[1,"\\n "],[10,2],[12],[1,"\\n This action cannot be undone. "],[1,[30,4]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[39,20],null,null,[["default"],[[[[1,"\\n "],[8,[39,23],[[4,[38,15],[[30,0],[30,2]],null]],[["@text","@color"],["Yes, Delete","critical"]],null],[1,"\\n "],[8,[39,23],[[4,[38,15],[[30,0],[30,5]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n "]],[]]]]],[1,"\\n "]],[5]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],[[[1," "],[8,[39,29],null,[["@message","@execute","@cancel"],[[30,4],[30,2],[30,3]]],null],[1,"\\n"]],[]]],[1," "]],[2,3,4]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[13],[1,"\\n"],[13],[1,"\\n"]],["confirm","execute","cancel","message","close"],false,["policy-form","form","partition","nspace","item","block-slot","if","not","create","data-source","uri","hash","dc","or","id","action","mut","items","gt","token-list","hds/button-set","and","can","hds/button","eq","on","route-action","confirmation-dialog","modal-dialog","delete-confirmation"]]',moduleName:"consul-ui/templates/dc/acls/policies/-form.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls/policies/edit",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"ZeBYu7Wq",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/policy/${id}",[28,[37,4],null,[["partition","nspace","dc","id"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[28,[37,5],[[30,1,["params","id"]],""],null]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,6],null,[["@name"],["error"]],[["default"],[[[[1,"\\n"],[41,[28,[37,8],[[30,2,["error","status"]],"401"],null],[[[1," "],[8,[39,9],null,null,null],[1,"\\n"]],[]],[[[1," "],[8,[39,10],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n"]],[]]],[1," "]],[]]]]],[1,"\\n\\n "],[8,[39,6],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[30,1,["params","dc"]],[30,1,["params","partition"]],[30,1,["params","nspace"]],[28,[37,5],[[30,1,["params","id"]],""],null],[30,2,["data"]],[30,2,["data","isNew"]]],[[[1," "],[8,[39,12],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["breadcrumbs"]],[["default"],[[[[1,"\\n "],[10,"ol"],[12],[1,"\\n "],[10,"li"],[12],[10,3],[15,6,[28,[37,13],["dc.acls.policies"],null]],[12],[1,"All Policies"],[13],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n"],[41,[30,8],[[[1," "],[8,[30,1,["Title"]],null,[["@title"],["New Policy"]],null],[1,"\\n"]],[]],[[[41,[28,[37,14],["write policy"],[["item"],[[30,7]]]],[[[1," "],[8,[30,1,["Title"]],null,[["@title"],["Edit Policy"]],null],[1,"\\n"]],[]],[[[1," "],[8,[30,1,["Title"]],null,[["@title"],["View Policy"]],null],[1,"\\n"]],[]]]],[]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["content"]],[["default"],[[[[1,"\\n"],[41,[28,[37,15],[[30,8]],null],[[[1," "],[10,0],[14,0,"definition-table"],[12],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Policy ID"],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[8,[39,16],null,[["@value","@name"],[[30,7,["ID"]],"Policy ID"]],null],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null],[41,[28,[37,5],[[28,[37,8],[[28,[37,17],[[30,7]],null],"policy-management"],null],[28,[37,8],[[28,[37,17],[[30,7]],null],"read-only"],null]],null],[[[1," "],[8,[39,18],[[24,0,"mb-3 mt-2"]],[["@type","@icon"],["inline","star-fill"]],[["default"],[[[[1,"\\n "],[8,[30,9,["Title"]],null,null,[["default"],[[[[1,"Built-in policy"]],[]]]]],[1,"\\n "],[8,[30,9,["Description"]],null,null,[["default"],[[[[1,"This policy is built into Consul\'s ACL system. You can use this special policy by adding it to a token. This policy is not editable or removable, but can be ignored by not applying it to any tokens.\\n "]],[]]]]],[1,"\\n "],[8,[30,9,["Link::Standalone"]],null,[["@text","@href","@icon","@iconPosition"],["Learn more",[29,[[28,[37,19],["CONSUL_DOCS_URL"],null],"/guides/acl.html#builtin-policies"]],"docs-link","trailing"]],null],[1,"\\n "]],[9]]]]],[1,"\\n "],[10,0],[14,0,"definition-table"],[12],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Name"],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,7,["Name"]]],[13],[1,"\\n "],[10,"dt"],[12],[1,"Valid Datacenters"],[13],[1,"\\n "],[10,"dd"],[12],[1,[28,[35,20],[", ",[28,[37,21],[[30,7]],null]],null]],[13],[1,"\\n "],[10,"dt"],[12],[1,"Description"],[13],[1,"\\n "],[10,"dd"],[12],[1,[30,7,["Description"]]],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[8,[39,22],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/tokens/for-policy/${id}",[28,[37,4],null,[["partition","nspace","dc","id"],[[30,4],[30,5],[30,3],[30,6]]]]],null]]],[["default"],[[[[1,"\\n"],[41,[28,[37,23],[[30,10,["data","length"]],0],null],[[[1," "],[8,[39,24],null,[["@caption","@items"],["Applied to the following tokens:",[30,10,["data"]]]],null],[1,"\\n"]],[]],null],[1," "]],[10]]]]],[1,"\\n"]],[]],[[[1," "],[19,"dc/acls/policies/form",[1,2,3,4,5,6,7,8]],[1,"\\n"]],[]]],[1," "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[3,4,5,6,7,8]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","loader","dc","partition","nspace","id","item","create","A","loader"],true,["route","routeName","data-loader","uri","hash","or","block-slot","if","eq","consul/acl/disabled","app-error","let","app-view","href-to","can","not","copyable-code","policy/typeof","hds/alert","env","join","policy/datacenters","data-source","gt","token-list","partial"]]',moduleName:"consul-ui/templates/dc/acls/policies/edit.hbs",isStrictMode:!1}) -e.default=n})) -define("consul-ui/templates/dc/acls/policies/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})),define("consul-ui/templates/dc/acls/policies/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"fHN/RQtj",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/policies",[28,[37,4],null,[["partition","nspace","dc"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n"],[41,[28,[37,7],[[30,2,["error","status"]],"401"],null],[[[1," "],[8,[39,8],null,null,null],[1,"\\n"]],[]],[[[1," "],[8,[39,9],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n"]],[]]],[1," "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[28,[37,4],null,[["value","change"],[[28,[37,11],[[33,12],"Name:asc"],null],[28,[37,13],[[30,0],[28,[37,14],[[33,12]],null]],[["value"],["target.selected"]]]]]],[28,[37,4],null,[["kind","datacenter","searchproperty"],[[28,[37,4],null,[["value","change"],[[52,[33,15],[28,[37,16],[[33,15],","],null],[27]],[28,[37,13],[[30,0],[28,[37,14],[[33,15]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,17],[28,[37,16],[[33,17],","],null],[27]],[28,[37,13],[[30,0],[28,[37,14],[[33,17]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change","default"],[[52,[28,[37,18],[[33,19],[27]],null],[28,[37,16],[[33,19],","],null],[33,20]],[28,[37,13],[[30,0],[28,[37,14],[[33,19]],null]],[["value"],["target.selectedItems"]]],[33,20]]]]]]],[30,2,["data"]]],[[[1," "],[8,[39,21],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],["Policies"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n"],[41,[28,[37,22],["create policies"],null],[[[1," "],[8,[39,23],null,[["@text","@route"],["Create","dc.acls.policies.create"]],null],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["toolbar"]],[["default"],[[[[1,"\\n"],[41,[28,[37,24],[[30,5,["length"]],0],null],[[[1," "],[8,[39,25],null,[["@partition","@search","@onsearch","@sort","@filter"],[[30,1,["params","partition"]],[99,26,["@search"]],[28,[37,13],[[30,0],[28,[37,14],[[33,26]],null]],[["value"],["target.value"]]],[30,3],[30,4]]],null],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@type","@sort","@filters","@search","@items"],["policy",[30,3,["value"]],[30,4],[99,26,["@search"]],[30,5]]],[["default"],[[[[1,"\\n "],[8,[30,6,["Collection"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,28],null,[["@items","@ondelete"],[[30,6,["items"]],[28,[37,29],["delete"],null]]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,6,["Empty"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,30],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,31],["routes.dc.acls.policies.index.empty.header"],[["items"],[[30,5,["length"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,31],["routes.dc.acls.policies.index.empty.body"],[["items","htmlSafe"],[[30,5,["length"]],true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,32],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on policies",[29,[[28,[37,33],["CONSUL_DOCS_URL"],null],"/commands/acl/policy"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,32],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,33],["CONSUL_LEARN_URL"],null],"/consul/security-networking/managing-acl-policies"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n\\n"]],[3,4,5]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","loader","sort","filters","items","collection"],false,["route","routeName","data-loader","uri","hash","block-slot","if","eq","consul/acl/disabled","app-error","let","or","sortBy","action","mut","kind","split","datacenter","not-eq","searchproperty","searchProperties","app-view","can","hds/button","gt","consul/policy/search-bar","search","data-collection","consul/policy/list","route-action","empty-state","t","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/acls/policies/index.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls/roles/-form",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -var n=(0,t.createTemplateFactory)({id:"xSvLYGJe",block:'[[[1,"\\n"],[10,"form"],[12],[1,"\\n "],[8,[39,0],null,[["@form","@item","@dc","@nspace","@partition"],[[99,1,["@form"]],[99,2,["@item"]],[99,3,["@dc"]],[99,4,["@nspace"]],[99,5,["@partition"]]]],null],[1,"\\n"],[41,[28,[37,7],[[33,8]],null],[[[1," "],[8,[39,9],null,[["@src"],[[28,[37,10],["/${partition}/${nspace}/${dc}/tokens/for-role/${id}",[28,[37,11],null,[["partition","nspace","dc","id"],[[33,5],[33,4],[33,3],[28,[37,12],[[33,13],""],null]]]]],null]]],[["default"],[[[[1,"\\n"],[41,[28,[37,14],[[30,1,["data","length"]],0],null],[[[1," "],[10,"h2"],[12],[1,"Where is this role used?"],[13],[1,"\\n "],[10,2],[12],[1,"\\n We\'re only able to show information for the primary datacenter and the current datacenter. This list may not\\n show every case where this role is applied.\\n "],[13],[1,"\\n "],[8,[39,15],null,[["@caption","@items"],["Tokens",[30,1,["data"]]]],null],[1,"\\n"]],[]],null],[1," "]],[1]]]]],[1,"\\n"]],[]],null],[1," "],[10,0],[12],[1,"\\n "],[8,[39,16],null,null,[["default"],[[[[1,"\\n"],[41,[28,[37,17],[[33,8],[28,[37,18],["create roles"],null]],null],[[[1," "],[8,[39,19],[[16,"disabled",[28,[37,12],[[33,2,["isPristine"]],[33,2,["isInvalid"]],[28,[37,20],[[33,2,["Name"]],""],null]],null]],[24,4,"submit"],[4,[38,21],["click",[28,[37,22],["create",[33,2]],null]],null]],[["@text"],["Save"]],null],[1,"\\n"]],[]],[[[41,[28,[37,18],["write role"],[["item"],[[33,2]]]],[[[1," "],[8,[39,19],[[16,"disabled",[33,2,["isInvalid"]]],[24,4,"submit"],[4,[38,21],["click",[28,[37,22],["update",[33,2]],null]],null]],[["@text"],["Save"]],null],[1,"\\n"]],[]],null]],[]]],[1," "],[8,[39,19],[[24,4,"reset"],[4,[38,23],[[30,0],"cancel",[33,2]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n\\n"],[41,[28,[37,17],[[28,[37,7],[[33,8]],null],[28,[37,18],["delete role"],[["item"],[[33,2]]]]],null],[[[1," "],[8,[39,24],null,[["@message"],["Are you sure you want to delete this Role?"]],[["default"],[[[[1,"\\n "],[8,[39,25],null,[["@name"],["action"]],[["default"],[[[[1,"\\n "],[8,[39,19],[[4,[38,23],[[30,0],[30,2],"delete",[33,2]],null]],[["@text","@color"],["Delete","critical"]],null],[1,"\\n "]],[2]]]]],[1,"\\n "],[8,[39,25],null,[["@name"],["dialog"]],[["default"],[[[[1,"\\n"],[41,[28,[37,14],[[33,26,["length"]],0],null],[[[1," "],[8,[39,27],null,[["@onclose","@aria"],[[28,[37,23],[[30,0],[30,4]],null],[28,[37,11],null,[["label"],["Role in Use"]]]]],[["default"],[[[[1,"\\n "],[8,[39,25],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"Role in Use"],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,25],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[10,2],[12],[1,"\\n This Role is currently in use. If you choose to delete this Role, it will be removed from the\\n following "],[10,"strong"],[12],[1,[33,26,["length"]]],[1," Tokens"],[13],[1,":\\n "],[13],[1,"\\n "],[8,[39,15],null,[["@items","@target"],[[99,26,["@items"]],"_blank"]],null],[1,"\\n "],[10,2],[12],[1,"\\n This action cannot be undone. "],[1,[30,5]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,25],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[39,16],null,null,[["default"],[[[[1,"\\n "],[8,[39,19],[[4,[38,23],[[30,0],[30,3]],null]],[["@text","@color"],["Yes, Delete","critical"]],null],[1,"\\n "],[8,[39,19],[[4,[38,23],[[30,0],[30,6]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],[[[1," "],[8,[39,28],null,[["@message","@execute","@cancel"],[[30,5],[30,3],[30,4]]],null],[1,"\\n"]],[]]],[1," "]],[3,4,5]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[13],[1,"\\n"],[13],[1,"\\n"]],["loader","confirm","execute","cancel","message","close"],false,["role-form","form","item","dc","nspace","partition","if","not","create","data-source","uri","hash","or","id","gt","token-list","hds/button-set","and","can","hds/button","eq","on","route-action","action","confirmation-dialog","block-slot","items","modal-dialog","delete-confirmation"]]',moduleName:"consul-ui/templates/dc/acls/roles/-form.hbs",isStrictMode:!1}) +var n=(0,t.createTemplateFactory)({id:"6qtq9TRB",block:'[[[1,"\\n"],[10,"form"],[12],[1,"\\n "],[8,[39,0],null,[["@form","@item","@dc","@nspace","@partition"],[[99,1,["@form"]],[99,2,["@item"]],[99,3,["@dc"]],[99,4,["@nspace"]],[99,5,["@partition"]]]],null],[1,"\\n"],[41,[28,[37,7],[[33,8]],null],[[[1," "],[8,[39,9],null,[["@src"],[[28,[37,10],["/${partition}/${nspace}/${dc}/tokens/for-role/${id}",[28,[37,11],null,[["partition","nspace","dc","id"],[[33,5],[33,4],[33,3],[52,[33,2],[33,2,["ID"]],""]]]]],null]]],[["default"],[[[[1,"\\n"],[41,[28,[37,12],[[30,1,["data","length"]],0],null],[[[1," "],[10,"h2"],[12],[1,"Where is this role used?"],[13],[1,"\\n "],[10,2],[12],[1,"\\n We\'re only able to show information for the primary datacenter and the current datacenter. This list may not\\n show every case where this role is applied.\\n "],[13],[1,"\\n "],[8,[39,13],null,[["@caption","@items"],["Tokens",[30,1,["data"]]]],null],[1,"\\n"]],[]],null],[1," "]],[1]]]]],[1,"\\n"]],[]],null],[1," "],[10,0],[12],[1,"\\n "],[8,[39,14],null,null,[["default"],[[[[1,"\\n"],[41,[28,[37,15],[[33,8],[28,[37,16],["create roles"],null]],null],[[[1," "],[8,[39,17],[[16,"disabled",[28,[37,18],[[33,2,["isPristine"]],[33,2,["isInvalid"]],[28,[37,19],[[33,2,["Name"]],""],null]],null]],[24,4,"submit"],[4,[38,20],["click",[28,[37,21],["create",[33,2]],null]],null]],[["@text"],["Save"]],null],[1,"\\n"]],[]],[[[41,[28,[37,16],["write role"],[["item"],[[33,2]]]],[[[1," "],[8,[39,17],[[16,"disabled",[33,2,["isInvalid"]]],[24,4,"submit"],[4,[38,20],["click",[28,[37,21],["update",[33,2]],null]],null]],[["@text"],["Save"]],null],[1,"\\n"]],[]],null]],[]]],[1," "],[8,[39,17],[[24,4,"reset"],[4,[38,22],[[30,0],"cancel",[33,2]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n\\n"],[41,[28,[37,15],[[28,[37,7],[[33,8]],null],[28,[37,16],["delete role"],[["item"],[[33,2]]]]],null],[[[1," "],[8,[39,23],null,[["@message"],["Are you sure you want to delete this Role?"]],[["default"],[[[[1,"\\n "],[8,[39,24],null,[["@name"],["action"]],[["default"],[[[[1,"\\n "],[8,[39,17],[[4,[38,22],[[30,0],[30,2],"delete",[33,2]],null]],[["@text","@color"],["Delete","critical"]],null],[1,"\\n "]],[2]]]]],[1,"\\n "],[8,[39,24],null,[["@name"],["dialog"]],[["default"],[[[[1,"\\n"],[41,[28,[37,12],[[33,25,["length"]],0],null],[[[1," "],[8,[39,26],null,[["@onclose","@aria"],[[28,[37,22],[[30,0],[30,4]],null],[28,[37,11],null,[["label"],["Role in Use"]]]]],[["default"],[[[[1,"\\n "],[8,[39,24],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"Role in Use"],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,24],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[10,2],[12],[1,"\\n This Role is currently in use. If you choose to delete this Role, it will be removed from the\\n following "],[10,"strong"],[12],[1,[33,25,["length"]]],[1," Tokens"],[13],[1,":\\n "],[13],[1,"\\n "],[8,[39,13],null,[["@items","@target"],[[99,25,["@items"]],"_blank"]],null],[1,"\\n "],[10,2],[12],[1,"\\n This action cannot be undone. "],[1,[30,5]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,24],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[39,14],null,null,[["default"],[[[[1,"\\n "],[8,[39,17],[[4,[38,22],[[30,0],[30,3]],null]],[["@text","@color"],["Yes, Delete","critical"]],null],[1,"\\n "],[8,[39,17],[[4,[38,22],[[30,0],[30,6]],null]],[["@text","@color"],["Cancel","secondary"]],null],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],[[[1," "],[8,[39,27],null,[["@message","@execute","@cancel"],[[30,5],[30,3],[30,4]]],null],[1,"\\n"]],[]]],[1," "]],[3,4,5]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[13],[1,"\\n"],[13],[1,"\\n"]],["loader","confirm","execute","cancel","message","close"],false,["role-form","form","item","dc","nspace","partition","if","not","create","data-source","uri","hash","gt","token-list","hds/button-set","and","can","hds/button","or","eq","on","route-action","action","confirmation-dialog","block-slot","items","modal-dialog","delete-confirmation"]]',moduleName:"consul-ui/templates/dc/acls/roles/-form.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls/roles/edit",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"B1T3t9iM",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/role/${id}",[28,[37,4],null,[["partition","nspace","dc","id"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[28,[37,5],[[30,1,["params","id"]],""],null]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,6],null,[["@name"],["error"]],[["default"],[[[[1,"\\n"],[41,[28,[37,8],[[30,2,["error","status"]],"401"],null],[[[1," "],[8,[39,9],null,null,null],[1,"\\n"]],[]],[[[1," "],[8,[39,10],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n"]],[]]],[1," "]],[]]]]],[1,"\\n\\n "],[8,[39,6],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[30,1,["params","dc"]],[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,2,["data"]],[30,2,["data","isNew"]]],[[[1," "],[8,[39,12],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["breadcrumbs"]],[["default"],[[[[1,"\\n "],[10,"ol"],[12],[1,"\\n "],[10,"li"],[12],[10,3],[15,6,[28,[37,13],["dc.acls.roles"],null]],[12],[1,"All Roles"],[13],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n"],[41,[30,7],[[[1," "],[8,[30,1,["Title"]],null,[["@title"],["New Role"]],null],[1,"\\n"]],[]],[[[1," "],[8,[30,1,["Title"]],null,[["@title"],["Edit Role"]],null],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["content"]],[["default"],[[[[1,"\\n"],[41,[28,[37,14],[[30,7]],null],[[[1," "],[10,0],[14,0,"definition-table"],[12],[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Role ID"],[13],[1,"\\n "],[10,"dd"],[12],[1,"\\n "],[8,[39,15],null,[["@value","@name"],[[30,6,["ID"]],"Role ID"]],null],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "],[19,"dc/acls/roles/form",[1,2,3,4,5,6,7]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[3,4,5,6,7]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","loader","dc","partition","nspace","item","create"],true,["route","routeName","data-loader","uri","hash","or","block-slot","if","eq","consul/acl/disabled","app-error","let","app-view","href-to","not","copyable-code","partial"]]',moduleName:"consul-ui/templates/dc/acls/roles/edit.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/acls/roles/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -3968,19 +3982,19 @@ e.default=n})),define("consul-ui/templates/dc/peers/index",["exports","@ember/te var n=(0,t.createTemplateFactory)({id:"uPTWAtBk",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/peers",[28,[37,4],null,[["partition","nspace","dc"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[28,[37,4],null,[["value","change"],[[28,[37,8],[[33,9],"State:asc"],null],[28,[37,10],[[30,0],[28,[37,11],[[33,9]],null]],[["value"],["target.selected"]]]]]],[28,[37,4],null,[["state","searchproperty"],[[28,[37,4],null,[["value","change"],[[52,[33,13],[28,[37,14],[[33,13],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,13]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change","default"],[[52,[28,[37,15],[[33,16],[27]],null],[28,[37,14],[[33,16],","],null],[33,17]],[28,[37,10],[[30,0],[28,[37,11],[[33,16]],null]],[["value"],["target.selectedItems"]]],[33,17]]]]]]],[30,2,["data"]]],[[[1," "],[8,[39,18],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],["Peers"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["toolbar"]],[["default"],[[[[1,"\\n\\n"],[41,[28,[37,19],[[30,5,["length"]],0],null],[[[1," "],[8,[39,20],null,[["@search","@onsearch","@sort","@filter"],[[99,21,["@search"]],[28,[37,10],[[30,0],[28,[37,11],[[33,21]],null]],[["value"],["target.value"]]],[30,3],[30,4]]],null],[1,"\\n"]],[]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n\\n "],[8,[39,22],[[24,0,"peer-create-modal"]],[["@aria"],[[28,[37,4],null,[["label"],["Add peer connection"]]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[1,[28,[35,23],[[28,[37,24],[[30,0],"create",[30,6]],null]],null]],[1,"\\n "],[10,"h2"],[12],[1,"\\n Add peer connection\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n\\n"],[41,[30,6,["opened"]],[[[1," "],[8,[39,25],null,[["@params"],[[30,1,["params"]]]],[["default"],[[[[1,"\\n "],[8,[30,7,["Form"]],null,[["@onchange","@onsubmit"],[[30,2,["invalidate"]],[28,[37,26],[[30,0,["redirectToPeerShow"]],[30,6,["close"]]],null]]],[["default"],[[[[1,"\\n "],[1,[28,[35,23],[[28,[37,24],[[30,0],"form",[30,8]],null]],null]],[1,"\\n "],[8,[30,8,["Fieldsets"]],null,null,null],[1,"\\n "]],[8]]]]],[1,"\\n "]],[7]]]]],[1,"\\n"]],[]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[30,0,["form","Actions"]],null,[["@onclose"],[[30,0,["create","close"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n "],[8,[39,27],[[4,[38,28],["click",[28,[37,29],[[30,0,["create","open"]]],null]],null]],[["@color","@text"],["primary","Add peer connection"]],null],[1,"\\n\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n\\n "],[8,[39,30],null,[["@sink","@type","@label"],[[28,[37,3],["/${partition}/${dc}/${nspace}/peer/",[28,[37,4],null,[["partition","nspace","dc"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]]]]]],null],"peer","Peer"]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["removed"]],[["default"],[[[[1,"\\n "],[8,[39,31],[[4,[38,32],null,[["after"],[[28,[37,10],[[30,0],[30,10]],null]]]]],[["@type"],["remove"]],null],[1,"\\n "]],[10]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n\\n "],[8,[39,22],null,[["@aria","@onclose"],[[28,[37,4],null,[["label"],["Regenerate token"]]],[28,[37,24],[[30,0],"item",[27]],null]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[1,[28,[35,23],[[28,[37,24],[[30,0],"regenerate",[30,11]],null]],null]],[1,"\\n "],[10,"h2"],[12],[1,"\\n Regenerate token\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n"],[41,[30,0,["item"]],[[[1," "],[8,[39,33],null,[["@item","@onchange","@regenerate"],[[30,0,["item"]],[30,2,["invalidate"]],true]],[["default"],[[[[1,"\\n "],[1,[28,[35,23],[[28,[37,24],[[30,0],"regenerateForm",[30,12]],null]],null]],[1,"\\n "],[8,[30,12,["Fieldsets"]],null,null,null],[1,"\\n "]],[12]]]]],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[8,[30,0,["regenerateForm","Actions"]],null,[["@onclose"],[[30,0,["regenerate","close"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n "]],[11]]]]],[1,"\\n\\n "],[8,[39,34],null,[["@type","@sort","@filters","@search","@items"],["peer",[30,3,["value"]],[30,4],[99,21,["@search"]],[30,5]]],[["default"],[[[[1,"\\n "],[8,[30,13,["Collection"]],null,null,[["default"],[[[[1,"\\n\\n "],[8,[39,35],null,[["@items","@onedit","@ondelete"],[[30,13,["items"]],[28,[37,36],[[28,[37,24],[[30,0],"item"],null],[30,0,["regenerate","open"]]],null],[30,9,["delete"]]]],null],[1,"\\n\\n "]],[]]]]],[1,"\\n "],[8,[30,13,["Empty"]],null,null,[["default"],[[[[1,"\\n"],[1," "],[8,[39,37],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,38],["routes.dc.peers.index.empty.header"],[["items"],[[30,5,["length"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[10,2],[12],[1,"\\n "],[1,[28,[35,38],["routes.dc.peers.index.empty.body"],[["items","canUsePartitions","canUseACLs","htmlSafe"],[[30,5,["length"]],[28,[37,39],["use partitions"],null],[28,[37,39],["use acls"],null],true]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n"],[1," "],[8,[39,40],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Peers",[29,[[28,[37,41],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,40],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,41],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering/create-manage-peering"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[13]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[3,4,5]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","loader","sort","filters","items","modal","form","form","writer","after","modal","form","collection"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","or","sortBy","action","mut","if","state","split","not-eq","searchproperty","searchProperties","app-view","gt","consul/peer/search-bar","search","modal-dialog","did-insert","set","consul/peer/form","fn","hds/button","on","optional","data-writer","consul/peer/notifications","notification","consul/peer/form/generate","data-collection","consul/peer/list","queue","empty-state","t","can","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/peers/index.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/peers/show",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"AvoaCEAO",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/peer/${name}",[28,[37,4],null,[["partition","nspace","dc","name"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["params","name"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[30,1,["params","dc"]],[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,2,["data"]]],[[[1," "],[8,[39,8],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["breadcrumbs"]],[["default"],[[[[1,"\\n "],[10,"ol"],[12],[1,"\\n "],[10,"li"],[12],[10,3],[15,6,[28,[37,9],["dc.peers"],null]],[12],[1,"All Peers"],[13],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],[[30,6,["Name"]]]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[8,[39,10],null,[["@peering"],[[30,6]]],null],[1,"\\n "],[8,[39,11],null,[["@peer"],[[30,6]]],[["default"],[[[[1,"\\n "],[8,[39,12],null,[["@items"],[[30,7,["data","tabs"]]]],null],[1,"\\n\\n "]],[7]]]]],[1,"\\n "],[8,[39,13],null,[["@name","@model"],[[99,1,["@name"]],[28,[37,14],[[28,[37,4],null,[["items","peer"],[[30,6,["PeerServerAddresses"]],[30,6]]]],[30,1,["model"]]],null]]],[["default"],[[[[1,"\\n "],[46,[28,[37,16],null,null],null,null,null],[1,"\\n "]],[8]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[3,4,5,6]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","loader","dc","partition","nspace","item","peering","o"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","app-view","href-to","consul/peer/bento-box","peerings/provider","tab-nav","outlet","assign","component","-outlet"]]',moduleName:"consul-ui/templates/dc/peers/show.hbs",isStrictMode:!1}) -e.default=n})),define("consul-ui/templates/dc/peers/show/addresses",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})) +define("consul-ui/templates/dc/peers/show/addresses",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"3k5sOecZ",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n"],[41,[28,[37,3],[[30,1,["model","items","length"]],0],null],[[[1," "],[8,[39,4],null,[["@items"],[[30,1,["model","items"]]]],null],[1,"\\n"]],[]],[[[1," "],[8,[39,5],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,7],["routes.dc.peers.show.addresses.empty.header"],null]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,7],["routes.dc.peers.show.addresses.empty.body"],[["htmlSafe"],[true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,6],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,8],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Peers",[29,[[28,[37,9],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,8],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,9],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering/create-manage-peering"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]]],[1]]]]]],["route"],false,["route","routeName","if","gt","consul/peer/address/list","empty-state","block-slot","t","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/peers/show/addresses.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/peers/show/exported",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"Z0gVGZWd",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/exported-services/${name}",[28,[37,4],null,[["partition","nspace","dc","name"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["model","peer","Name"]]]]]],null]]],[["default"],[[[[1,"\\n"],[44,[[28,[37,6],[[30,1,["params","partition"]],[30,1,["model","user","token","Partition"]],"default"],null],[30,2,["data"]]],[[[1,"\\n "],[8,[39,7],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,8],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,7],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[41,[30,4,["length"]],[[[1," "],[10,0],[14,0,"search-bar"],[12],[1,"\\n "],[10,"form"],[14,0,"filter-bar"],[12],[1,"\\n "],[8,[39,10],[[24,0,"!w-80"]],[["@onsearch","@value","@placeholder"],[[28,[37,11],["target.value",[30,0,["updateSearch"]]],null],[30,0,["search"]],"Search"]],null],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "],[8,[39,12],null,[["@items","@search","@searchProperties"],[[30,4],[30,0,["search"]],[28,[37,13],["Name"],null]]],[["default"],[[[[1,"\\n "],[8,[39,14],null,null,[["default"],[[[[1,"\\n"],[41,[30,6,["data","height"]],[[[1," "],[10,0],[15,5,[30,6,["data","fillRemainingHeightStyle"]]],[14,0,"overflow-y-scroll"],[12],[1,"\\n"],[41,[30,5,["data","items","length"]],[[[1," "],[8,[39,15],null,[["@tagName","@estimateHeight","@items"],["ul",[30,6,["data","height"]],[30,5,["data","items"]]]],[["default"],[[[[1,"\\n "],[10,"li"],[14,0,"px-3 h-12 border-bottom-primary"],[12],[1,"\\n "],[10,3],[14,0,"hds-typography-display-300 hds-foreground-strong hds-font-weight-semibold h-full w-full flex items-center"],[15,6,[28,[37,16],["dc.services.show.index",[30,7,["Name"]]],[["params"],[[52,[28,[37,17],[[30,7,["Partition"]],[30,3]],null],[28,[37,4],null,[["partition","nspace","peer"],[[30,7,["Partition"]],[30,7,["Namespace"]],[30,7,["PeerName"]]]]],[28,[37,4],null,[["peer"],[[30,7,["PeerName"]]]]]]]]]],[12],[1,"\\n "],[1,[30,7,["Name"]]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "]],[7,8]]]]],[1,"\\n"]],[]],[[[1," "],[8,[39,18],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,7],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,19],["routes.dc.peers.show.exported.empty.header"],[["name"],[[30,1,["model","peer","Name"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,19],["routes.dc.peers.show.exported.empty.body"],[["items","name","htmlSafe"],[[30,4,["length"]],[30,1,["model","peer","Name"]],true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,7],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,20],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Peers",[29,[[28,[37,21],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,20],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,21],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering/create-manage-peering"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]],[1," "],[13],[1,"\\n"]],[]],null],[1," "]],[6]]]]],[1,"\\n\\n "]],[5]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[3,4]]],[1," "]],[2]]]]],[1,"\\n\\n"]],[1]]]]]],["route","api","partition","items","search","p","service","index"],false,["route","routeName","data-loader","uri","hash","let","or","block-slot","app-error","if","freetext-filter","pick","providers/search","array","providers/dimension","vertical-collection","href-to","not-eq","empty-state","t","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/peers/show/exported.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/peers/show/imported",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -var n=(0,t.createTemplateFactory)({id:"WW9UdfAm",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/services/${peer}/${peerId}",[28,[37,4],null,[["partition","nspace","dc","peer","peerId"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["model","peer","Name"]],[30,1,["model","peer","id"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[28,[37,4],null,[["value","change"],[[28,[37,8],[[33,9],"Status:asc"],null],[28,[37,10],[[30,0],[28,[37,11],[[33,9]],null]],[["value"],["target.selected"]]]]]],[28,[37,4],null,[["status","kind","source","searchproperty"],[[28,[37,4],null,[["value","change"],[[52,[33,13],[28,[37,14],[[33,13],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,13]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,15],[28,[37,14],[[33,15],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,15]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,16],[28,[37,14],[[33,16],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,16]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change","default"],[[52,[28,[37,17],[[33,18],[27]],null],[28,[37,14],[[33,18],","],null],[30,0,["searchProperties"]]],[28,[37,10],[[30,0],[28,[37,11],[[33,18]],null]],[["value"],["target.selectedItems"]]],[30,0,["searchProperties"]]]]]]]],[28,[37,19],["Kind","connect-proxy",[30,2,["data"]]],null],[28,[37,8],[[30,1,["params","partition"]],[30,1,["model","user","token","Partition"]],"default"],null],[28,[37,8],[[30,1,["params","nspace"]],[30,1,["model","user","token","Namespace"]],"default"],null]],[[[1,"\\n"],[41,[28,[37,20],[[30,5,["length"]],0],null],[[[44,[[28,[37,21],[[30,5]],null]],[[[1," "],[8,[39,22],null,[["@sources","@partitions","@partition","@search","@onsearch","@sort","@filter","@peer"],[[28,[37,23],[[30,8],"ExternalSources"],null],[28,[37,23],[[30,8],"Partitions"],null],[30,6],[99,24,["@search"]],[28,[37,10],[[30,0],[28,[37,11],[[33,24]],null]],[["value"],["target.value"]]],[30,3],[30,4],[30,1,["model","peer"]]]],null],[1,"\\n"]],[8]]]],[]],null],[1," "],[8,[39,25],null,[["@type","@sort","@filters","@search","@items"],["service",[30,3,["value"]],[30,4],[99,24,["@search"]],[30,5]]],[["default"],[[[[1,"\\n "],[8,[30,9,["Collection"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,26],null,[["@items","@partition","@isPeerDetail"],[[30,9,["items"]],[30,6],true]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,9,["Empty"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,28],["routes.dc.peers.show.imported.empty.header"],[["name"],[[30,1,["model","peer","Name"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,28],["routes.dc.peers.show.imported.empty.body"],[["items","name","htmlSafe"],[[30,5,["length"]],[30,1,["model","peer","Name"]],true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n"],[1," "],[8,[39,29],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Peers",[29,[[28,[37,30],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,29],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,30],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering/create-manage-peering"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n"]],[3,4,5,6,7]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","api","sort","filters","items","partition","nspace","items","collection"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","or","sortBy","action","mut","if","status","split","kind","source","not-eq","searchproperty","reject-by","gt","collection","consul/service/search-bar","get","search","data-collection","consul/service/list","empty-state","t","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/peers/show/imported.hbs",isStrictMode:!1}) -e.default=n})) -define("consul-ui/templates/dc/peers/show/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +var n=(0,t.createTemplateFactory)({id:"Ioh7AUof",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/services/${peer}/${peerId}",[28,[37,4],null,[["partition","nspace","dc","peer","peerId"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["model","peer","Name"]],[30,1,["model","peer","id"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[28,[37,4],null,[["value","change"],[[28,[37,8],[[33,9],"Status:asc"],null],[28,[37,10],[[30,0],[28,[37,11],[[33,9]],null]],[["value"],["target.selected"]]]]]],[28,[37,4],null,[["status","kind","source","searchproperty"],[[28,[37,4],null,[["value","change"],[[52,[33,13],[28,[37,14],[[33,13],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,13]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,15],[28,[37,14],[[33,15],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,15]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,16],[28,[37,14],[[33,16],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,16]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change","default"],[[52,[28,[37,17],[[33,18],[27]],null],[28,[37,14],[[33,18],","],null],[30,0,["searchProperties"]]],[28,[37,10],[[30,0],[28,[37,11],[[33,18]],null]],[["value"],["target.selectedItems"]]],[30,0,["searchProperties"]]]]]]]],[28,[37,19],["Kind","connect-proxy",[30,2,["data"]]],null],[28,[37,8],[[30,1,["params","partition"]],[30,1,["model","user","token","Partition"]],"default"],null],[28,[37,8],[[30,1,["params","nspace"]],[30,1,["model","user","token","Namespace"]],"default"],null]],[[[1,"\\n"],[41,[28,[37,20],[[30,5,["length"]],0],null],[[[44,[[28,[37,21],[[30,5]],null]],[[[1," "],[8,[39,22],null,[["@sources","@partitions","@partition","@search","@onsearch","@sort","@filter","@peer"],[[28,[37,23],[[30,8],"ExternalSources"],null],[28,[37,23],[[30,8],"Partitions"],null],[30,6],[99,24,["@search"]],[28,[37,10],[[30,0],[28,[37,11],[[33,24]],null]],[["value"],["target.value"]]],[30,3],[30,4],[30,1,["model","peer"]]]],null],[1,"\\n"]],[8]]]],[]],null],[1," "],[8,[39,25],null,[["@type","@sort","@filters","@search","@items"],["service",[30,3,["value"]],[30,4],[99,24,["@search"]],[30,5]]],[["default"],[[[[1,"\\n "],[8,[30,9,["Collection"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,26],null,[["@items","@partition","@nspace","@isPeerDetail"],[[30,9,["items"]],[30,6],[30,7],true]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,9,["Empty"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,28],["routes.dc.peers.show.imported.empty.header"],[["name"],[[30,1,["model","peer","Name"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,28],["routes.dc.peers.show.imported.empty.body"],[["items","name","htmlSafe"],[[30,5,["length"]],[30,1,["model","peer","Name"]],true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n"],[1," "],[8,[39,29],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Peers",[29,[[28,[37,30],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,29],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,30],["CONSUL_DOCS_URL"],null],"/connect/cluster-peering/create-manage-peering"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n"]],[3,4,5,6,7]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","api","sort","filters","items","partition","nspace","items","collection"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","or","sortBy","action","mut","if","status","split","kind","source","not-eq","searchproperty","reject-by","gt","collection","consul/service/search-bar","get","search","data-collection","consul/service/list","empty-state","t","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/peers/show/imported.hbs",isStrictMode:!1}) +e.default=n})),define("consul-ui/templates/dc/peers/show/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"IJMk41B8",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[1,[28,[35,2],[[30,0,["transitionToImported"]]],null]],[1,"\\n"]],[1]]]]]],["route"],false,["route","routeName","did-insert"]]',moduleName:"consul-ui/templates/dc/peers/show/index.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/routing-config",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"ag2giQ2I",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/discovery-chain/${name}",[28,[37,4],null,[["partition","nspace","dc","name"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["params","name"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[30,2,["data"]]],[[[8,[39,8],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["breadcrumbs"]],[["default"],[[[[1,"\\n "],[10,"ol"],[12],[1,"\\n "],[10,"li"],[12],[10,3],[15,6,[28,[37,9],["dc.services"],null]],[12],[1,"All Services"],[13],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],[[30,3,["Chain","ServiceName"]]]],null],[1,"\\n "],[13],[1,"\\n "],[8,[39,10],null,[["@source","@withInfo"],[[28,[37,11],["routes.dc.routing-config.source"],null],true]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[10,0],[14,0,"container"],[12],[1,"\\n "],[8,[39,12],null,[["@chain"],[[30,3,["Chain"]]]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n"]],[]]]]],[1,"\\n"]],[3]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","loader","item"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","app-view","href-to","consul/source","t","consul/discovery-chain"]]',moduleName:"consul-ui/templates/dc/routing-config.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/services/index",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 -var n=(0,t.createTemplateFactory)({id:"9rUU3uSO",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/services",[28,[37,4],null,[["partition","nspace","dc"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n\\n"],[44,[[28,[37,4],null,[["value","change"],[[28,[37,8],[[33,9],"Status:asc"],null],[28,[37,10],[[30,0],[28,[37,11],[[33,9]],null]],[["value"],["target.selected"]]]]]],[28,[37,4],null,[["status","kind","source","searchproperty"],[[28,[37,4],null,[["value","change"],[[52,[33,13],[28,[37,14],[[33,13],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,13]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,15],[28,[37,14],[[33,15],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,15]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,16],[28,[37,14],[[33,16],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,16]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change","default"],[[52,[28,[37,17],[[33,18],[27]],null],[28,[37,14],[[33,18],","],null],[30,0,["_searchProperties"]]],[28,[37,10],[[30,0],[28,[37,11],[[33,18]],null]],[["value"],["target.selectedItems"]]],[30,0,["_searchProperties"]]]]]]]],[28,[37,19],["Kind","connect-proxy",[30,2,["data"]]],null],[28,[37,8],[[30,1,["params","partition"]],[30,1,["model","user","token","Partition"]],"default"],null],[28,[37,8],[[30,1,["params","nspace"]],[30,1,["model","user","token","Namespace"]],"default"],null]],[[[1,"\\n "],[8,[39,20],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],["Services"]],null],[1," "],[10,"em"],[12],[1,[28,[35,21],[[30,5,["length"]]],null]],[1," total"],[13],[1,"\\n "],[13],[1,"\\n "],[10,"label"],[14,"for","toolbar-toggle"],[12],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["toolbar"]],[["default"],[[[[1,"\\n"],[41,[28,[37,22],[[30,5,["length"]],0],null],[[[44,[[28,[37,23],[[30,5]],null]],[[[1," "],[8,[39,24],null,[["@sources","@partitions","@partition","@search","@onsearch","@sort","@filter"],[[28,[37,25],[[30,8],"ExternalSources"],null],[28,[37,25],[[30,8],"Partitions"],null],[30,6],[99,26,["@search"]],[28,[37,10],[[30,0],[28,[37,11],[[33,26]],null]],[["value"],["target.value"]]],[30,3],[30,4]]],null],[1,"\\n"]],[8]]]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@type","@sort","@filters","@search","@items"],["service",[30,3,["value"]],[30,4],[99,26,["@search"]],[30,5]]],[["default"],[[[[1,"\\n "],[8,[30,9,["Collection"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,28],null,[["@items","@partition"],[[30,9,["items"]],[30,6]]],[["default"],[[[[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,9,["Empty"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,29],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,30],["routes.dc.services.index.empty.header"],[["items"],[[30,5,["length"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,30],["routes.dc.services.index.empty.body"],[["items","canUseACLs","htmlSafe"],[[30,5,["length"]],[28,[37,31],["use acls"],null],true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,32],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Services",[29,[[28,[37,33],["CONSUL_DOCS_URL"],null],"/commands/services"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,32],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,33],["CONSUL_DOCS_LEARN_URL"],null],"/consul/getting-started/services"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n\\n "]],[]]]]],[1,"\\n\\n"]],[3,4,5,6,7]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","api","sort","filters","items","partition","nspace","items","collection"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","or","sortBy","action","mut","if","status","split","kind","source","not-eq","searchproperty","reject-by","app-view","format-number","gt","collection","consul/service/search-bar","get","search","data-collection","consul/service/list","empty-state","t","can","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/services/index.hbs",isStrictMode:!1}) +var n=(0,t.createTemplateFactory)({id:"k/tlhz7S",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/services",[28,[37,4],null,[["partition","nspace","dc"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n\\n"],[44,[[28,[37,4],null,[["value","change"],[[28,[37,8],[[33,9],"Status:asc"],null],[28,[37,10],[[30,0],[28,[37,11],[[33,9]],null]],[["value"],["target.selected"]]]]]],[28,[37,4],null,[["status","kind","source","searchproperty"],[[28,[37,4],null,[["value","change"],[[52,[33,13],[28,[37,14],[[33,13],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,13]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,15],[28,[37,14],[[33,15],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,15]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change"],[[52,[33,16],[28,[37,14],[[33,16],","],null],[27]],[28,[37,10],[[30,0],[28,[37,11],[[33,16]],null]],[["value"],["target.selectedItems"]]]]]],[28,[37,4],null,[["value","change","default"],[[52,[28,[37,17],[[33,18],[27]],null],[28,[37,14],[[33,18],","],null],[30,0,["_searchProperties"]]],[28,[37,10],[[30,0],[28,[37,11],[[33,18]],null]],[["value"],["target.selectedItems"]]],[30,0,["_searchProperties"]]]]]]]],[28,[37,19],["Kind","connect-proxy",[30,2,["data"]]],null],[28,[37,8],[[30,1,["params","partition"]],[30,1,["model","user","token","Partition"]],"default"],null],[28,[37,8],[[30,1,["params","nspace"]],[30,1,["model","user","token","Namespace"]],"default"],null]],[[[1,"\\n "],[8,[39,20],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],["Services"]],null],[1," "],[10,"em"],[12],[1,[28,[35,21],[[30,5,["length"]]],null]],[1," total"],[13],[1,"\\n "],[13],[1,"\\n "],[10,"label"],[14,"for","toolbar-toggle"],[12],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["toolbar"]],[["default"],[[[[1,"\\n"],[41,[28,[37,22],[[30,5,["length"]],0],null],[[[44,[[28,[37,23],[[30,5]],null]],[[[1," "],[8,[39,24],null,[["@sources","@partitions","@partition","@search","@onsearch","@sort","@filter"],[[28,[37,25],[[30,8],"ExternalSources"],null],[28,[37,25],[[30,8],"Partitions"],null],[30,6],[99,26,["@search"]],[28,[37,10],[[30,0],[28,[37,11],[[33,26]],null]],[["value"],["target.value"]]],[30,3],[30,4]]],null],[1,"\\n"]],[8]]]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@type","@sort","@filters","@search","@items"],["service",[30,3,["value"]],[30,4],[99,26,["@search"]],[30,5]]],[["default"],[[[[1,"\\n "],[8,[30,9,["Collection"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,28],null,[["@items","@partition","@nspace"],[[30,9,["items"]],[30,6],[30,7]]],[["default"],[[[[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[30,9,["Empty"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,29],null,[["@login"],[[30,1,["model","app","login","open"]]]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h2"],[12],[1,"\\n "],[1,[28,[35,30],["routes.dc.services.index.empty.header"],[["items"],[[30,5,["length"]]]]]],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["body"]],[["default"],[[[[1,"\\n "],[1,[28,[35,30],["routes.dc.services.index.empty.body"],[["items","canUseACLs","htmlSafe"],[[30,5,["length"]],[28,[37,31],["use acls"],null],true]]]],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,32],null,[["@text","@href","@icon","@iconPosition","@size"],["Documentation on Services",[29,[[28,[37,33],["CONSUL_DOCS_URL"],null],"/commands/services"]],"docs-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "],[10,"li"],[12],[1,"\\n "],[8,[39,32],null,[["@text","@href","@icon","@iconPosition","@size"],["Take the tutorial",[29,[[28,[37,33],["CONSUL_DOCS_LEARN_URL"],null],"/consul/getting-started/services"]],"learn-link","trailing","small"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[9]]]]],[1,"\\n "]],[]]]]],[1,"\\n\\n "]],[]]]]],[1,"\\n\\n"]],[3,4,5,6,7]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","api","sort","filters","items","partition","nspace","items","collection"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","let","or","sortBy","action","mut","if","status","split","kind","source","not-eq","searchproperty","reject-by","app-view","format-number","gt","collection","consul/service/search-bar","get","search","data-collection","consul/service/list","empty-state","t","can","hds/link/standalone","env"]]',moduleName:"consul-ui/templates/dc/services/index.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/services/instance",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"UwadJzgF",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["/${partition}/${nspace}/${dc}/service-instance/${id}/${node}/${name}/${peer}",[28,[37,4],null,[["partition","nspace","dc","id","node","name","peer"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["params","id"]],[30,1,["params","node"]],[30,1,["params","name"]],[30,1,["params","peer"]]]]]],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,5],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,6],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["disconnected"]],[["default"],[[[[1,"\\n"],[41,[28,[37,8],[[30,2,["error","status"]],"404"],null],[[[1," "],[8,[39,9],[[4,[38,10],null,[["sticky"],[true]]]],[["@color"],["warning"]],[["default"],[[[[1,"\\n "],[8,[30,4,["Title"]],null,null,[["default"],[[[[1,"Warning!"]],[]]]]],[1,"\\n "],[8,[30,4,["Description"]],null,null,[["default"],[[[[1,"\\n This service has been deregistered and no longer exists in the catalog.\\n "]],[]]]]],[1,"\\n "]],[4]]]]],[1,"\\n"]],[]],[[[41,[28,[37,8],[[30,2,["error","status"]],"403"],null],[[[1," "],[8,[39,9],[[4,[38,10],null,[["sticky"],[true]]]],[["@color"],["critical"]],[["default"],[[[[1,"\\n "],[8,[30,5,["Title"]],null,null,[["default"],[[[[1,"Error!"]],[]]]]],[1,"\\n "],[8,[30,5,["Description"]],null,null,[["default"],[[[[1,"\\n You no longer have access to this service.\\n "]],[]]]]],[1,"\\n "]],[5]]]]],[1,"\\n"]],[]],[[[1," "],[8,[39,9],[[4,[38,10],null,[["sticky"],[true]]]],[["@color"],["critical"]],[["default"],[[[[1,"\\n "],[8,[30,6,["Title"]],null,null,[["default"],[[[[1,"Warning!"]],[]]]]],[1,"\\n "],[8,[30,6,["Description"]],null,null,[["default"],[[[[1,"\\n An error was returned whilst loading this data, refresh to try again.\\n "]],[]]]]],[1,"\\n "]],[6]]]]],[1,"\\n "]],[]]]],[]]],[1," "]],[3]]]]],[1,"\\n\\n "],[8,[39,5],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[30,2,["data"]]],[[[41,[30,7,["IsOrigin"]],[[[1," "],[8,[39,12],null,[["@src","@onchange"],[[28,[37,3],["/${partition}/${nspace}/${dc}/proxy-instance/${id}/${node}/${name}",[28,[37,4],null,[["partition","nspace","dc","id","node","name"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,1,["params","id"]],[30,1,["params","node"]],[30,1,["params","name"]]]]]],null],[28,[37,13],[[30,0],[28,[37,14],[[33,15]],null]],[["value"],["data"]]]]],[["default"],[[[[1,"\\n"],[41,[30,8,["data","ServiceID"]],[[[1," "],[8,[39,12],null,[["@src","@onchange"],[[28,[37,3],["/${partition}/${nspace}/${dc}/service-instance/${id}/${node}/${name}/${peer}",[28,[37,4],null,[["partition","nspace","dc","id","node","name","peer"],[[30,1,["params","partition"]],[30,1,["params","nspace"]],[30,1,["params","dc"]],[30,8,["data","ServiceID"]],[30,8,["data","NodeName"]],[30,8,["data","ServiceName"]],[30,1,["params","peer"]]]]]],null],[28,[37,13],[[30,0],[28,[37,14],[[33,16]],null]],[["value"],["data"]]]]],null],[1,"\\n"]],[]],null],[1," "]],[8]]]]],[1,"\\n"]],[]],null],[1," "],[8,[39,17],null,null,[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@name"],["breadcrumbs"]],[["default"],[[[[1,"\\n "],[10,"ol"],[12],[1,"\\n "],[10,"li"],[12],[10,3],[15,6,[28,[37,18],["dc.services"],[["params"],[[28,[37,4],null,[["peer"],[[27]]]]]]]],[12],[1,"All Services"],[13],[13],[1,"\\n "],[10,"li"],[12],[11,3],[16,6,[28,[37,18],["dc.services.show"],null]],[4,[38,19],[[28,[37,20],["Service (",[30,7,["Service","Service"]],")"],null]],null],[12],[1,"\\n Service ("],[1,[30,7,["Service","Service"]]],[1,")\\n "],[13],[13],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],[[30,7,["Service","ID"]]]],null],[1,"\\n "],[13],[1,"\\n "],[8,[39,21],null,[["@item","@withInfo"],[[30,7],true]],null],[1,"\\n "],[8,[39,22],null,[["@item","@withInfo"],[[30,7],true]],null],[1,"\\n"],[41,[28,[37,8],[[33,15,["ServiceProxy","Mode"]],"transparent"],null],[[[1," "],[8,[39,23],null,null,null],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["nav"]],[["default"],[[[[1,"\\n "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Service Name"],[13],[1,"\\n "],[10,"dd"],[12],[10,3],[15,6,[29,[[28,[37,18],["dc.services.show",[30,7,["Service","Service"]]],null]]]],[12],[1,[30,7,["Service","Service"]]],[13],[13],[1,"\\n "],[13],[1,"\\n"],[41,[51,[30,7,["Node","Meta","synthetic-node"]]],[[[1," "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Node Name"],[13],[1,"\\n "],[10,"dd"],[12],[10,3],[15,6,[29,[[28,[37,18],["dc.nodes.show",[30,7,["Node","Node"]]],null]]]],[12],[1,[30,7,["Node","Node"]]],[13],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null],[41,[30,7,["Service","PeerName"]],[[[1," "],[10,"dl"],[12],[1,"\\n "],[10,"dt"],[12],[1,"Peer Name"],[13],[1,"\\n "],[10,"dd"],[12],[10,3],[15,6,[28,[37,18],["dc.peers.show",[30,7,["Service","PeerName"]]],[["params"],[[28,[37,4],null,[["peer"],[[27]]]]]]]],[12],[1,[30,7,["Service","PeerName"]]],[13],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["actions"]],[["default"],[[[[1,"\\n"],[44,[[28,[37,25],[[30,7,["Service","Address"]],[30,7,["Node","Address"]]],null]],[[[1," "],[8,[39,26],null,[["@value","@name"],[[30,9],"Address"]],[["default"],[[[[1,[30,9]]],[]]]]],[1,"\\n"]],[9]]],[1," "]],[]]]]],[1,"\\n "],[8,[39,5],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[8,[39,27],null,[["@items"],[[28,[37,28],[[28,[37,29],[[28,[37,4],null,[["label","href","selected"],["Health Checks",[28,[37,18],["dc.services.instance.healthchecks"],null],[28,[37,30],["dc.services.instance.healthchecks"],null]]]],[52,[28,[37,8],[[30,7,["Service","Kind"]],"mesh-gateway"],null],[28,[37,4],null,[["label","href","selected"],["Addresses",[28,[37,18],["dc.services.instance.addresses"],null],[28,[37,30],["dc.services.instance.addresses"],null]]]]],[52,[33,16],[28,[37,4],null,[["label","href","selected"],["Upstreams",[28,[37,18],["dc.services.instance.upstreams"],null],[28,[37,30],["dc.services.instance.upstreams"],null]]]]],[52,[33,16],[28,[37,4],null,[["label","href","selected"],["Exposed Paths",[28,[37,18],["dc.services.instance.exposedpaths"],null],[28,[37,30],["dc.services.instance.exposedpaths"],null]]]]],[28,[37,4],null,[["label","href","selected"],["Tags & Meta",[28,[37,18],["dc.services.instance.metadata"],null],[28,[37,30],["dc.services.instance.metadata"],null]]]]],null]],null]]],null],[1,"\\n "],[8,[39,31],null,[["@name","@model"],[[99,1,["@name"]],[28,[37,32],[[28,[37,4],null,[["proxy","meta","item"],[[33,16],[33,15],[30,7]]]],[30,1,["model"]]],null]]],[["default"],[[[[1,"\\n "],[46,[28,[37,34],null,null],null,null,null],[1,"\\n "]],[10]]]]],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[7]]],[1," "]],[]]]]],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]]],["route","loader","after","T","T","T","item","meta","address","o"],false,["route","routeName","data-loader","uri","hash","block-slot","app-error","if","eq","hds/toast","notification","let","data-source","action","mut","meta","proxy","app-view","href-to","tooltip","concat","consul/external-source","consul/kind","consul/transparent-proxy","unless","or","consul-copy-button","tab-nav","compact","array","is-href","outlet","assign","component","-outlet"]]',moduleName:"consul-ui/templates/dc/services/instance.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/dc/services/instance/addresses",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 @@ -4029,14 +4043,16 @@ e.default=n})),define("consul-ui/templates/index",["exports","@ember/template-fa var n=(0,t.createTemplateFactory)({id:"CJ8DiXUS",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@name","@model"],[[99,1,["@name"]],[30,1,["model"]]]],[["default"],[[[[1,"\\n "],[46,[28,[37,4],null,null],null,null,null],[1,"\\n "]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","o"],false,["route","routeName","outlet","component","-outlet"]]',moduleName:"consul-ui/templates/index.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/loading",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"5kbK/dah",block:'[[[1,"\\n"]],[],false,[]]',moduleName:"consul-ui/templates/loading.hbs",isStrictMode:!1}) -e.default=n})),define("consul-ui/templates/notfound",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})) +define("consul-ui/templates/notfound",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"qt+16XBx",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@login","@error"],[[30,1,["model","app","login","open"]],[28,[37,3],null,[["status","message"],[404,"Unable to find that page"]]]]],null],[1,"\\n"]],[1]]]]],[1,"\\n\\n"]],["route"],false,["route","routeName","app-error","hash"]]',moduleName:"consul-ui/templates/notfound.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/oauth-provider-debug",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"Lxy3wDlI",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n"],[10,0],[14,5,"width: 50%;margin: 0 auto;"],[12],[1,"\\n "],[10,"h1"],[12],[8,[30,1,["Title"]],null,[["@title"],["Mock OAuth Provider"]],null],[13],[1,"\\n "],[10,"main"],[12],[1,"\\n "],[10,"form"],[14,"method","GET"],[15,"action",[36,2]],[12],[1,"\\n"],[44,[[28,[37,4],null,[["state","code"],["state-123456789/abcdefghijklmnopqrstuvwxyz","code-abcdefghijklmnopqrstuvwxyz/123456789"]]]],[[[1," "],[8,[39,5],null,[["@name","@label","@item","@help"],["state","State",[30,2],"The OIDC state value that will get passed through to Consul"]],null],[1,"\\n "],[8,[39,5],null,[["@name","@label","@item","@help"],["code","Code",[30,2],"The OIDC code value that will get passed through to Consul"]],null],[1,"\\n"]],[2]]],[1," "],[8,[39,6],null,[["@type"],["submit"]],[["default"],[[[[1,"\\n Login\\n "]],[]]]]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"],[13],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","item"],false,["route","routeName","redirect_uri","let","hash","text-input","action"]]',moduleName:"consul-ui/templates/oauth-provider-debug.hbs",isStrictMode:!1}) e.default=n})),define("consul-ui/templates/settings",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=(0,t.createTemplateFactory)({id:"GXqC0vCH",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n "],[8,[39,2],null,[["@src"],[[28,[37,3],["settings://consul:client"],null]]],[["default"],[[[[1,"\\n\\n "],[8,[39,4],null,[["@name"],["error"]],[["default"],[[[[1,"\\n "],[8,[39,5],null,[["@error","@login"],[[30,2,["error"]],[30,1,["model","app","login","open"]]]],null],[1,"\\n "]],[]]]]],[1,"\\n\\n "],[8,[39,4],null,[["@name"],["loaded"]],[["default"],[[[[1,"\\n"],[44,[[28,[37,7],[[30,2,["data"]],[28,[37,8],null,[["blocking"],[true]]]],null]],[[[1," "],[8,[39,9],null,null,[["default"],[[[[1,"\\n "],[8,[39,4],null,[["@name"],["header"]],[["default"],[[[[1,"\\n "],[10,"h1"],[12],[1,"\\n "],[8,[30,1,["Title"]],null,[["@title"],["Settings"]],null],[1,"\\n "],[13],[1,"\\n "]],[]]]]],[1,"\\n "],[8,[39,4],null,[["@name"],["content"]],[["default"],[[[[1,"\\n "],[8,[39,10],[[24,0,"mb-3 mt-2"]],[["@type"],["inline"]],[["default"],[[[[1,"\\n "],[8,[30,4,["Title"]],null,null,[["default"],[[[[1,"Local Storage"]],[]]]]],[1,"\\n "],[8,[30,4,["Description"]],null,null,[["default"],[[[[1,"These settings are immediately saved to local storage and persisted through browser usage."]],[]]]]],[1,"\\n "]],[4]]]]],[1,"\\n "],[10,"form"],[12],[1,"\\n"],[41,[28,[37,12],[[28,[37,13],["CONSUL_UI_DISABLE_REALTIME"],null]],null],[[[1," "],[8,[39,14],null,null,[["default"],[[[[1,"\\n "],[8,[30,5,["Details"]],null,null,[["default"],[[[[1,"\\n "],[8,[39,15],null,[["@data","@sink","@onchange"],[[30,3],"settings://consul:client",[28,[37,16],[[30,0],[28,[37,17],[[30,5,["close"]]],null]],null]]],null],[1,"\\n "]],[]]]]],[1,"\\n "],[10,"fieldset"],[12],[1,"\\n "],[10,"h2"],[12],[1,"Blocking Queries"],[13],[1,"\\n "],[10,2],[12],[1,"Keep catalog info up-to-date without refreshing the page. Any changes made to services, nodes and intentions would be reflected in real time."],[13],[1,"\\n "],[10,0],[14,0,"type-toggle"],[12],[1,"\\n "],[10,"label"],[12],[1,"\\n "],[11,"input"],[24,3,"client[blocking]"],[16,"checked",[52,[30,3,["blocking"]],"checked"]],[24,4,"checkbox"],[4,[38,18],["change",[28,[37,19],[[28,[37,20],[[30,3],"blocking",[28,[37,12],[[30,3,["blocking"]]],null]],null],[28,[37,17],[[30,5,["open"]]],null]],null]],null],[12],[13],[1,"\\n "],[10,1],[12],[1,[52,[30,3,["blocking"]],"On","Off"]],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "]],[5]]]]],[1,"\\n"]],[]],null],[1," "],[13],[1,"\\n "]],[]]]]],[1,"\\n "]],[]]]]],[1,"\\n"]],[3]]],[1," "]],[]]]]],[1,"\\n"]],[2]]]]],[1,"\\n"]],[1]]]]],[1,"\\n"]],["route","loader","item","A","disclosure"],false,["route","routeName","data-loader","uri","block-slot","app-error","let","or","hash","app-view","hds/alert","if","not","env","disclosure","data-sink","action","fn","on","queue","set"]]',moduleName:"consul-ui/templates/settings.hbs",isStrictMode:!1}) -e.default=n})) -define("consul-ui/transforms/array",["exports","ember-data-model-fragments/transforms/array"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +e.default=n})),define("consul-ui/templates/unavailable",["exports","@ember/template-factory"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +var n=(0,t.createTemplateFactory)({id:"hP024biE",block:'[[[1,"\\n"],[8,[39,0],null,[["@name"],[[99,1,["@name"]]]],[["default"],[[[[1,"\\n"],[41,[28,[37,3],["CONSUL_V2_CATALOG_ENABLED"],null],[[[1," "],[10,0],[14,0,"h-screen w-full flex flex-col justify-center items-center"],[12],[1,"\\n "],[10,0],[12],[1,"\\n "],[10,"svg"],[14,"width","149"],[14,"height","39"],[14,"viewBox","0 0 149 39"],[14,"fill","none"],[14,"xmlns","http://www.w3.org/2000/svg","http://www.w3.org/2000/xmlns/"],[14,0,"mb-8"],[12],[1,"\\n "],[10,"g"],[14,"clip-path","url(#clip0_2336_115454)"],[12],[1,"\\n "],[10,"path"],[14,"d","M54.6631 13.8631C54.6631 9.36592 57.3284 6.74561 63.5515 6.74561C65.8492 6.7447 68.1385 7.01683 70.3697 7.55608L69.8428 11.578C67.8266 11.2067 65.7822 11.0028 63.7313 10.9686C60.4647 10.9686 59.3924 12.0715 59.3924 14.6919V24.1128C59.3924 26.727 60.4399 27.8361 63.7313 27.8361C65.7822 27.8018 67.8266 27.598 69.8428 27.2267L70.3697 31.2486C68.1385 31.7878 65.8492 32.06 63.5515 32.059C57.3532 32.059 54.6631 29.4387 54.6631 24.9415V13.8631Z"],[14,"fill","black"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M80.4668 32.0408C74.2003 32.0408 72.5205 28.6405 72.5205 24.9843V20.4262C72.5205 16.7394 74.2065 13.3452 80.473 13.3452C86.7395 13.3452 88.4193 16.7394 88.4193 20.4262V24.9843C88.4131 28.6405 86.7271 32.0408 80.4668 32.0408ZM80.4668 17.1782C78.0246 17.1782 77.0887 18.2507 77.0887 20.2799V25.1061C77.0887 27.1354 78.0246 28.2018 80.4668 28.2018C82.9089 28.2018 83.8387 27.1354 83.8387 25.1061V20.2799C83.8387 18.2812 82.9027 17.1782 80.4668 17.1782Z"],[14,"fill","black"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M102.328 31.6877V19.1345C102.328 18.1778 101.913 17.6964 100.865 17.6964C99.8178 17.6964 97.7661 18.3606 96.0988 19.2077V31.6877H91.5244V13.7172H95.0141L95.4542 15.2345C97.7321 14.1126 100.223 13.4712 102.768 13.3516C105.805 13.3516 106.896 15.4539 106.896 18.6592V31.6877H102.328Z"],[14,"fill","black"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M116.312 32.0412C114.172 32.0062 112.05 31.657 110.015 31.0052L110.634 27.5805C112.403 28.0763 114.231 28.3366 116.07 28.3544C118.097 28.3544 118.395 27.9096 118.395 26.5263C118.395 25.4233 118.172 24.8688 115.209 24.168C110.746 23.1016 110.219 21.9926 110.219 18.5252C110.219 14.9116 111.831 13.3272 117.037 13.3272C118.88 13.3221 120.716 13.5265 122.511 13.9366L122.108 17.5502C120.448 17.2493 118.768 17.0762 117.081 17.0322C115.091 17.0322 114.756 17.4771 114.756 18.5801C114.756 20.0182 114.868 20.1279 117.347 20.7555C122.442 22.084 122.926 22.7482 122.926 26.4349C122.913 29.9022 121.829 32.0412 116.312 32.0412Z"],[14,"fill","black"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M130.487 13.7168V26.2516C130.487 27.2084 130.897 27.6898 131.95 27.6898C133.004 27.6898 135.049 27.0255 136.711 26.1785V13.7168H141.285V31.6873H137.802L137.349 30.176C135.071 31.2988 132.58 31.9402 130.035 32.059C126.998 32.059 125.913 29.9566 125.913 26.7452V13.7168H130.487Z"],[14,"fill","black"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M145.221 31.6877V6.38037L149.795 5.771V31.6877H145.221Z"],[14,"fill","black"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M20.1451 38.75C16.9414 38.7517 13.7857 37.9848 10.9519 36.5157C8.1181 35.0466 5.69179 32.9197 3.88359 30.3197C2.0754 27.7198 0.939957 24.7252 0.575821 21.596C0.211686 18.4668 0.629862 15.2975 1.79405 12.3632C2.95824 9.42894 4.83326 6.81831 7.25637 4.75795C9.67949 2.69759 12.5775 1.24976 15.6988 0.540121C18.8201 -0.169518 22.0704 -0.119518 25.1675 0.685782C28.2647 1.49108 31.1152 3.02734 33.4716 5.16123L28.8166 9.9631C26.9587 8.31623 24.655 7.2343 22.1844 6.84834C19.7138 6.46239 17.1824 6.78896 14.8967 7.78851C12.6111 8.78806 10.6693 10.4177 9.30646 12.4801C7.94365 14.5424 7.21832 16.9491 7.21832 19.4084C7.21832 21.8678 7.94365 24.2744 9.30646 26.3367C10.6693 28.3991 12.6111 30.0288 14.8967 31.0283C17.1824 32.0279 19.7138 32.3544 22.1844 31.9685C24.655 31.5825 26.9587 30.5006 28.8166 28.8537L33.4716 33.6373C29.842 36.9293 25.0834 38.7549 20.1451 38.75Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M35.9875 29.0672C35.6688 29.0672 35.3572 28.9743 35.0922 28.8002C34.8272 28.6261 34.6206 28.3786 34.4987 28.0891C34.3767 27.7996 34.3448 27.4811 34.4069 27.1737C34.4691 26.8664 34.6226 26.5841 34.848 26.3625C35.0734 26.1409 35.3605 25.99 35.6731 25.9289C35.9858 25.8677 36.3098 25.8991 36.6043 26.019C36.8987 26.139 37.1504 26.342 37.3275 26.6026C37.5046 26.8631 37.5991 27.1695 37.5991 27.4828C37.5991 27.903 37.4293 28.306 37.1271 28.6031C36.8249 28.9003 36.415 29.0672 35.9875 29.0672Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M20.0203 23.5891C19.1769 23.5891 18.3524 23.3432 17.6511 22.8825C16.9498 22.4219 16.4032 21.7671 16.0805 21.001C15.7577 20.2349 15.6733 19.392 15.8378 18.5787C16.0023 17.7654 16.4085 17.0184 17.0049 16.4321C17.6013 15.8457 18.3611 15.4464 19.1884 15.2847C20.0156 15.1229 20.873 15.2059 21.6523 15.5232C22.4315 15.8406 23.0975 16.3779 23.5661 17.0674C24.0347 17.7568 24.2848 18.5674 24.2848 19.3966C24.2848 20.5085 23.8355 21.5749 23.0358 22.3611C22.236 23.1474 21.1513 23.5891 20.0203 23.5891Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M37.8411 23.6497C37.5223 23.6497 37.2107 23.5568 36.9457 23.3827C36.6807 23.2086 36.4741 22.9612 36.3522 22.6716C36.2302 22.3821 36.1983 22.0636 36.2605 21.7562C36.3226 21.4489 36.4761 21.1666 36.7015 20.945C36.9269 20.7234 37.214 20.5725 37.5267 20.5114C37.8393 20.4503 38.1633 20.4816 38.4578 20.6016C38.7523 20.7215 39.004 20.9246 39.181 21.1851C39.3581 21.4457 39.4526 21.752 39.4526 22.0653C39.451 22.485 39.2807 22.8871 38.9788 23.1839C38.6769 23.4807 38.268 23.6481 37.8411 23.6497Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M33.0432 23.4671C32.7245 23.4671 32.4129 23.3742 32.1479 23.2001C31.8828 23.026 31.6763 22.7785 31.5543 22.489C31.4323 22.1995 31.4004 21.881 31.4626 21.5736C31.5248 21.2663 31.6783 20.984 31.9037 20.7624C32.129 20.5408 32.4162 20.3899 32.7288 20.3288C33.0414 20.2677 33.3655 20.299 33.6599 20.4189C33.9544 20.5389 34.2061 20.7419 34.3832 21.0025C34.5603 21.263 34.6548 21.5694 34.6548 21.8827C34.6548 22.3029 34.485 22.7059 34.1828 23.003C33.8805 23.3002 33.4706 23.4671 33.0432 23.4671Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M37.8411 18.3177C37.5223 18.3177 37.2107 18.2248 36.9457 18.0507C36.6807 17.8766 36.4741 17.6291 36.3522 17.3396C36.2302 17.0501 36.1983 16.7315 36.2605 16.4242C36.3226 16.1169 36.4761 15.8346 36.7015 15.613C36.9269 15.3914 37.214 15.2405 37.5267 15.1794C37.8393 15.1182 38.1633 15.1496 38.4578 15.2695C38.7523 15.3894 39.004 15.5925 39.181 15.8531C39.3581 16.1136 39.4526 16.4199 39.4526 16.7333C39.451 17.153 39.2807 17.5551 38.9788 17.8518C38.6769 18.1486 38.268 18.3161 37.8411 18.3177Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M33.0432 18.5008C32.7245 18.5008 32.4129 18.4079 32.1479 18.2338C31.8828 18.0597 31.6763 17.8122 31.5543 17.5227C31.4323 17.2332 31.4004 16.9146 31.4626 16.6073C31.5248 16.3 31.6783 16.0177 31.9037 15.7961C32.129 15.5745 32.4162 15.4236 32.7288 15.3625C33.0414 15.3013 33.3655 15.3327 33.6599 15.4526C33.9544 15.5726 34.2061 15.7756 34.3832 16.0362C34.5603 16.2967 34.6548 16.603 34.6548 16.9164C34.6548 17.3366 34.485 17.7396 34.1828 18.0367C33.8805 18.3339 33.4706 18.5008 33.0432 18.5008Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[10,"path"],[14,"d","M36.0803 12.9856C35.7616 12.9856 35.45 12.8927 35.185 12.7186C34.92 12.5445 34.7134 12.2971 34.5914 12.0076C34.4694 11.7181 34.4375 11.3995 34.4997 11.0922C34.5619 10.7848 34.7154 10.5025 34.9408 10.2809C35.1662 10.0594 35.4533 9.90847 35.7659 9.84734C36.0785 9.7862 36.4026 9.81758 36.697 9.9375C36.9915 10.0574 37.2432 10.2605 37.4203 10.521C37.5974 10.7816 37.6919 11.0879 37.6919 11.4013C37.6919 11.8215 37.5221 12.2245 37.2199 12.5216C36.9176 12.8187 36.5077 12.9856 36.0803 12.9856Z"],[14,"fill","#E03875"],[12],[13],[1,"\\n "],[13],[1,"\\n "],[10,"defs"],[12],[1,"\\n "],[10,"clipPath"],[14,1,"clip0_2336_115454"],[12],[1,"\\n "],[10,"rect"],[14,"width","150"],[14,"height","39"],[14,"fill","white"],[12],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n\\n "],[8,[39,4],null,null,[["default"],[[[[1,"\\n "],[8,[30,2,["Header"]],null,[["@title"],["User Interface Unavailable"]],null],[1,"\\n "],[8,[30,2,["Body"]],null,[["@text"],["The Consul v2 catalog API (beta) is enabled, and is not yet compatible with the Consul UI."]],null],[1,"\\n "],[8,[30,2,["Footer"]],null,[["@hasDivider"],[true]],[["default"],[[[[1,"\\n "],[8,[30,3,["Link::Standalone"]],null,[["@icon","@iconPosition","@isHrefExternal","@text","@href"],["docs-link","trailing",true,"Learn more","https://developer.hashicorp.com/consul/docs/architecture/catalog/v2#constraints-and-limitations"]],null],[1,"\\n "],[8,[30,3,["Link::Standalone"]],null,[["@icon","@iconPosition","@isHrefExternal","@text","@href"],["external-link","trailing",true,"Provide feedback","https://hashicorp.sjc1.qualtrics.com/jfe/form/SV_cHDaObigIBbQneC"]],null],[1,"\\n "]],[3]]]]],[1,"\\n "]],[2]]]]],[1,"\\n "],[13],[1,"\\n "],[13],[1,"\\n"]],[]],null]],[1]]]]]],["route","A","F"],false,["route","routeName","if","env","hds/application-state"]]',moduleName:"consul-ui/templates/unavailable.hbs",isStrictMode:!1}) +e.default=n})),define("consul-ui/transforms/array",["exports","ember-data-model-fragments/transforms/array"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=t.default e.default=n})),define("consul-ui/transforms/boolean",["exports","@ember-data/serializer/-private"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.BooleanTransform}})})),define("consul-ui/transforms/date",["exports","@ember-data/serializer/-private"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.DateTransform}})})),define("consul-ui/transforms/fragment-array",["exports","ember-data-model-fragments/transforms/fragment-array"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 var n=t.default @@ -4177,7 +4193,8 @@ return null==e?[]:[e]},get NONE(){return 0},get CAPTURING_PHASE(){return 1},get e.stopped=!0,"function"==typeof e.event.stopPropagation&&e.event.stopPropagation()},stopImmediatePropagation(){const e=l(this) e.stopped=!0,e.immediateStopped=!0,"function"==typeof e.event.stopImmediatePropagation&&e.event.stopImmediatePropagation()},get bubbles(){return Boolean(l(this).event.bubbles)},get cancelable(){return Boolean(l(this).event.cancelable)},preventDefault(){r(l(this))},get defaultPrevented(){return l(this).canceled},get composed(){return Boolean(l(this).event.composed)},get timeStamp(){return l(this).timeStamp},get srcElement(){return l(this).eventTarget},get cancelBubble(){return l(this).stopped},set cancelBubble(e){if(!e)return const t=l(this) -t.stopped=!0,"boolean"==typeof t.event.cancelBubble&&(t.event.cancelBubble=!0)},get returnValue(){return!l(this).canceled},set returnValue(e){e||r(l(this))},initEvent(){}},Object.defineProperty(i.prototype,"constructor",{value:i,configurable:!0,writable:!0}),"undefined"!=typeof window&&void 0!==window.Event&&(Object.setPrototypeOf(i.prototype,window.Event.prototype),n.set(window.Event.prototype,i))})),define("consul-ui/utils/dom/event-target/rsvp",["exports","rsvp","consul-ui/utils/dom/event-target/event-target-shim/event"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +t.stopped=!0,"boolean"==typeof t.event.cancelBubble&&(t.event.cancelBubble=!0)},get returnValue(){return!l(this).canceled},set returnValue(e){e||r(l(this))},initEvent(){}},Object.defineProperty(i.prototype,"constructor",{value:i,configurable:!0,writable:!0}),"undefined"!=typeof window&&void 0!==window.Event&&(Object.setPrototypeOf(i.prototype,window.Event.prototype),n.set(window.Event.prototype,i))})) +define("consul-ui/utils/dom/event-target/rsvp",["exports","rsvp","consul-ui/utils/dom/event-target/event-target-shim/event"],(function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 const l=function(){} l.prototype=Object.assign(Object.create(Object.prototype,{constructor:{value:l,configurable:!0,writable:!0}}),{dispatchEvent:function(e){const t=(0,n.wrapEvent)(this,e);(0,n.setCurrentTarget)(t,null) const l=e.type,r=t @@ -4201,8 +4218,7 @@ if("object"!=typeof l)return l throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string") return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){let l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{} if(void 0!==e.target)return e -return{target:n(n({},l),{name:e,value:t})}}})) -define("consul-ui/utils/dom/qsa-factory",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document +return{target:n(n({},l),{name:e,value:t})}}})),define("consul-ui/utils/dom/qsa-factory",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document return function(t){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:e).querySelectorAll(t)}}})),define("consul-ui/utils/dom/sibling",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){let n=e for(;n=n.nextSibling;)if(1===n.nodeType&&n.nodeName.toLowerCase()===t)return n}})),define("consul-ui/utils/editor/lint",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.createLoader=void 0,e.default=function(e,t){n(e,t,(function(){e.getValue().trim().length&&e.performLint()}))} const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:document.getElementsByTagName.bind(document),t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:CodeMirror @@ -4275,7 +4291,7 @@ case"CONSUL_UI_CONFIG":return r={service:void 0},i=t("CONSUL_METRICS_PROVIDER"), case"CONSUL_BASE_UI_URL":return c.split("/").slice(0,-2).join("/") case"CONSUL_HTTP_PROTOCOL":return void 0===d&&(d=function(e){try{return n.performance.getEntriesByType("resource").find((t=>"script"===t.initiatorType&&e===t.name))||{}}catch(t){return{}}}(c)),d.nextHopProtocol||"http/1.1" case"CONSUL_HTTP_MAX_CONNECTIONS":switch(l=t("CONSUL_HTTP_PROTOCOL"),!0){case 0===l.indexOf("h2"):case 0===l.indexOf("hq"):case 0===l.indexOf("spdy"):return -default:return 5}}},f=function(t){let n={} +default:return 5}case"CONSUL_V2_CATALOG_ENABLED":return"undefined"!==a.V2CatalogEnabled&&a.V2CatalogEnabled}},f=function(t){let n={} switch(e.environment){case"development":case"staging":case"coverage":case"test":n=i().reduce((function(e,t){let[n,l]=t switch(n){case"CONSUL_INTL_LOCALE":e.CONSUL_INTL_LOCALE=String(l).toLowerCase() break @@ -4301,6 +4317,8 @@ case"CONSUL_UI_CONFIG":e.CONSUL_UI_CONFIG=JSON.parse(l) break case"TokenSecretID":e.CONSUL_HTTP_TOKEN=l break +case"CONSUL_V2_CATALOG_ENABLE":e.CONSUL_V2_CATALOG_ENABLED=JSON.parse(l) +break default:e[n]=l}return e}),{}) break case"production":n=i().reduce((function(e,t){let[n,l]=t @@ -4308,7 +4326,7 @@ if("TokenSecretID"===n)e.CONSUL_HTTP_TOKEN=l return e}),{})}return void 0!==n[t]?n[t]:e[t]} return function e(t){switch(t){case"CONSUL_UI_DISABLE_REALTIME":case"CONSUL_UI_DISABLE_ANCHOR_SELECTION":return!!JSON.parse(String(o(t)||0).toLowerCase())||f(t) case"CONSUL_UI_REALTIME_RUNNER":return o(t)||f(t) -case"CONSUL_UI_CONFIG":case"CONSUL_DATACENTER_LOCAL":case"CONSUL_DATACENTER_PRIMARY":case"CONSUL_HCP_MANAGED_RUNTIME":case"CONSUL_API_PREFIX":case"CONSUL_HCP_URL":case"CONSUL_ACLS_ENABLED":case"CONSUL_NSPACES_ENABLED":case"CONSUL_PEERINGS_ENABLED":case"CONSUL_AGENTLESS_ENABLED":case"CONSUL_HCP_ENABLED":case"CONSUL_SSO_ENABLED":case"CONSUL_PARTITIONS_ENABLED":case"CONSUL_METRICS_PROVIDER":case"CONSUL_METRICS_PROXY_ENABLE":case"CONSUL_SERVICE_DASHBOARD_URL":case"CONSUL_BASE_UI_URL":case"CONSUL_HTTP_PROTOCOL":case"CONSUL_HTTP_MAX_CONNECTIONS":{const n=f(t) +case"CONSUL_UI_CONFIG":case"CONSUL_DATACENTER_LOCAL":case"CONSUL_DATACENTER_PRIMARY":case"CONSUL_HCP_MANAGED_RUNTIME":case"CONSUL_API_PREFIX":case"CONSUL_HCP_URL":case"CONSUL_ACLS_ENABLED":case"CONSUL_NSPACES_ENABLED":case"CONSUL_PEERINGS_ENABLED":case"CONSUL_AGENTLESS_ENABLED":case"CONSUL_HCP_ENABLED":case"CONSUL_SSO_ENABLED":case"CONSUL_PARTITIONS_ENABLED":case"CONSUL_METRICS_PROVIDER":case"CONSUL_METRICS_PROXY_ENABLE":case"CONSUL_SERVICE_DASHBOARD_URL":case"CONSUL_BASE_UI_URL":case"CONSUL_V2_CATALOG_ENABLED":case"CONSUL_HTTP_PROTOCOL":case"CONSUL_HTTP_MAX_CONNECTIONS":{const n=f(t) return void 0!==n?n:p(t,e)}default:return f(t)}}}})),define("consul-ui/utils/get-form-name-property",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){if(-1!==e.indexOf("["))return e.match(/(.*)\[(.*)\]/).slice(1) return["",e]}})),define("consul-ui/utils/helpers/call-if-type",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){return function(t){return function(n){let l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{} return typeof n[0]!==e?n[0]:t(n[0],l)}}}})),define("consul-ui/utils/http/consul",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.HEADERS_TOKEN=e.HEADERS_SYMBOL=e.HEADERS_PARTITION=e.HEADERS_NAMESPACE=e.HEADERS_INDEX=e.HEADERS_DIGEST=e.HEADERS_DEFAULT_ACL_POLICY=e.HEADERS_DATACENTER=void 0 @@ -4383,14 +4401,14 @@ return 0===e.indexOf(t)?e.substr(t.length):e}})),define("consul-ui/utils/maybe-c e.default=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],l=arguments.length>1&&void 0!==arguments[1]&&arguments[1] const r=new(arguments.length>2&&void 0!==arguments[2]?arguments[2]:n.default),i=e.shift().map((e=>(""===e.ServiceName&&r.set(e.Node,e.CheckID),e))).concat(e.reduce(((e,t)=>void 0===t?e:e.concat(t.reduce(((e,t)=>{if(""===t.ServiceName){if((r.get(t.Node)||[]).includes(t.CheckID))return e r.set(t.Node,t.CheckID)}return e.push(t),e}),[]))),[])) -return l&&i.filter((e=>(0,t.get)(e,"Exposable"))).forEach((e=>{(0,t.set)(e,"Exposed",l)})),i}})),define("consul-ui/utils/minimizeModel",["exports","@ember/object"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){if(Array.isArray(e))return e.filter((function(e){return!(0,t.get)(e,"isNew")})).map((function(e){return{ID:(0,t.get)(e,"ID"),Name:(0,t.get)(e,"Name")}}))}})),define("consul-ui/utils/non-empty-set",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){return function(t){return null==t||""===t?{}:{[e]:t}}}})),define("consul-ui/utils/path/resolve",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 +return l&&i.filter((e=>(0,t.get)(e,"Exposable"))).forEach((e=>{(0,t.set)(e,"Exposed",l)})),i}})),define("consul-ui/utils/minimizeModel",["exports","@ember/object"],(function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){if(Array.isArray(e))return e.filter((function(e){return!(0,t.get)(e,"isNew")})).map((function(e){return{ID:(0,t.get)(e,"ID"),Name:(0,t.get)(e,"Name")}}))}})) +define("consul-ui/utils/non-empty-set",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){return function(t){return null==t||""===t?{}:{[e]:t}}}})),define("consul-ui/utils/path/resolve",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 e.default=(e,t)=>0===t.indexOf("/")?t:t.split("/").reduce(((e,t,n,l)=>("."!==t&&(".."===t?e.pop():""===t&&n!==l.length-1||e.push(t)),e)),e.split("/")).join("/")})),define("consul-ui/utils/promisedTimeout",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Promise,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:setTimeout return function(n){let l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){} return new e(((e,r)=>{l(t((function(){e(n)}),n))}))}}})),define("consul-ui/utils/right-trim",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"" const n=e.length-t.length if(n>=0)return e.lastIndexOf(t)===n?e.substr(0,n):e -return e}})) -define("consul-ui/utils/routing/redirect-to",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){return function(t,n){const l=this.routeName.split(".").slice(0,-1).join(".") +return e}})),define("consul-ui/utils/routing/redirect-to",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){return function(t,n){const l=this.routeName.split(".").slice(0,-1).join(".") this.replaceWith(`${l}.${e}`,t)}}})),define("consul-ui/utils/routing/transitionable",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){let l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2?arguments[2]:void 0 null===e&&(e=r.lookup("route:application")) let i,o=n(e,l),a=e @@ -4462,4 +4480,4 @@ let l=e.split("."),r=l.pop(),i=l.join("."),u=(0,t.get)(o,i) return u&&u.hasOwnProperty&&u.hasOwnProperty(r)?n:(0,t.get)(a,e)}return o.hasOwnProperty(e)?(0,t.get)(o,e):(0,t.get)(a,e)}} return!n.call(u,o,a)||e(l,r,i,o,a)}}(e)}})),define("consul-ui/validations/token",["exports"],(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0 e.default={}})),define("consul-ui/config/environment",[],(function(){try{var e="consul-ui/config/environment",t=document.querySelector('meta[name="'+e+'"]').getAttribute("content"),n={default:JSON.parse(decodeURIComponent(t))} -return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(l){throw new Error('Could not read config from meta tag with name "'+e+'".')}})),runningTests||require("consul-ui/app").default.create({name:"consul-ui",version:"2.2.0+85171f50"}) +return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(l){throw new Error('Could not read config from meta tag with name "'+e+'".')}})),runningTests||require("consul-ui/app").default.create({name:"consul-ui",version:"2.2.0+3c24c491"}) diff --git a/agent/uiserver/dist/assets/consul-ui-ebf15e0a88f8aa4b2e353442d718d20d.css b/agent/uiserver/dist/assets/consul-ui-ebf15e0a88f8aa4b2e353442d718d20d.css deleted file mode 100644 index 6e8358ba96..0000000000 --- a/agent/uiserver/dist/assets/consul-ui-ebf15e0a88f8aa4b2e353442d718d20d.css +++ /dev/null @@ -1,2 +0,0 @@ -@charset "UTF-8";/*! tailwindcss v3.2.7 | MIT License | https://tailwindcss.com - */.hds-table,table{border-spacing:0}input[type=checkbox],input[type=radio],progress,sub,sup{vertical-align:baseline}.hover\:scale-125:hover,.scale-100,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.ease-in-out,.transition{transition-timing-function:cubic-bezier(.4,0,.2,1)}*,::after,::before{border-width:0;border-style:solid;border-color:currentColor}html{line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-feature-settings:normal}a,hr{color:inherit}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto}[hidden]{display:none}*,::after,::backdrop,::before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scroll-snap-strictness:proximity;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgb(59 130 246 / 0.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.invisible{visibility:hidden}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.hds-side-nav,.sticky{position:sticky}.bottom-0{bottom:0}.isolate{isolation:isolate}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-6{margin-bottom:1.5rem}.ml-4{margin-left:1rem}.mr-0{margin-right:0}.mr-0\.5{margin-right:.125rem}.mr-1{margin-right:.25rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mr-2\.5{margin-right:.625rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.contents{display:contents}.hidden{display:none}.h-12{height:3rem}.h-16{height:4rem}.h-24{height:6rem}.h-4{height:1rem}.h-48{height:12rem}.h-8{height:2rem}.h-full{height:100%}.\!w-80{width:20rem!important}.w-24{width:6rem}.w-4{width:1rem}.w-8{width:2rem}.w-full{width:100%}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-col,.hds-accordion{flex-direction:column}.scale-100{--tw-scale-x:1;--tw-scale-y:1}.cursor-pointer{cursor:pointer}.resize{resize:both}.flex-nowrap{flex-wrap:nowrap}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.space-x-12>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(3rem * var(--tw-space-x-reverse));margin-left:calc(3rem * calc(1 - var(--tw-space-x-reverse)))}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.overflow-x-auto{overflow-x:auto}.overflow-y-scroll{overflow-y:scroll}.hds-breadcrumb__text,.hds-card__container--overflow-hidden,.truncate{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.border{border-width:1px}.p-6{padding:1.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize,.type-source.popover-select li:not(.partition) button{text-transform:capitalize}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 rgb(0 0 0 / 0.1),0 1px 2px -1px rgb(0 0 0 / 0.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.hds-elevation-inset,.hds-form-checkbox:not(:checked,:indeterminate){box-shadow:var(--token-elevation-inset-box-shadow)}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-duration:150ms}.consul-surface-nav{background:var(--token-color-palette-neutral-700)}:root{--token-color-palette-blue-500:#1c345f;--token-color-palette-blue-400:#0046d1;--token-color-palette-blue-300:#0c56e9;--token-color-palette-blue-200:#1060ff;--token-color-palette-blue-100:#cce3fe;--token-color-palette-blue-50:#f2f8ff;--token-color-palette-purple-500:#42215b;--token-color-palette-purple-400:#7b00db;--token-color-palette-purple-300:#911ced;--token-color-palette-purple-200:#a737ff;--token-color-palette-purple-100:#ead2fe;--token-color-palette-purple-50:#f9f2ff;--token-color-palette-green-500:#054220;--token-color-palette-green-400:#006619;--token-color-palette-green-300:#00781e;--token-color-palette-green-200:#008a22;--token-color-palette-green-100:#cceeda;--token-color-palette-green-50:#f2fbf6;--token-color-palette-amber-500:#542800;--token-color-palette-amber-400:#803d00;--token-color-palette-amber-300:#9e4b00;--token-color-palette-amber-200:#bb5a00;--token-color-palette-amber-100:#fbeabf;--token-color-palette-amber-50:#fff9e8;--token-color-palette-red-500:#51130a;--token-color-palette-red-400:#940004;--token-color-palette-red-300:#c00005;--token-color-palette-red-200:#e52228;--token-color-palette-red-100:#fbd4d4;--token-color-palette-red-50:#fff5f5;--token-color-palette-neutral-700:#0c0c0e;--token-color-palette-neutral-600:#3b3d45;--token-color-palette-neutral-500:#656a76;--token-color-palette-neutral-400:#8c909c;--token-color-palette-neutral-300:#c2c5cb;--token-color-palette-neutral-200:#dedfe3;--token-color-palette-neutral-100:#f1f2f3;--token-color-palette-neutral-50:#fafafa;--token-color-palette-neutral-0:#ffffff;--token-color-palette-alpha-300:#3b3d4566;--token-color-palette-alpha-200:#656a7633;--token-color-palette-alpha-100:#656a761a;--token-color-border-primary:#656a7633;--token-color-border-faint:#656a761a;--token-color-border-strong:#3b3d4566;--token-color-border-action:#cce3fe;--token-color-border-highlight:#ead2fe;--token-color-border-success:#cceeda;--token-color-border-warning:#fbeabf;--token-color-border-critical:#fbd4d4;--token-color-focus-action-internal:#0c56e9;--token-color-focus-action-external:#5990ff;--token-color-focus-critical-internal:#c00005;--token-color-focus-critical-external:#dd7578;--token-color-foreground-strong:#0c0c0e;--token-color-foreground-primary:#3b3d45;--token-color-foreground-faint:#656a76;--token-color-foreground-high-contrast:#ffffff;--token-color-foreground-disabled:#8c909c;--token-color-foreground-action:#1060ff;--token-color-foreground-action-hover:#0c56e9;--token-color-foreground-action-active:#0046d1;--token-color-foreground-highlight:#a737ff;--token-color-foreground-highlight-on-surface:#911ced;--token-color-foreground-highlight-high-contrast:#42215b;--token-color-foreground-success:#008a22;--token-color-foreground-success-on-surface:#00781e;--token-color-foreground-success-high-contrast:#054220;--token-color-foreground-warning:#bb5a00;--token-color-foreground-warning-on-surface:#9e4b00;--token-color-foreground-warning-high-contrast:#542800;--token-color-foreground-critical:#e52228;--token-color-foreground-critical-on-surface:#c00005;--token-color-foreground-critical-high-contrast:#51130a;--token-color-page-primary:#ffffff;--token-color-page-faint:#fafafa;--token-color-surface-primary:#ffffff;--token-color-surface-faint:#fafafa;--token-color-surface-strong:#f1f2f3;--token-color-surface-interactive:#ffffff;--token-color-surface-interactive-hover:#f1f2f3;--token-color-surface-interactive-active:#dedfe3;--token-color-surface-interactive-disabled:#fafafa;--token-color-surface-action:#f2f8ff;--token-color-surface-highlight:#f9f2ff;--token-color-surface-success:#f2fbf6;--token-color-surface-warning:#fff9e8;--token-color-surface-critical:#fff5f5;--token-color-hashicorp-brand:#000000;--token-color-boundary-brand:#f24c53;--token-color-boundary-foreground:#cf2d32;--token-color-boundary-surface:#ffecec;--token-color-boundary-border:#fbd7d8;--token-color-boundary-gradient-primary-start:#f97076;--token-color-boundary-gradient-primary-stop:#db363b;--token-color-boundary-gradient-faint-start:#fffafa;--token-color-boundary-gradient-faint-stop:#ffecec;--token-color-consul-brand:#e03875;--token-color-consul-foreground:#d01c5b;--token-color-consul-surface:#ffe9f1;--token-color-consul-border:#ffcede;--token-color-consul-gradient-primary-start:#ff99be;--token-color-consul-gradient-primary-stop:#da306e;--token-color-consul-gradient-faint-start:#fff9fb;--token-color-consul-gradient-faint-stop:#ffe9f1;--token-color-hcp-brand:#000000;--token-color-nomad-brand:#06d092;--token-color-nomad-foreground:#008661;--token-color-nomad-surface:#d3fdeb;--token-color-nomad-border:#bff3dd;--token-color-nomad-gradient-primary-start:#bff3dd;--token-color-nomad-gradient-primary-stop:#60dea9;--token-color-nomad-gradient-faint-start:#f3fff9;--token-color-nomad-gradient-faint-stop:#d3fdeb;--token-color-packer-brand:#02a8ef;--token-color-packer-foreground:#007eb4;--token-color-packer-surface:#d4f2ff;--token-color-packer-border:#b4e4ff;--token-color-packer-gradient-primary-start:#b4e4ff;--token-color-packer-gradient-primary-stop:#63d0ff;--token-color-packer-gradient-faint-start:#f3fcff;--token-color-packer-gradient-faint-stop:#d4f2ff;--token-color-terraform-brand:#7b42bc;--token-color-terraform-foreground:#773cb4;--token-color-terraform-surface:#f4ecff;--token-color-terraform-border:#ebdbfc;--token-color-terraform-gradient-primary-start:#bb8deb;--token-color-terraform-gradient-primary-stop:#844fba;--token-color-terraform-gradient-faint-start:#fcfaff;--token-color-terraform-gradient-faint-stop:#f4ecff;--token-color-vagrant-brand:#1868f2;--token-color-vagrant-foreground:#1c61d8;--token-color-vagrant-surface:#d6ebff;--token-color-vagrant-border:#c7dbfc;--token-color-vagrant-gradient-primary-start:#c7dbfc;--token-color-vagrant-gradient-primary-stop:#7dadff;--token-color-vagrant-gradient-faint-start:#f4faff;--token-color-vagrant-gradient-faint-stop:#d6ebff;--token-color-vault-secrets-brand:#ffd814;--token-color-vault-secrets-brand-alt:#000000;--token-color-vault-secrets-foreground:#9a6f00;--token-color-vault-secrets-surface:#fff9cf;--token-color-vault-secrets-border:#feec7b;--token-color-vault-secrets-gradient-primary-start:#feec7b;--token-color-vault-secrets-gradient-primary-stop:#ffe543;--token-color-vault-secrets-gradient-faint-start:#fffdf2;--token-color-vault-secrets-gradient-faint-stop:#fff9cf;--token-color-vault-brand:#ffd814;--token-color-vault-brand-alt:#000000;--token-color-vault-foreground:#9a6f00;--token-color-vault-surface:#fff9cf;--token-color-vault-border:#feec7b;--token-color-vault-gradient-primary-start:#feec7b;--token-color-vault-gradient-primary-stop:#ffe543;--token-color-vault-gradient-faint-start:#fffdf2;--token-color-vault-gradient-faint-stop:#fff9cf;--token-color-waypoint-brand:#14c6cb;--token-color-waypoint-foreground:#008196;--token-color-waypoint-surface:#e0fcff;--token-color-waypoint-border:#cbf1f3;--token-color-waypoint-gradient-primary-start:#cbf1f3;--token-color-waypoint-gradient-primary-stop:#62d4dc;--token-color-waypoint-gradient-faint-start:#f6feff;--token-color-waypoint-gradient-faint-stop:#e0fcff;--token-elevation-inset-box-shadow:inset 0px 1px 2px 1px #656a761a;--token-elevation-low-box-shadow:0px 1px 1px 0px #656a760d,0px 2px 2px 0px #656a760d;--token-elevation-mid-box-shadow:0px 2px 3px 0px #656a761a,0px 8px 16px -10px #656a7633;--token-elevation-high-box-shadow:0px 2px 3px 0px #656a7626,0px 16px 16px -10px #656a7633;--token-elevation-higher-box-shadow:0px 2px 3px 0px #656a761a,0px 12px 28px 0px #656a7640;--token-elevation-overlay-box-shadow:0px 2px 3px 0px #3b3d4540,0px 12px 24px 0px #3b3d4559;--token-surface-inset-box-shadow:inset 0 0 0 1px #656a764d,inset 0px 1px 2px 1px #656a761a;--token-surface-base-box-shadow:0 0 0 1px #656a7633;--token-surface-low-box-shadow:0 0 0 1px #656a7626,0px 1px 1px 0px #656a760d,0px 2px 2px 0px #656a760d;--token-surface-mid-box-shadow:0 0 0 1px #656a7626,0px 2px 3px 0px #656a761a,0px 8px 16px -10px #656a7633;--token-surface-high-box-shadow:0 0 0 1px #656a7640,0px 2px 3px 0px #656a7626,0px 16px 16px -10px #656a7633;--token-surface-higher-box-shadow:0 0 0 1px #656a7633,0px 2px 3px 0px #656a761a,0px 12px 28px 0px #656a7640;--token-surface-overlay-box-shadow:0 0 0 1px #3b3d4540,0px 2px 3px 0px #3b3d4540,0px 12px 24px 0px #3b3d4559;--token-focus-ring-action-box-shadow:inset 0 0 0 1px #0c56e9,0 0 0 3px #5990ff;--token-focus-ring-critical-box-shadow:inset 0 0 0 1px #c00005,0 0 0 3px #dd7578;--token-form-label-color:#0c0c0e;--token-form-legend-color:#0c0c0e;--token-form-helper-text-color:#656a76;--token-form-indicator-optional-color:#656a76;--token-form-error-color:#c00005;--token-form-error-icon-size:14px;--token-form-checkbox-size:16px;--token-form-checkbox-border-radius:3px;--token-form-checkbox-border-width:1px;--token-form-checkbox-background-image-size:12px;--token-form-checkbox-background-image-data-url:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%23FFF'/%3e%3c/svg%3e");--token-form-checkbox-background-image-data-url-indeterminate:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='m2.03125,6a0.66146,0.75 0 0 1 0.66146,-0.75l6.61458,0a0.66146,0.75 0 0 1 0,1.5l-6.61458,0a0.66146,0.75 0 0 1 -0.66146,-0.75z' fill='%23FFF'/%3e%3c/svg%3e");--token-form-checkbox-background-image-data-url-disabled:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%238C909C'/%3e%3c/svg%3e");--token-form-checkbox-background-image-data-url-indeterminate-disabled:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='m2.03125,6a0.66146,0.75 0 0 1 0.66146,-0.75l6.61458,0a0.66146,0.75 0 0 1 0,1.5l-6.61458,0a0.66146,0.75 0 0 1 -0.66146,-0.75z' fill='%238C909C'/%3e%3c/svg%3e");--token-form-control-base-foreground-value-color:#0c0c0e;--token-form-control-base-foreground-placeholder-color:#656a76;--token-form-control-base-surface-color-default:#ffffff;--token-form-control-base-surface-color-hover:#f1f2f3;--token-form-control-base-border-color-default:#8c909c;--token-form-control-base-border-color-hover:#656a76;--token-form-control-checked-foreground-color:#ffffff;--token-form-control-checked-surface-color-default:#1060ff;--token-form-control-checked-surface-color-hover:#0c56e9;--token-form-control-checked-border-color-default:#0c56e9;--token-form-control-checked-border-color-hover:#0046d1;--token-form-control-invalid-border-color-default:#c00005;--token-form-control-invalid-border-color-hover:#940004;--token-form-control-readonly-foreground-color:#3b3d45;--token-form-control-readonly-surface-color:#f1f2f3;--token-form-control-readonly-border-color:#656a761a;--token-form-control-disabled-foreground-color:#8c909c;--token-form-control-disabled-surface-color:#fafafa;--token-form-control-disabled-border-color:#656a7633;--token-form-control-padding:7px;--token-form-control-border-radius:5px;--token-form-control-border-width:1px;--token-form-radio-size:16px;--token-form-radio-border-width:1px;--token-form-radio-background-image-size:12px;--token-form-radio-background-image-data-url:url("data:image/svg+xml,%3csvg width='12' height='12' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='6' cy='6' r='2.5' fill='%23ffffff'/%3e%3c/svg%3e");--token-form-radio-background-image-data-url-disabled:url("data:image/svg+xml,%3csvg width='12' height='12' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='6' cy='6' r='2.5' fill='%238C909C'/%3e%3c/svg%3e");--token-form-radiocard-group-gap:16px;--token-form-radiocard-border-width:1px;--token-form-radiocard-border-radius:6px;--token-form-radiocard-content-padding:24px;--token-form-radiocard-control-padding:8px;--token-form-radiocard-transition-duration:0.2s;--token-form-select-background-image-size:16px;--token-form-select-background-image-position-right-x:7px;--token-form-select-background-image-position-top-y:9px;--token-form-select-background-image-data-url:url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.55 2.24a.75.75 0 0 0-1.1 0L4.2 5.74a.75.75 0 1 0 1.1 1.02L8 3.852l2.7 2.908a.75.75 0 1 0 1.1-1.02l-3.25-3.5Zm-1.1 11.52a.75.75 0 0 0 1.1 0l3.25-3.5a.75.75 0 1 0-1.1-1.02L8 12.148 5.3 9.24a.75.75 0 0 0-1.1 1.02l3.25 3.5Z' fill='%23656A76'/%3E%3C/svg%3E");--token-form-select-background-image-data-url-disabled:url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.55 2.24a.75.75 0 0 0-1.1 0L4.2 5.74a.75.75 0 1 0 1.1 1.02L8 3.852l2.7 2.908a.75.75 0 1 0 1.1-1.02l-3.25-3.5Zm-1.1 11.52a.75.75 0 0 0 1.1 0l3.25-3.5a.75.75 0 1 0-1.1-1.02L8 12.148 5.3 9.24a.75.75 0 0 0-1.1 1.02l3.25 3.5Z' fill='%238C909C'/%3E%3C/svg%3E");--token-form-text-input-background-image-size:16px;--token-form-text-input-background-image-position-x:7px;--token-form-text-input-background-image-data-url-date:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M11.5.75a.75.75 0 00-1.5 0V1H6V.75a.75.75 0 00-1.5 0V1H3.25A2.25 2.25 0 001 3.25v9.5A2.25 2.25 0 003.25 15h9.5A2.25 2.25 0 0015 12.75v-9.5A2.25 2.25 0 0012.75 1H11.5V.75zm-7 2.5V2.5H3.25a.75.75 0 00-.75.75V5h11V3.25a.75.75 0 00-.75-.75H11.5v.75a.75.75 0 01-1.5 0V2.5H6v.75a.75.75 0 01-1.5 0zm9 3.25h-11v6.25c0 .414.336.75.75.75h9.5a.75.75 0 00.75-.75V6.5z' fill-rule='evenodd' clip-rule='evenodd' fill='%233B3D45'/%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-time:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cg fill='%233B3D45'%3e%3cpath d='M8.5 3.75a.75.75 0 00-1.5 0V8c0 .284.16.544.415.67l2.5 1.25a.75.75 0 10.67-1.34L8.5 7.535V3.75z'/%3e%3cpath d='M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z' fill-rule='evenodd' clip-rule='evenodd'/%3e%3c/g%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-search:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cg fill='%23656A76'%3e%3cpath d='M7.25 2a5.25 5.25 0 103.144 9.455l2.326 2.325a.75.75 0 101.06-1.06l-2.325-2.326A5.25 5.25 0 007.25 2zM3.5 7.25a3.75 3.75 0 117.5 0 3.75 3.75 0 01-7.5 0z' fill-rule='evenodd' clip-rule='evenodd'/%3e%3c/g%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-search-cancel:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.78 4.28a.75.75 0 00-1.06-1.06L8 6.94 4.28 3.22a.75.75 0 00-1.06 1.06L6.94 8l-3.72 3.72a.75.75 0 101.06 1.06L8 9.06l3.72 3.72a.75.75 0 101.06-1.06L9.06 8l3.72-3.72z'/%3e%3c/svg%3e");--token-form-text-input-background-image-data-url-search-loading:url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg' %3e%3cg fill='%23656A76' fill-rule='evenodd' clip-rule='evenodd'%3e%3canimateTransform attributeName='transform' type='rotate' dur='0.9s' from='0 8 8' to='360 8 8' repeatCount='indefinite'/%3e%3cpath d='M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z' opacity='.2'/%3e%3cpath d='M7.25.75A.75.75 0 018 0a8 8 0 018 8 .75.75 0 01-1.5 0A6.5 6.5 0 008 1.5a.75.75 0 01-.75-.75z'/%3e%3c/g%3e%3c/svg%3e");--token-form-toggle-width:32px;--token-form-toggle-height:16px;--token-form-toggle-base-surface-color-default:#f1f2f3;--token-form-toggle-border-radius:3px;--token-form-toggle-border-width:1px;--token-form-toggle-background-image-size:12px;--token-form-toggle-background-image-position-x:2px;--token-form-toggle-background-image-data-url:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%23FFF'/%3e%3c/svg%3e");--token-form-toggle-background-image-data-url-disabled:url("data:image/svg+xml,%3csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M9.78033 3.21967C10.0732 3.51256 10.0732 3.98744 9.78033 4.28033L5.28033 8.78033C4.98744 9.07322 4.51256 9.07322 4.21967 8.78033L2.21967 6.78033C1.92678 6.48744 1.92678 6.01256 2.21967 5.71967C2.51256 5.42678 2.98744 5.42678 3.28033 5.71967L4.75 7.18934L8.71967 3.21967C9.01256 2.92678 9.48744 2.92678 9.78033 3.21967Z' fill='%238C909C'/%3e%3c/svg%3e");--token-form-toggle-transition-duration:0.2s;--token-form-toggle-transition-timing-function:cubic-bezier(0.68, -0.2, 0.265, 1.15);--token-form-toggle-thumb-size:16px;--token-pagination-nav-control-height:36px;--token-pagination-nav-control-padding-horizontal:12px;--token-pagination-nav-control-focus-inset:4px;--token-pagination-nav-control-icon-spacing:6px;--token-pagination-nav-indicator-height:2px;--token-pagination-nav-indicator-spacing:6px;--token-pagination-child-spacing-vertical:8px;--token-pagination-child-spacing-horizontal:20px;--token-side-nav-wrapper-border-width:1px;--token-side-nav-wrapper-border-color:#656a76;--token-side-nav-wrapper-padding-horizontal:16px;--token-side-nav-wrapper-padding-vertical:16px;--token-side-nav-wrapper-padding-horizontal-minimized:8px;--token-side-nav-wrapper-padding-vertical-minimized:22px;--token-side-nav-toggle-button-border-radius:5px;--token-side-nav-header-home-link-padding:4px;--token-side-nav-header-home-link-logo-size:48px;--token-side-nav-header-home-link-logo-size-minimized:32px;--token-side-nav-header-actions-spacing:8px;--token-side-nav-body-list-margin-vertical:24px;--token-side-nav-body-list-item-height:36px;--token-side-nav-body-list-item-padding-horizontal:8px;--token-side-nav-body-list-item-padding-vertical:4px;--token-side-nav-body-list-item-spacing-vertical:2px;--token-side-nav-body-list-item-content-spacing-horizontal:8px;--token-side-nav-body-list-item-border-radius:5px;--token-side-nav-color-foreground-primary:#dedfe3;--token-side-nav-color-foreground-strong:#fff;--token-side-nav-color-foreground-faint:#8c909c;--token-side-nav-color-surface-primary:#0c0c0e;--token-side-nav-color-surface-interactive-hover:#3b3d45;--token-side-nav-color-surface-interactive-active:#656a76;--token-tabs-tab-height:36px;--token-tabs-tab-padding-horizontal:12px;--token-tabs-tab-padding-vertical:0px;--token-tabs-tab-border-radius:5px;--token-tabs-tab-focus-inset:6px;--token-tabs-tab-gutter:6px;--token-tabs-indicator-height:3px;--token-tabs-indicator-transition-function:cubic-bezier(0.5, 1, 0.89, 1);--token-tabs-indicator-transition-duration:0.6s;--token-tabs-divider-height:1px;--token-tooltip-border-radius:5px;--token-tooltip-color-foreground-primary:var(--token-color-foreground-high-contrast);--token-tooltip-color-surface-primary:var(--token-color-palette-neutral-700);--token-tooltip-focus-offset:-2px;--token-tooltip-max-width:280px;--token-tooltip-padding-horizontal:12px;--token-tooltip-padding-vertical:8px;--token-tooltip-transition-function:cubic-bezier(0.54, 1.5, 0.38, 1.11);--token-typography-font-stack-display:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-font-stack-text:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-font-stack-code:ui-monospace,Menlo,Consolas,monospace;--token-typography-font-weight-regular:400;--token-typography-font-weight-medium:500;--token-typography-font-weight-semibold:600;--token-typography-font-weight-bold:700;--token-typography-display-500-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-500-font-size:1.875rem;--token-typography-display-500-line-height:1.2666;--token-typography-display-400-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-400-font-size:1.5rem;--token-typography-display-400-line-height:1.3333;--token-typography-display-300-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-300-font-size:1.125rem;--token-typography-display-300-line-height:1.3333;--token-typography-display-300-letter-spacing:-0.5px;--token-typography-display-200-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-200-font-size:1rem;--token-typography-display-200-line-height:1.5;--token-typography-display-200-letter-spacing:-0.5px;--token-typography-display-100-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-display-100-font-size:0.8125rem;--token-typography-display-100-line-height:1.3846;--token-typography-body-300-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-body-300-font-size:1rem;--token-typography-body-300-line-height:1.5;--token-typography-body-200-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-body-200-font-size:0.875rem;--token-typography-body-200-line-height:1.4286;--token-typography-body-100-font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;--token-typography-body-100-font-size:0.8125rem;--token-typography-body-100-line-height:1.3846;--token-typography-code-100-font-family:ui-monospace,Menlo,Consolas,monospace;--token-typography-code-100-font-size:0.8125rem;--token-typography-code-100-line-height:1.23;--token-typography-code-200-font-family:ui-monospace,Menlo,Consolas,monospace;--token-typography-code-200-font-size:0.875rem;--token-typography-code-200-line-height:1.125;--token-typography-code-300-font-family:ui-monospace,Menlo,Consolas,monospace;--token-typography-code-300-font-size:1rem;--token-typography-code-300-line-height:1.25;--hds-app-desktop-breakpoint:1088px;--hds-app-sidenav-width-minimized:48px;--hds-app-sidenav-width-expanded:280px;--hds-app-sidenav-width-fixed:var(--hds-app-sidenav-width-expanded);--hds-app-sidenav-animation-duration:200ms;--hds-app-sidenav-animation-delay:var(--hds-app-sidenav-animation-duration);--hds-app-sidenav-animation-easing:cubic-bezier(0.65, 0, 0.35, 1);--decor-radius-000:0;--decor-radius-100:2px;--decor-radius-200:4px;--decor-radius-250:6px;--decor-radius-300:7px;--decor-radius-999:9999px;--decor-radius-full:100%;--decor-border-000:none;--decor-border-100:1px solid;--decor-border-200:2px solid;--decor-border-300:3px solid;--decor-border-400:4px solid;--icon-alert-triangle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-alert-triangle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-left-16:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-left-24:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-right-16:url('data:image/svg+xml;charset=UTF-8,');--icon-arrow-right-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-fill-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-fill-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-down-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-down-24:url('data:image/svg+xml;charset=UTF-8,');--icon-clipboard-copy-16:url('data:image/svg+xml;charset=UTF-8,');--icon-clipboard-copy-24:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-16:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-24:url('data:image/svg+xml;charset=UTF-8,');--icon-external-link-16:url('data:image/svg+xml;charset=UTF-8,');--icon-external-link-24:url('data:image/svg+xml;charset=UTF-8,');--icon-file-16:url('data:image/svg+xml;charset=UTF-8,');--icon-file-24:url('data:image/svg+xml;charset=UTF-8,');--icon-folder-16:url('data:image/svg+xml;charset=UTF-8,');--icon-folder-24:url('data:image/svg+xml;charset=UTF-8,');--icon-activity-16:url('data:image/svg+xml;charset=UTF-8,');--icon-activity-24:url('data:image/svg+xml;charset=UTF-8,');--icon-help-16:url('data:image/svg+xml;charset=UTF-8,');--icon-help-24:url('data:image/svg+xml;charset=UTF-8,');--icon-learn-16:url('data:image/svg+xml;charset=UTF-8,');--icon-learn-24:url('data:image/svg+xml;charset=UTF-8,');--icon-github-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-github-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-google-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-google-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-kubernetes-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-kubernetes-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-menu-16:url('data:image/svg+xml;charset=UTF-8,');--icon-menu-24:url('data:image/svg+xml;charset=UTF-8,');--icon-minus-square-16:url('data:image/svg+xml;charset=UTF-8,');--icon-minus-square-24:url('data:image/svg+xml;charset=UTF-8,');--icon-more-horizontal-16:url('data:image/svg+xml;charset=UTF-8,');--icon-more-horizontal-24:url('data:image/svg+xml;charset=UTF-8,');--icon-globe-16:url('data:image/svg+xml;charset=UTF-8,');--icon-globe-24:url('data:image/svg+xml;charset=UTF-8,');--icon-search-16:url('data:image/svg+xml;charset=UTF-8,');--icon-search-24:url('data:image/svg+xml;charset=UTF-8,');--icon-star-16:url('data:image/svg+xml;charset=UTF-8,');--icon-star-24:url('data:image/svg+xml;charset=UTF-8,');--icon-org-16:url('data:image/svg+xml;charset=UTF-8,');--icon-org-24:url('data:image/svg+xml;charset=UTF-8,');--icon-user-16:url('data:image/svg+xml;charset=UTF-8,');--icon-user-24:url('data:image/svg+xml;charset=UTF-8,');--icon-users-16:url('data:image/svg+xml;charset=UTF-8,');--icon-users-24:url('data:image/svg+xml;charset=UTF-8,');--icon-alert-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-alert-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-check-16:url('data:image/svg+xml;charset=UTF-8,');--icon-check-24:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-fill-16:url('data:image/svg+xml;charset=UTF-8,');--icon-check-circle-fill-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-left-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-left-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-right-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-right-24:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-up-16:url('data:image/svg+xml;charset=UTF-8,');--icon-chevron-up-24:url('data:image/svg+xml;charset=UTF-8,');--icon-delay-16:url('data:image/svg+xml;charset=UTF-8,');--icon-delay-24:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-link-16:url('data:image/svg+xml;charset=UTF-8,');--icon-docs-link-24:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-16:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-24:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-off-16:url('data:image/svg+xml;charset=UTF-8,');--icon-eye-off-24:url('data:image/svg+xml;charset=UTF-8,');--icon-file-text-16:url('data:image/svg+xml;charset=UTF-8,');--icon-file-text-24:url('data:image/svg+xml;charset=UTF-8,');--icon-gateway-16:url('data:image/svg+xml;charset=UTF-8,');--icon-gateway-24:url('data:image/svg+xml;charset=UTF-8,');--icon-git-commit-16:url('data:image/svg+xml;charset=UTF-8,');--icon-git-commit-24:url('data:image/svg+xml;charset=UTF-8,');--icon-hexagon-16:url('data:image/svg+xml;charset=UTF-8,');--icon-hexagon-24:url('data:image/svg+xml;charset=UTF-8,');--icon-history-16:url('data:image/svg+xml;charset=UTF-8,');--icon-history-24:url('data:image/svg+xml;charset=UTF-8,');--icon-info-16:url('data:image/svg+xml;charset=UTF-8,');--icon-info-24:url('data:image/svg+xml;charset=UTF-8,');--icon-layers-16:url('data:image/svg+xml;charset=UTF-8,');--icon-layers-24:url('data:image/svg+xml;charset=UTF-8,');--icon-loading-16:url('data:image/svg+xml;charset=UTF-8,');--icon-loading-24:url('data:image/svg+xml;charset=UTF-8,');--icon-network-alt-16:url('data:image/svg+xml;charset=UTF-8,');--icon-network-alt-24:url('data:image/svg+xml;charset=UTF-8,');--icon-path-16:url('data:image/svg+xml;charset=UTF-8,');--icon-path-24:url('data:image/svg+xml;charset=UTF-8,');--icon-running-16:url('data:image/svg+xml;charset=UTF-8,');--icon-running-24:url('data:image/svg+xml;charset=UTF-8,');--icon-skip-16:url('data:image/svg+xml;charset=UTF-8,');--icon-skip-24:url('data:image/svg+xml;charset=UTF-8,');--icon-socket-16:url('data:image/svg+xml;charset=UTF-8,');--icon-socket-24:url('data:image/svg+xml;charset=UTF-8,');--icon-star-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-star-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-star-fill-16:url('data:image/svg+xml;charset=UTF-8,');--icon-star-fill-24:url('data:image/svg+xml;charset=UTF-8,');--icon-tag-16:url('data:image/svg+xml;charset=UTF-8,');--icon-tag-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-circle-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-circle-24:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-16:url('data:image/svg+xml;charset=UTF-8,');--icon-x-square-24:url('data:image/svg+xml;charset=UTF-8,');--icon-cloud-cross-16:url('data:image/svg+xml;charset=UTF-8,');--icon-loading-motion-16:url('data:image/svg+xml;charset=UTF-8,');--icon-auth0-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-auth0-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-ember-circle-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-glimmer-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-jwt-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-microsoft-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-microsoft-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-logo-oidc-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-okta-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-okta-color-24:url('data:image/svg+xml;charset=UTF-8,');--icon-mesh-16:url('data:image/svg+xml;charset=UTF-8,');--icon-mesh-24:url('data:image/svg+xml;charset=UTF-8,');--icon-port-16:url('data:image/svg+xml;charset=UTF-8,');--icon-protocol-16:url('data:image/svg+xml;charset=UTF-8,');--icon-redirect-16:url('data:image/svg+xml;charset=UTF-8,');--icon-redirect-24:url('data:image/svg+xml;charset=UTF-8,');--icon-search-color-16:url('data:image/svg+xml;charset=UTF-8,');--icon-sort-desc-16:url('data:image/svg+xml;charset=UTF-8,');--icon-sort-desc-24:url('data:image/svg+xml;charset=UTF-8,');--icon-union-16:url('data:image/svg+xml;charset=UTF-8,');--chrome-width:280px;--chrome-height:64px;--typo-action:var(--token-color-foreground-action);--decor-error:var(--token-color-foreground-critical);--typo-contrast:var(--token-color-hashicorp-brand);--syntax-light-grey:#dde3e7;--syntax-light-gray:#a4a4a4;--syntax-light-grey-blue:#6c7b81;--syntax-dark-grey:#788290;--syntax-faded-gray:#eaeaea;--syntax-atlas:#127eff;--syntax-vagrant:#2f88f7;--syntax-consul:#69499a;--syntax-terraform:#822ff7;--syntax-serf:#dd4e58;--syntax-packer:#1ddba3;--syntax-gray:lighten(#000, 89%);--syntax-red:#ff3d3d;--syntax-green:#39b54a;--syntax-dark-gray:#535f73;--syntax-gutter-grey:#2a2f36;--syntax-yellow:var(--token-color-vault-brand);--horizontal-kv-list-separator-width:18px;--horizontal-kv-list-key-separator:":";--horizontal-kv-list-key-wrapper-start:"(";--horizontal-kv-list-key-wrapper-end:")";--csv-list-separator:",";--icon-loading:icon-loading-motion;--color-info:var(--token-color-foreground-action);--color-alert:var(--token-color-palette-amber-200)}.hds-border-primary{border:1px solid var(--token-color-border-primary)}.hds-border-faint{border:1px solid var(--token-color-border-faint)}.hds-border-strong{border:1px solid var(--token-color-border-strong)}.hds-border-action{border:1px solid var(--token-color-border-action)}.hds-border-highlight{border:1px solid var(--token-color-border-highlight)}.hds-border-success{border:1px solid var(--token-color-border-success)}.hds-border-warning{border:1px solid var(--token-color-border-warning)}.hds-border-critical{border:1px solid var(--token-color-border-critical)}.hds-foreground-strong{color:var(--token-color-foreground-strong)}.hds-foreground-primary{color:var(--token-color-foreground-primary)}.hds-foreground-faint{color:var(--token-color-foreground-faint)}.hds-foreground-high-contrast{color:var(--token-color-foreground-high-contrast)}.hds-foreground-disabled{color:var(--token-color-foreground-disabled)}.hds-foreground-action{color:var(--token-color-foreground-action)}.hds-foreground-action-hover{color:var(--token-color-foreground-action-hover)}.hds-foreground-action-active{color:var(--token-color-foreground-action-active)}.hds-foreground-highlight{color:var(--token-color-foreground-highlight)}.hds-foreground-highlight-on-surface{color:var(--token-color-foreground-highlight-on-surface)}.hds-foreground-highlight-high-contrast{color:var(--token-color-foreground-highlight-high-contrast)}.hds-foreground-success{color:var(--token-color-foreground-success)}.hds-foreground-success-on-surface{color:var(--token-color-foreground-success-on-surface)}.hds-foreground-success-high-contrast{color:var(--token-color-foreground-success-high-contrast)}.hds-foreground-warning{color:var(--token-color-foreground-warning)}.hds-foreground-warning-on-surface{color:var(--token-color-foreground-warning-on-surface)}.hds-foreground-warning-high-contrast{color:var(--token-color-foreground-warning-high-contrast)}.hds-foreground-critical{color:var(--token-color-foreground-critical)}.hds-foreground-critical-on-surface{color:var(--token-color-foreground-critical-on-surface)}.hds-foreground-critical-high-contrast{color:var(--token-color-foreground-critical-high-contrast)}.hds-page-primary{background-color:var(--token-color-page-primary)}.hds-page-faint{background-color:var(--token-color-page-faint)}.hds-surface-primary{background-color:var(--token-color-surface-primary)}.hds-surface-faint{background-color:var(--token-color-surface-faint)}.hds-badge--color-neutral.hds-badge--type-filled,.hds-surface-strong{background-color:var(--token-color-surface-strong)}.hds-surface-interactive{background-color:var(--token-color-surface-interactive)}.hds-surface-interactive-hover{background-color:var(--token-color-surface-interactive-hover)}.hds-surface-interactive-active{background-color:var(--token-color-surface-interactive-active)}.hds-surface-interactive-disabled{background-color:var(--token-color-surface-interactive-disabled)}.hds-surface-action{background-color:var(--token-color-surface-action)}.hds-surface-highlight{background-color:var(--token-color-surface-highlight)}.hds-surface-success{background-color:var(--token-color-surface-success)}.hds-surface-warning{background-color:var(--token-color-surface-warning)}.hds-surface-critical{background-color:var(--token-color-surface-critical)}.hds-elevation-low{box-shadow:var(--token-elevation-low-box-shadow)}.hds-elevation-mid{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-elevation-high{box-shadow:var(--token-elevation-high-box-shadow)}.hds-elevation-higher{box-shadow:var(--token-elevation-higher-box-shadow)}.consul-server-list a:hover div,.hds-elevation-overlay,.modal-dialog [role=document]{box-shadow:var(--token-elevation-overlay-box-shadow)}.hds-surface-inset{box-shadow:var(--token-surface-inset-box-shadow)}.hds-surface-base{box-shadow:var(--token-surface-base-box-shadow)}.hds-surface-low{box-shadow:var(--token-surface-low-box-shadow)}.hds-accordion-item.hds-accordion-item--does-not-contain-interactive,.hds-surface-mid{box-shadow:var(--token-surface-mid-box-shadow)}.hds-surface-high{box-shadow:var(--token-surface-high-box-shadow)}.hds-surface-higher{box-shadow:var(--token-surface-higher-box-shadow)}.hds-surface-overlay{box-shadow:var(--token-surface-overlay-box-shadow)}.hds-focus-ring-action-box-shadow{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-focus-ring-critical-box-shadow{box-shadow:var(--token-focus-ring-critical-box-shadow)}.hds-font-family-sans-display{font-family:var(--token-typography-font-stack-display)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive,.hds-badge-count,.hds-badge__text,.hds-breadcrumb__text,.hds-button,.hds-font-family-sans-text{font-family:var(--token-typography-font-stack-text)}.hds-font-family-mono-code{font-family:var(--token-typography-font-stack-code)}#metrics-container .sparkline-wrapper .tooltip,.app-view h1 span.kind-proxy,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.app-view>div form:not(.filter-bar) [role=radiogroup] label>strong,.auth-form em,.consul-auth-method-type,.consul-auth-method-view section,.consul-external-source,.consul-health-check-list .health-check-output dd em,.consul-health-check-list .health-check-output dl>dd,.consul-intention-fieldsets .permissions>button,.consul-intention-list td strong,.consul-intention-list td.destination em,.consul-intention-list td.permissions,.consul-intention-list td.source em,.consul-intention-permission-header-list>ul>li dd,.consul-intention-permission-list strong,.consul-intention-permission-list>ul>li dd,.consul-intention-search-bar li button span,.consul-kind,.consul-peer-search-bar li button span,.consul-server-card .health-status+dd,.consul-source,.consul-transparent-proxy,.disclosure-menu [aria-expanded]~*>div,.discovery-chain .resolvers>header>*,.discovery-chain .route-card header dt,.discovery-chain .route-card>header ul li,.discovery-chain .routes>header>*,.discovery-chain .splitters>header>*,.empty-state header :nth-child(2),.empty-state p,.empty-state>ul>li>*,.empty-state>ul>li>::before,.empty-state>ul>li>label>button,.empty-state>ul>li>label>button::before,.has-error>strong,.has-error>strong::before,.hds-font-weight-regular,.informed-action p,.leader,.menu-panel>div,.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-password>strong,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-select>strong,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] .type-text>strong,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] [role=radiogroup] label>strong,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] label a[rel*=help],.modal-dialog [role=document] p,.modal-dialog [role=document] table td,.modal-dialog [role=document] table td p,.modal-dialog [role=document] table th em,.more-popover-menu>[type=checkbox]+label+div>div,.oidc-select button.reset,.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.oidc-select label>em,.oidc-select label>span,.oidc-select label>strong,.popover-menu>[type=checkbox]+label+div>div,.search-bar-status li:not(.remove-all),.tippy-box[data-theme~=tooltip] .tippy-content,.topology-metrics-source-type,.topology-metrics-status-error,.topology-metrics-status-loader,.type-toggle [type=password],.type-toggle [type=text],.type-toggle textarea,.type-toggle>em,.type-toggle>span,.type-toggle>strong,body,html[data-route^="dc.acls.index"] main td strong,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-password>em,main .type-password>span,main .type-password>strong,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-select>em,main .type-select>span,main .type-select>strong,main .type-text [type=password],main .type-text [type=text],main .type-text textarea,main .type-text>em,main .type-text>span,main .type-text>strong,main form button+em,main label a[rel*=help],main p,main table td,main table td p,main table th em,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dt,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,section[data-route="dc.show.license"] .validity dl,span.label,span.policy-node-identity,span.policy-service-identity,table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div>div{font-weight:400}.app-view h1 em,.consul-exposed-path-list>ul>li .copy-button button,.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child) .copy-button button,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-peer-search-bar .value-active span,.consul-peer-search-bar .value-deleting span,.consul-peer-search-bar .value-establishing span,.consul-peer-search-bar .value-failing span,.consul-peer-search-bar .value-pending span,.consul-peer-search-bar .value-terminated span,.consul-upstream-instance-list li .copy-button button,.consul-upstream-instance-list li>.header,.disclosure-menu [aria-expanded]~* [role=separator],.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.hds-font-weight-medium,.informed-action>ul>li>*,.list-collection>ul>li:not(:first-child) .copy-button button,.list-collection>ul>li:not(:first-child)>.header,.menu-panel [role=separator],.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div [role=separator],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.peerings-badge .peerings-badge__text,.popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.tab-nav,main header nav:first-child ol li>*,table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{font-weight:500}#downstream-container .topology-metrics-card p,#metrics-container .sparkline-wrapper .tooltip .sparkline-time,#metrics-container div:first-child,#upstream-container .topology-metrics-card p,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.code-editor .toolbar-container .toolbar .title,.consul-auth-method-binding-list h2,.consul-auth-method-nspace-list thead td,.consul-auth-method-view section h2,.consul-auth-method-view section table thead td,.consul-bucket-list .service+dd,.consul-health-check-list .health-check-output dt,.consul-health-check-list .health-check-output header>*,.consul-intention-action-warn-modal button.dangerous,.consul-intention-list td.destination,.consul-intention-list td.source,.consul-intention-permission-form h2,.consul-intention-view h2,.consul-peer-form-generate li::after,.consul-server-card .name+dd,.copy-button button,.definition-table dt,.empty-state header :first-child,.hds-font-weight-semibold,.informed-action header,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] form h2,.modal-dialog [role=document] table caption,.modal-dialog [role=document] table td:first-child,.modal-dialog [role=document] table td:first-child p,.modal-dialog [role=document] table th,.modal-dialog [role=document]>header>:not(button),.modal-dialog-body h2,.oidc-select label>span,.popover-select label>*,.radio-card header,.sparkline-key h3,.topology-notices button,.type-sort.popover-select label>*,.type-toggle label span,.type-toggle>span,.warning.modal-dialog header>:not(label),fieldset>header,html[data-route^="dc.services.instance.metadata"] .tab-section section h2,html[data-route^="dc.kv.edit"] h2,main .type-password>span,main .type-select>span,main .type-text>span,main form h2,main table caption,main table td:first-child,main table td:first-child p,main table th,section[data-route="dc.show.serverstatus"] .redundancy-zones h3,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dd,section[data-route="dc.show.serverstatus"] h2,section[data-route="dc.show.serverstatus"] h3,section[data-route="dc.show.license"] aside header>:first-child,section[data-route="dc.show.license"] h2,span.label,strong{font-weight:600}.discovery-chain .route-card header:not(.short) dd,.discovery-chain .route-card section dt,.discovery-chain .splitter-card>header,.hds-font-weight-bold,h1{font-weight:700}.hds-typography-display-500,h1{font-family:var(--token-typography-display-500-font-family);font-size:var(--token-typography-display-500-font-size);line-height:var(--token-typography-display-500-line-height);margin:0;padding:0}.consul-auth-method-binding-list h2,.consul-auth-method-view section h2,.consul-intention-permission-form h2,.consul-intention-view h2,.empty-state header :first-child,.hds-typography-display-400,.modal-dialog [role=document] form h2,.modal-dialog [role=document]>header>:not(button),.modal-dialog-body h2,html[data-route^="dc.kv.edit"] h2,main form h2,section[data-route="dc.show.license"] h2{font-family:var(--token-typography-display-400-font-family);font-size:var(--token-typography-display-400-font-size);line-height:var(--token-typography-display-400-line-height);margin:0;padding:0}#downstream-container .topology-metrics-card p,#upstream-container .topology-metrics-card p,.consul-exposed-path-list>ul>li>.header,.consul-health-check-list .health-check-output header>*,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.header,.hds-typography-display-300,.list-collection>ul>li:not(:first-child)>.header,.sparkline-key h3,.warning.modal-dialog header>:not(label),html[data-route^="dc.services.instance.metadata"] .tab-section section h2,section[data-route="dc.show.serverstatus"] .redundancy-zones h3,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dd,section[data-route="dc.show.serverstatus"] h2,section[data-route="dc.show.serverstatus"] h3,section[data-route="dc.show.license"] aside header>:first-child{font-family:var(--token-typography-display-300-font-family);font-size:var(--token-typography-display-300-font-size);line-height:var(--token-typography-display-300-line-height);margin:0;padding:0}.consul-server-card .name+dd,.hds-side-nav .ember-a11y-refocus-skip-link,.hds-typography-display-200{font-size:var(--token-typography-display-200-font-size);line-height:var(--token-typography-display-200-line-height)}.consul-server-card .name+dd,.hds-typography-display-200{font-family:var(--token-typography-display-200-font-family);margin:0;padding:0}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.consul-intention-list td.destination,.consul-intention-list td.source,.definition-table dt,.hds-typography-display-100,.informed-action header,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] table caption,.modal-dialog [role=document] table th,.oidc-select label>span,.radio-card header,.type-toggle>span,fieldset>header,main .type-password>span,main .type-select>span,main .type-text>span,main table caption,main table th{font-family:var(--token-typography-display-100-font-family);font-size:var(--token-typography-display-100-font-size);line-height:var(--token-typography-display-100-line-height);margin:0;padding:0}#metrics-container div:first-child,.hds-typography-body-300,section[data-route="dc.show.license"] .validity dl{font-family:var(--token-typography-body-300-font-family);font-size:var(--token-typography-body-300-font-size);line-height:var(--token-typography-body-300-line-height);margin:0;padding:0}#metrics-container .sparkline-wrapper .tooltip,#metrics-container .sparkline-wrapper .tooltip .sparkline-time,.app-view h1 em,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.code-editor .toolbar-container .toolbar .title,.consul-auth-method-nspace-list thead td,.consul-auth-method-view section,.consul-auth-method-view section table thead td,.consul-external-source,.consul-health-check-list .health-check-output dl>dd,.consul-health-check-list .health-check-output dt,.consul-kind,.consul-peer-form-generate li::after,.consul-source,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.empty-state>ul>li>::before,.empty-state>ul>li>label>button::before,.has-error>strong::before,.hds-typography-body-200,.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.modal-dialog [role=document] table td,.modal-dialog [role=document] table td p,.modal-dialog [role=document] table td:first-child,.modal-dialog [role=document] table td:first-child p,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.tab-nav,.topology-metrics-status-error,.topology-metrics-status-loader,.type-toggle [type=password],.type-toggle [type=text],.type-toggle label span,.type-toggle textarea,body,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-text [type=password],main .type-text [type=text],main .type-text textarea,main header nav:first-child ol li>*,main table td,main table td p,main table td:first-child,main table td:first-child p,strong,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{font-family:var(--token-typography-body-200-font-family);font-size:var(--token-typography-body-200-font-size);line-height:var(--token-typography-body-200-line-height);margin:0;padding:0}.app-view h1 span.kind-proxy,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.auth-form em,.consul-exposed-path-list>ul>li .copy-button button,.consul-intention-action-warn-modal button.dangerous,.consul-intention-fieldsets .permissions>button,.consul-intention-list td.permissions,.consul-intention-permission-header-list>ul>li dd,.consul-intention-permission-list>ul>li dd,.consul-lock-session-list ul>li:not(:first-child) .copy-button button,.consul-server-card .health-status+dd,.consul-upstream-instance-list li .copy-button button,.copy-button button,.disclosure-menu [aria-expanded]~* [role=separator],.disclosure-menu [aria-expanded]~*>div,.discovery-chain .resolvers>header>*,.discovery-chain .routes>header>*,.discovery-chain .splitters>header>*,.empty-state header :nth-child(2),.empty-state p,.empty-state>ul>li>*,.empty-state>ul>li>label>button,.has-error>strong,.hds-typography-body-100,.informed-action p,.list-collection>ul>li:not(:first-child) .copy-button button,.menu-panel [role=separator],.menu-panel>div,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] p,.more-popover-menu>[type=checkbox]+label+div [role=separator],.more-popover-menu>[type=checkbox]+label+div>div,.oidc-select button.reset,.oidc-select label>em,.oidc-select label>span,.peerings-badge .peerings-badge__text,.popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div>div,.popover-select label>*,.tippy-box[data-theme~=tooltip] .tippy-content,.topology-notices button,.type-sort.popover-select label>*,.type-toggle>em,.type-toggle>span,main .type-password>em,main .type-password>span,main .type-select>em,main .type-select>span,main .type-text>em,main .type-text>span,main form button+em,main p,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dt,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,span.label,table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div>div{font-family:var(--token-typography-body-100-font-family);font-size:var(--token-typography-body-100-font-size);line-height:var(--token-typography-body-100-line-height);margin:0;padding:0}.hds-typography-code-100{font-family:var(--token-typography-code-100-font-family);font-size:var(--token-typography-code-100-font-size);line-height:var(--token-typography-code-100-line-height);margin:0;padding:0}.hds-typography-code-200{font-family:var(--token-typography-code-200-font-family);font-size:var(--token-typography-code-200-font-size);line-height:var(--token-typography-code-200-line-height);margin:0;padding:0}.hds-typography-code-300{font-family:var(--token-typography-code-300-font-family);font-size:var(--token-typography-code-300-font-size);line-height:var(--token-typography-code-300-line-height);margin:0;padding:0}.hds-accordion{display:flex;gap:12px}.hds-accordion-item{background:var(--token-color-surface-primary);border-radius:6px}.hds-accordion-item.hds-accordion-item--does-not-contain-interactive.mock-hover,.hds-accordion-item.hds-accordion-item--does-not-contain-interactive:hover{box-shadow:var(--token-surface-high-box-shadow)}.hds-accordion-item.hds-accordion-item--contains-interactive{box-shadow:var(--token-surface-base-box-shadow)}.hds-accordion-item__toggle{position:relative;display:flex;gap:12px;align-items:center;padding:16px 16px 16px 12px}.hds-accordion-item__button{padding:0}.hds-accordion-item__button:hover{cursor:pointer}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive{outline-style:solid;outline-color:transparent;isolation:isolate;position:static;margin:-1px 0;color:var(--token-color-foreground-primary);background:0 0;border:1px solid transparent}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive::before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:5px;content:""}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive.mock-focus::before,.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus:not(:focus-visible)::before{box-shadow:none}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus-visible::before,.hds-breadcrumb__link.mock-focus,.hds-breadcrumb__link:focus{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive.mock-focus.mock-active::before,.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive:focus:active::before{box-shadow:none}.hds-accordion-item__button.hds-accordion-item__button--parent-does-not-contain-interactive::after{position:absolute;display:block;border-radius:6px;content:"";inset:0}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive{position:relative;display:flex;gap:.375rem;align-items:center;justify-content:center;font-weight:var(--token-typography-font-weight-regular);text-decoration:none;border:1px solid transparent;border-radius:5px;outline-style:solid;outline-color:transparent;isolation:isolate;width:24px;height:24px;color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong);box-shadow:var(--token-elevation-low-box-shadow)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-focus::before,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:focus::before{position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;z-index:-1;border:3px solid transparent;border-radius:8px;content:""}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-hover,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-focus,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:focus{box-shadow:none;color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-focus::before,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:focus::before{border-color:var(--token-color-focus-action-external)}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-active,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive.mock-active::before,.hds-accordion-item__button.hds-accordion-item__button--parent-contains-interactive:active::before{border-color:transparent}.hds-accordion-item__button.hds-accordion-item__button--is-open .flight-icon-chevron-down{transform:rotate(-180deg)}.hds-accordion-item__toggle-content{flex:1}.hds-accordion-item__content{padding:4px 16px 16px}.hds-alert{display:flex;align-items:flex-start}.hds-alert__icon{flex:none;width:20px;height:20px;margin-right:12px}.hds-alert__content{flex:1 1 auto}.hds-alert__text{display:flex;flex-direction:column;gap:4px;justify-content:center;color:var(--token-color-foreground-warning-on-surface)}.hds-alert__description{word-break:break-word}.hds-alert__description strong{font-weight:var(--token-typography-font-weight-semibold)}.hds-alert__description code,.hds-alert__description pre{display:inline;padding:1px 5px;font-size:.9em;font-family:var(--token-typography-code-100-font-family);line-height:1em;background-color:var(--token-color-surface-primary);border:1px solid var(--token-color-palette-neutral-200);border-radius:5px}.hds-alert__description a:not([class*=hds-]){color:var(--token-color-foreground-strong)}.hds-alert__description a:not([class*=hds-]):focus,.hds-alert__description a:not([class*=hds-]):focus-visible{text-decoration:none;outline:var(--token-color-focus-action-internal) solid 2px;outline-offset:1px}.hds-alert__description a:not([class*=hds-]):hover{color:var(--token-color-foreground-primary)}.hds-alert--color-neutral .hds-alert__icon,.hds-alert__description a:not([class*=hds-]):active{color:var(--token-color-foreground-faint)}.hds-alert__actions{display:flex;gap:16px;align-items:center}.hds-alert__actions>*{margin-top:16px}.hds-alert__dismiss{margin-top:2px;margin-left:16px}.hds-alert--type-compact .hds-alert__dismiss{margin-top:1px}.hds-alert--type-page{padding:16px 48px}.hds-alert--type-inline{padding:16px;border-style:solid;border-width:1px;border-radius:6px}.hds-alert--type-compact .hds-alert__icon{width:14px;height:14px;margin-top:2px;margin-right:8px}.hds-alert--type-compact .hds-alert__title{display:none}.hds-alert--type-compact .hds-alert__title+.hds-alert__description{margin-top:0}.hds-alert--color-neutral.hds-alert--type-page{background-color:var(--token-color-surface-faint);box-shadow:0 1px 0 0 var(--token-color-palette-alpha-300)}.hds-alert--color-neutral.hds-alert--type-inline{background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong)}.hds-alert--color-neutral .hds-alert__title{color:var(--token-color-foreground-primary)}.hds-alert--color-highlight.hds-alert--type-page{background-color:var(--token-color-surface-highlight);box-shadow:0 1px 0 0 var(--token-color-border-highlight)}.hds-alert--color-highlight.hds-alert--type-inline{background-color:var(--token-color-surface-highlight);border-color:var(--token-color-border-highlight)}.hds-alert--color-highlight .hds-alert__icon,.hds-alert--color-highlight .hds-alert__title{color:var(--token-color-foreground-highlight-on-surface)}.hds-alert--color-success.hds-alert--type-page{background-color:var(--token-color-surface-success);box-shadow:0 1px 0 0 var(--token-color-border-success)}.hds-alert--color-success.hds-alert--type-inline{background-color:var(--token-color-surface-success);border-color:var(--token-color-border-success)}.hds-alert--color-success .hds-alert__icon,.hds-alert--color-success .hds-alert__title{color:var(--token-color-foreground-success-on-surface)}.hds-alert--color-warning.hds-alert--type-page{background-color:var(--token-color-surface-warning);box-shadow:0 1px 0 0 var(--token-color-border-warning)}.hds-alert--color-warning.hds-alert--type-inline{background-color:var(--token-color-surface-warning);border-color:var(--token-color-border-warning)}.hds-alert--color-warning .hds-alert__icon,.hds-alert--color-warning .hds-alert__title{color:var(--token-color-foreground-warning-on-surface)}.hds-alert--color-critical.hds-alert--type-page{background-color:var(--token-color-surface-critical);box-shadow:0 1px 0 0 var(--token-color-border-critical)}.hds-alert--color-critical.hds-alert--type-inline{background-color:var(--token-color-surface-critical);border-color:var(--token-color-border-critical)}.hds-alert--color-critical .hds-alert__icon,.hds-alert--color-critical .hds-alert__title{color:var(--token-color-foreground-critical-on-surface)}.hds-app-footer{display:flex;flex-wrap:wrap;gap:24px;justify-content:flex-end;padding:24px;color:var(--app-footer-foreground-color);border-top:1px solid var(--app-footer-border-top-color)}.hds-app-footer__list:not(:has(li)){display:none}.hds-app-footer__legal-links,.hds-app-footer__list{display:flex;flex-wrap:wrap;gap:24px;align-items:center;justify-content:flex-end;width:-moz-fit-content;width:fit-content;min-width:0;margin:0;padding:0;list-style-type:none}.hds-app-footer__status-link.hds-link-inline--icon-leading>.hds-link-inline__icon{margin-right:6px}.hds-app-footer__status-link .flight-icon{fill:var(--hds-app-footer-status-icon-color,currentColor)}.hds-app-footer__status-link--operational .flight-icon{fill:var(--app-footer-status-link-icon-operational-color)}.hds-app-footer__status-link--degraded .flight-icon{fill:var(--app-footer-status-link-icon-degraded-color)}.hds-app-footer__status-link--maintenance .flight-icon{fill:var(--app-footer-status-link-icon-maintenance-color)}.hds-app-footer__status-link--critical .flight-icon{fill:var(--app-footer-status-link-icon-critical-color)}.hds-app-footer__link.hds-link-inline--color-secondary,.hds-app-footer__status-link{color:var(--app-footer-link-default-color);text-align:right}.hds-app-footer__link.hds-link-inline--color-secondary.mock-hover,.hds-app-footer__link.hds-link-inline--color-secondary:hover,.hds-app-footer__status-link.mock-hover,.hds-app-footer__status-link:hover{color:var(--app-footer-link-hover-color)}.hds-app-footer__link.hds-link-inline--color-secondary.mock-active,.hds-app-footer__link.hds-link-inline--color-secondary:active,.hds-app-footer__status-link.mock-active,.hds-app-footer__status-link:active{color:var(--app-footer-link-active-color)}.hds-app-footer__link.hds-link-inline--color-secondary.mock-focus,.hds-app-footer__link.hds-link-inline--color-secondary:focus,.hds-app-footer__link.hds-link-inline--color-secondary:focus-visible,.hds-app-footer__status-link.mock-focus,.hds-app-footer__status-link:focus,.hds-app-footer__status-link:focus-visible{color:var(--app-footer-link-focus-color);outline-color:var(--app-footer-link-focus-outline-color)}.hds-app-footer__list-item{display:flex;align-items:center}.hds-app-footer__copyright{display:flex;gap:6px;align-items:center;color:var(--app-footer-copyright-text-color)}.hds-app-footer__copyright .flight-icon{fill:var(--app-footer-copyright-icon-color)}.hds-app-footer--theme-light{--app-footer-foreground-color:var(--token-color-foreground-primary);--app-footer-border-top-color:var(--token-color-border-primary);--app-footer-link-default-color:var(--token-color-foreground-faint);--app-footer-link-hover-color:var(--token-color-palette-neutral-600);--app-footer-link-active-color:var(--token-color-palette-neutral-700);--app-footer-link-focus-color:var(--token-color-foreground-faint);--app-footer-link-focus-outline-color:var(--token-color-focus-action-internal);--app-footer-copyright-text-color:var(--token-color-foreground-primary);--app-footer-copyright-icon-color:var(--token-color-hashicorp-brand);--app-footer-status-link-icon-operational-color:var(--token-color-foreground-success);--app-footer-status-link-icon-degraded-color:var(--token-color-foreground-warning);--app-footer-status-link-icon-maintenance-color:var(--token-color-foreground-warning);--app-footer-status-link-icon-critical-color:var(--token-color-foreground-critical)}.hds-app-footer--theme-dark{--app-footer-foreground-color:#b2b6bd;--app-footer-border-top-color:#b2b6bd66;--app-footer-link-default-color:#b2b6bd;--app-footer-link-hover-color:#d5d7db;--app-footer-link-active-color:#efeff1;--app-footer-link-focus-color:#b2b6bd;--app-footer-link-focus-outline-color:#389aff;--app-footer-copyright-text-color:#b2b6bd;--app-footer-copyright-icon-color:#fff;--app-footer-status-link-icon-operational-color:#009241;--app-footer-status-link-icon-degraded-color:#e88c03;--app-footer-status-link-icon-maintenance-color:#e88c03;--app-footer-status-link-icon-critical-color:#ef3016}.hds-app-frame{display:grid;grid-template-areas:"header header" "sidebar main" "sidebar footer";grid-template-rows:auto 1fr auto;grid-template-columns:auto 1fr;min-height:100vh}.hds-app-frame__modals:empty,button.hds-button[href] .hds-button__text,button.hds-button[href]::before{display:none}.hds-app-frame__header{z-index:7;grid-area:header}.hds-app-frame__sidebar{z-index:6;grid-area:sidebar}.hds-app-frame__main{grid-area:main}.hds-app-frame__footer{grid-area:footer}.hds-app-frame__modals{position:fixed;top:0;left:0;z-index:100;width:100vw;height:100vh;pointer-events:none}.hds-application-state{width:19.5rem;max-width:100%;margin:0 auto}.hds-application-state__header{display:grid;grid-template-columns:min-content 1fr;align-items:start;color:var(--token-color-foreground-faint)}.hds-application-state__icon{margin-right:8px;padding-top:4px}.hds-application-state__error-code,.hds-application-state__title{grid-column-start:2}.hds-application-state__body{padding:12px 0;color:var(--token-color-foreground-faint)}.hds-application-state__footer{display:flex;gap:8px;justify-content:space-between}.hds-application-state__footer.hds-application-state__footer--has-divider{padding:12px 0;border-top:1px solid var(--token-color-border-strong)}.hds-avatar{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;width:32px;height:32px}.hds-avatar svg,.hds-dropdown--is-inline,.hds-form-toggle{display:inline-block}.hds-avatar img{width:inherit;height:inherit;border-radius:2px}.hds-badge{display:inline-flex;align-items:center;max-width:100%;vertical-align:middle;border:1px solid transparent;border-radius:5px}.hds-badge__icon{display:block;flex:0 0 auto}.hds-badge__text{flex:1 0 0;font-weight:var(--token-typography-font-weight-medium)}.hds-badge--size-small{gap:.25rem;min-height:1.25rem;padding:calc(.125rem - 1px) calc(.375rem - 1px)}.hds-badge--size-small .hds-badge__icon{width:.75rem;height:.75rem}.hds-badge--size-large .hds-badge__icon,.hds-badge--size-medium .hds-badge__icon{width:1rem;height:1rem}.hds-badge--size-small .hds-badge__text{font-size:.8125rem;line-height:1.2308}.hds-badge--size-medium{gap:.25rem;min-height:1.5rem;padding:calc(.25rem - 1px) calc(.5rem - 1px)}.hds-badge--size-medium .hds-badge__text{font-size:.8125rem;line-height:1.2308}.hds-badge--size-large{gap:.375rem;min-height:2rem;padding:calc(.25rem - 1px) calc(.5rem - 1px)}.hds-badge--size-large .hds-badge__text{font-size:1rem;line-height:1.5}.hds-badge--color-neutral.hds-badge--type-filled{color:var(--token-color-foreground-primary)}.hds-badge--color-neutral.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge--color-neutral.hds-badge--type-outlined{color:var(--token-color-foreground-primary);background-color:transparent;border-color:var(--token-color-foreground-faint)}.hds-badge--color-neutral-dark-mode.hds-badge--type-filled{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge--color-neutral-dark-mode.hds-badge--type-inverted{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint)}.hds-badge--color-neutral-dark-mode.hds-badge--type-outlined{color:var(--token-color-foreground-high-contrast);background-color:transparent;border-color:var(--token-color-palette-neutral-100)}.hds-badge--color-highlight.hds-badge--type-filled{color:var(--token-color-foreground-highlight-on-surface);background-color:var(--token-color-surface-highlight)}.hds-badge--color-highlight.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-highlight)}.hds-badge--color-highlight.hds-badge--type-outlined{color:var(--token-color-foreground-highlight);background-color:transparent;border-color:currentColor}.hds-badge--color-success.hds-badge--type-filled{color:var(--token-color-foreground-success-on-surface);background-color:var(--token-color-surface-success)}.hds-badge--color-success.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-success)}.hds-badge--color-success.hds-badge--type-outlined{color:var(--token-color-foreground-success);background-color:transparent;border-color:currentColor}.hds-badge--color-warning.hds-badge--type-filled{color:var(--token-color-foreground-warning-on-surface);background-color:var(--token-color-surface-warning)}.hds-badge--color-warning.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-warning)}.hds-badge--color-warning.hds-badge--type-outlined{color:var(--token-color-foreground-warning);background-color:transparent;border-color:currentColor}.hds-badge--color-critical.hds-badge--type-filled{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-surface-critical)}.hds-badge--color-critical.hds-badge--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-critical)}.hds-badge--color-critical.hds-badge--type-outlined{color:var(--token-color-foreground-critical);background-color:transparent;border-color:currentColor}.hds-badge-count{display:inline-flex;align-items:center;max-width:100%;font-weight:var(--token-typography-font-weight-medium);border:1px solid transparent}.hds-button,.hds-dropdown-toggle-button{font-weight:var(--token-typography-font-weight-regular)}.hds-badge-count--size-small{min-height:1.25rem;padding:calc(.125rem - 1px) calc(.5rem - 1px);font-size:.8125rem;line-height:1.2308;border-radius:.625rem}.hds-badge-count--size-medium{min-height:1.5rem;padding:calc(.25rem - 1px) calc(.75rem - 1px);font-size:.8125rem;line-height:1.2308;border-radius:.75rem}.hds-badge-count--size-large{min-height:2rem;padding:calc(.25rem - 1px) calc(.875rem - 1px);font-size:1rem;line-height:1.5;border-radius:1rem}.hds-breadcrumb__list,.hds-breadcrumb__sublist{margin:0;padding:0;list-style:none}.hds-badge-count--color-neutral.hds-badge-count--type-filled{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-strong)}.hds-badge-count--color-neutral.hds-badge-count--type-inverted{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge-count--color-neutral.hds-badge-count--type-outlined{color:var(--token-color-foreground-primary);background-color:transparent;border-color:var(--token-color-foreground-faint)}.hds-badge-count--color-neutral-dark-mode.hds-badge-count--type-filled{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-foreground-faint)}.hds-badge-count--color-neutral-dark-mode.hds-badge-count--type-inverted{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint)}.hds-badge-count--color-neutral-dark-mode.hds-badge-count--type-outlined{color:var(--token-color-foreground-high-contrast);background-color:transparent;border-color:var(--token-color-palette-neutral-100)}.hds-breadcrumb{position:relative}.hds-breadcrumb__list{display:flex}.hds-breadcrumb--items-can-wrap .hds-breadcrumb__list{flex-wrap:wrap}.hds-breadcrumb__item{position:relative;display:flex;flex-direction:row;align-items:center;min-width:0}.hds-breadcrumb__list>.hds-breadcrumb__item:not(:last-child)::after{padding:0 8px;color:var(--token-color-palette-neutral-300);content:"/"}.hds-breadcrumb__sublist>.hds-breadcrumb__item+.hds-breadcrumb__item{margin-top:4px}.hds-breadcrumb__current,.hds-breadcrumb__link{margin:0 -4px;padding:0 4px;display:flex;min-width:0}.hds-breadcrumb__item--is-truncation{flex:none}.hds-breadcrumb__link{flex-direction:row;align-items:center;color:var(--token-color-foreground-faint);border-radius:5px;text-decoration-color:transparent;outline-style:solid;outline-color:transparent}.hds-breadcrumb__link.mock-active>.hds-breadcrumb__text,.hds-breadcrumb__link.mock-hover>.hds-breadcrumb__text,.hds-breadcrumb__link:active>.hds-breadcrumb__text,.hds-breadcrumb__link:hover>.hds-breadcrumb__text{text-decoration-color:currentColor}.hds-breadcrumb__link.mock-hover,.hds-breadcrumb__link:hover{color:var(--token-color-palette-neutral-600)}.hds-breadcrumb__link:focus:not(:focus-visible){box-shadow:none}.hds-breadcrumb__link:focus-visible{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-breadcrumb__link.mock-focus.mock-active,.hds-breadcrumb__link:focus:active{box-shadow:none}.hds-breadcrumb__link.mock-active,.hds-breadcrumb__link:active{color:var(--token-color-foreground-secondary)}.hds-breadcrumb__current{flex-direction:row;align-items:center;color:var(--token-color-foreground-strong)}.hds-breadcrumb__icon{flex:none;width:13px;height:13px;margin-right:6px}.hds-breadcrumb__text{padding:calc((28px - 1rem)/ 2) 0;font-size:.8125rem;line-height:1rem;white-space:nowrap;text-decoration:underline;text-overflow:ellipsis;text-decoration-color:transparent}.hds-breadcrumb__sublist .hds-breadcrumb__text{white-space:normal}.hds-breadcrumb__truncation-toggle{display:flex;flex:none;align-items:center;justify-content:center;width:28px;height:28px;margin:0 -4px;padding:0;color:var(--token-color-foreground-faint);background-color:transparent;border:1px solid transparent;border-radius:5px;outline:transparent solid 0;cursor:pointer}.hds-button,.hds-copy-snippet{align-items:center;isolation:isolate}.hds-button,.hds-copy-snippet,.hds-dismiss-button,.hds-dropdown-toggle-button,.hds-dropdown-toggle-icon{outline-style:solid;outline-color:transparent}.hds-breadcrumb__truncation-toggle.mock-hover,.hds-breadcrumb__truncation-toggle:hover{color:var(--token-color-foreground-faint);border-color:var(--token-color-border-strong)}.hds-breadcrumb__truncation-toggle.mock-focus,.hds-breadcrumb__truncation-toggle:focus{box-shadow:var(--token-focus-ring-action-box-shadow);background-color:transparent;border:none}.hds-breadcrumb__truncation-toggle:focus:not(:focus-visible){box-shadow:none}.hds-breadcrumb__truncation-toggle:focus-visible,.hds-copy-snippet.mock-focus::before,.hds-copy-snippet:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-breadcrumb__truncation-toggle.mock-focus.mock-active,.hds-breadcrumb__truncation-toggle:focus:active{box-shadow:none}.hds-breadcrumb__truncation-toggle.mock-active,.hds-breadcrumb__truncation-toggle:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-breadcrumb__truncation-content{position:absolute;top:100%;left:-4px;z-index:300;width:-moz-max-content;width:max-content;max-width:200px;margin-top:4px;padding:6px 12px;background-color:var(--token-color-surface-primary);border-radius:6px;box-shadow:var(--token-surface-high-box-shadow)}.hds-button.hds-button--width-full,.hds-copy-snippet--is-truncated,.hds-copy-snippet--width-full,.hds-dropdown-toggle-button--width-full{max-width:100%;width:100%}.hds-button--size-small,.hds-dropdown-toggle-button--size-small{padding:.375rem .6875rem;min-height:1.75rem}.hds-button{position:relative;display:flex;gap:.375rem;justify-content:center;width:auto;text-decoration:none;border:1px solid transparent;border-radius:5px}a.hds-button{width:-moz-fit-content;width:fit-content}a.hds-button.mock-active,a.hds-button.mock-focus,a.hds-button.mock-hover,a.hds-button:active,a.hds-button:focus,a.hds-button:hover{text-decoration:underline}.hds-button.mock-disabled,.hds-button.mock-disabled:focus,.hds-button.mock-disabled:hover,.hds-button:disabled,.hds-button:disabled:focus,.hds-button:disabled:hover,.hds-button[disabled],.hds-button[disabled]:focus,.hds-button[disabled]:hover{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed}.hds-button.mock-disabled::before,.hds-button.mock-disabled:focus::before,.hds-button.mock-disabled:hover::before,.hds-button:disabled::before,.hds-button:disabled:focus::before,.hds-button:disabled:hover::before,.hds-button[disabled]::before,.hds-button[disabled]:focus::before,.hds-button[disabled]:hover::before{border-color:transparent}.hds-button.hds-button--width-full .hds-button__text{flex:0 0 auto}.hds-button__text,.hds-copy-snippet__text,.hds-form-group--radio-cards .hds-form-radio-card--has-fluid-width{flex:1 0 0}.hds-button.mock-focus,.hds-button:focus{box-shadow:none}.hds-button.mock-focus::before,.hds-button:focus::before{position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;z-index:-1;border:3px solid transparent;border-radius:8px;content:""}.hds-button__text{text-align:center}.hds-button--size-small .hds-button__icon{width:.75rem;height:.75rem}.hds-button--size-small .hds-button__text{font-size:.8125rem;line-height:.875rem}.hds-button--size-small.hds-button--is-icon-only{min-width:1.75rem;padding-right:.375rem;padding-left:.375rem}.hds-button--size-medium{min-height:2.25rem;padding:.5625rem .9375rem}.hds-button--size-medium .hds-button__icon{width:1rem;height:1rem}.hds-button--size-medium .hds-button__text{font-size:.875rem;line-height:1rem}.hds-button--size-medium.hds-button--is-icon-only{min-width:2.25rem;padding-right:.5625rem;padding-left:.5625rem}.hds-button--size-large{min-height:3rem;padding:.6875rem 1.1875rem}.hds-button--size-large .hds-button__icon{width:1.5rem;height:1.5rem}.hds-button--size-large .hds-button__text{font-size:1rem;line-height:1.5rem}.hds-button--size-large.hds-button--is-icon-only{min-width:3rem;padding-right:.6875rem;padding-left:.6875rem}.hds-button--color-primary{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-palette-blue-300);box-shadow:var(--token-elevation-low-box-shadow)}.hds-button--color-primary.mock-hover,.hds-button--color-primary:hover{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-300);border-color:var(--token-color-palette-blue-400);cursor:pointer}.hds-button--color-primary.mock-focus,.hds-button--color-primary:focus{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-focus-action-internal)}.hds-button--color-primary.mock-focus::before,.hds-button--color-primary:focus::before{top:-6px;right:-6px;bottom:-6px;left:-6px;border-color:var(--token-color-focus-action-external);border-radius:10px}.hds-button--color-primary.mock-active,.hds-button--color-primary:active{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-400);border-color:var(--token-color-palette-blue-400);box-shadow:none}.hds-button--color-primary.mock-active::before,.hds-button--color-primary:active::before{border-color:transparent}.hds-button--color-secondary{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong);box-shadow:var(--token-elevation-low-box-shadow)}.hds-button--color-secondary.mock-hover,.hds-button--color-secondary:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-button--color-secondary.mock-focus,.hds-button--color-secondary:focus{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal)}.hds-button--color-secondary.mock-focus::before,.hds-button--color-secondary:focus::before{border-color:var(--token-color-focus-action-external)}.hds-button--color-secondary.mock-active,.hds-button--color-secondary:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-button--color-secondary.mock-active::before,.hds-button--color-secondary:active::before{border-color:transparent}.hds-button--color-tertiary{color:var(--token-color-foreground-action);background-color:transparent;border-color:transparent}.hds-button--color-tertiary.mock-hover,.hds-button--color-tertiary:hover{color:var(--token-color-foreground-action-hover);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-button--color-tertiary.mock-focus,.hds-button--color-tertiary:focus{color:var(--token-color-foreground-action);border-color:var(--token-color-focus-action-internal)}.hds-button--color-tertiary.mock-focus::before,.hds-button--color-tertiary:focus::before{border-color:var(--token-color-focus-action-external)}.hds-button--color-tertiary.mock-active,.hds-button--color-tertiary:active{color:var(--token-color-foreground-action-active);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-button--color-tertiary.mock-active::before,.hds-button--color-tertiary:active::before{border-color:transparent}.hds-button--color-tertiary.mock-disabled,.hds-button--color-tertiary.mock-disabled:focus,.hds-button--color-tertiary.mock-disabled:hover,.hds-button--color-tertiary:disabled,.hds-button--color-tertiary:disabled:focus,.hds-button--color-tertiary:disabled:hover,.hds-button--color-tertiary[disabled],.hds-button--color-tertiary[disabled]:focus,.hds-button--color-tertiary[disabled]:hover{background-color:transparent;border-color:transparent}.hds-button--color-tertiary.mock-disabled::before,.hds-button--color-tertiary.mock-disabled:focus::before,.hds-button--color-tertiary.mock-disabled:hover::before,.hds-button--color-tertiary:disabled::before,.hds-button--color-tertiary:disabled:focus::before,.hds-button--color-tertiary:disabled:hover::before,.hds-button--color-tertiary[disabled]::before,.hds-button--color-tertiary[disabled]:focus::before,.hds-button--color-tertiary[disabled]:hover::before{border-color:transparent}.hds-button--color-critical{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-surface-critical);border-color:var(--token-color-foreground-critical-on-surface);box-shadow:var(--token-elevation-low-box-shadow)}.hds-button--color-critical.mock-hover,.hds-button--color-critical:hover{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-red-300);border-color:var(--token-color-palette-red-400);cursor:pointer}.hds-button--color-critical.mock-focus,.hds-button--color-critical:focus{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-surface-critical);border-color:var(--token-color-focus-critical-internal)}.hds-button--color-critical.mock-focus::before,.hds-button--color-critical:focus::before{border-color:var(--token-color-focus-critical-external)}.hds-button--color-critical.mock-active,.hds-button--color-critical:active{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-red-400);border-color:var(--token-color-palette-red-400);box-shadow:none}.hds-button--color-critical.mock-active::before,.hds-button--color-critical:active::before{border-color:transparent}button.hds-button[href]{color:#fff!important;background-color:red!important;border:none}button.hds-button[href]::after{content:' Attention: you’re passing a "href" attribute to the "Hds::Button" component, you should use an "@href" argument.'}.hds-button-set{display:flex;gap:16px}.hds-card__container{position:relative;background-color:#fff;border-radius:6px}.hds-card__container--level-surface-base{box-shadow:var(--token-surface-base-box-shadow)}.hds-card__container--level-surface-mid{box-shadow:var(--token-surface-mid-box-shadow)}.hds-card__container--level-surface-high{box-shadow:var(--token-surface-high-box-shadow)}.hds-card__container--hover-level-surface-base.mock-hover,.hds-card__container--hover-level-surface-base:hover{box-shadow:var(--token-surface-base-box-shadow)}.hds-card__container--hover-level-surface-mid.mock-hover,.hds-card__container--hover-level-surface-mid:hover{box-shadow:var(--token-surface-mid-box-shadow)}.hds-card__container--hover-level-surface-high.mock-hover,.hds-card__container--hover-level-surface-high:hover{box-shadow:var(--token-surface-high-box-shadow)}.hds-card__container--active-level-surface-base.mock-active,.hds-card__container--active-level-surface-base:active{box-shadow:var(--token-surface-base-box-shadow)}.hds-card__container--active-level-surface-mid.mock-active,.hds-card__container--active-level-surface-mid:active{box-shadow:var(--token-surface-mid-box-shadow)}.hds-card__container--active-level-surface-high.mock-active,.hds-card__container--active-level-surface-high:active{box-shadow:var(--token-surface-high-box-shadow)}.hds-card__container--level-elevation-base{box-shadow:var(--token-elevation-base-box-shadow)}.hds-card__container--level-elevation-mid{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-card__container--level-elevation-high{box-shadow:var(--token-elevation-high-box-shadow)}.hds-card__container--hover-level-elevation-base.mock-hover,.hds-card__container--hover-level-elevation-base:hover{box-shadow:var(--token-elevation-base-box-shadow)}.hds-card__container--hover-level-elevation-mid.mock-hover,.hds-card__container--hover-level-elevation-mid:hover{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-card__container--hover-level-elevation-high.mock-hover,.hds-card__container--hover-level-elevation-high:hover{box-shadow:var(--token-elevation-high-box-shadow)}.hds-card__container--active-level-elevation-base.mock-active,.hds-card__container--active-level-elevation-base:active{box-shadow:var(--token-elevation-base-box-shadow)}.hds-card__container--active-level-elevation-mid.mock-active,.hds-card__container--active-level-elevation-mid:active{box-shadow:var(--token-elevation-mid-box-shadow)}.hds-card__container--active-level-elevation-high.mock-active,.hds-card__container--active-level-elevation-high:active{box-shadow:var(--token-elevation-high-box-shadow)}.hds-card__container--background-neutral-primary{background-color:var(--token-color-surface-primary)}.hds-card__container--background-neutral-secondary{background-color:var(--token-color-surface-faint)}.hds-card__container--overflow-visible{overflow:visible}.hds-copy-button{cursor:pointer}.hds-copy-button .hds-button__icon{color:var(--token-color-foreground-action)}.hds-copy-button.hds-copy-button--status-success .hds-button__icon{color:var(--token-color-foreground-success)}.hds-copy-button.hds-copy-button--status-error .hds-button__icon{color:var(--token-color-foreground-critical)}.hds-copy-snippet{position:relative;display:flex;gap:8px;justify-content:space-between;padding:6px 4px;text-align:left;border:1px solid transparent;border-radius:5px;cursor:pointer}.hds-copy-snippet::before,.hds-dismiss-button::before{position:absolute;z-index:-1;content:""}.hds-copy-snippet::before{top:0;right:0;bottom:0;left:0;border-radius:5px}.hds-copy-snippet:focus:not(:focus-visible)::before{box-shadow:none}.hds-copy-snippet:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-copy-snippet.mock-focus.mock-active::before,.hds-copy-snippet:focus:active::before{box-shadow:none}.hds-copy-snippet--color-primary{color:var(--token-color-foreground-action);background-color:transparent}.hds-copy-snippet--color-primary.mock-hover,.hds-copy-snippet--color-primary:hover{color:var(--token-color-foreground-action-hover);background-color:var(--token-color-surface-interactive);border-color:var(--token-color-border-strong)}.hds-copy-snippet--color-primary.mock-active,.hds-copy-snippet--color-primary:active{color:var(--token-color-foreground-action-active);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-copy-snippet--color-primary:focus{background-color:transparent}.hds-copy-snippet--color-secondary{color:var(--token-color-foreground-primary);background-color:transparent}.hds-copy-snippet--color-secondary.mock-hover,.hds-copy-snippet--color-secondary:hover{background-color:var(--token-color-surface-interactive);border-color:var(--token-color-border-strong)}.hds-copy-snippet--color-secondary.mock-active,.hds-copy-snippet--color-secondary:active{background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-copy-snippet--status-error,.hds-copy-snippet--status-success{background-color:var(--token-color-surface-interactive)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon{color:var(--token-color-foreground-action)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon:hover{color:var(--token-color-foreground-action-hover)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon:active{color:var(--token-color-foreground-action-active)}.hds-copy-snippet--color-secondary .hds-copy-snippet__icon:focus{color:var(--token-color-foreground-action)}.hds-copy-snippet--status-success .hds-copy-snippet__icon{color:var(--token-color-foreground-success)}.hds-copy-snippet--status-error .hds-copy-snippet__icon{color:var(--token-color-foreground-critical)}.hds-copy-snippet__icon{flex:none}.hds-copy-snippet--is-truncated .hds-copy-snippet__text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.hds-disclosure-primitive{position:relative}.hds-dismiss-button{flex:none;padding:0;color:var(--token-color-foreground-faint);background-color:transparent;border:none;cursor:pointer;position:relative;isolation:isolate}.hds-dismiss-button.mock-hover::before,.hds-dismiss-button:hover::before{background-color:rgba(222,223,227,.4)}.hds-dismiss-button::before{top:-4px;right:-4px;bottom:-4px;left:-4px;border-radius:5px}.hds-dismiss-button.mock-focus::before,.hds-dismiss-button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dismiss-button:focus:not(:focus-visible)::before{box-shadow:none}.hds-dismiss-button:focus-visible::before,.hds-dropdown-toggle-icon.mock-focus::before,.hds-dropdown-toggle-icon:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dismiss-button.mock-focus.mock-active::before,.hds-dismiss-button:focus:active::before{box-shadow:none}.hds-dismiss-button.mock-active,.hds-dismiss-button:active{color:var(--token-color-foreground-secondary)}.hds-dismiss-button.mock-active::before,.hds-dismiss-button:active::before{background-color:rgba(222,223,227,.4);border:1px solid var(--token-color-border-strong)}.hds-dropdown--is-inline .hds-dropdown-toggle-button,.hds-dropdown--is-inline .hds-dropdown-toggle-icon{display:inline-flex}.hds-dropdown-toggle-icon{display:flex;gap:2px;align-items:center;justify-content:center;padding:1px;background-color:var(--token-color-surface-faint);border:1px solid var(--token-color-border-strong);border-radius:5px;position:relative;isolation:isolate}.hds-dropdown-toggle-button,.hds-link-standalone{gap:.375rem;font-family:var(--token-typography-font-stack-text);isolation:isolate}.hds-dropdown-toggle-icon.mock-hover,.hds-dropdown-toggle-icon:hover{background-color:var(--token-color-surface-interactive);cursor:pointer}.hds-dropdown-toggle-icon::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-dropdown-toggle-icon:focus:not(:focus-visible)::before{box-shadow:none}.hds-dropdown-toggle-icon:focus-visible::before,.hds-link-standalone.mock-focus::before,.hds-link-standalone:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dropdown-toggle-icon.mock-focus.mock-active::before,.hds-dropdown-toggle-icon:focus:active::before{box-shadow:none}.hds-dropdown-toggle-icon.mock-active,.hds-dropdown-toggle-icon:active{background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong)}.hds-dropdown-toggle-icon.mock-disabled,.hds-dropdown-toggle-icon:disabled{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed}.hds-dropdown-toggle-icon.mock-disabled::before,.hds-dropdown-toggle-icon:disabled::before{border-color:transparent}.hds-dropdown-toggle-icon__wrapper{display:flex;align-items:center;justify-content:center;border-radius:3px}.hds-dropdown-toggle-icon__wrapper img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;border-radius:inherit}.hds-dropdown-toggle-icon--size-small .hds-dropdown-toggle-icon__wrapper{width:24px;height:24px}.hds-dropdown-toggle-icon--size-medium .hds-dropdown-toggle-icon__wrapper{width:32px;height:32px}.hds-dropdown-toggle-button{position:relative;display:flex;align-items:center;justify-content:center;width:auto;text-decoration:none;border:1px solid transparent;border-radius:5px}.hds-dropdown-toggle-button.mock-focus,.hds-dropdown-toggle-button:focus{box-shadow:none}.hds-dropdown-toggle-button.mock-focus::before,.hds-dropdown-toggle-button:focus::before{position:absolute;top:-4px;right:-4px;bottom:-4px;left:-4px;z-index:-1;border:3px solid transparent;border-radius:8px;content:""}.hds-dropdown-toggle-button.mock-disabled,.hds-dropdown-toggle-button.mock-disabled:focus,.hds-dropdown-toggle-button.mock-disabled:hover,.hds-dropdown-toggle-button:disabled,.hds-dropdown-toggle-button:disabled:focus,.hds-dropdown-toggle-button:disabled:hover{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed}.hds-dropdown-toggle-button.mock-disabled::before,.hds-dropdown-toggle-button.mock-disabled:focus::before,.hds-dropdown-toggle-button.mock-disabled:hover::before,.hds-dropdown-toggle-button:disabled::before,.hds-dropdown-toggle-button:disabled:focus::before,.hds-dropdown-toggle-button:disabled:hover::before{border-color:transparent}.hds-dropdown-toggle-button.mock-disabled .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button.mock-disabled .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button.mock-disabled:focus .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button.mock-disabled:focus .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button.mock-disabled:hover .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button.mock-disabled:hover .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button:disabled .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button:disabled .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button:disabled:focus .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button:disabled:focus .hds-dropdown-toggle-button__count,.hds-dropdown-toggle-button:disabled:hover .hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button:disabled:hover .hds-dropdown-toggle-button__count{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-strong)}.hds-dropdown-toggle-button--size-small .hds-dropdown-toggle-button__icon{width:.75rem;height:.75rem}.hds-dropdown-toggle-button--size-small .hds-dropdown-toggle-button__text{font-size:.8125rem;line-height:.875rem}.hds-dropdown-toggle-button--size-small.hds-dropdown-toggle-button--is-icon-only{min-width:1.75rem;padding-right:.375rem;padding-left:.375rem}.hds-dropdown-toggle-button--size-medium{min-height:2.25rem;padding:.5625rem .9375rem}.hds-dropdown-toggle-button--size-medium .hds-dropdown-toggle-button__icon{width:1rem;height:1rem}.hds-dropdown-toggle-button--size-medium .hds-dropdown-toggle-button__text{font-size:.875rem;line-height:1rem}.hds-dropdown-toggle-button--size-medium.hds-dropdown-toggle-button--is-icon-only{min-width:2.25rem;padding-right:.5625rem;padding-left:.5625rem}.hds-dropdown-toggle-button--size-large{min-height:3rem;padding:.6875rem 1.1875rem}.hds-dropdown-toggle-button--size-large .hds-dropdown-toggle-button__icon{width:1.5rem;height:1.5rem}.hds-dropdown-toggle-button--size-large .hds-dropdown-toggle-button__text{font-size:1rem;line-height:1.5rem}.hds-dropdown-toggle-button--size-large.hds-dropdown-toggle-button--is-icon-only{min-width:3rem;padding-right:.6875rem;padding-left:.6875rem}.hds-dropdown-toggle-button--size-small{padding-right:.375rem}.hds-dropdown-toggle-button--size-medium{padding-right:.5625rem}.hds-dropdown-toggle-button--color-primary{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-palette-blue-300);box-shadow:var(--token-elevation-low-box-shadow)}.hds-dropdown-toggle-button--color-primary.mock-hover,.hds-dropdown-toggle-button--color-primary:hover{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-300);border-color:var(--token-color-palette-blue-400);cursor:pointer}.hds-dropdown-toggle-button--color-primary.mock-focus,.hds-dropdown-toggle-button--color-primary:focus{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-200);border-color:var(--token-color-focus-action-internal)}.hds-dropdown-toggle-button--color-primary.mock-focus::before,.hds-dropdown-toggle-button--color-primary:focus::before{top:-6px;right:-6px;bottom:-6px;left:-6px;border-color:var(--token-color-focus-action-external);border-radius:10px}.hds-dropdown-toggle-button--color-primary.mock-active,.hds-dropdown-toggle-button--color-primary:active{color:var(--token-color-foreground-high-contrast);background-color:var(--token-color-palette-blue-400);border-color:var(--token-color-palette-blue-400);box-shadow:none}.hds-dropdown-toggle-button--color-primary.mock-active::before,.hds-dropdown-toggle-button--color-primary:active::before{border-color:transparent}.hds-dropdown-toggle-button--color-secondary{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-strong);box-shadow:var(--token-elevation-low-box-shadow)}.hds-dropdown-toggle-button--color-secondary.mock-hover,.hds-dropdown-toggle-button--color-secondary:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong);cursor:pointer}.hds-dropdown-toggle-button--color-secondary.mock-focus,.hds-dropdown-toggle-button--color-secondary:focus{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal)}.hds-dropdown-toggle-button--color-secondary.mock-focus::before,.hds-dropdown-toggle-button--color-secondary:focus::before{border-color:var(--token-color-focus-action-external)}.hds-dropdown-toggle-button--color-secondary.mock-active,.hds-dropdown-toggle-button--color-secondary:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-dropdown-toggle-button--color-secondary.mock-active::before,.hds-dropdown-toggle-button--color-secondary:active::before{border-color:transparent}.hds-dropdown-list-item--variant-separator::before,.hds-dropdown__header--with-divider{border-bottom:1px solid var(--token-color-border-primary)}.hds-dropdown-toggle-button--width-full{justify-content:space-between}.hds-dropdown-toggle-button__text{text-align:left}.hds-dropdown-toggle-button__icon{flex:none}.hds-dropdown-toggle-button__badge,.hds-dropdown-toggle-button__count{margin:-3px 0}.hds-dropdown-toggle-chevron{margin-left:auto;padding-left:2px}@media (prefers-reduced-motion:no-preference){.hds-accordion-item__button .flight-icon-chevron-down,.hds-dropdown-toggle-chevron .flight-icon-chevron-down{transition:transform .3s}}.hds-dropdown-toggle-button--is-open .hds-dropdown-toggle-chevron .flight-icon-chevron-down,.hds-dropdown-toggle-icon--is-open .hds-dropdown-toggle-chevron .flight-icon-chevron-down{transform:rotate(-180deg)}.hds-dropdown__content{display:flex;flex-direction:column;width:-moz-max-content;width:max-content;min-width:200px;max-width:400px;background-color:var(--token-color-surface-primary);border-radius:6px;box-shadow:var(--token-surface-high-box-shadow)}.hds-dropdown__content--fixed-width{min-width:initial;max-width:initial}.hds-dropdown__content--position-bottom-right{position:absolute;top:calc(100% + 4px);right:0;z-index:2}.hds-dropdown__content--position-bottom-left{position:absolute;top:calc(100% + 4px);left:0;z-index:2}.hds-dropdown__content--position-top-right{position:absolute;right:0;bottom:calc(100% + 4px);z-index:2}.hds-dropdown__content--position-top-left{position:absolute;bottom:calc(100% + 4px);left:0;z-index:2}.hds-dropdown__list{flex:1 1 auto;margin:0;padding:4px 0;overflow-y:auto;list-style:none;overscroll-behavior:contain}.hds-dropdown__footer,.hds-dropdown__header{position:relative;flex:none;padding:0 8px}.hds-dropdown__footer>.hds-link-standalone,.hds-dropdown__header>.hds-link-standalone{width:initial;margin:4px 0;padding:7px 8px}.hds-dropdown__footer>.hds-link-standalone::before,.hds-dropdown__header>.hds-link-standalone::before{top:0;bottom:0}.hds-dropdown__footer>.hds-button,.hds-dropdown__footer>.hds-form-text-input,.hds-dropdown__header>.hds-button,.hds-dropdown__header>.hds-form-text-input{margin:8px 0}.hds-dropdown__footer>.hds-button-set,.hds-dropdown__header>.hds-button-set{gap:8px;margin:8px 0}.hds-dropdown__footer--with-divider{border-top:1px solid var(--token-color-border-primary)}.hds-dropdown-list-item__copy-item-title{padding:2px 0 4px;color:var(--token-color-foreground-faint)}.hds-dropdown-list-item--variant-copy-item{width:100%;padding:10px 16px 12px}.hds-dropdown-list-item--variant-description{padding:2px 16px 4px;color:var(--token-color-foreground-faint)}.hds-dropdown-list-item--variant-generic{padding-right:16px;padding-left:16px}.hds-dropdown-list-item--variant-checkmark,.hds-dropdown-list-item--variant-interactive{position:relative;min-height:36px;isolation:isolate}.hds-dropdown-list-item--variant-checkmark button,.hds-dropdown-list-item--variant-interactive button{width:100%;background-color:transparent}.hds-dropdown-list-item--variant-checkmark button:hover,.hds-dropdown-list-item--variant-interactive button:hover{cursor:pointer}.hds-dropdown-list-item--variant-checkmark a,.hds-dropdown-list-item--variant-checkmark button,.hds-dropdown-list-item--variant-interactive a,.hds-dropdown-list-item--variant-interactive button{display:flex;align-items:flex-start;padding:7px 9px 7px 15px;text-decoration:none;border:1px solid transparent;outline-style:solid;outline-color:transparent}.hds-dropdown-list-item--variant-checkmark a::before,.hds-dropdown-list-item--variant-checkmark button::before,.hds-dropdown-list-item--variant-interactive a::before,.hds-dropdown-list-item--variant-interactive button::before{position:absolute;top:6px;bottom:6px;left:4px;z-index:-1;width:2px;border-radius:1px;content:""}.hds-dropdown-list-item--variant-checkmark a::after,.hds-dropdown-list-item--variant-checkmark button::after,.hds-dropdown-list-item--variant-interactive a::after,.hds-dropdown-list-item--variant-interactive button::after{position:absolute;top:0;right:4px;bottom:0;left:10px;z-index:-1;border-radius:5px;content:""}.hds-dropdown-list-item--variant-checkmark a.mock-hover,.hds-dropdown-list-item--variant-checkmark a:hover,.hds-dropdown-list-item--variant-checkmark button.mock-hover,.hds-dropdown-list-item--variant-checkmark button:hover,.hds-dropdown-list-item--variant-interactive a.mock-hover,.hds-dropdown-list-item--variant-interactive a:hover,.hds-dropdown-list-item--variant-interactive button.mock-hover,.hds-dropdown-list-item--variant-interactive button:hover{color:var(--current-color-hover)}.hds-dropdown-list-item--variant-checkmark a.mock-focus,.hds-dropdown-list-item--variant-checkmark a:focus,.hds-dropdown-list-item--variant-checkmark a:focus-visible,.hds-dropdown-list-item--variant-checkmark button.mock-focus,.hds-dropdown-list-item--variant-checkmark button:focus,.hds-dropdown-list-item--variant-checkmark button:focus-visible,.hds-dropdown-list-item--variant-interactive a.mock-focus,.hds-dropdown-list-item--variant-interactive a:focus,.hds-dropdown-list-item--variant-interactive a:focus-visible,.hds-dropdown-list-item--variant-interactive button.mock-focus,.hds-dropdown-list-item--variant-interactive button:focus,.hds-dropdown-list-item--variant-interactive button:focus-visible{color:var(--current-color-focus)}.hds-dropdown-list-item--variant-checkmark a.mock-hover::before,.hds-dropdown-list-item--variant-checkmark a:hover::before,.hds-dropdown-list-item--variant-checkmark button.mock-hover::before,.hds-dropdown-list-item--variant-checkmark button:hover::before,.hds-dropdown-list-item--variant-interactive a.mock-hover::before,.hds-dropdown-list-item--variant-interactive a:hover::before,.hds-dropdown-list-item--variant-interactive button.mock-hover::before,.hds-dropdown-list-item--variant-interactive button:hover::before{background-color:currentColor}.hds-dropdown-list-item--variant-checkmark a.mock-focus::after,.hds-dropdown-list-item--variant-checkmark a:focus::after,.hds-dropdown-list-item--variant-checkmark button.mock-focus::after,.hds-dropdown-list-item--variant-checkmark button:focus::after,.hds-dropdown-list-item--variant-interactive a.mock-focus::after,.hds-dropdown-list-item--variant-interactive a:focus::after,.hds-dropdown-list-item--variant-interactive button.mock-focus::after,.hds-dropdown-list-item--variant-interactive button:focus::after{left:4px;box-shadow:var(--current-focus-ring-box-shadow)}.hds-dropdown-list-item--variant-checkmark a:focus:not(:focus-visible)::after,.hds-dropdown-list-item--variant-checkmark button:focus:not(:focus-visible)::after,.hds-dropdown-list-item--variant-interactive a:focus:not(:focus-visible)::after,.hds-dropdown-list-item--variant-interactive button:focus:not(:focus-visible)::after{background-color:transparent;box-shadow:none}.hds-dropdown-list-item--variant-checkmark a:focus-visible::after,.hds-dropdown-list-item--variant-checkmark button:focus-visible::after,.hds-dropdown-list-item--variant-interactive a:focus-visible::after,.hds-dropdown-list-item--variant-interactive button:focus-visible::after{left:4px;box-shadow:var(--current-focus-ring-box-shadow)}.hds-dropdown-list-item--variant-checkmark a.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-checkmark a:focus-visible:active::after,.hds-dropdown-list-item--variant-checkmark a:focus:active::after,.hds-dropdown-list-item--variant-checkmark button.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-checkmark button:focus-visible:active::after,.hds-dropdown-list-item--variant-checkmark button:focus:active::after,.hds-dropdown-list-item--variant-interactive a.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-interactive a:focus-visible:active::after,.hds-dropdown-list-item--variant-interactive a:focus:active::after,.hds-dropdown-list-item--variant-interactive button.mock-focus.mock-active::after,.hds-dropdown-list-item--variant-interactive button:focus-visible:active::after,.hds-dropdown-list-item--variant-interactive button:focus:active::after{left:10px;background-color:var(--current-background-color);box-shadow:none}.hds-dropdown-list-item--variant-checkmark a.mock-active,.hds-dropdown-list-item--variant-checkmark a:active,.hds-dropdown-list-item--variant-checkmark button.mock-active,.hds-dropdown-list-item--variant-checkmark button:active,.hds-dropdown-list-item--variant-interactive a.mock-active,.hds-dropdown-list-item--variant-interactive a:active,.hds-dropdown-list-item--variant-interactive button.mock-active,.hds-dropdown-list-item--variant-interactive button:active{color:var(--current-color-active)}.hds-dropdown-list-item--variant-checkmark a.mock-active::before,.hds-dropdown-list-item--variant-checkmark a:active::before,.hds-dropdown-list-item--variant-checkmark button.mock-active::before,.hds-dropdown-list-item--variant-checkmark button:active::before,.hds-dropdown-list-item--variant-interactive a.mock-active::before,.hds-dropdown-list-item--variant-interactive a:active::before,.hds-dropdown-list-item--variant-interactive button.mock-active::before,.hds-dropdown-list-item--variant-interactive button:active::before{background-color:currentColor}.hds-dropdown-list-item__interactive-icon{margin-top:2px;margin-right:8px}.hds-dropdown-list-item__interactive-text{flex:1;text-align:left}.hds-dropdown-list-item--color-action a,.hds-dropdown-list-item--color-action button{color:var(--token-color-foreground-primary);--current-color-hover:var(--token-color-foreground-action-hover);--current-color-focus:var(--token-color-foreground-action-active);--current-color-active:var(--token-color-foreground-action-active)}.hds-dropdown-list-item--color-action a::after,.hds-dropdown-list-item--color-action button::after{--current-focus-ring-box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-dropdown-list-item--color-critical a,.hds-dropdown-list-item--color-critical button{color:var(--token-color-foreground-critical);--current-color-hover:var(--token-color-palette-red-300);--current-color-focus:var(--token-color-palette-red-400);--current-color-active:var(--token-color-palette-red-400)}.hds-dropdown-list-item--color-critical a::after,.hds-dropdown-list-item--color-critical button::after{--current-background-color:var(--token-color-surface-critical);--current-focus-ring-box-shadow:var(--token-focus-ring-critical-box-shadow)}.hds-dropdown-list-item__interactive-loading-wrapper{display:flex;align-items:center;padding:8px 10px 8px 16px}.hds-dropdown-list-item__interactive-loading-wrapper .hds-dropdown-list-item__interactive-text{color:var(--token-color-foreground-faint)}.hds-dropdown-list-item__interactive-loading-wrapper .hds-dropdown-list-item__interactive-icon{color:var(--token-color-foreground-primary)}.hds-dropdown-list-item--variant-separator{position:relative;width:100%;height:4px}.hds-dropdown-list-item--variant-separator::before{position:absolute;right:6px;bottom:0;left:6px;content:""}.hds-dropdown-list-item--variant-title{padding:10px 16px 4px;color:var(--token-color-foreground-strong)}.hds-dropdown-list-item--variant-checkmark-selected .hds-dropdown-list-item__interactive{color:var(--token-color-foreground-action)}.hds-dropdown-list-item__checkmark{display:flex;width:16px;height:20px;margin-left:8px}.hds-dropdown-list-item__checkmark-icon{align-self:center}.hds-dropdown-list-item__interactive[disabled],.hds-dropdown-list-item__interactive[disabled]:hover{color:var(--token-color-foreground-disabled);cursor:not-allowed}.hds-dropdown-list-item--variant-checkbox,.hds-dropdown-list-item--variant-radio{display:flex;align-items:self-start;padding:8px 16px}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control{flex-shrink:0;margin-top:2px;margin-right:8px}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__count,.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__icon,.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__text-content,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__count,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__icon,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__control[disabled]~.hds-dropdown-list-item__text-content{color:var(--token-color-foreground-disabled)}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__label,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__label{display:flex;flex-grow:1;align-items:flex-start;color:var(--token-color-foreground-primary)}.hds-dropdown-list-item--variant-checkbox .hds-dropdown-list-item__icon,.hds-dropdown-list-item--variant-radio .hds-dropdown-list-item__icon{margin-top:2px;margin-right:4px}.hds-dropdown-list-item__count{margin-left:auto;padding-left:8px;color:var(--token-color-foreground-faint);line-height:20px}.hds-dropdown-list-item--variant-checkbox .hds-badge,.hds-dropdown-list-item--variant-checkmark .hds-badge,.hds-dropdown-list-item--variant-radio .hds-badge{vertical-align:bottom}.hds-flyout{z-index:49;flex-direction:column;height:100vh;max-height:100vh;margin:0;padding:0;background:var(--token-color-surface-primary);border:none;box-shadow:0 2px 3px 0 rgba(59,61,69,.2509803922),0 12px 24px 0 rgba(59,61,69,.3490196078)}.hds-flyout__footer .hds-button-set .hds-button--color-tertiary,.hds-modal__footer .hds-button-set .hds-button--color-tertiary{margin-left:auto}.hds-flyout__body,.hds-flyout__footer{border-top:1px solid var(--token-color-border-primary)}.hds-flyout[open]{position:fixed;display:flex}.hds-flyout::backdrop{display:none}.hds-flyout__overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:49;background:var(--token-color-palette-neutral-700);opacity:.5}.hds-form-masked-input__toggle-button,.hds-form-text-input__visibility-toggle{right:calc(var(--token-form-control-padding) - var(--token-form-control-border-width))}.hds-flyout__header{display:flex;flex:none;gap:16px;align-items:flex-start;padding:16px 24px;color:var(--token-color-foreground-strong)}.hds-flyout__icon{flex:none;align-self:center}.hds-flyout__title{flex-grow:1}.hds-flyout__tagline{margin-bottom:4px}.hds-flyout__dismiss{align-self:center}.hds-flyout__description{padding:0 24px 16px}.hds-flyout__body{flex:1 1 auto;padding:24px;overflow-y:auto;overscroll-behavior:contain}.hds-flyout__footer{flex:none;padding:16px 24px;background:var(--token-color-surface-faint)}.hds-flyout--size-medium{width:min(480px,100vw - 40px);max-width:calc(100vw - 40px)}.hds-flyout--size-medium[open]{margin-left:calc(100% - min(480px,100vw - 40px))}.hds-flyout--size-large{width:min(720px,100vw - 40px);max-width:calc(100vw - 40px)}.hds-flyout--size-large[open]{margin-left:calc(100% - min(720px,100vw - 40px))}.hds-form-label{display:block;width:-moz-max-content;width:max-content;max-width:100%;color:var(--token-form-label-color)}.hds-form-label .hds-badge{vertical-align:initial}.hds-form-helper-text{display:block;color:var(--token-form-helper-text-color)}.hds-form-error{display:flex;gap:8px;align-items:flex-start;color:var(--token-form-error-color)}.hds-form-error__icon{flex:none;width:var(--token-form-error-icon-size);height:var(--token-form-error-icon-size);margin:2px 0}.hds-form-error__content{flex:1 1 auto}.hds-form-error__message{margin:0}.hds-form-field--layout-vertical{display:grid;justify-items:start;width:100%}.hds-form-field--layout-vertical .hds-form-field__label{width:-moz-fit-content;width:fit-content}.hds-form-field--layout-vertical .hds-form-field__helper-text:not(:first-child){margin-top:4px}.hds-form-field--layout-vertical .hds-form-field__helper-text+.hds-form-helper-text{margin-top:2px}.hds-form-field--layout-vertical .hds-form-field__control{display:flex;justify-self:stretch}.hds-form-field--layout-vertical .hds-form-field__control:not(:first-child){margin-top:8px}.hds-form-field--layout-vertical .hds-form-field__control:not(:last-child){margin-bottom:8px}.hds-form-field--layout-flag{display:grid;grid-auto-flow:row;grid-template-areas:"control label" "control helper-text" "control error";grid-template-rows:auto auto auto;grid-template-columns:auto 1fr;justify-items:start}.hds-form-field--layout-flag .hds-form-field__label{grid-area:label;width:-moz-fit-content;width:fit-content}.hds-form-field--layout-flag .hds-form-field__helper-text{grid-area:helper-text;margin-top:4px}.hds-form-field--layout-flag .hds-form-field__control{display:flex;grid-area:control}.hds-form-field--layout-flag .hds-form-field__control:not(:only-child){margin-top:2px;margin-right:8px}.hds-form-field--layout-flag .hds-form-field__error{grid-area:error;margin-top:4px}.hds-form-file-input{margin:-4px 0 -4px -4px;padding:3px 0 3px 3px;color:var(--token-color-foreground-primary)}.hds-form-file-input:focus,.hds-form-file-input:focus-visible{outline:0}.hds-form-file-input::file-selector-button{min-height:36px;margin-right:16px;padding:7px 16px 7px 37px;color:var(--token-color-foreground-primary);font:inherit;background-color:var(--token-color-surface-faint);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cg fill='%233b3d45'%3E%3Cpath d='M4.24 5.8a.75.75 0 001.06-.04l1.95-2.1v6.59a.75.75 0 001.5 0V3.66l1.95 2.1a.75.75 0 101.1-1.02l-3.25-3.5a.75.75 0 00-1.101.001L4.2 4.74a.75.75 0 00.04 1.06z'/%3E%3Cpath d='M1.75 9a.75.75 0 01.75.75v3c0 .414.336.75.75.75h9.5a.75.75 0 00.75-.75v-3a.75.75 0 011.5 0v3A2.25 2.25 0 0112.75 15h-9.5A2.25 2.25 0 011 12.75v-3A.75.75 0 011.75 9z'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:15px 50%;background-size:var(--token-form-text-input-background-image-size);border:1px solid var(--token-color-border-strong);border-radius:5px;box-shadow:var(--token-elevation-low-box-shadow);cursor:pointer}.hds-form-group__legend~.hds-form-group__control-fields-wrapper .hds-form-label,.hds-link-standalone{font-weight:var(--token-typography-font-weight-regular)}.hds-form-file-input.mock-hover::file-selector-button,.hds-form-file-input::file-selector-button:hover{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-primary);border-color:var(--token-color-border-strong)}.hds-form-file-input.mock-focus::file-selector-button,.hds-form-file-input:focus-within::file-selector-button{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-faint);border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px}.hds-form-file-input:not(:focus,.mock-focus)::file-selector-button{border-color:var(--token-color-border-strong);outline:0}.hds-form-file-input.mock-active::file-selector-button,.hds-form-file-input::file-selector-button:active{color:var(--token-color-foreground-primary);background-color:var(--token-color-surface-interactive-active);border-color:var(--token-color-border-strong);box-shadow:none}.hds-form-file-input.mock-disabled,.hds-form-file-input.mock-disabled:focus,.hds-form-file-input.mock-disabled:hover,.hds-form-file-input:disabled,.hds-form-file-input:disabled:focus,.hds-form-file-input:disabled:hover,.hds-form-file-input[disabled],.hds-form-file-input[disabled]:focus,.hds-form-file-input[disabled]:hover{color:var(--token-color-foreground-disabled)}.hds-form-file-input.mock-disabled::file-selector-button,.hds-form-file-input.mock-disabled:focus::file-selector-button,.hds-form-file-input.mock-disabled:hover::file-selector-button,.hds-form-file-input:disabled::file-selector-button,.hds-form-file-input:disabled:focus::file-selector-button,.hds-form-file-input:disabled:hover::file-selector-button,.hds-form-file-input[disabled]::file-selector-button,.hds-form-file-input[disabled]:focus::file-selector-button,.hds-form-file-input[disabled]:hover::file-selector-button{color:var(--token-color-foreground-disabled);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary);box-shadow:none;cursor:not-allowed;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3E%3Cg fill='%238c909c'%3E%3Cpath d='M4.24 5.8a.75.75 0 001.06-.04l1.95-2.1v6.59a.75.75 0 001.5 0V3.66l1.95 2.1a.75.75 0 101.1-1.02l-3.25-3.5a.75.75 0 00-1.101.001L4.2 4.74a.75.75 0 00.04 1.06z'/%3E%3Cpath d='M1.75 9a.75.75 0 01.75.75v3c0 .414.336.75.75.75h9.5a.75.75 0 00.75-.75v-3a.75.75 0 011.5 0v3A2.25 2.25 0 0112.75 15h-9.5A2.25 2.25 0 011 12.75v-3A.75.75 0 011.75 9z'/%3E%3C/g%3E%3C/svg%3E")}.hds-form-file-input.mock-disabled::file-selector-button::before,.hds-form-file-input.mock-disabled:focus::file-selector-button::before,.hds-form-file-input.mock-disabled:hover::file-selector-button::before,.hds-form-file-input:disabled::file-selector-button::before,.hds-form-file-input:disabled:focus::file-selector-button::before,.hds-form-file-input:disabled:hover::file-selector-button::before,.hds-form-file-input[disabled]::file-selector-button::before,.hds-form-file-input[disabled]:focus::file-selector-button::before,.hds-form-file-input[disabled]:hover::file-selector-button::before{border-color:transparent}.hds-form-legend{display:block;color:var(--token-form-legend-color)}.hds-form-legend .hds-badge{vertical-align:initial}.hds-form-group{display:block;margin:0;padding:0;border:none}.hds-form-checkbox,.hds-form-radio{background-position:center center;border-style:solid;-moz-appearance:none}.hds-form-group__legend{margin:0 0 4px;padding:0}.hds-form-group--layout-vertical .hds-form-group__control-fields-wrapper{display:flex;flex-direction:column}.hds-form-group--layout-vertical .hds-form-group__control-field+.hds-form-group__control-field{margin-top:12px}.hds-form-group--layout-horizontal .hds-form-group__control-fields-wrapper{display:flex;flex-wrap:wrap;margin-bottom:-4px}.hds-form-group--layout-horizontal .hds-form-group__control-field{margin-right:16px;margin-bottom:4px}.hds-form-group__helper-text{margin-bottom:8px}.hds-form-group__error{margin-top:8px}.hds-form-indicator--optional{color:var(--token-form-indicator-optional-color)}.hds-form-checkbox{width:var(--token-form-checkbox-size);height:var(--token-form-checkbox-size);margin:0;padding:0;background-size:var(--token-form-checkbox-background-image-size) var(--token-form-checkbox-background-image-size);border-width:var(--token-form-checkbox-border-width);border-radius:var(--token-form-checkbox-border-radius);cursor:pointer;-webkit-appearance:none;appearance:none}.hds-form-checkbox:not(:checked,:indeterminate){background-color:var(--token-form-control-base-surface-color-default);border-color:var(--token-form-control-base-border-color-default)}.hds-form-checkbox:checked,.hds-form-checkbox:indeterminate{background-color:var(--token-form-control-checked-surface-color-default);border-color:var(--token-form-control-checked-border-color-default)}.hds-form-checkbox:checked{background-image:var(--token-form-checkbox-background-image-data-url)}.hds-form-checkbox:indeterminate{background-image:var(--token-form-checkbox-background-image-data-url-indeterminate)}.hds-form-checkbox.mock-hover:not(:checked,:indeterminate),.hds-form-checkbox:hover:not(:checked,:indeterminate){background-color:var(--token-form-control-base-surface-color-hover);border-color:var(--token-form-control-base-border-color-hover)}.hds-form-checkbox.mock-hover:checked,.hds-form-checkbox.mock-hover:indeterminate,.hds-form-checkbox:hover:checked,.hds-form-checkbox:hover:indeterminate{background-color:var(--token-form-control-checked-border-color-default);border-color:var(--token-form-control-checked-border-color-hover)}.hds-form-checkbox:disabled:checked,.hds-form-checkbox:disabled:indeterminate,.hds-form-checkbox:disabled:not(:checked,:indeterminate){background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-checkbox.mock-focus,.hds-form-checkbox:focus{outline:var(--token-color-focus-action-external) solid 3px;outline-offset:1px}.hds-form-checkbox:disabled:checked{background-image:var(--token-form-checkbox-background-image-data-url-disabled)}.hds-form-checkbox:disabled:indeterminate{background-image:var(--token-form-checkbox-background-image-data-url-indeterminate-disabled);background-repeat:no-repeat}.hds-form-masked-input{position:relative;display:grid;grid-template-areas:"input copy-button";grid-template-columns:1fr auto;width:100%}.hds-form-masked-input .hds-form-masked-input__control{grid-area:input;padding-right:calc(var(--token-form-control-padding) + 24px)}.hds-form-masked-input--is-masked .hds-form-masked-input__control{-webkit-text-security:disc}.hds-form-masked-input--is-not-masked .hds-form-masked-input__control{-webkit-text-security:none}.hds-form-masked-input__toggle-button{position:absolute;top:calc(var(--token-form-control-padding) - var(--token-form-control-border-width));grid-area:input}.hds-form-masked-input__copy-button{grid-area:copy-button;align-self:flex-start;margin-left:8px}.hds-form-radio{width:var(--token-form-radio-size);height:var(--token-form-radio-size);margin:0;padding:0;background-size:var(--token-form-radio-background-image-size) var(--token-form-radio-background-image-size);border-width:var(--token-form-radio-border-width);border-radius:50%;cursor:pointer;-webkit-appearance:none;appearance:none}.hds-form-radio:not(:checked){background-color:var(--token-form-control-base-surface-color-default);border-color:var(--token-form-control-base-border-color-default);box-shadow:var(--token-elevation-inset-box-shadow)}.hds-form-radio:checked{background-color:var(--token-form-control-checked-surface-color-default);background-image:var(--token-form-radio-background-image-data-url);border-color:var(--token-form-control-checked-border-color-default)}.hds-form-radio.mock-hover:not(:checked),.hds-form-radio:hover:not(:checked){background-color:var(--token-form-control-base-surface-color-hover);border-color:var(--token-form-control-base-border-color-hover)}.hds-form-radio.mock-hover:checked,.hds-form-radio:hover:checked{background-color:var(--token-form-control-checked-border-color-default);border-color:var(--token-form-control-checked-border-color-hover)}.hds-form-radio:disabled:checked,.hds-form-radio:disabled:not(:checked){background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-radio.mock-focus,.hds-form-radio:focus{outline:var(--token-color-focus-action-external) solid 3px;outline-offset:1px}.hds-form-radio:disabled:checked{background-image:var(--token-form-radio-background-image-data-url-disabled)}.hds-form-group--radio-cards .hds-form-group__control-fields-wrapper{margin:calc(-1 * var(--token-form-radiocard-group-gap)/ 2)}.hds-form-group--radio-cards .hds-form-group__legend{margin-bottom:12px}.hds-form-group--radio-cards .hds-form-radio-card{margin:calc(var(--token-form-radiocard-group-gap)/ 2)}.hds-form-group--radio-cards .hds-form-radio-card--has-fixed-width{flex:1 0 100%}.hds-form-radio-card{display:flex;flex-direction:column;background-color:var(--token-color-surface-primary);border:var(--token-form-radiocard-border-width) solid var(--token-color-border-primary);border-radius:var(--token-form-radiocard-border-radius);box-shadow:var(--token-elevation-mid-box-shadow);cursor:pointer}.hds-form-radio-card .hds-form-radio-card__control{outline-color:transparent}.hds-form-radio-card.mock-hover,.hds-form-radio-card:hover{box-shadow:var(--token-elevation-high-box-shadow);transition:var(--token-form-radiocard-transition-duration)}.hds-form-radio-card.mock-focus,.hds-form-radio-card:focus-within{border-color:var(--token-color-focus-action-internal);box-shadow:0 0 0 3px var(--token-color-focus-action-external)}.hds-form-radio-card--checked,.hds-form-radio-card.mock-checked{border-color:var(--token-color-focus-action-internal)}.hds-form-radio-card--checked .hds-form-radio-card__control-wrapper,.hds-form-radio-card.mock-checked .hds-form-radio-card__control-wrapper{background-color:var(--token-color-surface-action);border-color:var(--token-color-border-action)}.hds-form-radio-card--disabled,.hds-form-radio-card--disabled .hds-form-radio-card__control-wrapper,.hds-form-radio-card.mock-disabled,.hds-form-radio-card.mock-disabled .hds-form-radio-card__control-wrapper{background-color:var(--token-color-surface-interactive-disabled);border-color:var(--token-color-border-primary)}.hds-form-radio-card--disabled,.hds-form-radio-card.mock-disabled{box-shadow:none;cursor:not-allowed}.hds-form-radio-card--align-left{text-align:left}.hds-form-radio-card--align-center{text-align:center}.hds-form-radio-card--align-center .flight-icon{margin:auto}.hds-form-radio-card--control-bottom .hds-form-radio-card__control-wrapper{border-top-width:var(--token-form-radiocard-border-width);border-top-style:solid;border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.hds-form-radio-card--control-left{flex-direction:row-reverse}.hds-form-radio-card--control-left .hds-form-radio-card__control-wrapper{display:flex;align-items:center;border-right-width:var(--token-form-radiocard-border-width);border-right-style:solid;border-top-left-radius:inherit;border-bottom-left-radius:inherit}.hds-form-radio-card__content{flex:1;padding:var(--token-form-radiocard-content-padding)}.hds-form-radio-card__content .hds-badge{margin-bottom:12px}.hds-form-radio-card__label{display:block;margin:8px 0;color:var(--token-form-label-color);overflow-wrap:break-word}.hds-form-radio-card__label:first-child{margin-top:0}.hds-form-radio-card__description{display:block;color:var(--token-color-foreground-primary)}.hds-form-radio-card__control-wrapper{padding:var(--token-form-radiocard-control-padding);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary)}.hds-form-select,.hds-form-text-input{border:var(--token-form-control-border-width) solid var(--token-form-control-base-border-color-default)}.hds-form-radio-card__control{display:block;margin:auto}.hds-form-select{max-width:100%;padding:var(--token-form-control-padding);padding-right:calc(var(--token-form-control-padding) + 24px);color:var(--token-form-control-base-foreground-value-color);background-color:var(--token-form-control-base-surface-color-default);background-image:var(--token-form-select-background-image-data-url);background-repeat:no-repeat;background-position:right var(--token-form-select-background-image-position-right-x) top var(--token-form-select-background-image-position-top-y);background-size:var(--token-form-select-background-image-size) var(--token-form-select-background-image-size);border-radius:var(--token-form-control-border-radius);box-shadow:var(--token-elevation-low-box-shadow);-webkit-appearance:none;-moz-appearance:none;appearance:none}.hds-form-select.mock-hover,.hds-form-select:hover{border-color:var(--token-form-control-base-border-color-hover)}.hds-form-select.mock-focus,.hds-form-select:focus{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px;outline-offset:0}.hds-form-select:disabled{color:var(--token-form-control-disabled-foreground-color);background-color:var(--token-form-control-disabled-surface-color);background-image:var(--token-form-select-background-image-data-url-disabled);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-select.hds-form-select--is-invalid{border-color:var(--token-form-control-invalid-border-color-default)}.hds-form-select.hds-form-select--is-invalid.mock-hover,.hds-form-select.hds-form-select--is-invalid:hover{border-color:var(--token-form-control-invalid-border-color-hover)}.hds-form-select.hds-form-select--is-invalid.mock-focus,.hds-form-select.hds-form-select--is-invalid:focus{border-color:var(--token-color-focus-critical-internal);outline-color:var(--token-color-focus-critical-external)}.hds-form-select[multiple],.hds-form-select[size]{background:0 0}.hds-form-select[multiple] option,.hds-form-select[size] option{margin:2px auto;border-radius:3px}.hds-form-select[multiple] option:hover,.hds-form-select[size] option:hover{color:var(--token-color-foreground-action)}.hds-form-select[multiple] option:disabled,.hds-form-select[size] option:disabled{color:var(--token-color-foreground-disabled)}.hds-form-select[multiple] option:checked,.hds-form-select[size] option:checked{color:var(--token-color-foreground-high-contrast);background:var(--token-color-palette-blue-200)}.hds-form-text-input,.hds-form-textarea{background-color:var(--token-form-control-base-surface-color-default);max-width:100%}.hds-form-select[multiple] optgroup,.hds-form-select[size] optgroup{color:var(--token-color-foreground-strong);font-weight:var(--token-typography-font-weight-semibold);font-style:normal}.hds-form-text-input{width:100%;padding:var(--token-form-control-padding);color:var(--token-form-control-base-foreground-value-color);border-radius:var(--token-form-control-border-radius);box-shadow:var(--token-elevation-inset-box-shadow)}.hds-form-text-input ::-moz-placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-text-input ::placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-text-input.mock-hover,.hds-form-text-input:hover{border-color:var(--token-form-control-base-border-color-hover)}.hds-form-text-input.mock-focus,.hds-form-text-input:focus{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px;outline-offset:0}.hds-form-text-input:-moz-read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-text-input:read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-text-input:disabled{color:var(--token-form-control-disabled-foreground-color);background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-text-input.hds-form-text-input--is-invalid{border-color:var(--token-form-control-invalid-border-color-default)}.hds-form-text-input.hds-form-text-input--is-invalid.mock-hover,.hds-form-text-input.hds-form-text-input--is-invalid:hover{border-color:var(--token-form-control-invalid-border-color-hover)}.hds-form-text-input.hds-form-text-input--is-invalid.mock-focus,.hds-form-text-input.hds-form-text-input--is-invalid:focus{border-color:var(--token-color-focus-critical-internal);outline-color:var(--token-color-focus-critical-external)}.hds-form-text-input__wrapper{position:relative;width:100%}.hds-form-text-input--has-visibility-toggle{padding-right:calc(var(--token-form-control-padding) + 24px)}.hds-form-text-input__visibility-toggle{position:absolute;top:calc(var(--token-form-control-padding) - var(--token-form-control-border-width))}.hds-form-text-input[type=date],.hds-form-text-input[type=datetime-local],.hds-form-text-input[type=time]{width:initial}.hds-form-text-input[type=date]:disabled::-webkit-calendar-picker-indicator,.hds-form-text-input[type=datetime-local]:disabled::-webkit-calendar-picker-indicator,.hds-form-text-input[type=time]:disabled::-webkit-calendar-picker-indicator{visibility:visible;opacity:.5}.hds-form-text-input[type=date][readonly]::-webkit-calendar-picker-indicator,.hds-form-text-input[type=datetime-local][readonly]::-webkit-calendar-picker-indicator,.hds-form-text-input[type=time][readonly]::-webkit-calendar-picker-indicator{visibility:visible}.hds-form-text-input[type=date]::-webkit-calendar-picker-indicator,.hds-form-text-input[type=datetime-local]::-webkit-calendar-picker-indicator{background-image:var(--token-form-text-input-background-image-data-url-date);background-position:center center;background-size:var(--token-form-text-input-background-image-size)}.hds-form-text-input[type=time]::-webkit-calendar-picker-indicator{background-image:var(--token-form-text-input-background-image-data-url-time);background-position:center center;background-size:var(--token-form-text-input-background-image-size)}.hds-form-text-input[type=search]{padding-left:calc(var(--token-form-control-padding) + 24px);background-image:var(--token-form-text-input-background-image-data-url-search);background-repeat:no-repeat;background-position:var(--token-form-text-input-background-image-position-x) 50%;background-size:var(--token-form-text-input-background-image-size)}.hds-form-text-input[type=search]::-webkit-search-cancel-button{width:var(--token-form-text-input-background-image-size);height:var(--token-form-text-input-background-image-size);background-image:var(--token-form-text-input-background-image-data-url-search-cancel);background-position:center center;background-size:var(--token-form-text-input-background-image-size);-webkit-appearance:none}.hds-form-text-input[type=search].hds-form-text-input--is-loading{background-image:var(--token-form-text-input-background-image-data-url-search-loading)}.hds-form-textarea{width:100%;min-height:36px;padding:var(--token-form-control-padding);color:var(--token-form-control-base-foreground-value-color);border:var(--token-form-control-border-width) solid var(--token-form-control-base-border-color-default);border-radius:var(--token-form-control-border-radius);box-shadow:var(--token-elevation-inset-box-shadow);resize:vertical}.hds-form-textarea ::-moz-placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-textarea ::placeholder{color:var(--token-form-control-base-foreground-placeholder-color)}.hds-form-textarea.mock-hover,.hds-form-textarea:hover{border-color:var(--token-form-control-base-border-color-hover)}.hds-form-textarea.mock-focus,.hds-form-textarea:focus{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px;outline-offset:0}.hds-form-textarea:-moz-read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-textarea:read-only{color:var(--token-form-control-readonly-foreground-color);background-color:var(--token-form-control-readonly-surface-color);border-color:var(--token-form-control-readonly-border-color);box-shadow:none}.hds-form-textarea:disabled{color:var(--token-form-control-disabled-foreground-color);background-color:var(--token-form-control-disabled-surface-color);border-color:var(--token-form-control-disabled-border-color);box-shadow:none;cursor:not-allowed}.hds-form-textarea.hds-form-textarea--is-invalid{border-color:var(--token-form-control-invalid-border-color-default)}.hds-form-textarea.hds-form-textarea--is-invalid.mock-hover,.hds-form-textarea.hds-form-textarea--is-invalid:hover{border-color:var(--token-form-control-invalid-border-color-hover)}.hds-form-textarea.hds-form-textarea--is-invalid.mock-focus,.hds-form-textarea.hds-form-textarea--is-invalid:focus{border-color:var(--token-color-focus-critical-internal);outline-color:var(--token-color-focus-critical-external)}.hds-form-toggle{position:relative;isolation:isolate}.hds-form-toggle__control{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;display:block;height:100%;margin:0;padding:0;color:transparent;background-color:transparent;border:none;outline:0;cursor:pointer;opacity:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.hds-form-toggle__control:disabled{cursor:not-allowed}.hds-form-toggle__facade{position:relative;display:block;width:var(--token-form-toggle-width);height:var(--token-form-toggle-height);background-image:var(--token-form-toggle-background-image-data-url);background-repeat:no-repeat;background-position:var(--token-form-toggle-background-image-position-x) 50%;background-size:var(--token-form-toggle-background-image-size) var(--token-form-toggle-background-image-size);border:var(--token-form-radio-border-width) solid var(--border-color);border-radius:calc(var(--token-form-toggle-height)/ 2)}.hds-form-toggle__facade::after{position:absolute;top:calc(var(--token-form-radio-border-width) * -1);left:calc(var(--token-form-radio-border-width) * -1);width:var(--token-form-toggle-thumb-size);height:var(--token-form-toggle-thumb-size);background-color:var(--token-form-control-base-surface-color-default);border:var(--token-form-radio-border-width) solid var(--border-color);border-radius:50%;transform:translate3d(0,0,0);content:""}@media (prefers-reduced-motion:no-preference){.hds-form-toggle__facade,.hds-form-toggle__facade::after{transition-timing-function:var(--token-form-toggle-transition-timing-function);transition-duration:var(--token-form-toggle-transition-duration);transition-property:all}}.hds-form-toggle__facade::before{position:absolute;top:-5px;right:-5px;bottom:-5px;left:-5px;margin:auto;border-width:3px;border-radius:calc(var(--token-form-toggle-height)/ 2 + 3px + 1px);content:""}:not(:checked)+.hds-form-toggle__facade{--border-color:var(--token-form-control-base-border-color-default);background-color:var(--token-form-toggle-base-surface-color-default)}:checked+.hds-form-toggle__facade{--border-color:var(--token-form-control-checked-border-color-default);background-color:var(--token-form-control-checked-surface-color-default)}:checked+.hds-form-toggle__facade::after{transform:translate3d(calc(var(--token-form-toggle-width) - var(--token-form-toggle-thumb-size)),0,0)}.mock-hover:not(:checked)+.hds-form-toggle__facade,:hover:not(:checked)+.hds-form-toggle__facade{--border-color:var(--token-form-control-base-border-color-hover)}.mock-hover:checked+.hds-form-toggle__facade,:hover:checked+.hds-form-toggle__facade{--border-color:var(--token-form-control-checked-border-color-hover);background-color:var(--token-form-control-checked-border-color-default)}.mock-focus+.hds-form-toggle__facade::before,:focus+.hds-form-toggle__facade::before{border-color:var(--token-color-focus-action-external);border-style:solid}:disabled:checked+.hds-form-toggle__facade,:disabled:not(:checked)+.hds-form-toggle__facade{--border-color:var(--token-form-control-disabled-border-color);background-color:var(--token-form-control-disabled-surface-color);background-image:var(--token-form-toggle-background-image-data-url-disabled)}.hds-form-visibility-toggle{width:24px;height:24px;padding:2px;color:var(--token-color-foreground-primary);background-color:transparent;border-color:transparent;cursor:pointer}.hds-icon-tile--logo,.hds-icon-tile__extra{background-color:var(--token-color-surface-primary)}.hds-icon-tile{position:relative;display:flex;border:1px solid transparent;border-radius:4px;box-shadow:0 1px 1px rgba(101,106,118,.05)}.hds-icon-tile__icon,.hds-icon-tile__logo{display:flex;margin:auto}.hds-icon-tile__extra{position:absolute;right:-6px;bottom:-6px;display:flex;box-sizing:content-box;border:1px solid var(--token-color-border-primary);box-shadow:0 1px 1px rgba(101,106,118,.05)}.hds-icon-tile__extra-icon{display:flex;margin:auto;color:var(--token-color-foreground-strong)}.hds-icon-tile--size-small{width:1.75rem;height:1.75rem;border-radius:5px}.hds-icon-tile--size-small .hds-icon-tile__icon{width:1rem;height:1rem}.hds-icon-tile--size-small .hds-icon-tile__logo{width:1.125rem;height:1.125rem}.hds-icon-tile--size-small .hds-icon-tile__extra{width:1.125rem;height:1.125rem;border-radius:4px}.hds-icon-tile--size-small .hds-icon-tile__extra-icon{width:.75rem;height:.75rem}.hds-icon-tile--size-medium{width:2.5rem;height:2.5rem;border-radius:6px}.hds-icon-tile--size-medium .hds-icon-tile__icon{width:1.5rem;height:1.5rem}.hds-icon-tile--size-medium .hds-icon-tile__logo{width:1.75rem;height:1.75rem}.hds-icon-tile--size-medium .hds-icon-tile__extra{width:1.5rem;height:1.5rem;border-radius:5px}.hds-icon-tile--size-medium .hds-icon-tile__extra-icon{width:1rem;height:1rem}.hds-icon-tile--size-large{width:3rem;height:3rem;border-radius:6px}.hds-icon-tile--size-large .hds-icon-tile__icon{width:1.5rem;height:1.5rem}.hds-icon-tile--size-large .hds-icon-tile__logo{width:2rem;height:2rem}.hds-icon-tile--size-large .hds-icon-tile__extra{width:1.5rem;height:1.5rem;border-radius:5px}.hds-icon-tile--size-large .hds-icon-tile__extra-icon{width:1rem;height:1rem}.hds-icon-tile--logo{border-color:var(--token-color-border-primary)}.hds-icon-tile--icon.hds-icon-tile--color-neutral{color:var(--token-color-foreground-faint);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary)}.hds-icon-tile--icon.hds-icon-tile--color-boundary{color:var(--token-color-boundary-foreground);background:linear-gradient(135deg,var(--token-color-boundary-gradient-faint-start) 0,var(--token-color-boundary-gradient-faint-stop) 100%);border-color:var(--token-color-boundary-border)}.hds-icon-tile--icon.hds-icon-tile--color-consul{color:var(--token-color-consul-foreground);background:linear-gradient(135deg,var(--token-color-consul-gradient-faint-start) 0,var(--token-color-consul-gradient-faint-stop) 100%);border-color:var(--token-color-consul-border)}.hds-icon-tile--icon.hds-icon-tile--color-hcp{color:var(--token-color-palette-hcp-brand);background-color:var(--token-color-surface-faint);border-color:var(--token-color-border-primary)}.hds-icon-tile--icon.hds-icon-tile--color-nomad{color:var(--token-color-nomad-foreground);background:linear-gradient(135deg,var(--token-color-nomad-gradient-faint-start) 0,var(--token-color-nomad-gradient-faint-stop) 100%);border-color:var(--token-color-nomad-border)}.hds-icon-tile--icon.hds-icon-tile--color-packer{color:var(--token-color-packer-foreground);background:linear-gradient(135deg,var(--token-color-packer-gradient-faint-start) 0,var(--token-color-packer-gradient-faint-stop) 100%);border-color:var(--token-color-packer-border)}.hds-icon-tile--icon.hds-icon-tile--color-terraform{color:var(--token-color-terraform-foreground);background:linear-gradient(135deg,var(--token-color-terraform-gradient-faint-start) 0,var(--token-color-terraform-gradient-faint-stop) 100%);border-color:var(--token-color-terraform-border)}.hds-icon-tile--icon.hds-icon-tile--color-vagrant{color:var(--token-color-vagrant-foreground);background:linear-gradient(135deg,var(--token-color-vagrant-gradient-faint-start) 0,var(--token-color-vagrant-gradient-faint-stop) 100%);border-color:var(--token-color-vagrant-border)}.hds-icon-tile--icon.hds-icon-tile--color-vault{color:var(--token-color-vault-foreground);background:linear-gradient(135deg,var(--token-color-vault-gradient-faint-start) 0,var(--token-color-vault-gradient-faint-stop) 100%);border-color:var(--token-color-vault-border)}.hds-icon-tile--icon.hds-icon-tile--color-vault-secrets{color:var(--token-color-vault-secrets-foreground);background:linear-gradient(135deg,var(--token-color-vault-secrets-gradient-faint-start) 0,var(--token-color-vault-secrets-gradient-faint-stop) 100%);border-color:var(--token-color-vault-secrets-border)}.hds-icon-tile--icon.hds-icon-tile--color-waypoint{color:var(--token-color-waypoint-foreground);background:linear-gradient(135deg,var(--token-color-waypoint-gradient-faint-start) 0,var(--token-color-waypoint-gradient-faint-stop) 100%);border-color:var(--token-color-waypoint-border)}.hds-link-inline{border-radius:2px}.hds-link-inline.mock-focus,.hds-link-inline:focus,.hds-link-inline:focus-visible{text-decoration:none;outline:var(--token-color-focus-action-internal) solid 2px;outline-offset:1px}.hds-link-inline__icon{display:inline-block;width:1em;height:1em;vertical-align:text-bottom}.hds-link-inline--icon-leading>.hds-link-inline__icon{margin-right:.25em}.hds-link-inline--icon-trailing>.hds-link-inline__icon{margin-left:.25em}.hds-link-inline--color-primary{color:var(--token-color-foreground-action)}.hds-link-inline--color-primary.mock-hover,.hds-link-inline--color-primary:hover{color:var(--token-color-foreground-action-hover)}.hds-link-inline--color-primary.mock-active,.hds-link-inline--color-primary:active{color:var(--token-color-foreground-action-active)}.hds-link-inline--color-secondary{color:var(--token-color-foreground-strong)}.hds-link-inline--color-secondary.mock-hover,.hds-link-inline--color-secondary:hover{color:var(--token-color-foreground-primary)}.hds-link-inline--color-secondary.mock-active,.hds-link-inline--color-secondary:active{color:var(--token-color-foreground-faint)}.hds-link-standalone{display:flex;align-items:center;justify-content:center;width:-moz-fit-content;width:fit-content;padding-top:4px;padding-bottom:4px;background-color:transparent;border:1px solid transparent;text-decoration-color:transparent;position:relative;outline-style:solid;outline-color:transparent}.hds-link-standalone__text{flex:1 0 0;text-decoration:underline;text-decoration-color:transparent;transition:text-decoration-color .25s ease-in}#login-toggle+div footer button,.consul-intention-fieldsets .permissions>button,.empty-state>ul>li>*,.empty-state>ul>li>:active,.empty-state>ul>li>label>button,.empty-state>ul>li>label>button:active,.hds-pagination-nav__control,.hds-side-nav__list-item-link,.hds-tabs__tab,.modal-dialog [role=document] dd a,.modal-dialog [role=document] p a,.oidc-select button.reset,.search-bar-status .remove-all button,a,main dd a,main dd a:active,main p a,main p a:active{text-decoration:none}.hds-link-standalone--size-small .hds-link-standalone__icon{width:.75rem;height:.75rem}.hds-link-standalone--size-small .hds-link-standalone__text{font-size:.8125rem;line-height:1.231}.hds-link-standalone--size-medium .hds-link-standalone__icon{width:1rem;height:1rem}.hds-link-standalone--size-medium .hds-link-standalone__text{font-size:.875rem;line-height:1.143}.hds-link-standalone--size-large .hds-link-standalone__icon{width:1.5rem;height:1.5rem}.hds-link-standalone--size-large .hds-link-standalone__text{font-size:1rem;line-height:1.5}.hds-link-standalone--color-primary{color:var(--token-color-foreground-action)}.hds-link-standalone--color-primary.mock-hover,.hds-link-standalone--color-primary:hover{color:var(--token-color-foreground-action-hover)}.hds-link-standalone--color-primary.mock-hover .hds-link-standalone__text,.hds-link-standalone--color-primary:hover .hds-link-standalone__text{text-decoration-color:#4e81e8}.hds-link-standalone--color-primary.mock-active,.hds-link-standalone--color-primary:active{color:var(--token-color-foreground-action-active)}.hds-link-standalone--color-primary.mock-active .hds-link-standalone__text,.hds-link-standalone--color-primary:active .hds-link-standalone__text{text-decoration-color:#396ed6}.hds-link-standalone--color-primary.mock-active::before,.hds-link-standalone--color-primary:active::before{background-color:var(--token-color-surface-action)}.hds-link-standalone--color-secondary{color:var(--token-color-foreground-strong)}.hds-link-standalone--color-secondary.mock-hover .hds-link-standalone__text,.hds-link-standalone--color-secondary:hover .hds-link-standalone__text{text-decoration-color:#4d4d4f}.hds-link-standalone--color-secondary.mock-active,.hds-link-standalone--color-secondary:active{color:var(--token-color-foreground-primary)}.hds-link-standalone--color-secondary.mock-active .hds-link-standalone__text,.hds-link-standalone--color-secondary:active .hds-link-standalone__text{text-decoration-color:#6e7075}.hds-link-standalone--color-secondary.mock-active::before,.hds-link-standalone--color-secondary:active::before{background-color:var(--token-color-surface-interactive-active)}.hds-link-standalone::before{position:absolute;top:0;right:-5px;bottom:0;left:-5px;z-index:-1;border-radius:5px;content:""}.hds-link-standalone:focus:not(:focus-visible)::before{box-shadow:none}.hds-link-standalone:focus-visible::before,.hds-pagination-nav__control.mock-focus::before,.hds-pagination-nav__control:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-link-standalone.mock-focus.mock-active::before,.hds-link-standalone:focus:active::before{box-shadow:none}.hds-link-standalone.hds-link-standalone--icon-position-leading::before{right:-7px}.hds-link-standalone.hds-link-standalone--icon-position-trailing::before{left:-7px}.hds-menu-primitive{position:relative;width:-moz-fit-content;width:fit-content}.hds-modal{z-index:50;flex-direction:column;padding:0;background:var(--token-color-surface-primary);border:none;border-radius:8px;box-shadow:var(--token-surface-overlay-box-shadow)}.hds-modal[open]{position:fixed;display:flex}.hds-modal::backdrop{display:none}.hds-modal__overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:var(--token-color-palette-neutral-700);opacity:.5}.hds-modal__header{display:flex;flex:none;gap:16px;align-items:flex-start;padding:16px 24px;border-top-left-radius:inherit;border-top-right-radius:inherit}.hds-modal__icon{flex:none;align-self:center}.freetext-filter>label,.freetext-filter_input,.hds-modal__title{flex-grow:1}.hds-modal__tagline{margin-bottom:4px}.hds-modal__dismiss{align-self:center}.hds-modal__body{flex:1 1 auto;padding:24px;overflow-y:auto;overscroll-behavior:contain}.hds-modal__footer{flex:none;padding:16px 24px;background:var(--token-color-surface-faint);border-top:1px solid var(--token-color-border-primary);border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.hds-modal--size-small{width:min(400px,95vw)}.hds-modal--size-medium{width:min(600px,95vw)}.hds-modal--size-large{width:min(800px,95vw)}.hds-modal--color-neutral .hds-modal__header{color:var(--token-color-foreground-strong);background:var(--token-color-surface-faint);border-bottom:1px solid var(--token-color-border-primary)}.hds-modal--color-neutral .hds-modal__tagline{color:var(--token-color-foreground-faint)}.hds-modal--color-warning .hds-modal__header,.hds-modal--color-warning .hds-modal__tagline{color:var(--token-color-foreground-warning-on-surface)}.hds-modal--color-warning .hds-modal__header{background:var(--token-color-surface-warning);border-bottom:1px solid var(--token-color-border-warning)}.hds-modal--color-critical .hds-modal__header,.hds-modal--color-critical .hds-modal__tagline{color:var(--token-color-foreground-critical-on-surface)}.hds-modal--color-critical .hds-modal__header{background:var(--token-color-surface-critical);border-bottom:1px solid var(--token-color-border-critical)}.hds-page-header{position:relative;display:flex;flex-direction:column;gap:16px;container-type:inline-size}.hds-page-header__body{display:flex;flex-direction:column;gap:8px 16px}.hds-page-header__body .hds-icon-tile{flex-shrink:0}@container (min-width:400px){.hds-page-header__body{flex-direction:row}}.hds-page-header__main{display:flex;flex-direction:column;flex-grow:1;gap:16px;align-items:start;justify-content:start}@container (min-width:768px){.hds-page-header__main{flex-direction:row;justify-content:space-between;min-width:0}}.hds-page-header__content{display:flex;flex-direction:column;flex-grow:1;gap:8px;min-width:0;max-width:100%}.hds-page-header__title-wrapper{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px 16px;align-items:center}.hds-page-header__title{max-width:100%;overflow-wrap:break-word}.hds-page-header__badges-wrapper{display:flex;flex-wrap:wrap;gap:8px}.hds-page-header__metadata{display:flex;flex-direction:column;gap:4px}.hds-page-header__description,.hds-page-header__subtitle{overflow-wrap:break-word}.hds-page-header__actions{display:flex;flex-direction:row;flex-shrink:0;flex-wrap:wrap;gap:16px;align-items:center}.hds-pagination{display:grid;grid-template-areas:"info nav selector";grid-template-rows:auto;grid-template-columns:1fr auto 1fr;align-items:center;margin:0 auto}@media screen and (max-width:1000px){.hds-pagination{display:flex;flex-wrap:wrap;justify-content:center}.hds-pagination .hds-pagination-info{margin-top:var(--token-pagination-child-spacing-vertical);margin-left:var(--token-pagination-child-spacing-horizontal)}}.hds-pagination .hds-pagination-info{grid-area:info;justify-self:flex-start;margin-right:var(--token-pagination-child-spacing-horizontal)}.hds-pagination .hds-pagination-nav{grid-area:nav}@media screen and (max-width:1000px){.hds-pagination .hds-pagination-nav{justify-content:center;order:-1;width:100%}.hds-pagination .hds-pagination-size-selector{margin-top:var(--token-pagination-child-spacing-vertical);margin-right:var(--token-pagination-child-spacing-horizontal)}}.hds-pagination .hds-pagination-size-selector{grid-area:selector;justify-self:flex-end;margin-left:var(--token-pagination-child-spacing-horizontal)}.hds-pagination-info{white-space:nowrap}.hds-pagination-nav{display:flex}.hds-pagination-nav__page-list{display:flex;margin:0;padding:0}.hds-pagination-nav__page-item{list-style-type:none}.hds-pagination-nav__control{display:flex;align-items:center;height:var(--token-pagination-nav-control-height);padding:0 calc(var(--token-pagination-nav-control-padding-horizontal) - 1px);color:var(--token-color-foreground-primary);background-color:transparent;border:1px solid transparent;position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-pagination-nav__control::before{position:absolute;top:var(--token-pagination-nav-control-focus-inset);right:var(--token-pagination-nav-control-focus-inset);bottom:var(--token-pagination-nav-control-focus-inset);left:var(--token-pagination-nav-control-focus-inset);z-index:-1;border-radius:5px;content:""}.hds-pagination-nav__control:focus:not(:focus-visible)::before{box-shadow:none}.hds-pagination-nav__control:focus-visible::before,.hds-side-nav__home-link.mock-focus.mock-focus::before,.hds-side-nav__home-link.mock-focus:focus::before,.hds-side-nav__home-link:focus.mock-focus::before,.hds-side-nav__home-link:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-pagination-nav__control.mock-focus.mock-active::before,.hds-pagination-nav__control:focus:active::before{box-shadow:none}.hds-pagination-nav__control.mock-hover,.hds-pagination-nav__control:hover{color:var(--token-color-foreground-action-hover)}.hds-pagination-nav__control.mock-active,.hds-pagination-nav__control:active{color:var(--token-color-foreground-action-active)}.hds-pagination-nav__arrow{gap:var(--token-pagination-nav-control-icon-spacing)}.hds-pagination-nav__arrow.mock-disabled,.hds-pagination-nav__arrow:disabled{color:var(--token-color-foreground-disabled);cursor:not-allowed}.hds-pagination-nav__arrow--direction-prev{flex-direction:row;justify-content:flex-start}.hds-pagination-nav__arrow--direction-next{flex-direction:row-reverse;justify-content:flex-end}.hds-pagination-nav__number--is-selected{position:relative;color:var(--token-color-foreground-action)}.hds-pagination-nav__number--is-selected:hover{color:var(--token-color-foreground-action-hover)}.hds-pagination-nav__number--is-selected:active{color:var(--token-color-foreground-action-active)}.hds-pagination-nav__number--is-selected::after{position:absolute;right:calc(var(--token-pagination-nav-indicator-spacing) - 1px);bottom:-1px;left:calc(var(--token-pagination-nav-indicator-spacing) - 1px);height:var(--token-pagination-nav-indicator-height);margin:0 auto;background-color:currentColor;border-radius:2px;content:""}.hds-pagination-nav__ellipsis{display:flex;align-items:center;height:var(--token-pagination-nav-control-height);padding:0 var(--token-pagination-nav-control-padding-horizontal);color:var(--token-color-foreground-faint)}.hds-pagination-size-selector{display:flex;align-items:center}.hds-pagination-size-selector>label{white-space:nowrap}.hds-pagination-size-selector>select{height:28px;margin-left:12px;padding:0 24px 0 8px;font-size:var(--token-typography-body-100-font-size);font-family:var(--token-typography-body-100-font-family);line-height:var(--token-typography-body-100-line-height);background-position:center right 5px}.hds-reveal{width:-moz-fit-content;width:fit-content}.hds-reveal__toggle-button{min-height:1.75rem;padding:.313rem .313rem .313rem .188rem}@media (prefers-reduced-motion:no-preference){.hds-reveal__toggle-button .flight-icon-chevron-down{transition:transform .3s}}.hds-reveal__toggle-button--is-open .flight-icon-chevron-down{transform:rotate(-180deg)}.hds-reveal__content{margin-top:4px}.hds-segmented-group{display:inline-flex}.hds-side-nav--is-desktop .hds-side-nav__overlay,.hds-side-nav__toggle-button.mock-focus::after,.hds-side-nav__toggle-button.mock-focus::before,.hds-side-nav__toggle-button:focus-visible::after,.hds-side-nav__toggle-button:focus-visible::before{display:none}.hds-segmented-group>.hds-button:first-child,.hds-segmented-group>.hds-dropdown:first-child,.hds-segmented-group>.hds-form-select:first-child,.hds-segmented-group>.hds-form-text-input:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.hds-segmented-group>.hds-button:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-button:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-button:first-child::before,.hds-segmented-group>.hds-dropdown:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-dropdown:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-dropdown:first-child::before,.hds-segmented-group>.hds-form-select:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-select:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-select:first-child::before,.hds-segmented-group>.hds-form-text-input:first-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-text-input:first-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-text-input:first-child::before{border-top-right-radius:inherit;border-bottom-right-radius:inherit}.hds-segmented-group>.hds-button:last-child,.hds-segmented-group>.hds-dropdown:last-child,.hds-segmented-group>.hds-form-select:last-child,.hds-segmented-group>.hds-form-text-input:last-child{margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.hds-segmented-group>.hds-button:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-button:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-button:last-child::before,.hds-segmented-group>.hds-dropdown:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-dropdown:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-dropdown:last-child::before,.hds-segmented-group>.hds-form-select:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-select:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-select:last-child::before,.hds-segmented-group>.hds-form-text-input:last-child .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-text-input:last-child .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-text-input:last-child::before{border-top-left-radius:inherit;border-bottom-left-radius:inherit}.hds-segmented-group>.hds-button:not(:first-child,:last-child),.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child),.hds-segmented-group>.hds-form-select:not(:first-child,:last-child),.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child){margin-left:-1px;border-radius:0}.hds-segmented-group>.hds-button:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-button:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-button:not(:first-child,:last-child)::before,.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-dropdown:not(:first-child,:last-child)::before,.hds-segmented-group>.hds-form-select:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-select:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-select:not(:first-child,:last-child)::before,.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child) .hds-dropdown-toggle-button,.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child) .hds-dropdown-toggle-button::before,.hds-segmented-group>.hds-form-text-input:not(:first-child,:last-child)::before{border-radius:inherit}.hds-segmented-group>.hds-button .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-button.mock-focus,.hds-segmented-group>.hds-button:focus,.hds-segmented-group>.hds-dropdown .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-dropdown.mock-focus,.hds-segmented-group>.hds-dropdown:focus,.hds-segmented-group>.hds-form-select .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-form-select.mock-focus,.hds-segmented-group>.hds-form-select:focus,.hds-segmented-group>.hds-form-text-input .hds-dropdown-toggle-button:focus,.hds-segmented-group>.hds-form-text-input.mock-focus,.hds-segmented-group>.hds-form-text-input:focus{z-index:1}.hds-separator{border:none;border-top:1px solid var(--token-color-border-primary)}.hds-separator--spacing-24{margin:24px 0}.hds-separator--spacing-0{margin:0}.hds-side-nav{top:0;z-index:20;width:var(--hds-app-sidenav-width-fixed);height:100vh;min-height:100vh;isolation:isolate}.hds-side-nav.hds-side-nav--is-responsive{transition:width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav.hds-side-nav--is-mobile{width:var(--hds-app-sidenav-width-minimized)}.hds-side-nav.hds-side-nav--is-desktop.hds-side-nav--is-not-minimized{width:var(--hds-app-sidenav-width-expanded)}.hds-side-nav--is-minimized .hds-side-nav__wrapper,.hds-side-nav.hds-side-nav--is-desktop.hds-side-nav--is-minimized{width:var(--hds-app-sidenav-width-minimized)}.hds-side-nav__overlay{position:fixed;z-index:-1;inset:0;background-color:var(--token-color-palette-neutral-700);opacity:.2;transition:opacity var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing) var(--hds-app-sidenav-animation-delay)}.hds-side-nav--is-minimized .hds-side-nav__overlay{opacity:0;pointer-events:none}.hds-side-nav__wrapper{display:flex;flex-direction:column;height:100%;color:var(--token-side-nav-color-foreground-primary);background:var(--token-side-nav-color-surface-primary);border-right:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color)}.hds-side-nav--is-responsive .hds-side-nav__wrapper{transition:width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav--is-not-minimized .hds-side-nav__wrapper{width:var(--hds-app-sidenav-width-expanded)}.hds-side-nav__wrapper-header{padding-top:var(--token-side-nav-wrapper-padding-vertical);padding-right:var(--token-side-nav-wrapper-padding-horizontal);padding-bottom:8px;padding-left:var(--token-side-nav-wrapper-padding-horizontal);transition:padding var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav--is-minimized .hds-side-nav__wrapper-header{padding-top:var(--token-side-nav-wrapper-padding-vertical-minimized);padding-right:var(--token-side-nav-wrapper-padding-horizontal-minimized);padding-left:var(--token-side-nav-wrapper-padding-horizontal-minimized)}.hds-side-nav__wrapper-body,.hds-side-nav__wrapper-footer{padding:var(--token-side-nav-wrapper-padding-vertical) var(--token-side-nav-wrapper-padding-horizontal)}.hds-side-nav__wrapper-body{flex:1;overflow-x:hidden;overflow-y:auto}.hds-side-nav--is-minimized .hds-side-nav-hide-when-minimized{visibility:hidden!important;opacity:0;pointer-events:none}.hds-side-nav--is-not-minimized .hds-side-nav-hide-when-minimized{visibility:visible;opacity:1;transition:opacity var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing) var(--hds-app-sidenav-animation-delay)}.hds-side-nav--is-animating .hds-side-nav-hide-when-minimized{pointer-events:none}.hds-side-nav-header{display:flex;align-items:center;justify-content:space-between}.hds-side-nav-header__logo-container{display:flex;flex:none;align-items:center;justify-content:center;width:var(--token-side-nav-header-home-link-logo-size);height:var(--token-side-nav-header-home-link-logo-size);transition:width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing),height var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav--is-minimized .hds-side-nav-header__logo-container{width:var(--token-side-nav-header-home-link-logo-size-minimized);height:var(--token-side-nav-header-home-link-logo-size-minimized)}.hds-side-nav__home-link{color:var(--token-side-nav-color-foreground-strong);background-color:transparent;border:1px solid transparent;border-radius:var(--token-side-nav-body-list-item-border-radius);cursor:pointer;display:block;width:100%;height:100%;padding:calc(var(--token-side-nav-header-home-link-padding) - 1px)}.hds-side-nav__home-link.mock-focus,.hds-side-nav__home-link:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__home-link.mock-focus::before,.hds-side-nav__home-link:focus::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-side-nav__home-link.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__home-link:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__home-link.mock-focus:focus-visible::before,.hds-side-nav__home-link:focus:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__home-link.mock-focus.mock-focus.mock-active::before,.hds-side-nav__home-link.mock-focus:focus:active::before,.hds-side-nav__home-link:focus.mock-focus.mock-active::before,.hds-side-nav__home-link:focus:focus:active::before{box-shadow:none}.hds-side-nav__home-link.mock-hover,.hds-side-nav__home-link:hover{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__home-link.mock-active,.hds-side-nav__home-link:active{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav-header__actions-container{display:flex;gap:var(--token-side-nav-header-actions-spacing)}.hds-side-nav__dropdown .hds-dropdown-toggle-button,.hds-side-nav__dropdown .hds-dropdown-toggle-icon{color:var(--token-side-nav-color-foreground-strong);background-color:transparent;border:1px solid transparent;border-radius:var(--token-side-nav-body-list-item-border-radius);cursor:pointer;border-color:var(--token-color-palette-neutral-500)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus.mock-focus::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus:not(:focus-visible)::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus-visible::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus-visible::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus-visible::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-focus:focus:active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-button:focus:focus:active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-focus:focus:active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus.mock-focus.mock-active::before,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:focus:focus:active::before{box-shadow:none}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-hover,.hds-side-nav__dropdown .hds-dropdown-toggle-button:hover,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-hover,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:hover{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__dropdown .hds-dropdown-toggle-button.mock-active,.hds-side-nav__dropdown .hds-dropdown-toggle-button:active,.hds-side-nav__dropdown .hds-dropdown-toggle-icon.mock-active,.hds-side-nav__dropdown .hds-dropdown-toggle-icon:active{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-active);border-color:var(--token-color-palette-neutral-400)}.hds-side-nav__icon-button{color:var(--token-side-nav-color-foreground-strong);background-color:transparent;border:1px solid transparent;border-radius:var(--token-side-nav-body-list-item-border-radius);cursor:pointer;border-color:var(--token-color-palette-neutral-500);display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:5px}.hds-side-nav__icon-button.mock-focus,.hds-side-nav__icon-button:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__icon-button.mock-focus::before,.hds-side-nav__icon-button:focus::before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:-1;border-radius:5px;content:""}.hds-side-nav__icon-button.mock-focus.mock-focus::before,.hds-side-nav__icon-button.mock-focus:focus::before,.hds-side-nav__icon-button:focus.mock-focus::before,.hds-side-nav__icon-button:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__icon-button.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__icon-button:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__icon-button.mock-focus:focus-visible::before,.hds-side-nav__icon-button:focus:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__icon-button.mock-focus.mock-focus.mock-active::before,.hds-side-nav__icon-button.mock-focus:focus:active::before,.hds-side-nav__icon-button:focus.mock-focus.mock-active::before,.hds-side-nav__icon-button:focus:focus:active::before{box-shadow:none}.hds-side-nav__icon-button.mock-hover,.hds-side-nav__icon-button:hover{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__icon-button.mock-active,.hds-side-nav__icon-button:active{color:var(--token-side-nav-color-foreground-strong);background:var(--token-side-nav-color-surface-interactive-active);border-color:var(--token-color-palette-neutral-400)}.hds-side-nav__content{margin:0 calc(var(--token-side-nav-wrapper-padding-horizontal) * -1)}.hds-side-nav__content-panels{display:grid;grid-template-columns:repeat(5,var(--hds-app-sidenav-width-expanded));width:100%}.hds-side-nav__content-panel{padding:0 var(--token-side-nav-wrapper-padding-horizontal)}.hds-side-nav__list-title{display:flex;align-items:center;min-height:var(--token-side-nav-body-list-item-height);margin-top:var(--token-side-nav-body-list-margin-vertical);padding:9px var(--token-side-nav-body-list-item-padding-horizontal);color:var(--token-side-nav-color-foreground-faint)}.hds-side-nav__list-wrapper:first-child .hds-side-nav__list-item:first-child>.hds-side-nav__list-title{margin-top:0}.hds-side-nav__list,.hds-side-nav__list-wrapper{margin:0;padding:0}.hds-side-nav__list-item{list-style-type:none}.hds-side-nav__list-item+.hds-side-nav__list-item{margin-top:var(--token-side-nav-body-list-item-spacing-vertical)}.hds-side-nav__list-item-link{display:flex;gap:var(--token-side-nav-body-list-item-content-spacing-horizontal);align-items:center;width:100%;min-height:var(--token-side-nav-body-list-item-height);padding:var(--token-side-nav-body-list-item-padding-vertical) var(--token-side-nav-body-list-item-padding-horizontal);color:var(--token-side-nav-color-foreground-primary);background:var(--token-side-nav-color-surface-primary);border-color:transparent;border-radius:var(--token-side-nav-body-list-item-border-radius)}.hds-side-nav__list-item-link.active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link.active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link.active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link.mock-active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link.mock-active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link.mock-active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link.mock-hover .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link.mock-hover .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link.mock-hover .hds-side-nav__list-item-text,.hds-side-nav__list-item-link:active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link:active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link:active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link:hover .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link:hover .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link:hover .hds-side-nav__list-item-text,.hds-side-nav__list-item-link:hover:focus .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link:hover:focus .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link:hover:focus .hds-side-nav__list-item-text{color:var(--token-side-nav-color-foreground-strong)}.hds-side-nav__list-item-link.mock-focus,.hds-side-nav__list-item-link:focus{position:relative;outline-style:solid;outline-color:transparent;isolation:isolate}.hds-side-nav__list-item-link.mock-focus::before,.hds-side-nav__list-item-link:focus::before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:5px;content:""}.hds-side-nav__list-item-link.mock-focus.mock-focus::before,.hds-side-nav__list-item-link.mock-focus:focus::before,.hds-side-nav__list-item-link:focus.mock-focus::before,.hds-side-nav__list-item-link:focus:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__list-item-link.mock-focus:focus:not(:focus-visible)::before,.hds-side-nav__list-item-link:focus:focus:not(:focus-visible)::before{box-shadow:none}.hds-side-nav__list-item-link.mock-focus:focus-visible::before,.hds-side-nav__list-item-link:focus:focus-visible::before,.hds-table__th-sort button.mock-focus::before,.hds-table__th-sort button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-side-nav__list-item-link.mock-focus.mock-focus.mock-active::before,.hds-side-nav__list-item-link.mock-focus:focus:active::before,.hds-side-nav__list-item-link:focus.mock-focus.mock-active::before,.hds-side-nav__list-item-link:focus:focus:active::before{box-shadow:none}.hds-side-nav__list-item-link.mock-hover,.hds-side-nav__list-item-link:hover{background:var(--token-side-nav-color-surface-interactive-hover);border-color:transparent}.hds-side-nav__list-item-link.active,.hds-side-nav__list-item-link.mock-active,.hds-side-nav__list-item-link:active,.hds-side-nav__list-item-link:hover:focus{background:var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__list-item-link.active .hds-badge,.hds-side-nav__list-item-link.active .hds-badge-count,.hds-side-nav__list-item-link.mock-active .hds-badge,.hds-side-nav__list-item-link.mock-active .hds-badge-count,.hds-side-nav__list-item-link:active .hds-badge,.hds-side-nav__list-item-link:active .hds-badge-count,.hds-side-nav__list-item-link:hover:focus .hds-badge,.hds-side-nav__list-item-link:hover:focus .hds-badge-count{color:var(--token-color-foreground-primary);background:var(--token-color-surface-strong)}.hds-side-nav__list-item-link--back-link.mock-active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link--back-link.mock-active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link--back-link.mock-active .hds-side-nav__list-item-text,.hds-side-nav__list-item-link--back-link:active .hds-side-nav__list-item-icon-leading,.hds-side-nav__list-item-link--back-link:active .hds-side-nav__list-item-icon-trailing,.hds-side-nav__list-item-link--back-link:active .hds-side-nav__list-item-text,.hds-side-nav__list-item-text{color:var(--token-side-nav-color-foreground-primary)}.hds-side-nav__list-item-link--back-link.mock-active,.hds-side-nav__list-item-link--back-link:active{background:var(--token-side-nav-color-surface-primary)}.hds-side-nav__list-item-text{text-align:left}.hds-side-nav__list-item-icon-leading{flex:none}.hds-side-nav__list-item-icon-trailing{flex:none;margin-left:auto}.hds-side-nav__toggle-button{position:absolute;top:22px;left:calc(var(--token-side-nav-wrapper-border-width) * -1);z-index:1;display:flex;flex-direction:row-reverse;align-items:center;width:26px;height:36px;padding:0 4px;color:var(--token-color-foreground-high-contrast);background:0 0;background-color:var(--token-side-nav-color-surface-primary);border:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);border-left-color:transparent;border-top-right-radius:var(--token-side-nav-toggle-button-border-radius);border-bottom-right-radius:var(--token-side-nav-toggle-button-border-radius);transform:translateX(var(--hds-app-sidenav-width-expanded));cursor:pointer;transition:transform var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing),width var(--hds-app-sidenav-animation-duration) var(--hds-app-sidenav-animation-easing)}.hds-side-nav__toggle-button::after,.hds-side-nav__toggle-button::before{position:absolute;left:calc(var(--token-side-nav-wrapper-border-width) * -1);width:calc(var(--token-side-nav-toggle-button-border-radius) * 2);height:calc(var(--token-side-nav-toggle-button-border-radius) * 2);border-left:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);box-sizing:border-box;content:""}.hds-side-nav__toggle-button::before{top:calc(var(--token-side-nav-toggle-button-border-radius) * -2);border-bottom:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);border-bottom-left-radius:var(--token-side-nav-toggle-button-border-radius);box-shadow:0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-primary)}.hds-side-nav__toggle-button::after{bottom:calc(var(--token-side-nav-toggle-button-border-radius) * -2);border-top:var(--token-side-nav-wrapper-border-width) solid var(--token-side-nav-wrapper-border-color);border-top-left-radius:var(--token-side-nav-toggle-button-border-radius);box-shadow:0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-primary)}.hds-side-nav__toggle-button.mock-hover,.hds-side-nav__toggle-button:hover{width:30px;background-color:var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__toggle-button.mock-hover::before,.hds-side-nav__toggle-button:hover::before{box-shadow:0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__toggle-button.mock-hover::after,.hds-side-nav__toggle-button:hover::after{box-shadow:0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-interactive-hover)}.hds-side-nav__toggle-button.mock-active,.hds-side-nav__toggle-button:active{background-color:var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__toggle-button.mock-active::before,.hds-side-nav__toggle-button:active::before{box-shadow:0 var(--token-side-nav-toggle-button-border-radius) 0 var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__toggle-button.mock-active::after,.hds-side-nav__toggle-button:active::after{box-shadow:0 calc(var(--token-side-nav-toggle-button-border-radius) * -1) 0 var(--token-side-nav-color-surface-interactive-active)}.hds-side-nav__toggle-button.mock-focus,.hds-side-nav__toggle-button:focus-visible{border-color:var(--token-color-focus-action-internal);outline:var(--token-color-focus-action-external) solid 3px}.hds-table__th-sort button,.hds-tabs__tab-button,.hds-tooltip-button{outline-color:transparent;outline-style:solid}.hds-side-nav--is-minimized .hds-side-nav__toggle-button{transform:translateX(var(--hds-app-sidenav-width-minimized))}.hds-side-nav .ember-a11y-refocus-skip-link{top:10px;left:10px;z-index:20;width:-moz-max-content;width:max-content;padding:2px 10px 4px;color:var(--token-color-foreground-action);font-family:var(--token-typography-display-200-font-family);background-color:var(--token-color-surface-faint);border-radius:3px;transform:translateY(-200%);transition:.6s ease-in-out}.hds-side-nav .ember-a11y-refocus-skip-link:focus{transform:translateY(0)}.hds-stepper-indicator-step{position:relative;width:24px;height:24px}.hds-stepper-indicator-step__svg-hexagon{width:100%;height:100%;filter:drop-shadow(0 1px 1px rgba(101, 106, 118, .05))}.hds-stepper-indicator-step__status{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center}.hds-stepper-indicator-step__icon{width:12px;height:12px}.hds-stepper-indicator-step__text{width:20px;overflow:hidden;white-space:nowrap;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__status{color:var(--token-color-foreground-strong)}.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__status{color:var(--token-color-foreground-high-contrast)}.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-faint);stroke:var(--token-color-foreground-strong)}.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-foreground-strong);stroke:var(--token-color-foreground-strong)}.hds-stepper-indicator-step--is-interactive{cursor:pointer}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__status{color:var(--token-color-foreground-primary)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__status{color:var(--token-color-foreground-high-contrast)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-interactive);stroke:var(--token-color-border-strong)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-interactive-hover)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-incomplete:active .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-surface-interactive-active)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-200);stroke:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-300);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-progress:active .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-400);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-200);stroke:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-300);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-processing:active .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-400);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__status{color:var(--token-color-palette-blue-200)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-50);stroke:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-hover .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:active .hds-stepper-indicator-step__svg-hexagon path,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:hover .hds-stepper-indicator-step__svg-hexagon path{fill:var(--token-color-palette-blue-100);stroke:var(--token-color-palette-blue-400)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-hover .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:hover .hds-stepper-indicator-step__status{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete.mock-active .hds-stepper-indicator-step__status,.hds-stepper-indicator-step--is-interactive.hds-stepper-indicator-step--status-complete:active .hds-stepper-indicator-step__status{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task{position:relative;display:flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--token-color-foreground-strong)}.hds-stepper-indicator-task__icon{width:12px;height:12px}.hds-stepper-indicator-task--is-interactive{cursor:pointer}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete{color:var(--token-color-palette-neutral-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete:hover{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-incomplete:active{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress{color:var(--token-color-palette-blue-200)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress:hover{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-progress:active{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing{color:var(--token-color-palette-blue-200)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing:hover{color:var(--token-color-palette-blue-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-processing:active{color:var(--token-color-palette-blue-400)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete{color:var(--token-color-palette-green-200)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete.mock-hover,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete:hover{color:var(--token-color-palette-green-300)}.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete.mock-active,.hds-stepper-indicator-task--is-interactive.hds-stepper-indicator-task--status-complete:active{color:var(--token-color-palette-green-400)}.hds-table{width:100%;border:1px solid var(--token-color-border-primary);border-radius:6px}.hds-table--layout-fixed{table-layout:fixed}.hds-table__thead .hds-table__tr{color:var(--token-color-foreground-strong);background-color:var(--token-color-surface-strong)}.hds-table__thead .hds-table__tr:first-of-type th:first-child{border-top-left-radius:5px}.hds-table__thead .hds-table__tr:first-of-type th:last-child{border-top-right-radius:5px}.hds-table__thead .hds-table__th,.hds-table__thead .hds-table__th-sort{min-height:48px}.hds-table__th,.hds-table__th-sort{text-align:left;border-top:none;border-right:none;border-bottom:1px solid var(--token-color-border-primary);border-left:none}.hds-table__th{padding:14px 16px 13px}.hds-table__th-sort{padding:0}.hds-table__th-sort button{width:100%;height:100%;min-height:48px;margin:0;padding:14px 16px 13px;text-align:inherit;background-color:transparent;border:1px solid transparent;border-radius:inherit;position:relative;isolation:isolate}.hds-table__th-sort button .hds-table__th-sort--button-content{display:flex;align-items:center}.hds-table__th-sort button .hds-table__th-sort--button-content .flight-icon{flex:none;margin-left:8px;color:var(--token-color-foreground-action)}.hds-table__th-sort button.mock-hover,.hds-table__th-sort button:hover{color:var(--token-color-foreground-strong);background-color:var(--token-color-palette-neutral-200);cursor:pointer}.hds-table__th-sort button::before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:inherit;content:""}.hds-table__th-sort button:focus:not(:focus-visible)::before{box-shadow:none}.hds-table__th-sort button:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-table__th-sort button.mock-focus.mock-active::before,.hds-table__th-sort button:focus:active::before{box-shadow:none}.hds-table__th-sort button.mock-active,.hds-table__th-sort button:active{color:var(--token-color-foreground-strong);background-color:var(--token-color-palette-neutral-300)}.hds-table__tbody .hds-table__tr,.hds-tabs__tab,.hds-tag__dismiss-icon{color:var(--token-color-foreground-primary)}.hds-table--striped .hds-table__tbody .hds-table__tr:nth-child(even){background-color:var(--token-color-surface-faint)}.hds-table--density-short .hds-table__tbody td,.hds-table--density-short .hds-table__tbody th{padding:6px 16px 5px}.hds-table--density-medium .hds-table__tbody td,.hds-table--density-medium .hds-table__tbody th{padding:14px 16px 13px}.hds-table--density-tall .hds-table__tbody td,.hds-table--density-tall .hds-table__tbody th{padding:22px 16px 21px}.hds-table--valign-top .hds-table__tbody td,.hds-table--valign-top .hds-table__tbody th{vertical-align:top}.hds-table--valign-middle .hds-table__tbody td,.hds-table--valign-middle .hds-table__tbody th,.hds-tag{vertical-align:middle}.hds-table__td--text-right,.hds-table__th--text-right,.hds-table__th-sort--text-right{text-align:right}.hds-table__th-sort--text-right .hds-table__th-sort--button-content{justify-content:flex-end}.hds-table__td--text-center,.hds-table__th--text-center,.hds-table__th-sort--text-center{text-align:center}.hds-table__tbody .hds-table__tr{background-color:var(--token-color-surface-primary)}.hds-table__tbody .hds-table__tr td,.hds-table__tbody .hds-table__tr th{border-top:none;border-right:none;border-bottom:1px solid var(--token-color-border-primary);border-left:none}.hds-table__tbody .hds-table__tr:last-of-type td,.hds-table__tbody .hds-table__tr:last-of-type th{border-bottom:none}.hds-table__tbody .hds-table__tr:last-of-type td:first-child,.hds-table__tbody .hds-table__tr:last-of-type th:first-child{border-bottom-left-radius:5px}.hds-table__tbody .hds-table__tr:last-of-type td:last-child{border-bottom-right-radius:5px}.hds-tabs__tablist-wrapper{position:relative}.hds-tabs__tablist-wrapper::before{position:absolute;right:0;bottom:calc((var(--token-tabs-indicator-height) - var(--token-tabs-divider-height))/ 2);left:0;display:block;border-top:var(--token-tabs-divider-height) solid var(--token-color-border-primary);content:""}.hds-tabs__tablist{position:relative;display:flex;margin:0;padding:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.hds-tabs__tab{position:relative;display:flex;align-items:center;height:var(--token-tabs-tab-height);margin:0;padding:var(--token-tabs-tab-padding-vertical) var(--token-tabs-tab-padding-horizontal);white-space:nowrap;list-style:none}.hds-tabs__tab.hds-tabs__tab--is-selected,.hds-tabs__tab.mock-hover,.hds-tabs__tab:hover{color:var(--token-color-foreground-action)}.hds-tabs__tab.hds-tabs__tab--is-selected:hover{color:var(--token-color-foreground-action-hover)}.hds-tabs__tab.hds-tabs__tab--is-selected:hover~.hds-tabs__tab-indicator{background:var(--token-color-foreground-action-hover)}.hds-tabs__tab-button{isolation:isolate;position:static;display:flex;gap:var(--token-tabs-tab-gutter);align-items:center;padding:0;color:inherit;background-color:transparent;border:none;border-radius:var(--token-tabs-tab-border-radius);cursor:pointer}.hds-tabs__tab-button::before{position:absolute;top:var(--token-tabs-tab-focus-inset);right:var(--token-tabs-tab-focus-inset);bottom:var(--token-tabs-tab-focus-inset);left:var(--token-tabs-tab-focus-inset);z-index:-1;border-radius:5px;content:""}.hds-tabs__tab-button.mock-focus::before,.hds-tabs__tab-button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tabs__tab-button:focus:not(:focus-visible)::before{box-shadow:none}.hds-tabs__tab-button:focus-visible::before,.hds-tag__dismiss.mock-focus.mock-focus,.hds-tag__dismiss.mock-focus:focus,.hds-tag__dismiss:focus.mock-focus,.hds-tag__dismiss:focus:focus,.hds-tag__link.mock-focus.mock-focus,.hds-tag__link.mock-focus:focus,.hds-tag__link:focus.mock-focus,.hds-tag__link:focus:focus{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tabs__tab-button.mock-focus.mock-active::before,.hds-tabs__tab-button:focus:active::before{box-shadow:none}.hds-tabs__tab-button::after{position:absolute;content:"";inset:0}.hds-tabs__tab-indicator{position:absolute;right:0;bottom:0;left:var(--indicator-left-pos);z-index:10;display:block;width:var(--indicator-width);height:var(--token-tabs-indicator-height);background-color:var(--token-color-foreground-action);border-radius:var(--token-tabs-indicator-height)}.hds-tabs__panel[hidden],.readonly-codemirror .CodeMirror-cursors{display:none}.hds-tag,.hds-tag__dismiss,.hds-tag__link{background-color:var(--token-color-surface-interactive)}@media screen and (prefers-reduced-motion:no-preference){.hds-tabs__tab-indicator{transition-timing-function:var(--token-tabs-indicator-transition-function);transition-duration:var(--token-tabs-indicator-transition-duration);transition-property:left,width}}.tippy-box,.tippy-box[data-theme~=hds]{transition-property:transform,visibility,opacity}.hds-tag,:where(.hds-tooltip-button--is-inline){display:inline-flex}.hds-tag{align-items:stretch;line-height:1rem;border:1px solid var(--token-color-border-strong);border-radius:50px}.hds-tag__dismiss{flex:0 0 auto;margin:0;padding:6px 4px 6px 8px;border:none;border-radius:inherit;border-top-right-radius:0;border-bottom-right-radius:0}.hds-tag__dismiss-icon{width:12px;height:12px}.hds-tag__link,.hds-tag__text{flex:1 0 0;padding:3px 10px 5px;border-radius:inherit}.hds-tag__dismiss~.hds-tag__link,.hds-tag__dismiss~.hds-tag__text{padding:3px 8px 5px 6px;border-top-left-radius:0;border-bottom-left-radius:0}.hds-tag__dismiss,.hds-tag__link{cursor:pointer}.hds-tag__dismiss.mock-hover,.hds-tag__dismiss:hover,.hds-tag__link.mock-hover,.hds-tag__link:hover{background-color:var(--token-color-surface-interactive-hover)}.hds-tag__dismiss.mock-active,.hds-tag__dismiss:active,.hds-tag__link.mock-active,.hds-tag__link:active{background-color:var(--token-color-surface-interactive-active)}.hds-tag__dismiss.mock-focus,.hds-tag__dismiss:focus,.hds-tag__link.mock-focus,.hds-tag__link:focus{outline-style:solid;outline-color:transparent;z-index:1}.hds-tag__dismiss.mock-focus:focus:not(:focus-visible),.hds-tag__dismiss:focus:focus:not(:focus-visible),.hds-tag__link.mock-focus:focus:not(:focus-visible),.hds-tag__link:focus:focus:not(:focus-visible){box-shadow:none}.hds-tag__dismiss.mock-focus:focus-visible,.hds-tag__dismiss:focus:focus-visible,.hds-tag__link.mock-focus:focus-visible,.hds-tag__link:focus:focus-visible{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tag__dismiss.mock-focus.mock-focus.mock-active,.hds-tag__dismiss.mock-focus:focus:active,.hds-tag__dismiss:focus.mock-focus.mock-active,.hds-tag__dismiss:focus:focus:active,.hds-tag__link.mock-focus.mock-focus.mock-active,.hds-tag__link.mock-focus:focus:active,.hds-tag__link:focus.mock-focus.mock-active,.hds-tag__link:focus:focus:active{box-shadow:none}.hds-tag--color-primary .hds-tag__link{color:var(--token-color-foreground-action)}.hds-tag--color-primary .hds-tag__link.mock-hover,.hds-tag--color-primary .hds-tag__link:hover{color:var(--token-color-foreground-action-hover)}.hds-tag--color-primary .hds-tag__link.mock-active,.hds-tag--color-primary .hds-tag__link:active{color:var(--token-color-foreground-action-active)}.hds-tag--color-secondary .hds-tag__link{color:var(--token-color-foreground-strong)}.hds-text--align-left{text-align:left}.hds-text--align-center{text-align:center}.hds-text--align-right{text-align:right}.hds-toast{width:-moz-fit-content;width:fit-content;min-width:min(360px,80vw);max-width:min(500px,80vw);box-shadow:var(--token-elevation-higher-box-shadow)}.hds-tooltip-button{position:relative;isolation:isolate}.hds-tooltip-button::before{position:absolute;top:var(--token-tooltip-focus-offset);right:var(--token-tooltip-focus-offset);bottom:var(--token-tooltip-focus-offset);left:var(--token-tooltip-focus-offset);z-index:-1;border-radius:5px;content:""}.hds-tooltip-button.mock-focus::before,.hds-tooltip-button:focus::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tooltip-button:focus:not(:focus-visible)::before{box-shadow:none}.hds-tooltip-button:focus-visible::before{box-shadow:var(--token-focus-ring-action-box-shadow)}.hds-tooltip-button.mock-focus.mock-active::before,.hds-tooltip-button:focus:active::before{box-shadow:none}:where(.hds-tooltip-button){margin:0;padding:0;color:inherit;font:inherit;text-align:inherit;background-color:inherit;border:none}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.menu-panel>ul>[role=treeitem],.menu-panel>ul>li,.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.modal-dialog [role=document] table caption,.modal-dialog [role=document] table thead th,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],main table caption,main table thead th,table td,table th,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],td,th{text-align:left}:where(.hds-tooltip-button--is-block){display:flex}article,aside,figure,footer,header,hgroup,hr,section{display:block}.tippy-box[data-theme~=hds]{padding:var(--token-tooltip-padding-vertical) var(--token-tooltip-padding-horizontal);color:var(--token-tooltip-color-foreground-primary);font-weight:var(--token-typography-font-weight-regular);font-size:var(--token-typography-body-200-font-size);font-family:var(--token-typography-body-200-font-family);line-height:var(--token-typography-body-200-line-height);overflow-wrap:break-word;background-color:var(--token-tooltip-color-surface-primary);border-radius:var(--token-tooltip-border-radius);box-shadow:var(--token-elevation-higher-box-shadow)}.tippy-box[data-theme~=hds][data-animation=fade][data-state=hidden]{opacity:0}.tippy-box[data-theme~=hds][data-inertia][data-state=visible]{transition-timing-function:var(--token-tooltip-transition-function)}.tippy-box[data-theme~=hds] .tippy-content{position:relative;z-index:1;max-width:var(--token-tooltip-max-width);white-space:normal}.tippy-box[data-theme~=hds] .tippy-svg-arrow{fill:var(--token-tooltip-color-surface-primary)}.sr-only{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;overflow:hidden!important;white-space:nowrap!important;border:0!important;clip:rect(1px,1px,1px,1px)!important;-webkit-clip-path:inset(50%)!important;clip-path:inset(50%)!important}fieldset,hr{border:none}blockquote,body,dd,dl,dt,fieldset,figure,hr,html,iframe,legend,li,ol,p,textarea,ul{margin:0;padding:0}ul{list-style:none}table td,table th{padding:0}audio,embed,img,object,video{height:auto;max-width:100%}.consul-intention-action-warn-modal button.dangerous,.copy-button button,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-select label>*,.topology-notices button,.type-sort.popover-select label>*,label span,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}a{color:var(--token-color-foreground-action)}span,strong,td,th{color:inherit}body{color:var(--token-color-foreground-strong)}html{background-color:var(--token-color-surface-primary);font-size:16px;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;overflow-x:hidden;overflow-y:scroll;box-sizing:border-box;min-width:300px}hr{background-color:var(--token-color-surface-interactive-active);height:1px;margin:1.5rem 0}body,input,select,textarea{font-family:var(--token-typography-font-stack-text)}strong{font-style:inherit}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}pre{-webkit-overflow-scrolling:touch;overflow-x:auto;white-space:pre;word-wrap:normal}*,::after,::before{box-sizing:inherit;animation-play-state:paused;animation-fill-mode:forwards}fieldset{width:100%}a,input[type=checkbox],input[type=radio]{cursor:pointer}td,th{vertical-align:top}button,input,select,textarea{margin:0}iframe{border:0}.consul-bucket-list .service,.consul-bucket-list:not([class]) dt:not([class]),.consul-exposed-path-list>ul>li>.detail dl:not([class]) dt:not([class]),.consul-instance-checks:not([class]) dt:not([class]),.consul-lock-session-list dl:not([class]) dt:not([class]),.consul-server-card dt:not(.name),.consul-upstream-instance-list dl.local-bind-address dt,.consul-upstream-instance-list dl.local-bind-socket-path dt,.consul-upstream-instance-list dl:not([class]) dt:not([class]),.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dt:not([class]),.route-title,.tag-list:not([class]) dt:not([class]),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dt:not([class]),section[data-route="dc.show.license"] .validity dl .expired+dd,section[data-route="dc.show.license"] .validity dl:not([class]) dt:not([class]),td.tags:not([class]) dt:not([class]){position:absolute;overflow:hidden;clip:rect(0 0 0 0);width:1px;height:1px;margin:-1px;padding:0;border:0}.consul-upstream-instance-list dl.local-bind-socket-mode dt,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dt{position:static!important;clip:unset!important;overflow:visible!important;width:auto!important;height:auto!important;margin:0!important;padding:0!important}.animatable.tab-nav ul::after,.consul-auth-method-type,.consul-external-source,.consul-intention-action-warn-modal button.dangerous,.consul-intention-action-warn-modal button.dangerous:hover:active,.consul-intention-action-warn-modal button.dangerous:hover:not(:disabled):not(:active),.consul-intention-list td.intent- strong,.consul-intention-permission-form button.type-submit,.consul-intention-permission-form button.type-submit:disabled,.consul-intention-permission-form button.type-submit:focus:not(:disabled),.consul-intention-permission-form button.type-submit:hover:not(:disabled),.consul-intention-search-bar .value- span,.consul-kind,.consul-source,.consul-transparent-proxy,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:first-child,.discovery-chain .route-card>header ul li,.informed-action>ul>.dangerous>*,.informed-action>ul>.dangerous>:focus,.informed-action>ul>.dangerous>:hover,.leader,.menu-panel>ul>li.dangerous>:first-child,.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.tab-nav .selected>*,.topology-metrics-source-type,html[data-route^="dc.acls.index"] main td strong,span.policy-node-identity,span.policy-service-identity,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child{border-style:solid}.ember-power-select-trigger,.ember-power-select-trigger--active,.ember-power-select-trigger:focus{border-top:1px solid #aaa;border-bottom:1px solid #aaa;border-right:1px solid #aaa;border-left:1px solid #aaa}.animatable.tab-nav ul::after,.app .notifications .app-notification,.tab-nav li>*{transition-duration:.15s;transition-timing-function:ease-out}html body>.brand-loader{transition-timing-function:cubic-bezier(.1,.1,.25,.9);transition-duration:.1s}html[data-state]:not(.ember-loading) body>.brand-loader{animation-timing-function:cubic-bezier(.1,.1,.25,.9);animation-duration:.1s;animation-name:remove-from-flow;animation-fill-mode:forwards}@keyframes remove-from-flow{100%{visibility:hidden;overflow:hidden;clip:rect(0 0 0 0)}}@keyframes typo-truncate{100%{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.CodeMirror-lint-tooltip,dd code,dd pre code{font-family:var(--token-typography-font-stack-code);font-size:var(--token-typography-code-100-font-size);line-height:var(--token-typography-code-100-line-height);font-weight:var(--token-typography-font-weight-regular)}.consul-health-check-list .health-check-output pre code,code,pre,pre code{font-family:var(--token-typography-font-stack-code);font-size:var(--token-typography-code-200-font-size);line-height:var(--token-typography-code-200-line-height);font-weight:var(--token-typography-font-weight-regular)}.informed-action header>*{font-size:inherit;font-weight:inherit;line-height:inherit;font-style:inherit}::after,::before{--tw-content:'';display:inline-block;vertical-align:text-top;background-repeat:no-repeat;background-position:center;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat;mask-position:center;-webkit-mask-position:center}::before{animation-name:var(--icon-name-start,var(--icon-name)),var(--icon-size-start,var(--icon-size,icon-000));background-color:var(--icon-color-start,var(--icon-color))}::after{animation-name:var(--icon-name-end,var(--icon-name)),var(--icon-size-end,var(--icon-size,icon-000));background-color:var(--icon-color-end,var(--icon-color))}[style*="--icon-color-start"]::before{color:var(--icon-color-start)}[style*="--icon-color-end"]::after{color:var(--icon-color-end)}[style*="--icon-name-start"]::before,[style*="--icon-name-end"]::after{content:""}@keyframes icon-000{100%{width:1.2em;height:1.2em}}@keyframes icon-100{100%{width:.625rem;height:.625rem}}@keyframes icon-200{100%{width:.75rem;height:.75rem}}@keyframes icon-300{100%{width:1rem;height:1rem}}@keyframes icon-400{100%{width:1.125rem;height:1.125rem}}@keyframes icon-500{100%{width:1.25rem;height:1.25rem}}@keyframes icon-600{100%{width:1.375rem;height:1.375rem}}@keyframes icon-700{100%{width:1.5rem;height:1.5rem}}@keyframes icon-800{100%{width:1.625rem;height:1.625rem}}@keyframes icon-900{100%{width:1.75rem;height:1.75rem}}@keyframes icon-999{100%{width:100%;height:100%}}.consul-intention-permission-header-list dt::before,.consul-intention-permission-list dt::before,.discovery-chain .resolver-card dt,.discovery-chain .route-card section header>::before{font-weight:var(--token-typography-font-weight-regular);background-color:var(--token-color-surface-strong);visibility:visible;padding:0 4px}#downstream-container .topology-metrics-card .details .group span::before,#downstream-container .topology-metrics-card div .critical::before,#downstream-container .topology-metrics-card div .empty::before,#downstream-container .topology-metrics-card div .health dt::before,#downstream-container .topology-metrics-card div .nspace dt::before,#downstream-container .topology-metrics-card div .partition dt::before,#downstream-container .topology-metrics-card div .passing::before,#downstream-container .topology-metrics-card div .warning::before,#downstream-container>div:first-child span::before,#login-toggle+div footer button::after,#metrics-container .link .config-link::before,#metrics-container .link .metrics-link::before,#metrics-container:hover .sparkline-key-link::before,#upstream-container .topology-metrics-card .details .group span::before,#upstream-container .topology-metrics-card div .critical::before,#upstream-container .topology-metrics-card div .empty::before,#upstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .partition dt::before,#upstream-container .topology-metrics-card div .passing::before,#upstream-container .topology-metrics-card div .warning::before,.animatable.tab-nav ul::after,.consul-auth-method-binding-list dl dt.type+dd span::before,.consul-auth-method-list ul .locality::before,.consul-auth-method-view dl dt.type+dd span::before,.consul-auth-method-view section dl dt.type+dd span::before,.consul-bucket-list .nspace::before,.consul-bucket-list .partition::before,.consul-bucket-list .peer::before,.consul-exposed-path-list>ul>li>.detail .policy-management::before,.consul-exposed-path-list>ul>li>.detail .policy::before,.consul-exposed-path-list>ul>li>.detail .role::before,.consul-exposed-path-list>ul>li>.detail dl.address dt::before,.consul-exposed-path-list>ul>li>.detail dl.behavior dt::before,.consul-exposed-path-list>ul>li>.detail dl.checks dt::before,.consul-exposed-path-list>ul>li>.detail dl.critical dt::before,.consul-exposed-path-list>ul>li>.detail dl.datacenter dt::before,.consul-exposed-path-list>ul>li>.detail dl.empty dt::before,.consul-exposed-path-list>ul>li>.detail dl.lock-delay dt::before,.consul-exposed-path-list>ul>li>.detail dl.mesh dt::before,.consul-exposed-path-list>ul>li>.detail dl.node dt::before,.consul-exposed-path-list>ul>li>.detail dl.nspace dt::before,.consul-exposed-path-list>ul>li>.detail dl.passing dt::before,.consul-exposed-path-list>ul>li>.detail dl.path dt::before,.consul-exposed-path-list>ul>li>.detail dl.port dt::before,.consul-exposed-path-list>ul>li>.detail dl.protocol dt::before,.consul-exposed-path-list>ul>li>.detail dl.socket dt::before,.consul-exposed-path-list>ul>li>.detail dl.ttl dt::before,.consul-exposed-path-list>ul>li>.detail dl.unknown dt::before,.consul-exposed-path-list>ul>li>.detail dl.warning dt::before,.consul-exposed-path-list>ul>li>.header .critical dd::before,.consul-exposed-path-list>ul>li>.header .empty dd::before,.consul-exposed-path-list>ul>li>.header .passing dd::before,.consul-exposed-path-list>ul>li>.header .policy-management dd::before,.consul-exposed-path-list>ul>li>.header .unknown dd::before,.consul-exposed-path-list>ul>li>.header .warning dd::before,.consul-exposed-path-list>ul>li>.header [rel=me] dd::before,.consul-external-source.jwt::before,.consul-external-source.oidc::before,.consul-health-check-list .health-check-output dd em.jwt::before,.consul-health-check-list .health-check-output dd em.oidc::before,.consul-health-check-list .health-check-output::before,.consul-instance-checks dt::before,.consul-intention-fieldsets .value->:last-child::before,.consul-intention-fieldsets .value-allow>:last-child::before,.consul-intention-fieldsets .value-deny>:last-child::before,.consul-intention-list em span::before,.consul-intention-list td strong.jwt::before,.consul-intention-list td strong.oidc::before,.consul-intention-list td.intent- strong::before,.consul-intention-list td.intent-allow strong::before,.consul-intention-list td.intent-deny strong::before,.consul-intention-permission-list .intent-allow::before,.consul-intention-permission-list .intent-deny::before,.consul-intention-permission-list strong.jwt::before,.consul-intention-permission-list strong.oidc::before,.consul-intention-search-bar .value- span::before,.consul-intention-search-bar .value-allow span::before,.consul-intention-search-bar .value-deny span::before,.consul-intention-search-bar li button span.jwt::before,.consul-intention-search-bar li button span.oidc::before,.consul-kind::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy-management::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .role::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.address dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.behavior dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.checks dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.datacenter dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.lock-delay dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.mesh dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.node dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.nspace dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.path dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.port dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.protocol dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.socket dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.ttl dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.unknown dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .critical dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .empty dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .passing dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .policy-management dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .unknown dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .warning dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header [rel=me] dd::before,.consul-peer-search-bar li button span.jwt::before,.consul-peer-search-bar li button span.oidc::before,.consul-server-card .health-status+dd.jwt::before,.consul-server-card .health-status+dd.oidc::before,.consul-upstream-instance-list dl.datacenter dt::before,.consul-upstream-instance-list dl.nspace dt::before,.consul-upstream-instance-list dl.partition dt::before,.consul-upstream-instance-list li>.detail .policy-management::before,.consul-upstream-instance-list li>.detail .policy::before,.consul-upstream-instance-list li>.detail .role::before,.consul-upstream-instance-list li>.detail dl.address dt::before,.consul-upstream-instance-list li>.detail dl.behavior dt::before,.consul-upstream-instance-list li>.detail dl.checks dt::before,.consul-upstream-instance-list li>.detail dl.critical dt::before,.consul-upstream-instance-list li>.detail dl.datacenter dt::before,.consul-upstream-instance-list li>.detail dl.empty dt::before,.consul-upstream-instance-list li>.detail dl.lock-delay dt::before,.consul-upstream-instance-list li>.detail dl.mesh dt::before,.consul-upstream-instance-list li>.detail dl.node dt::before,.consul-upstream-instance-list li>.detail dl.nspace dt::before,.consul-upstream-instance-list li>.detail dl.passing dt::before,.consul-upstream-instance-list li>.detail dl.path dt::before,.consul-upstream-instance-list li>.detail dl.port dt::before,.consul-upstream-instance-list li>.detail dl.protocol dt::before,.consul-upstream-instance-list li>.detail dl.socket dt::before,.consul-upstream-instance-list li>.detail dl.ttl dt::before,.consul-upstream-instance-list li>.detail dl.unknown dt::before,.consul-upstream-instance-list li>.detail dl.warning dt::before,.consul-upstream-instance-list li>.header .critical dd::before,.consul-upstream-instance-list li>.header .empty dd::before,.consul-upstream-instance-list li>.header .passing dd::before,.consul-upstream-instance-list li>.header .policy-management dd::before,.consul-upstream-instance-list li>.header .unknown dd::before,.consul-upstream-instance-list li>.header .warning dd::before,.consul-upstream-instance-list li>.header [rel=me] dd::before,.consul-upstream-list dl.partition dt::before,.copy-button button::before,.dangerous.informed-action header::before,.disclosure-menu [aria-expanded]~*>ul>li.is-active>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-checked]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-current]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-selected]>::after,.discovery-chain .resolvers>header span::after,.discovery-chain .route-card::before,.discovery-chain .route-card>header ul li.jwt::before,.discovery-chain .route-card>header ul li.oidc::before,.discovery-chain .routes>header span::after,.discovery-chain .splitter-card::before,.discovery-chain .splitters>header span::after,.empty-state li[class*=-link]>::after,.has-error>strong::before,.info.informed-action header::before,.jwt.consul-auth-method-type::before,.jwt.consul-external-source::before,.jwt.consul-kind::before,.jwt.consul-source::before,.jwt.consul-transparent-proxy::before,.jwt.leader::before,.jwt.topology-metrics-source-type::before,.leader::before,.list-collection>button::after,.list-collection>ul>li:not(:first-child)>.detail .policy-management::before,.list-collection>ul>li:not(:first-child)>.detail .policy::before,.list-collection>ul>li:not(:first-child)>.detail .role::before,.list-collection>ul>li:not(:first-child)>.detail dl.address dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.behavior dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.checks dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.critical dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.datacenter dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.empty dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.lock-delay dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.mesh dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.node dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.nspace dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.passing dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.path dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.port dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.protocol dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.socket dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.ttl dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.unknown dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.warning dt::before,.list-collection>ul>li:not(:first-child)>.header .critical dd::before,.list-collection>ul>li:not(:first-child)>.header .empty dd::before,.list-collection>ul>li:not(:first-child)>.header .passing dd::before,.list-collection>ul>li:not(:first-child)>.header .policy-management dd::before,.list-collection>ul>li:not(:first-child)>.header .unknown dd::before,.list-collection>ul>li:not(:first-child)>.header .warning dd::before,.list-collection>ul>li:not(:first-child)>.header [rel=me] dd::before,.menu-panel>ul>li.is-active>::after,.menu-panel>ul>li[aria-checked]>::after,.menu-panel>ul>li[aria-current]>::after,.menu-panel>ul>li[aria-selected]>::after,.modal-dialog [role=document] a[rel*=help]::after,.modal-dialog [role=document] table td.folder::before,.modal-dialog [role=document] table th span::after,.more-popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,.more-popover-menu>[type=checkbox]+label>::after,.oidc-select .auth0-oidc-provider::before,.oidc-select .google-oidc-provider::before,.oidc-select .microsoft-oidc-provider::before,.oidc-select .okta-oidc-provider::before,.oidc.consul-auth-method-type::before,.oidc.consul-external-source::before,.oidc.consul-kind::before,.oidc.consul-source::before,.oidc.consul-transparent-proxy::before,.oidc.leader::before,.oidc.topology-metrics-source-type::before,.popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,.popover-menu>[type=checkbox]+label>::after,.popover-select .jwt button::before,.popover-select .oidc button::before,.popover-select .value-critical button::before,.popover-select .value-empty button::before,.popover-select .value-passing button::before,.popover-select .value-unknown button::before,.popover-select .value-warning button::before,.search-bar-status li.jwt:not(.remove-all)::before,.search-bar-status li.oidc:not(.remove-all)::before,.search-bar-status li:not(.remove-all) button::before,.sparkline-key h3::before,.tag-list dt::before,.tooltip-panel dd>div::before,.topology-metrics-popover.deny .tippy-arrow::after,.topology-metrics-popover.deny>button::before,.topology-metrics-popover.l7 .tippy-arrow::after,.topology-metrics-popover.l7>button::before,.topology-metrics-popover.not-defined .tippy-arrow::after,.topology-metrics-popover.not-defined>button::before,.topology-metrics-status-error span::before,.topology-metrics-status-loader span::before,.topology-notices button::before,.type-sort.popover-select label>::before,.type-source.popover-select li.partition button::before,.warning.informed-action header::before,.warning.modal-dialog header::before,[class*=status-].empty-state header::before,a[rel*=external]::after,html[data-route^="dc.acls.index"] main td strong.jwt::before,html[data-route^="dc.acls.index"] main td strong.oidc::before,main a[rel*=help]::after,main header nav:first-child ol li:first-child a::before,main table td.folder::before,main table th span::after,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.jwt::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.oidc::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.jwt::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.oidc::before,span.jwt.policy-node-identity::before,span.jwt.policy-service-identity::before,span.oidc.policy-node-identity::before,span.oidc.policy-service-identity::before,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.has-actions tr>.actions>[type=checkbox]+label>::after,table.with-details td:only-child>div>label::before,table.with-details td>label::before,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.with-details tr>.actions>[type=checkbox]+label>::after,td.tags dt::before{content:""}@keyframes icon-alert-circle-outline{100%{-webkit-mask-image:var(--icon-alert-circle-16);mask-image:var(--icon-alert-circle-16);background-color:var(--icon-color,var(--color-alert-circle-outline-500,currentColor))}}[class*=status-].empty-state header::before{--icon-name:icon-alert-circle-outline;content:""}@keyframes icon-alert-triangle{100%{-webkit-mask-image:var(--icon-alert-triangle-16);mask-image:var(--icon-alert-triangle-16);background-color:var(--icon-color,var(--color-alert-triangle-500,currentColor))}}#downstream-container .topology-metrics-card div .warning::before,#upstream-container .topology-metrics-card div .warning::before,.consul-exposed-path-list>ul>li>.detail dl.warning dt::before,.consul-exposed-path-list>ul>li>.header .warning dd::before,.consul-health-check-list .warning.health-check-output::before,.consul-instance-checks.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .warning dd::before,.consul-upstream-instance-list li>.detail dl.warning dt::before,.consul-upstream-instance-list li>.header .warning dd::before,.dangerous.informed-action header::before,.list-collection>ul>li:not(:first-child)>.detail dl.warning dt::before,.list-collection>ul>li:not(:first-child)>.header .warning dd::before,.popover-select .value-warning button::before,.topology-metrics-popover.not-defined .tippy-arrow::after,.topology-metrics-popover.not-defined>button::before,.warning.informed-action header::before,.warning.modal-dialog header::before{--icon-name:icon-alert-triangle;content:""}@keyframes icon-arrow-left{100%{-webkit-mask-image:var(--icon-arrow-left-16);mask-image:var(--icon-arrow-left-16);background-color:var(--icon-color,var(--color-arrow-left-500,currentColor))}}@keyframes icon-arrow-right{100%{-webkit-mask-image:var(--icon-arrow-right-16);mask-image:var(--icon-arrow-right-16);background-color:var(--icon-color,var(--color-arrow-right-500,currentColor))}}@keyframes icon-cancel-plain{100%{-webkit-mask-image:var(--icon-x-16);mask-image:var(--icon-x-16);background-color:var(--icon-color,var(--color-cancel-plain-500,currentColor))}}.search-bar-status li:not(.remove-all) button::before{--icon-name:icon-cancel-plain;content:""}@keyframes icon-cancel-square-fill{100%{-webkit-mask-image:var(--icon-x-square-fill-16);mask-image:var(--icon-x-square-fill-16);background-color:var(--icon-color,var(--color-cancel-square-fill-500,currentColor))}}#downstream-container .topology-metrics-card div .critical::before,#upstream-container .topology-metrics-card div .critical::before,.consul-exposed-path-list>ul>li>.detail dl.critical dt::before,.consul-exposed-path-list>ul>li>.header .critical dd::before,.consul-health-check-list .critical.health-check-output::before,.consul-instance-checks.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .critical dd::before,.consul-upstream-instance-list li>.detail dl.critical dt::before,.consul-upstream-instance-list li>.header .critical dd::before,.has-error>strong::before,.list-collection>ul>li:not(:first-child)>.detail dl.critical dt::before,.list-collection>ul>li:not(:first-child)>.header .critical dd::before,.popover-select .value-critical button::before,.topology-metrics-popover.deny .tippy-arrow::after,.topology-metrics-popover.deny>button::before{--icon-name:icon-cancel-square-fill;content:""}@keyframes icon-check-plain{100%{-webkit-mask-image:var(--icon-check-16);mask-image:var(--icon-check-16);background-color:var(--icon-color,var(--color-check-plain-500,currentColor))}}.disclosure-menu [aria-expanded]~*>ul>li.is-active>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-checked]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-current]>::after,.disclosure-menu [aria-expanded]~*>ul>li[aria-selected]>::after,.menu-panel>ul>li.is-active>::after,.menu-panel>ul>li[aria-checked]>::after,.menu-panel>ul>li[aria-current]>::after,.menu-panel>ul>li[aria-selected]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.more-popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,.popover-menu>[type=checkbox]+label+div>ul>li.is-active>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-checked]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-current]>::after,.popover-menu>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.is-active>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-checked]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-current]>::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li[aria-selected]>::after{--icon-name:icon-check-plain;content:""}@keyframes icon-chevron-down{100%{-webkit-mask-image:var(--icon-chevron-down-16);mask-image:var(--icon-chevron-down-16);background-color:var(--icon-color,var(--color-chevron-down-500,currentColor))}}.list-collection>button.closed::after,.more-popover-menu>[type=checkbox]+label>::after,.popover-menu>[type=checkbox]+label>::after,.topology-notices button::before,table.has-actions tr>.actions>[type=checkbox]+label>::after,table.with-details td:only-child>div>label::before,table.with-details td>label::before,table.with-details tr>.actions>[type=checkbox]+label>::after{--icon-name:icon-chevron-down;content:""}@keyframes icon-copy-action{100%{-webkit-mask-image:var(--icon-clipboard-copy-16);mask-image:var(--icon-clipboard-copy-16);background-color:var(--icon-color,var(--color-copy-action-500,currentColor))}}.copy-button button::before{--icon-name:icon-copy-action;content:"";--icon-color:var(--token-color-foreground-faint)}@keyframes icon-deny-alt{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-deny-alt-500,currentColor))}}@keyframes icon-deny-default{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-deny-default-500,currentColor))}}@keyframes icon-disabled{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-disabled-500,currentColor))}}.status-403.empty-state header::before{--icon-name:icon-disabled;content:""}@keyframes icon-docs{100%{-webkit-mask-image:var(--icon-docs-16);mask-image:var(--icon-docs-16);background-color:var(--icon-color,var(--color-docs-500,currentColor))}}#metrics-container .link .config-link::before,.empty-state .docs-link>::after{--icon-name:icon-docs;content:""}@keyframes icon-exit{100%{-webkit-mask-image:var(--icon-external-link-16);mask-image:var(--icon-external-link-16);background-color:var(--icon-color,var(--color-exit-500,currentColor))}}#metrics-container .link .metrics-link::before,a[rel*=external]::after{--icon-name:icon-exit;content:""}@keyframes icon-file-fill{100%{-webkit-mask-image:var(--icon-file-16);mask-image:var(--icon-file-16);background-color:var(--icon-color,var(--color-file-fill-500,currentColor))}}@keyframes icon-folder-outline{100%{-webkit-mask-image:var(--icon-folder-16);mask-image:var(--icon-folder-16);background-color:var(--icon-color,var(--color-folder-outline-500,currentColor))}}#downstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .nspace dt::before,.consul-bucket-list .nspace::before,.consul-exposed-path-list>ul>li>.detail dl.nspace dt::before,.consul-intention-list span[class|=nspace]::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.nspace dt::before,.consul-upstream-instance-list dl.nspace dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.nspace dt::before,.modal-dialog [role=document] table td.folder::before,main table td.folder::before{--icon-name:icon-folder-outline;content:""}@keyframes icon-health{100%{-webkit-mask-image:var(--icon-activity-16);mask-image:var(--icon-activity-16);background-color:var(--icon-color,var(--color-health-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.checks dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.checks dt::before,.consul-upstream-instance-list li>.detail dl.checks dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.checks dt::before{--icon-name:icon-health;content:""}@keyframes icon-help-circle-outline{100%{-webkit-mask-image:var(--icon-help-16);mask-image:var(--icon-help-16);background-color:var(--icon-color,var(--color-help-circle-outline-500,currentColor))}}#downstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .health dt::before,.consul-exposed-path-list>ul>li>.detail dl.unknown dt::before,.consul-exposed-path-list>ul>li>.header .unknown dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.unknown dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .unknown dd::before,.consul-upstream-instance-list li>.detail dl.unknown dt::before,.consul-upstream-instance-list li>.header .unknown dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.unknown dt::before,.list-collection>ul>li:not(:first-child)>.header .unknown dd::before,.popover-select .value-unknown button::before,.status-404.empty-state header::before{--icon-name:icon-help-circle-outline;content:""}@keyframes icon-info-circle-fill{100%{-webkit-mask-image:var(--icon-info-16);mask-image:var(--icon-info-16);background-color:var(--icon-color,var(--color-info-circle-fill-500,currentColor))}}#metrics-container:hover .sparkline-key-link::before,.info.informed-action header::before,.sparkline-key h3::before{--icon-name:icon-info-circle-fill;content:""}@keyframes icon-info-circle-outline{100%{-webkit-mask-image:var(--icon-info-16);mask-image:var(--icon-info-16);background-color:var(--icon-color,var(--color-info-circle-outline-500,currentColor))}}#downstream-container>div:first-child span::before,.consul-auth-method-binding-list dl dt.type+dd span::before,.consul-auth-method-view dl dt.type+dd span::before,.consul-exposed-path-list>ul>li>.detail dl.behavior dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.behavior dt::before,.consul-upstream-instance-list li>.detail dl.behavior dt::before,.discovery-chain .resolvers>header span::after,.discovery-chain .routes>header span::after,.discovery-chain .splitters>header span::after,.list-collection>ul>li:not(:first-child)>.detail dl.behavior dt::before,.modal-dialog [role=document] a[rel*=help]::after,.modal-dialog [role=document] table th span::after,.topology-metrics-status-error span::before,.topology-metrics-status-loader span::before,main a[rel*=help]::after,main table th span::after{--icon-name:icon-info-circle-outline;content:""}@keyframes icon-learn{100%{-webkit-mask-image:var(--icon-learn-16);mask-image:var(--icon-learn-16);background-color:var(--icon-color,var(--color-learn-500,currentColor))}}.empty-state .learn-link>::after{--icon-name:icon-learn;content:""}@keyframes icon-logo-github-monochrome{100%{-webkit-mask-image:var(--icon-github-color-16);mask-image:var(--icon-github-color-16);background-color:var(--icon-color,var(--color-logo-github-monochrome-500,currentColor))}}@keyframes icon-logo-google-color{100%{background-image:var(--icon-google-color-16)}}.oidc-select .google-oidc-provider::before{--icon-name:icon-logo-google-color;content:""}@keyframes icon-logo-kubernetes-color{100%{background-image:var(--icon-kubernetes-color-16)}}@keyframes icon-menu{100%{-webkit-mask-image:var(--icon-menu-16);mask-image:var(--icon-menu-16);background-color:var(--icon-color,var(--color-menu-500,currentColor))}}@keyframes icon-minus-square-fill{100%{-webkit-mask-image:var(--icon-minus-square-16);mask-image:var(--icon-minus-square-16);background-color:var(--icon-color,var(--color-minus-square-fill-500,currentColor))}}#downstream-container .topology-metrics-card div .empty::before,#upstream-container .topology-metrics-card div .empty::before,.consul-exposed-path-list>ul>li>.detail dl.empty dt::before,.consul-exposed-path-list>ul>li>.header .empty dd::before,.consul-instance-checks.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .empty dd::before,.consul-upstream-instance-list li>.detail dl.empty dt::before,.consul-upstream-instance-list li>.header .empty dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.empty dt::before,.list-collection>ul>li:not(:first-child)>.header .empty dd::before,.popover-select .value-empty button::before{--icon-name:icon-minus-square-fill;content:""}@keyframes icon-more-horizontal{100%{-webkit-mask-image:var(--icon-more-horizontal-16);mask-image:var(--icon-more-horizontal-16);background-color:var(--icon-color,var(--color-more-horizontal-500,currentColor))}}@keyframes icon-public-default{100%{-webkit-mask-image:var(--icon-globe-16);mask-image:var(--icon-globe-16);background-color:var(--icon-color,var(--color-public-default-500,currentColor))}}.consul-auth-method-list ul .locality::before,.consul-exposed-path-list>ul>li>.detail dl.address dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.address dt::before,.consul-upstream-instance-list li>.detail dl.address dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.address dt::before{--icon-name:icon-public-default;content:""}@keyframes icon-search{100%{-webkit-mask-image:var(--icon-search-16);mask-image:var(--icon-search-16);background-color:var(--icon-color,var(--color-search-500,currentColor))}}@keyframes icon-star-outline{100%{-webkit-mask-image:var(--icon-star-16);mask-image:var(--icon-star-16);background-color:var(--icon-color,var(--color-star-outline-500,currentColor))}}.leader::before{--icon-name:icon-star-outline;content:""}@keyframes icon-user-organization{100%{-webkit-mask-image:var(--icon-org-16);mask-image:var(--icon-org-16);background-color:var(--icon-color,var(--color-user-organization-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.datacenter dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.datacenter dt::before,.consul-upstream-instance-list dl.datacenter dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.datacenter dt::before{--icon-name:icon-user-organization;content:""}@keyframes icon-user-plain{100%{-webkit-mask-image:var(--icon-user-16);mask-image:var(--icon-user-16);background-color:var(--icon-color,var(--color-user-plain-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail .role::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .role::before,.consul-upstream-instance-list li>.detail .role::before,.list-collection>ul>li:not(:first-child)>.detail .role::before{--icon-name:icon-user-plain;content:""}@keyframes icon-user-team{100%{-webkit-mask-image:var(--icon-users-16);mask-image:var(--icon-users-16);background-color:var(--icon-color,var(--color-user-team-500,currentColor))}}#downstream-container .topology-metrics-card div .partition dt::before,#upstream-container .topology-metrics-card div .partition dt::before,.consul-bucket-list .partition::before,.consul-intention-list span[class|=partition]::before,.consul-upstream-instance-list dl.partition dt::before,.consul-upstream-list dl.partition dt::before,.type-source.popover-select li.partition button::before{--icon-name:icon-user-team;content:""}@keyframes icon-alert-circle{100%{-webkit-mask-image:var(--icon-alert-circle-16);mask-image:var(--icon-alert-circle-16);background-color:var(--icon-color,var(--color-alert-circle-500,currentColor))}}@keyframes icon-check{100%{-webkit-mask-image:var(--icon-check-16);mask-image:var(--icon-check-16);background-color:var(--icon-color,var(--color-check-500,currentColor))}}@keyframes icon-check-circle{100%{-webkit-mask-image:var(--icon-check-circle-16);mask-image:var(--icon-check-circle-16);background-color:var(--icon-color,var(--color-check-circle-500,currentColor))}}@keyframes icon-check-circle-fill{100%{-webkit-mask-image:var(--icon-check-circle-fill-16);mask-image:var(--icon-check-circle-fill-16);background-color:var(--icon-color,var(--color-check-circle-fill-500,currentColor))}}#downstream-container .topology-metrics-card div .passing::before,#upstream-container .topology-metrics-card div .passing::before,.consul-exposed-path-list>ul>li>.detail dl.passing dt::before,.consul-exposed-path-list>ul>li>.header .passing dd::before,.consul-exposed-path-list>ul>li>.header [rel=me] dd::before,.consul-health-check-list .passing.health-check-output::before,.consul-instance-checks.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .passing dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header [rel=me] dd::before,.consul-upstream-instance-list li>.detail dl.passing dt::before,.consul-upstream-instance-list li>.header .passing dd::before,.consul-upstream-instance-list li>.header [rel=me] dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.passing dt::before,.list-collection>ul>li:not(:first-child)>.header .passing dd::before,.list-collection>ul>li:not(:first-child)>.header [rel=me] dd::before,.popover-select .value-passing button::before{--icon-name:icon-check-circle-fill;content:""}@keyframes icon-chevron-left{100%{-webkit-mask-image:var(--icon-chevron-left-16);mask-image:var(--icon-chevron-left-16);background-color:var(--icon-color,var(--color-chevron-left-500,currentColor))}}.empty-state .back-link>::after,main header nav:first-child ol li:first-child a::before{--icon-name:icon-chevron-left;content:""}@keyframes icon-chevron-right{100%{-webkit-mask-image:var(--icon-chevron-right-16);mask-image:var(--icon-chevron-right-16);background-color:var(--icon-color,var(--color-chevron-right-500,currentColor))}}#login-toggle+div footer button::after{--icon-name:icon-chevron-right;content:""}@keyframes icon-chevron-up{100%{-webkit-mask-image:var(--icon-chevron-up-16);mask-image:var(--icon-chevron-up-16);background-color:var(--icon-color,var(--color-chevron-up-500,currentColor))}}.list-collection>button::after,.more-popover-menu>[type=checkbox]:checked+label>::after,.popover-menu>[type=checkbox]:checked+label>::after,.topology-notices button[aria-expanded=true]::before,table.has-actions tr>.actions>[type=checkbox]:checked+label>::after,table.with-details tr>.actions>[type=checkbox]:checked+label>::after{--icon-name:icon-chevron-up;content:""}@keyframes icon-delay{100%{-webkit-mask-image:var(--icon-delay-16);mask-image:var(--icon-delay-16);background-color:var(--icon-color,var(--color-delay-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.lock-delay dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.lock-delay dt::before,.consul-upstream-instance-list li>.detail dl.lock-delay dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.lock-delay dt::before{--icon-name:icon-delay;content:""}@keyframes icon-docs-link{100%{-webkit-mask-image:var(--icon-docs-link-16);mask-image:var(--icon-docs-link-16);background-color:var(--icon-color,var(--color-docs-link-500,currentColor))}}@keyframes icon-eye{100%{-webkit-mask-image:var(--icon-eye-16);mask-image:var(--icon-eye-16);background-color:var(--icon-color,var(--color-eye-500,currentColor))}}@keyframes icon-eye-off{100%{-webkit-mask-image:var(--icon-eye-off-16);mask-image:var(--icon-eye-off-16);background-color:var(--icon-color,var(--color-eye-off-500,currentColor))}}@keyframes icon-file-text{100%{-webkit-mask-image:var(--icon-file-text-16);mask-image:var(--icon-file-text-16);background-color:var(--icon-color,var(--color-file-text-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail .policy::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy::before,.consul-upstream-instance-list li>.detail .policy::before,.list-collection>ul>li:not(:first-child)>.detail .policy::before{--icon-name:icon-file-text;content:""}@keyframes icon-gateway{100%{-webkit-mask-image:var(--icon-gateway-16);mask-image:var(--icon-gateway-16);background-color:var(--icon-color,var(--color-gateway-500,currentColor))}}.consul-kind::before{--icon-name:icon-gateway;content:""}@keyframes icon-git-commit{100%{-webkit-mask-image:var(--icon-git-commit-16);mask-image:var(--icon-git-commit-16);background-color:var(--icon-color,var(--color-git-commit-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.node dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.node dt::before,.consul-upstream-instance-list li>.detail dl.node dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.node dt::before{--icon-name:icon-git-commit;content:""}@keyframes icon-hexagon{100%{-webkit-mask-image:var(--icon-hexagon-16);mask-image:var(--icon-hexagon-16);background-color:var(--icon-color,var(--color-hexagon-500,currentColor))}}@keyframes icon-history{100%{-webkit-mask-image:var(--icon-history-16);mask-image:var(--icon-history-16);background-color:var(--icon-color,var(--color-history-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.ttl dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.ttl dt::before,.consul-upstream-instance-list li>.detail dl.ttl dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.ttl dt::before{--icon-name:icon-history;content:""}@keyframes icon-info{100%{-webkit-mask-image:var(--icon-info-16);mask-image:var(--icon-info-16);background-color:var(--icon-color,var(--color-info-500,currentColor))}}@keyframes icon-layers{100%{-webkit-mask-image:var(--icon-layers-16);mask-image:var(--icon-layers-16);background-color:var(--icon-color,var(--color-layers-500,currentColor))}}.topology-metrics-popover.l7 .tippy-arrow::after,.topology-metrics-popover.l7>button::before{--icon-name:icon-layers;content:"";--icon-color:var(--token-color-palette-neutral-300)}@keyframes icon-loading{100%{-webkit-mask-image:var(--icon-loading-16);mask-image:var(--icon-loading-16);background-color:var(--icon-color,var(--color-loading-500,currentColor))}}@keyframes icon-network-alt{100%{-webkit-mask-image:var(--icon-network-alt-16);mask-image:var(--icon-network-alt-16);background-color:var(--icon-color,var(--color-network-alt-500,currentColor))}}.consul-bucket-list .peer::before{--icon-name:icon-network-alt;content:""}@keyframes icon-path{100%{-webkit-mask-image:var(--icon-path-16);mask-image:var(--icon-path-16);background-color:var(--icon-color,var(--color-path-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.path dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.path dt::before,.consul-upstream-instance-list li>.detail dl.path dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.path dt::before{--icon-name:icon-path;content:""}@keyframes icon-running{100%{-webkit-mask-image:var(--icon-running-16);mask-image:var(--icon-running-16);background-color:var(--icon-color,var(--color-running-500,currentColor))}}@keyframes icon-skip{100%{-webkit-mask-image:var(--icon-skip-16);mask-image:var(--icon-skip-16);background-color:var(--icon-color,var(--color-skip-500,currentColor))}}@keyframes icon-socket{100%{-webkit-mask-image:var(--icon-socket-16);mask-image:var(--icon-socket-16);background-color:var(--icon-color,var(--color-socket-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.socket dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.socket dt::before,.consul-upstream-instance-list li>.detail dl.socket dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.socket dt::before{--icon-name:icon-socket;content:""}@keyframes icon-star-circle{100%{-webkit-mask-image:var(--icon-star-circle-16);mask-image:var(--icon-star-circle-16);background-color:var(--icon-color,var(--color-star-circle-500,currentColor))}}@keyframes icon-star-fill{100%{-webkit-mask-image:var(--icon-star-fill-16);mask-image:var(--icon-star-fill-16);background-color:var(--icon-color,var(--color-star-fill-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail .policy-management::before,.consul-exposed-path-list>ul>li>.header .policy-management dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy-management::before,.consul-lock-session-list ul>li:not(:first-child)>.header .policy-management dd::before,.consul-upstream-instance-list li>.detail .policy-management::before,.consul-upstream-instance-list li>.header .policy-management dd::before,.list-collection>ul>li:not(:first-child)>.detail .policy-management::before,.list-collection>ul>li:not(:first-child)>.header .policy-management dd::before{--icon-name:icon-star-fill;content:"";--icon-color:var(--token-color-consul-brand)}@keyframes icon-tag{100%{-webkit-mask-image:var(--icon-tag-16);mask-image:var(--icon-tag-16);background-color:var(--icon-color,var(--color-tag-500,currentColor))}}.tag-list dt::before,td.tags dt::before{--icon-name:icon-tag;content:""}@keyframes icon-x{100%{-webkit-mask-image:var(--icon-x-16);mask-image:var(--icon-x-16);background-color:var(--icon-color,var(--color-x-500,currentColor))}}@keyframes icon-x-circle{100%{-webkit-mask-image:var(--icon-x-circle-16);mask-image:var(--icon-x-circle-16);background-color:var(--icon-color,var(--color-x-circle-500,currentColor))}}@keyframes icon-x-square{100%{-webkit-mask-image:var(--icon-x-square-16);mask-image:var(--icon-x-square-16);background-color:var(--icon-color,var(--color-x-square-500,currentColor))}}@keyframes icon-cloud-cross{100%{-webkit-mask-image:var(--icon-cloud-cross-16);mask-image:var(--icon-cloud-cross-16);background-color:var(--icon-color,var(--color-cloud-cross-500,currentColor))}}@keyframes icon-loading-motion{100%{-webkit-mask-image:var(--icon-loading-motion-16);mask-image:var(--icon-loading-motion-16);background-color:var(--icon-color,var(--color-loading-motion-500,currentColor))}}@keyframes icon-logo-auth0-color{100%{background-image:var(--icon-auth0-color-16)}}.oidc-select .auth0-oidc-provider::before{--icon-name:icon-logo-auth0-color;content:""}@keyframes icon-logo-ember-circle-color{100%{background-image:var(--icon-logo-ember-circle-color-16)}}@keyframes icon-logo-glimmer-color{100%{background-image:var(--icon-logo-glimmer-color-16)}}@keyframes icon-logo-jwt-color{100%{background-image:var(--icon-logo-jwt-color-16)}}.consul-external-source.jwt::before,.consul-health-check-list .health-check-output dd em.jwt::before,.consul-intention-list td strong.jwt::before,.consul-intention-permission-list strong.jwt::before,.consul-intention-search-bar li button span.jwt::before,.consul-peer-search-bar li button span.jwt::before,.consul-server-card .health-status+dd.jwt::before,.discovery-chain .route-card>header ul li.jwt::before,.jwt.consul-auth-method-type::before,.jwt.consul-kind::before,.jwt.consul-source::before,.jwt.consul-transparent-proxy::before,.jwt.leader::before,.jwt.topology-metrics-source-type::before,.popover-select .jwt button::before,.search-bar-status li.jwt:not(.remove-all)::before,html[data-route^="dc.acls.index"] main td strong.jwt::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.jwt::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.jwt::before,span.jwt.policy-node-identity::before,span.jwt.policy-service-identity::before{--icon-name:icon-logo-jwt-color;content:""}@keyframes icon-logo-microsoft-color{100%{background-image:var(--icon-microsoft-color-16)}}.oidc-select .microsoft-oidc-provider::before{--icon-name:icon-logo-microsoft-color;content:""}@keyframes icon-logo-oidc-color{100%{background-image:var(--icon-logo-oidc-color-16)}}.consul-external-source.oidc::before,.consul-health-check-list .health-check-output dd em.oidc::before,.consul-intention-list td strong.oidc::before,.consul-intention-permission-list strong.oidc::before,.consul-intention-search-bar li button span.oidc::before,.consul-peer-search-bar li button span.oidc::before,.consul-server-card .health-status+dd.oidc::before,.discovery-chain .route-card>header ul li.oidc::before,.oidc.consul-auth-method-type::before,.oidc.consul-kind::before,.oidc.consul-source::before,.oidc.consul-transparent-proxy::before,.oidc.leader::before,.oidc.topology-metrics-source-type::before,.popover-select .oidc button::before,.search-bar-status li.oidc:not(.remove-all)::before,html[data-route^="dc.acls.index"] main td strong.oidc::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.oidc::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em.oidc::before,span.oidc.policy-node-identity::before,span.oidc.policy-service-identity::before{--icon-name:icon-logo-oidc-color;content:""}@keyframes icon-logo-okta-color{100%{background-image:var(--icon-okta-color-16)}}.oidc-select .okta-oidc-provider::before{--icon-name:icon-logo-okta-color;content:""}@keyframes icon-mesh{100%{-webkit-mask-image:var(--icon-mesh-16);mask-image:var(--icon-mesh-16);background-color:var(--icon-color,var(--color-mesh-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.mesh dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.mesh dt::before,.consul-upstream-instance-list li>.detail dl.mesh dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.mesh dt::before{--icon-name:icon-mesh;content:""}@keyframes icon-port{100%{-webkit-mask-image:var(--icon-port-16);mask-image:var(--icon-port-16);background-color:var(--icon-color,var(--color-port-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.port dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.port dt::before,.consul-upstream-instance-list li>.detail dl.port dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.port dt::before{--icon-name:icon-port;content:""}@keyframes icon-protocol{100%{-webkit-mask-image:var(--icon-protocol-16);mask-image:var(--icon-protocol-16);background-color:var(--icon-color,var(--color-protocol-500,currentColor))}}.consul-exposed-path-list>ul>li>.detail dl.protocol dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.protocol dt::before,.consul-upstream-instance-list li>.detail dl.protocol dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.protocol dt::before{--icon-name:icon-protocol;content:""}@keyframes icon-redirect{100%{-webkit-mask-image:var(--icon-redirect-16);mask-image:var(--icon-redirect-16);background-color:var(--icon-color,var(--color-redirect-500,currentColor))}}@keyframes icon-search-color{100%{background-image:var(--icon-search-color-16)}}[for=toolbar-toggle]{--icon-name:icon-search-color;content:""}@keyframes icon-sort{100%{-webkit-mask-image:var(--icon-sort-desc-16);mask-image:var(--icon-sort-desc-16);background-color:var(--icon-color,var(--color-sort-500,currentColor))}}.type-sort.popover-select label>::before{--icon-name:icon-sort;content:""}@keyframes icon-union{100%{-webkit-mask-image:var(--icon-union-16);mask-image:var(--icon-union-16);background-color:var(--icon-color,var(--color-union-500,currentColor))}}#downstream-container .topology-metrics-card .details .group span::before,#upstream-container .topology-metrics-card .details .group span::before{--icon-name:icon-union;content:""}.ember-basic-dropdown{position:relative}.ember-basic-dropdown,.ember-basic-dropdown-content,.ember-basic-dropdown-content *{box-sizing:border-box}.ember-basic-dropdown-content{position:absolute;width:auto;z-index:1000;background-color:#fff}.ember-basic-dropdown-content--left{left:0}.ember-basic-dropdown-content--right{right:0}.ember-basic-dropdown-overlay{position:fixed;background:rgba(0,0,0,.5);width:100%;height:100%;z-index:10;top:0;left:0;pointer-events:none}.ember-basic-dropdown-content-wormhole-origin{display:inline}.ember-power-select-dropdown *{box-sizing:border-box}.ember-power-select-trigger{position:relative;border-radius:4px;background-color:#fff;line-height:1.75;overflow-x:hidden;text-overflow:ellipsis;min-height:1.75em;-moz-user-select:none;user-select:none;-webkit-user-select:none;color:inherit}.ember-power-select-trigger:after{content:"";display:table;clear:both}.ember-power-select-trigger--active,.ember-power-select-trigger:focus{box-shadow:none}.ember-basic-dropdown-trigger--below.ember-power-select-trigger[aria-expanded=true],.ember-basic-dropdown-trigger--in-place.ember-power-select-trigger[aria-expanded=true]{border-bottom-left-radius:0;border-bottom-right-radius:0}.ember-basic-dropdown-trigger--above.ember-power-select-trigger[aria-expanded=true]{border-top-left-radius:0;border-top-right-radius:0}.ember-power-select-placeholder{color:#999;display:block;overflow-x:hidden;white-space:nowrap;text-overflow:ellipsis}.ember-power-select-status-icon{position:absolute;display:inline-block;width:0;height:0;top:0;bottom:0;margin:auto;border-style:solid;border-width:7px 4px 0;border-color:#aaa transparent transparent;right:5px}.ember-basic-dropdown-trigger[aria-expanded=true] .ember-power-select-status-icon{transform:rotate(180deg)}.ember-power-select-clear-btn{position:absolute;cursor:pointer;right:25px}.ember-power-select-trigger-multiple-input{font-family:inherit;font-size:inherit;border:none;display:inline-block;line-height:inherit;-webkit-appearance:none;outline:0;padding:0;float:left;background-color:transparent;text-indent:2px}.ember-power-select-trigger-multiple-input:disabled{background-color:#eee}.ember-power-select-trigger-multiple-input::placeholder{opacity:1;color:#999}.ember-power-select-trigger-multiple-input::-webkit-input-placeholder{opacity:1;color:#999}.ember-power-select-trigger-multiple-input::-moz-placeholder{opacity:1;color:#999}.ember-power-select-trigger-multiple-input::-ms-input-placeholder{opacity:1;color:#999}.active.discovery-chain [id*=":"],.discovery-chain path,.ember-power-select-multiple-remove-btn:not(:hover){opacity:.5}.ember-power-select-multiple-options{padding:0;margin:0}.ember-power-select-multiple-option{border:1px solid gray;border-radius:4px;color:#333;background-color:#e4e4e4;padding:0 4px;display:inline-block;line-height:1.45;float:left;margin:2px 0 2px 3px}.ember-power-select-multiple-remove-btn{cursor:pointer}.ember-power-select-search{padding:4px}.ember-power-select-search-input{border:1px solid #aaa;border-radius:0;width:100%;font-size:inherit;line-height:inherit;padding:0 5px}.ember-power-select-search-input:focus{border:1px solid #aaa;box-shadow:none}.ember-power-select-dropdown{border-left:1px solid #aaa;border-right:1px solid #aaa;line-height:1.75;border-radius:4px;box-shadow:none;overflow:hidden;color:inherit}.ember-power-select-dropdown.ember-basic-dropdown-content--above{border-top:1px solid #aaa;border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.ember-power-select-dropdown.ember-basic-dropdown-content--below,.ember-power-select-dropdown.ember-basic-dropdown-content--in-place{border-top:none;border-bottom:1px solid #aaa;border-top-left-radius:0;border-top-right-radius:0}.ember-power-select-dropdown.ember-basic-dropdown-content--in-place{width:100%}.ember-power-select-options{list-style:none;margin:0;padding:0;-moz-user-select:none;user-select:none;-webkit-user-select:none}.ember-power-select-placeholder,.ember-power-select-selected-item,a[rel*=external]::after{margin-left:8px}.ember-power-select-options[role=listbox]{overflow-y:auto;-webkit-overflow-scrolling:touch;max-height:12.25em}.ember-power-select-option{cursor:pointer;padding:0 8px}.ember-power-select-group[aria-disabled=true]{color:#999;cursor:not-allowed}.ember-power-select-group[aria-disabled=true] .ember-power-select-option,.ember-power-select-option[aria-disabled=true]{color:#999;pointer-events:none;cursor:not-allowed}.ember-power-select-option[aria-selected=true]{background-color:#ddd}.ember-power-select-option[aria-current=true]{background-color:#5897fb;color:#fff}.ember-power-select-group-name{cursor:default;font-weight:700}.ember-power-select-trigger[aria-disabled=true]{background-color:#eee}.ember-power-select-trigger{padding:0 16px 0 0}.ember-power-select-group .ember-power-select-group .ember-power-select-group-name{padding-left:24px}.ember-power-select-group .ember-power-select-group .ember-power-select-option{padding-left:40px}.ember-power-select-group .ember-power-select-option{padding-left:24px}.ember-power-select-group .ember-power-select-group-name{padding-left:8px}.ember-power-select-trigger[dir=rtl]{padding:0 0 0 16px}.ember-power-select-trigger[dir=rtl] .ember-power-select-placeholder,.ember-power-select-trigger[dir=rtl] .ember-power-select-selected-item{margin-right:8px}.ember-power-select-trigger[dir=rtl] .ember-power-select-multiple-option,.ember-power-select-trigger[dir=rtl] .ember-power-select-trigger-multiple-input{float:right}.ember-power-select-trigger[dir=rtl] .ember-power-select-status-icon{left:5px;right:initial}.ember-power-select-trigger[dir=rtl] .ember-power-select-clear-btn{left:25px;right:initial}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-group .ember-power-select-group-name{padding-right:24px}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-group .ember-power-select-option{padding-right:40px}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-option{padding-right:24px}.ember-power-select-dropdown[dir=rtl] .ember-power-select-group .ember-power-select-group-name{padding-right:8px}#login-toggle+div footer button:focus,#login-toggle+div footer button:hover,.consul-intention-fieldsets .permissions>button:focus,.consul-intention-fieldsets .permissions>button:hover,.empty-state>ul>li>:focus,.empty-state>ul>li>:hover,.empty-state>ul>li>label>button:focus,.empty-state>ul>li>label>button:hover,.modal-dialog [role=document] dd a:focus,.modal-dialog [role=document] dd a:hover,.modal-dialog [role=document] p a:focus,.modal-dialog [role=document] p a:hover,.oidc-select button.reset:focus,.oidc-select button.reset:hover,.search-bar-status .remove-all button:focus,.search-bar-status .remove-all button:hover,main dd a:focus,main dd a:hover,main p a:focus,main p a:hover{text-decoration:underline}#login-toggle+div footer button,.consul-intention-fieldsets .permissions>button,.empty-state>ul>li>*,.empty-state>ul>li>:active,.empty-state>ul>li>:focus,.empty-state>ul>li>:hover,.empty-state>ul>li>label>button,.empty-state>ul>li>label>button:active,.empty-state>ul>li>label>button:focus,.empty-state>ul>li>label>button:hover,.modal-dialog [role=document] dd a,.modal-dialog [role=document] p a,.oidc-select button.reset,.search-bar-status .remove-all button,main dd a,main dd a:active,main dd a:focus,main dd a:hover,main p a,main p a:active,main p a:focus,main p a:hover{color:var(--token-color-foreground-action)}.modal-dialog [role=document] label a[rel*=help],div.with-confirmation p,main label a[rel*=help]{color:var(--token-color-foreground-disabled)}#login-toggle+div footer button,.consul-intention-fieldsets .permissions>button,.empty-state>ul>li>*,.empty-state>ul>li>label>button,.modal-dialog [role=document] dd a,.modal-dialog [role=document] p a,.oidc-select button.reset,.search-bar-status .remove-all button,main dd a,main p a{cursor:pointer;background-color:transparent}#login-toggle+div footer button:active,.consul-intention-fieldsets .permissions>button:active,.empty-state>ul>li>:active,.empty-state>ul>li>label>button:active,.modal-dialog [role=document] dd a:active,.modal-dialog [role=document] p a:active,.oidc-select button.reset:active,.search-bar-status .remove-all button:active,main dd a:active,main p a:active{outline:0}.modal-dialog [role=document] a[rel*=help]::after,main a[rel*=help]::after{opacity:.4}.modal-dialog [role=document] h2 a,main h2 a{color:var(--token-color-foreground-strong)}.auth-form em,.empty-state,main header nav:first-child ol li a,main header nav:first-child ol li:not(:first-child) a::before{color:var(--token-color-foreground-faint)}.modal-dialog [role=document] h2 a[rel*=help]::after,main h2 a[rel*=help]::after{font-size:.65em;margin-top:.2em;margin-left:.2em}.tab-section>p:only-child [rel*=help]::after{content:none}.auth-form{width:320px;margin:-20px 25px 0}.auth-form em{font-style:normal;display:inline-block;margin-top:1em}.auth-form .oidc-select,.auth-form form{padding-top:1em}.auth-form form{margin-bottom:0!important}.auth-form .ember-basic-dropdown-trigger,.auth-form button:not(.reset){width:100%}.auth-form .progress{margin:0 auto}#login-toggle+div footer button::after{font-size:120%;position:relative;top:-1px;left:-3px}#login-toggle+div footer{border-top:0;background-color:transparent;padding:10px 42px 20px}#login-toggle+div>div>div>div{padding-bottom:0}main header nav:first-child ol li a{text-decoration:none}main header nav:first-child ol li a:hover{color:var(--token-color-foreground-action);text-decoration:underline}main header nav:first-child ol li a::before{text-decoration:none}main header nav:first-child ol{display:grid;grid-auto-flow:column;white-space:nowrap;overflow:hidden}main header nav:first-child ol>li{list-style-type:none;display:inline-flex;overflow:hidden}main header nav:first-child ol li:first-child a::before{background-color:var(--token-color-foreground-faint);margin-right:4px;display:inline-block}main header nav:first-child ol li:not(:first-child) a{margin-left:6px;overflow:hidden;text-overflow:ellipsis}main header nav:first-child ol li:not(:first-child) a::before{content:"/";margin-right:8px;display:inline-block}main header nav:first-child{position:absolute;top:12px}.consul-intention-action-warn-modal button.dangerous,.copy-button button,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-select label>*,.topology-notices button,.type-sort.popover-select label>*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{cursor:pointer;white-space:nowrap;text-decoration:none}.consul-intention-action-warn-modal button.dangerous:disabled,.copy-button button:disabled,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]:disabled,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]:disabled,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]:disabled,.informed-action>ul>li>:disabled,.menu-panel>ul>[role=treeitem]:disabled,.menu-panel>ul>li>[role=menuitem]:disabled,.menu-panel>ul>li>[role=option]:disabled,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:disabled,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:disabled,.popover-select label>:disabled,.topology-notices button:disabled,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:disabled,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:disabled,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:disabled,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:disabled{cursor:default;box-shadow:none}.checkbox-group label,.more-popover-menu>[type=checkbox]~label,.popover-menu>[type=checkbox]~label,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label,table.has-actions tr>.actions>[type=checkbox]~label,table.with-details tr>.actions>[type=checkbox]~label{cursor:pointer}.consul-intention-action-warn-modal button.dangerous{border-width:1px;border-radius:var(--decor-radius-100);box-shadow:var(--token-elevation-high-box-shadow)}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{color:var(--token-color-foreground-strong);background-color:var(--token-color-surface-primary)}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]:focus,.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]:hover,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]:focus,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]:hover,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]:focus,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]:hover,.informed-action>ul>li>:focus,.informed-action>ul>li>:hover,.menu-panel>ul>[role=treeitem]:focus,.menu-panel>ul>[role=treeitem]:hover,.menu-panel>ul>li>[role=menuitem]:focus,.menu-panel>ul>li>[role=menuitem]:hover,.menu-panel>ul>li>[role=option]:focus,.menu-panel>ul>li>[role=option]:hover,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:focus,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:hover,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:focus,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:hover,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:focus,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]:hover,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:focus,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]:hover,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:focus,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:hover,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:focus,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:hover,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:focus,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]:hover,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:focus,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]:hover,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:focus,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]:hover{background-color:var(--token-color-surface-strong)}.type-sort.popover-select label>::before{position:relative;width:16px;height:16px}.type-sort.popover-select label>::after{top:0!important}.consul-intention-action-warn-modal button.dangerous,.copy-button button,.popover-select label>*,.topology-notices button,.type-sort.popover-select label>*{position:relative}.consul-intention-action-warn-modal button.dangerous .progress.indeterminate,.copy-button button .progress.indeterminate,.popover-select label>* .progress.indeterminate,.topology-notices button .progress.indeterminate{position:absolute;top:50%;left:50%;margin-left:-12px;margin-top:-12px}.consul-intention-action-warn-modal button.dangerous:disabled .progress+*,.copy-button button:disabled .progress+*,.popover-select label>:disabled .progress+*,.topology-notices button:disabled .progress+*{visibility:hidden}.consul-intention-action-warn-modal button.dangerous:empty,.copy-button button:empty,.popover-select label>:empty,.topology-notices button:empty{padding-right:0!important;padding-left:18px!important;margin-right:5px}.consul-intention-action-warn-modal button.dangerous:empty::before,.copy-button button:empty::before,.popover-select label>:empty::before,.topology-notices button:empty::before{left:1px}.consul-intention-action-warn-modal button.dangerous:not(:empty),.copy-button button:not(:empty),.popover-select label>:not(:empty),.topology-notices button:not(:empty){display:inline-flex;text-align:center;justify-content:center;align-items:center;padding:calc(.5em - 1px) calc(2.2em - 1px);min-width:100px}.consul-intention-action-warn-modal button.dangerous:not(:last-child),.copy-button button:not(:last-child),.popover-select label>:not(:last-child),.topology-notices button:not(:last-child){margin-right:8px}.app-view>header .actions a{padding-top:calc(.4em - 1px)!important;padding-bottom:calc(.4em - 1px)!important}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.informed-action>ul>li>*,.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{padding:.9em 1em;text-align:center;display:inline-block;box-sizing:border-box}.type-sort.popover-select label>*{height:35px!important}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card{border:var(--decor-border-100);border-radius:var(--decor-radius-100);background-color:var(--token-color-surface-faint);display:block;position:relative}.discovery-chain .resolver-card>section,.discovery-chain .resolver-card>ul>li,.discovery-chain .route-card>section,.discovery-chain .route-card>ul>li,.discovery-chain .splitter-card>section,.discovery-chain .splitter-card>ul>li{border-top:var(--decor-border-100)}.discovery-chain .resolver-card,.discovery-chain .resolver-card>section,.discovery-chain .resolver-card>ul>li,.discovery-chain .route-card,.discovery-chain .route-card>section,.discovery-chain .route-card>ul>li,.discovery-chain .splitter-card,.discovery-chain .splitter-card>section,.discovery-chain .splitter-card>ul>li{border-color:var(--token-color-surface-interactive-active)}.discovery-chain .resolver-card:focus,.discovery-chain .resolver-card:hover,.discovery-chain .route-card:focus,.discovery-chain .route-card:hover,.discovery-chain .splitter-card:focus,.discovery-chain .splitter-card:hover{box-shadow:var(--token-surface-mid-box-shadow)}.discovery-chain .resolver-card>header,.discovery-chain .route-card>header,.discovery-chain .splitter-card>header{padding:10px}.discovery-chain .resolver-card>section,.discovery-chain .resolver-card>ul>li,.discovery-chain .route-card>section,.discovery-chain .route-card>ul>li,.discovery-chain .splitter-card>section,.discovery-chain .splitter-card>ul>li{padding:5px 10px}.discovery-chain .resolver-card ul,.discovery-chain .route-card ul,.discovery-chain .splitter-card ul{list-style-type:none;margin:0;padding:0}.checkbox-group label{margin-right:10px;white-space:nowrap}.checkbox-group span{display:inline-block;margin-left:10px;min-width:50px}.CodeMirror{max-width:1260px;min-height:300px;height:auto;padding-bottom:20px}.CodeMirror-scroll{overflow-x:hidden!important}.CodeMirror-lint-tooltip{background-color:#f9f9fa;border:1px solid var(--syntax-light-gray);border-radius:0;color:#212121;padding:7px 8px 9px}.cm-s-hashi.CodeMirror{width:100%;background-color:var(--token-color-hashicorp-brand)!important;color:#cfd2d1!important;border:none;font-family:var(--token-typography-font-stack-code);-webkit-font-smoothing:auto;line-height:1.4}.cm-s-hashi .CodeMirror-gutters{color:var(--syntax-dark-grey);background-color:var(--syntax-gutter-grey);border:none}.cm-s-hashi .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-hashi .CodeMirror-linenumber{color:#6d8a88}.cm-s-hashi.CodeMirror-focused div.CodeMirror-selected{background:#214283}.cm-s-hashi .CodeMirror-line::selection,.cm-s-hashi .CodeMirror-line>span::selection,.cm-s-hashi .CodeMirror-line>span>span::selection{background:#214283}.cm-s-hashi .CodeMirror-line::-moz-selection,.cm-s-hashi .CodeMirror-line>span::-moz-selection,.cm-s-hashi .CodeMirror-line>span>span::-moz-selection{background:var(--token-color-surface-interactive)}.cm-s-hashi span.cm-comment{color:var(--syntax-light-grey)}.cm-s-hashi span.cm-string,.cm-s-hashi span.cm-string-2{color:var(--syntax-packer)}.cm-s-hashi span.cm-number{color:var(--syntax-serf)}.cm-s-hashi span.cm-variable,.cm-s-hashi span.cm-variable-2{color:#9e84c5}.cm-s-hashi span.cm-def{color:var(--syntax-packer)}.cm-s-hashi span.cm-operator{color:var(--syntax-gray)}.cm-s-hashi span.cm-keyword{color:var(--syntax-yellow)}.cm-s-hashi span.cm-atom{color:var(--syntax-serf)}.cm-s-hashi span.cm-meta,.cm-s-hashi span.cm-tag{color:var(--syntax-packer)}.cm-s-hashi span.cm-error{color:var(--syntax-red)}.cm-s-hashi span.cm-attribute,.cm-s-hashi span.cm-qualifier{color:#9fca56}.cm-s-hashi span.cm-property{color:#9e84c5}.cm-s-hashi span.cm-builtin,.cm-s-hashi span.cm-variable-3{color:#9fca56}.cm-s-hashi .CodeMirror-activeline-background{background:#101213}.cm-s-hashi .CodeMirror-matchingbracket{text-decoration:underline;color:var(--token-color-surface-primary)!important}.readonly-codemirror .cm-s-hashi span{color:var(--syntax-light-grey)}.readonly-codemirror .cm-s-hashi span.cm-string,.readonly-codemirror .cm-s-hashi span.cm-string-2{color:var(--syntax-faded-gray)}.readonly-codemirror .cm-s-hashi span.cm-number{color:#a3acbc}.readonly-codemirror .cm-s-hashi span.cm-property,.tippy-box[data-theme~=tooltip]{color:var(--token-color-surface-primary)}.readonly-codemirror .cm-s-hashi span.cm-variable-2{color:var(--syntax-light-grey-blue)}.code-editor .toolbar-container{background:var(--token-color-surface-strong);background:linear-gradient(180deg,var(--token-color-surface-strong) 50%,var(--token-color-surface-interactive-active) 100%);border:1px solid var(--token-color-surface-interactive-active);border-bottom-color:var(--token-color-foreground-faint);border-top-color:var(--token-color-foreground-disabled)}.code-editor .toolbar-container .toolbar .title{color:var(--token-color-foreground-strong);padding:0 8px}.code-editor .toolbar-container .toolbar .toolbar-separator{border-right:1px solid var(--token-color-palette-neutral-300)}.code-editor .toolbar-container .ember-power-select-trigger{background-color:var(--token-color-surface-primary);color:var(--token-color-hashicorp-brand);border-radius:var(--decor-radius-100);border:var(--decor-border-100);border-color:var(--token-color-foreground-faint)}.code-editor{display:block;border:10px;overflow:hidden;position:relative;clear:both}.code-editor::after{position:absolute;bottom:0;width:100%;height:25px;background-color:var(--token-color-hashicorp-brand);content:"";display:block}.code-editor>pre{display:none}.code-editor .toolbar-container,.code-editor .toolbar-container .toolbar{align-items:center;justify-content:space-between;display:flex}.code-editor .toolbar-container{position:relative;margin-top:4px;height:44px}.code-editor .toolbar-container .toolbar{flex:1;white-space:nowrap}.code-editor .toolbar-container .toolbar .toolbar-separator{height:32px;margin:0 4px;width:0}.code-editor .toolbar-container .toolbar .tools{display:flex;flex-direction:row;margin:0 10px;align-items:center}.code-editor .toolbar-container .toolbar .tools .copy-button{margin-left:10px}.code-editor .toolbar-container .ember-basic-dropdown-trigger{margin:0 8px;width:120px;height:32px;display:flex;align-items:center;flex-direction:row}.consul-exposed-path-list>ul>li,.consul-lock-session-list ul>li:not(:first-child),.consul-upstream-instance-list li,.list-collection>ul>li:not(:first-child){display:grid;grid-template-columns:1fr auto;grid-template-rows:50% 50%;grid-template-areas:"header actions" "detail actions"}.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.header,.list-collection>ul>li:not(:first-child)>.header{grid-area:header;align-self:start}.consul-exposed-path-list>ul>li>.detail,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-upstream-instance-list li>.detail,.list-collection>ul>li:not(:first-child)>.detail{grid-area:detail;align-self:end}.consul-exposed-path-list>ul>li>.detail *,.consul-lock-session-list ul>li:not(:first-child)>.detail *,.consul-upstream-instance-list li>.detail *,.list-collection>ul>li:not(:first-child)>.detail *{flex-wrap:nowrap!important}.consul-exposed-path-list>ul>li>.actions,.consul-lock-session-list ul>li:not(:first-child)>.actions,.consul-upstream-instance-list li>.actions,.list-collection>ul>li:not(:first-child)>.actions{grid-area:actions;display:inline-flex}.consul-nspace-list>ul>li:not(:first-child) dt,.consul-policy-list>ul li:not(:first-child) dl:not(.datacenter) dt,.consul-role-list>ul>li:not(:first-child) dt,.consul-service-instance-list .port dt,.consul-service-instance-list .port dt::before,.consul-token-list>ul>li:not(:first-child) dt{display:none}.consul-exposed-path-list>ul>li>.header:nth-last-child(2),.consul-lock-session-list ul>li:not(:first-child)>.header:nth-last-child(2),.consul-upstream-instance-list li>.header:nth-last-child(2),.list-collection>ul>li:not(:first-child)>.header:nth-last-child(2){grid-column-start:header;grid-column-end:actions}.consul-exposed-path-list>ul>li>.detail:last-child,.consul-lock-session-list ul>li:not(:first-child)>.detail:last-child,.consul-upstream-instance-list li>.detail:last-child,.list-collection>ul>li:not(:first-child)>.detail:last-child{grid-column-start:detail;grid-column-end:actions}.consul-nspace-list>ul>li:not(:first-child) dt+dd,.consul-policy-list>ul li:not(:first-child) dl:not(.datacenter) dt+dd,.consul-role-list>ul>li:not(:first-child) dt+dd,.consul-token-list>ul>li:not(:first-child) dt+dd{margin-left:0!important}.consul-policy-list dl.datacenter dt,.consul-service-list li>div:first-child>dl:first-child dd{margin-top:1px}.consul-service-instance-list .detail,.consul-service-list .detail{overflow-x:visible!important}.consul-intention-permission-list>ul{border-top:1px solid var(--token-color-surface-interactive-active)}.consul-service-instance-list .port .copy-button{margin-right:0}.consul-exposed-path-list>ul>li .copy-button,.consul-lock-session-list ul>li:not(:first-child) .copy-button,.consul-upstream-instance-list li .copy-button,.list-collection>ul>li:not(:first-child) .copy-button{display:inline-flex}.consul-exposed-path-list>ul>li>.header .copy-button,.consul-lock-session-list ul>li:not(:first-child)>.header .copy-button,.consul-upstream-instance-list li>.header .copy-button,.list-collection>ul>li:not(:first-child)>.header .copy-button{margin-left:4px}.consul-exposed-path-list>ul>li>.detail .copy-button,.consul-lock-session-list ul>li:not(:first-child)>.detail .copy-button,.consul-upstream-instance-list li>.detail .copy-button,.list-collection>ul>li:not(:first-child)>.detail .copy-button{margin-top:2px}.consul-exposed-path-list>ul>li .copy-button button,.consul-lock-session-list ul>li:not(:first-child) .copy-button button,.consul-upstream-instance-list li .copy-button button,.list-collection>ul>li:not(:first-child) .copy-button button{padding:0!important;margin:0!important}.consul-exposed-path-list>ul>li>.header .copy-button button,.consul-lock-session-list ul>li:not(:first-child)>.header .copy-button button,.consul-upstream-instance-list li>.header .copy-button button,.list-collection>ul>li:not(:first-child)>.header .copy-button button{display:none}.consul-exposed-path-list>ul>li>.header:hover .copy-button button,.consul-lock-session-list ul>li:not(:first-child)>.header:hover .copy-button button,.consul-upstream-instance-list li>.header:hover .copy-button button,.list-collection>ul>li:not(:first-child)>.header:hover .copy-button button{display:block}.consul-exposed-path-list>ul>li .copy-button button:hover,.consul-lock-session-list ul>li:not(:first-child) .copy-button button:hover,.consul-upstream-instance-list li .copy-button button:hover,.list-collection>ul>li:not(:first-child) .copy-button button:hover{background-color:transparent!important}.consul-exposed-path-list>ul>li>.detail>.consul-external-source:first-child,.consul-exposed-path-list>ul>li>.detail>.consul-kind:first-child,.consul-lock-session-list ul>li:not(:first-child)>.detail>.consul-external-source:first-child,.consul-lock-session-list ul>li:not(:first-child)>.detail>.consul-kind:first-child,.consul-upstream-instance-list li>.detail>.consul-external-source:first-child,.consul-upstream-instance-list li>.detail>.consul-kind:first-child,.list-collection>ul>li:not(:first-child)>.detail>.consul-external-source:first-child,.list-collection>ul>li:not(:first-child)>.detail>.consul-kind:first-child{margin-left:-5px}.consul-exposed-path-list>ul>li>.detail .policy-management::before,.consul-exposed-path-list>ul>li>.detail .policy::before,.consul-exposed-path-list>ul>li>.detail .role::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy-management::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .policy::before,.consul-lock-session-list ul>li:not(:first-child)>.detail .role::before,.consul-upstream-instance-list li>.detail .policy-management::before,.consul-upstream-instance-list li>.detail .policy::before,.consul-upstream-instance-list li>.detail .role::before,.list-collection>ul>li:not(:first-child)>.detail .policy-management::before,.list-collection>ul>li:not(:first-child)>.detail .policy::before,.list-collection>ul>li:not(:first-child)>.detail .role::before{margin-right:3px}table div.with-confirmation.confirming{background-color:var(--token-color-surface-primary)}div.with-confirmation p{margin-right:12px;padding-left:12px;margin-bottom:0!important}div.with-confirmation{justify-content:end;width:100%;display:flex;align-items:center}table td>div.with-confirmation.confirming{position:absolute;right:0}@media (max-width:420px){div.with-confirmation{float:none;margin-top:1em;display:block}div.with-confirmation p{margin-bottom:1em}}.copy-button button{color:var(--token-color-foreground-action);--icon-color:transparent;min-height:17px}.copy-button button::after{--icon-color:var(--token-color-surface-strong)}.copy-button button:focus,.copy-button button:hover:not(:disabled):not(:active){color:var(--token-color-foreground-action);--icon-color:var(--token-color-surface-strong)}.copy-button button:hover::before{--icon-color:var(--token-color-foreground-action)}.copy-button button:active{--icon-color:var(--token-color-surface-interactive-active)}.copy-button button:empty{padding:0!important;margin-right:0;top:-1px}.copy-button button:empty::after{content:"";display:none;position:absolute;top:-2px;left:-3px;width:20px;height:22px}.copy-button button:empty:hover::after{display:block}.copy-button button:empty::before{position:relative;z-index:1}.copy-button button:not(:empty)::before{margin-right:4px}.consul-bucket-list .copy-button,.consul-exposed-path-list>ul>li>.detail dl .copy-button,.consul-instance-checks .copy-button,.consul-lock-session-list dl .copy-button,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .copy-button,.consul-upstream-instance-list dl .copy-button,.list-collection>ul>li:not(:first-child)>.detail dl .copy-button,.tag-list .copy-button,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .copy-button,section[data-route="dc.show.license"] .validity dl .copy-button,td.tags .copy-button{margin-top:0!important}.consul-bucket-list .copy-btn,.consul-exposed-path-list>ul>li>.detail dl .copy-btn,.consul-instance-checks .copy-btn,.consul-lock-session-list dl .copy-btn,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .copy-btn,.consul-upstream-instance-list dl .copy-btn,.list-collection>ul>li:not(:first-child)>.detail dl .copy-btn,.tag-list .copy-btn,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .copy-btn,section[data-route="dc.show.license"] .validity dl .copy-btn,td.tags .copy-btn{top:0!important}.consul-bucket-list .copy-btn:empty::before,.consul-exposed-path-list>ul>li>.detail dl .copy-btn:empty::before,.consul-instance-checks .copy-btn:empty::before,.consul-lock-session-list dl .copy-btn:empty::before,.consul-upstream-instance-list dl .copy-btn:empty::before,.list-collection>ul>li:not(:first-child)>.detail dl .copy-btn:empty::before,.tag-list .copy-btn:empty::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .copy-btn:empty::before,section[data-route="dc.show.license"] .validity dl .copy-btn:empty::before,td.tags .copy-btn:empty::before{left:0!important}.definition-table>dl{display:grid;grid-template-columns:140px auto;grid-gap:.4em 20px;margin-bottom:1.4em}.disclosure-menu{position:relative}.disclosure-menu [aria-expanded]~*{overflow-y:auto!important;will-change:scrollPosition}.more-popover-menu>[type=checkbox],.more-popover-menu>[type=checkbox]~:not(.animating):not(label),.popover-menu>[type=checkbox],.popover-menu>[type=checkbox]~:not(.animating):not(label),table.has-actions tr>.actions>[type=checkbox],table.has-actions tr>.actions>[type=checkbox]~:not(.animating):not(label),table.with-details tr>.actions>[type=checkbox],table.with-details tr>.actions>[type=checkbox]~:not(.animating):not(label){display:none}.more-popover-menu>[type=checkbox]:checked~:not(label),.popover-menu>[type=checkbox]:checked~:not(label),table.has-actions tr>.actions>[type=checkbox]:checked~:not(label),table.with-details tr>.actions>[type=checkbox]:checked~:not(label){display:block}table.dom-recycling{position:relative}table.dom-recycling tr>*{overflow:hidden}.list-collection-scroll-virtual>ul,table.dom-recycling tbody{overflow-x:hidden!important}table.dom-recycling dd{flex-wrap:nowrap}table.dom-recycling dd>*{margin-bottom:0}.empty-state,.empty-state>div{display:flex;flex-direction:column}.empty-state header :first-child{padding:0;margin:0}.empty-state{margin-top:0!important;padding-bottom:2.8em;background-color:var(--token-color-surface-faint)}.empty-state>*{width:370px;margin:0 auto}.empty-state button{margin:0 auto;display:inline}.empty-state header :first-child{margin-bottom:-3px;border-bottom:none}.empty-state header{margin-top:1.8em;margin-bottom:.5em}.empty-state>ul{display:flex;justify-content:space-between;margin-top:1em}.empty-state>ul>li>*,.empty-state>ul>li>label>button{display:inline-flex;align-items:center}.empty-state>div:only-child{padding:50px 0 10px;text-align:center}.empty-state header::before{font-size:2.6em;position:relative;top:-3px;float:left;margin-right:10px}.oidc-select button.reset,.type-dialog{float:right}.empty-state>ul>li>::before,.empty-state>ul>li>label>button::before{margin-top:-1px;margin-right:.5em}.empty-state li[class*=-link]>::after{margin-left:5px}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup]{border:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300);border-radius:var(--decor-radius-100)}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]:checked+*,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]:focus+*,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]:hover+*{box-shadow:var(--token-elevation-high-box-shadow);background-color:var(--token-color-surface-primary)}@media (min-width:996px){html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup]{display:flex}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label{flex-grow:1}}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] input[type=radio]{display:none}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] .type-password,.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select,.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text,.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label textarea,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] [role=radiogroup] label>span,.modal-dialog [role=document] form button+em,.oidc-select label,.oidc-select label textarea,.oidc-select label>em,.oidc-select label>span,.type-toggle,.type-toggle textarea,.type-toggle>em,.type-toggle>span,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label span,main .type-password,main .type-password textarea,main .type-password>em,main .type-password>span,main .type-select,main .type-select textarea,main .type-select>em,main .type-select>span,main .type-text,main .type-text textarea,main .type-text>em,main .type-text>span,main form button+em,span.label{display:block}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup],html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label,html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label span{height:100%}html[data-route^="dc.acls.index"] .filter-bar [role=radiogroup] label span{padding:5px 14px}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.type-toggle [type=password],.type-toggle [type=text],.type-toggle textarea,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-text [type=password],main .type-text [type=text],main .type-text textarea{-moz-appearance:none;-webkit-appearance:none;box-shadow:var(--token-surface-inset-box-shadow);border-radius:var(--decor-radius-100);border:var(--decor-border-100);outline:0}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:-moz-read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:-moz-read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:-moz-read-only,.modal-dialog [role=document] .type-password [type=password]:-moz-read-only,.modal-dialog [role=document] .type-password [type=text]:-moz-read-only,.modal-dialog [role=document] .type-password textarea:-moz-read-only,.modal-dialog [role=document] .type-select [type=password]:-moz-read-only,.modal-dialog [role=document] .type-select [type=text]:-moz-read-only,.modal-dialog [role=document] .type-select textarea:-moz-read-only,.modal-dialog [role=document] .type-text [type=password]:-moz-read-only,.modal-dialog [role=document] .type-text [type=text]:-moz-read-only,.modal-dialog [role=document] .type-text textarea:-moz-read-only,.modal-dialog [role=document] [role=radiogroup] label [type=password]:-moz-read-only,.modal-dialog [role=document] [role=radiogroup] label [type=text]:-moz-read-only,.modal-dialog [role=document] [role=radiogroup] label textarea:-moz-read-only,.oidc-select label [type=password]:-moz-read-only,.oidc-select label [type=text]:-moz-read-only,.oidc-select label textarea:-moz-read-only,.type-toggle [type=password]:-moz-read-only,.type-toggle [type=text]:-moz-read-only,.type-toggle textarea:-moz-read-only,main .type-password [type=password]:-moz-read-only,main .type-password [type=text]:-moz-read-only,main .type-password textarea:-moz-read-only,main .type-select [type=password]:-moz-read-only,main .type-select [type=text]:-moz-read-only,main .type-select textarea:-moz-read-only,main .type-text [type=password]:-moz-read-only,main .type-text [type=text]:-moz-read-only,main .type-text textarea:-moz-read-only{cursor:not-allowed}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:disabled,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:disabled,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:read-only,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:disabled,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:read-only,.modal-dialog [role=document] .type-password [type=password]:disabled,.modal-dialog [role=document] .type-password [type=password]:read-only,.modal-dialog [role=document] .type-password [type=text]:disabled,.modal-dialog [role=document] .type-password [type=text]:read-only,.modal-dialog [role=document] .type-password textarea:disabled,.modal-dialog [role=document] .type-password textarea:read-only,.modal-dialog [role=document] .type-select [type=password]:disabled,.modal-dialog [role=document] .type-select [type=password]:read-only,.modal-dialog [role=document] .type-select [type=text]:disabled,.modal-dialog [role=document] .type-select [type=text]:read-only,.modal-dialog [role=document] .type-select textarea:disabled,.modal-dialog [role=document] .type-select textarea:read-only,.modal-dialog [role=document] .type-text [type=password]:disabled,.modal-dialog [role=document] .type-text [type=password]:read-only,.modal-dialog [role=document] .type-text [type=text]:disabled,.modal-dialog [role=document] .type-text [type=text]:read-only,.modal-dialog [role=document] .type-text textarea:disabled,.modal-dialog [role=document] .type-text textarea:read-only,.modal-dialog [role=document] [role=radiogroup] label [type=password]:disabled,.modal-dialog [role=document] [role=radiogroup] label [type=password]:read-only,.modal-dialog [role=document] [role=radiogroup] label [type=text]:disabled,.modal-dialog [role=document] [role=radiogroup] label [type=text]:read-only,.modal-dialog [role=document] [role=radiogroup] label textarea:disabled,.modal-dialog [role=document] [role=radiogroup] label textarea:read-only,.oidc-select label [type=password]:disabled,.oidc-select label [type=password]:read-only,.oidc-select label [type=text]:disabled,.oidc-select label [type=text]:read-only,.oidc-select label textarea:disabled,.oidc-select label textarea:read-only,.type-toggle [type=password]:disabled,.type-toggle [type=password]:read-only,.type-toggle [type=text]:disabled,.type-toggle [type=text]:read-only,.type-toggle textarea:disabled,.type-toggle textarea:read-only,main .type-password [type=password]:disabled,main .type-password [type=password]:read-only,main .type-password [type=text]:disabled,main .type-password [type=text]:read-only,main .type-password textarea:disabled,main .type-password textarea:read-only,main .type-select [type=password]:disabled,main .type-select [type=password]:read-only,main .type-select [type=text]:disabled,main .type-select [type=text]:read-only,main .type-select textarea:disabled,main .type-select textarea:read-only,main .type-text [type=password]:disabled,main .type-text [type=password]:read-only,main .type-text [type=text]:disabled,main .type-text [type=text]:read-only,main .type-text textarea:disabled,main .type-text textarea:read-only,textarea:disabled+.CodeMirror{cursor:not-allowed}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]::-moz-placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]::-moz-placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea::-moz-placeholder,.modal-dialog [role=document] .type-password [type=password]::-moz-placeholder,.modal-dialog [role=document] .type-password [type=text]::-moz-placeholder,.modal-dialog [role=document] .type-password textarea::-moz-placeholder,.modal-dialog [role=document] .type-select [type=password]::-moz-placeholder,.modal-dialog [role=document] .type-select [type=text]::-moz-placeholder,.modal-dialog [role=document] .type-select textarea::-moz-placeholder,.modal-dialog [role=document] .type-text [type=password]::-moz-placeholder,.modal-dialog [role=document] .type-text [type=text]::-moz-placeholder,.modal-dialog [role=document] .type-text textarea::-moz-placeholder,.modal-dialog [role=document] [role=radiogroup] label [type=password]::-moz-placeholder,.modal-dialog [role=document] [role=radiogroup] label [type=text]::-moz-placeholder,.modal-dialog [role=document] [role=radiogroup] label textarea::-moz-placeholder,.oidc-select label [type=password]::-moz-placeholder,.oidc-select label [type=text]::-moz-placeholder,.oidc-select label textarea::-moz-placeholder,.type-toggle [type=password]::-moz-placeholder,.type-toggle [type=text]::-moz-placeholder,.type-toggle textarea::-moz-placeholder,main .type-password [type=password]::-moz-placeholder,main .type-password [type=text]::-moz-placeholder,main .type-password textarea::-moz-placeholder,main .type-select [type=password]::-moz-placeholder,main .type-select [type=text]::-moz-placeholder,main .type-select textarea::-moz-placeholder,main .type-text [type=password]::-moz-placeholder,main .type-text [type=text]::-moz-placeholder,main .type-text textarea::-moz-placeholder{color:var(--token-color-foreground-disabled)}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]::placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]::placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea::placeholder,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.modal-dialog [role=document] .type-password [type=password]::placeholder,.modal-dialog [role=document] .type-password [type=text]::placeholder,.modal-dialog [role=document] .type-password textarea::placeholder,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-select [type=password]::placeholder,.modal-dialog [role=document] .type-select [type=text]::placeholder,.modal-dialog [role=document] .type-select textarea::placeholder,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-text [type=password]::placeholder,.modal-dialog [role=document] .type-text [type=text]::placeholder,.modal-dialog [role=document] .type-text textarea::placeholder,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] [role=radiogroup] label [type=password]::placeholder,.modal-dialog [role=document] [role=radiogroup] label [type=text]::placeholder,.modal-dialog [role=document] [role=radiogroup] label textarea::placeholder,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] form fieldset>p,.oidc-select label [type=password]::placeholder,.oidc-select label [type=text]::placeholder,.oidc-select label textarea::placeholder,.oidc-select label>em,.type-toggle [type=password]::placeholder,.type-toggle [type=text]::placeholder,.type-toggle textarea::placeholder,.type-toggle>em,main .type-password [type=password]::placeholder,main .type-password [type=text]::placeholder,main .type-password textarea::placeholder,main .type-password>em,main .type-select [type=password]::placeholder,main .type-select [type=text]::placeholder,main .type-select textarea::placeholder,main .type-select>em,main .type-text [type=password]::placeholder,main .type-text [type=text]::placeholder,main .type-text textarea::placeholder,main .type-text>em,main form button+em,main form fieldset>p{color:var(--token-color-foreground-disabled)}.has-error>input,.has-error>textarea{border-color:var(--decor-error,var(--token-color-foreground-critical))!important}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.modal-dialog [role=document] [role=radiogroup] label textarea,.oidc-select label [type=password],.oidc-select label [type=text],.oidc-select label textarea,.type-toggle [type=password],.type-toggle [type=text],.type-toggle textarea,main .type-password [type=password],main .type-password [type=text],main .type-password textarea,main .type-select [type=password],main .type-select [type=text],main .type-select textarea,main .type-text [type=password],main .type-text [type=text],main .type-text textarea{color:var(--token-color-foreground-faint);border-color:var(--token-color-palette-neutral-300)}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:hover,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:hover,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:hover,.modal-dialog [role=document] .type-password [type=password]:hover,.modal-dialog [role=document] .type-password [type=text]:hover,.modal-dialog [role=document] .type-password textarea:hover,.modal-dialog [role=document] .type-select [type=password]:hover,.modal-dialog [role=document] .type-select [type=text]:hover,.modal-dialog [role=document] .type-select textarea:hover,.modal-dialog [role=document] .type-text [type=password]:hover,.modal-dialog [role=document] .type-text [type=text]:hover,.modal-dialog [role=document] .type-text textarea:hover,.modal-dialog [role=document] [role=radiogroup] label [type=password]:hover,.modal-dialog [role=document] [role=radiogroup] label [type=text]:hover,.modal-dialog [role=document] [role=radiogroup] label textarea:hover,.oidc-select label [type=password]:hover,.oidc-select label [type=text]:hover,.oidc-select label textarea:hover,.type-toggle [type=password]:hover,.type-toggle [type=text]:hover,.type-toggle textarea:hover,main .type-password [type=password]:hover,main .type-password [type=text]:hover,main .type-password textarea:hover,main .type-select [type=password]:hover,main .type-select [type=text]:hover,main .type-select textarea:hover,main .type-text [type=password]:hover,main .type-text [type=text]:hover,main .type-text textarea:hover{border-color:var(--token-color-foreground-faint)}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password]:focus,.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text]:focus,.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea:focus,.modal-dialog [role=document] .type-password [type=password]:focus,.modal-dialog [role=document] .type-password [type=text]:focus,.modal-dialog [role=document] .type-password textarea:focus,.modal-dialog [role=document] .type-select [type=password]:focus,.modal-dialog [role=document] .type-select [type=text]:focus,.modal-dialog [role=document] .type-select textarea:focus,.modal-dialog [role=document] .type-text [type=password]:focus,.modal-dialog [role=document] .type-text [type=text]:focus,.modal-dialog [role=document] .type-text textarea:focus,.modal-dialog [role=document] [role=radiogroup] label [type=password]:focus,.modal-dialog [role=document] [role=radiogroup] label [type=text]:focus,.modal-dialog [role=document] [role=radiogroup] label textarea:focus,.oidc-select label [type=password]:focus,.oidc-select label [type=text]:focus,.oidc-select label textarea:focus,.type-toggle [type=password]:focus,.type-toggle [type=text]:focus,.type-toggle textarea:focus,main .type-password [type=password]:focus,main .type-password [type=text]:focus,main .type-password textarea:focus,main .type-select [type=password]:focus,main .type-select [type=text]:focus,main .type-select textarea:focus,main .type-text [type=password]:focus,main .type-text [type=text]:focus,main .type-text textarea:focus{border-color:var(--typo-action,var(--token-color-foreground-action))}.app-view>div form:not(.filter-bar) [role=radiogroup] label a,.modal-dialog [role=document] .type-password a,.modal-dialog [role=document] .type-select a,.modal-dialog [role=document] .type-text a,.modal-dialog [role=document] [role=radiogroup] label a,.oidc-select label a,.type-toggle a,main .type-password a,main .type-select a,main .type-text a{display:inline}.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=password],.app-view>div form:not(.filter-bar) [role=radiogroup] label [type=text],.modal-dialog [role=document] .type-password [type=password],.modal-dialog [role=document] .type-password [type=text],.modal-dialog [role=document] .type-select [type=password],.modal-dialog [role=document] .type-select [type=text],.modal-dialog [role=document] .type-text [type=password],.modal-dialog [role=document] .type-text [type=text],.modal-dialog [role=document] [role=radiogroup] label [type=password],.modal-dialog [role=document] [role=radiogroup] label [type=text],.oidc-select label [type=password],.oidc-select label [type=text],.type-toggle [type=password],.type-toggle [type=text],main .type-password [type=password],main .type-password [type=text],main .type-select [type=password],main .type-select [type=text],main .type-text [type=password],main .type-text [type=text]{display:inline-flex;justify-content:flex-start;max-width:100%;width:100%;height:0;padding:17px 13px}.consul-exposed-path-list>ul>li>.header dt,.consul-lock-session-list ul>li:not(:first-child)>.header dt,.consul-upstream-instance-list li>.header dt,.list-collection>ul>li:not(:first-child)>.header dt,.type-toggle input{display:none}.app-view>div form:not(.filter-bar) [role=radiogroup] label textarea,.modal-dialog [role=document] .type-password textarea,.modal-dialog [role=document] .type-select textarea,.modal-dialog [role=document] .type-text textarea,.modal-dialog [role=document] [role=radiogroup] label textarea,.oidc-select label textarea,.type-toggle textarea,main .type-password textarea,main .type-select textarea,main .type-text textarea{resize:vertical;max-width:100%;min-width:100%;min-height:70px;padding:6px 13px}.app-view>div form:not(.filter-bar) [role=radiogroup],.app-view>div form:not(.filter-bar) [role=radiogroup] label,.checkbox-group,.modal-dialog [role=document] .type-password,.modal-dialog [role=document] .type-select,.modal-dialog [role=document] .type-text,.modal-dialog [role=document] [role=radiogroup],.modal-dialog [role=document] [role=radiogroup] label,.modal-dialog [role=document] form table,.oidc-select label,.type-toggle,main .type-password,main .type-select,main .type-text,main form table{margin-bottom:1.4em}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] .type-text>span,.modal-dialog [role=document] [role=radiogroup] label>span,.oidc-select label>span,.type-toggle>span,main .type-password>span,main .type-select>span,main .type-text>span,span.label{color:var(--typo-contrast,inherit);margin-bottom:.3em}.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] form button+em,.oidc-select label>em,.type-toggle>em,main .type-password>em,main .type-select>em,main .type-text>em,main form button+em{margin-top:2px}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span+em,.modal-dialog [role=document] .type-password>span+em,.modal-dialog [role=document] .type-select>span+em,.modal-dialog [role=document] .type-text>span+em,.modal-dialog [role=document] [role=radiogroup] label>span+em,.oidc-select label>span+em,.type-toggle>span+em,main .type-password>span+em,main .type-select>span+em,main .type-text>span+em,span.label+em{margin-top:-.5em;margin-bottom:.5em}.modal-dialog [role=document] .type-password>span,.modal-dialog [role=document] .type-select>span,.modal-dialog [role=document] label.type-text>span,main .type-password>span,main .type-select>span,main label.type-text>span{line-height:2.2em}.type-toggle+.checkbox-group{margin-top:-1em}.consul-exposed-path-list>ul>li,.consul-intention-permission-header-list>ul>li,.consul-intention-permission-list>ul>li,.consul-lock-session-list ul>li:not(:first-child),.consul-upstream-instance-list li,.list-collection>ul>li:not(:first-child){list-style-type:none;border:var(--decor-border-100);border-top-color:transparent;border-bottom-color:var(--token-color-surface-interactive-active);border-right-color:transparent;border-left-color:transparent;--horizontal-padding:12px;--vertical-padding:10px;padding:var(--vertical-padding) 0;padding-left:var(--horizontal-padding)}.consul-auth-method-list>ul>li:active:not(:first-child),.consul-auth-method-list>ul>li:focus:not(:first-child),.consul-auth-method-list>ul>li:hover:not(:first-child),.consul-exposed-path-list>ul>li.linkable:active,.consul-exposed-path-list>ul>li.linkable:focus,.consul-exposed-path-list>ul>li.linkable:hover,.consul-intention-permission-list:not(.readonly)>ul>li:active,.consul-intention-permission-list:not(.readonly)>ul>li:focus,.consul-intention-permission-list:not(.readonly)>ul>li:hover,.consul-lock-session-list ul>li.linkable:active:not(:first-child),.consul-lock-session-list ul>li.linkable:focus:not(:first-child),.consul-lock-session-list ul>li.linkable:hover:not(:first-child),.consul-node-list>ul>li:active:not(:first-child),.consul-node-list>ul>li:focus:not(:first-child),.consul-node-list>ul>li:hover:not(:first-child),.consul-policy-list>ul>li:active:not(:first-child),.consul-policy-list>ul>li:focus:not(:first-child),.consul-policy-list>ul>li:hover:not(:first-child),.consul-role-list>ul>li:active:not(:first-child),.consul-role-list>ul>li:focus:not(:first-child),.consul-role-list>ul>li:hover:not(:first-child),.consul-service-instance-list>ul>li:active:not(:first-child),.consul-service-instance-list>ul>li:focus:not(:first-child),.consul-service-instance-list>ul>li:hover:not(:first-child),.consul-token-list>ul>li:active:not(:first-child),.consul-token-list>ul>li:focus:not(:first-child),.consul-token-list>ul>li:hover:not(:first-child),.consul-upstream-instance-list li.linkable:active,.consul-upstream-instance-list li.linkable:focus,.consul-upstream-instance-list li.linkable:hover,.list-collection>ul>li.linkable:active:not(:first-child),.list-collection>ul>li.linkable:focus:not(:first-child),.list-collection>ul>li.linkable:hover:not(:first-child){border-color:var(--token-color-surface-interactive-active);box-shadow:var(--token-elevation-high-box-shadow);border-top-color:transparent;cursor:pointer}.radio-card,.tippy-box{box-shadow:var(--token-surface-mid-box-shadow)}.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.header,.list-collection>ul>li:not(:first-child)>.header{color:var(--token-color-hashicorp-brand)}.consul-exposed-path-list>ul>li>.header *,.consul-lock-session-list ul>li:not(:first-child)>.header *,.consul-upstream-instance-list li>.header *,.list-collection>ul>li:not(:first-child)>.header *{color:inherit}.consul-exposed-path-list>ul>li>.detail,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-upstream-instance-list li>.detail,.list-collection>ul>li:not(:first-child)>.detail,.radio-card{color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul>li>.detail a,.consul-lock-session-list ul>li:not(:first-child)>.detail a,.consul-upstream-instance-list li>.detail a,.list-collection>ul>li:not(:first-child)>.detail a{color:inherit}.consul-exposed-path-list>ul>li>.detail a:hover,.consul-lock-session-list ul>li:not(:first-child)>.detail a:hover,.consul-upstream-instance-list li>.detail a:hover,.list-collection>ul>li:not(:first-child)>.detail a:hover{color:var(--token-color-foreground-action);text-decoration:underline}.consul-exposed-path-list>ul>li>.detail,.consul-exposed-path-list>ul>li>.header>dl:first-child,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-lock-session-list ul>li:not(:first-child)>.header>dl:first-child,.consul-upstream-instance-list li>.detail,.consul-upstream-instance-list li>.header>dl:first-child,.list-collection>ul>li:not(:first-child)>.detail,.list-collection>ul>li:not(:first-child)>.header>dl:first-child{margin-right:6px}.consul-exposed-path-list>ul>li>.header dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header dd::before,.consul-upstream-instance-list li>.header dd::before,.list-collection>ul>li:not(:first-child)>.header dd::before{font-size:.9em}.consul-exposed-path-list>ul>li>.detail,.consul-exposed-path-list>ul>li>.header,.consul-lock-session-list ul>li:not(:first-child)>.detail,.consul-lock-session-list ul>li:not(:first-child)>.header,.consul-upstream-instance-list li>.detail,.consul-upstream-instance-list li>.header,.list-collection>ul>li:not(:first-child)>.detail,.list-collection>ul>li:not(:first-child)>.header{display:flex;flex-wrap:nowrap;overflow-x:hidden}.consul-exposed-path-list>ul>li>.detail *,.consul-exposed-path-list>ul>li>.header *,.consul-lock-session-list ul>li:not(:first-child)>.detail *,.consul-lock-session-list ul>li:not(:first-child)>.header *,.consul-upstream-instance-list li>.detail *,.consul-upstream-instance-list li>.header *,.list-collection>ul>li:not(:first-child)>.detail *,.list-collection>ul>li:not(:first-child)>.header *{white-space:nowrap;flex-wrap:nowrap}.consul-exposed-path-list>ul>li>.detail>span,.consul-lock-session-list ul>li:not(:first-child)>.detail>span,.consul-upstream-instance-list li>.detail>span,.list-collection>ul>li:not(:first-child)>.detail>span{margin-right:18px}.consul-intention-permission-header-list>ul>li,.consul-intention-permission-list>ul>li{padding-top:0!important;padding-bottom:0!important}.consul-intention-permission-header-list>ul>li .detail,.consul-intention-permission-list>ul>li .detail{grid-row-start:header!important;grid-row-end:detail!important;align-self:center!important;padding:5px 0}.consul-intention-permission-header-list>ul>li .popover-menu>[type=checkbox]+label,.consul-intention-permission-list>ul>li .popover-menu>[type=checkbox]+label{padding:0}.consul-intention-permission-header-list>ul>li .popover-menu>[type=checkbox]+label+div:not(.above),.consul-intention-permission-list>ul>li .popover-menu>[type=checkbox]+label+div:not(.above){top:30px}.has-error>strong{font-style:normal;font-weight:var(--token-typography-font-weight-regular);color:inherit;color:var(--token-color-foreground-critical);position:relative;padding-left:20px}.has-error>strong::before{color:var(--token-color-foreground-critical);position:absolute;top:50%;left:0;margin-top:-8px}.more-popover-menu .popover-menu>[type=checkbox]+label,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label,table.with-details tr>.actions .popover-menu>[type=checkbox]+label{padding:7px}.more-popover-menu .popover-menu>[type=checkbox]+label>*,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>*,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>*{background-color:transparent;border-radius:var(--decor-radius-100);width:30px;height:30px;font-size:0}.more-popover-menu .popover-menu>[type=checkbox]+label>:active,.more-popover-menu .popover-menu>[type=checkbox]+label>:focus,.more-popover-menu .popover-menu>[type=checkbox]+label>:hover,.radio-card>:first-child,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>:active,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>:focus,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>:hover,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>:active,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>:focus,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>:hover{background-color:var(--token-color-surface-strong)}.more-popover-menu .popover-menu>[type=checkbox]+label>::after,table.has-actions tr>.actions .popover-menu>[type=checkbox]+label>::after,table.with-details tr>.actions .popover-menu>[type=checkbox]+label>::after{--icon-name:icon-more-horizontal;--icon-color:var(--token-color-foreground-strong);--icon-size:icon-300;content:"";position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.oidc-select [class$=-oidc-provider]::before{width:22px;height:22px;flex:0 0 auto;margin-right:10px}.oidc-select .ember-power-select-trigger,.oidc-select li{margin-bottom:1em}.informed-action header,.radio-card header{margin-bottom:.5em}.oidc-select .ember-power-select-trigger{width:100%}.radio-card{border:var(--decor-border-100);border-radius:var(--decor-radius-100);border-color:var(--token-color-surface-interactive-active);cursor:pointer;float:none!important;margin-right:0!important;display:flex!important}.checked.radio-card{border-color:var(--token-color-foreground-action)}.checked.radio-card>:first-child{background-color:var(--token-color-surface-action)}.radio-card header{color:var(--token-color-hashicorp-brand)}.consul-intention-fieldsets .radio-card>:last-child{padding-left:47px;position:relative}.consul-intention-fieldsets .radio-card>:last-child::before{position:absolute;left:14px;font-size:1rem}.radio-card>:first-child{padding:10px;display:grid;align-items:center;justify-items:center}.radio-card>:last-child{padding:18px}.consul-server-card,.disclosure-menu [aria-expanded]~*,.menu-panel,.more-popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div,section[data-route="dc.show.serverstatus"] .server-failure-tolerance,section[data-route="dc.show.license"] aside,table.has-actions tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div{--tone-border:var(--token-color-palette-neutral-300);border:var(--decor-border-100);border-radius:var(--decor-radius-200);box-shadow:var(--token-surface-high-box-shadow);color:var(--token-color-foreground-strong);background-color:var(--token-color-surface-primary);--padding-x:14px;--padding-y:14px;position:relative}.disclosure-menu [aria-expanded]~* [role=separator],.menu-panel [role=separator],.more-popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]{border-top:var(--decor-border-100);margin:0}.consul-server-card,.disclosure-menu [aria-expanded]~*,.disclosure-menu [aria-expanded]~* [role=separator],.menu-panel,.menu-panel [role=separator],.more-popover-menu>[type=checkbox]+label+div,.more-popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div [role=separator],section[data-route="dc.show.serverstatus"] .server-failure-tolerance,section[data-route="dc.show.license"] aside,table.has-actions tr>.actions>[type=checkbox]+label+div,table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]{border-color:var(--tone-border)}.paged-collection-scroll,[style*="--paged-row-height"]{overflow-y:auto!important;will-change:scrollPosition}[style*="--paged-start"]::before{content:"";display:block;height:var(--paged-start)}.consul-auth-method-type,.consul-external-source,.consul-health-check-list .health-check-output dd em,.consul-intention-list td strong,.consul-intention-permission-list strong,.consul-intention-search-bar li button span,.consul-kind,.consul-peer-search-bar li button span,.consul-server-card .health-status+dd,.consul-source,.consul-transparent-proxy,.discovery-chain .route-card>header ul li,.leader,.search-bar-status li:not(.remove-all),.topology-metrics-source-type,html[data-route^="dc.acls.index"] main td strong,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,span.policy-node-identity,span.policy-service-identity{border-radius:var(--decor-radius-100);display:inline-flex;position:relative;align-items:center;white-space:nowrap}.consul-auth-method-type::before,.consul-external-source::before,.consul-health-check-list .health-check-output dd em::before,.consul-intention-list td strong::before,.consul-intention-permission-list strong::before,.consul-intention-search-bar li button span::before,.consul-kind::before,.consul-peer-search-bar li button span::before,.consul-server-card .health-status+dd::before,.consul-source::before,.consul-transparent-proxy::before,.discovery-chain .route-card>header ul li::before,.leader::before,.search-bar-status li:not(.remove-all)::before,.topology-metrics-source-type::before,html[data-route^="dc.acls.index"] main td strong::before,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl::before,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em::before,span.policy-node-identity::before,span.policy-service-identity::before{margin-right:4px;--icon-size:icon-300}.consul-auth-method-type,.consul-external-source,.consul-kind,.consul-server-card .health-status+dd,.consul-source,.consul-transparent-proxy,.leader,.search-bar-status li:not(.remove-all),.topology-metrics-source-type,section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em,span.policy-node-identity,span.policy-service-identity{padding:0 8px;--icon-size:icon-200}.consul-intention-permission-list strong,.consul-peer-search-bar li button span,.discovery-chain .route-card>header ul li,html[data-route^="dc.acls.index"] main td strong,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl{padding:1px 5px}.consul-intention-list td strong,.consul-intention-search-bar li button span{padding:4px 8px}span.policy-node-identity::before,span.policy-service-identity::before{vertical-align:unset}span.policy-node-identity::before{content:"Node Identity: "}span.policy-service-identity::before{content:"Service Identity: "}.more-popover-menu>[type=checkbox]+label>*,.popover-menu>[type=checkbox]+label>*,table.has-actions tr>.actions>[type=checkbox]+label>*,table.with-details tr>.actions>[type=checkbox]+label>*{cursor:pointer}.more-popover-menu>[type=checkbox]+label>::after,.popover-menu>[type=checkbox]+label>::after,table.has-actions tr>.actions>[type=checkbox]+label>::after,table.with-details tr>.actions>[type=checkbox]+label>::after{width:16px;height:16px;position:relative}.more-popover-menu,.popover-menu,table.has-actions tr>.actions,table.with-details tr>.actions{position:relative}.more-popover-menu>[type=checkbox]+label,.popover-menu>[type=checkbox]+label,table.has-actions tr>.actions>[type=checkbox]+label,table.with-details tr>.actions>[type=checkbox]+label{display:block}.more-popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div,table.has-actions tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div{min-width:192px}.more-popover-menu>[type=checkbox]+label+div:not(.above),.popover-menu>[type=checkbox]+label+div:not(.above),table.has-actions tr>.actions>[type=checkbox]+label+div:not(.above),table.with-details tr>.actions>[type=checkbox]+label+div:not(.above){top:38px}.more-popover-menu>[type=checkbox]+label+div:not(.left),.popover-menu>[type=checkbox]+label+div:not(.left),table.has-actions tr>.actions>[type=checkbox]+label+div:not(.left),table.with-details tr>.actions>[type=checkbox]+label+div:not(.left){right:5px}.popover-menu .menu-panel{position:absolute!important}.popover-select label{height:100%}.popover-select label>*{padding:0 8px!important;height:100%!important;justify-content:space-between!important;min-width:auto!important}.popover-select label>::after{margin-left:6px}.popover-select button::before{margin-right:10px}.popover-select .value-passing button::before{color:var(--token-color-foreground-success)}.popover-select .value-warning button::before{color:var(--token-color-foreground-warning)}.popover-select .value-critical button::before{color:var(--token-color-foreground-critical)}.popover-select .value-empty button::before{color:var(--token-color-foreground-disabled)}.popover-select .value-unknown button::before,.type-source.popover-select li.partition button::before{color:var(--token-color-foreground-faint)}.type-source.popover-select li.aws button{text-transform:uppercase}.progress.indeterminate{width:100%;display:flex;align-items:center;justify-content:center;--icon-size:icon-700;--icon-name:var(--icon-loading);--icon-color:var(--token-color-foreground-faint)}.progress.indeterminate::before{content:""}.app-view>div form:not(.filter-bar) [role=radiogroup],.modal-dialog [role=document] [role=radiogroup]{overflow:hidden;padding-left:1px}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label{float:left}.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] [role=radiogroup] label>span{float:right;margin-left:1em}.app-view>div form:not(.filter-bar) [role=radiogroup] label:not(:last-child),.modal-dialog [role=document] [role=radiogroup] label:not(:last-child){margin-right:25px}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.app-view>div form:not(.filter-bar) [role=radiogroup] label>span,.modal-dialog [role=document] [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label>span{margin-bottom:0!important}.type-toggle label span{cursor:pointer}.type-toggle label span::after{border-radius:var(--decor-radius-full)}.type-toggle label span::before{border-radius:7px;left:0;width:24px;height:12px;margin-top:-5px}.type-negative.type-toggle{border:0}.app-view>header .title,.modal-dialog [role=document] table td,.modal-dialog [role=document] table th,main table td,main table th{border-bottom:var(--decor-border-100)}.type-toggle label span::after{background-color:var(--token-color-surface-primary);margin-top:-3px;width:8px;height:8px}.type-negative.type-toggle label input+span::before,.type-toggle label input:checked+span::before{background-color:var(--token-color-foreground-action)}.type-negative.type-toggle label input:checked+span::before,.type-toggle label span::before{background-color:var(--token-color-palette-neutral-300)}.type-toggle label{position:relative}.type-toggle label span{color:var(--token-color-foreground-strong);display:inline-block;padding-left:34px}.type-toggle label span::after,.type-toggle label span::before{position:absolute;display:block;content:"";top:50%}.type-negative.type-toggle label input+span::after,.type-toggle label input:checked+span::after{left:14px}.type-negative.type-toggle label input:checked+span::after,.type-toggle label span::after{left:2px}.consul-intention-list td.destination,.consul-intention-list td.source,.modal-dialog [role=document] table th,main table th{border-color:var(--token-color-palette-neutral-300)}.modal-dialog [role=document] table td,main table td{border-color:var(--token-color-palette-neutral-300);color:var(--token-color-foreground-faint);height:50px;vertical-align:middle}.modal-dialog [role=document] table td strong,.modal-dialog [role=document] table th,main table td strong,main table th{color:var(--token-color-foreground-faint)}.modal-dialog [role=document] table a,.tomography-graph .tick text,main table a{color:var(--token-color-foreground-strong)}.modal-dialog [role=document] table,main table{width:100%;border-collapse:collapse}table.dom-recycling tr{display:flex}table.dom-recycling tr>*{flex:1 1 auto;display:inline-flex;align-items:center}.modal-dialog [role=document] table th.actions input,main table th.actions input{display:none}.modal-dialog [role=document] table th.actions,main table th.actions{text-align:right}.modal-dialog [role=document] table td a,main table td a{display:block}.modal-dialog [role=document] table td.no-actions~.actions,main table td.no-actions~.actions{display:none}.modal-dialog [role=document] table td:not(.actions)>:only-child,main table td:not(.actions)>:only-child{overflow:hidden;text-overflow:ellipsis}.modal-dialog [role=document] table td:not(.actions)>*,main table td:not(.actions)>*{white-space:nowrap}.modal-dialog [role=document] table caption,main table caption{margin-bottom:.8em}.modal-dialog [role=document] table th,main table th{padding:.6em 0}.modal-dialog [role=document] table td a,.modal-dialog [role=document] table td:not(.actions),.modal-dialog [role=document] table th:not(.actions),main table td a,main table td:not(.actions),main table th:not(.actions){padding-right:.9em}.modal-dialog [role=document] table tbody td em,main table tbody td em{display:block;font-style:normal;font-weight:var(--token-typography-font-weight-regular);color:var(--token-color-foreground-faint)}table.has-actions tr>.actions,table.with-details tr>.actions{width:60px!important;overflow:visible}table.has-actions tr>.actions>[type=checkbox]+label,table.with-details tr>.actions>[type=checkbox]+label{position:absolute;right:5px}table.consul-metadata-list tbody tr{cursor:default}table.consul-metadata-list tbody tr:hover{box-shadow:none}.modal-dialog [role=document] table th span::after,main table th span::after{color:var(--token-color-foreground-faint);margin-left:4px}.modal-dialog [role=document] table tbody tr,main table tbody tr{cursor:pointer}.modal-dialog [role=document] table td:first-child,main table td:first-child{padding:0}.modal-dialog [role=document] table tbody tr:hover,main table tbody tr:hover{box-shadow:var(--token-elevation-high-box-shadow)}.modal-dialog [role=document] table td.folder::before,main table td.folder::before{background-color:var(--token-color-palette-neutral-300);margin-top:1px;margin-right:5px}@media (max-width:420px){.consul-intention-list tr>:nth-last-child(2),.modal-dialog [role=document] table tr>.actions,main table tr>.actions{display:none}}.voting-status-leader.consul-server-card .name{width:var(--tile-size,3rem);height:var(--tile-size,3rem)}.voting-status-leader.consul-server-card .name::before{display:block;content:"";width:100%;height:100%;border-radius:var(--decor-radius-250);border:var(--decor-border-100);background-image:linear-gradient(135deg,var(--token-color-consul-surface) 0,var(--token-color-consul-border) 100%);border-color:var(--token-color-border-faint)}.voting-status-leader.consul-server-card .name::after{content:"";position:absolute;top:calc(var(--tile-size,3rem)/ 4);left:calc(var(--tile-size,3rem)/ 4);--icon-name:icon-star-fill;--icon-size:icon-700;color:var(--token-color-consul-brand)}table.with-details td:only-child>div>label,table.with-details td>label{border-radius:var(--decor-radius-100);cursor:pointer;min-width:30px;min-height:30px;display:inline-flex;align-items:center;justify-content:center}table.with-details td:only-child>div>label:active,table.with-details td:only-child>div>label:focus,table.with-details td:only-child>div>label:hover,table.with-details td>label:active,table.with-details td>label:focus,table.with-details td>label:hover{background-color:var(--token-color-surface-strong)}table.dom-recycling tbody{top:33px!important;width:100%}table.dom-recycling caption~tbody{top:57px!important}table tr>:nth-last-child(2):first-child,table tr>:nth-last-child(2):first-child~*{width:50%}table tr>:nth-last-child(3):first-child,table tr>:nth-last-child(3):first-child~*{width:33.3333333333%}table tr>:nth-last-child(4):first-child,table tr>:nth-last-child(4):first-child~*{width:25%}table tr>:nth-last-child(5):first-child,table tr>:nth-last-child(5):first-child~*{width:20%}table.has-actions tr>:nth-last-child(2):first-child,table.has-actions tr>:nth-last-child(2):first-child~*{width:calc(100% - 60px)}table.has-actions tr>:nth-last-child(3):first-child,table.has-actions tr>:nth-last-child(3):first-child~*{width:calc(50% - 30px)}table.has-actions tr>:nth-last-child(4):first-child,table.has-actions tr>:nth-last-child(4):first-child~*{width:calc(33% - 20px)}table.has-actions tr>:nth-last-child(5):first-child,table.has-actions tr>:nth-last-child(5):first-child~*{width:calc(25% - 15px)}html[data-route^="dc.acls.policies"] [role=dialog] table tr>:not(last-child),html[data-route^="dc.acls.policies"] table tr>:not(last-child),html[data-route^="dc.acls.roles"] [role=dialog] table tr>:not(last-child),html[data-route^="dc.acls.roles"] main table.token-list tr>:not(last-child){width:120px}html[data-route^="dc.acls.policies"] table tr>:last-child,html[data-route^="dc.acls.roles"] [role=dialog] table tr>:last-child,html[data-route^="dc.acls.roles"] main table.token-list tr>:last-child{width:calc(100% - 240px)!important}table.with-details td:only-child{cursor:default;border:0}table.with-details td:only-child>div::before,table.with-details td:only-child>div>div,table.with-details td:only-child>div>label{background-color:var(--token-color-surface-primary)}table.with-details td:only-child>div>label::before{transform:rotate(180deg)}table.with-details td:only-child>div::before{background:var(--token-color-surface-interactive-active);content:"";display:block;height:1px;position:absolute;bottom:-20px;left:10px;width:calc(100% - 20px)}table.with-details tr>.actions{position:relative}table.with-details td:only-child>div>label,table.with-details td>label{pointer-events:auto;position:absolute;top:8px}table.with-details td:only-child>div>label span,table.with-details td>label span{display:none}table.with-details td>label{right:2px}table.with-details tr:nth-child(even) td{height:auto;position:relative;display:table-cell}table.with-details tr:nth-child(even) td>*{display:none}table.with-details td:only-child>div>label{right:11px}table.with-details tr:nth-child(even) td>input:checked+*{display:block}table.with-details td:only-child{overflow:visible;width:100%}table.with-details td:only-child>div{border:1px solid var(--token-color-palette-neutral-300);border-radius:var(--decor-radius-100);box-shadow:var(--token-surface-high-box-shadow);margin-bottom:20px;position:relative;left:-10px;right:-10px;width:calc(100% + 20px);margin-top:-51px;pointer-events:none;padding:10px}table.with-details td:only-child>div::after{content:"";display:block;clear:both}table.with-details td:only-child>div>div{pointer-events:auto;margin-top:36px}.consul-auth-method-binding-list dl,.consul-auth-method-view dl,.consul-auth-method-view section dl{display:flex;flex-wrap:wrap}.consul-auth-method-binding-list dl dd,.consul-auth-method-binding-list dl dt,.consul-auth-method-view dl dd,.consul-auth-method-view dl dt{padding:12px 0;margin:0;border-top:1px solid!important}.consul-auth-method-binding-list dl dt,.consul-auth-method-view dl dt{width:20%;font-weight:var(--token-typography-font-weight-bold)}.consul-auth-method-binding-list dl dd,.consul-auth-method-view dl dd{margin-left:auto;width:80%;display:flex}.consul-auth-method-binding-list dl dd>ul li,.consul-auth-method-view dl dd>ul li{display:flex}.consul-auth-method-binding-list dl dd>ul li:not(:last-of-type),.consul-auth-method-view dl dd>ul li:not(:last-of-type){padding-bottom:12px}.consul-auth-method-binding-list dl dt.check+dd,.consul-auth-method-view dl dt.check+dd{padding-top:16px}.consul-auth-method-binding-list dl>dd:last-of-type,.consul-auth-method-binding-list dl>dt:last-of-type,.consul-auth-method-view dl>dd:last-of-type,.consul-auth-method-view dl>dt:last-of-type{border-bottom:1px solid!important;border-color:var(--token-color-palette-neutral-300)!important}.consul-auth-method-binding-list dl dd,.consul-auth-method-binding-list dl dt,.consul-auth-method-view dl dd,.consul-auth-method-view dl dt{border-color:var(--token-color-palette-neutral-300)!important;color:var(--token-color-hashicorp-brand)!important}.consul-auth-method-binding-list dl dd .copy-button button::before,.consul-auth-method-view dl dd .copy-button button::before{background-color:var(--token-color-hashicorp-brand)}.consul-auth-method-binding-list dl dt.type+dd span::before,.consul-auth-method-view dl dt.type+dd span::before{margin-left:4px;background-color:var(--token-color-foreground-faint)}.tooltip-panel dt{cursor:pointer}.tooltip-panel dd>div::before{width:12px;height:12px;background-color:var(--token-color-surface-primary);border-top:1px solid var(--token-color-palette-neutral-300);border-right:1px solid var(--token-color-palette-neutral-300);transform:rotate(-45deg);position:absolute;left:16px;top:-7px}.tooltip-panel,.tooltip-panel dt{display:flex;flex-direction:column}.tooltip-panel dd>div.menu-panel{top:auto;overflow:visible}.tooltip-panel dd{display:none;position:relative;z-index:1;padding-top:10px;margin-bottom:-10px}.tooltip-panel:hover dd{display:block}.tooltip-panel dd>div{width:250px}.app-view>header .title{display:grid;grid-template-columns:1fr auto;grid-template-areas:"title actions";position:relative;z-index:5;padding-bottom:1.4em}.app-view>div form:not(.filter-bar) fieldset{border-bottom:var(--decor-border-200)}.app-view>header h1>em{color:var(--token-color-foreground-faint)}.app-view>header dd>a{color:var(--token-color-hashicorp-brand)}.app-view>div div>dl>dd{color:var(--token-color-foreground-disabled)}.app-view>div form:not(.filter-bar) fieldset,.app-view>header .title{border-color:var(--token-color-surface-interactive-active)}.app-view>header .title .title-left-container{grid-area:title;display:flex;flex-wrap:wrap;align-items:center;white-space:normal}.app-view>header .title .title-left-container>:first-child{flex-basis:100%}.app-view>header .title .title-left-container>:not(:first-child){margin-right:8px}.app-view>header .actions{grid-area:actions;align-self:end;display:flex;align-items:flex-start;margin-left:auto;margin-top:9px}.app-view>div form:not(.filter-bar) fieldset{padding-bottom:.3em;margin-bottom:2em}[for=toolbar-toggle]{background-position:0 4px;display:inline-block;width:26px;height:26px;cursor:pointer;color:var(--token-color-foreground-action)}#toolbar-toggle{display:none}@media (max-width:849px){.app-view>header .actions{margin-top:9px}}@media (min-width:996px){[for=toolbar-toggle]{display:none}}@media (max-width:995px){.app-view>header h1{display:inline-block}html[data-route$="dc.services.instance.show"] h1{display:block}#toolbar-toggle+*{display:none}#toolbar-toggle:checked+*{display:flex}}.brand-loader{position:absolute;top:50%;margin-top:-26px;left:50%}.app .notifications{position:fixed;z-index:100;bottom:2rem;left:1.5rem;pointer-events:none}.app .notifications .app-notification>*{min-width:400px}.app .notifications .app-notification{transition-property:opacity;width:-moz-fit-content;width:fit-content;max-width:80%;pointer-events:auto}.hashicorp-consul .consul-side-nav li.consul-disabled-nav{width:100%;min-height:var(--token-side-nav-body-list-item-height);padding:var(--token-side-nav-body-list-item-padding-vertical) var(--token-side-nav-body-list-item-padding-horizontal);color:var(--token-color-foreground-disabled)}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .consul-side-nav__selector-toggle{min-width:15.5rem}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .consul-side-nav__selector-toggle:disabled{color:var(--token-color-foreground-disabled);border-color:var(--token-color-border-primary)}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .consul-side-nav__selector-toggle:disabled:hover{background-color:transparent}.hashicorp-consul .consul-side-nav li.consul-side-nav__selector .hds-dropdown__content{min-width:15.5rem;max-height:500px}.hashicorp-consul .consul-side-nav .hds-side-nav__wrapper-body{overflow-y:unset;overflow-x:unset}.hashicorp-consul .consul-side-nav li.consul-side-nav__datacenter{display:flex;gap:.5rem;align-items:center;padding-left:.5rem}.hashicorp-consul .consul-side-nav .consul-side-nav__selector-group{margin-bottom:1.5rem}.hashicorp-consul .consul-side-nav .consul-datacenter-selector__dc-name{display:flex;align-items:center;gap:.5rem}.hashicorp-consul .consul-side-nav .consul-datacenter-selector__dc-name .consul-datacenter-selector__badges{display:flex;gap:.25rem}.hashicorp-consul .consul-side-nav .consul-side-nav__selector-title{margin-top:.5rem}.hashicorp-consul .consul-side-nav .consul-side-nav__selector-description{padding-top:.5rem}.disclosure-menu [aria-expanded]~*>div+ul,.menu-panel>div+ul,.more-popover-menu>[type=checkbox]+label+div>div+ul,.popover-menu>[type=checkbox]+label+div>div+ul,table.has-actions tr>.actions>[type=checkbox]+label+div>div+ul,table.with-details tr>.actions>[type=checkbox]+label+div>div+ul{border-top:var(--decor-border-100);border-color:var(--token-form--base-border-color-default)}.disclosure-menu [aria-expanded]~* [role=separator]:first-child:not(:empty),.menu-panel [role=separator]:first-child:not(:empty),.more-popover-menu>[type=checkbox]+label+div [role=separator]:first-child:not(:empty),.popover-menu>[type=checkbox]+label+div [role=separator]:first-child:not(:empty),table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator]:first-child:not(:empty),table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]:first-child:not(:empty){border:none}.disclosure-menu [aria-expanded]~*>ul>li,.menu-panel>ul>li,.more-popover-menu>[type=checkbox]+label+div>ul>li,.popover-menu>[type=checkbox]+label+div>ul>li,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li{list-style-type:none}.disclosure-menu [aria-expanded]~*>ul .informed-action,.menu-panel>ul .informed-action,.more-popover-menu>[type=checkbox]+label+div>ul .informed-action,.popover-menu>[type=checkbox]+label+div>ul .informed-action,table.has-actions tr>.actions>[type=checkbox]+label+div>ul .informed-action,table.with-details tr>.actions>[type=checkbox]+label+div>ul .informed-action{border:0!important}.disclosure-menu [aria-expanded]~*>div,.menu-panel>div,.more-popover-menu>[type=checkbox]+label+div>div,.popover-menu>[type=checkbox]+label+div>div,table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div>div{padding:.625rem var(--padding-x);white-space:normal;max-width:-moz-fit-content;max-width:fit-content}@supports not ((max-width:-moz-fit-content) or (max-width:fit-content)){.disclosure-menu [aria-expanded]~*>div,.menu-panel>div,.more-popover-menu>[type=checkbox]+label+div>div,.popover-menu>[type=checkbox]+label+div>div,table.has-actions tr>.actions>[type=checkbox]+label+div>div,table.with-details tr>.actions>[type=checkbox]+label+div>div{max-width:200px}}.disclosure-menu [aria-expanded]~*>div::before,.menu-panel>div::before,.more-popover-menu>[type=checkbox]+label+div>div::before,.popover-menu>[type=checkbox]+label+div>div::before,table.has-actions tr>.actions>[type=checkbox]+label+div>div::before,table.with-details tr>.actions>[type=checkbox]+label+div>div::before{position:absolute;left:15px;top:calc(10px + .1em)}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]+*,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]+*,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]+*,.menu-panel-deprecated>ul>li>div[role=menu],.menu-panel>ul>[role=treeitem]+*,.menu-panel>ul>li>[role=menuitem]+*,.menu-panel>ul>li>[role=option]+*,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]+*,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]+*,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]+*,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]+*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]+*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]+*,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]+*,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]+*,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]+*{position:absolute;top:0;left:calc(100% + 10px)}.disclosure-menu [aria-expanded]~*>ul,.menu-panel>ul,.more-popover-menu>[type=checkbox]+label+div>ul,.popover-menu>[type=checkbox]+label+div>ul,table.has-actions tr>.actions>[type=checkbox]+label+div>ul,table.with-details tr>.actions>[type=checkbox]+label+div>ul{margin:0;padding:calc(var(--padding-y) - .625rem) 0;transition:transform 150ms}.disclosure-menu [aria-expanded]~*>ul,.disclosure-menu [aria-expanded]~*>ul>li,.disclosure-menu [aria-expanded]~*>ul>li>*,.menu-panel>ul,.menu-panel>ul>li,.menu-panel>ul>li>*,.more-popover-menu>[type=checkbox]+label+div>ul,.more-popover-menu>[type=checkbox]+label+div>ul>li,.more-popover-menu>[type=checkbox]+label+div>ul>li>*,.popover-menu>[type=checkbox]+label+div>ul,.popover-menu>[type=checkbox]+label+div>ul>li,.popover-menu>[type=checkbox]+label+div>ul>li>*,table.has-actions tr>.actions>[type=checkbox]+label+div>ul,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>*,table.with-details tr>.actions>[type=checkbox]+label+div>ul,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>*{width:100%}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem],.disclosure-menu [aria-expanded]~*>ul>li>[role=option],.menu-panel>ul>[role=treeitem],.menu-panel>ul>li>[role=menuitem],.menu-panel>ul>li>[role=option],.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option],.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem],.popover-menu>[type=checkbox]+label+div>ul>li>[role=option],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option],table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem],table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]{display:flex}.disclosure-menu [aria-expanded]~*>ul>[role=treeitem]::after,.disclosure-menu [aria-expanded]~*>ul>li>[role=menuitem]::after,.disclosure-menu [aria-expanded]~*>ul>li>[role=option]::after,.menu-panel>ul>[role=treeitem]::after,.menu-panel>ul>li>[role=menuitem]::after,.menu-panel>ul>li>[role=option]::after,.more-popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]::after,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,.more-popover-menu>[type=checkbox]+label+div>ul>li>[role=option]::after,.popover-menu>[type=checkbox]+label+div>ul>[role=treeitem]::after,.popover-menu>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,.popover-menu>[type=checkbox]+label+div>ul>li>[role=option]::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>[role=treeitem]::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=menuitem]::after,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li>[role=option]::after{margin-left:auto;padding-right:var(--padding-x);transform:translate(calc(var(--padding-x)/ 2),0)}.disclosure-menu [aria-expanded]~* [role=separator],.menu-panel [role=separator],.more-popover-menu>[type=checkbox]+label+div [role=separator],.popover-menu>[type=checkbox]+label+div [role=separator],table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator],table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]{text-transform:uppercase;color:var(--token-color-foreground-faint);padding-top:.375rem}.disclosure-menu [aria-expanded]~* [role=separator]:not(:first-child),.menu-panel [role=separator]:not(:first-child),.more-popover-menu>[type=checkbox]+label+div [role=separator]:not(:first-child),.popover-menu>[type=checkbox]+label+div [role=separator]:not(:first-child),table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator]:not(:first-child),table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]:not(:first-child){margin-top:.275rem}.disclosure-menu [aria-expanded]~* [role=separator]:not(:empty),.menu-panel [role=separator]:not(:empty),.more-popover-menu>[type=checkbox]+label+div [role=separator]:not(:empty),.popover-menu>[type=checkbox]+label+div [role=separator]:not(:empty),table.has-actions tr>.actions>[type=checkbox]+label+div [role=separator]:not(:empty),table.with-details tr>.actions>[type=checkbox]+label+div [role=separator]:not(:empty){padding-left:var(--padding-x);padding-right:var(--padding-x);padding-bottom:.125rem}.disclosure-menu [aria-expanded]~.menu-panel-confirming,.menu-panel-confirming.menu-panel,.more-popover-menu>[type=checkbox]+label+div.menu-panel-confirming,.popover-menu>[type=checkbox]+label+div.menu-panel-confirming,table.has-actions tr>.actions>[type=checkbox]+label+div.menu-panel-confirming,table.with-details tr>.actions>[type=checkbox]+label+div.menu-panel-confirming{overflow:hidden}.disclosure-menu [aria-expanded]~.menu-panel-confirming>ul,.menu-panel-confirming.menu-panel>ul,.more-popover-menu>[type=checkbox]+label+div.menu-panel-confirming>ul,.popover-menu>[type=checkbox]+label+div.menu-panel-confirming>ul,table.has-actions tr>.actions>[type=checkbox]+label+div.menu-panel-confirming>ul,table.with-details tr>.actions>[type=checkbox]+label+div.menu-panel-confirming>ul{transform:translateX(calc(-100% - 10px))}.disclosure-menu [aria-expanded]~*,.menu-panel,.more-popover-menu>[type=checkbox]+label+div,.popover-menu>[type=checkbox]+label+div,table.has-actions tr>.actions>[type=checkbox]+label+div,table.with-details tr>.actions>[type=checkbox]+label+div{overflow:hidden}.menu-panel-deprecated{position:absolute;transition:max-height 150ms;transition:min-height 150ms,max-height 150ms;min-height:0}.menu-panel-deprecated [type=checkbox]{display:none}.menu-panel-deprecated:not(.confirmation) [type=checkbox]~*{transition:transform 150ms}.confirmation.menu-panel-deprecated [role=menu]{min-height:205px!important}.menu-panel-deprecated [type=checkbox]:checked~*{transform:translateX(calc(-100% - 10px));min-height:143px;max-height:143px}.menu-panel-deprecated [id$="-"]:first-child:checked~ul label[for$="-"] * [role=menu],.menu-panel-deprecated [id$="-"]:first-child:checked~ul>li>[role=menu]{display:block}.menu-panel-deprecated>ul>li>:not(div[role=menu]),.tippy-box{position:relative}.menu-panel-deprecated:not(.left){right:0!important;left:auto!important}.left.menu-panel-deprecated{left:0}.menu-panel-deprecated:not(.above){top:28px}.above.menu-panel-deprecated{bottom:42px}.consul-upstream-instance-list dl.local-bind-socket-mode dt::after{display:inline;content:var(--horizontal-kv-list-key-separator)}.consul-bucket-list,.consul-exposed-path-list>ul>li>.detail dl,.consul-instance-checks,.consul-lock-session-list dl,.consul-lock-session-list ul>li:not(:first-child)>.detail dl,.consul-upstream-instance-list dl,.consul-upstream-instance-list li>.detail dl,.list-collection>ul>li:not(:first-child)>.detail dl,.tag-list,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl,section[data-route="dc.show.license"] .validity dl,td.tags{display:inline-flex;flex-wrap:nowrap;align-items:center}.consul-bucket-list:empty,.consul-exposed-path-list>ul>li>.detail dl:empty,.consul-instance-checks:empty,.consul-lock-session-list dl:empty,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:empty,.consul-upstream-instance-list dl:empty,.list-collection>ul>li:not(:first-child)>.detail dl:empty,.tag-list:empty,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:empty,section[data-route="dc.show.license"] .validity dl:empty,td.tags:empty{display:none}.consul-bucket-list>*>*,.consul-exposed-path-list>ul>li>.detail dl>*>*,.consul-instance-checks>*>*,.consul-lock-session-list dl>*>*,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>*>*,.consul-upstream-instance-list dl>*>*,.consul-upstream-instance-list li>.detail dl>*>*,.list-collection>ul>li:not(:first-child)>.detail dl>*>*,.tag-list>*>*,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl>*>*,section[data-route="dc.show.license"] .validity dl>*>*,td.tags>*>*{display:inline-block}.consul-bucket-list>*,.consul-exposed-path-list>ul>li>.detail dl>*,.consul-instance-checks>*,.consul-lock-session-list dl>*,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>*,.consul-upstream-instance-list dl>*,.consul-upstream-instance-list li>.detail dl>*,.list-collection>ul>li:not(:first-child)>.detail dl>*,.tag-list>*,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl>*,section[data-route="dc.show.license"] .validity dl>*,td.tags>*{white-space:nowrap}.consul-bucket-list>dd,.consul-exposed-path-list>ul>li>.detail dl>dd,.consul-instance-checks>dd,.consul-lock-session-list dl>dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>dd,.consul-upstream-instance-list dl>dd,.consul-upstream-instance-list li>.detail dl>dd,.list-collection>ul>li:not(:first-child)>.detail dl>dd,.tag-list>dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl>dd,section[data-route="dc.show.license"] .validity dl>dd,td.tags>dd{flex-wrap:wrap}.consul-upstream-instance-list dl.local-bind-socket-mode dt{display:inline-flex;min-width:18px;overflow:hidden}.consul-lock-session-list .checks dd,.discovery-chain .resolver-card ol,.filter-bar,.filter-bar>div,.modal-dialog,.tag-list dd,td.tags dd{display:flex}.consul-bucket-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-bucket-list .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-bucket-list .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-bucket-list .tag-list:not([class]) dd+dt:not([class])+dd,.consul-bucket-list dd+dt,.consul-bucket-list td.tags:not([class]) dd+dt:not([class])+dd,.consul-bucket-list+.consul-bucket-list:not(:first-of-type),.consul-bucket-list+.consul-instance-checks:not(:first-of-type),.consul-bucket-list+.tag-list:not(:first-of-type),.consul-bucket-list+td.tags:not(:first-of-type),.consul-bucket-list:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-bucket-list:not([class]) .tag-list dd+dt:not([class])+dd,.consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-bucket-list:not([class]) td.tags dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail .consul-bucket-list+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-instance-checks+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-lock-session-list dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-exposed-path-list>ul>li>.detail .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-exposed-path-list>ul>li>.detail .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail .tag-list+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl dd+dt,.consul-exposed-path-list>ul>li>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl+.consul-bucket-list:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+.consul-instance-checks:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+.tag-list:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl+td.tags:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-exposed-path-list>ul>li>.detail td.tags+dl:not(:first-of-type),.consul-instance-checks .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-instance-checks .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-instance-checks .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-instance-checks .tag-list:not([class]) dd+dt:not([class])+dd,.consul-instance-checks dd+dt,.consul-instance-checks td.tags:not([class]) dd+dt:not([class])+dd,.consul-instance-checks+.consul-bucket-list:not(:first-of-type),.consul-instance-checks+.consul-instance-checks:not(:first-of-type),.consul-instance-checks+.tag-list:not(:first-of-type),.consul-instance-checks+td.tags:not(:first-of-type),.consul-instance-checks:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-instance-checks:not([class]) .tag-list dd+dt:not([class])+dd,.consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-instance-checks:not([class]) td.tags dd+dt:not([class])+dd,.consul-lock-session-list .consul-bucket-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-bucket-list+dl:not(:first-of-type),.consul-lock-session-list .consul-bucket-list:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-instance-checks ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-instance-checks+dl:not(:first-of-type),.consul-lock-session-list .consul-instance-checks:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-lock-session-list .consul-upstream-instance-list dl.local-bind-address dl dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list dl.local-bind-socket-path dl dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl.local-bind-address dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl.local-bind-socket-path dd+dt+dd,.consul-lock-session-list .consul-upstream-instance-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .list-collection>ul>li:not(:first-child)>.detail ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .tag-list dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .tag-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list .tag-list+dl:not(:first-of-type),.consul-lock-session-list .tag-list:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list .tag-list:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-lock-session-list dl .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-lock-session-list dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl dd+dt,.consul-lock-session-list dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl+.consul-bucket-list:not(:first-of-type),.consul-lock-session-list dl+.consul-instance-checks:not(:first-of-type),.consul-lock-session-list dl+.tag-list:not(:first-of-type),.consul-lock-session-list dl+dl:not(:first-of-type),.consul-lock-session-list dl+td.tags:not(:first-of-type),.consul-lock-session-list dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-lock-session-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-lock-session-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.license"] .validity dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-lock-session-list section[data-route="dc.show.license"] .validity dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list td.tags dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list td.tags ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list td.tags+dl:not(:first-of-type),.consul-lock-session-list td.tags:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list td.tags:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-bucket-list+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-instance-checks+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail .tag-list+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt,.consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl+.consul-bucket-list:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+.consul-instance-checks:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+.tag-list:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl+td.tags:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-lock-session-list ul>li:not(:first-child)>.detail td.tags+dl:not(:first-of-type),.consul-upstream-instance-list .consul-bucket-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-bucket-list+dl:not(:first-of-type),.consul-upstream-instance-list .consul-bucket-list:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-instance-checks li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-instance-checks+dl:not(:first-of-type),.consul-upstream-instance-list .consul-instance-checks:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list dl+dl:not(:first-of-type),.consul-upstream-instance-list .consul-lock-session-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .list-collection>ul>li:not(:first-child)>.detail li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list+dl:not(:first-of-type),.consul-upstream-instance-list .tag-list:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list .tag-list:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl dd+dt,.consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl+.consul-bucket-list:not(:first-of-type),.consul-upstream-instance-list dl+.consul-instance-checks:not(:first-of-type),.consul-upstream-instance-list dl+.tag-list:not(:first-of-type),.consul-upstream-instance-list dl+dl:not(:first-of-type),.consul-upstream-instance-list dl+td.tags:not(:first-of-type),.consul-upstream-instance-list dl.local-bind-address .consul-bucket-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address .consul-instance-checks dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address .consul-lock-session-list dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address .tag-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address section[data-route="dc.show.license"] .validity dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-address td.tags dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .consul-bucket-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .consul-instance-checks dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .consul-lock-session-list dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path .tag-list dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path section[data-route="dc.show.license"] .validity dl dd+dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path td.tags dd+dt+dd,.consul-upstream-instance-list dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail .consul-bucket-list+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail .consul-instance-checks+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail .consul-lock-session-list dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail .tag-list+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl dd+dt,.consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl+.consul-bucket-list:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+.consul-instance-checks:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+.tag-list:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail dl+td.tags:not(:first-of-type),.consul-upstream-instance-list li>.detail dl.local-bind-address dd+dt+dd,.consul-upstream-instance-list li>.detail dl.local-bind-socket-path dd+dt+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.consul-upstream-instance-list li>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-upstream-instance-list li>.detail td.tags+dl:not(:first-of-type),.consul-upstream-instance-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.consul-upstream-instance-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list section[data-route="dc.show.license"] .validity dl li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.consul-upstream-instance-list section[data-route="dc.show.license"] .validity dl:not([class]) li>.detail dl dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags li>.detail dl:not([class]) dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags+dl:not(:first-of-type),.consul-upstream-instance-list td.tags:not([class]) dl dd+dt:not([class])+dd,.consul-upstream-instance-list td.tags:not([class]) li>.detail dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-bucket-list+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-instance-checks+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-lock-session-list dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.list-collection>ul>li:not(:first-child)>.detail .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail .tag-list+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl .tag-list:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl dd+dt,.list-collection>ul>li:not(:first-child)>.detail dl section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl td.tags:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl+.consul-bucket-list:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+.consul-instance-checks:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+.tag-list:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl+td.tags:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) .tag-list dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) td.tags dd+dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),.list-collection>ul>li:not(:first-child)>.detail td.tags+dl:not(:first-of-type),.tag-list .consul-bucket-list:not([class]) dd+dt:not([class])+dd,.tag-list .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-instance-checks:not([class]) dd+dt:not([class])+dd,.tag-list .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,.tag-list .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,.tag-list .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,.tag-list .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,.tag-list dd+dt,.tag-list section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,.tag-list section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,.tag-list td.tags:not([class]) dd+dt:not([class])+dd,.tag-list+.consul-bucket-list:not(:first-of-type),.tag-list+.consul-instance-checks:not(:first-of-type),.tag-list+.tag-list:not(:first-of-type),.tag-list+td.tags:not(:first-of-type),.tag-list:not([class]) .consul-bucket-list dd+dt:not([class])+dd,.tag-list:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-instance-checks dd+dt:not([class])+dd,.tag-list:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,.tag-list:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,.tag-list:not([class]) dd+dt:not([class])+dd,.tag-list:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,.tag-list:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd,.tag-list:not([class]) td.tags dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-bucket-list+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-instance-checks+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl.local-bind-address dl dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl.local-bind-socket-path dl dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .tag-list dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header .tag-list+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header .tag-list:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl .tag-list:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl td.tags:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+.consul-bucket-list:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+.consul-instance-checks:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+.tag-list:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl+td.tags:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) .tag-list dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) td.tags dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header td.tags dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header td.tags+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section header td.tags:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section[data-route="dc.show.license"] .validity header dl+dl:not(:first-of-type),section[data-route="dc.show.serverstatus"] .redundancy-zones section[data-route="dc.show.license"] header .validity dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-bucket-list+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-exposed-path-list>ul>li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-exposed-path-list>ul>li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-exposed-path-list>ul>li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-instance-checks+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-lock-session-list dl ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-lock-session-list dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-lock-session-list dl:not([class]) ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-lock-session-list ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-lock-session-list ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl.local-bind-address dl dd+dt+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl.local-bind-socket-path dl dd+dt+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list dl:not([class]) li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list li>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .consul-upstream-instance-list li>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .consul-upstream-instance-list li>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .list-collection>ul>li:not(:first-child)>.detail dl dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .list-collection>ul>li:not(:first-child)>.detail dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .tag-list dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity .tag-list+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity .tag-list:not([class]) dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,section[data-route="dc.show.license"] .validity dl .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,section[data-route="dc.show.license"] .validity dl .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl .tag-list:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl dd+dt,section[data-route="dc.show.license"] .validity dl td.tags:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl+.consul-bucket-list:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+.consul-instance-checks:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+.tag-list:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity dl+td.tags:not(:first-of-type),section[data-route="dc.show.license"] .validity dl:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) .tag-list dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) td.tags dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity td.tags dl:not([class]) dd+dt:not([class])+dd,section[data-route="dc.show.license"] .validity td.tags+dl:not(:first-of-type),section[data-route="dc.show.license"] .validity td.tags:not([class]) dl dd+dt:not([class])+dd,td.tags .consul-bucket-list:not([class]) dd+dt:not([class])+dd,td.tags .consul-exposed-path-list>ul>li>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-instance-checks:not([class]) dd+dt:not([class])+dd,td.tags .consul-lock-session-list dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-lock-session-list ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-upstream-instance-list dl.local-bind-address dd+dt+dd,td.tags .consul-upstream-instance-list dl.local-bind-socket-path dd+dt+dd,td.tags .consul-upstream-instance-list dl:not([class]) dd+dt:not([class])+dd,td.tags .consul-upstream-instance-list li>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dd+dt:not([class])+dd,td.tags .tag-list:not([class]) dd+dt:not([class])+dd,td.tags dd+dt,td.tags section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dd+dt:not([class])+dd,td.tags section[data-route="dc.show.license"] .validity dl:not([class]) dd+dt:not([class])+dd,td.tags+.consul-bucket-list:not(:first-of-type),td.tags+.consul-instance-checks:not(:first-of-type),td.tags+.tag-list:not(:first-of-type),td.tags+td.tags:not(:first-of-type),td.tags:not([class]) .consul-bucket-list dd+dt:not([class])+dd,td.tags:not([class]) .consul-exposed-path-list>ul>li>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-instance-checks dd+dt:not([class])+dd,td.tags:not([class]) .consul-lock-session-list dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-lock-session-list ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-upstream-instance-list dl dd+dt:not([class])+dd,td.tags:not([class]) .consul-upstream-instance-list li>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .list-collection>ul>li:not(:first-child)>.detail dl dd+dt:not([class])+dd,td.tags:not([class]) .tag-list dd+dt:not([class])+dd,td.tags:not([class]) dd+dt:not([class])+dd,td.tags:not([class]) section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dd+dt:not([class])+dd,td.tags:not([class]) section[data-route="dc.show.license"] .validity dl dd+dt:not([class])+dd{margin-left:var(--horizontal-kv-list-separator-width)}.consul-bucket-list dt+dd,.consul-exposed-path-list>ul>li>.detail dl dt+dd,.consul-instance-checks dt+dd,.consul-lock-session-list dl dt+dd,.consul-lock-session-list ul>li:not(:first-child)>.detail dl dt+dd,.consul-upstream-instance-list dl dt+dd,.consul-upstream-instance-list li>.detail dl dt+dd,.list-collection>ul>li:not(:first-child)>.detail dl dt+dd,.tag-list dt+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl dt+dd,section[data-route="dc.show.license"] .validity dl dt+dd,td.tags dt+dd{margin-left:4px}.consul-bucket-list:not([class]) dt:not([class])+dd,.consul-exposed-path-list>ul>li>.detail dl:not([class]) dt:not([class])+dd,.consul-instance-checks:not([class]) dt:not([class])+dd,.consul-lock-session-list dl:not([class]) dt:not([class])+dd,.consul-upstream-instance-list dl.local-bind-address dt+dd,.consul-upstream-instance-list dl.local-bind-socket-path dt+dd,.consul-upstream-instance-list dl:not([class]) dt:not([class])+dd,.list-collection>ul>li:not(:first-child)>.detail dl:not([class]) dt:not([class])+dd,.tag-list:not([class]) dt:not([class])+dd,section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not([class]) dt:not([class])+dd,section[data-route="dc.show.license"] .validity dl:not([class]) dt:not([class])+dd,td.tags:not([class]) dt:not([class])+dd{margin-left:0!important}.consul-lock-session-list .checks dd>:not(:last-child)::after,.discovery-chain .resolver-card ol>:not(:last-child)::after,.tag-list dd>:not(:last-child)::after,td.tags dd>:not(:last-child)::after{display:inline;content:var(--csv-list-separator);vertical-align:initial;margin-right:.3em}.freetext-filter_label::after,.tippy-box .tippy-arrow::before{content:"";position:absolute}.tag-list dt::before,td.tags dt::before{color:inherit;color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul>li>.detail dl>dt>*,.consul-lock-session-list ul>li:not(:first-child)>.detail dl>dt>*,.consul-upstream-instance-list li>.detail dl>dt>*,.list-collection>ul>li:not(:first-child)>.detail dl>dt>*{display:none}.consul-exposed-path-list>ul>li>.detail dl.passing dt::before,.consul-exposed-path-list>ul>li>.header .passing dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.passing dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .passing dd::before,.consul-upstream-instance-list li>.detail dl.passing dt::before,.consul-upstream-instance-list li>.header .passing dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.passing dt::before,.list-collection>ul>li:not(:first-child)>.header .passing dd::before{color:var(--token-color-foreground-success)}.consul-exposed-path-list>ul>li>.detail dl.warning dt::before,.consul-exposed-path-list>ul>li>.header .warning dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.warning dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .warning dd::before,.consul-upstream-instance-list li>.detail dl.warning dt::before,.consul-upstream-instance-list li>.header .warning dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.warning dt::before,.list-collection>ul>li:not(:first-child)>.header .warning dd::before{color:var(--token-color-foreground-warning)}.consul-exposed-path-list>ul>li>.detail dl.critical dt::before,.consul-exposed-path-list>ul>li>.header .critical dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.critical dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .critical dd::before,.consul-upstream-instance-list li>.detail dl.critical dt::before,.consul-upstream-instance-list li>.header .critical dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.critical dt::before,.list-collection>ul>li:not(:first-child)>.header .critical dd::before{color:var(--token-color-foreground-critical)}.consul-exposed-path-list>ul>li>.detail dl.empty dt::before,.consul-exposed-path-list>ul>li>.detail dl.unknown dt::before,.consul-exposed-path-list>ul>li>.header .empty dd::before,.consul-exposed-path-list>ul>li>.header .unknown dd::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.empty dt::before,.consul-lock-session-list ul>li:not(:first-child)>.detail dl.unknown dt::before,.consul-lock-session-list ul>li:not(:first-child)>.header .empty dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header .unknown dd::before,.consul-upstream-instance-list li>.detail dl.empty dt::before,.consul-upstream-instance-list li>.detail dl.unknown dt::before,.consul-upstream-instance-list li>.header .empty dd::before,.consul-upstream-instance-list li>.header .unknown dd::before,.list-collection>ul>li:not(:first-child)>.detail dl.empty dt::before,.list-collection>ul>li:not(:first-child)>.detail dl.unknown dt::before,.list-collection>ul>li:not(:first-child)>.header .empty dd::before,.list-collection>ul>li:not(:first-child)>.header .unknown dd::before{color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul>li>.header [rel=me] dd::before,.consul-lock-session-list ul>li:not(:first-child)>.header [rel=me] dd::before,.consul-upstream-instance-list li>.header [rel=me] dd::before,.list-collection>ul>li:not(:first-child)>.header [rel=me] dd::before{color:var(--token-color-foreground-action)}.app-view>div form:not(.filter-bar) [role=radiogroup] label>em>code,.modal-dialog [role=document] .type-password>em>code,.modal-dialog [role=document] .type-select>em>code,.modal-dialog [role=document] .type-text>em>code,.modal-dialog [role=document] [role=radiogroup] label>em>code,.modal-dialog [role=document] form button+em>code,.modal-dialog [role=document] p code,.oidc-select label>em>code,.type-toggle>em>code,main .type-password>em>code,main .type-select>em>code,main .type-text>em>code,main form button+em>code,main p code{border:1px solid;color:var(--token-color-consul-brand);background-color:var(--token-color-surface-strong);border-color:var(--token-color-surface-interactive-active);display:inline-block;padding:0 4px}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{outline:0;background-color:var(--token-color-surface-primary);border-radius:var(--decor-radius-100)}[data-animation=fade][data-state=hidden].tippy-box{opacity:0}[data-inertia][data-state=visible].tippy-box{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-box .tippy-arrow{--size:5px}[data-placement^=top].tippy-box>.tippy-arrow{bottom:0}[data-placement^=top].tippy-box>.tippy-arrow::before{left:0;bottom:calc(0px - var(--size));transform-origin:center top}[data-placement^=bottom].tippy-box>.tippy-arrow{top:0}[data-placement^=bottom].tippy-box>.tippy-arrow::before{left:0;top:calc(0px - var(--size));transform-origin:center bottom}[data-placement^=left].tippy-box>.tippy-arrow{right:0}[data-placement^=left].tippy-box>.tippy-arrow::before{right:calc(0px - var(--size));transform-origin:center left}[data-placement^=right].tippy-box>.tippy-arrow{left:0}[data-placement^=right].tippy-box>.tippy-arrow::before{left:calc(0px - var(--size));transform-origin:center right}[data-theme~=square-tail] .tippy-arrow{--size:18px;left:calc(0px - var(--size)/ 2)!important}[data-theme~=square-tail] .tippy-arrow::before{background-color:var(--token-color-surface-primary);width:calc(1px + var(--size));height:calc(1px + var(--size));border:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300)}[data-theme~=square-tail] .tippy-arrow::after{position:absolute;left:1px}[data-theme~=square-tail][data-placement^=top]{bottom:-10px}[data-theme~=square-tail][data-placement^=top] .informed-action{border-bottom-left-radius:0!important}[data-theme~=square-tail][data-placement^=top] .tippy-arrow::before{border-bottom-left-radius:var(--decor-radius-200);border-bottom-right-radius:var(--decor-radius-200);border-top:0!important}[data-theme~=square-tail][data-placement^=top] .tippy-arrow::after{bottom:calc(0px - var(--size))}[data-theme~=square-tail][data-placement^=bottom]{top:-10px}[data-theme~=square-tail][data-placement^=bottom] .informed-action{border-top-left-radius:0!important}[data-theme~=square-tail][data-placement^=bottom] .tippy-arrow::before{border-top-left-radius:var(--decor-radius-200);border-top-right-radius:var(--decor-radius-200);border-bottom:0!important}[data-theme~=square-tail][data-placement^=bottom] .tippy-arrow::after{top:calc(0px - var(--size))}.tippy-box[data-theme~=tooltip] .tippy-content{padding:12px;max-width:224px;position:relative;z-index:1}.tippy-box[data-theme~=tooltip]{background-color:var(--token-color-foreground-faint)}.tippy-box[data-theme~=tooltip] .tippy-arrow{--size:5px;color:var(--token-color-foreground-faint);width:calc(var(--size) * 2);height:calc(var(--size) * 2)}.tippy-box[data-theme~=tooltip] .tippy-arrow::before{border-color:transparent;border-style:solid}.tippy-box[data-theme~=tooltip][data-placement^=top]>.tippy-arrow::before{border-width:var(--size) var(--size) 0;border-top-color:initial}.tippy-box[data-theme~=tooltip][data-placement^=bottom]>.tippy-arrow::before{border-width:0 var(--size) var(--size);border-bottom-color:initial}.tippy-box[data-theme~=tooltip][data-placement^=left]>.tippy-arrow::before{border-width:var(--size) 0 var(--size) var(--size);border-left-color:initial}.tippy-box[data-theme~=tooltip][data-placement^=right]>.tippy-arrow::before{border-width:var(--size) var(--size) var(--size) 0;border-right-color:initial}.warning.modal-dialog header{background-color:var(--token-color-vault-gradient-faint-start);border-color:var(--token-color-vault-brand);color:var(--token-color-vault-foreground)}.warning.modal-dialog header::before{color:var(--token-color-vault-brand);float:left;margin-top:2px;margin-right:3px}.modal-dialog>div:first-child{background-color:var(--token-color-surface-interactive);opacity:.9}.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,.modal-dialog-body{border-color:var(--token-color-palette-neutral-300)}.modal-dialog-body{border-style:solid;border-left-width:1px;border-right-width:1px}.modal-layer{height:0}.modal-dialog [role=document] table{height:150px!important}.modal-dialog [role=document] tbody{max-height:100px}.modal-dialog table{min-height:149px}.modal-dialog,.modal-dialog>div:first-child{position:fixed;top:0;right:0;bottom:0;left:0}.modal-dialog{z-index:500;align-items:center;justify-content:center;height:100%}[aria-hidden=true].modal-dialog{display:none}.modal-dialog [role=document]{background-color:var(--token-color-surface-primary);margin:auto;z-index:2;max-width:855px;position:relative}.modal-dialog [role=document]>*{padding-left:15px;padding-right:15px}.modal-dialog [role=document]>div{overflow-y:auto;max-height:80vh;padding:20px 23px}.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header{border-width:1px;padding-top:12px;padding-bottom:10px}.modal-dialog [role=document]>header{position:relative}.modal-dialog [role=document]>header button{float:right;margin-top:-3px}.list-collection>ul{border-top:1px solid;border-color:var(--token-color-surface-interactive-active)}.list-collection>button{cursor:pointer;background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-action);width:100%;padding:15px}.list-collection-scroll-virtual,.list-collection>ul>li{position:relative}.list-collection-scroll-virtual{height:500px}.filter-bar{background-color:var(--token-color-foreground-high-contrast);border-bottom:var(--decor-border-100);border-color:var(--token-color-surface-interactive-active);padding:4px 8px}.filter-bar .filters .popover-menu>[type=checkbox]:checked+label button,.filter-bar .sort .popover-menu>[type=checkbox]:checked+label button{color:var(--token-color-foreground-action);background-color:var(--token-color-foreground-high-contrast)}.filter-bar .sort{margin-left:auto}.filter-bar .popover-select{position:relative;z-index:3}.filter-bar .popover-menu>[type=checkbox]+label button{padding-left:1.5rem!important;padding-right:1.5rem!important}.filter-bar .popover-menu [role=menuitem]{justify-content:normal!important}@media (max-width:1379px){.filter-bar,.filter-bar>div{flex-wrap:wrap}.filter-bar .search{position:relative;z-index:4;width:100%;margin-bottom:.3rem}}@media (max-width:995px){.filter-bar .filters,.filter-bar .sort{display:none}}html[data-route^="dc.acls.index"] .filter-bar{color:inherit}.freetext-filter{border:var(--decor-border-100);border-radius:var(--decor-radius-100);background-color:var(--token-color-surface-primary);border-color:var(--token-color-surface-interactive-active);color:var(--token-color-foreground-disabled)}.freetext-filter:hover,.freetext-filter:hover *{border-color:var(--token-color-foreground-disabled)}.freetext-filter_input::-moz-placeholder{cursor:inherit;color:inherit;border-color:inherit}.freetext-filter *,.freetext-filter_input::placeholder{cursor:inherit;color:inherit;border-color:inherit}.freetext-filter_input{-webkit-appearance:none;border:none}.freetext-filter_label::after{visibility:visible;--icon-name:icon-search;top:50%;left:50%;width:16px;height:16px;margin-left:-8px;margin-top:-8px}.freetext-filter .popover-menu{background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-primary);border-left:1px solid;border-color:inherit}.freetext-filter .popover-menu>[type=checkbox]:checked+label button{background-color:var(--token-color-surface-interactive-active)}.freetext-filter{--height:2.2rem;display:flex;position:relative;height:var(--height);width:100%}.freetext-filter_input,.freetext-filter_label{height:100%}.freetext-filter_input{padding:8px 10px;padding-left:var(--height);min-width:12.7rem;width:100%}.freetext-filter_label{visibility:hidden;position:absolute;z-index:1;width:var(--height)}.informed-action{border-radius:var(--decor-radius-200);border:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300);background-color:var(--token-color-surface-primary);min-width:190px}.informed-action>div{border-top-left-radius:var(--decor-radius-200);border-top-right-radius:var(--decor-radius-200);cursor:default;padding:1rem}.informed-action p{color:var(--token-color-hashicorp-brand)}.informed-action>ul>li>:focus,.informed-action>ul>li>:hover{background-color:var(--token-color-surface-strong)}.info.informed-action header{color:var(--token-color-foreground-action-active)}.info.informed-action header::before{background-color:var(--token-color-foreground-action);margin-right:5px}.info.informed-action>div{background-color:var(--token-color-surface-action)}.dangerous.informed-action header{color:var(--token-color-palette-red-400)}.dangerous.informed-action header::before{background-color:var(--token-color-foreground-critical)}.dangerous.informed-action>div{background-color:var(--token-color-surface-critical)}.warning.informed-action header{color:var(--token-color-foreground-warning-on-surface)}.warning.informed-action header::before{background-color:var(--token-color-vault-brand);margin-right:5px}.warning.informed-action>div{background-color:var(--token-color-vault-gradient-faint-start)}.copyable-code::after,.tab-nav li:not(.selected)>:active,.tab-nav li:not(.selected)>:focus,.tab-nav li:not(.selected)>:hover{background-color:var(--token-color-surface-strong)}.informed-action>ul>.action>*{color:var(--token-color-foreground-action)}.documentation.informed-action{min-width:270px}.informed-action header::before{float:left;margin-right:5px}.informed-action>ul{list-style:none;display:flex;margin:0;padding:4px}.informed-action>ul>li{width:50%}.informed-action>ul>li>*{width:100%}.tab-nav ul{list-style-type:none;display:inline-flex;align-items:center;position:relative;padding:0;margin:0}.tab-nav li>:not(:disabled){cursor:pointer}.tab-nav{border-bottom:var(--decor-border-100)}.animatable.tab-nav ul::after,.tab-nav li>*{border-bottom:var(--decor-border-300)}.tab-nav{border-color:var(--token-color-surface-interactive-active);clear:both;overflow:auto}.tab-nav li>*{white-space:nowrap;text-decoration:none;transition-property:background-color,border-color;border-color:transparent;color:var(--token-color-foreground-faint);display:inline-block;padding:16px 13px}.tab-nav li:not(.selected)>:focus,.tab-nav li:not(.selected)>:hover{border-color:var(--token-color-palette-neutral-300)}.animatable.tab-nav .selected a{border-color:transparent!important}.animatable.tab-nav ul::after{position:absolute;bottom:0;height:0;border-top:0;width:calc(var(--selected-width,0) * 1px);transform:translate(calc(var(--selected-left,0) * 1px),0);transition-property:transform,width}.search-bar-status{border-bottom:var(--decor-border-100);border-bottom-color:var(--token-color-surface-interactive-active);padding:.5rem 0 .5rem .5rem}.search-bar-status li:not(.remove-all) button::before{color:var(--token-color-foreground-faint);margin-top:1px;margin-right:.2rem}.search-bar-status dt::after{content:":";padding-right:.3rem}.search-bar-status>dl>dt{float:left}.search-bar-status dt{white-space:nowrap}.search-bar-status li{display:inline-flex}.search-bar-status li:not(:last-child){margin-right:.3rem;margin-bottom:.3rem}.search-bar-status li:not(.remove-all){border:var(--decor-border-100);border-color:var(--token-color-surface-interactive-active);color:var(--token-color-foreground-faint);padding:0 .2rem}.search-bar-status li:not(.remove-all) dl{display:flex}.search-bar-status li:not(.remove-all) button{cursor:pointer;padding:0}.copyable-code{display:flex;align-items:flex-start;position:relative;width:100%;padding:8px 14px 3px;border:var(--decor-border-100);border-color:var(--token-color-surface-interactive-active);border-radius:var(--decor-radius-200)}.copyable-code.obfuscated{padding-left:4px}.copyable-code::after{position:absolute;top:0;right:0;width:40px;height:100%;display:block;content:""}.copyable-code .copy-button{position:absolute;top:0;right:0;z-index:1}.copyable-code .copy-button button{width:40px;height:40px}.copyable-code .copy-button button:empty::after{display:none}.copyable-code button[aria-expanded]{margin-top:1px;margin-right:4px;cursor:pointer}.copyable-code button[aria-expanded]::before{content:"";--icon-size:icon-000;--icon-color:var(--token-color-foreground-faint)}.copyable-code button[aria-expanded=true]::before{--icon-name:icon-eye-off}.copyable-code button[aria-expanded=false]::before{--icon-name:icon-eye}.copyable-code pre{padding-right:30px}.copyable-code code{display:inline-block;overflow:hidden;text-overflow:ellipsis;width:100%}.copyable-code hr{width:calc(100% - 80px);margin:8px 0 13px;border:3px dashed var(--token-color-palette-neutral-300);background-color:var(--token-color-surface-primary)}.consul-loader circle{fill:var(--token-color-consul-gradient-faint-stop);animation:loader-animation 1.5s infinite ease-in-out;transform-origin:50% 50%}.consul-loader g:nth-last-child(2) circle{animation-delay:.2s}.consul-loader g:nth-last-child(3) circle{animation-delay:.3s}.consul-loader g:nth-last-child(4) circle{animation-delay:.4s}.consul-loader g:nth-last-child(5) circle{animation-delay:.5s}@keyframes loader-animation{0%,100%{transform:scale3D(1,1,1)}33%{transform:scale3D(0,0,1)}}.consul-loader{display:flex;align-items:center;justify-content:center;height:100%;position:absolute;width:100%;top:0;margin-top:0!important}.tomography-graph .background{fill:var(--token-color-surface-strong)}.tomography-graph .axis{fill:none;stroke:var(--token-color-palette-neutral-300);stroke-dasharray:4 4}.tomography-graph .border{fill:none;stroke:var(--token-color-palette-neutral-300)}.tomography-graph .point{stroke:var(--token-color-foreground-disabled);fill:var(--token-color-consul-foreground)}.tomography-graph .lines rect{fill:var(--token-color-consul-foreground);stroke:transparent;stroke-width:5px}.tomography-graph .lines rect:hover{fill:var(--token-color-palette-neutral-300);height:3px;y:-1px}.tomography-graph .tick line{stroke:var(--token-color-palette-neutral-300)}.tomography-graph .tick text{text-anchor:start}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card,.discovery-chain path{transition-duration:.1s;transition-timing-function:linear;cursor:pointer}.discovery-chain path{transition-property:stroke;fill:none;stroke:var(--token-color-foreground-disabled);stroke-width:2;vector-effect:non-scaling-stroke}#downstream-lines svg circle,#upstream-lines svg circle,.discovery-chain circle{fill:var(--token-color-surface-primary)}.discovery-chain .resolver-card,.discovery-chain .resolver-card a,.discovery-chain .route-card,.discovery-chain .route-card a,.discovery-chain .splitter-card,.discovery-chain .splitter-card a{color:var(--token-color-foreground-strong)!important}.discovery-chain path:focus,.discovery-chain path:hover{stroke:var(--token-color-foreground-strong)}.discovery-chain .resolvers,.discovery-chain .routes,.discovery-chain .splitters{border-radius:var(--decor-radius-100);border:1px solid;border-color:var(--token-color-surface-interactive-active);background-color:var(--token-color-surface-strong);pointer-events:none}.discovery-chain .resolver-card,.discovery-chain .resolvers>header span,.discovery-chain .route-card,.discovery-chain .routes>header span,.discovery-chain .splitter-card,.discovery-chain .splitters>header span{pointer-events:all}.discovery-chain .resolvers>header>*,.discovery-chain .routes>header>*,.discovery-chain .splitters>header>*{text-transform:uppercase}.discovery-chain .resolvers>header span::after,.discovery-chain .routes>header span::after,.discovery-chain .splitters>header span::after{width:1.2em;height:1.2em;opacity:.6}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card{transition-property:opacity background-color border-color;margin-top:0!important}.discovery-chain [id*=":"]:not(path):hover{opacity:1;background-color:var(--token-color-surface-primary);border-color:var(--token-color-foreground-faint)}.discovery-chain .route-card header:not(.short) dd{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.discovery-chain .route-card section header>*{visibility:hidden}.discovery-chain .route-card .match-headers header ::before{content:"H"}.discovery-chain .route-card .match-queryparams header>::before{content:"Q"}.discovery-chain .resolver-card dt::before{content:"";--icon-size:icon-999}.discovery-chain .resolver-card dl.failover dt::before{--icon-name:icon-cloud-cross}.discovery-chain .resolver-card dl.redirect dt::before{--icon-name:icon-redirect}.discovery-chain circle{stroke-width:2;stroke:var(--token-color-foreground-disabled)}.discovery-chain{position:relative;display:flex;justify-content:space-between}.discovery-chain svg{position:absolute}.discovery-chain .resolvers,.discovery-chain .routes,.discovery-chain .splitters{padding:10px 1%;width:32%}.discovery-chain .resolvers>header,.discovery-chain .routes>header,.discovery-chain .splitters>header{height:18px}.discovery-chain .resolvers>header span,.discovery-chain .routes>header span,.discovery-chain .splitters>header span{position:relative;z-index:1;margin-left:2px}.discovery-chain .resolvers [role=group],.discovery-chain .routes [role=group],.discovery-chain .splitters [role=group]{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:space-around;height:100%}.discovery-chain .resolver-card dl,.discovery-chain .route-card dl,.discovery-chain .splitter-card dl{margin:0;float:none}.discovery-chain .resolver-card,.discovery-chain .route-card,.discovery-chain .splitter-card{margin-bottom:20px}.discovery-chain .route-card header.short dl{display:flex}.discovery-chain .route-card header.short dt::after{content:" ";display:inline-block}.discovery-chain .route-card>header ul{float:right;margin-top:-2px}.discovery-chain .route-card>header ul li{margin-left:5px}.discovery-chain .route-card section{display:flex}.discovery-chain .route-card section header{display:block;width:19px;margin-right:14px}.discovery-chain .resolver-card a{display:block}.discovery-chain .resolver-card dl{display:flex;flex-wrap:wrap;margin-top:5px}.discovery-chain .resolver-card dt{font-size:0;margin-right:6px;margin-top:1px;width:23px;height:20px}.discovery-chain .resolver-card ol{display:flex;flex-wrap:wrap;list-style-type:none}.discovery-chain .route-card,.discovery-chain .splitter-card{position:relative}.discovery-chain .route-card::before,.discovery-chain .splitter-card::before{background-color:var(--token-color-surface-primary);border-radius:var(--decor-radius-full);border:2px solid;border-color:var(--token-color-foreground-disabled);position:absolute;z-index:1;right:-5px;top:50%;margin-top:-5px;width:10px;height:10px}.discovery-chain .resolver-inlets,.discovery-chain .splitter-inlets{width:10px;height:100%;z-index:1}.discovery-chain .splitter-inlets{left:50%;margin-left:calc(-15% - 3px)}.discovery-chain .resolver-inlets{right:calc(31% - 7px)}.consul-bucket-list dd:not(:last-child)::after{display:inline-block;content:"/";margin:0 6px 0 3px}.consul-bucket-list .service+dd,.consul-bucket-list dd+dt{margin-left:0!important}.consul-upstream-instance-list dl.local-bind-socket-mode dt{text-transform:lowercase;font-weight:var(--token-typography-font-weight-semibold)}.consul-health-check-list .health-check-output::before{min-width:20px;min-height:20px;margin-right:15px}@media (max-width:650px){.consul-health-check-list .health-check-output::before{min-width:18px;min-height:18px;margin-right:8px}}.consul-health-check-list .health-check-output dd em{background-color:var(--token-color-surface-strong);cursor:default;font-style:normal;margin-top:-2px;margin-left:.5em}.consul-health-check-list .passing.health-check-output::before{color:var(--token-color-foreground-success)}.consul-health-check-list .warning.health-check-output::before{color:var(--token-color-foreground-warning)}.consul-health-check-list .critical.health-check-output::before{color:var(--token-color-foreground-critical)}.consul-health-check-list .health-check-output,.consul-health-check-list .health-check-output pre{border-radius:var(--decor-radius-100)}.consul-health-check-list .health-check-output dd:first-of-type{color:var(--token-color-foreground-disabled)}.consul-health-check-list .health-check-output pre{background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-faint)}.consul-health-check-list .health-check-output{border-width:1px 1px 1px 4px;color:var(--token-color-foreground-strong);border-color:var(--token-color-surface-interactive-active);border-style:solid;display:flex;padding:20px 24px 20px 16px}.consul-health-check-list .passing.health-check-output{border-left-color:var(--token-color-foreground-success)}.consul-health-check-list .warning.health-check-output{border-left-color:var(--token-color-vault-brand)}.consul-health-check-list .critical.health-check-output{border-left-color:var(--token-color-foreground-critical)}.consul-health-check-list .health-check-output:not(:last-child){margin-bottom:24px}.consul-health-check-list .health-check-output dl:last-of-type,.consul-health-check-list .health-check-output header{width:100%}.consul-health-check-list .health-check-output header{margin-bottom:.9em}.consul-health-check-list .health-check-output>div{flex:1 1 auto;width:calc(100% - 26px);display:flex;flex-wrap:wrap;justify-content:space-between}.consul-health-check-list .health-check-output dl{min-width:110px}.consul-health-check-list .health-check-output dl>*{display:block;width:auto;position:static;padding-left:0}.consul-health-check-list .health-check-output dt{margin-bottom:0}.consul-health-check-list .health-check-output dd{position:relative}.consul-health-check-list .health-check-output dl:nth-last-of-type(2){width:50%}.consul-health-check-list .health-check-output dl:last-of-type{margin-top:1em;margin-bottom:0}.consul-health-check-list .health-check-output dl:last-of-type dt{margin-bottom:.3em}.consul-health-check-list .health-check-output pre{padding:12px 40px 12px 12px;white-space:pre-wrap;position:relative}.consul-health-check-list .health-check-output pre code{word-wrap:break-word}.consul-health-check-list .health-check-output .copy-button{position:absolute;right:.5em;top:.7em}@media (max-width:650px){.consul-health-check-list .health-check-output{padding:15px 19px 15px 14px}.consul-health-check-list .health-check-output::before{margin-right:8px}.consul-health-check-list .health-check-output dl:nth-last-of-type(2){width:100%}.consul-health-check-list .health-check-output dl:not(:last-of-type){margin-right:0}}.consul-instance-checks.passing dt::before{color:var(--token-color-foreground-success)}.consul-instance-checks.warning dt::before{color:var(--token-color-foreground-warning)}.consul-instance-checks.critical dt::before{color:var(--token-color-foreground-critical)}.consul-instance-checks.empty dt::before{color:var(--token-color-foreground-faint)}.consul-exposed-path-list>ul{border-top:1px solid var(--token-color-surface-interactive-active)}.consul-external-source::before,.consul-kind::before{--icon-size:icon-300}.consul-intention-list td.intent- strong::before,.consul-intention-list td.intent-allow strong::before,.consul-intention-list td.intent-deny strong::before,.consul-intention-permission-list .intent-allow::before,.consul-intention-permission-list .intent-deny::before,.consul-intention-search-bar .value- span::before,.consul-intention-search-bar .value-allow span::before,.consul-intention-search-bar .value-deny span::before{margin-right:5px}.consul-intention-list td.intent- strong,.consul-intention-list td.intent-allow strong,.consul-intention-list td.intent-deny strong,.consul-intention-permission-list .intent-allow,.consul-intention-permission-list .intent-deny,.consul-intention-search-bar .value- span,.consul-intention-search-bar .value-allow span,.consul-intention-search-bar .value-deny span{font-weight:var(--token-typography-font-weight-regular);font-size:var(--token-typography-body-200-font-size);display:inline-block}.consul-intention-list td.intent-allow strong,.consul-intention-permission-list .intent-allow,.consul-intention-search-bar .value-allow span{color:var(--token-color-foreground-success-on-surface);background-color:var(--token-color-border-success)}.consul-intention-list td.intent-deny strong,.consul-intention-permission-list .intent-deny,.consul-intention-search-bar .value-deny span{color:var(--token-color-foreground-critical-on-surface);background-color:var(--token-color-border-critical)}.consul-intention-list td.permissions{color:var(--token-color-foreground-action)}.consul-intention-list em{--word-spacing:0.25rem}.consul-intention-list em span::before,.consul-intention-list em span:first-child{margin-right:var(--word-spacing)}.consul-intention-list em span:last-child{margin-left:var(--word-spacing)}.consul-intention-list td{height:59px}.consul-intention-list tr>:nth-child(1){width:calc(30% - 50px)}.consul-intention-list tr>:nth-child(2){width:120px}.consul-intention-list tr>:nth-child(3){width:calc(30% - 50px)}.consul-intention-list tr>:nth-child(4){width:calc(40% - 240px)}.consul-intention-list tr>:nth-child(5){width:160px}.consul-intention-list tr>:last-child{width:60px}.consul-intention-list .menu-panel.confirmation{width:200px}@media (max-width:849px){.consul-intention-list tr>:not(.source):not(.destination):not(.intent){display:none}}.consul-intention-action-warn-modal .modal-dialog-window{max-width:450px}.consul-intention-fieldsets [role=radiogroup]{overflow:visible!important;display:grid;grid-gap:12px;grid-template-columns:repeat(auto-fit,minmax(270px,auto))}.consul-intention-fieldsets .radio-card header>*{display:inline}.consul-intention-fieldsets .permissions>button{float:right}.consul-intention-permission-modal [role=dialog]{width:100%}.consul-intention-permission-list dl.permission-methods dt::before{content:"M"}.consul-intention-permission-list dl.permission-path dt::before{content:"P"}.consul-intention-permission-header-list dt::before,.consul-intention-permission-list dl.permission-header dt::before{content:"H"}.consul-intention-permission-list .detail>div{display:flex;width:100%}.consul-intention-permission-list strong{margin-right:8px}.consul-intention-permission-form h2{border-top:1px solid var(--token-color-foreground-action);padding-top:1.4em;margin-top:.2em;margin-bottom:.6em}.consul-intention-permission-form .consul-intention-permission-header-form{margin-top:10px}.consul-intention-permission-form .consul-intention-permission-header-form fieldset>div,.consul-intention-permission-form fieldset:nth-child(2)>div{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));grid-gap:12px}.consul-intention-permission-form fieldset:nth-child(2)>div label:last-child{grid-column:span 2}.consul-intention-permission-form .ember-basic-dropdown-trigger{padding:5px}.consul-intention-permission-form .checkbox-group{flex-direction:column}.consul-intention-permission-header-list{max-height:200px;overflow:auto}.consul-lock-session-list button{margin-right:var(--horizontal-padding)}.consul-lock-session-form{overflow:hidden}.consul-server-list ul{display:grid;grid-template-columns:repeat(4,minmax(215px,25%));gap:12px}.consul-server-list a:hover div{--tone-border:var(--token-color-foreground-faint)}.consul-server-card .name+dd{color:var(--token-color-hashicorp-brand);animation-name:typo-truncate}.voting-status-non-voter.consul-server-card .health-status+dd{background-color:var(--token-color-surface-strong);color:var(--token-color-foreground-faint)}.consul-server-card:not(.voting-status-non-voter) .health-status.healthy+dd{background-color:var(--token-color-surface-success);color:var(--token-color-palette-green-400)}.consul-server-card:not(.voting-status-non-voter) .health-status:not(.healthy)+dd{background-color:var(--token-color-surface-critical);color:var(--token-color-foreground-critical)}.consul-server-card .health-status+dd::before{--icon-size:icon-000;content:""}.consul-server-card .health-status.healthy+dd::before{--icon-name:icon-check}.consul-server-card .health-status:not(.healthy)+dd::before{--icon-name:icon-x}.consul-server-card{position:relative;overflow:hidden;--padding-x:24px;--padding-y:24px;padding:var(--padding-y) var(--padding-x);--tile-size:3rem}.consul-auth-method-binding-list h2,.consul-auth-method-view section h2{padding-bottom:12px}.voting-status-leader.consul-server-card .name{position:absolute!important}.consul-server-card dd:not(:last-of-type){margin-bottom:calc(var(--padding-y)/ 2)}.voting-status-leader.consul-server-card dd{margin-left:calc(var(--tile-size) + 1rem)}.consul-auth-method-list ul .locality::before{margin-right:4px}.consul-auth-method-view{margin-bottom:32px}.consul-auth-method-view section{width:100%;position:relative;overflow-y:auto}.consul-auth-method-view section table thead td{color:var(--token-color-foreground-faint)}.consul-auth-method-view section table tbody td{color:var(--token-color-hashicorp-brand)}.consul-auth-method-view section table tbody tr{cursor:default}.consul-auth-method-view section table tbody tr:hover{box-shadow:none}.consul-auth-method-view section dt{width:30%}.consul-auth-method-view section dd{width:70%}.consul-auth-method-binding-list p{margin-bottom:4px!important}.consul-auth-method-binding-list code{background-color:var(--token-color-surface-strong);padding:0 12px}.consul-auth-method-nspace-list thead td{color:var(--token-color-foreground-faint)!important}.consul-auth-method-nspace-list tbody td{color:var(--token-color-hashicorp-brand)}.consul-auth-method-nspace-list tbody tr{cursor:default}.consul-auth-method-nspace-list tbody tr:hover{box-shadow:none}.role-selector [name="role[state]"],.role-selector [name="role[state]"]+*{display:none}.role-selector [name="role[state]"]:checked+*{display:block}.topology-notices button{color:var(--token-color-foreground-action);float:right;margin-top:16px;margin-bottom:32px}#metrics-container .link a,.topology-container{color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card:not(:last-child),#upstream-column #upstream-container:not(:last-child),#upstream-container .topology-metrics-card:not(:last-child){margin-bottom:8px}#downstream-container,#metrics-container,#upstream-container{border-radius:var(--decor-radius-100);border:1px solid;border-color:var(--token-color-surface-interactive-active)}#downstream-container,#upstream-container{background-color:var(--token-color-surface-strong);padding:12px}#downstream-container>div:first-child{display:inline-flex}#downstream-container>div:first-child span::before{background-color:var(--token-color-foreground-faint)}#metrics-container div:first-child{background-color:var(--token-color-surface-primary);padding:12px;border:none}#metrics-container .link{background-color:var(--token-color-surface-strong);padding:18px}#metrics-container .link a:hover{color:var(--token-color-foreground-action)}#downstream-lines svg path,#upstream-lines svg path{fill:transparent}#downstream-lines svg .allow-arrow,#upstream-lines svg .allow-arrow{fill:var(--token-color-palette-neutral-300);stroke-linejoin:round}#downstream-lines svg .allow-arrow,#downstream-lines svg .allow-dot,#downstream-lines svg path,#upstream-lines svg .allow-arrow,#upstream-lines svg .allow-dot,#upstream-lines svg path{stroke:var(--token-color-palette-neutral-300);stroke-width:2}#downstream-lines svg path[data-permission=empty],#downstream-lines svg path[data-permission=not-defined],#upstream-lines svg path[data-permission=empty],#upstream-lines svg path[data-permission=not-defined]{stroke-dasharray:4}#downstream-lines svg path[data-permission=deny],#upstream-lines svg path[data-permission=deny]{stroke:var(--token-color-foreground-critical)}#downstream-lines svg .deny-dot,#upstream-lines svg .deny-dot{stroke:var(--token-color-foreground-critical);stroke-width:2}#downstream-lines svg .deny-arrow,#upstream-lines svg .deny-arrow{fill:var(--token-color-foreground-critical);stroke:var(--token-color-foreground-critical);stroke-linejoin:round}.topology-notices{display:flow-root}.topology-container{display:grid;height:100%;align-items:start;grid-template-columns:2fr 1fr 2fr 1fr 2fr;grid-template-rows:50px 1fr 50px;grid-template-areas:"down-cards down-lines . up-lines up-cards" "down-cards down-lines metrics up-lines up-cards" "down-cards down-lines . up-lines up-cards"}#downstream-container{grid-area:down-cards}#downstream-lines{grid-area:down-lines;margin-left:-20px}#upstream-lines{grid-area:up-lines;margin-right:-20px}#upstream-column{grid-area:up-cards}#downstream-lines,#upstream-lines{position:relative}#metrics-container{grid-area:metrics}#metrics-container .link a::before{background-color:var(--token-color-foreground-faint);margin-right:4px}#downstream-container .topology-metrics-card,#upstream-container .topology-metrics-card{display:block;color:var(--token-color-foreground-faint);overflow:hidden;background-color:var(--token-color-surface-primary);border-radius:var(--decor-radius-100);border:1px solid;border-color:var(--token-color-surface-interactive-active)}#downstream-container .topology-metrics-card p,#upstream-container .topology-metrics-card p{padding:12px 12px 0;margin-bottom:0!important}#downstream-container .topology-metrics-card p.empty,#upstream-container .topology-metrics-card p.empty{padding:12px!important}#downstream-container .topology-metrics-card div dl,#upstream-container .topology-metrics-card div dl{display:inline-flex;margin-right:8px}#downstream-container .topology-metrics-card div dd,#upstream-container .topology-metrics-card div dd{color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card div span,#upstream-container .topology-metrics-card div span{margin-right:8px}#downstream-container .topology-metrics-card div dt::before,#downstream-container .topology-metrics-card div span::before,#upstream-container .topology-metrics-card div dt::before,#upstream-container .topology-metrics-card div span::before{margin-right:4px}#downstream-container .topology-metrics-card div .health dt::before,#downstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .nspace dt::before{margin-top:2px}#downstream-container .topology-metrics-card div .health dt::before,#downstream-container .topology-metrics-card div .nspace dt::before,#downstream-container .topology-metrics-card div .partition dt::before,#upstream-container .topology-metrics-card div .health dt::before,#upstream-container .topology-metrics-card div .nspace dt::before,#upstream-container .topology-metrics-card div .partition dt::before{--icon-color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card div .passing::before,#upstream-container .topology-metrics-card div .passing::before{--icon-color:var(--token-color-foreground-success)}#downstream-container .topology-metrics-card div .warning::before,#upstream-container .topology-metrics-card div .warning::before{--icon-color:var(--token-color-foreground-warning)}#downstream-container .topology-metrics-card div .critical::before,#upstream-container .topology-metrics-card div .critical::before{--icon-color:var(--token-color-foreground-critical)}#downstream-container .topology-metrics-card div .empty::before,#upstream-container .topology-metrics-card div .empty::before{--icon-color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card .details,#upstream-container .topology-metrics-card .details{padding:0 12px 12px}#downstream-container .topology-metrics-card .details>:not(:last-child),#upstream-container .topology-metrics-card .details>:not(:last-child){padding-bottom:6px}#downstream-container .topology-metrics-card .details .group,#upstream-container .topology-metrics-card .details .group{display:grid;grid-template-columns:20px 1fr;grid-template-rows:repeat(2,1fr);grid-template-areas:"partition partition" "union namespace"}#downstream-container .topology-metrics-card .details .group span,#upstream-container .topology-metrics-card .details .group span{display:inline-block;grid-area:union;padding-left:7px;margin-right:0}#downstream-container .topology-metrics-card .details .group span::before,#upstream-container .topology-metrics-card .details .group span::before{margin-right:0;--icon-color:var(--token-color-foreground-faint)}#downstream-container .topology-metrics-card .details .group dl:first-child,#upstream-container .topology-metrics-card .details .group dl:first-child{grid-area:partition;padding-bottom:6px}#downstream-container .topology-metrics-card .details .group dl:nth-child(2),#upstream-container .topology-metrics-card .details .group dl:nth-child(2){grid-area:namespace}.topology-metrics-source-type{margin:6px 0 6px 12px;display:table}.topology-metrics-popover>button{position:absolute;transform:translate(-50%,-50%);background-color:var(--token-color-surface-primary);padding:1px}.topology-metrics-popover>button:hover{cursor:pointer}.topology-metrics-popover>button:disabled,html[data-route^="dc.nodes.show.metadata"] table tr{cursor:default}.topology-metrics-popover>button:active,.topology-metrics-popover>button:focus{outline:0}.topology-metrics-popover.deny .informed-action header::before{display:none}.topology-metrics-popover.deny .tippy-arrow::after,.topology-metrics-popover.deny>button::before{--icon-color:var(--token-color-foreground-critical)}.topology-metrics-popover.not-defined .tippy-arrow::after,.topology-metrics-popover.not-defined>button::before{--icon-color:var(--token-color-vault-brand)}#metrics-container .sparkline-wrapper svg path{stroke-width:0}#metrics-container .sparkline-wrapper .tooltip{padding:0 0 10px;border:1px solid var(--token-color-palette-neutral-300);background:#fff;border-radius:2px;box-sizing:border-box;box-shadow:var(--token-elevation-higher-box-shadow)}#metrics-container .sparkline-wrapper .tooltip .sparkline-time{padding:8px 10px;color:#000;border-bottom:1px solid var(--token-color-surface-interactive-active);margin-bottom:4px;text-align:center}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-legend,#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-sum{border:0;padding:3px 10px 0}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-sum{border-top:1px solid var(--token-color-surface-interactive-active);margin-top:4px;padding:8px 10px 0}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-legend-color{width:12px;height:12px;border-radius:2px;margin:0 5px 0 0;padding:0}#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-legend-value,#metrics-container .sparkline-wrapper .tooltip .sparkline-tt-sum-value{float:right}#metrics-container .sparkline-wrapper div.tooltip:before{content:"";display:block;position:absolute;width:12px;height:12px;left:15px;bottom:-7px;border:1px solid var(--token-color-palette-neutral-300);border-top:0;border-left:0;background:#fff;transform:rotate(45deg)}.sparkline-key h3::before{margin:2px 3px 0 0;font-size:var(--token-typography-body-200-font-size)}.sparkline-key h3{color:var(--token-color-foreground-strong)}.sparkline-key .sparkline-key-content dd,.sparkline-key-link{color:var(--token-color-foreground-faint)}.sparkline-key-link:hover{color:var(--token-color-foreground-action)}#metrics-container:hover .sparkline-key-link::before{margin:1px 3px 0 0;font-size:12px}#metrics-container div .sparkline-wrapper,#metrics-container div .sparkline-wrapper svg.sparkline{width:100%;height:70px;padding:0;margin:0}#metrics-container div .sparkline-wrapper{position:relative}#metrics-container div .sparkline-wrapper .tooltip{visibility:hidden;position:absolute;z-index:10;bottom:78px;width:217px}#metrics-container div .sparkline-wrapper .sparkline-tt-legend-color{display:inline-block}#metrics-container div .sparkline-wrapper .topology-metrics-error,#metrics-container div .sparkline-wrapper .topology-metrics-loader{padding-top:15px}.sparkline-key .sparkline-key-content{width:500px;min-height:100px}.sparkline-key .sparkline-key-content dl{padding:10px 0 0}.sparkline-key .sparkline-key-content dt{font-weight:var(--token-typography-font-weight-semibold);width:125px;float:left}.sparkline-key .sparkline-key-content dd{margin:0 0 12px 135px}.sparkline-key-link{visibility:hidden;float:right;margin-top:-35px;margin-right:12px}#metrics-container:hover .sparkline-key-link{visibility:visible}.topology-metrics-stats{padding:12px 12px 0;display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;width:100%;border-top:1px solid var(--token-color-surface-interactive-active)}.topology-metrics-stats dl{display:flex;padding-bottom:12px}.topology-metrics-stats dt{margin-right:5px;line-height:1.5em!important}.topology-metrics-stats dd{color:var(--token-color-foreground-disabled)!important}.topology-metrics-stats span{padding-bottom:12px}.topology-metrics-status-error,.topology-metrics-status-loader{color:var(--token-color-foreground-faint);text-align:center;margin:0 auto!important;display:block}.topology-metrics-status-error span::before,.topology-metrics-status-loader span::before{background-color:var(--token-color-foreground-faint)}span.topology-metrics-status-loader::after{--icon-name:var(--icon-loading);content:"";margin-left:.5rem}.consul-node-peer-info .consul-node-peer-info__name,.consul-peer-info .consul-peer-info__description{margin-left:4px}.consul-intention-list-table__meta-info{display:flex}.consul-intention-list-table__meta-info .consul-intention-list-table__meta-info__peer{display:flex;align-items:center}.consul-node-peer-info,.peerings-badge{align-items:center;display:flex}.consul-peer-search-bar .value-active span::before,.consul-peer-search-bar .value-deleting span::before,.consul-peer-search-bar .value-establishing span::before,.consul-peer-search-bar .value-failing span::before,.consul-peer-search-bar .value-pending span::before,.consul-peer-search-bar .value-terminated span::before{--icon-size:icon-000;content:""}.consul-peer-search-bar .value-active span,.consul-peer-search-bar .value-deleting span,.consul-peer-search-bar .value-establishing span,.consul-peer-search-bar .value-failing span,.consul-peer-search-bar .value-pending span,.consul-peer-search-bar .value-terminated span{font-size:var(--token-typography-body-200-font-size)}.consul-peer-search-bar .value-pending span::before{--icon-name:icon-running;--icon-color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-pending span{background-color:var(--token-color-consul-surface);color:var(--token-color-consul-foreground)}.consul-peer-search-bar .value-establishing span::before{--icon-name:icon-running;--icon-color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-establishing span{background-color:var(--token-color-palette-blue-50);color:var(--token-color-palette-blue-200)}.consul-peer-search-bar .value-active span::before{--icon-name:icon-check;--icon-color:var(--token-color-palette-green-400)}.consul-peer-search-bar .value-active span{background-color:var(--token-color-palette-green-50);color:var(--token-color-palette-green-200)}.consul-peer-search-bar .value-failing span::before{--icon-name:icon-x;--icon-color:var(--token-color-palette-red-200)}.consul-peer-search-bar .value-failing span{background-color:var(--token-color-palette-red-50);color:var(--token-color-palette-red-200)}.consul-peer-search-bar .value-terminated span::before{--icon-name:icon-x-square;--icon-color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-terminated span{background-color:var(--token-color-palette-neutral-200);color:var(--token-color-palette-neutral-600)}.consul-peer-search-bar .value-deleting span::before{--icon-name:icon-loading;--icon-color:var(--token-color-foreground-warning-on-surface)}.consul-peer-search-bar .value-deleting span{background-color:var(--token-color-surface-warning);color:var(--token-color-foreground-warning-on-surface)}.peers__list__peer-detail{display:flex;align-content:center;gap:18px}.border-bottom-primary{border-bottom:1px solid var(--token-color-border-primary)}.peerings-badge{justify-content:center;padding:2px 8px;border-radius:5px;gap:4px}.peerings-badge.active{background:var(--token-color-surface-success);color:var(--token-color-foreground-success)}.peerings-badge.pending{background:var(--token-color-consul-surface);color:var(--token-color-consul-brand)}.peerings-badge.establishing{background:var(--token-color-surface-action);color:var(--token-color-foreground-action)}.peerings-badge.failing{background:var(--token-color-surface-critical);color:var(--token-color-foreground-critical)}.peerings-badge.deleting{background:var(--token-color-surface-warning);color:var(--token-color-foreground-warning-on-surface)}.peerings-badge.terminated,.peerings-badge.undefined{background:var(--token-color-surface-interactive-active);color:var(--token-color-foreground-primary)}.consul-peer-info,section[data-route="dc.show.serverstatus"] .server-failure-tolerance dt{color:var(--token-color-foreground-faint)}.consul-peer-info{background:var(--token-color-surface-faint);padding:0 8px;border-radius:2px;display:flex;align-items:center}.consul-peer-form{width:416px}.consul-peer-form nav{margin-bottom:20px}.consul-peer-form-generate{width:416px;min-height:200px}.consul-peer-form-generate ol{list-style-position:outside;list-style-type:none;counter-reset:hexagonal-counter;position:relative}.consul-peer-form-generate ol::before{content:"";border-left:var(--decor-border-100);border-color:var(--token-color-palette-neutral-300);height:100%;position:absolute;left:2rem}.consul-peer-form-generate li{counter-increment:hexagonal-counter;position:relative;margin-left:60px;margin-bottom:1rem}.consul-peer-form-generate li .copyable-code{margin-top:1rem}.consul-peer-form-generate li::before{--icon-name:icon-hexagon;--icon-size:icon-600;content:"";position:absolute;z-index:2}.consul-peer-form-generate li::after{content:counter(hexagonal-counter);position:absolute;top:0;background-color:var(--token-color-palette-neutral-0);z-index:1;text-align:center}.consul-peer-form-generate li::after,.consul-peer-form-generate li::before{left:-2.4rem;width:20px;height:20px}.agentless-node-notice .hds-alert__title{display:flex;justify-content:space-between}.definition-table dt{line-height:var(--token-typography-body-300-line-height)}.app-view>div form:not(.filter-bar) [role=radiogroup] label,.modal-dialog [role=document] [role=radiogroup] label{line-height:var(--token-typography-body-100-line-height)}.app-view h1 em,.app-view>div form:not(.filter-bar) [role=radiogroup] label>em,.consul-intention-list td.destination em,.consul-intention-list td.source em,.modal-dialog [role=document] .type-password>em,.modal-dialog [role=document] .type-select>em,.modal-dialog [role=document] .type-text>em,.modal-dialog [role=document] [role=radiogroup] label>em,.modal-dialog [role=document] form button+em,.modal-dialog [role=document] table th em,.oidc-select label>em,.type-toggle>em,main .type-password>em,main .type-select>em,main .type-text>em,main form button+em,main table th em{font-style:normal}.consul-exposed-path-list>ul>li>.header :not(button),.consul-lock-session-list ul>li:not(:first-child)>.header :not(button),.consul-upstream-instance-list li>.header :not(button),.list-collection>ul>li:not(:first-child)>.header :not(button){font-size:inherit;font-weight:inherit}@media (max-width:420px) and (-webkit-min-device-pixel-ratio:0){input{font-size:var(--token-typography-body-300-font-size)!important}}#wrapper,#wrapper>footer>*,.modal-dialog>*,main>*{box-sizing:border-box}html[data-route$=create] main,html[data-route$=edit] main{max-width:1260px}fieldset [role=group]{display:flex;flex-wrap:wrap;flex-direction:row}.outlet[data-state=loading],html.ember-loading .view-loader,html:not(.has-nspaces) [class*=nspace-],html:not(.has-partitions) [class*=partition-],html[data-state=idle] .view-loader{display:none}[role=group] fieldset{width:50%}[role=group] fieldset:not(:first-of-type){padding-left:20px;border-left:1px solid;border-left:var(--token-color-foreground-faint)}[role=group] fieldset:not(:last-of-type){padding-right:20px}.app-view{margin-top:50px}@media (max-width:849px){html:not(.with-breadcrumbs) .app-view{margin-top:10px}}html body>.brand-loader{transition-property:transform,opacity;transform:translate(0,0);opacity:1}html[data-state]:not(.ember-loading) body>.brand-loader{opacity:0}@media (min-width:900px){html[data-state] body>.brand-loader{transform:translate(calc(var(--chrome-width)/ 2),0)}}html[data-route$=create] .app-view>header+div>:first-child,html[data-route$=edit] .app-view>header+div>:first-child{margin-top:1.8em}.app-view>div .container,.app-view>div .tab-section .consul-health-check-list,.app-view>div .tab-section>.search-bar+p,.app-view>div .tab-section>:first-child:not(.filter-bar):not(table){margin-top:1.25em}.consul-upstream-instance-list,html[data-route^="dc.nodes.show.sessions"] .consul-lock-session-list{margin-top:0!important}.consul-auth-method-list ul,.consul-node-list ul,.consul-nspace-list ul,.consul-peer-list ul,.consul-policy-list ul,.consul-role-list ul,.consul-service-instance-list ul,.consul-token-list ul,html[data-route="dc.services.index"] .consul-service-list ul,html[data-route^="dc.nodes.show.sessions"] .consul-lock-session-list ul{border-top-width:0!important}#wrapper{display:flex;min-height:100vh}main{padding:0 48px;position:relative;flex:1}html:not([data-route$=index]):not([data-route$=instances]) main{margin-bottom:2em}@media (max-width:849px){.actions button.copy-btn{margin-top:-56px;padding:0}}.modal-dialog [role=document] p:not(:last-child),main p:not(:last-child){margin-bottom:1em}.modal-dialog [role=document] form+div .with-confirmation,.modal-dialog [role=document] form:not(.filter-bar),main form+div .with-confirmation,main form:not(.filter-bar){margin-bottom:2em}@media (max-width:420px){main form [type=reset]{float:right;margin-right:0!important}}html[data-route^="dc.services.show"] .app-view .actions .external-dashboard{position:absolute;top:50px;right:0}html[data-route^="dc.services.instance"] .app-view>header dl{float:left;margin-top:19px;margin-bottom:23px;margin-right:50px}html[data-route^="dc.services.instance"] .app-view>header dt{font-weight:var(--token-typography-font-weight-bold)}html[data-route^="dc.services.instance"] .tab-nav{border-top:var(--decor-border-100)}html[data-route^="dc.services.instance"] .tab-section section:not(:last-child){border-bottom:var(--decor-border-100);padding-bottom:24px}html[data-route^="dc.services.instance"] .tab-nav,html[data-route^="dc.services.instance"] .tab-section section:not(:last-child){border-color:var(--token-color-surface-interactive-active)}html[data-route^="dc.services.instance.metadata"] .tab-section section h2{margin:24px 0 12px}html[data-route^="dc.kv"] .type-toggle{float:right;margin-bottom:0!important}html[data-route^="dc.kv.edit"] h2{border-bottom:var(--decor-border-200);border-color:var(--token-color-surface-interactive-active);padding-bottom:.2em;margin-bottom:.5em}html[data-route^="dc.acls.index"] main td strong{margin-right:3px}@media (max-width:420px){html[data-route^="dc.acls.create"] main header .actions,html[data-route^="dc.acls.edit"] main header .actions{float:none;display:flex;justify-content:space-between;margin-bottom:1em}html[data-route^="dc.acls.create"] main header .actions .with-feedback,html[data-route^="dc.acls.edit"] main header .actions .with-feedback{position:absolute;right:0}html[data-route^="dc.acls.create"] main header .actions .with-confirmation,html[data-route^="dc.acls.edit"] main header .actions .with-confirmation{margin-top:0}}html[data-route^="dc.intentions.edit"] .definition-table{margin-bottom:1em}section[data-route="dc.show.serverstatus"] .server-failure-tolerance{box-shadow:none;padding:var(--padding-y) var(--padding-x);max-width:770px;display:flex;flex-wrap:wrap}section[data-route="dc.show.serverstatus"] .server-failure-tolerance>header{width:100%;display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding-bottom:.5rem;margin-bottom:1rem;border-bottom:var(--decor-border-100);border-color:var(--tone-border)}section[data-route="dc.show.serverstatus"] .server-failure-tolerance header em{background-color:var(--token-color-surface-interactive-active);text-transform:uppercase;font-style:normal}section[data-route="dc.show.serverstatus"] .server-failure-tolerance>section{width:50%}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dl,section[data-route="dc.show.serverstatus"] .server-failure-tolerance>section{display:flex;flex-direction:column}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dl{flex-grow:1;justify-content:space-between}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dl.warning dd::before{--icon-name:icon-alert-circle;--icon-size:icon-800;--icon-color:var(--token-color-foreground-warning);content:"";margin-right:.5rem}section[data-route="dc.show.serverstatus"] .server-failure-tolerance section:first-of-type dl{padding-right:1.5rem}section[data-route="dc.show.serverstatus"] .server-failure-tolerance dd{display:flex;align-items:center;color:var(--token-color-hashicorp-brand)}section[data-route="dc.show.serverstatus"] .server-failure-tolerance header span::before{--icon-name:icon-info;--icon-size:icon-300;--icon-color:var(--token-color-foreground-faint);vertical-align:unset;content:""}section[data-route="dc.show.serverstatus"] section:not([class*=-tolerance]) h2{margin-top:1.5rem;margin-bottom:1.5rem}section[data-route="dc.show.serverstatus"] section:not([class*=-tolerance]) header{margin-top:18px;margin-bottom:18px}section[data-route="dc.show.serverstatus"] .redundancy-zones section header{display:flow-root}section[data-route="dc.show.serverstatus"] .redundancy-zones section header h3{float:left;margin-right:.5rem}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl:not(.warning){background-color:var(--token-color-surface-strong)}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.warning{background-color:var(--token-color-border-warning);color:var(--token-color-palette-amber-400)}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dl.warning::before{--icon-name:icon-alert-circle;--icon-size:icon-000;margin-right:.312rem;content:""}section[data-route="dc.show.serverstatus"] .redundancy-zones section header dt::after{content:":";display:inline-block;vertical-align:revert;background-color:transparent}section[data-route="dc.show.license"] .validity p{color:var(--token-color-foreground-faint)}section[data-route="dc.show.license"] .validity dl dt::before{content:"";margin-right:.25rem}section[data-route="dc.show.license"] .validity dl .expired::before{--icon-name:icon-x-circle;--icon-color:var(--token-color-foreground-critical)}section[data-route="dc.show.license"] .validity dl .warning::before{--icon-name:icon-alert-circle;--icon-color:var(--token-color-foreground-warning)}section[data-route="dc.show.license"] .validity dl .valid:not(.warning)::before{--icon-name:icon-check-circle;--icon-color:var(--token-color-foreground-success)}section[data-route="dc.show.license"] aside{box-shadow:none;padding:var(--padding-y) var(--padding-x);width:40%;min-width:413px;margin-top:1rem}section[data-route="dc.show.license"] aside header{margin-bottom:1rem}.prefers-reduced-motion{--icon-loading:icon-loading}@media (prefers-reduced-motion){:root{--hds-app-sidenav-animation-duration:0;--icon-loading:icon-loading}}.consul-intention-fieldsets .value->:last-child::before,.consul-intention-fieldsets .value-allow>:last-child::before,.consul-intention-fieldsets .value-deny>:last-child::before{--icon-size:icon-500;--icon-resolution:0.5}.consul-intention-fieldsets .value-allow>:last-child::before,.consul-intention-list td.intent-allow strong::before,.consul-intention-permission-list .intent-allow::before,.consul-intention-search-bar .value-allow span::before{--icon-name:icon-arrow-right;--icon-color:var(--token-color-foreground-success-on-surface)}.consul-intention-fieldsets .value-deny>:last-child::before,.consul-intention-list td.intent-deny strong::before,.consul-intention-permission-list .intent-deny::before,.consul-intention-search-bar .value-deny span::before{--icon-name:icon-skip;--icon-color:var(--token-color-foreground-critical-on-surface)}.consul-intention-fieldsets .value->:last-child::before,.consul-intention-list td.intent- strong::before,.consul-intention-search-bar .value- span::before{--icon-name:icon-layers}*{border-width:0}.animatable.tab-nav ul::after,.consul-auth-method-type,.consul-external-source,.consul-intention-action-warn-modal button.dangerous,.consul-intention-action-warn-modal button.dangerous:disabled,.consul-intention-action-warn-modal button.dangerous:focus,.consul-intention-action-warn-modal button.dangerous:hover:active,.consul-intention-action-warn-modal button.dangerous:hover:not(:disabled):not(:active),.consul-intention-list td.intent- strong,.consul-intention-permission-form button.type-submit,.consul-intention-permission-form button.type-submit:disabled,.consul-intention-permission-form button.type-submit:focus:not(:disabled),.consul-intention-permission-form button.type-submit:hover:not(:disabled),.consul-intention-search-bar .value- span,.consul-kind,.consul-source,.consul-transparent-proxy,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:first-child,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:focus:first-child,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:hover:first-child,.discovery-chain .route-card>header ul li,.informed-action>ul>.dangerous>*,.informed-action>ul>.dangerous>:focus,.informed-action>ul>.dangerous>:hover,.leader,.menu-panel>ul>li.dangerous>:first-child,.menu-panel>ul>li.dangerous>:focus:first-child,.menu-panel>ul>li.dangerous>:hover:first-child,.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,.tab-nav .selected>*,.topology-metrics-source-type,html[data-route^="dc.acls.index"] main td strong,span.policy-node-identity,span.policy-service-identity,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child{border-style:solid}.consul-auth-method-type,.consul-external-source,.consul-kind,.consul-source,.consul-transparent-proxy,.leader,.topology-metrics-source-type,span.policy-node-identity,span.policy-service-identity{background-color:var(--token-color-surface-strong);border-color:var(--token-color-foreground-faint);color:var(--token-color-foreground-primary)}.consul-intention-list td.intent- strong,.consul-intention-search-bar .value- span,.discovery-chain .route-card>header ul li,.modal-dialog [role=document]>footer,.modal-dialog [role=document]>header,html[data-route^="dc.acls.index"] main td strong{background-color:var(--token-color-surface-strong);border-color:var(--token-color-palette-neutral-300);color:var(--token-color-foreground-strong)}.animatable.tab-nav ul::after,.consul-intention-permission-form button.type-submit,.consul-intention-permission-form button.type-submit:disabled,.tab-nav .selected>*{background-color:var(--token-color-surface-primary);border-color:var(--token-color-foreground-action);color:var(--token-color-foreground-action)}.consul-intention-permission-form button.type-submit:focus:not(:disabled),.consul-intention-permission-form button.type-submit:hover:not(:disabled){background-color:var(--token-color-surface-action);border-color:var(--token-color-foreground-action);color:var(--token-color-palette-blue-500)}.consul-intention-action-warn-modal button.dangerous,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:first-child,.informed-action>ul>.dangerous>*,.menu-panel>ul>li.dangerous>:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:first-child{background-color:transparent;border-color:var(--token-color-foreground-critical);color:var(--token-color-foreground-critical)}.consul-intention-action-warn-modal button.dangerous:disabled{background-color:var(--token-color-border-critical);border-color:var(--token-color-foreground-disabled);color:var(--token-color-surface-primary)}.consul-intention-action-warn-modal button.dangerous:focus,.consul-intention-action-warn-modal button.dangerous:hover:not(:disabled):not(:active),.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:focus:first-child,.disclosure-menu [aria-expanded]~*>ul>li.dangerous>:hover:first-child,.informed-action>ul>.dangerous>:focus,.informed-action>ul>.dangerous>:hover,.menu-panel>ul>li.dangerous>:focus:first-child,.menu-panel>ul>li.dangerous>:hover:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.more-popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,.popover-menu>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.has-actions tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:focus:first-child,table.with-details tr>.actions>[type=checkbox]+label+div>ul>li.dangerous>:hover:first-child{background-color:var(--token-color-foreground-critical);border-color:var(--token-color-foreground-critical-high-contrast);color:var(--token-color-surface-primary)}.consul-intention-action-warn-modal button.dangerous:hover:active{background-color:var(--token-color-palette-red-400);border-color:var(--token-color-foreground-critical-high-contrast);color:var(--token-color-surface-primary)}.hover\:scale-125:hover{--tw-scale-x:1.25;--tw-scale-y:1.25}.group:hover .group-hover\:opacity-100{opacity:1} \ No newline at end of file diff --git a/agent/uiserver/dist/assets/consul-ui/routes-e47ed633758c4b43c40de4ae84cdf564.js b/agent/uiserver/dist/assets/consul-ui/routes-447282731d763ac6ad60d55ed447a4a6.js similarity index 97% rename from agent/uiserver/dist/assets/consul-ui/routes-e47ed633758c4b43c40de4ae84cdf564.js rename to agent/uiserver/dist/assets/consul-ui/routes-447282731d763ac6ad60d55ed447a4a6.js index c63b984723..9c841e4bfc 100644 --- a/agent/uiserver/dist/assets/consul-ui/routes-e47ed633758c4b43c40de4ae84cdf564.js +++ b/agent/uiserver/dist/assets/consul-ui/routes-447282731d763ac6ad60d55ed447a4a6.js @@ -1 +1 @@ -((e,t=("undefined"!=typeof document?document.currentScript.dataset:module.exports))=>{t.routes=JSON.stringify(e)})({dc:{_options:{path:"/:dc"},index:{_options:{path:"/",redirect:"../services"}},show:{_options:{path:"/overview",abilities:["access overview"]},serverstatus:{_options:{path:"/server-status",abilities:["read servers"]}},cataloghealth:{_options:{path:"/catalog-health",abilities:["access overview"]}},license:{_options:{path:"/license",abilities:["read license"]}}},services:{_options:{path:"/services"},index:{_options:{path:"/",queryParams:{sortBy:"sort",status:"status",source:"source",kind:"kind",searchproperty:{as:"searchproperty",empty:[["Partition","Name","Tags","PeerName"]]},search:{as:"filter",replace:!0}}}},show:{_options:{path:"/:name"},instances:{_options:{path:"/instances",queryParams:{sortBy:"sort",status:"status",source:"source",searchproperty:{as:"searchproperty",empty:[["Name","Node","Tags","ID","Address","Port","Service.Meta","Node.Meta"]]},search:{as:"filter",replace:!0}}}},intentions:{_options:{path:"/intentions"},index:{_options:{path:"",queryParams:{sortBy:"sort",access:"access",searchproperty:{as:"searchproperty",empty:[["SourceName","DestinationName"]]},search:{as:"filter",replace:!0}}}},edit:{_options:{path:"/:intention_id"}},create:{_options:{template:"../edit",path:"/create"}}},topology:{_options:{path:"/topology"}},services:{_options:{path:"/services",queryParams:{sortBy:"sort",instance:"instance",searchproperty:{as:"searchproperty",empty:[["Name","Tags"]]},search:{as:"filter",replace:!0}}}},upstreams:{_options:{path:"/upstreams",queryParams:{sortBy:"sort",instance:"instance",searchproperty:{as:"searchproperty",empty:[["Name","Tags"]]},search:{as:"filter",replace:!0}}}},routing:{_options:{path:"/routing"}},tags:{_options:{path:"/tags"}}},instance:{_options:{path:"/:name/instances/:node/:id",redirect:"./healthchecks"},healthchecks:{_options:{path:"/health-checks",queryParams:{sortBy:"sort",status:"status",check:"check",searchproperty:{as:"searchproperty",empty:[["Name","Node","CheckID","Notes","Output","ServiceTags"]]},search:{as:"filter",replace:!0}}}},upstreams:{_options:{path:"/upstreams",queryParams:{sortBy:"sort",search:{as:"filter",replace:!0},searchproperty:{as:"searchproperty",empty:[["DestinationName","LocalBindAddress","LocalBindPort"]]}}}},exposedpaths:{_options:{path:"/exposed-paths"}},addresses:{_options:{path:"/addresses"}},metadata:{_options:{path:"/metadata"}}},notfound:{_options:{path:"/:name/:node/:id"}}},nodes:{_options:{path:"/nodes"},index:{_options:{path:"",queryParams:{sortBy:"sort",status:"status",version:"version",searchproperty:{as:"searchproperty",empty:[["Node","Address","Meta","PeerName"]]},search:{as:"filter",replace:!0}}}},show:{_options:{path:"/:name"},healthchecks:{_options:{path:"/health-checks",queryParams:{sortBy:"sort",status:"status",kind:"kind",check:"check",searchproperty:{as:"searchproperty",empty:[["Name","Service","CheckID","Notes","Output","ServiceTags"]]},search:{as:"filter",replace:!0}}}},services:{_options:{path:"/service-instances",queryParams:{sortBy:"sort",status:"status",source:"source",searchproperty:{as:"searchproperty",empty:[["Name","Tags","ID","Address","Port","Service.Meta"]]},search:{as:"filter",replace:!0}}}},rtt:{_options:{path:"/round-trip-time"}},metadata:{_options:{path:"/metadata"}}}},intentions:{_options:{path:"/intentions"},index:{_options:{path:"/",queryParams:{sortBy:"sort",access:"access",searchproperty:{as:"searchproperty",empty:[["SourceName","DestinationName"]]},search:{as:"filter",replace:!0}}}},edit:{_options:{path:"/:intention_id",abilities:["read intentions"]}},create:{_options:{template:"../edit",path:"/create",abilities:["create intentions"]}}},kv:{_options:{path:"/kv"},index:{_options:{path:"/",queryParams:{sortBy:"sort",kind:"kind",search:{as:"filter",replace:!0}}}},folder:{_options:{template:"../index",path:"/*key"}},edit:{_options:{path:"/*key/edit"}},create:{_options:{template:"../edit",path:"/*key/create",abilities:["create kvs"]}},"root-create":{_options:{template:"../edit",path:"/create",abilities:["create kvs"]}}},acls:{_options:{path:"/acls",abilities:["access acls"]},policies:{_options:{path:"/policies",abilities:["read policies"]},edit:{_options:{path:"/:id"}},create:{_options:{path:"/create",abilities:["create policies"]}}},roles:{_options:{path:"/roles",abilities:["read roles"]},edit:{_options:{path:"/:id"}},create:{_options:{path:"/create",abilities:["create roles"]}}},tokens:{_options:{path:"/tokens",abilities:["access acls"]},edit:{_options:{path:"/:id"}},create:{_options:{path:"/create",abilities:["create tokens"]}}},"auth-methods":{_options:{path:"/auth-methods",abilities:["read auth-methods"]},show:{_options:{path:"/:id"},"auth-method":{_options:{path:"/auth-method"}},"binding-rules":{_options:{path:"/binding-rules"}},"nspace-rules":{_options:{path:"/nspace-rules"}}}}},"routing-config":{_options:{path:"/routing-config/:name"}}},index:{_options:{path:"/"}},settings:{_options:{path:"/settings"}},setting:{_options:{path:"/setting",redirect:"../settings"}},notfound:{_options:{path:"/*notfound"}}}) +((e,t=("undefined"!=typeof document?document.currentScript.dataset:module.exports))=>{t.routes=JSON.stringify(e)})({dc:{_options:{path:"/:dc"},index:{_options:{path:"/",redirect:"../services"}},show:{_options:{path:"/overview",abilities:["access overview"]},serverstatus:{_options:{path:"/server-status",abilities:["read servers"]}},cataloghealth:{_options:{path:"/catalog-health",abilities:["access overview"]}},license:{_options:{path:"/license",abilities:["read license"]}}},services:{_options:{path:"/services"},index:{_options:{path:"/",queryParams:{sortBy:"sort",status:"status",source:"source",kind:"kind",searchproperty:{as:"searchproperty",empty:[["Partition","Name","Tags","PeerName"]]},search:{as:"filter",replace:!0}}}},show:{_options:{path:"/:name"},instances:{_options:{path:"/instances",queryParams:{sortBy:"sort",status:"status",source:"source",searchproperty:{as:"searchproperty",empty:[["Name","Node","Tags","ID","Address","Port","Service.Meta","Node.Meta"]]},search:{as:"filter",replace:!0}}}},intentions:{_options:{path:"/intentions"},index:{_options:{path:"",queryParams:{sortBy:"sort",access:"access",searchproperty:{as:"searchproperty",empty:[["SourceName","DestinationName"]]},search:{as:"filter",replace:!0}}}},edit:{_options:{path:"/:intention_id"}},create:{_options:{template:"../edit",path:"/create"}}},topology:{_options:{path:"/topology"}},services:{_options:{path:"/services",queryParams:{sortBy:"sort",instance:"instance",searchproperty:{as:"searchproperty",empty:[["Name","Tags"]]},search:{as:"filter",replace:!0}}}},upstreams:{_options:{path:"/upstreams",queryParams:{sortBy:"sort",instance:"instance",searchproperty:{as:"searchproperty",empty:[["Name","Tags"]]},search:{as:"filter",replace:!0}}}},routing:{_options:{path:"/routing"}},tags:{_options:{path:"/tags"}}},instance:{_options:{path:"/:name/instances/:node/:id",redirect:"./healthchecks"},healthchecks:{_options:{path:"/health-checks",queryParams:{sortBy:"sort",status:"status",check:"check",searchproperty:{as:"searchproperty",empty:[["Name","Node","CheckID","Notes","Output","ServiceTags"]]},search:{as:"filter",replace:!0}}}},upstreams:{_options:{path:"/upstreams",queryParams:{sortBy:"sort",search:{as:"filter",replace:!0},searchproperty:{as:"searchproperty",empty:[["DestinationName","LocalBindAddress","LocalBindPort"]]}}}},exposedpaths:{_options:{path:"/exposed-paths"}},addresses:{_options:{path:"/addresses"}},metadata:{_options:{path:"/metadata"}}},notfound:{_options:{path:"/:name/:node/:id"}}},nodes:{_options:{path:"/nodes"},index:{_options:{path:"",queryParams:{sortBy:"sort",status:"status",version:"version",searchproperty:{as:"searchproperty",empty:[["Node","Address","Meta","PeerName"]]},search:{as:"filter",replace:!0}}}},show:{_options:{path:"/:name"},healthchecks:{_options:{path:"/health-checks",queryParams:{sortBy:"sort",status:"status",kind:"kind",check:"check",searchproperty:{as:"searchproperty",empty:[["Name","Service","CheckID","Notes","Output","ServiceTags"]]},search:{as:"filter",replace:!0}}}},services:{_options:{path:"/service-instances",queryParams:{sortBy:"sort",status:"status",source:"source",searchproperty:{as:"searchproperty",empty:[["Name","Tags","ID","Address","Port","Service.Meta"]]},search:{as:"filter",replace:!0}}}},rtt:{_options:{path:"/round-trip-time"}},metadata:{_options:{path:"/metadata"}}}},intentions:{_options:{path:"/intentions"},index:{_options:{path:"/",queryParams:{sortBy:"sort",access:"access",searchproperty:{as:"searchproperty",empty:[["SourceName","DestinationName"]]},search:{as:"filter",replace:!0}}}},edit:{_options:{path:"/:intention_id",abilities:["read intentions"]}},create:{_options:{template:"../edit",path:"/create",abilities:["create intentions"]}}},kv:{_options:{path:"/kv"},index:{_options:{path:"/",queryParams:{sortBy:"sort",kind:"kind",search:{as:"filter",replace:!0}}}},folder:{_options:{template:"../index",path:"/*key"}},edit:{_options:{path:"/*key/edit"}},create:{_options:{template:"../edit",path:"/*key/create",abilities:["create kvs"]}},"root-create":{_options:{template:"../edit",path:"/create",abilities:["create kvs"]}}},acls:{_options:{path:"/acls",abilities:["access acls"]},policies:{_options:{path:"/policies",abilities:["read policies"]},edit:{_options:{path:"/:id"}},create:{_options:{path:"/create",abilities:["create policies"]}}},roles:{_options:{path:"/roles",abilities:["read roles"]},edit:{_options:{path:"/:id"}},create:{_options:{path:"/create",abilities:["create roles"]}}},tokens:{_options:{path:"/tokens",abilities:["access acls"]},edit:{_options:{path:"/:id"}},create:{_options:{path:"/create",abilities:["create tokens"]}}},"auth-methods":{_options:{path:"/auth-methods",abilities:["read auth-methods"]},show:{_options:{path:"/:id"},"auth-method":{_options:{path:"/auth-method"}},"binding-rules":{_options:{path:"/binding-rules"}},"nspace-rules":{_options:{path:"/nspace-rules"}}}}},"routing-config":{_options:{path:"/routing-config/:name"}}},index:{_options:{path:"/"}},settings:{_options:{path:"/settings"}},setting:{_options:{path:"/setting",redirect:"../settings"}},unavailable:{_options:{path:"/unavailable"}},notfound:{_options:{path:"/*notfound"}}}) diff --git a/agent/uiserver/dist/index.html b/agent/uiserver/dist/index.html index 438fc074ed..18dbc01051 100644 --- a/agent/uiserver/dist/index.html +++ b/agent/uiserver/dist/index.html @@ -13,16 +13,16 @@ - + - - - + + @@ -63,7 +63,7 @@ } - + @@ -81,20 +81,16 @@ {{if .NamespacesEnabled}} {{end}} -{{if .HCPEnabled}} - - -{{end}} - + {{ range .ExtraScripts }} {{ end }} - + From 1f4caaedf22296072a21921536a98944dd82da7c Mon Sep 17 00:00:00 2001 From: Dhia Ayachi Date: Thu, 16 May 2024 13:40:15 -0400 Subject: [PATCH 033/185] upgrade deep-copy version, upgrade go to 1.22.3 (#21113) * upgrade deep-copy version, upgrade go to 1.22.3 * add changelog --- .changelog/21113.txt | 3 +++ .go-version | 2 +- Makefile | 2 +- agent/config/config.deepcopy.go | 13 +++++++++---- agent/consul/state/catalog_schema.deepcopy.go | 5 +---- agent/proxycfg/proxycfg.deepcopy.go | 2 +- agent/structs/structs.deepcopy.go | 2 +- 7 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 .changelog/21113.txt diff --git a/.changelog/21113.txt b/.changelog/21113.txt new file mode 100644 index 0000000000..e1e153f0ac --- /dev/null +++ b/.changelog/21113.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +upgrade go version to v1.22.3. +``` diff --git a/.go-version b/.go-version index ae7bbdf047..98f7da137c 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.21.10 +1.22.3 \ No newline at end of file diff --git a/Makefile b/Makefile index 84900d4c5e..75a7b5b742 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ PROTOC_GEN_GO_GRPC_VERSION='v1.2.0' MOG_VERSION='v0.4.2' PROTOC_GO_INJECT_TAG_VERSION='v1.3.0' PROTOC_GEN_GO_BINARY_VERSION='v0.1.0' -DEEP_COPY_VERSION='bc3f5aa5735d8a54961580a3a24422c308c831c2' +DEEP_COPY_VERSION='e112476c0181d3d69067bac191f9b6bcda2ce812' COPYWRITE_TOOL_VERSION='v0.16.4' LINT_CONSUL_RETRY_VERSION='v1.4.0' # Go imports formatter diff --git a/agent/config/config.deepcopy.go b/agent/config/config.deepcopy.go index 2a5ebfce27..bd9b85fca4 100644 --- a/agent/config/config.deepcopy.go +++ b/agent/config/config.deepcopy.go @@ -1,7 +1,4 @@ -// 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. +// Code generated by deep-copy -pointer-receiver -o ./config.deepcopy.go -type RuntimeConfig ./; DO NOT EDIT. package config @@ -359,6 +356,10 @@ func (o *RuntimeConfig) DeepCopy() *RuntimeConfig { } } } + if o.Cloud.TLSConfig.Certificates[i5].Leaf.Policies != nil { + cp.Cloud.TLSConfig.Certificates[i5].Leaf.Policies = make([]x509.OID, len(o.Cloud.TLSConfig.Certificates[i5].Leaf.Policies)) + copy(cp.Cloud.TLSConfig.Certificates[i5].Leaf.Policies, o.Cloud.TLSConfig.Certificates[i5].Leaf.Policies) + } } } } @@ -698,6 +699,10 @@ func (o *RuntimeConfig) DeepCopy() *RuntimeConfig { } } } + if v5.Leaf.Policies != nil { + cp_Cloud_TLSConfig_NameToCertificate_v5.Leaf.Policies = make([]x509.OID, len(v5.Leaf.Policies)) + copy(cp_Cloud_TLSConfig_NameToCertificate_v5.Leaf.Policies, v5.Leaf.Policies) + } } } cp.Cloud.TLSConfig.NameToCertificate[k5] = cp_Cloud_TLSConfig_NameToCertificate_v5 diff --git a/agent/consul/state/catalog_schema.deepcopy.go b/agent/consul/state/catalog_schema.deepcopy.go index af4d430d2f..43937edd87 100644 --- a/agent/consul/state/catalog_schema.deepcopy.go +++ b/agent/consul/state/catalog_schema.deepcopy.go @@ -1,7 +1,4 @@ -// 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. +// Code generated by deep-copy -pointer-receiver -o ./catalog_schema.deepcopy.go -type upstreamDownstream ./; DO NOT EDIT. package state diff --git a/agent/proxycfg/proxycfg.deepcopy.go b/agent/proxycfg/proxycfg.deepcopy.go index 669a519094..1922810fe5 100644 --- a/agent/proxycfg/proxycfg.deepcopy.go +++ b/agent/proxycfg/proxycfg.deepcopy.go @@ -1,4 +1,4 @@ -// generated by deep-copy -pointer-receiver -o ./proxycfg.deepcopy.go -type ConfigSnapshot -type ConfigSnapshotUpstreams -type PeerServersValue -type PeeringServiceValue -type configSnapshotAPIGateway -type configSnapshotConnectProxy -type configSnapshotIngressGateway -type configSnapshotMeshGateway -type configSnapshotTerminatingGateway ./; DO NOT EDIT. +// Code generated by deep-copy -pointer-receiver -o ./proxycfg.deepcopy.go -type ConfigSnapshot -type ConfigSnapshotUpstreams -type PeerServersValue -type PeeringServiceValue -type configSnapshotAPIGateway -type configSnapshotConnectProxy -type configSnapshotIngressGateway -type configSnapshotMeshGateway -type configSnapshotTerminatingGateway ./; DO NOT EDIT. package proxycfg diff --git a/agent/structs/structs.deepcopy.go b/agent/structs/structs.deepcopy.go index 7d26a76469..52621d2c91 100644 --- a/agent/structs/structs.deepcopy.go +++ b/agent/structs/structs.deepcopy.go @@ -1,4 +1,4 @@ -// generated by deep-copy -pointer-receiver -o ./structs.deepcopy.go -type APIGatewayListener -type BoundAPIGatewayListener -type CARoot -type CheckServiceNode -type CheckType -type CompiledDiscoveryChain -type ConnectProxyConfig -type DiscoveryFailover -type DiscoveryGraphNode -type DiscoveryResolver -type DiscoveryRoute -type DiscoverySplit -type ExposeConfig -type ExportedServicesConfigEntry -type FileSystemCertificateConfigEntry -type GatewayService -type GatewayServiceTLSConfig -type HTTPHeaderModifiers -type HTTPRouteConfigEntry -type HashPolicy -type HealthCheck -type IndexedCARoots -type IngressListener -type InlineCertificateConfigEntry -type Intention -type IntentionPermission -type LoadBalancer -type MeshConfigEntry -type MeshDirectionalTLSConfig -type MeshTLSConfig -type Node -type NodeService -type PeeringServiceMeta -type ServiceConfigEntry -type ServiceConfigResponse -type ServiceConnect -type ServiceDefinition -type ServiceResolverConfigEntry -type ServiceResolverFailover -type ServiceRoute -type ServiceRouteDestination -type ServiceRouteMatch -type ServiceSpecificRequest -type TCPRouteConfigEntry -type Upstream -type UpstreamConfiguration -type Status -type BoundAPIGatewayConfigEntry ./; DO NOT EDIT. +// Code generated by deep-copy -pointer-receiver -o ./structs.deepcopy.go -type APIGatewayListener -type BoundAPIGatewayListener -type CARoot -type CheckServiceNode -type CheckType -type CompiledDiscoveryChain -type ConnectProxyConfig -type DiscoveryFailover -type DiscoveryGraphNode -type DiscoveryResolver -type DiscoveryRoute -type DiscoverySplit -type ExposeConfig -type ExportedServicesConfigEntry -type FileSystemCertificateConfigEntry -type GatewayService -type GatewayServiceTLSConfig -type HTTPHeaderModifiers -type HTTPRouteConfigEntry -type HashPolicy -type HealthCheck -type IndexedCARoots -type IngressListener -type InlineCertificateConfigEntry -type Intention -type IntentionPermission -type LoadBalancer -type MeshConfigEntry -type MeshDirectionalTLSConfig -type MeshTLSConfig -type Node -type NodeService -type PeeringServiceMeta -type ServiceConfigEntry -type ServiceConfigResponse -type ServiceConnect -type ServiceDefinition -type ServiceResolverConfigEntry -type ServiceResolverFailover -type ServiceRoute -type ServiceRouteDestination -type ServiceRouteMatch -type ServiceSpecificRequest -type TCPRouteConfigEntry -type Upstream -type UpstreamConfiguration -type Status -type BoundAPIGatewayConfigEntry ./; DO NOT EDIT. package structs From b9e84375a4e815bc621bba17a3a603ca94a56a28 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Mon, 20 May 2024 08:42:58 -0700 Subject: [PATCH 034/185] docs: FIPS certification (#21131) * FIPS section * small updates * remove month * backticks --- website/content/docs/enterprise/fips.mdx | 25 +++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/website/content/docs/enterprise/fips.mdx b/website/content/docs/enterprise/fips.mdx index 0aca1ad207..dc4d2ed3bc 100644 --- a/website/content/docs/enterprise/fips.mdx +++ b/website/content/docs/enterprise/fips.mdx @@ -2,7 +2,7 @@ layout: docs page_title: FIPS 140-2 description: >- - A version of Consul compliant with FIPS 140-2 is available to Enterprise users. Learn about where to find FIPS-compliant versions of Consul, as well as usage restrictions and technical details. + A version of Consul compliant with FIPS 140-2 is available to Enterprise users. Learn about where to find FIPS-compliant versions of Consul, its usage restrictions, technical details, and Leidos validation. --- # FIPS 140-2 @@ -17,9 +17,9 @@ To use this feature, you must have an [active or trial license for Consul Enterp ## Using FIPS 140-2 Consul Enterprise -FIPS 140-2 builds of Consul Enterprise behave in the same way as non-FIPS builds. There are no restrictions on Consul algorithms and ensuring that Consul remains in a FIPS-compliant mode of operation is your responsibility. To maintain FIPS-compliant operation, you must [ensure that TLS is enabled](/consul/tutorials/security/tls-encryption-secure) so that communication is encrypted. Consul products surface some helpful warnings where settings are insecure. +FIPS 140-2 builds of Consul Enterprise behave in the same way as non-FIPS builds. There are no restrictions on Consul algorithms and ensuring that Consul remains in a FIPS-compliant mode of operation is your responsibility. To maintain FIPS-compliant operation, you must [ensure that TLS is enabled](/consul/tutorials/archive/tls-encryption-secure) so that communication is encrypted. Consul products surface some helpful warnings where settings are insecure. -Encryption is disabled in Consul Enterprise by default. As a result, Consul may transmit sensitive control plane information. You must ensure that gossip encryption and mTLS is enabled for all agents when running Consul with FIPS-compliant settings. In addition, be aware that TLSv1.3 does not work with FIPS 140-2, as HKDF is not a certified primitive. +Encryption is disabled in Consul Enterprise by default. As a result, Consul may transmit sensitive control plane information. You must ensure that gossip encryption and mTLS is enabled for all agents when running Consul with FIPS-compliant settings. In addition, be aware that TLS v1.3 does not work with FIPS 140-2, as HKDF is not a certified primitive. HashiCorp is not a NIST-certified testing laboratory and can only provide general guidance about using Consul Enterprise in a FIPS-compliant manner. We recommend consulting an approved auditor for further information. @@ -45,6 +45,7 @@ When using Consul Enterprise with FIPS 140-2, be aware of the following operatio We do not support in-place migrations from non-FIPS builds of Consul to FIPS builds of Consul, regardless of version. A fresh cluster installation is required to support FIPS 140-2. You cannot upgrade directly to a FIPS-compliant build. #### TLS restrictions + Consul Enterprise's FIPS modifications include restrictions to supported TLS cipher suites and key information. Only the following cipher suites are allowed: - `TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256` @@ -125,7 +126,21 @@ Similarly, on a FIPS Windows binary, run `go tool nm` on the binary to get a sym On both Linux and Windows non-FIPS builds, the search output yields no results. -### Compliance validation +## Leidos validation -A Lab, authorized by the U.S. Government to certify FIPS 140-2 compliance, is in the process of verifying that Consul Enterprise and its related packages are compliant with the requirements of FIPS 140-2 Level 1. +In 2024, Leidos certified the integration of FIPS 140-2 cryptographic module [BoringCrypto Cert. #4407](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/4407) for the following Consul releases: +- Consul Enterprise builds: + - [`consul_1.16.0+ent.fips1402`](https://releases.hashicorp.com/consul/1.16.0+ent.fips1402/) + - [`consul_1.16.1+ent.fips1402`](https://releases.hashicorp.com/consul/1.16.1+ent.fips1402/) +- Consul Dataplane builds: + - [`consul-dataplane_1.2.0+fips1402`](https://releases.hashicorp.com/consul-dataplane/1.2.0+fips1402/) + - [`consul-dataplane_1.2.1+fips1402`](https://releases.hashicorp.com/consul-dataplane/1.2.1+fips1402/) +- Consul K8s builds: + - [`consul-k8s_1.2.0+fips1402`](https://releases.hashicorp.com/consul-k8s/1.2.0+fips1402/) + - [`consul-k8s_1.2.1+fips1402`](https://releases.hashicorp.com/consul-k8s/1.2.1+fips1402/) +- Consul K8s Control Plane builds: + - [`consul-k8s-control-plane_1.2.0+fips1402`](https://releases.hashicorp.com/consul-k8s-control-plane/1.2.0+fips1402/) + - [`consul-k8s-control-plane_1.2.1+fips1402`](https://releases.hashicorp.com/consul-k8s-control-plane/1.2.2+fips1402/) + +For more information about verified platform architectures and confirmed feature support, [review the Leidos certification letter](https://www.datocms-assets.com/2885/1715791547-boringcrypto_compliance_letter_signed.pdf). \ No newline at end of file From f12ba3f2a52e2c04a0b5cb5118d326b5af19b487 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Mon, 20 May 2024 16:25:59 -0400 Subject: [PATCH 035/185] chore: fix PR Labeler config (#21141) chore: fix PR labeler config format --- .github/pr-labeler.yml | 94 +++++++++++++++++++++++--------- .github/workflows/pr-labeler.yml | 10 ++-- 2 files changed, 74 insertions(+), 30 deletions(-) diff --git a/.github/pr-labeler.yml b/.github/pr-labeler.yml index fd39f2ccab..10db39816d 100644 --- a/.github/pr-labeler.yml +++ b/.github/pr-labeler.yml @@ -2,45 +2,75 @@ # SPDX-License-Identifier: BUSL-1.1 pr/dependencies: - - vendor/**/* - - go.* + - changed-files: + - any-glob-to-any-file: + - vendor/**/* + - go.* theme/acls: - - acl/**/* + - changed-files: + - any-glob-to-any-file: + - acl/**/* theme/agent-cache: - - agent/cache/**/* + - changed-files: + - any-glob-to-any-file: + - agent/cache/**/* theme/api: - - api/**/* + - changed-files: + - any-glob-to-any-file: + - api/**/* theme/catalog: - - agent/catalog/**/* + - changed-files: + - any-glob-to-any-file: + - agent/catalog/**/* theme/certificates: - - tlsutil/**/* + - changed-files: + - any-glob-to-any-file: + - tlsutil/**/* theme/cli: - - command/**/* + - changed-files: + - any-glob-to-any-file: + - command/**/* theme/config: - - agent/config/**/* + - changed-files: + - any-glob-to-any-file: + - agent/config/**/* theme/connect: - - connect/**/* - - agent/connect/**/* + - changed-files: + - any-glob-to-any-file: + - connect/**/* + - agent/connect/**/* # theme/consul-nomad: theme/consul-terraform-sync: - - website/content/docs/nia/**/* - - website/content/docs/integrate/nia* + - changed-files: + - any-glob-to-any-file: + - website/content/docs/nia/**/* + - website/content/docs/integrate/nia* # theme/consul-vault: theme/contributing: - - .github/**/* + - changed-files: + - any-glob-to-any-file: + - .github/**/* theme/dns: - - dns/**/* + - changed-files: + - any-glob-to-any-file: + - dns/**/* theme/envoy/xds: - - agent/xds/**/* + - changed-files: + - any-glob-to-any-file: + - agent/xds/**/* # theme/federation-usability: theme/health-checks: - - agent/health* - - api/health* + - changed-files: + - any-glob-to-any-file: + - agent/health* + - api/health* # theme/ingress-gw: # theme/internal-cleanup: theme/internals: - - lib/**/* - - types/**/* + - changed-files: + - any-glob-to-any-file: + - lib/**/* + - types/**/* # theme/kubernetes: # theme/mesh-gw: # theme/operator-usability: @@ -48,19 +78,31 @@ theme/internals: # theme/service-metadata: # theme/streaming: theme/telemetry: - - logging/**/* + - changed-files: + - any-glob-to-any-file: + - logging/**/* # theme/terminating-gw: theme/testing: - - ./*test*/**/* + - changed-files: + - any-glob-to-any-file: + - ./*test*/**/* theme/tls: - - tlsutil/**/* + - changed-files: + - any-glob-to-any-file: + - tlsutil/**/* theme/ui: - - ui/**/* + - changed-files: + - any-glob-to-any-file: + - ui/**/* # theme/windows: # thinking: # type/bug: type/ci: - - .github/workflows/* + - changed-files: + - any-glob-to-any-file: + - .github/workflows/* # type/crash: type/docs: - - website/**/* + - changed-files: + - any-glob-to-any-file: + - website/**/* diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 579e7cbb65..409ba8c8cf 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -1,6 +1,6 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + name: "Pull Request Labeler" on: pull_request_target: @@ -10,7 +10,9 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 + - name: 'Checkout repo' + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/pr-labeler.yml From 1c0f6e559796cdc5389b7941ebb36c8a9c1296f8 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Mon, 20 May 2024 14:04:10 -0700 Subject: [PATCH 036/185] docs: Well Architected Framework content migration (#21099) * Migration * move page --- website/content/docs/agent/monitor/alerts.mdx | 83 +++++++ .../content/docs/agent/monitor/components.mdx | 121 ++++++++++ .../docs/agent/{ => monitor}/telemetry.mdx | 0 .../docs/connect/observability/service.mdx | 212 ++++++++++++++++++ website/data/docs-nav-data.json | 21 +- 5 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 website/content/docs/agent/monitor/alerts.mdx create mode 100644 website/content/docs/agent/monitor/components.mdx rename website/content/docs/agent/{ => monitor}/telemetry.mdx (100%) create mode 100644 website/content/docs/connect/observability/service.mdx diff --git a/website/content/docs/agent/monitor/alerts.mdx b/website/content/docs/agent/monitor/alerts.mdx new file mode 100644 index 0000000000..d8dcc90247 --- /dev/null +++ b/website/content/docs/agent/monitor/alerts.mdx @@ -0,0 +1,83 @@ +--- +layout: docs +page_title: Consul monitoring and alerts recommendations +description: >- + Apply best practices towards Consul monitoring and alerts. +--- + +# Consul monitoring and alerts recommendations + +This document will guide you through which host resources to monitor and how monitoring tools can help you set up alerts to notify you when your Consul cluster exceeds its limits. By monitoring Consul and setting up alerts, you can ensure Consul works as expected for all your service discovery and service mesh needs. + +## Instance level monitoring + +While each host environment and Consul deployment is unique, these recommendations can serve as a starting point for you to reference to meet the unique needs of your deployment. + +A Consul datacenter is the smallest unit of Consul infrastructure that can perform basic Consul operations like service discovery or service mesh. A datacenter contains at least one Consul server agent, but a real-world deployment contains three or five server agents and several Consul client agents. + +Consul server agents store all state information, including service and node IP addresses, health checks, and configuration. Consul clients report node and service health status to the Consul cluster. In a typical deployment, you must run client agents on every compute node in your datacenter. If you have Kubernetes workloads, you can also run Consul with an alternate service mesh configuration that deploys Envoy proxies but not client agents. Refer to [Simplified service mesh with Consul dataplanes](/consul/docs/connect/dataplane) for more information. + +We recommend monitoring the following parameters for Consul agents health: +- Disk space and file handles +- [RAM utilization](/consul/docs/agent/telemetry#memory-usage) +- CPU utilization +- Network activity and utilization + +We recommend using an [application performance monitoring (APM) system](#monitoring-tools) to track these metrics. For a full list of key metrics, visit the [Key metrics](/consul/docs/agent/telemetry#key-metrics) section of Telemetry documentation. + +## Recommendations for host-level alerts + +We recommend starting with a small cluster for most initial production deployments or for testing environments. For production environments with a consistently high workload, we recommend large clusters . Refer to the [Consul capacity planning](/well-architected-framework/reliability/reliability-consul-capacity-planning#minimum-hardware-requirements) article for more information. + +When collecting metrics, it is important to establish a baseline. This baseline ensures your Consul deployment is healthy, and serves as a reference point when troubleshooting abnormal Cluster behavior. Complete the [Monitor Consul datacenter health](/consul/tutorials/day-2-operations/monitor-datacenter-health#how-to-collect-metrics) tutorial to learn how to collect metrics. + +Once you have established a baseline for your metrics, use them and the following recommendations to configure reasonable alerts for your Consul agent. + +### Memory alert recommendations + +Consul uses RAM as the primary storage for data on its leader node, while periodically flushing it to disk. Reference the [Memory usage](/consul/docs/agent/telemetry#memory-usage) section of the Telemetry documentation for more details. The recommended instance type depends on your hosting provider. Refer to the [Hardware sizing for Consul servers](/consul/tutorials/production-deploy/reference-architecture#hardware-sizing-for-consul-servers) for recommended instance types for most cloud providers along with other up-to-date hardware recommendations. + +When determining how much RAM you should allocate, we recommend enough RAM for your server agents to contain between 2 to 4 times the working set size. You can determine the working set size by noting the value of `consul.runtime.alloc_bytes` in the telemetry data. + +Set up an alert if your RAM usage exceeds a reasonable threshold (for example, 90% of your allocated RAM). + +### CPU alert recommendations + +Your Consul servers should scale up to handle peak CPU load, not idle load. When idle, Consul servers are waiting to react to changes in service health, placement, or other configuration. If there are any service state changes, the Consul server has to notify all impacted Consul clients simultaneously. For example, if the Consul server has to notify hundreds or thousands of Consul clients of a service state update, the Consul server CPU may spike. + +If this happens, your monitoring dashboard will show a CPU spike on all servers immediately after a big registration/deregistration operation. This should not happen — you should be able to do a rollout or other high-change operation without taxing the Consul servers. + +Set up an alert to detect CPU spikes on your Consul server agents. When this happens, evaluate the size of your Consul servers and upgrade them accordingly. + +### Network recommendations + +The data sent between all Consul agents must follow latency requirements for total round trip time (RTT): + +Average RTT for all traffic cannot exceed 50ms. +RTT for 99 percent of traffic cannot exceed 100ms. + +Refer to the [Reference architecture](/consul/tutorials/production-deploy/reference-architecture#network-latency-and-bandwidth) to learn more about network latency and bandwidth guidance. + +Set an alert to detect when the RTT exceeds these values. When this happens, Therefore, you should monitor metrics related to the host's network latency so the RTT does not exceed these values. + +### Monitoring Consul using Prometheus and Grafana + +Time series based observability tools, such as Grafana and Prometheus, help you monitor the health of Consul clusters over long intervals of time. Refer to the +[Monitoring for Layer 7 observability with Prometheus, Grafana, and Kubernetes](/consul/tutorials/day-2-operations/kubernetes-layer7-observability) tutorial for additional information. + +### Monitoring Consul using Datadog + +Datadog is a SaaS-based monitoring and analytics platform for large-scale applications and infrastructure. It is one of the supported platforms for monitoring Consul. Datadogs agents run on your host reporting logs, metrics and traces. By configuring Datadog agents on your Consul server and client instances, you can monitor your Consul cluster's health. + +Refer to the following resources for more information: + +- [Setup Consul logging with DataDog](https://www.datadoghq.com/blog/consul-datadog/) +- [Datadog monitoring solutions brief](https://www.datocms-assets.com/2885/1576713622-datadog-consul.pdf) +- [Hashicorp partner portal for Consul support on Datadog](https://www.hashicorp.com/partners/tech/datadog#consul) + +## Next steps + +In this guide, you learned which host resources to monitor and how monitoring tools can help you set up alerts to notify you when your Consul cluster exceeds its limits. + +- To learn about monitoring the Consul control and data plane, visit our [Monitoring Consul components](/well-architected-framework/reliability/reliability-consul-monitoring-consul-components) documentation. +- Complete the [Monitor Consul datacenter health with Telegraf](/consul/tutorials/day-2-operations/monitor-health-telegraf) tutorial for additional metrics and alerting recommendations. diff --git a/website/content/docs/agent/monitor/components.mdx b/website/content/docs/agent/monitor/components.mdx new file mode 100644 index 0000000000..958b62260b --- /dev/null +++ b/website/content/docs/agent/monitor/components.mdx @@ -0,0 +1,121 @@ +--- +layout: docs +page_title: Monitoring Consul components +description: >- + Apply best practices monitoring your Consul control and data plane. +--- + +# Monitoring Consul components + +This document will guide you recommendations for monitoring your Consul control and data plane. By keeping track of these components and setting up alerts, you can better maintain the overall health and resilience of your service mesh. + +## Background + +A Consul datacenter is the smallest unit of Consul infrastructure that can perform basic Consul operations like service discovery or service mesh. A datacenter contains at least one Consul server agent, but a real-world deployment contains three or five server agents and several Consul client agents. + +The Consul control plane consists of server agents that store all state information, including service and node IP addresses, health checks, and configuration. In addition, the control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. In addition, the control plane contains client agents that report node and service health status to the Consul cluster. In a typical deployment, you must run client agents on every compute node in your datacenter. + +The Consul data plane consists of proxies deployed locally alongside each service instance. These proxies, called sidecar proxies, receive mesh configuration data from the control plane, and control network communication between their local service instance and other services in the network. The sidecar proxy handles inbound and outbound service connections, and ensures TLS connections between services are both verified and encrypted. + +If you have Kubernetes workloads, you can also run Consul with an alternate service mesh configuration that deploys Envoy proxies but not client agents. Refer to [Simplified service mesh with Consul dataplanes](/consul/docs/connect/dataplane) for more information. + +## Consul control plane monitoring + +The Consul control plane consists of the following components: + +- RPC Communication between Consul servers and clients. +- Data plane routing instructions for the Envoy Layer 7 proxy. +- Serf Traffic: LAN and WAN +- Consul cluster peering and server federation + +It is important to monitor and establish baseline and alert thresholds for Consul control plane components for abnormal behavior detection. Note that these alerts can also be triggered by some planned events like Consul cluster upgrades, configuration changes, or leadership change. + +To help monitor your Consul control plane, we recommend to establish a baseline and standard deviation for the following: + +- [Server health](/consul/docs/agent/telemetry#server-health) +- [Leadership changes](/consul/docs/agent/telemetry#leadership-changes) +- [Key metrics](/consul/docs/agent/telemetry#key-metrics) +- [Autopilot](/consul/docs/agent/telemetry#autopilot) +- [Network activity](/consul/docs/agent/telemetry#network-activity-rpc-count) +- [Certificate authority expiration](/consul/docs/agent/telemetry#certificate-authority-expiration) + +It is important to have a highly performant network with low network latency. Ensure network latency for gossip in all datacenters are within the 8ms latency budget for all Consul agents. View the [Production server requirements](/consul/docs/install/performance#production-server-requirements) for more information. + +### Raft recommendations + +Consul uses [Raft for consensus protocol](/consul/docs/architecture/consensus). High saturation of the Raft goroutines can lead to elevated latency in the rest of the system and may cause the Consul cluster to be unstable. As a result, it is important to monitor Raft to track your control plane health. We recommend the following actions to keep control plane healthy: +- Create an alert that notifies you when [Raft thread saturation](/consul/docs/agent/telemetry#raft-thread-saturation) exceeds 50%. +- Monitor [Raft replication capacity](/consul/docs/agent/telemetry#raft-replication-capacity-issues) when Consul is handling large amounts of data and high write throughput. +- Lower [`raft_multiplier`](/consul/docs/install/performance#production) to keep your Consul cluster stable. The value of `raft_multiplier` defines the scaling factor for Consul. Default value for raft_multiplier is 5. + + A short multiplier minimizes failure detection and election time but may trigger frequently in high latency situations. This can cause constant leadership churn and associated unavailability. A high multiplier reduces the chances that spurious failures will cause leadership churn but it does this at the expense of taking longer to detect real failures and thus takes longer to restore Consul cluster availability. + + Wide networks with higher latency will perform better with larger `raft_multipler` values. + +Raft uses BoltDB for storing data and maintaining its own state. Refer to the [Bolt DB performance metrics](/consul/docs/agent/telemetry#bolt-db-performance) when you are troubleshooting Raft performance issues. + +## Consul data plane monitoring + +The data plane of Consul consists of Consul clients or [Connect proxies](/consul/docs/connect/proxies) interacting with each other through service-to-service communication. Service-to-service traffic always stays within the data plane, while the control plane only enforces traffic rules. Monitoring service-to-service communication is important but may become extremely complex in an enterprise setup with multiple services communicating to each other across federated Consul clusters through mesh, ingress and terminating gateways. + +### Service monitoring + +You can extract the following service-related information: + +- Use the [`catalog`](/consul/commands/catalog) command or the Consul UI to query all registered services in a Consul datacenter. +- Use the [`/agent/service/:service_id`](/consul/api-docs/agent/service#get-service-configuration) API endpoint to query individual services. Connect proxies use this endpoint to discover embedded configuration. + +### Proxy monitoring + +Envoy is the supported Connect proxy for Consul service mesh. For virtual machines (VMs), Envoy starts as a sidecar service process. For Kubernetes, Envoy starts as a sidecar container in a Kubernetes service pod. +Refer to the [Supported Envoy versions](/consul/docs/connect/proxies/envoy#supported-versions) documentation to find the compatible Envoy versions for your version of Consul. + +For troubleshooting service mesh issues, set Consul logs to `trace` or `debug`. The following example annotation sets Envoy logging to `debug`. + +```yaml +annotations: + consul.hashicorp.com/envoy-extra-args: '--log-level debug --disable-hot-restart' +``` + +Refer to the [Enable logging on Envoy sidecar pods](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-envoy-extra-args) documention for more information. + +#### Envoy Admin Interface + +To troubleshoot service-to-service communication issues, monitor Envoy host statistics. Envoy exposes a local administration interface that can be used to query and modify different aspects of the server on port `19000` by default. Envoy also exposes a public listener port to receive mTLS connections from other proxies in the mesh on port `20000` by default. + +All endpoints exposed by Envoy are available at the node running Envoy on port `19000`. The node can either be a pod in Kubernetes or VM running Consul Service Mesh. For example, if you forward the Envoy port to your local machine, you can access the Envoy admin interface at `http://localhost:19000/`. + +The following Envoy admin interface endpoints are particularly useful: + +- The `listeners` endpoint lists all listeners running on `localhost`. This allows you to confirm whether the upstream services are binding correctly to Envoy. + +```shell-session +$ curl http://localhost:19000/listeners +public_listener:192.168.19.168:20000::192.168.19.168:20000 +Outbound_listener:127.0.0.1:15001::127.0.0.1:15001 +``` + +- The `/clusters` endpoint displays information about the xDS clusters, such as service requests and mTLS related data. The following example shows a truncated output. + +```shell-session +$ http://localhost:19000/clusters +`local_app::observability_name::local_app +local_app::default_priority::max_connections::1024 +local_app::default_priority::max_pending_requests::1024 +local_app::default_priority::max_requests::1024 +local_app::default_priority::max_retries::3 +local_app::high_priority::max_connections::1024 +local_app::high_priority::max_pending_requests::1024 +local_app::high_priority::max_requests::1024 +local_app::high_priority::max_retries::3 +local_app::added_via_api::true +## ... +``` + +Visit the main admin interface (`http://localhost:19000`) to find the full list of possible Consul admin endpoints. Refer to the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/operations/admin) for more information. + +## Next steps + +In this guide, you learned recommendations for monitoring your Consul control and data plane. + +To learn about monitoring the Consul host and instance resources, visit our [Monitoring best practices](/well-architected-framework/reliability/reliability-monitoring-service-to-service-communication-with-envoy) documentation. diff --git a/website/content/docs/agent/telemetry.mdx b/website/content/docs/agent/monitor/telemetry.mdx similarity index 100% rename from website/content/docs/agent/telemetry.mdx rename to website/content/docs/agent/monitor/telemetry.mdx diff --git a/website/content/docs/connect/observability/service.mdx b/website/content/docs/connect/observability/service.mdx new file mode 100644 index 0000000000..55b4580aff --- /dev/null +++ b/website/content/docs/connect/observability/service.mdx @@ -0,0 +1,212 @@ +--- +layout: docs +page_title: Monitoring service-to-service communication with Envoy +description: >- + Learn to monitor the appropriate metrics when using Envoy proxy. +--- + +# Monitoring service-to-service communication with Envoy + +When running a service mesh with Envoy as the proxy, there are a wide array of possible metrics produced from traffic flowing through the data plane. This document covers a set of scenarios and key baseline metrics and potential alerts that will help you maintain the overall health and resilience of the mesh for HTTP services. In addition, it provides examples of using these metrics in specific ways to generate a Grafana dashboard using a Prometheus backend to better understand how the metrics behave. + +When collecting metrics, it is important to establish a baseline. This baseline ensures your Consul deployment is healthy, and serves as a reference point when troubleshooting abnormal Cluster behavior. Once you have established a baseline for your metrics, use them and the following recommendations to configure reasonable alerts for your Consul agent. + + + + The following examples assume that the operator adds the cluster name (i.e. datacenter) using the label “cluster” and the node name (i.e. machine or pod) using the label “node” to all scrape targets. + + + +## General scenarios + +### Is Envoy's configuration growing stale? + +When Envoy connects to the Consul control plane over xDS, it will rapidly converge to the current configuration that the control plane expects it to have. If the xDS stream terminates and does not reconnect for an extended period, then the xDS configuration currently in the Envoy instances will “fail static” and slowly grow out of date. + +##### Metric + +`envoy_control_plane_connected_state` + +#### Alerting + +If the value for a given node/pod/machine was 0 for an extended period of time. + +#### Example dashboard (table) + +``` +group(last_over_time(envoy_control_plane_connected_state{cluster="$cluster"}[1m] ) == 0) by (node) +``` + +## Inbound traffic scenarios + +### Is this service being sent requests? + +Within a mesh, a request travels from one service to another. You may choose to measure many relevant metrics from the calling-side, the serving-side, or both. + +It is useful to track the perceived request rate of requests from the calling-side as that would include all requests, even those that fail to arrive at the serving-side due to any failures. + +Any measurement of the request rate is also generally useful for capacity planning purposes as increased traffic typically correlates with a need for a scale-up event in the near future. + +##### Metric + +`envoy_cluster_upstream_rq_total` + +#### Alerting + +If the value has a significant change, check if services are properly interacting with each other and if you need to increase your Consul agent resource requirements. + +#### Example dashboard (plot; rate) + +``` +sum(irate(envoy_cluster_upstream_rq_total{consul_destination_datacenter="$cluster", +consul_destination_service="$service"}[1m])) by (cluster, local_cluster) +``` + +### Are requests sent to this service mostly successful? + +A service mesh is about communication between services, so it is important to track the perceived success rate of requests witnessed by the calling services. + +##### Metric + +`envoy_cluster_upstream_rq_xx` + +#### Alerting + +If the value crosses a user defined baseline. + +#### Example dashboard (plot; %) + +``` +sum(irate(envoy_cluster_upstream_rq_xx{envoy_response_code_class!="5",consul_destination_datacenter="$cluster",consul_destination_service="$service"}[1m])) by (cluster, local_cluster) / sum(irate(envoy_cluster_upstream_rq_xx{consul_destination_datacenter="$cluster",consul_destination_service="$service"}[1m])) by (cluster, local_cluster) +``` + +### Are requests sent to this service handled in a timely manner? + +If you undersize your infrastructure from a resource perspective, then you may expect a decline in response speed over time. You can track this by plotting the 95th percentile of the latency as experienced by the clients. + +##### Metric + +`envoy_cluster_upstream_rq_time_bucket` + +#### Alerting + +If the value crosses a user defined baseline. + +#### Example dashboard (plot; value) + +``` +histogram_quantile(0.95, sum(rate(envoy_cluster_upstream_rq_time_bucket{consul_destination_datacenter="$cluster",consul_destination_service="$service",local_cluster!=""}[1m])) by (le, cluster, local_cluster)) +``` + +### Is this service responding to requests that it receives? + +Unlike the perceived request rate, which is measured from the calling side, this is the real request rate measured on the serving-side. This is a serving-side parallel metric that can help clarify underlying causes of problems in the calling-side equivalent metric. Ideally this metric should roughly track the calling side values in a 1-1 manner. + +##### Metric + +`envoy_http_downstream_rq_total` + +#### Alerting + +If the value crosses a user defined baseline. + +#### Example dashboard (plot; rate) + +``` +sum(irate(envoy_http_downstream_rq_total{cluster="$cluster",local_cluster="$service",envoy_http_conn_manager_prefix="public_listener"}[1m])) +``` + +### Are responses from this service mostly successful? + +Unlike the perceived success rate of requests, which is measured from the calling side, this is the real success rate of requests measured on the serving-side. This is a serving-side parallel metric that can help clarify underlying causes of problems in the calling-side equivalent metric. Ideally this metric should roughly track the calling side values in a 1-1 manner. + +##### Metrics + +`envoy_http_downstream_rq_total` + +`envoy_http_downstream_rq_xx` + +#### Alerting + +If the value crosses a user defined baseline. + +#### Example dashboard (plot; %) + +##### Total + +``` +sum(increase(envoy_http_downstream_rq_total{cluster="$cluster",local_cluster="$service",envoy_http_conn_manager_prefix="public_listener"}[1m])) +``` + +##### BY STATUS CODE: + +``` +sum(increase(envoy_http_downstream_rq_xx{cluster="$cluster",local_cluster="$service",envoy_http_conn_manager_prefix="public_listener"}[1m])) by (envoy_response_code_class) +``` + +## Outbound traffic scenarios + +### Is this service sending traffic to its upstreams? + +Similar to the real request rate for requests arriving at a service, it may be helpful to view the perceived request rate departing from a service through its upstreams. + +##### Metric + +`envoy_cluster_upstream_rq_total` + +#### Alerting + +If the value crosses a user defined success threshold. + +#### Example dashboard (plot; rate) + +``` +sum(irate(envoy_cluster_upstream_rq_total{cluster="$cluster", +local_cluster="$service", +consul_destination_target!=""}[1m])) by (consul_destination_target) +``` + +### Are requests from this service to its upstreams mostly successful? + +Similar to the real success rate of requests arriving at a service, it is also important to track the perceived success rate of requests departing from a service through its upstreams. + +##### Metric + +`envoy_cluster_upstream_rq_xx` + +#### Alerting + +If the value crosses a user defined success threshold. + +#### Example dashboard (plot; value) + +``` +sum(irate(envoy_cluster_upstream_rq_xx{envoy_response_code_class!="5", +cluster="$cluster",local_cluster="$service", +consul_destination_target!=""}[1m])) by (consul_destination_target) / sum(irate(envoy_cluster_upstream_rq_xx{cluster="$cluster",local_cluster="$service",consul_destination_target!=""}[1m])) by (consul_destination_target) +``` + +### Are requests from this service to its upstreams handled in a timely manner? + +Similar to the latency of requests departing for a service, it is useful to track the 95th percentile of the latency of requests departing from a service through its upstreams. + +##### Metric + +`envoy_cluster_upstream_rq_time_bucket` + +#### Alerting + +If the value crosses a user defined success threshold. + +#### Example dashboard (plot; value) + +``` +histogram_quantile(0.95, sum(rate(envoy_cluster_upstream_rq_time_bucket{cluster="$cluster", +local_cluster="$service",consul_target!=""}[1m])) by (le, consul_destination_target)) +``` + +## Next steps + +In this guide, you learned recommendations for monitoring your Envoy metrics, and why monitoring these metrics is important for your Consul deployment. + +To learn about monitoring Consul components, visit our [Monitoring Consul components](/well-architected-framework/reliability/reliability-consul-monitoring-consul-components) documentation. diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index b7eb58cadb..3d4000811d 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -667,6 +667,10 @@ "title": "Access Logs", "path": "connect/observability/access-logs" }, + { + "title": "Monitor service-to-service communication", + "path": "connect/observability/service" + }, { "title": "UI Visualization", "path": "connect/observability/ui-visualization" @@ -1251,8 +1255,21 @@ "path": "agent/config-entries" }, { - "title": "Telemetry", - "path": "agent/telemetry" + "title": "Monitor Consul", + "routes": [ + { + "title": "Agent telemetry", + "path": "agent/monitor/telemetry" + }, + { + "title": "Monitor components", + "path": "agent/monitor/components" + }, + { + "title": "Recommendations", + "path": "agent/monitor/alerts" + } + ] }, { "title": "Sentinel", From 943f0072c00b979dba3bceb19ebafff5bcfaa435 Mon Sep 17 00:00:00 2001 From: Sujata Roy <61177855+20sr20@users.noreply.github.com> Date: Mon, 20 May 2024 16:05:32 -0700 Subject: [PATCH 037/185] Doc added for Version specific upgrade Consul on Kubernetes components (#21101) * Added upgrade instruction - NET-4882 * Update website/content/docs/k8s/upgrade/index.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update index.mdx Fixed the link of grpc ports --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- website/content/docs/k8s/upgrade/index.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/content/docs/k8s/upgrade/index.mdx b/website/content/docs/k8s/upgrade/index.mdx index da345de80b..690ed380f3 100644 --- a/website/content/docs/k8s/upgrade/index.mdx +++ b/website/content/docs/k8s/upgrade/index.mdx @@ -15,6 +15,8 @@ As of Consul v1.14.0 and the corresponding Helm chart version v1.0.0, Kubernetes The v1.0.0 release of the Consul on Kubernetes Helm chart also introduced a change to the [`externalServers[].hosts` parameter](/consul/docs/k8s/helm#v-externalservers-hosts). Previously, you were able to enter a provider lookup as a string in this field. Now, you must include `exec=` at the start of a string containing a provider lookup. Otherwise, the string is treated as a DNS name. Refer to the [`go-netaddrs`](https://github.com/hashicorp/go-netaddrs) library and command line tool for more information. +If you configured your Consul agents to use [`ports.grpc_tls`](https://developer.hashicorp.com/consul/docs/agent/config/config-files#grpc_tls_port) instead of [`ports.grpc`](https://developer.hashicorp.com/consul/docs/agent/config/config-files#grpc_port) and you want to upgrade a multi-datacenter deployment with Consul servers running outside of the Kubernetes cluster to v1.0.0 or higher, set [`externalServers.tlsServerName`](/consul/docs/k8s/helm#v-externalservers-tlsservername) to `server..domain`. + ## Upgrade types We recommend updating Consul on Kubernetes when: From 6d088db52b9e68897d1b8f0a39f15104c84191da Mon Sep 17 00:00:00 2001 From: Dhia Ayachi Date: Tue, 21 May 2024 14:38:48 -0400 Subject: [PATCH 038/185] set go toolchain to go1.22.3 (#21195) --- go.mod | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.mod b/go.mod index 07b19d7b5f..de1ee7a0c3 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/hashicorp/consul go 1.20 +toolchain go1.22.3 + replace ( github.com/hashicorp/consul/api => ./api github.com/hashicorp/consul/envoyextensions => ./envoyextensions From 50b26aa56a0f77acfb59690692bb66ab6c679a36 Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Tue, 21 May 2024 14:52:19 -0500 Subject: [PATCH 039/185] deployer: remove catalog/mesh v2 support (#21194) - Low level plumbing for resources is still retained for now. - Retain "Workload" terminology over "Service". - Revert "Destination" terminology back to "Upstream". - Remove TPROXY support as it only worked for v2. --- test-integ/README.md | 51 +- test-integ/connect/snapshot_test.go | 8 +- .../peering_commontopo/ac1_basic_test.go | 10 +- .../ac2_disco_chain_test.go | 15 +- .../ac3_service_defaults_upstream_test.go | 18 +- .../ac4_proxy_defaults_test.go | 20 +- .../peering_commontopo/ac6_failovers_test.go | 11 +- .../ac7_1_rotate_gw_test.go | 9 +- .../ac7_2_rotate_leader_test.go | 13 +- test-integ/peering_commontopo/commontopo.go | 10 +- test-integ/topoutil/asserter.go | 85 +- test-integ/topoutil/asserter_blankspace.go | 58 +- test-integ/topoutil/fixtures.go | 8 - test-integ/topoutil/naming_shim.go | 19 +- test-integ/upgrade/basic/common.go | 6 +- .../upgrade/l7_traffic_management/common.go | 13 +- .../l7_traffic_management/resolver_test.go | 8 +- testing/deployer/README.md | 24 +- testing/deployer/sprawl/acl_rules.go | 8 - testing/deployer/sprawl/boot.go | 17 +- testing/deployer/sprawl/catalog.go | 380 +------ testing/deployer/sprawl/details.go | 23 +- .../deployer/sprawl/internal/build/docker.go | 2 +- .../deployer/sprawl/internal/tfgen/agent.go | 13 +- testing/deployer/sprawl/internal/tfgen/dns.go | 33 - testing/deployer/sprawl/internal/tfgen/gen.go | 3 - .../deployer/sprawl/internal/tfgen/nodes.go | 8 +- .../templates/container-app-dataplane.tf.tmpl | 19 - .../deployer/sprawl/sprawltest/test_test.go | 166 +--- testing/deployer/topology/compile.go | 314 +----- testing/deployer/topology/compile_test.go | 930 +----------------- testing/deployer/topology/naming_shim.go | 4 +- testing/deployer/topology/relationships.go | 50 +- testing/deployer/topology/topology.go | 286 +----- 34 files changed, 293 insertions(+), 2349 deletions(-) diff --git a/test-integ/README.md b/test-integ/README.md index 8955d0556d..048e377aeb 100644 --- a/test-integ/README.md +++ b/test-integ/README.md @@ -25,7 +25,7 @@ You can run the entire set of deployer integration tests using: You can also run them one by one if you like: - go test ./catalogv2 -run TestBasicL4ExplicitDestinations -v + go test ./connect/ -run Test_Snapshot_Restore_Agentless -v You can have the logs stream unbuffered directly to your terminal which can help diagnose stuck tests that would otherwise need to fully timeout before the @@ -65,26 +65,18 @@ These are comprised of 4 main parts: - **Nodes**: A "box with ip address(es)". This should feel a bit like a VM or a Kubernetes Pod as an enclosing entity. - - **Workloads**: The list of service instances (v1) or workloads - (v2) that will execute on the given node. v2 Services will - be implied by similarly named workloads here unless opted - out. This helps define a v1-compatible topology and - repurpose it for v2 without reworking it. + - **Workloads**: The list of service instances that will execute on the given node. - - **Services** (v2): v2 Service definitions to define explicitly, in addition - to the inferred ones. + - **InitialConfigEntries**: Config entries that should be created as + part of the fixture and that make sense to + include as part of the test definition, rather + than something created during the test assertion + phase. - - **InitialConfigEntries** (v1): Config entries that should be created as - part of the fixture and that make sense to - include as part of the test definition, - rather than something created during the - test assertion phase. - - - **InitialResources** (v2): v2 Resources that should be created as part of - the fixture and that make sense to include as - part of the test definition, rather than - something created during the test assertion - phase. + - **InitialResources**: Resources that should be created as part of + the fixture and that make sense to include as part of + the test definition, rather than something created + during the test assertion phase. - **Peerings**: The peering relationships between Clusters to establish. @@ -102,15 +94,13 @@ a variety of axes: - agentful (clients) vs agentless (dataplane) - tenancies (partitions, namespaces) - locally or across a peering -- catalog v1 or v2 object model Since the topology is just a declarative struct, a test author could rewrite -any one of these attributes with a single field (such as `Node.Kind` or -`Node.Version`) and cause the identical test to run against the other -configuration. With the addition of a few `if enterprise {}` blocks and `for` -loops, a test author could easily write one test of a behavior and execute it -to cover agentless, agentful, non-default tenancy, and v1/v2 in a few extra -lines of code. +any one of these attributes with a single field (such as `Node.Kind`) and cause +the identical test to run against the other configuration. With the addition of +a few `if enterprise {}` blocks and `for` loops, a test author could easily +write one test of a behavior and execute it to cover agentless, agentful, and +non-default tenancy in a few extra lines of code. #### Non-optional security settings @@ -197,12 +187,3 @@ and Envoy that you can create in your test: asserter := topoutil.NewAsserter(sp) asserter.UpstreamEndpointStatus(t, svc, clusterPrefix+".", "HEALTHY", 1) - -## Examples - -- `catalogv2` - - [Explicit L4 destinations](./catalogv2/explicit_destinations_test.go) - - [Implicit L4 destinations](./catalogv2/implicit_destinations_test.go) - - [Explicit L7 destinations with traffic splits](./catalogv2/explicit_destinations_l7_test.go) -- [`peering_commontopo`](./peering_commontopo) - - A variety of extensive v1 Peering tests. diff --git a/test-integ/connect/snapshot_test.go b/test-integ/connect/snapshot_test.go index 5a7a4a342c..423fa25340 100644 --- a/test-integ/connect/snapshot_test.go +++ b/test-integ/connect/snapshot_test.go @@ -27,7 +27,7 @@ import ( // 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 destination is updated with the +// 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() @@ -89,7 +89,7 @@ func Test_Snapshot_Restore_Agentless(t *testing.T) { "-http-port", "8080", "-redirect-port", "-disabled", }, - Destinations: []*topology.Destination{ + Upstreams: []*topology.Upstream{ { ID: staticServerSID, LocalPort: 5000, @@ -153,7 +153,7 @@ func Test_Snapshot_Restore_Agentless(t *testing.T) { topology.NewNodeID("dc1-client2", "default"), staticClientSID, ) - asserter.FortioFetch2HeaderEcho(t, staticClient, &topology.Destination{ + asserter.FortioFetch2HeaderEcho(t, staticClient, &topology.Upstream{ ID: staticServerSID, LocalPort: 5000, }) @@ -182,7 +182,7 @@ func Test_Snapshot_Restore_Agentless(t *testing.T) { require.NoError(t, sp.Relaunch(cfg)) // Ensure the static-client connected to the new static-server - asserter.FortioFetch2HeaderEcho(t, staticClient, &topology.Destination{ + asserter.FortioFetch2HeaderEcho(t, staticClient, &topology.Upstream{ ID: staticServerSID, LocalPort: 5000, }) diff --git a/test-integ/peering_commontopo/ac1_basic_test.go b/test-integ/peering_commontopo/ac1_basic_test.go index e104288c1f..c09bd3d537 100644 --- a/test-integ/peering_commontopo/ac1_basic_test.go +++ b/test-integ/peering_commontopo/ac1_basic_test.go @@ -30,8 +30,8 @@ type ac1BasicSuite struct { sidClientHTTP topology.ID nodeClientHTTP topology.NodeID - upstreamHTTP *topology.Destination - upstreamTCP *topology.Destination + upstreamHTTP *topology.Upstream + upstreamTCP *topology.Upstream } var ac1BasicSuites []sharedTopoSuite = []sharedTopoSuite{ @@ -65,7 +65,7 @@ func (s *ac1BasicSuite) setup(t *testing.T, ct *commonTopo) { Name: prefix + "server-http", Partition: partition, } - upstreamHTTP := &topology.Destination{ + upstreamHTTP := &topology.Upstream{ ID: topology.ID{ Name: httpServerSID.Name, Partition: partition, @@ -73,7 +73,7 @@ func (s *ac1BasicSuite) setup(t *testing.T, ct *commonTopo) { LocalPort: 5001, Peer: peer, } - upstreamTCP := &topology.Destination{ + upstreamTCP := &topology.Upstream{ ID: topology.ID{ Name: tcpServerSID.Name, Partition: partition, @@ -93,7 +93,7 @@ func (s *ac1BasicSuite) setup(t *testing.T, ct *commonTopo) { clu.Datacenter, sid, func(s *topology.Workload) { - s.Destinations = []*topology.Destination{ + s.Upstreams = []*topology.Upstream{ upstreamTCP, upstreamHTTP, } diff --git a/test-integ/peering_commontopo/ac2_disco_chain_test.go b/test-integ/peering_commontopo/ac2_disco_chain_test.go index ab85b7ffdb..0c0f05ae45 100644 --- a/test-integ/peering_commontopo/ac2_disco_chain_test.go +++ b/test-integ/peering_commontopo/ac2_disco_chain_test.go @@ -7,9 +7,10 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" ) type ac2DiscoChainSuite struct { @@ -84,7 +85,7 @@ func (s *ac2DiscoChainSuite) setup(t *testing.T, ct *commonTopo) { ct.AddServiceNode(clu, serviceExt{Workload: server}) // Define server as upstream for client - upstream := &topology.Destination{ + upstream := &topology.Upstream{ ID: topology.ID{ Name: server.ID.Name, Partition: partition, // TODO: iterate over all possible partitions @@ -105,7 +106,7 @@ func (s *ac2DiscoChainSuite) setup(t *testing.T, ct *commonTopo) { clu.Datacenter, clientSID, func(s *topology.Workload) { - s.Destinations = []*topology.Destination{ + s.Upstreams = []*topology.Upstream{ upstream, } }, @@ -164,8 +165,8 @@ func (s *ac2DiscoChainSuite) test(t *testing.T, ct *commonTopo) { require.Len(t, svcs, 1, "expected exactly one client in datacenter") client := svcs[0] - require.Len(t, client.Destinations, 1, "expected exactly one upstream for client") - u := client.Destinations[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() @@ -176,7 +177,7 @@ func (s *ac2DiscoChainSuite) test(t *testing.T, ct *commonTopo) { t.Run("peered upstream endpoint status is healthy", func(t *testing.T) { t.Parallel() - ct.Assert.DestinationEndpointStatus(t, client, peerClusterPrefix(u), "HEALTHY", 1) + ct.Assert.UpstreamEndpointStatus(t, client, peerClusterPrefix(u), "HEALTHY", 1) }) t.Run("response contains header injected by splitter", func(t *testing.T) { @@ -196,7 +197,7 @@ func (s *ac2DiscoChainSuite) test(t *testing.T, ct *commonTopo) { // func (s *ResourceGenerator) getTargetClusterName // // and connect/sni.go -func peerClusterPrefix(u *topology.Destination) string { +func peerClusterPrefix(u *topology.Upstream) string { if u.Peer == "" { panic("upstream is not from a peer") } diff --git a/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go b/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go index caf801b09e..30b4b19480 100644 --- a/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go +++ b/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go @@ -11,13 +11,15 @@ import ( "testing" "time" + "github.com/itchyny/gojq" + "github.com/stretchr/testify/require" + + "github.com/hashicorp/go-cleanhttp" + "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/hashicorp/go-cleanhttp" - "github.com/itchyny/gojq" - "github.com/stretchr/testify/require" ) var ac3SvcDefaultsSuites []sharedTopoSuite = []sharedTopoSuite{ @@ -40,7 +42,7 @@ type ac3SvcDefaultsSuite struct { sidClient topology.ID nodeClient topology.NodeID - upstream *topology.Destination + upstream *topology.Upstream } func (s *ac3SvcDefaultsSuite) testName() string { @@ -60,7 +62,7 @@ func (s *ac3SvcDefaultsSuite) setup(t *testing.T, ct *commonTopo) { Name: "ac3-server", Partition: partition, } - upstream := &topology.Destination{ + upstream := &topology.Upstream{ ID: topology.ID{ Name: serverSID.Name, Partition: partition, @@ -78,7 +80,7 @@ func (s *ac3SvcDefaultsSuite) setup(t *testing.T, ct *commonTopo) { clu.Datacenter, sid, func(s *topology.Workload) { - s.Destinations = []*topology.Destination{ + s.Upstreams = []*topology.Upstream{ upstream, } }, @@ -183,7 +185,7 @@ func (s *ac3SvcDefaultsSuite) test(t *testing.T, ct *commonTopo) { // 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(""), + 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)), ) @@ -219,7 +221,7 @@ func (s *ac3SvcDefaultsSuite) test(t *testing.T, ct *commonTopo) { require.True(r, resultAsBool) }) - url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort(""), + 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) { diff --git a/test-integ/peering_commontopo/ac4_proxy_defaults_test.go b/test-integ/peering_commontopo/ac4_proxy_defaults_test.go index c6bbc9506b..c27057a07a 100644 --- a/test-integ/peering_commontopo/ac4_proxy_defaults_test.go +++ b/test-integ/peering_commontopo/ac4_proxy_defaults_test.go @@ -9,10 +9,12 @@ import ( "net/url" "testing" + "github.com/stretchr/testify/require" + + "github.com/hashicorp/go-cleanhttp" + "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 { @@ -24,7 +26,7 @@ type ac4ProxyDefaultsSuite struct { serverSID topology.ID clientSID topology.ID - upstream *topology.Destination + upstream *topology.Upstream } var ac4ProxyDefaultsSuites []sharedTopoSuite = []sharedTopoSuite{ @@ -54,7 +56,7 @@ func (s *ac4ProxyDefaultsSuite) setup(t *testing.T, ct *commonTopo) { Partition: partition, } // Define server as upstream for client - upstream := &topology.Destination{ + upstream := &topology.Upstream{ ID: serverSID, LocalPort: 5000, Peer: peer, @@ -70,7 +72,7 @@ func (s *ac4ProxyDefaultsSuite) setup(t *testing.T, ct *commonTopo) { clu.Datacenter, clientSID, func(s *topology.Workload) { - s.Destinations = []*topology.Destination{ + s.Upstreams = []*topology.Upstream{ upstream, } }, @@ -165,11 +167,11 @@ func (s *ac4ProxyDefaultsSuite) test(t *testing.T, ct *commonTopo) { dcSvcs := dc.WorkloadsByID(s.clientSID) require.Len(t, dcSvcs, 1, "expected exactly one client") client = dcSvcs[0] - require.Len(t, client.Destinations, 1, "expected exactly one upstream for client") + require.Len(t, client.Upstreams, 1, "expected exactly one upstream for client") server := dc.WorkloadsByID(s.serverSID) require.Len(t, server, 1, "expected exactly one server") - require.Len(t, server[0].Destinations, 0, "expected no upstream for server") + require.Len(t, server[0].Upstreams, 0, "expected no upstream for server") }) t.Run("peered upstream exists in catalog", func(t *testing.T) { @@ -179,11 +181,11 @@ func (s *ac4ProxyDefaultsSuite) test(t *testing.T, ct *commonTopo) { }) 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(""), + 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(""), + url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort(), url.QueryEscape(fmt.Sprintf("http://localhost:%d/", s.upstream.LocalPort)), ) diff --git a/test-integ/peering_commontopo/ac6_failovers_test.go b/test-integ/peering_commontopo/ac6_failovers_test.go index ad71cf477b..4b37d10955 100644 --- a/test-integ/peering_commontopo/ac6_failovers_test.go +++ b/test-integ/peering_commontopo/ac6_failovers_test.go @@ -7,11 +7,12 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" "github.com/hashicorp/consul/testing/deployer/sprawl" "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" ) type ac6FailoversSuite struct { @@ -347,8 +348,8 @@ func (s *ac6FailoversSuite) setup(t *testing.T, ct *commonTopo) { nearClu.Datacenter, clientSID, func(s *topology.Workload) { - // Destination per partition - s.Destinations = []*topology.Destination{ + // Upstream per partition + s.Upstreams = []*topology.Upstream{ { ID: topology.ID{ Name: nearServerSID.Name, @@ -437,8 +438,8 @@ func (s *ac6FailoversSuite) test(t *testing.T, ct *commonTopo) { require.Len(t, svcs, 1, "expected exactly one client in datacenter") client := svcs[0] - require.Len(t, client.Destinations, 1, "expected one upstream for client") - upstream := client.Destinations[0] + require.Len(t, client.Upstreams, 1, "expected one upstream for client") + upstream := client.Upstreams[0] fmt.Println("### preconditions") diff --git a/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go b/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go index 6c5749f37c..e901c7c305 100644 --- a/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go +++ b/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go @@ -8,9 +8,10 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" ) // TestRotateGW ensures that peered services continue to be able to talk to their @@ -27,7 +28,7 @@ type suiteRotateGW struct { sidClient topology.ID nodeClient topology.NodeID - upstream *topology.Destination + upstream *topology.Upstream newMGWNodeName string } @@ -70,7 +71,7 @@ func (s *suiteRotateGW) setup(t *testing.T, ct *commonTopo) { ) // Make clients which have server upstreams - upstream := &topology.Destination{ + upstream := &topology.Upstream{ ID: topology.ID{ Name: server.ID.Name, Partition: partition, @@ -88,7 +89,7 @@ func (s *suiteRotateGW) setup(t *testing.T, ct *commonTopo) { Partition: partition, }, func(s *topology.Workload) { - s.Destinations = []*topology.Destination{ + s.Upstreams = []*topology.Upstream{ 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 index 2cf9920278..0f6fe439e2 100644 --- a/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go +++ b/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go @@ -8,13 +8,14 @@ import ( "testing" "time" + "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" "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" ) // TestAC7_2RotateLeader ensures that after a leader rotation, information continues to replicate to peers @@ -29,7 +30,7 @@ type ac7_2RotateLeaderSuite struct { sidClient topology.ID nodeClient topology.NodeID - upstream *topology.Destination + upstream *topology.Upstream } func TestAC7_2RotateLeader(t *testing.T) { @@ -71,7 +72,7 @@ func (s *ac7_2RotateLeaderSuite) setup(t *testing.T, ct *commonTopo) { ) // Make clients which have server upstreams - upstream := &topology.Destination{ + upstream := &topology.Upstream{ ID: topology.ID{ Name: server.ID.Name, Partition: partition, @@ -87,7 +88,7 @@ func (s *ac7_2RotateLeaderSuite) setup(t *testing.T, ct *commonTopo) { Partition: partition, }, func(s *topology.Workload) { - s.Destinations = []*topology.Destination{ + s.Upstreams = []*topology.Upstream{ upstream, } }, diff --git a/test-integ/peering_commontopo/commontopo.go b/test-integ/peering_commontopo/commontopo.go index 8d931d86bb..c436093255 100644 --- a/test-integ/peering_commontopo/commontopo.go +++ b/test-integ/peering_commontopo/commontopo.go @@ -9,16 +9,16 @@ import ( "testing" "time" + "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-integ/topoutil" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" "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/test-integ/topoutil" ) // commonTopo helps create a shareable topology configured to represent @@ -509,7 +509,7 @@ func NewFortioServiceWithDefaults( sid topology.ID, mut func(s *topology.Workload), ) *topology.Workload { - return topoutil.NewFortioServiceWithDefaults(cluster, sid, topology.NodeVersionV1, mut) + return topoutil.NewFortioServiceWithDefaults(cluster, sid, mut) } func newTopologyMeshGatewaySet( diff --git a/test-integ/topoutil/asserter.go b/test-integ/topoutil/asserter.go index 361adf1769..0ba842ad07 100644 --- a/test-integ/topoutil/asserter.go +++ b/test-integ/topoutil/asserter.go @@ -6,16 +6,6 @@ package topoutil import ( "encoding/json" "fmt" - "github.com/google/go-cmp/cmp" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" - "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" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "io" "net/http" "net/url" @@ -24,6 +14,18 @@ import ( "strings" "testing" "time" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/consul/sdk/testutil" + "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" + "github.com/hashicorp/consul/testing/deployer/topology" ) // Asserter is a utility to help in reducing boilerplate in invoking test @@ -33,7 +35,7 @@ import ( // 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 a destination) leave port as an argument +// 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 { @@ -82,12 +84,12 @@ func (a *Asserter) httpClientFor(cluster string) (*http.Client, error) { return client, nil } -// DestinationEndpointStatus validates that proxy was configured with provided clusterName in the healthStatus +// 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) DestinationEndpointStatus( +func (a *Asserter) UpstreamEndpointStatus( t *testing.T, workload *topology.Workload, clusterName string, @@ -169,7 +171,7 @@ func (a *Asserter) AssertEnvoyHTTPrbacFiltersContainIntentions(t *testing.T, wor // // 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 destination. +// 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, workload *topology.Workload, @@ -193,7 +195,7 @@ func (a *Asserter) HTTPServiceEchoes( // // 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 destination. +// 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, workload *topology.Workload, @@ -266,27 +268,27 @@ type testingT interface { Helper() } -// does a fortio /fetch2 to the given fortio service, targetting the given destination. Returns +// 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) fortioFetch2Destination( +func (a *Asserter) fortioFetch2Upstream( t testutil.TestingTB, client *http.Client, addr string, - dest *topology.Destination, + us *topology.Upstream, path string, ) (body []byte, res *http.Response) { t.Helper() - err, res := getFortioFetch2DestinationResponse(t, client, addr, dest, path, nil) + err, res := getFortioFetch2UpstreamResponse(t, client, addr, us, path, nil) require.NoError(t, 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(t, http.StatusServiceUnavailable, res.StatusCode) require.NotEqual(t, http.StatusGatewayTimeout, res.StatusCode) - // not sure when this happens, suspect it's when envoy hasn't configured the local destination yet + // not sure when this happens, suspect it's when envoy hasn't configured the local upstream yet require.NotEqual(t, http.StatusBadRequest, res.StatusCode) body, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -294,19 +296,8 @@ func (a *Asserter) fortioFetch2Destination( return body, res } -func getFortioFetch2DestinationResponse(t testutil.TestingTB, client *http.Client, addr string, dest *topology.Destination, path string, headers map[string]string) (error, *http.Response) { - var actualURL string - if dest.Implied { - actualURL = fmt.Sprintf("http://%s--%s--%s.virtual.consul:%d/%s", - dest.ID.Name, - dest.ID.Namespace, - dest.ID.Partition, - dest.VirtualPort, - path, - ) - } else { - actualURL = fmt.Sprintf("http://localhost:%d/%s", dest.LocalPort, path) - } +func getFortioFetch2UpstreamResponse(t testutil.TestingTB, client *http.Client, addr string, us *topology.Upstream, path string, headers map[string]string) (error, *http.Response) { + actualURL := fmt.Sprintf("http://localhost:%d/%s", us.LocalPort, path) url := fmt.Sprintf("http://%s/fortio/fetch2?url=%s", addr, url.QueryEscape(actualURL), @@ -324,20 +315,20 @@ func getFortioFetch2DestinationResponse(t testutil.TestingTB, client *http.Clien } // uses the /fortio/fetch2 endpoint to do a header echo check against an -// destination fortio -func (a *Asserter) FortioFetch2HeaderEcho(t *testing.T, fortioWrk *topology.Workload, dest *topology.Destination) { +// upstream fortio +func (a *Asserter) FortioFetch2HeaderEcho(t *testing.T, fortioWrk *topology.Workload, us *topology.Upstream) { const kPassphrase = "x-passphrase" const passphrase = "hello" path := (fmt.Sprintf("/?header=%s:%s", kPassphrase, passphrase)) var ( node = fortioWrk.Node - addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioWrk.PortOrDefault(dest.PortName)) + addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioWrk.Port) client = a.mustGetHTTPClient(t, node.Cluster) ) retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - _, res := a.fortioFetch2Destination(r, client, addr, dest, path) + _, res := a.fortioFetch2Upstream(r, client, addr, us, path) require.Equal(r, http.StatusOK, res.StatusCode) v := res.Header.Get(kPassphrase) require.Equal(r, passphrase, v) @@ -345,12 +336,12 @@ func (a *Asserter) FortioFetch2HeaderEcho(t *testing.T, fortioWrk *topology.Work } // similar to libassert.AssertFortioName, -// uses the /fortio/fetch2 endpoint to hit the debug endpoint on the destination, +// 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, fortioWrk *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, clusterName string, sid topology.ID, ) { @@ -358,7 +349,7 @@ func (a *Asserter) FortioFetch2FortioName( var ( node = fortioWrk.Node - addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioWrk.PortOrDefault(dest.PortName)) + addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioWrk.Port) client = a.mustGetHTTPClient(t, node.Cluster) ) @@ -366,7 +357,7 @@ func (a *Asserter) FortioFetch2FortioName( path := "/debug?env=dump" retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - body, res := a.fortioFetch2Destination(r, client, addr, dest, path) + body, res := a.fortioFetch2Upstream(r, client, addr, us, path) require.Equal(r, http.StatusOK, res.StatusCode) @@ -378,24 +369,24 @@ func (a *Asserter) FortioFetch2FortioName( }) } -func (a *Asserter) FortioFetch2ServiceUnavailable(t *testing.T, fortioWrk *topology.Workload, dest *topology.Destination) { +func (a *Asserter) FortioFetch2ServiceUnavailable(t *testing.T, fortioWrk *topology.Workload, us *topology.Upstream) { const kPassphrase = "x-passphrase" const passphrase = "hello" path := (fmt.Sprintf("/?header=%s:%s", kPassphrase, passphrase)) - a.FortioFetch2ServiceStatusCodes(t, fortioWrk, dest, path, nil, []int{http.StatusServiceUnavailable}) + a.FortioFetch2ServiceStatusCodes(t, fortioWrk, us, path, nil, []int{http.StatusServiceUnavailable}) } -// FortioFetch2ServiceStatusCodes uses the /fortio/fetch2 endpoint to do a header echo check against a destination +// FortioFetch2ServiceStatusCodes uses the /fortio/fetch2 endpoint to do a header echo check against a upstream // fortio and asserts that the returned status code matches the desired one(s) -func (a *Asserter) FortioFetch2ServiceStatusCodes(t *testing.T, fortioWrk *topology.Workload, dest *topology.Destination, path string, headers map[string]string, statuses []int) { +func (a *Asserter) FortioFetch2ServiceStatusCodes(t *testing.T, fortioWrk *topology.Workload, us *topology.Upstream, path string, headers map[string]string, statuses []int) { var ( node = fortioWrk.Node - addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioWrk.PortOrDefault(dest.PortName)) + addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioWrk.Port) client = a.mustGetHTTPClient(t, node.Cluster) ) retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - _, res := getFortioFetch2DestinationResponse(r, client, addr, dest, path, headers) + _, res := getFortioFetch2UpstreamResponse(r, client, addr, us, path, headers) defer res.Body.Close() require.Contains(r, statuses, res.StatusCode) }) diff --git a/test-integ/topoutil/asserter_blankspace.go b/test-integ/topoutil/asserter_blankspace.go index ca41e2f32d..ed6d76b9b3 100644 --- a/test-integ/topoutil/asserter_blankspace.go +++ b/test-integ/topoutil/asserter_blankspace.go @@ -9,9 +9,10 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" ) // CheckBlankspaceNameViaHTTP calls a copy of blankspace and asserts it arrived @@ -19,7 +20,7 @@ import ( func (a *Asserter) CheckBlankspaceNameViaHTTP( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, useHTTP2 bool, path string, clusterName string, @@ -27,7 +28,7 @@ func (a *Asserter) CheckBlankspaceNameViaHTTP( ) { t.Helper() - a.checkBlankspaceNameViaHTTPWithCallback(t, workload, dest, useHTTP2, path, 1, func(_ *retry.R) {}, func(r *retry.R, remoteName string) { + a.checkBlankspaceNameViaHTTPWithCallback(t, workload, us, useHTTP2, path, 1, func(_ *retry.R) {}, func(r *retry.R, remoteName string) { require.Equal(r, fmt.Sprintf("%s::%s", clusterName, sid.String()), remoteName) }, func(r *retry.R) {}) } @@ -37,7 +38,7 @@ func (a *Asserter) CheckBlankspaceNameViaHTTP( func (a *Asserter) CheckBlankspaceNameTrafficSplitViaHTTP( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, useHTTP2 bool, path string, expect map[string]int, @@ -45,7 +46,7 @@ func (a *Asserter) CheckBlankspaceNameTrafficSplitViaHTTP( t.Helper() got := make(map[string]int) - a.checkBlankspaceNameViaHTTPWithCallback(t, workload, dest, useHTTP2, path, 100, func(_ *retry.R) { + a.checkBlankspaceNameViaHTTPWithCallback(t, workload, us, useHTTP2, path, 100, func(_ *retry.R) { got = make(map[string]int) }, func(_ *retry.R, name string) { got[name]++ @@ -57,7 +58,7 @@ func (a *Asserter) CheckBlankspaceNameTrafficSplitViaHTTP( func (a *Asserter) checkBlankspaceNameViaHTTPWithCallback( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, useHTTP2 bool, path string, count int, @@ -69,7 +70,7 @@ func (a *Asserter) checkBlankspaceNameViaHTTPWithCallback( var ( node = workload.Node - internalPort = workload.PortOrDefault(dest.PortName) + internalPort = workload.Port addr = fmt.Sprintf("%s:%d", node.LocalAddress(), internalPort) client = a.mustGetHTTPClient(t, node.Cluster) ) @@ -85,18 +86,7 @@ func (a *Asserter) checkBlankspaceNameViaHTTPWithCallback( client = EnableHTTP2(client) } - var actualURL string - if dest.Implied { - actualURL = fmt.Sprintf("http://%s--%s--%s.virtual.consul:%d/%s", - dest.ID.Name, - dest.ID.Namespace, - dest.ID.Partition, - dest.VirtualPort, - path, - ) - } else { - actualURL = fmt.Sprintf("http://localhost:%d/%s", dest.LocalPort, path) - } + actualURL := fmt.Sprintf("http://localhost:%d/%s", us.LocalPort, path) multiassert(t, count, resetFn, func(r *retry.R) { name, err := GetBlankspaceNameViaHTTP(context.Background(), client, addr, actualURL) @@ -112,13 +102,13 @@ func (a *Asserter) checkBlankspaceNameViaHTTPWithCallback( func (a *Asserter) CheckBlankspaceNameViaTCP( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, clusterName string, sid topology.ID, ) { t.Helper() - a.checkBlankspaceNameViaTCPWithCallback(t, workload, dest, 1, func(_ *retry.R) {}, func(r *retry.R, remoteName string) { + a.checkBlankspaceNameViaTCPWithCallback(t, workload, us, 1, func(_ *retry.R) {}, func(r *retry.R, remoteName string) { require.Equal(r, fmt.Sprintf("%s::%s", clusterName, sid.String()), remoteName) }, func(r *retry.R) {}) } @@ -128,13 +118,13 @@ func (a *Asserter) CheckBlankspaceNameViaTCP( func (a *Asserter) CheckBlankspaceNameTrafficSplitViaTCP( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, expect map[string]int, ) { t.Helper() got := make(map[string]int) - a.checkBlankspaceNameViaTCPWithCallback(t, workload, dest, 100, func(_ *retry.R) { + a.checkBlankspaceNameViaTCPWithCallback(t, workload, us, 100, func(_ *retry.R) { got = make(map[string]int) }, func(_ *retry.R, name string) { got[name]++ @@ -146,7 +136,7 @@ func (a *Asserter) CheckBlankspaceNameTrafficSplitViaTCP( func (a *Asserter) checkBlankspaceNameViaTCPWithCallback( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, count int, resetFn func(r *retry.R), attemptFn func(r *retry.R, remoteName string), @@ -154,8 +144,7 @@ func (a *Asserter) checkBlankspaceNameViaTCPWithCallback( ) { t.Helper() - require.False(t, dest.Implied, "helper does not support tproxy yet") - port := dest.LocalPort + port := us.LocalPort require.True(t, port > 0) node := workload.Node @@ -180,13 +169,13 @@ func (a *Asserter) checkBlankspaceNameViaTCPWithCallback( func (a *Asserter) CheckBlankspaceNameViaGRPC( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, clusterName string, sid topology.ID, ) { t.Helper() - a.checkBlankspaceNameViaGRPCWithCallback(t, workload, dest, 1, func(_ *retry.R) {}, func(r *retry.R, remoteName string) { + a.checkBlankspaceNameViaGRPCWithCallback(t, workload, us, 1, func(_ *retry.R) {}, func(r *retry.R, remoteName string) { require.Equal(r, fmt.Sprintf("%s::%s", clusterName, sid.String()), remoteName) }, func(_ *retry.R) {}) } @@ -196,13 +185,13 @@ func (a *Asserter) CheckBlankspaceNameViaGRPC( func (a *Asserter) CheckBlankspaceNameTrafficSplitViaGRPC( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, expect map[string]int, ) { t.Helper() got := make(map[string]int) - a.checkBlankspaceNameViaGRPCWithCallback(t, workload, dest, 100, func(_ *retry.R) { + a.checkBlankspaceNameViaGRPCWithCallback(t, workload, us, 100, func(_ *retry.R) { got = make(map[string]int) }, func(_ *retry.R, name string) { got[name]++ @@ -214,7 +203,7 @@ func (a *Asserter) CheckBlankspaceNameTrafficSplitViaGRPC( func (a *Asserter) checkBlankspaceNameViaGRPCWithCallback( t *testing.T, workload *topology.Workload, - dest *topology.Destination, + us *topology.Upstream, count int, resetFn func(r *retry.R), attemptFn func(r *retry.R, remoteName string), @@ -222,8 +211,7 @@ func (a *Asserter) checkBlankspaceNameViaGRPCWithCallback( ) { t.Helper() - require.False(t, dest.Implied, "helper does not support tproxy yet") - port := dest.LocalPort + port := us.LocalPort require.True(t, port > 0) node := workload.Node @@ -244,7 +232,7 @@ func (a *Asserter) checkBlankspaceNameViaGRPCWithCallback( } // assertTrafficSplitFor100Requests compares the counts of 100 requests that -// did reach an observed set of destinations (nameCounts) against the expected +// did reach an observed set of upstreams (nameCounts) against the expected // counts of those same services is the same within a fixed difference of 2. func assertTrafficSplitFor100Requests(t require.TestingT, nameCounts map[string]int, expect map[string]int) { const ( @@ -265,7 +253,7 @@ func sumMapValues(m map[string]int) int { } // assertTrafficSplit compares the counts of requests that did reach an -// observed set of destinations (nameCounts) against the expected counts of +// observed set of upstreams (nameCounts) against the expected counts of // those same services is the same within the provided allowedDelta value. // // When doing random traffic splits it'll never be perfect so we need the diff --git a/test-integ/topoutil/fixtures.go b/test-integ/topoutil/fixtures.go index aeb82a0bc9..49daac947c 100644 --- a/test-integ/topoutil/fixtures.go +++ b/test-integ/topoutil/fixtures.go @@ -15,12 +15,8 @@ const HashicorpDockerProxy = "docker.mirror.hashicorp.services" func NewFortioWorkloadWithDefaults( cluster string, sid topology.ID, - nodeVersion topology.NodeVersion, mut func(*topology.Workload), ) *topology.Workload { - if nodeVersion == topology.NodeVersionV2 { - panic("v2 nodes are not supported") - } const ( httpPort = 8080 grpcPort = 8079 @@ -56,12 +52,8 @@ func NewFortioWorkloadWithDefaults( func NewBlankspaceWorkloadWithDefaults( cluster string, sid topology.ID, - nodeVersion topology.NodeVersion, mut func(*topology.Workload), ) *topology.Workload { - if nodeVersion == topology.NodeVersionV2 { - panic("v2 nodes are not supported") - } const ( httpPort = 8080 grpcPort = 8079 diff --git a/test-integ/topoutil/naming_shim.go b/test-integ/topoutil/naming_shim.go index 40355992a3..8a4edc8f9e 100644 --- a/test-integ/topoutil/naming_shim.go +++ b/test-integ/topoutil/naming_shim.go @@ -4,38 +4,23 @@ package topoutil import ( - "testing" - "github.com/hashicorp/consul/testing/deployer/topology" ) -// Deprecated: DestinationEndpointStatus -func (a *Asserter) UpstreamEndpointStatus( - t *testing.T, - workload *topology.Workload, - clusterName string, - healthStatus string, - count int, -) { - a.DestinationEndpointStatus(t, workload, clusterName, healthStatus, count) -} - // Deprecated: NewFortioWorkloadWithDefaults func NewFortioServiceWithDefaults( cluster string, sid topology.ID, - nodeVersion topology.NodeVersion, mut func(*topology.Workload), ) *topology.Workload { - return NewFortioWorkloadWithDefaults(cluster, sid, nodeVersion, mut) + return NewFortioWorkloadWithDefaults(cluster, sid, mut) } // Deprecated: NewBlankspaceWorkloadWithDefaults func NewBlankspaceServiceWithDefaults( cluster string, sid topology.ID, - nodeVersion topology.NodeVersion, mut func(*topology.Workload), ) *topology.Workload { - return NewBlankspaceWorkloadWithDefaults(cluster, sid, nodeVersion, mut) + return NewBlankspaceWorkloadWithDefaults(cluster, sid, mut) } diff --git a/test-integ/upgrade/basic/common.go b/test-integ/upgrade/basic/common.go index c79fc82799..0b4bff8bf1 100644 --- a/test-integ/upgrade/basic/common.go +++ b/test-integ/upgrade/basic/common.go @@ -130,7 +130,7 @@ func newCommonTopo(t *testing.T) *commonTopo { "-http-port", "8080", "-redirect-port", "-disabled", }, - Upstreams: []*topology.Destination{ + Upstreams: []*topology.Upstream{ { ID: staticServerSID, LocalPort: 5000, @@ -218,7 +218,7 @@ func (ct *commonTopo) PostUpgradeValidation(t *testing.T) { cluster.Nodes[ct.StaticServerInstTwo].Disabled = false // client 3 -- new static-server require.NoError(t, ct.Sprawl.RelaunchWithPhase(cfg, sprawl.LaunchPhaseRegular)) // Ensure the static-client connected to the new static-server - ct.Assert.FortioFetch2HeaderEcho(t, ct.StaticClientWorkload, &topology.Destination{ + ct.Assert.FortioFetch2HeaderEcho(t, ct.StaticClientWorkload, &topology.Upstream{ ID: ct.StaticServerSID, LocalPort: 5000, }) @@ -244,7 +244,7 @@ func (ct *commonTopo) Launch(t *testing.T) { topology.NewNodeID("dc1-client2", "default"), ct.StaticClientSID, ) - ct.Assert.FortioFetch2HeaderEcho(t, staticClientWorkload, &topology.Destination{ + ct.Assert.FortioFetch2HeaderEcho(t, staticClientWorkload, &topology.Upstream{ ID: ct.StaticServerSID, LocalPort: 5000, }) diff --git a/test-integ/upgrade/l7_traffic_management/common.go b/test-integ/upgrade/l7_traffic_management/common.go index ca24a75c05..f60e995b71 100644 --- a/test-integ/upgrade/l7_traffic_management/common.go +++ b/test-integ/upgrade/l7_traffic_management/common.go @@ -8,12 +8,11 @@ import ( "testing" "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/test-integ/topoutil" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" "github.com/hashicorp/consul/testing/deployer/sprawl" "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" "github.com/hashicorp/consul/testing/deployer/topology" - - "github.com/hashicorp/consul/test-integ/topoutil" ) type commonTopo struct { @@ -51,11 +50,11 @@ func NewCommonTopo(t *testing.T) *commonTopo { // // dataplane // - workload(fortio) static-server on node dc1-client1 -// - workload(fortio) static-client on node dc1-client2 with destination to static-server +// - workload(fortio) static-client on node dc1-client2 with upstream to static-server // - static-client, static-server are registered at 2 agentless nodes. // // Intentions -// - static-client has destination to static-server +// - static-client has upstream to static-server func newCommonTopo(t *testing.T) *commonTopo { t.Helper() @@ -107,7 +106,7 @@ func newCommonTopo(t *testing.T) *commonTopo { }, }, }, - // static-client on dc1-client2 with destination to static-server + // static-client on dc1-client2 with upstream to static-server { Kind: topology.NodeKindDataplane, Name: "dc1-client2", @@ -123,7 +122,7 @@ func newCommonTopo(t *testing.T) *commonTopo { "-http-port", "8080", "-redirect-port", "-disabled", }, - Destinations: []*topology.Destination{ + Upstreams: []*topology.Upstream{ { ID: staticServerSID, // static-server LocalPort: 5000, @@ -208,7 +207,7 @@ func (ct *commonTopo) ValidateWorkloads(t *testing.T) { // check the service exists in catalog svcs := cluster.WorkloadsByID(ct.StaticClientSID) client := svcs[0] - upstream := client.Destinations[0] + upstream := client.Upstreams[0] ct.Assert.CatalogServiceExists(t, cluster.Name, upstream.ID.Name, utils.CompatQueryOpts(&api.QueryOptions{ Partition: upstream.ID.Partition, Namespace: upstream.ID.Namespace, diff --git a/test-integ/upgrade/l7_traffic_management/resolver_test.go b/test-integ/upgrade/l7_traffic_management/resolver_test.go index a3bc553c04..17c4eefaf0 100644 --- a/test-integ/upgrade/l7_traffic_management/resolver_test.go +++ b/test-integ/upgrade/l7_traffic_management/resolver_test.go @@ -38,15 +38,15 @@ func TestTrafficManagement_ResolverDefaultSubset_Agentless(t *testing.T) { topology.NewNodeID("dc1-client2", defaultPartition), ct.StaticClientSID, ) - ct.Assert.FortioFetch2HeaderEcho(t, staticClientWorkload, &topology.Destination{ + ct.Assert.FortioFetch2HeaderEcho(t, staticClientWorkload, &topology.Upstream{ ID: ct.StaticServerSID, LocalPort: 5000, }) - ct.Assert.FortioFetch2FortioName(t, staticClientWorkload, &topology.Destination{ + ct.Assert.FortioFetch2FortioName(t, staticClientWorkload, &topology.Upstream{ ID: ct.StaticServerSID, LocalPort: 5000, }, dc1, staticServerSID) - ct.Assert.DestinationEndpointStatus(t, staticClientWorkload, "v2.static-server.default", "HEALTHY", 1) + ct.Assert.UpstreamEndpointStatus(t, staticClientWorkload, "v2.static-server.default", "HEALTHY", 1) } resolverV2AssertFn() @@ -82,7 +82,7 @@ func TestTrafficManagement_ResolverDefaultSubset_Agentless(t *testing.T) { topology.NewNodeID("dc1-client2", defaultPartition), ct.StaticClientSID, ) - ct.Assert.FortioFetch2ServiceUnavailable(t, staticClientWorkload, &topology.Destination{ + ct.Assert.FortioFetch2ServiceUnavailable(t, staticClientWorkload, &topology.Upstream{ ID: ct.StaticServerSID, LocalPort: 5000, }) diff --git a/testing/deployer/README.md b/testing/deployer/README.md index 604bbdb087..513c6c6245 100644 --- a/testing/deployer/README.md +++ b/testing/deployer/README.md @@ -12,7 +12,7 @@ provider to manage a fleet of local docker containers and networks. The complete topology of Consul clusters is defined using a topology.Config which allows you to define a set of networks and reference those networks when -assigning nodes and services to clusters. Both Consul clients and +assigning nodes and workloads to clusters. Both Consul clients and `consul-dataplane` instances are supported. Here is an example configuration with two peered clusters: @@ -39,9 +39,9 @@ cfg := &topology.Config{ { Kind: topology.NodeKindClient, Name: "dc1-client1", - Services: []*topology.Service{ + Workloads: []*topology.Workload{ { - ID: topology.ServiceID{Name: "mesh-gateway"}, + ID: topology.ID{Name: "mesh-gateway"}, Port: 8443, EnvoyAdminPort: 19000, IsMeshGateway: true, @@ -51,9 +51,9 @@ cfg := &topology.Config{ { Kind: topology.NodeKindClient, Name: "dc1-client2", - Services: []*topology.Service{ + Workloads: []*topology.Workload{ { - ID: topology.ServiceID{Name: "ping"}, + ID: topology.ID{Name: "ping"}, Image: "rboyer/pingpong:latest", Port: 8080, EnvoyAdminPort: 19000, @@ -65,7 +65,7 @@ cfg := &topology.Config{ "-name", "ping", }, Upstreams: []*topology.Upstream{{ - ID: topology.ServiceID{Name: "pong"}, + ID: topology.ID{Name: "pong"}, LocalPort: 9090, Peer: "peer-dc2-default", }}, @@ -99,9 +99,9 @@ cfg := &topology.Config{ { Kind: topology.NodeKindClient, Name: "dc2-client1", - Services: []*topology.Service{ + Workloads: []*topology.Workload{ { - ID: topology.ServiceID{Name: "mesh-gateway"}, + ID: topology.ID{Name: "mesh-gateway"}, Port: 8443, EnvoyAdminPort: 19000, IsMeshGateway: true, @@ -111,9 +111,9 @@ cfg := &topology.Config{ { Kind: topology.NodeKindDataplane, Name: "dc2-client2", - Services: []*topology.Service{ + Workloads: []*topology.Workload{ { - ID: topology.ServiceID{Name: "pong"}, + ID: topology.ID{Name: "pong"}, Image: "rboyer/pingpong:latest", Port: 8080, EnvoyAdminPort: 19000, @@ -125,7 +125,7 @@ cfg := &topology.Config{ "-name", "pong", }, Upstreams: []*topology.Upstream{{ - ID: topology.ServiceID{Name: "ping"}, + ID: topology.ID{Name: "ping"}, LocalPort: 9090, Peer: "peer-dc1-default", }}, @@ -176,4 +176,4 @@ func TestSomething(t *testing.T) { sp := sprawltest.Launch(t, cfg) // do stuff with 'sp' } -``` \ No newline at end of file +``` diff --git a/testing/deployer/sprawl/acl_rules.go b/testing/deployer/sprawl/acl_rules.go index 554b418cd0..fd0033f246 100644 --- a/testing/deployer/sprawl/acl_rules.go +++ b/testing/deployer/sprawl/acl_rules.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/testing/deployer/topology" ) @@ -98,13 +97,6 @@ func tokenForWorkload(wrk *topology.Workload, overridePolicy *api.ACLPolicy, ent } if overridePolicy != nil { token.Policies = []*api.ACLTokenPolicyLink{{ID: overridePolicy.ID}} - } else if wrk.IsV2() { - token.TemplatedPolicies = []*api.ACLTemplatedPolicy{{ - TemplateName: api.ACLTemplatedPolicyWorkloadIdentityName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: wrk.WorkloadIdentity, - }, - }} } else { token.ServiceIdentities = []*api.ACLServiceIdentity{{ ServiceName: wrk.ID.Name, diff --git a/testing/deployer/sprawl/boot.go b/testing/deployer/sprawl/boot.go index 908916a113..2840eaf760 100644 --- a/testing/deployer/sprawl/boot.go +++ b/testing/deployer/sprawl/boot.go @@ -13,9 +13,10 @@ import ( "time" retry "github.com/avast/retry-go" - "github.com/hashicorp/consul/api" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/api" "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" @@ -258,8 +259,8 @@ func (s *Sprawl) initConsulServers() error { return fmt.Errorf("error creating final client for cluster=%s: %v", cluster.Name, err) } - // Connect to gRPC as well. - if cluster.EnableV2 { + // Connect to gRPC as well for the resource service. + { s.grpcConns[cluster.Name], s.grpcConnCancel[cluster.Name], err = s.dialServerGRPC(cluster, node, mgmtToken) if err != nil { return fmt.Errorf("error creating gRPC client conn for cluster=%s: %w", cluster.Name, err) @@ -281,11 +282,8 @@ func (s *Sprawl) initConsulServers() error { return fmt.Errorf("populateInitialConfigEntries[%s]: %w", cluster.Name, err) } - if cluster.EnableV2 { - // Resources are available only in V2 - if err := s.populateInitialResources(cluster); err != nil { - return fmt.Errorf("populateInitialResources[%s]: %w", cluster.Name, err) - } + if err := s.populateInitialResources(cluster); err != nil { + return fmt.Errorf("populateInitialResources[%s]: %w", cluster.Name, err) } if err := s.createAnonymousToken(cluster); err != nil { @@ -535,9 +533,6 @@ func (s *Sprawl) waitForLocalWrites(cluster *topology.Cluster, token string) { } func (s *Sprawl) waitForClientAntiEntropyOnce(cluster *topology.Cluster) error { - if cluster.EnableV2 { - return nil // v1 catalog is disabled when v2 catalog is enabled - } var ( client = s.clients[cluster.Name] logger = s.logger.With("cluster", cluster.Name) diff --git a/testing/deployer/sprawl/catalog.go b/testing/deployer/sprawl/catalog.go index bde3c9a266..e8ec68b03d 100644 --- a/testing/deployer/sprawl/catalog.go +++ b/testing/deployer/sprawl/catalog.go @@ -9,14 +9,11 @@ import ( "net/http" "time" - "github.com/hashicorp/consul/api" - 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" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/consul/testing/deployer/util" ) @@ -49,9 +46,6 @@ func (s *Sprawl) registerServicesToAgents(cluster *topology.Cluster) error { if !node.IsAgent() { continue } - if node.IsV2() { - panic("don't call this") - } agentClient, err := util.ProxyAPIClient( node.LocalProxyPort(), @@ -82,9 +76,6 @@ func (s *Sprawl) registerAgentService( if !node.IsAgent() { panic("called wrong method type") } - if node.IsV2() { - panic("don't call this") - } if wrk.IsMeshGateway { return nil // handled at startup time for agent-ful, but won't be for agent-less @@ -107,19 +98,19 @@ func (s *Sprawl) registerAgentService( if !wrk.DisableServiceMesh { var upstreams []api.Upstream - for _, dest := range wrk.Destinations { + for _, us := range wrk.Upstreams { uAPI := api.Upstream{ - DestinationPeer: dest.Peer, - DestinationName: dest.ID.Name, - LocalBindAddress: dest.LocalAddress, - LocalBindPort: dest.LocalPort, + DestinationPeer: us.Peer, + DestinationName: us.ID.Name, + LocalBindAddress: us.LocalAddress, + LocalBindPort: us.LocalPort, // Config map[string]interface{} `json:",omitempty" bexpr:"-"` // MeshGateway MeshGatewayConfig `json:",omitempty"` } if cluster.Enterprise { - uAPI.DestinationNamespace = dest.ID.Namespace - if dest.Peer == "" { - uAPI.DestinationPartition = dest.ID.Partition + uAPI.DestinationNamespace = us.ID.Namespace + if us.Peer == "" { + uAPI.DestinationPartition = us.ID.Partition } } upstreams = append(upstreams, uAPI) @@ -179,65 +170,14 @@ RETRY: // syncWorkloadsForDataplaneInstances register/deregister services in the given cluster func (s *Sprawl) syncWorkloadsForDataplaneInstances(cluster *topology.Cluster) error { - identityInfo := make(map[topology.ID]*Resource[*pbauth.WorkloadIdentity]) - // registerWorkloadToNode is called when node is not disabled registerWorkloadToNode := func(node *topology.Node, wrk *topology.Workload) error { - if node.IsV2() { - pending := workloadInstanceToResources(node, wrk) - - workloadID := topology.NewID(wrk.WorkloadIdentity, wrk.ID.Namespace, wrk.ID.Partition) - if _, ok := identityInfo[workloadID]; !ok { - identityInfo[workloadID] = pending.WorkloadIdentity - } - - // Write workload - res, err := pending.Workload.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.Workload.Resource.Id), err) - } - workload, err := s.writeResource(cluster, res) - if err != nil { - return err - } - // Write check linked to workload - for _, check := range pending.HealthStatuses { - check.Resource.Owner = workload.Id - res, err := check.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(check.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } - } - // maybe write destinations - if pending.Destinations != nil { - res, err := pending.Destinations.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.Destinations.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } - } - if pending.ProxyConfiguration != nil { - res, err := pending.ProxyConfiguration.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.ProxyConfiguration.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } - } - } else { - if err := s.registerCatalogServiceV1(cluster, node, wrk); err != nil { - return fmt.Errorf("error registering service: %w", err) - } - if !wrk.DisableServiceMesh { - if err := s.registerCatalogSidecarServiceV1(cluster, node, wrk); err != nil { - return fmt.Errorf("error registering sidecar service: %w", err) - } + if err := s.registerCatalogServiceV1(cluster, node, wrk); err != nil { + return fmt.Errorf("error registering service: %w", err) + } + if !wrk.DisableServiceMesh { + if err := s.registerCatalogSidecarServiceV1(cluster, node, wrk); err != nil { + return fmt.Errorf("error registering sidecar service: %w", err) } } return nil @@ -245,17 +185,12 @@ func (s *Sprawl) syncWorkloadsForDataplaneInstances(cluster *topology.Cluster) e // deregisterWorkloadFromNode is called when node is disabled deregisterWorkloadFromNode := func(node *topology.Node, wrk *topology.Workload) error { - if node.IsV2() { - // TODO: implement deregister workload for v2 - panic("deregister workload is not implemented for V2") - } else { - if err := s.deregisterCatalogServiceV1(cluster, node, wrk); err != nil { - return fmt.Errorf("error deregistering service: %w", err) - } - if !wrk.DisableServiceMesh { - if err := s.deregisterCatalogSidecarServiceV1(cluster, node, wrk); err != nil { - return fmt.Errorf("error deregistering sidecar service: %w", err) - } + if err := s.deregisterCatalogServiceV1(cluster, node, wrk); err != nil { + return fmt.Errorf("error deregistering service: %w", err) + } + if !wrk.DisableServiceMesh { + if err := s.deregisterCatalogSidecarServiceV1(cluster, node, wrk); err != nil { + return fmt.Errorf("error deregistering sidecar service: %w", err) } } return nil @@ -299,42 +234,6 @@ func (s *Sprawl) syncWorkloadsForDataplaneInstances(cluster *topology.Cluster) e } } - if cluster.EnableV2 { - for _, identity := range identityInfo { - res, err := identity.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(identity.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } - } - - for id, svcData := range cluster.Services { - svcInfo := &Resource[*pbcatalog.Service]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbcatalog.ServiceType, - Name: id.Name, - Tenancy: &pbresource.Tenancy{ - Partition: id.Partition, - Namespace: id.Namespace, - }, - }, - }, - Data: svcData, - } - - res, err := svcInfo.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(svcInfo.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } - } - } - return nil } @@ -342,9 +241,6 @@ func (s *Sprawl) registerCatalogNode( cluster *topology.Cluster, node *topology.Node, ) error { - if node.IsV2() { - return s.registerCatalogNodeV2(cluster, node) - } return s.registerCatalogNodeV1(cluster, node) } @@ -352,49 +248,9 @@ func (s *Sprawl) deregisterCatalogNode( cluster *topology.Cluster, node *topology.Node, ) error { - if node.IsV2() { - panic("deregister V2 node is not implemented") - } return s.deregisterCatalogNodeV1(cluster, node) } -func (s *Sprawl) registerCatalogNodeV2( - cluster *topology.Cluster, - node *topology.Node, -) error { - if !node.IsDataplane() { - panic("called wrong method type") - } - - nodeRes := &Resource[*pbcatalog.Node]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbcatalog.NodeType, - Name: node.PodName(), - Tenancy: &pbresource.Tenancy{ - Partition: node.Partition, - }, - }, - Metadata: map[string]string{ - "dataplane-faux": "1", - }, - }, - Data: &pbcatalog.Node{ - Addresses: []*pbcatalog.NodeAddress{ - {Host: node.LocalAddress()}, - }, - }, - } - - res, err := nodeRes.Build() - if err != nil { - return err - } - - _, err = s.writeResource(cluster, res) - return err -} - func (s *Sprawl) writeResource(cluster *topology.Cluster, res *pbresource.Resource) (*pbresource.Resource, error) { var ( client = s.getResourceClient(cluster.Name) @@ -505,9 +361,6 @@ func (s *Sprawl) deregisterCatalogServiceV1( if !node.IsDataplane() { panic("called wrong method type") } - if node.IsV2() { - panic("don't call this") - } var ( client = s.clients[cluster.Name] @@ -543,9 +396,6 @@ func (s *Sprawl) registerCatalogServiceV1( if !node.IsDataplane() { panic("called wrong method type") } - if node.IsV2() { - panic("don't call this") - } var ( client = s.clients[cluster.Name] @@ -582,9 +432,6 @@ func (s *Sprawl) deregisterCatalogSidecarServiceV1( if wrk.DisableServiceMesh { panic("not valid") } - if node.IsV2() { - panic("don't call this") - } var ( client = s.clients[cluster.Name] @@ -626,9 +473,6 @@ func (s *Sprawl) registerCatalogSidecarServiceV1( if wrk.DisableServiceMesh { panic("not valid") } - if node.IsV2() { - panic("don't call this") - } var ( client = s.clients[cluster.Name] @@ -667,172 +511,11 @@ func (r *Resource[V]) Build() (*pbresource.Resource, error) { return r.Resource, nil } -type ServiceResources struct { - Workload *Resource[*pbcatalog.Workload] - HealthStatuses []*Resource[*pbcatalog.HealthStatus] - Destinations *Resource[*pbmesh.Destinations] - WorkloadIdentity *Resource[*pbauth.WorkloadIdentity] - ProxyConfiguration *Resource[*pbmesh.ProxyConfiguration] -} - -func workloadInstanceToResources( - node *topology.Node, - wrk *topology.Workload, -) *ServiceResources { - if wrk.IsMeshGateway { - panic("v2 does not yet support mesh gateways") - } - - tenancy := &pbresource.Tenancy{ - Partition: wrk.ID.Partition, - Namespace: wrk.ID.Namespace, - } - - var ( - wlPorts = map[string]*pbcatalog.WorkloadPort{} - ) - for name, port := range wrk.Ports { - wlPorts[name] = &pbcatalog.WorkloadPort{ - Port: uint32(port.Number), - Protocol: port.ActualProtocol, - } - } - - var ( - selector = &pbcatalog.WorkloadSelector{ - Names: []string{wrk.Workload}, - } - - workloadRes = &Resource[*pbcatalog.Workload]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbcatalog.WorkloadType, - Name: wrk.Workload, - Tenancy: tenancy, - }, - Metadata: wrk.Meta, - }, - Data: &pbcatalog.Workload{ - NodeName: node.PodName(), - Identity: wrk.WorkloadIdentity, - Ports: wlPorts, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: node.LocalAddress()}, - }, - }, - } - workloadIdentityRes = &Resource[*pbauth.WorkloadIdentity]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.WorkloadIdentityType, - Name: wrk.WorkloadIdentity, - Tenancy: tenancy, - }, - }, - Data: &pbauth.WorkloadIdentity{}, - } - - healthResList []*Resource[*pbcatalog.HealthStatus] - destinationsRes *Resource[*pbmesh.Destinations] - proxyConfigRes *Resource[*pbmesh.ProxyConfiguration] - ) - - if wrk.HasCheck() { - // TODO: needs ownerId - checkRes := &Resource[*pbcatalog.HealthStatus]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbcatalog.HealthStatusType, - Name: wrk.Workload + "-check-0", - Tenancy: tenancy, - }, - }, - Data: &pbcatalog.HealthStatus{ - Type: "external-sync", - Status: pbcatalog.Health_HEALTH_PASSING, - }, - } - - healthResList = []*Resource[*pbcatalog.HealthStatus]{checkRes} - } - - if node.HasPublicAddress() { - workloadRes.Data.Addresses = append(workloadRes.Data.Addresses, - &pbcatalog.WorkloadAddress{Host: node.PublicAddress(), External: true}, - ) - } - - if !wrk.DisableServiceMesh { - destinationsRes = &Resource[*pbmesh.Destinations]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbmesh.DestinationsType, - Name: wrk.Workload, - Tenancy: tenancy, - }, - }, - Data: &pbmesh.Destinations{ - Workloads: selector, - }, - } - - for _, dest := range wrk.Destinations { - meshDest := &pbmesh.Destination{ - DestinationRef: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: dest.ID.Name, - Tenancy: &pbresource.Tenancy{ - Partition: dest.ID.Partition, - Namespace: dest.ID.Namespace, - }, - }, - DestinationPort: dest.PortName, - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: dest.LocalAddress, - Port: uint32(dest.LocalPort), - }, - }, - } - destinationsRes.Data.Destinations = append(destinationsRes.Data.Destinations, meshDest) - } - - if wrk.EnableTransparentProxy { - proxyConfigRes = &Resource[*pbmesh.ProxyConfiguration]{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbmesh.ProxyConfigurationType, - Name: wrk.Workload, - Tenancy: tenancy, - }, - }, - Data: &pbmesh.ProxyConfiguration{ - Workloads: selector, - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - }, - }, - } - } - } - - return &ServiceResources{ - Workload: workloadRes, - HealthStatuses: healthResList, - Destinations: destinationsRes, - WorkloadIdentity: workloadIdentityRes, - ProxyConfiguration: proxyConfigRes, - } -} - func workloadToCatalogRegistration( cluster *topology.Cluster, node *topology.Node, wrk *topology.Workload, ) *api.CatalogRegistration { - if node.IsV2() { - panic("don't call this") - } reg := &api.CatalogRegistration{ Node: node.PodName(), SkipNodeUpdate: true, @@ -921,9 +604,6 @@ func workloadToSidecarCatalogRegistration( node *topology.Node, wrk *topology.Workload, ) (topology.ID, *api.CatalogRegistration) { - if node.IsV2() { - panic("don't call this") - } pid := wrk.ID pid.Name += "-sidecar-proxy" reg := &api.CatalogRegistration{ @@ -970,17 +650,17 @@ func workloadToSidecarCatalogRegistration( reg.Checks[0].Partition = pid.Partition } - for _, dest := range wrk.Destinations { + for _, us := range wrk.Upstreams { pu := api.Upstream{ - DestinationName: dest.ID.Name, - DestinationPeer: dest.Peer, - LocalBindAddress: dest.LocalAddress, - LocalBindPort: dest.LocalPort, + DestinationName: us.ID.Name, + DestinationPeer: us.Peer, + LocalBindAddress: us.LocalAddress, + LocalBindPort: us.LocalPort, } if cluster.Enterprise { - pu.DestinationNamespace = dest.ID.Namespace - if dest.Peer == "" { - pu.DestinationPartition = dest.ID.Partition + pu.DestinationNamespace = us.ID.Namespace + if us.Peer == "" { + pu.DestinationPartition = us.ID.Partition } } reg.Service.Proxy.Upstreams = append(reg.Service.Proxy.Upstreams, pu) diff --git a/testing/deployer/sprawl/details.go b/testing/deployer/sprawl/details.go index 4fde28bed2..f4f91f8d74 100644 --- a/testing/deployer/sprawl/details.go +++ b/testing/deployer/sprawl/details.go @@ -13,6 +13,7 @@ import ( "time" retry "github.com/avast/retry-go" + "github.com/hashicorp/consul/api" ) @@ -86,15 +87,10 @@ func (s *Sprawl) PrintDetails() error { Service: wrk.ID.String(), }) } else { - ports := make(map[string]int) - for name, port := range wrk.Ports { - ports[name] = node.ExposedPort(port.Number) - } cd.Apps = append(cd.Apps, appDetail{ Type: "app", Container: node.DockerName(), ExposedPort: node.ExposedPort(wrk.Port), - ExposedPorts: ports, ExposedEnvoyAdminPort: node.ExposedPort(wrk.EnvoyAdminPort), Addresses: addrs, Service: wrk.ID.String(), @@ -142,17 +138,7 @@ func (s *Sprawl) PrintDetails() error { if d.Type == "server" && d.Container == cluster.Leader { d.Type = "leader" } - var portStr string - if len(d.ExposedPorts) > 0 { - var out []string - for name, exposed := range d.ExposedPorts { - out = append(out, fmt.Sprintf("app:%s=%d", name, exposed)) - } - sort.Strings(out) - portStr = strings.Join(out, " ") - } else { - portStr = "app=" + strconv.Itoa(d.ExposedPort) - } + portStr := "app=" + strconv.Itoa(d.ExposedPort) if d.ExposedEnvoyAdminPort > 0 { portStr += " envoy=" + strconv.Itoa(d.ExposedEnvoyAdminPort) } @@ -191,9 +177,8 @@ type appDetail struct { Type string // server|mesh-gateway|app Container string Addresses []string - ExposedPort int `json:",omitempty"` - ExposedPorts map[string]int `json:",omitempty"` - ExposedEnvoyAdminPort int `json:",omitempty"` + ExposedPort int `json:",omitempty"` + ExposedEnvoyAdminPort int `json:",omitempty"` // just services Service string `json:",omitempty"` } diff --git a/testing/deployer/sprawl/internal/build/docker.go b/testing/deployer/sprawl/internal/build/docker.go index 53baa07ae7..bb24047154 100644 --- a/testing/deployer/sprawl/internal/build/docker.go +++ b/testing/deployer/sprawl/internal/build/docker.go @@ -102,7 +102,7 @@ func DockerImages( built := make(map[string]struct{}) for _, c := range t.Clusters { for _, n := range c.Nodes { - needsTproxy := n.NeedsTransparentProxy() + const needsTproxy = false // TODO: see if we can bring this back for v1 CDP joint := n.Images.EnvoyConsulImage() if _, ok := built[joint]; joint != "" && !ok { diff --git a/testing/deployer/sprawl/internal/tfgen/agent.go b/testing/deployer/sprawl/internal/tfgen/agent.go index 58bd564e64..efd8589525 100644 --- a/testing/deployer/sprawl/internal/tfgen/agent.go +++ b/testing/deployer/sprawl/internal/tfgen/agent.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/consul/testing/deployer/topology" ) -func (g *Generator) generateAgentHCL(node *topology.Node, enableV2, enableV2Tenancy bool) string { +func (g *Generator) generateAgentHCL(node *topology.Node) string { if !node.IsAgent() { panic("generateAgentHCL only applies to agents") } @@ -41,17 +41,6 @@ func (g *Generator) generateAgentHCL(node *topology.Node, enableV2, enableV2Tena b.add("enable_debug", true) b.add("use_streaming_backend", true) - var experiments []string - if enableV2 { - experiments = append(experiments, "resource-apis") - } - if enableV2Tenancy { - experiments = append(experiments, "v2tenancy") - } - if len(experiments) > 0 { - b.addSlice("experiments", experiments) - } - // speed up leaves b.addBlock("performance", func() { b.add("leave_drain_time", "50ms") diff --git a/testing/deployer/sprawl/internal/tfgen/dns.go b/testing/deployer/sprawl/internal/tfgen/dns.go index 9b03693c83..73ea5f388d 100644 --- a/testing/deployer/sprawl/internal/tfgen/dns.go +++ b/testing/deployer/sprawl/internal/tfgen/dns.go @@ -8,11 +8,8 @@ import ( "fmt" "os" "path/filepath" - "sort" "strings" - "golang.org/x/exp/maps" - "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/consul/testing/deployer/util" ) @@ -66,22 +63,6 @@ func (g *Generator) writeCoreDNSFiles(net *topology.Network, dnsIPAddress string } } - // Until Consul DNS understands v2, simulate it. - // - // NOTE: this DNS is not quite what consul normally does. It's simpler - // to simulate this format here. - virtualNames := make(map[string][]string) - for id, svcData := range cluster.Services { - if len(svcData.VirtualIps) == 0 { - continue - } - vips := svcData.VirtualIps - - // ----.virtual. - name := fmt.Sprintf("%s--%s--%s", id.Name, id.Namespace, id.Partition) - virtualNames[name] = vips - } - var ( clusterDNSName = cluster.Name + "-consulcluster.lan" virtualDNSName = "virtual.consul" @@ -132,7 +113,6 @@ func (g *Generator) writeCoreDNSFiles(net *topology.Network, dnsIPAddress string generateCoreDNSVirtualZoneFile( dnsIPAddress, virtualDNSName, - virtualNames, ), virtualZonefilePath, 0644, @@ -230,7 +210,6 @@ server IN A %s ; Consul server func generateCoreDNSVirtualZoneFile( dnsIPAddress string, virtualDNSName string, - nameToAddr map[string][]string, ) []byte { var buf bytes.Buffer buf.WriteString(fmt.Sprintf(` @@ -247,17 +226,5 @@ $ORIGIN %[1]s. ns IN A %[2]s ; self `, virtualDNSName, dnsIPAddress)) - names := maps.Keys(nameToAddr) - sort.Strings(names) - - for _, name := range names { - vips := nameToAddr[name] - for _, vip := range vips { - buf.WriteString(fmt.Sprintf(` -%s IN A %s ; Consul server -`, name, vip)) - } - } - return buf.Bytes() } diff --git a/testing/deployer/sprawl/internal/tfgen/gen.go b/testing/deployer/sprawl/internal/tfgen/gen.go index 7985cff774..0f5f74df28 100644 --- a/testing/deployer/sprawl/internal/tfgen/gen.go +++ b/testing/deployer/sprawl/internal/tfgen/gen.go @@ -262,9 +262,6 @@ func (g *Generator) Generate(step Step) error { addImage("", node.Images.Consul) addImage("", node.Images.EnvoyConsulImage()) addImage("", node.Images.LocalDataplaneImage()) - if node.NeedsTransparentProxy() { - addImage("", node.Images.LocalDataplaneTProxyImage()) - } if node.IsAgent() { addVolume(node.DockerName()) diff --git a/testing/deployer/sprawl/internal/tfgen/nodes.go b/testing/deployer/sprawl/internal/tfgen/nodes.go index 8ef8f10199..06f37453a4 100644 --- a/testing/deployer/sprawl/internal/tfgen/nodes.go +++ b/testing/deployer/sprawl/internal/tfgen/nodes.go @@ -67,7 +67,7 @@ func (g *Generator) generateNodeContainers( }{ terraformPod: pod, ImageResource: DockerImageResourceName(node.Images.Consul), - HCL: g.generateAgentHCL(node, cluster.EnableV2 && node.IsServer(), cluster.EnableV2Tenancy && node.IsServer()), + HCL: g.generateAgentHCL(node), EnterpriseLicense: g.license, })) } @@ -125,11 +125,7 @@ func (g *Generator) generateNodeContainers( var img string if node.IsDataplane() { tmpl = tfAppDataplaneT - if wrk.EnableTransparentProxy { - img = DockerImageResourceName(node.Images.LocalDataplaneTProxyImage()) - } else { - img = DockerImageResourceName(node.Images.LocalDataplaneImage()) - } + img = DockerImageResourceName(node.Images.LocalDataplaneImage()) } else { img = DockerImageResourceName(node.Images.EnvoyConsulImage()) } 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 index a72bd21bbf..9a65c3426a 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl @@ -17,39 +17,20 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Workload.ID.TFString}}-side read_only = true } -{{ if .Workload.EnableTransparentProxy }} - capabilities { - add = ["NET_ADMIN"] - } - entrypoint = [ "/bin/tproxy-startup.sh" ] -{{ end }} - env = [ "DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan", -{{ if .Node.IsV2 }} - "DP_PROXY_ID={{.Workload.Workload}}", -{{ if .Enterprise }} - "DP_PROXY_NAMESPACE={{.Workload.ID.Namespace}}", - "DP_PROXY_PARTITION={{.Workload.ID.Partition}}", -{{ end }} -{{ else }} "DP_SERVICE_NODE_NAME={{.Node.PodName}}", "DP_PROXY_SERVICE_ID={{.Workload.ID.Name}}-sidecar-proxy", {{ if .Enterprise }} "DP_SERVICE_NAMESPACE={{.Workload.ID.Namespace}}", "DP_SERVICE_PARTITION={{.Workload.ID.Partition}}", {{ end }} -{{ end }} {{ if .Token }} "DP_CREDENTIAL_TYPE=static", "DP_CREDENTIAL_STATIC_TOKEN={{.Token}}", {{ end }} -{{ if .Workload.EnableTransparentProxy }} - "REDIRECT_TRAFFIC_ARGS=-exclude-inbound-port=19000", -{{ end }} - // for demo purposes "DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0", "DP_ENVOY_ADMIN_BIND_PORT=19000", diff --git a/testing/deployer/sprawl/sprawltest/test_test.go b/testing/deployer/sprawl/sprawltest/test_test.go index 30ebfc181f..84fc5ecbfd 100644 --- a/testing/deployer/sprawl/sprawltest/test_test.go +++ b/testing/deployer/sprawl/sprawltest/test_test.go @@ -12,147 +12,10 @@ import ( "github.com/stretchr/testify/require" "github.com/hashicorp/consul/api" - 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/testing/deployer/sprawl/sprawltest" "github.com/hashicorp/consul/testing/deployer/topology" ) -func TestSprawl_CatalogV2(t *testing.T) { - serversDC1 := newTopologyServerSet("dc1-server", 3, []string{"dc1", "wan"}, nil) - - cfg := &topology.Config{ - Images: topology.Images{ - ConsulCE: "hashicorppreview/consul:1.17-dev", - ConsulEnterprise: "hashicorppreview/consul-enterprise:1.17-dev", - Dataplane: "hashicorppreview/consul-dataplane:1.3-dev", - }, - Networks: []*topology.Network{ - {Name: "dc1"}, - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - { - Enterprise: true, - Name: "dc1", - Nodes: topology.MergeSlices(serversDC1, []*topology.Node{ - { - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Name: "dc1-client1", - Workloads: []*topology.Workload{ - { - ID: topology.ID{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", - }, - Destinations: []*topology.Destination{{ - ID: topology.ID{Name: "pong"}, - LocalPort: 9090, - }}, - }, - }, - }, - { - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Name: "dc1-client2", - Workloads: []*topology.Workload{ - { - ID: topology.ID{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", - }, - Destinations: []*topology.Destination{{ - ID: topology.ID{Name: "ping"}, - LocalPort: 9090, - }}, - }, - }, - }, - }), - InitialResources: []*pbresource.Resource{ - sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbmesh.HTTPRouteType, - Name: "test-http-route", - }, - }, &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Name: "test", - }, - }}, - }), - sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "ping-perms", - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "ping", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: []*pbauth.Source{{ - IdentityName: "pong", - }}, - }}, - }), - sprawltest.MustSetResourceData(t, &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbauth.TrafficPermissionsType, - Name: "pong-perms", - }, - }, &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "pong", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{{ - Sources: []*pbauth.Source{{ - IdentityName: "ping", - }}, - }}, - }), - }, - }, - }, - } - - 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 TestSprawl(t *testing.T) { serversDC1 := newTopologyServerSet("dc1-server", 3, []string{"dc1", "wan"}, nil) serversDC2 := newTopologyServerSet("dc2-server", 3, []string{"dc2", "wan"}, nil) @@ -201,7 +64,7 @@ func TestSprawl(t *testing.T) { "-dialfreq", "250ms", "-name", "ping", }, - Destinations: []*topology.Destination{{ + Upstreams: []*topology.Upstream{{ ID: topology.ID{Name: "pong"}, LocalPort: 9090, Peer: "peer-dc2-default", @@ -253,32 +116,7 @@ func TestSprawl(t *testing.T) { "-dialfreq", "250ms", "-name", "pong", }, - Destinations: []*topology.Destination{{ - ID: topology.ID{Name: "ping"}, - LocalPort: 9090, - Peer: "peer-dc1-default", - }}, - }, - }, - }, - { - Kind: topology.NodeKindDataplane, - Version: topology.NodeVersionV2, - Name: "dc2-client3", - Workloads: []*topology.Workload{ - { - ID: topology.ID{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", - }, - Destinations: []*topology.Destination{{ + Upstreams: []*topology.Upstream{{ ID: topology.ID{Name: "ping"}, LocalPort: 9090, Peer: "peer-dc1-default", diff --git a/testing/deployer/topology/compile.go b/testing/deployer/topology/compile.go index 130284f37d..ffed56aaf3 100644 --- a/testing/deployer/topology/compile.go +++ b/testing/deployer/topology/compile.go @@ -17,9 +17,6 @@ import ( "github.com/hashicorp/go-hclog" - 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/testing/deployer/util" ) @@ -133,22 +130,6 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) return nil, fmt.Errorf("cluster %q has no nodes", c.Name) } - if len(c.Services) == 0 { // always initialize this regardless of v2-ness, because we might late-enable it below - c.Services = make(map[ID]*pbcatalog.Service) - } - - var implicitV2Services bool - if len(c.Services) > 0 { - c.EnableV2 = true - for name, svc := range c.Services { - if svc.Workloads != nil { - return nil, fmt.Errorf("the workloads field for v2 service %q is not user settable", name) - } - } - } else { - implicitV2Services = true - } - if c.TLSVolumeName != "" { return nil, fmt.Errorf("user cannot specify the TLSVolumeName field") } @@ -177,31 +158,17 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) addTenancy(ce.GetPartition(), ce.GetNamespace()) } - if len(c.InitialResources) > 0 { - c.EnableV2 = true - } for _, res := range c.InitialResources { if res.Id.Tenancy == nil { res.Id.Tenancy = &pbresource.Tenancy{} } - // TODO(peering/v2) prevent non-local peer resources res.Id.Tenancy.Partition = PartitionOrDefault(res.Id.Tenancy.Partition) if !util.IsTypePartitionScoped(res.Id.Type) { res.Id.Tenancy.Namespace = NamespaceOrDefault(res.Id.Tenancy.Namespace) } - switch { - case util.EqualType(pbauth.ComputedTrafficPermissionsType, res.Id.GetType()), - util.EqualType(pbauth.WorkloadIdentityType, res.Id.GetType()): - fallthrough - case util.EqualType(pbmesh.ComputedRoutesType, res.Id.GetType()), - util.EqualType(pbmesh.ProxyStateTemplateType, res.Id.GetType()): - fallthrough - case util.EqualType(pbcatalog.HealthChecksType, res.Id.GetType()), - util.EqualType(pbcatalog.HealthStatusType, res.Id.GetType()), - util.EqualType(pbcatalog.NodeType, res.Id.GetType()), - util.EqualType(pbcatalog.ServiceEndpointsType, res.Id.GetType()), - util.EqualType(pbcatalog.WorkloadType, res.Id.GetType()): + // TODO: if we reintroduce new resources for v1, allow them here + if true { return nil, fmt.Errorf("you should not create a resource of type %q this way", util.TypeToString(res.Id.Type)) } @@ -222,20 +189,6 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) return nil, fmt.Errorf("cluster %q node %q has invalid kind: %s", c.Name, n.Name, n.Kind) } - if n.Version == NodeVersionUnknown { - n.Version = NodeVersionV1 - } - switch n.Version { - case NodeVersionV1: - case NodeVersionV2: - if n.Kind == NodeKindClient { - return nil, fmt.Errorf("v2 does not support client agents at this time") - } - c.EnableV2 = true - default: - return nil, fmt.Errorf("cluster %q node %q has invalid version: %s", c.Name, n.Name, n.Version) - } - n.Partition = PartitionOrDefault(n.Partition) if !IsValidLabel(n.Partition) { return nil, fmt.Errorf("node partition is not valid: %s", n.Partition) @@ -318,12 +271,6 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) return nil, fmt.Errorf("cluster %q node %q has more than one public address", c.Name, n.Name) } - if len(n.Services) > 0 { - logger.Warn("please use Node.Workloads instead of Node.Services") - n.Workloads = append(n.Workloads, n.Services...) - n.Services = nil - } - if n.IsDataplane() && len(n.Workloads) > 1 { // Our use of consul-dataplane here is supposed to mimic that // of consul-k8s, which ultimately has one IP per Service, so @@ -344,10 +291,6 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) // Denormalize wrk.Node = n - wrk.NodeVersion = n.Version - if n.IsV2() { - wrk.Workload = wrk.ID.Name + "-" + n.Name - } if !IsValidLabel(wrk.ID.Partition) { return nil, fmt.Errorf("service partition is not valid: %s", wrk.ID.Partition) @@ -404,136 +347,42 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) // return nil, fmt.Errorf("service has invalid protocol: %s", wrk.Protocol) // } - defaultDestination := func(dest *Destination) error { + defaultUpstream := func(us *Upstream) error { // Default to that of the enclosing service. - if dest.Peer == "" { - if dest.ID.Partition == "" { - dest.ID.Partition = wrk.ID.Partition + if us.Peer == "" { + if us.ID.Partition == "" { + us.ID.Partition = wrk.ID.Partition } - if dest.ID.Namespace == "" { - dest.ID.Namespace = wrk.ID.Namespace + if us.ID.Namespace == "" { + us.ID.Namespace = wrk.ID.Namespace } } else { - if dest.ID.Partition != "" { - dest.ID.Partition = "" // irrelevant here; we'll set it to the value of the OTHER side for plumbing purposes in tests + if us.ID.Partition != "" { + us.ID.Partition = "" // irrelevant here; we'll set it to the value of the OTHER side for plumbing purposes in tests } - dest.ID.Namespace = NamespaceOrDefault(dest.ID.Namespace) - foundPeerNames[dest.Peer] = struct{}{} + us.ID.Namespace = NamespaceOrDefault(us.ID.Namespace) + foundPeerNames[us.Peer] = struct{}{} } - addTenancy(dest.ID.Partition, dest.ID.Namespace) + addTenancy(us.ID.Partition, us.ID.Namespace) - if dest.Implied { - if dest.PortName == "" { - return fmt.Errorf("implicit destinations must use port names in v2") - } - } else { - if dest.LocalAddress == "" { - // v1 defaults to 127.0.0.1 but v2 does not. Safe to do this generally though. - dest.LocalAddress = "127.0.0.1" - } - if dest.PortName != "" && n.IsV1() { - return fmt.Errorf("explicit destinations cannot use port names in v1") - } - if dest.PortName == "" && n.IsV2() { - // Assume this is a v1->v2 conversion and name it. - dest.PortName = V1DefaultPortName - } + if us.LocalAddress == "" { + // v1 consul code defaults this to 127.0.0.1, but safer to not rely upon that. + us.LocalAddress = "127.0.0.1" } return nil } - for _, dest := range wrk.Destinations { - if err := defaultDestination(dest); err != nil { + for _, us := range wrk.Upstreams { + if err := defaultUpstream(us); err != nil { return nil, err } } - if n.IsV2() { - for _, dest := range wrk.ImpliedDestinations { - dest.Implied = true - if err := defaultDestination(dest); err != nil { - return nil, err - } - } - } else { - if len(wrk.ImpliedDestinations) > 0 { - return nil, fmt.Errorf("v1 does not support implied destinations yet") - } - } - if err := wrk.Validate(); err != nil { return nil, fmt.Errorf("cluster %q node %q service %q is not valid: %w", c.Name, n.Name, wrk.ID.String(), err) } - - if wrk.EnableTransparentProxy && !n.IsDataplane() { - return nil, fmt.Errorf("cannot enable tproxy on a non-dataplane node") - } - - if n.IsV2() { - if implicitV2Services { - wrk.V2Services = []string{wrk.ID.Name} - - var svcPorts []*pbcatalog.ServicePort - for name, cfg := range wrk.Ports { - svcPorts = append(svcPorts, &pbcatalog.ServicePort{ - TargetPort: name, - Protocol: cfg.ActualProtocol, - }) - } - sort.Slice(svcPorts, func(i, j int) bool { - a, b := svcPorts[i], svcPorts[j] - if a.TargetPort < b.TargetPort { - return true - } else if a.TargetPort > b.TargetPort { - return false - } - return a.Protocol < b.Protocol - }) - - v2svc := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{}, - Ports: svcPorts, - } - - prev, ok := c.Services[wrk.ID] - if !ok { - c.Services[wrk.ID] = v2svc - prev = v2svc - } - if prev.Workloads == nil { - prev.Workloads = &pbcatalog.WorkloadSelector{} - } - prev.Workloads.Names = append(prev.Workloads.Names, wrk.Workload) - - } else { - for _, name := range wrk.V2Services { - v2ID := NewServiceID(name, wrk.ID.Namespace, wrk.ID.Partition) - - v2svc, ok := c.Services[v2ID] - if !ok { - return nil, fmt.Errorf("cluster %q node %q service %q has a v2 service reference that does not exist %q", - c.Name, n.Name, wrk.ID.String(), name) - } - if v2svc.Workloads == nil { - v2svc.Workloads = &pbcatalog.WorkloadSelector{} - } - v2svc.Workloads.Names = append(v2svc.Workloads.Names, wrk.Workload) - } - } - - if wrk.WorkloadIdentity == "" { - wrk.WorkloadIdentity = wrk.ID.Name - } - } else { - if len(wrk.V2Services) > 0 { - return nil, fmt.Errorf("cannot specify v2 services for v1") - } - if wrk.WorkloadIdentity != "" { - return nil, fmt.Errorf("cannot specify workload identities for v1") - } - } } return foundPeerNames, nil } @@ -553,53 +402,6 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) maps.Copy(foundPeerNames, peerNames) } - // Default anything in the toplevel services map. - for _, svc := range c.Services { - for _, port := range svc.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - port.Protocol = pbcatalog.Protocol_PROTOCOL_TCP - } - } - } - - if err := assignVirtualIPs(c); err != nil { - return nil, err - } - - if c.EnableV2 { - // Populate the VirtualPort field on all destinations. - for _, n := range c.Nodes { - for _, wrk := range n.Workloads { - for _, dest := range wrk.ImpliedDestinations { - res, ok := c.Services[dest.ID] - if ok { - for _, sp := range res.Ports { - if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - if sp.MatchesPortId(dest.PortName) { - dest.VirtualPort = sp.VirtualPort - } - } - } - } - for _, dest := range wrk.Destinations { - res, ok := c.Services[dest.ID] - if ok { - for _, sp := range res.Ports { - if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - if sp.MatchesPortId(dest.PortName) { - dest.VirtualPort = sp.VirtualPort - } - } - } - } - } - } - } - // Explode this into the explicit list based on stray references made. c.Partitions = nil for ap, nsMap := range tenancies { @@ -723,40 +525,25 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) } } - // after we decoded the peering stuff, we can fill in some computed data in the destinations + // 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 _, wrk := range n.Workloads { - for _, dest := range wrk.Destinations { - if dest.Peer == "" { - dest.Cluster = c.Name - dest.Peering = nil + for _, us := range wrk.Upstreams { + if us.Peer == "" { + us.Cluster = c.Name + us.Peering = nil continue } - remotePeer, ok := c.Peerings[dest.Peer] + remotePeer, ok := c.Peerings[us.Peer] if !ok { return nil, fmt.Errorf("not possible") } - dest.Cluster = remotePeer.Link.Name - dest.Peering = remotePeer.Link + us.Cluster = remotePeer.Link.Name + us.Peering = remotePeer.Link // this helps in generating fortio assertions; otherwise field is ignored - dest.ID.Partition = remotePeer.Link.Partition - } - for _, dest := range wrk.ImpliedDestinations { - if dest.Peer == "" { - dest.Cluster = c.Name - dest.Peering = nil - continue - } - remotePeer, ok := c.Peerings[dest.Peer] - if !ok { - return nil, fmt.Errorf("not possible") - } - dest.Cluster = remotePeer.Link.Name - dest.Peering = remotePeer.Link - // this helps in generating fortio assertions; otherwise field is ignored - dest.ID.Partition = remotePeer.Link.Partition + us.ID.Partition = remotePeer.Link.Partition } } } @@ -825,51 +612,6 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology, testingID string) return t, nil } -func assignVirtualIPs(c *Cluster) error { - lastVIPIndex := 1 - for _, svcData := range c.Services { - lastVIPIndex++ - if lastVIPIndex > 250 { - return fmt.Errorf("too many ips using this approach to VIPs") - } - svcData.VirtualIps = []string{ - fmt.Sprintf("10.244.0.%d", lastVIPIndex), - } - - // populate virtual ports where we forgot them - var ( - usedPorts = make(map[uint32]struct{}) - next = uint32(8080) - ) - for _, sp := range svcData.Ports { - if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - if sp.VirtualPort > 0 { - usedPorts[sp.VirtualPort] = struct{}{} - } - } - for _, sp := range svcData.Ports { - if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - if sp.VirtualPort > 0 { - continue - } - RETRY: - attempt := next - next++ - _, used := usedPorts[attempt] - if used { - goto RETRY - } - usedPorts[attempt] = struct{}{} - sp.VirtualPort = attempt - } - } - return nil -} - const permutedWarning = "use the disabled node kind if you want to ignore a node" func inheritAndValidateNodes( @@ -893,7 +635,6 @@ func inheritAndValidateNodes( } if currNode.Node.Kind != node.Kind || - currNode.Node.Version != node.Version || currNode.Node.Partition != node.Partition || currNode.Node.Name != node.Name || currNode.Node.Index != node.Index || @@ -930,7 +671,6 @@ func inheritAndValidateNodes( if currWrk.ID != wrk.ID || currWrk.Port != wrk.Port || - !maps.Equal(currWrk.Ports, wrk.Ports) || currWrk.EnvoyAdminPort != wrk.EnvoyAdminPort || currWrk.EnvoyPublicListenerPort != wrk.EnvoyPublicListenerPort || isSame(currWrk.Command, wrk.Command) != nil || diff --git a/testing/deployer/topology/compile_test.go b/testing/deployer/topology/compile_test.go index d7da18599f..564906ae96 100644 --- a/testing/deployer/topology/compile_test.go +++ b/testing/deployer/topology/compile_test.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/go-hclog" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/sdk/testutil" ) @@ -143,7 +142,6 @@ func TestCompile_CE(t *testing.T) { Images: DefaultImages().ChooseConsul(false), Nodes: []*Node{{ Kind: NodeKindServer, - Version: NodeVersionV1, Partition: "default", Name: "node1", Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer), @@ -154,7 +152,6 @@ func TestCompile_CE(t *testing.T) { Cluster: "foo2", Datacenter: "foo2", }}, - Services: map[ID]*pbcatalog.Service{}, Partitions: []*Partition{{ Name: "default", Namespaces: []string{"default"}, @@ -285,7 +282,7 @@ func TestCompile_CE(t *testing.T) { Image: "busybox", Port: 8877, EnvoyAdminPort: 19001, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("gaz", "ns3", "ap3"), LocalAddress: "127.0.0.1", LocalPort: 5000, @@ -293,27 +290,6 @@ func TestCompile_CE(t *testing.T) { }, }, }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh2", - Partition: "ap2", - Addresses: []*Address{ - {Network: "foo"}, - }, - Workloads: []*Workload{ - { - ID: NewID("gir", "ns4", "ap2"), - Image: "busybox", - Port: 8877, - EnvoyAdminPort: 19001, - ImpliedDestinations: []*Destination{{ - ID: NewID("gaz", "", "ap4"), - PortName: "www", - }}, - }, - }, - }, }, }}, }, @@ -329,24 +305,10 @@ func TestCompile_CE(t *testing.T) { NetworkName: "foo", Datacenter: "foo", Enterprise: true, - EnableV2: true, Images: DefaultImages().ChooseConsul(true), - Services: map[ID]*pbcatalog.Service{ - NewID("gir", "ns4", "ap2"): { - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"gir-mesh2"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "legacy", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - VirtualIps: []string{"10.244.0.2"}, - }, - }, Nodes: []*Node{ { Kind: NodeKindServer, - Version: NodeVersionV1, Name: "server1", Partition: "default", Images: DefaultImages().ChooseConsul(true).ChooseNode(NodeKindServer), @@ -358,7 +320,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindClient, - Version: NodeVersionV1, Name: "mesh1", Partition: "ap1", Images: DefaultImages().ChooseConsul(true).ChooseNode(NodeKindClient), @@ -374,15 +335,13 @@ func TestCompile_CE(t *testing.T) { Image: "busybox", Port: 8888, EnvoyAdminPort: 19000, - NodeVersion: NodeVersionV1, }, { ID: NewID("gir", "ns2", "ap1"), Image: "busybox", Port: 8877, EnvoyAdminPort: 19001, - NodeVersion: NodeVersionV1, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("gaz", "ns3", "ap3"), Cluster: "foo", LocalAddress: "127.0.0.1", @@ -391,59 +350,16 @@ func TestCompile_CE(t *testing.T) { }, }, }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh2", - Partition: "ap2", - Images: DefaultImages().ChooseConsul(true).ChooseNode(NodeKindDataplane), - Addresses: []*Address{ - {Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID}, - }, - Cluster: "foo", - Datacenter: "foo", - Index: 2, - Workloads: []*Workload{ - { - ID: NewID("gir", "ns4", "ap2"), - Image: "busybox", - Ports: map[string]*Port{ - "legacy": {Number: 8877, Protocol: "tcp", ActualProtocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Number: 20000, Protocol: "mesh", ActualProtocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - EnvoyAdminPort: 19001, - EnvoyPublicListenerPort: 20000, - NodeVersion: NodeVersionV2, - V2Services: []string{"gir"}, - WorkloadIdentity: "gir", - Workload: "gir-mesh2", - ImpliedDestinations: []*Destination{{ - ID: NewID("gaz", "default", "ap4"), - Cluster: "foo", // TODO: why is this only sometimes populated? - PortName: "www", - Implied: true, - }}, - }, - }, - }, }, Partitions: []*Partition{ { Name: "ap1", Namespaces: []string{"default", "ns1", "ns2"}, }, - { - Name: "ap2", - Namespaces: []string{"default", "ns4"}, - }, { Name: "ap3", Namespaces: []string{"default", "ns3"}, }, - { - Name: "ap4", - Namespaces: []string{"default"}, - }, { Name: "default", Namespaces: []string{"default"}, @@ -453,93 +369,6 @@ func TestCompile_CE(t *testing.T) { }, }, }, - "explicit v2 services": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{{ - Kind: NodeKindServer, - Name: "node1", - }}, - Services: map[ID]*pbcatalog.Service{ - NewID("zim", "default", "default"): { - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http"}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - }}, - }, - expect: &Topology{ - ID: clusterID, - Images: DefaultImages(), - Networks: map[string]*Network{ - "foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID}, - }, - Clusters: map[string]*Cluster{ - "foo": { - Name: "foo", - NetworkName: "foo", - Datacenter: "foo", - Images: DefaultImages().ChooseConsul(false), - Nodes: []*Node{{ - Kind: NodeKindServer, - Version: NodeVersionV1, - Partition: "default", - Name: "node1", - Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer), - Addresses: []*Address{ - {Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID}, - }, - Cluster: "foo", - Datacenter: "foo", - }}, - EnableV2: true, - Services: map[ID]*pbcatalog.Service{ - NewID("zim", "default", "default"): { - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - VirtualIps: []string{"10.244.0.2"}, - }, - }, - Partitions: []*Partition{{ - Name: "default", - Namespaces: []string{"default"}, - }}, - }, - }, - }, - }, - "explicit v2 services/bad workload selector": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{{ - Kind: NodeKindServer, - Name: "node1", - }}, - Services: map[ID]*pbcatalog.Service{ - NewID("zim", "default", "default"): { - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"zzz"}}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http"}, - {TargetPort: "mesh"}, - }, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": the workloads field for v2 service "default/default/zim" is not user settable`, - }, "tls volume errantly set": { in: &Config{ Networks: []*Network{ @@ -599,38 +428,6 @@ func TestCompile_CE(t *testing.T) { }, expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has invalid kind`, }, - "node/bad version": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{{ - Kind: NodeKindServer, - Version: "v3", - Name: "zim", - }}, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "zim": cluster "foo" node "zim" has invalid version: v3`, - }, - "node/bad version for client": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{{ - Kind: NodeKindClient, - Version: NodeVersionV2, - Name: "zim", - }}, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "zim": v2 does not support client agents at this time`, - }, "node/invalid partition": { in: &Config{ Networks: []*Network{ @@ -977,41 +774,7 @@ func TestCompile_CE(t *testing.T) { }, expectErr: `error building cluster "foo": error compiling node "mesh1": cannot have two services on the same node "default/mesh1" in the same cluster "foo" with the same name "default/default/zim"`, }, - "workload/v1 and implied dest": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindClient, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - Port: 8080, - EnvoyAdminPort: 19000, - ImpliedDestinations: []*Destination{{ - ID: NewID("gir", "", ""), - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": v1 does not support implied destinations yet`, - }, - "workload/default-destination/impl dest need port names in v2": { + "workload/default-upstream/expl dest local address defaulting": { in: &Config{ Networks: []*Network{ {Name: "foo"}, @@ -1028,7 +791,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindDataplane, - Version: NodeVersionV2, Name: "mesh1", Addresses: []*Address{{Network: "foo"}}, Workloads: []*Workload{{ @@ -1036,158 +798,7 @@ func TestCompile_CE(t *testing.T) { Image: "busybox", Port: 8080, EnvoyAdminPort: 19000, - ImpliedDestinations: []*Destination{{ - ID: NewID("gir", "", ""), - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": implicit destinations must use port names in v2`, - }, - "workload/default-destination/expl dest port name legacy defaulting": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - Port: 8888, - EnvoyAdminPort: 19000, - Destinations: []*Destination{{ - ID: NewID("gir", "", ""), - LocalAddress: "127.0.0.1", - LocalPort: 5000, - }}, - }}, - }, - }, - }}, - }, - expect: &Topology{ - ID: clusterID, - Images: DefaultImages(), - Networks: map[string]*Network{ - "foo": {Name: "foo", Type: "lan", DockerName: "cslc-foo-" + clusterID}, - }, - Clusters: map[string]*Cluster{ - "foo": { - Name: "foo", - NetworkName: "foo", - Datacenter: "foo", - Images: DefaultImages().ChooseConsul(false), - EnableV2: true, - Services: map[ID]*pbcatalog.Service{ - NewID("zim", "default", "default"): { - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"zim-mesh1"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "legacy", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - VirtualIps: []string{"10.244.0.2"}, - }, - }, - Nodes: []*Node{ - { - Kind: NodeKindServer, - Version: NodeVersionV1, - Partition: "default", - Name: "server1", - Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer), - Addresses: []*Address{ - {Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID}, - }, - Cluster: "foo", - Datacenter: "foo", - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Partition: "default", - Name: "mesh1", - Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindDataplane), - Addresses: []*Address{ - {Network: "foo", Type: "lan", DockerNetworkName: "cslc-foo-" + clusterID}, - }, - Cluster: "foo", - Datacenter: "foo", - Index: 1, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - Ports: map[string]*Port{ - "legacy": {Number: 8888, Protocol: "tcp", ActualProtocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Number: 20000, Protocol: "mesh", ActualProtocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - EnvoyAdminPort: 19000, - EnvoyPublicListenerPort: 20000, - NodeVersion: NodeVersionV2, - V2Services: []string{"zim"}, - WorkloadIdentity: "zim", - Workload: "zim-mesh1", - Destinations: []*Destination{{ - ID: NewID("gir", "", ""), - LocalAddress: "127.0.0.1", - LocalPort: 5000, - Cluster: "foo", - PortName: "legacy", // <--- this - }}, - }}, - }, - }, - Partitions: []*Partition{{ - Name: "default", - Namespaces: []string{"default"}, - }}, - }, - }, - }, - }, - "workload/default-destination/expl dest local address defaulting": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV1, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - Port: 8080, - EnvoyAdminPort: 19000, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("gir", "", ""), LocalPort: 5000, }}, @@ -1208,13 +819,9 @@ func TestCompile_CE(t *testing.T) { NetworkName: "foo", Datacenter: "foo", Images: DefaultImages().ChooseConsul(false), - Services: map[ID]*pbcatalog.Service{ - // - }, Nodes: []*Node{ { Kind: NodeKindServer, - Version: NodeVersionV1, Partition: "default", Name: "server1", Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer), @@ -1226,7 +833,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindDataplane, - Version: NodeVersionV1, Partition: "default", Name: "mesh1", Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindDataplane), @@ -1242,8 +848,7 @@ func TestCompile_CE(t *testing.T) { Port: 8080, EnvoyAdminPort: 19000, EnvoyPublicListenerPort: 20000, - NodeVersion: NodeVersionV1, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("gir", "", ""), LocalAddress: "127.0.0.1", // <--- this LocalPort: 5000, @@ -1260,42 +865,6 @@ func TestCompile_CE(t *testing.T) { }, }, }, - "workload/default-destination/expl dest cannot use port names in v1": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV1, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - Port: 8080, - EnvoyAdminPort: 19000, - Destinations: []*Destination{{ - ID: NewID("gir", "", ""), - PortName: "http", - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": explicit destinations cannot use port names in v1`, - }, "workload/validate/no name": { in: &Config{ Networks: []*Network{ @@ -1398,13 +967,9 @@ func TestCompile_CE(t *testing.T) { NetworkName: "foo", Datacenter: "foo", Images: DefaultImages().ChooseConsul(false), - Services: map[ID]*pbcatalog.Service{ - // - }, Nodes: []*Node{ { Kind: NodeKindServer, - Version: NodeVersionV1, Partition: "default", Name: "server1", Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindServer), @@ -1416,7 +981,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindClient, - Version: NodeVersionV1, Partition: "default", Name: "mesh1", Images: DefaultImages().ChooseConsul(false).ChooseNode(NodeKindClient), @@ -1431,7 +995,6 @@ func TestCompile_CE(t *testing.T) { Port: 8080, EnvoyAdminPort: 19000, IsMeshGateway: true, - NodeVersion: NodeVersionV1, }}, }, }, @@ -1443,188 +1006,6 @@ func TestCompile_CE(t *testing.T) { }, }, }, - "workload/validate/single and multiport v2": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Version: NodeVersionV2, - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - Port: 8080, - EnvoyAdminPort: 19000, - Ports: map[string]*Port{ - "blah": { - Number: 8181, - Protocol: "tcp", - }, - }, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot specify both singleport and multiport on service in v2`, - }, - "workload/validate/multiport nil port": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Version: NodeVersionV2, - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Ports: map[string]*Port{ - "blah": nil, - }, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot be nil`, - }, - "workload/validate/multiport negative port": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Version: NodeVersionV2, - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Ports: map[string]*Port{ - "blah": { - Number: -5, - }, - }, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service has invalid port number`, - }, - "workload/validate/multiport set actualprotocol": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Version: NodeVersionV2, - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Ports: map[string]*Port{ - "blah": { - Number: 8888, - ActualProtocol: pbcatalog.Protocol_PROTOCOL_GRPC, - }, - }, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: user cannot specify ActualProtocol field`, - }, - "workload/validate/multiport invalid port protocol": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Version: NodeVersionV2, - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Ports: map[string]*Port{ - "blah": { - Number: 8888, - Protocol: "zzzz", - }, - }, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service has invalid port protocol "zzzz"`, - }, "workload/validate/singleport invalid port": { in: &Config{ Networks: []*Network{ @@ -1656,38 +1037,6 @@ func TestCompile_CE(t *testing.T) { }, expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: service has invalid port`, }, - "workload/validate/singleport tproxy": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Port: 999, - EnableTransparentProxy: true, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: tproxy does not work with v1 yet`, - }, "workload/validate/mesh with no admin port": { in: &Config{ Networks: []*Network{ @@ -1774,7 +1123,7 @@ func TestCompile_CE(t *testing.T) { EnvoyAdminPort: 19000, Image: "busybox", Port: 999, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("", "", ""), }}, }}, @@ -1782,7 +1131,7 @@ func TestCompile_CE(t *testing.T) { }, }}, }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: destination service name is required`, + expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: upstream service name is required`, }, "workload/validate/expl dest with no local port": { in: &Config{ @@ -1808,7 +1157,7 @@ func TestCompile_CE(t *testing.T) { EnvoyAdminPort: 19000, Image: "busybox", Port: 999, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("dib", "", ""), }}, }}, @@ -1816,7 +1165,7 @@ func TestCompile_CE(t *testing.T) { }, }}, }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: destination local port is required`, + expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: upstream local port is required`, }, "workload/validate/expl dest bad local address": { in: &Config{ @@ -1842,7 +1191,7 @@ func TestCompile_CE(t *testing.T) { EnvoyAdminPort: 19000, Image: "busybox", Port: 999, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("dib", "", ""), LocalPort: 5000, LocalAddress: "clown@address", @@ -1852,186 +1201,7 @@ func TestCompile_CE(t *testing.T) { }, }}, }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: destination local address is invalid: clown@address`, - }, - "workload/validate/expl dest with implied": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - EnvoyAdminPort: 19000, - Image: "busybox", - Port: 999, - Destinations: []*Destination{{ - ID: NewID("dib", "", ""), - LocalPort: 5000, - PortName: "http", - Implied: true, - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied field cannot be set`, - }, - "workload/validate/impl dest with no name": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - EnvoyAdminPort: 19000, - Image: "busybox", - Port: 999, - ImpliedDestinations: []*Destination{{ - ID: NewID("", "", ""), - PortName: "http", - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied destination service name is required`, - }, - "workload/validate/impl dest with local port": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - EnvoyAdminPort: 19000, - Image: "busybox", - Port: 999, - ImpliedDestinations: []*Destination{{ - ID: NewID("dib", "", ""), - PortName: "http", - LocalPort: 5000, - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied destination local port cannot be set`, - }, - "workload/validate/impl dest with local address": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - EnvoyAdminPort: 19000, - Image: "busybox", - Port: 999, - ImpliedDestinations: []*Destination{{ - ID: NewID("dib", "", ""), - PortName: "http", - LocalAddress: "127.0.0.1", - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: implied destination local address cannot be set`, - }, - "workload/validate/v1 cannot use multiport": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Ports: map[string]*Port{"web": {Number: 8080}}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot specify multiport on service in v1`, + expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: upstream local address is invalid: clown@address`, }, "workload/validate/disable-mesh/mgw": { in: &Config{ @@ -2083,7 +1253,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindDataplane, - Version: NodeVersionV2, Name: "mesh1", Addresses: []*Address{{Network: "foo"}}, Workloads: []*Workload{{ @@ -2092,7 +1261,7 @@ func TestCompile_CE(t *testing.T) { EnvoyAdminPort: 19000, Port: 8443, DisableServiceMesh: true, - Destinations: []*Destination{{ + Upstreams: []*Upstream{{ ID: NewID("gir", "", ""), }}, }}, @@ -2100,78 +1269,7 @@ func TestCompile_CE(t *testing.T) { }, }}, }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and configure destinations`, - }, - "workload/validate/disable-mesh/impl dest": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Port: 8443, - DisableServiceMesh: true, - ImpliedDestinations: []*Destination{{ - ID: NewID("gir", "", ""), - PortName: "web", - }}, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and configure implied destinations`, - }, - "workload/validate/disable-mesh/tproxy": { - in: &Config{ - Networks: []*Network{ - {Name: "foo"}, - }, - Clusters: []*Cluster{{ - Name: "foo", - Nodes: []*Node{ - { - Kind: NodeKindServer, - Name: "server1", - Addresses: []*Address{ - {Network: "foo"}, - }, - }, - { - Kind: NodeKindDataplane, - Version: NodeVersionV2, - Name: "mesh1", - Addresses: []*Address{{Network: "foo"}}, - Workloads: []*Workload{{ - ID: NewID("zim", "", ""), - Image: "busybox", - EnvoyAdminPort: 19000, - Port: 8443, - DisableServiceMesh: true, - EnableTransparentProxy: true, - }}, - }, - }, - }}, - }, - expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and activate tproxy`, + expectErr: `error building cluster "foo": error compiling node "mesh1": cluster "foo" node "mesh1" service "default/default/zim" is not valid: cannot disable service mesh and configure upstreams`, }, "workload/validate/disable-mesh/set admin port": { in: &Config{ @@ -2190,7 +1288,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindDataplane, - Version: NodeVersionV2, Name: "mesh1", Addresses: []*Address{{Network: "foo"}}, Workloads: []*Workload{{ @@ -2223,7 +1320,6 @@ func TestCompile_CE(t *testing.T) { }, { Kind: NodeKindDataplane, - Version: NodeVersionV2, Name: "mesh1", Addresses: []*Address{{Network: "foo"}}, Workloads: []*Workload{{ diff --git a/testing/deployer/topology/naming_shim.go b/testing/deployer/topology/naming_shim.go index 7cc51c19d8..e307b3b6e2 100644 --- a/testing/deployer/topology/naming_shim.go +++ b/testing/deployer/topology/naming_shim.go @@ -39,5 +39,5 @@ func NewServiceID(name, namespace, partition string) ID { return NewID(name, namespace, partition) } -// Deprecated: Destination -type Upstream = Destination +// Deprecated: +type Destination = Upstream diff --git a/testing/deployer/topology/relationships.go b/testing/deployer/topology/relationships.go index 212841de3c..b5fdc0b1f6 100644 --- a/testing/deployer/topology/relationships.go +++ b/testing/deployer/topology/relationships.go @@ -10,24 +10,16 @@ import ( ) // ComputeRelationships will analyze a full topology and generate all of the -// caller/destination information for all of them. +// caller/upstream information for all of them. func (t *Topology) ComputeRelationships() []Relationship { var out []Relationship for _, cluster := range t.Clusters { for _, n := range cluster.Nodes { for _, w := range n.Workloads { - for _, dest := range w.Destinations { + for _, us := range w.Upstreams { out = append(out, Relationship{ - Caller: w, - Destination: dest, - Upstream: dest, - }) - } - for _, dest := range w.ImpliedDestinations { - out = append(out, Relationship{ - Caller: w, - Destination: dest, - Upstream: dest, + Caller: w, + Upstream: us, }) } } @@ -43,18 +35,14 @@ func RenderRelationships(ships []Relationship) string { w := tabwriter.NewWriter(&buf, 0, 0, 3, ' ', tabwriter.Debug) fmt.Fprintf(w, "CALLER\tnode\tservice\tport\tDEST\tservice\t\n") for _, r := range ships { - suffix := "" - if r.Destination.Implied { - suffix = " (implied)" - } fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%s\t\n", r.callingCluster(), r.Caller.Node.ID().String(), r.Caller.ID.String(), - r.Destination.LocalPort, - r.destinationCluster(), - r.Destination.ID.String()+suffix, + r.Upstream.LocalPort, + r.upstreamCluster(), + r.Upstream.ID.String(), ) } fmt.Fprintf(w, "\t\t\t\t\t\t\n") @@ -64,27 +52,19 @@ func RenderRelationships(ships []Relationship) string { } type Relationship struct { - Caller *Workload - Destination *Destination - - // Deprecated: Destination - Upstream *Destination + Caller *Workload + Upstream *Upstream } func (r Relationship) String() string { - suffix := "" - if r.Destination.PortName != "" { - suffix = " port " + r.Destination.PortName - } return fmt.Sprintf( - "%s on %s in %s via :%d => %s in %s%s", + "%s on %s in %s via :%d => %s in %s", r.Caller.ID.String(), r.Caller.Node.ID().String(), r.callingCluster(), - r.Destination.LocalPort, - r.Destination.ID.String(), - r.destinationCluster(), - suffix, + r.Upstream.LocalPort, + r.Upstream.ID.String(), + r.upstreamCluster(), ) } @@ -92,6 +72,6 @@ func (r Relationship) callingCluster() string { return r.Caller.Node.Cluster } -func (r Relationship) destinationCluster() string { - return r.Destination.Cluster +func (r Relationship) upstreamCluster() string { + return r.Upstream.Cluster } diff --git a/testing/deployer/topology/topology.go b/testing/deployer/topology/topology.go index a45b27678d..a2feefca4b 100644 --- a/testing/deployer/topology/topology.go +++ b/testing/deployer/topology/topology.go @@ -10,17 +10,11 @@ import ( "net/netip" "reflect" "sort" - "strings" "github.com/hashicorp/consul/api" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) -const ( - V1DefaultPortName = "legacy" -) - type Topology struct { ID string @@ -252,14 +246,6 @@ type Cluster struct { // components. Enterprise bool `json:",omitempty"` - // Services is a forward declaration of V2 services. This goes in hand with - // the V2Services field on the Service (instance) struct. - // - // Use of this is optional. If you elect not to use it, then v2 Services - // definitions are inferred from the list of service instances defined on - // the nodes in this cluster. - Services map[ID]*pbcatalog.Service `json:"omitempty"` - // Nodes is the definition of the nodes (agent-less and agent-ful). Nodes []*Node @@ -295,14 +281,6 @@ type Cluster struct { // Denormalized during compile. Peerings map[string]*PeerCluster `json:",omitempty"` - // EnableV2 activates V2 on the servers. If any node in the cluster needs - // V2 this will be turned on automatically. - EnableV2 bool `json:",omitempty"` - - // EnableV2Tenancy activates V2 tenancy on the servers. If not enabled, - // V2 resources are bridged to V1 tenancy counterparts. - EnableV2Tenancy bool `json:",omitempty"` - // Segments is a map of network segment name and the ports Segments map[string]int @@ -505,14 +483,6 @@ const ( NodeKindDataplane NodeKind = "dataplane" ) -type NodeVersion string - -const ( - NodeVersionUnknown NodeVersion = "" - NodeVersionV1 NodeVersion = "v1" - NodeVersionV2 NodeVersion = "v2" -) - type NetworkSegment struct { Name string Port int @@ -521,7 +491,6 @@ type NetworkSegment struct { // TODO: rename pod type Node struct { Kind NodeKind - Version NodeVersion Partition string // will be not empty Name string // logical name @@ -534,8 +503,6 @@ type Node struct { Addresses []*Address Workloads []*Workload - // Deprecated: use Workloads - Services []*Workload // denormalized at topology compile Cluster string @@ -685,14 +652,6 @@ func (n *Node) PublicProxyPort() int { panic("node has no public network") } -func (n *Node) IsV2() bool { - return n.Version == NodeVersionV2 -} - -func (n *Node) IsV1() bool { - return !n.IsV2() -} - func (n *Node) IsServer() bool { return n.Kind == NodeKindServer } @@ -725,15 +684,6 @@ func (n *Node) SortedWorkloads() []*Workload { return out } -func (n *Node) NeedsTransparentProxy() bool { - for _, svc := range n.Workloads { - if svc.EnableTransparentProxy { - return true - } - } - return false -} - // DigestExposedPorts returns true if it was changed. func (n *Node) DigestExposedPorts(ports map[int]int) bool { if reflect.DeepEqual(n.usedPorts, ports) { @@ -768,63 +718,12 @@ func (n *Node) WorkloadByID(id ID) *Workload { panic("workload not found: " + id.String()) } -// Protocol is a convenience function to use when authoring topology configs. -func Protocol(s string) (pbcatalog.Protocol, bool) { - switch strings.ToLower(s) { - case "tcp": - return pbcatalog.Protocol_PROTOCOL_TCP, true - case "http": - return pbcatalog.Protocol_PROTOCOL_HTTP, true - case "http2": - return pbcatalog.Protocol_PROTOCOL_HTTP2, true - case "grpc": - return pbcatalog.Protocol_PROTOCOL_GRPC, true - case "mesh": - return pbcatalog.Protocol_PROTOCOL_MESH, true - default: - return pbcatalog.Protocol_PROTOCOL_UNSPECIFIED, false - } -} - -type Port struct { - Number int - Protocol string `json:",omitempty"` - - // denormalized at topology compile - ActualProtocol pbcatalog.Protocol `json:",omitempty"` -} - type Workload struct { ID ID Image string - // Port is the v1 single-port of this service. Port int `json:",omitempty"` - // Ports is the v2 multi-port list for this service. - // - // This only applies for multi-port (v2). - Ports map[string]*Port `json:",omitempty"` - - // V2Services contains service names (which are merged with the tenancy - // info from ID) to resolve services in the Services slice in the Cluster - // definition. - // - // If omitted it is inferred that the ID.Name field is the singular service - // for this workload. - // - // This only applies for multi-port (v2). - V2Services []string `json:",omitempty"` - - // WorkloadIdentity contains named WorkloadIdentity to assign to this - // workload. - // - // If omitted it is inferred that the ID.Name field is the singular - // identity for this workload. - // - // This only applies for multi-port (v2). - WorkloadIdentity string `json:",omitempty"` - Disabled bool `json:",omitempty"` // TODO // TODO: expose extra port here? @@ -842,55 +741,19 @@ type Workload struct { Command []string `json:",omitempty"` // optional Env []string `json:",omitempty"` // optional - EnableTransparentProxy bool `json:",omitempty"` - DisableServiceMesh bool `json:",omitempty"` - IsMeshGateway bool `json:",omitempty"` - Destinations []*Destination `json:",omitempty"` - ImpliedDestinations []*Destination `json:",omitempty"` - - // Deprecated: Destinations - Upstreams []*Destination `json:",omitempty"` - // Deprecated: ImpliedDestinations - ImpliedUpstreams []*Destination `json:",omitempty"` + DisableServiceMesh bool `json:",omitempty"` + IsMeshGateway bool `json:",omitempty"` + Upstreams []*Upstream `json:",omitempty"` // denormalized at topology compile - Node *Node `json:"-"` - NodeVersion NodeVersion `json:"-"` - Workload string `json:"-"` + Node *Node `json:"-"` } -func (w *Workload) ExposedPort(name string) int { +func (w *Workload) ExposedPort() int { if w.Node == nil { panic("ExposedPort cannot be called until after Compile") } - - var internalPort int - if name == "" { - internalPort = w.Port - } else { - port, ok := w.Ports[name] - if !ok { - panic("port with name " + name + " not present on service") - } - internalPort = port.Number - } - - return w.Node.ExposedPort(internalPort) -} - -func (w *Workload) PortOrDefault(name string) int { - if len(w.Ports) > 0 { - return w.Ports[name].Number - } - return w.Port -} - -func (w *Workload) IsV2() bool { - return w.NodeVersion == NodeVersionV2 -} - -func (w *Workload) IsV1() bool { - return !w.IsV2() + return w.Node.ExposedPort(w.Port) } func (w *Workload) inheritFromExisting(existing *Workload) { @@ -899,19 +762,7 @@ func (w *Workload) inheritFromExisting(existing *Workload) { func (w *Workload) ports() []int { var out []int - if len(w.Ports) > 0 { - seen := make(map[int]struct{}) - for _, port := range w.Ports { - if port == nil { - continue - } - if _, ok := seen[port.Number]; !ok { - // It's totally fine to expose the same port twice in a workload. - seen[port.Number] = struct{}{} - out = append(out, port.Number) - } - } - } else if w.Port > 0 { + if w.Port > 0 { out = append(out, w.Port) } if w.EnvoyAdminPort > 0 { @@ -920,9 +771,9 @@ func (w *Workload) ports() []int { if w.EnvoyPublicListenerPort > 0 { out = append(out, w.EnvoyPublicListenerPort) } - for _, dest := range w.Destinations { - if dest.LocalPort > 0 { - out = append(out, dest.LocalPort) + for _, us := range w.Upstreams { + if us.LocalPort > 0 { + out = append(out, us.LocalPort) } } return out @@ -950,78 +801,14 @@ func (w *Workload) Validate() error { return fmt.Errorf("service image is required") } - if len(w.Upstreams) > 0 { - w.Destinations = append(w.Destinations, w.Upstreams...) - w.Upstreams = nil - } - if len(w.ImpliedUpstreams) > 0 { - w.ImpliedDestinations = append(w.ImpliedDestinations, w.ImpliedUpstreams...) - w.ImpliedUpstreams = nil - } - - if w.IsV2() { - if len(w.Ports) > 0 && w.Port > 0 { - return fmt.Errorf("cannot specify both singleport and multiport on service in v2") - } - if w.Port > 0 { - w.Ports = map[string]*Port{ - V1DefaultPortName: { - Number: w.Port, - Protocol: "tcp", - }, - } - w.Port = 0 - } - if w.Ports == nil { - w.Ports = make(map[string]*Port) - } - - if !w.DisableServiceMesh && w.EnvoyPublicListenerPort > 0 { - w.Ports["mesh"] = &Port{ - Number: w.EnvoyPublicListenerPort, - Protocol: "mesh", - } - } - - for name, port := range w.Ports { - if port == nil { - return fmt.Errorf("cannot be nil") - } - if port.Number <= 0 { - return fmt.Errorf("service has invalid port number %q", name) - } - if port.ActualProtocol != pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - return fmt.Errorf("user cannot specify ActualProtocol field") - } - - proto, valid := Protocol(port.Protocol) - if !valid { - return fmt.Errorf("service has invalid port protocol %q", port.Protocol) - } - port.ActualProtocol = proto - } - } else { - if len(w.Ports) > 0 { - return fmt.Errorf("cannot specify multiport on service in v1") - } - if w.Port <= 0 { - return fmt.Errorf("service has invalid port") - } - if w.EnableTransparentProxy { - return fmt.Errorf("tproxy does not work with v1 yet") - } + if w.Port <= 0 { + return fmt.Errorf("service has invalid port") } if w.DisableServiceMesh && w.IsMeshGateway { return fmt.Errorf("cannot disable service mesh and still run a mesh gateway") } - if w.DisableServiceMesh && len(w.Destinations) > 0 { - return fmt.Errorf("cannot disable service mesh and configure destinations") - } - if w.DisableServiceMesh && len(w.ImpliedDestinations) > 0 { - return fmt.Errorf("cannot disable service mesh and configure implied destinations") - } - if w.DisableServiceMesh && w.EnableTransparentProxy { - return fmt.Errorf("cannot disable service mesh and activate tproxy") + if w.DisableServiceMesh && len(w.Upstreams) > 0 { + return fmt.Errorf("cannot disable service mesh and configure upstreams") } if w.DisableServiceMesh { @@ -1034,59 +821,36 @@ func (w *Workload) Validate() error { } } - for _, dest := range w.Destinations { - if dest.ID.Name == "" { - return fmt.Errorf("destination service name is required") + for _, us := range w.Upstreams { + if us.ID.Name == "" { + return fmt.Errorf("upstream service name is required") } - if dest.LocalPort <= 0 { - return fmt.Errorf("destination local port is required") + if us.LocalPort <= 0 { + return fmt.Errorf("upstream local port is required") } - if dest.LocalAddress != "" { - ip := net.ParseIP(dest.LocalAddress) + if us.LocalAddress != "" { + ip := net.ParseIP(us.LocalAddress) if ip == nil { - return fmt.Errorf("destination local address is invalid: %s", dest.LocalAddress) + return fmt.Errorf("upstream local address is invalid: %s", us.LocalAddress) } } - if dest.Implied { - return fmt.Errorf("implied field cannot be set") - } - } - for _, dest := range w.ImpliedDestinations { - if dest.ID.Name == "" { - return fmt.Errorf("implied destination service name is required") - } - if dest.LocalPort > 0 { - return fmt.Errorf("implied destination local port cannot be set") - } - if dest.LocalAddress != "" { - return fmt.Errorf("implied destination local address cannot be set") - } } return nil } -type Destination struct { +type Upstream struct { ID ID LocalAddress string `json:",omitempty"` // defaults to 127.0.0.1 LocalPort int Peer string `json:",omitempty"` - // PortName is the port of this Destination to route traffic to. - // - // For more details on potential values of this field, see documentation - // for Service.ServicePort. - // - // This only applies for multi-port (v2). - PortName 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 - Implied bool `json:",omitempty"` - VirtualPort uint32 `json:",omitempty"` + Cluster string `json:",omitempty"` + Peering *PeerCluster `json:",omitempty"` // this will have Link!=nil } type Peering struct { From d5e92da8affc2df16ffd3c46925f76b89332e287 Mon Sep 17 00:00:00 2001 From: NicoletaPopoviciu <87660255+NicoletaPopoviciu@users.noreply.github.com> Date: Wed, 22 May 2024 14:43:04 -0400 Subject: [PATCH 040/185] Update Vault/Nomad versions. (#21193) * Update Vault/Nomad versions. * Update test-integrations.yml amend vault versions * add nomad binary path to GITHUB_PATH --------- Co-authored-by: Dhia Ayachi --- .github/workflows/test-integrations.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 1c9fbcb0ca..3fc4031439 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -27,7 +27,7 @@ env: SKIP_CHECK_BRANCH: ${{ github.head_ref || github.ref_name }} concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + group: "${{ github.workflow }}-${{ github.head_ref || github.ref }}" cancel-in-progress: true jobs: @@ -86,7 +86,7 @@ jobs: contents: read strategy: matrix: - nomad-version: ['v1.7.3', 'v1.6.6', 'v1.5.13'] + nomad-version: ['v1.7.7', 'v1.6.10', 'v1.5.17'] steps: - name: Checkout Nomad uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 @@ -111,7 +111,9 @@ jobs: echo "$(pwd)/bin" >> $GITHUB_PATH - name: Make Nomad dev build - run: make pkg/linux_amd64/nomad + run: | + make pkg/linux_amd64/nomad + echo "$(pwd)/pkg/linux_amd64" >> $GITHUB_PATH - name: Run integration tests run: | @@ -167,7 +169,7 @@ jobs: contents: read strategy: matrix: - vault-version: ["1.15.4", "1.14.8", "1.13.12"] + vault-version: ["1.16.2", "1.15.6", "1.14.10"] env: VAULT_BINARY_VERSION: ${{ matrix.vault-version }} steps: From b2a618ba8a5fe67e49716618cc3d6402bb90a02a Mon Sep 17 00:00:00 2001 From: Ranjandas Date: Thu, 23 May 2024 07:27:26 +1000 Subject: [PATCH 041/185] Fixes annotation and introduce tabs for static-client spec (#21199) The upstream annotation is not required for external services defined using the ServiceDefaults Destinations. --- .../docs/k8s/connect/terminating-gateways.mdx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/website/content/docs/k8s/connect/terminating-gateways.mdx b/website/content/docs/k8s/connect/terminating-gateways.mdx index 319fedf71d..3ed8f71e5c 100644 --- a/website/content/docs/k8s/connect/terminating-gateways.mdx +++ b/website/content/docs/k8s/connect/terminating-gateways.mdx @@ -317,6 +317,57 @@ $ kubectl apply --filename service-intentions.yaml As a final step, you may define and deploy the external services as upstreams for the internal mesh services that wish to talk to them. An example deployment is provided which will serve as a static client for the terminating gateway service. + + + + + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: static-client +spec: + selector: + app: static-client + ports: + - port: 80 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: static-client +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + replicas: 1 + selector: + matchLabels: + app: static-client + template: + metadata: + name: static-client + labels: + app: static-client + annotations: + 'consul.hashicorp.com/connect-inject': 'true' + spec: + containers: + - name: static-client + image: curlimages/curl:latest + command: ['/bin/sh', '-c', '--'] + args: ['while true; do sleep 30; done;'] + serviceAccountName: static-client +``` + + + + + + ```yaml @@ -363,6 +414,9 @@ spec: + + + Deploy the service with `kubectl apply`. ```shell-session From 6f02144a140a9d687c5cb4340c5cec022bc33bbc Mon Sep 17 00:00:00 2001 From: Blake Covarrubias Date: Wed, 22 May 2024 15:36:57 -0700 Subject: [PATCH 042/185] docs: Fix spelling errors (#21204) Fix spelling errors across docs site. --- website/content/api-docs/hcp-link.mdx | 2 +- website/content/docs/agent/config-entries.mdx | 2 +- .../content/docs/agent/monitor/components.mdx | 12 ++-- .../content/docs/architecture/v2/catalog.mdx | 2 +- .../content/docs/architecture/v2/index.mdx | 4 +- .../connect/config-entries/proxy-defaults.mdx | 2 +- .../content/docs/connect/dataplane/index.mdx | 2 +- .../configuration/gatewayclassconfig.mdx | 2 +- .../configuration/gatewaypolicy.mdx | 60 +++++++++---------- .../api-gateway/configuration/routes.mdx | 6 +- .../api-gateway/define-routes/routes-k8s.mdx | 14 ++--- .../secure-traffic/verify-jwts-k8s.mdx | 4 +- .../gateways/api-gateway/tech-specs.mdx | 26 ++++---- .../manage-traffic/failover/sameness.mdx | 22 +++---- .../route-to-local-upstreams.mdx | 38 ++++++------ .../proxies/deploy-service-mesh-proxies.mdx | 22 +++---- .../proxies/deploy-sidecar-services.mdx | 40 ++++++------- website/content/docs/ecs/deploy/manual.mdx | 36 +++++------ .../ecs/deploy/migrate-existing-tasks.mdx | 10 ++-- website/content/docs/ecs/deploy/terraform.mdx | 38 ++++++------ .../docs/ecs/reference/consul-server-json.mdx | 34 +++++------ website/content/docs/install/ports.mdx | 2 +- .../k8s/deployment-configurations/datadog.mdx | 2 +- .../k8s/multiport/reference/grpcroute.mdx | 26 ++++---- .../k8s/multiport/reference/httproute.mdx | 32 +++++----- .../docs/k8s/multiport/reference/tcproute.mdx | 20 +++---- .../docs/release-notes/consul/v1_18_x.mdx | 6 +- .../content/docs/security/acl/acl-roles.mdx | 6 +- .../content/docs/security/acl/acl-rules.mdx | 4 +- 29 files changed, 238 insertions(+), 238 deletions(-) diff --git a/website/content/api-docs/hcp-link.mdx b/website/content/api-docs/hcp-link.mdx index 5b1cdfac73..7f54306691 100644 --- a/website/content/api-docs/hcp-link.mdx +++ b/website/content/api-docs/hcp-link.mdx @@ -32,7 +32,7 @@ The table below shows this endpoint's support for ### Link API vs. configuration-based linking -The Link API described here is an alternative method to accomplish the same thing as [configuration-based linking](/consul/docs/agent/config/config-files#self-managed-hcp-parameters). You should generally only choose one method or the other for linking your cluster, not both. If you do use both methods, they interract in the following ways: +The Link API described here is an alternative method to accomplish the same thing as [configuration-based linking](/consul/docs/agent/config/config-files#self-managed-hcp-parameters). You should generally only choose one method or the other for linking your cluster, not both. If you do use both methods, they interact in the following ways: * When Consul is started, values set in the `cloud` configuration will take precedence over what was previously set by the API or CLI. * Clusters can only be unlinked from HCP Consul Central by the API or CLI, regardless of if they were established via configuration, API, or CLI. diff --git a/website/content/docs/agent/config-entries.mdx b/website/content/docs/agent/config-entries.mdx index f4b7f97f14..9eb3f82f7f 100644 --- a/website/content/docs/agent/config-entries.mdx +++ b/website/content/docs/agent/config-entries.mdx @@ -56,7 +56,7 @@ See [Kubernetes Custom Resource Definitions](/consul/docs/k8s/crds). Configuration entries outside of Kubernetes should be managed with the Consul [CLI](/consul/commands/config) or [API](/consul/api-docs/config). Additionally, as a convenience for initial cluster bootstrapping, configuration entries can be -specified in all of the Consul servers's +specified in all of the Consul server [configuration files](/consul/docs/agent/config/config-files#config_entries_bootstrap) ### Managing Configuration Entries with the CLI diff --git a/website/content/docs/agent/monitor/components.mdx b/website/content/docs/agent/monitor/components.mdx index 958b62260b..1c3d49270e 100644 --- a/website/content/docs/agent/monitor/components.mdx +++ b/website/content/docs/agent/monitor/components.mdx @@ -11,9 +11,9 @@ This document will guide you recommendations for monitoring your Consul control ## Background -A Consul datacenter is the smallest unit of Consul infrastructure that can perform basic Consul operations like service discovery or service mesh. A datacenter contains at least one Consul server agent, but a real-world deployment contains three or five server agents and several Consul client agents. +A Consul datacenter is the smallest unit of Consul infrastructure that can perform basic Consul operations like service discovery or service mesh. A datacenter contains at least one Consul server agent, but a real-world deployment contains three or five server agents and several Consul client agents. -The Consul control plane consists of server agents that store all state information, including service and node IP addresses, health checks, and configuration. In addition, the control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. In addition, the control plane contains client agents that report node and service health status to the Consul cluster. In a typical deployment, you must run client agents on every compute node in your datacenter. +The Consul control plane consists of server agents that store all state information, including service and node IP addresses, health checks, and configuration. In addition, the control plane is responsible for securing the mesh, facilitating service discovery, health checking, policy enforcement, and other similar operational concerns. In addition, the control plane contains client agents that report node and service health status to the Consul cluster. In a typical deployment, you must run client agents on every compute node in your datacenter. The Consul data plane consists of proxies deployed locally alongside each service instance. These proxies, called sidecar proxies, receive mesh configuration data from the control plane, and control network communication between their local service instance and other services in the network. The sidecar proxy handles inbound and outbound service connections, and ensures TLS connections between services are both verified and encrypted. @@ -44,13 +44,13 @@ It is important to have a highly performant network with low network latency. En ### Raft recommendations Consul uses [Raft for consensus protocol](/consul/docs/architecture/consensus). High saturation of the Raft goroutines can lead to elevated latency in the rest of the system and may cause the Consul cluster to be unstable. As a result, it is important to monitor Raft to track your control plane health. We recommend the following actions to keep control plane healthy: -- Create an alert that notifies you when [Raft thread saturation](/consul/docs/agent/telemetry#raft-thread-saturation) exceeds 50%. +- Create an alert that notifies you when [Raft thread saturation](/consul/docs/agent/telemetry#raft-thread-saturation) exceeds 50%. - Monitor [Raft replication capacity](/consul/docs/agent/telemetry#raft-replication-capacity-issues) when Consul is handling large amounts of data and high write throughput. - Lower [`raft_multiplier`](/consul/docs/install/performance#production) to keep your Consul cluster stable. The value of `raft_multiplier` defines the scaling factor for Consul. Default value for raft_multiplier is 5. A short multiplier minimizes failure detection and election time but may trigger frequently in high latency situations. This can cause constant leadership churn and associated unavailability. A high multiplier reduces the chances that spurious failures will cause leadership churn but it does this at the expense of taking longer to detect real failures and thus takes longer to restore Consul cluster availability. - Wide networks with higher latency will perform better with larger `raft_multipler` values. + Wide networks with higher latency will perform better with larger `raft_multiplier` values. Raft uses BoltDB for storing data and maintaining its own state. Refer to the [Bolt DB performance metrics](/consul/docs/agent/telemetry#bolt-db-performance) when you are troubleshooting Raft performance issues. @@ -77,7 +77,7 @@ annotations: consul.hashicorp.com/envoy-extra-args: '--log-level debug --disable-hot-restart' ``` -Refer to the [Enable logging on Envoy sidecar pods](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-envoy-extra-args) documention for more information. +Refer to the [Enable logging on Envoy sidecar pods](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-envoy-extra-args) documentation for more information. #### Envoy Admin Interface @@ -87,7 +87,7 @@ All endpoints exposed by Envoy are available at the node running Envoy on port ` The following Envoy admin interface endpoints are particularly useful: -- The `listeners` endpoint lists all listeners running on `localhost`. This allows you to confirm whether the upstream services are binding correctly to Envoy. +- The `listeners` endpoint lists all listeners running on `localhost`. This allows you to confirm whether the upstream services are binding correctly to Envoy. ```shell-session $ curl http://localhost:19000/listeners diff --git a/website/content/docs/architecture/v2/catalog.mdx b/website/content/docs/architecture/v2/catalog.mdx index aee72d0093..2b31bbcbf6 100644 --- a/website/content/docs/architecture/v2/catalog.mdx +++ b/website/content/docs/architecture/v2/catalog.mdx @@ -41,7 +41,7 @@ The v2 catalog API is available alongside the existing v1 catalog API, but the c ## Catalog structure -Consul v1.17 introduces a new version of the catalog API designed to bridge differences between the Consul and Kubernetes data models. The v2 catalog API continues to track services and nodes for Consul, but it replaces service instances with _workloads_ and _workload identites_. +Consul v1.17 introduces a new version of the catalog API designed to bridge differences between the Consul and Kubernetes data models. The v2 catalog API continues to track services and nodes for Consul, but it replaces service instances with _workloads_ and _workload identities_. ### Catalog resources diff --git a/website/content/docs/architecture/v2/index.mdx b/website/content/docs/architecture/v2/index.mdx index 8301f370e4..03afb71aa2 100644 --- a/website/content/docs/architecture/v2/index.mdx +++ b/website/content/docs/architecture/v2/index.mdx @@ -1,7 +1,7 @@ --- layout: docs page_title: Consul v2 architecture -description: Learn about version 2 of Consul's internal architecture, which replaces services and service instances with workloads and workload identies. +description: Learn about version 2 of Consul's internal architecture, which replaces services and service instances with workloads and workload identities. --- @@ -12,7 +12,7 @@ The v2 catalog API and Traffic Permissions API are currently in beta. This docum # Consul v2 architecture -This topic provides an overview of Consul's v2 architecture changes and their impact on Consul operations. +This topic provides an overview of Consul's v2 architecture changes and their impact on Consul operations. In the v1.17.0 release, Consul introduced the option to enable the [v2 catalog API](/consul/docs/architecture/v2/catalog) for testing and development on Kubernetes deployments. The v2 catalog is one of several changes in development to simplify and streamline Consul's architecture. diff --git a/website/content/docs/connect/config-entries/proxy-defaults.mdx b/website/content/docs/connect/config-entries/proxy-defaults.mdx index 90ffb4eaa4..824ce83599 100644 --- a/website/content/docs/connect/config-entries/proxy-defaults.mdx +++ b/website/content/docs/connect/config-entries/proxy-defaults.mdx @@ -659,7 +659,7 @@ Example use-cases include exposing the `/metrics` endpoint to a monitoring syste - Default: None - Data type: Map containing the following parameters: - [`checks`](#expose-checks) - - [`aths`](#expose-paths) + - [`paths`](#expose-paths) ### `spec.expose{}.checks` diff --git a/website/content/docs/connect/dataplane/index.mdx b/website/content/docs/connect/dataplane/index.mdx index 52230cccba..30996e3476 100644 --- a/website/content/docs/connect/dataplane/index.mdx +++ b/website/content/docs/connect/dataplane/index.mdx @@ -87,7 +87,7 @@ $ export VERSION=1.0.0 && \ Refer to the following documentation for Consul on ECS workloads: - [Deploy Consul with the Terraform module](/consul/docs/ecs/deploy/terraform) -- [Deploy Consul manually](/consul/ecs/install-manul) +- [Deploy Consul manually](/consul/docs/ecs/deploy/manual) diff --git a/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx b/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx index 816550a786..612875db4f 100644 --- a/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx +++ b/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx @@ -155,7 +155,7 @@ You can specify the following strings: * `trace` ### mapPrivilegedContainerPorts -Specifies a value that Consul adds to privileged ports defined in the gateway. Privileged ports are port numbers less than 1024 and some platforms, such as Red Hat OpenShift, explicitly configure Kubernetes to avoid running containers on privileged ports. The total value of the configured port number and the `mapPriviledgedContainerPorts` value must not exceed 65535, which is the highest possible TCP port number allowed. +Specifies a value that Consul adds to privileged ports defined in the gateway. Privileged ports are port numbers less than 1024 and some platforms, such as Red Hat OpenShift, explicitly configure Kubernetes to avoid running containers on privileged ports. The total value of the configured port number and the `mapPrivilegedContainerPorts` value must not exceed 65535, which is the highest possible TCP port number allowed. for gateway containers * Type: Integer * Required: optional diff --git a/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx b/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx index dc638fbf72..1e0111a323 100644 --- a/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx +++ b/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx @@ -1,7 +1,7 @@ --- layout: docs page_title: GatewayPolicy configuration reference -description: Learn about the configuration options for the GatewayPolicy configuration resource. GatewayPolicy resources define API gateway polcies for Consul service mesh on Kubernetes. +description: Learn about the configuration options for the GatewayPolicy configuration resource. GatewayPolicy resources define API gateway policies for Consul service mesh on Kubernetes. --- # GatewayPolicy @@ -15,33 +15,33 @@ The following list outlines field hierarchy, data types, and requirements in a g - [`apiVersion`](#apiversion): string | required | must be set to `consul.hashicorp.com/v1alpha1` - [`kind`](#kind): string | required | must be set to `GatewayPolicy` - [`metadata`](#metadata): map | required - - [`name`](#metadata-name): string | required + - [`name`](#metadata-name): string | required - [`namespace`](#metadata-namespace): string | `default` - [`spec`](#spec): map | required - [`targetRef`](#spec-targetref): map | required - - [`namespace`](#spec-targetref): string | `default` - - [`name`](#spec-targetref): string | required + - [`namespace`](#spec-targetref): string | `default` + - [`name`](#spec-targetref): string | required - [`kind`](#spec-targetref): string | required | must be set to `Gateway` - - [`group`](#spec-targetref): string | required - - [`sectionName`](#spec-targetref): string - - [`override`](#spec-override): map | required - - [`jwt`](#spec-override-jwt): map | required - - [`providers`](#spec-override-providers): list | required - - [`name`](#spec-override-providers): string | required - - [`verifyClaims`](#spec-override-providers): map | required - - [`path`](#spec-override-providers): list of strings | required - - [`value`](#spec-override-providers): string | required - - [`default`](#spec-default): map | required - - [`jwt`](#spec-default-jwt): map | required - - [`providers`](#spec-default-providers): list | required - - [`name`](#spec-default-providers): string | required - - [`verifyClaims`](#spec-default-providers): map | required - - [`path`](#spec-default-providers): list of strings | required - - [`value`](#spec-default-providers): string | required + - [`group`](#spec-targetref): string | required + - [`sectionName`](#spec-targetref): string + - [`override`](#spec-override): map | required + - [`jwt`](#spec-override-jwt): map | required + - [`providers`](#spec-override-providers): list | required + - [`name`](#spec-override-providers): string | required + - [`verifyClaims`](#spec-override-providers): map | required + - [`path`](#spec-override-providers): list of strings | required + - [`value`](#spec-override-providers): string | required + - [`default`](#spec-default): map | required + - [`jwt`](#spec-default-jwt): map | required + - [`providers`](#spec-default-providers): list | required + - [`name`](#spec-default-providers): string | required + - [`verifyClaims`](#spec-default-providers): map | required + - [`path`](#spec-default-providers): list of strings | required + - [`value`](#spec-default-providers): string | required ## Complete configuration -When every field is defined, a gateway policy has the following form: +When every field is defined, a gateway policy has the following form: ```yaml apiVersion: consul.hashicorp.com/v1alpha1 @@ -53,7 +53,7 @@ spec: targetRef: name: gateway kind: Gateway - group: gateway.networking.kuberenetes.io + group: gateway.networking.kubernetes.io sectionName: override: jwt: @@ -109,7 +109,7 @@ Map that contains an arbitrary name for the resource and the namespace it applie ### `metadata.name` -Specifies a name for the resource. The name is metadata that you can use to reference the resource when performing Consul operations, such as applying the resource to a specific cluster. +Specifies a name for the resource. The name is metadata that you can use to reference the resource when performing Consul operations, such as applying the resource to a specific cluster. #### Values @@ -117,7 +117,7 @@ Specifies a name for the resource. The name is metadata that you can use to refe - This field is required. - Data type: String -### `metadata.namespace` +### `metadata.namespace` Specifies the namespace that the configuration applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information. @@ -138,7 +138,7 @@ Map that contains the details about the gateway policy. The `apiVersion`, `kind` ### `targetRef` -Map that contains references to the gateway that the policy applies to. +Map that contains references to the gateway that the policy applies to. #### Values @@ -153,7 +153,7 @@ The following table describes the members of the `targetRef` map: | `namespace` | Specifies the namespace that the target reference is a member of. | String | `default` | | `name` | Specifies the name of the API gateway that the policy attaches to. | String | None | | `kind` | Specifies the type of resource that the policy attaches to. Must be set to `Gateway`. | String | None | -| `group` | Specifies the resource group. Must be set to `gateway.networking.kuberenetes.io`. | String | None | +| `group` | Specifies the resource group. Must be set to `gateway.networking.kubernetes.io`. | String | None | | `sectionName` | Specifies a part of the gateway that the policy applies to. | String | None | ### `spec.override` @@ -192,7 +192,7 @@ The following table describes the parameters you can specify in a member of the ### `spec.default` -Map that contains default configurations to apply to listeners when the policy is attached to the gateway. All routes attached to the gateway listener inherit the default configurations. You can specify override configurations that have precedence over default configurations. Refer to [`spec.override`](#spec-override) for details. +Map that contains default configurations to apply to listeners when the policy is attached to the gateway. All routes attached to the gateway listener inherit the default configurations. You can specify override configurations that have precedence over default configurations. Refer to [`spec.override`](#spec-override) for details. #### Values @@ -226,7 +226,7 @@ The following table describes the parameters you can specify in a member of the ## Example configuration -In the following example, all requests through the gateway must have the `api.apps.organization.com` audience claim. Additionally, requests through the gateway must have a `user` role by default. +In the following example, all requests through the gateway must have the `api.apps.organization.com` audience claim. Additionally, requests through the gateway must have a `user` role by default. ```yaml apiVersion: consul.hashicorp.com/v1alpha1 @@ -237,7 +237,7 @@ spec: targetRef: name: gateway kind: Gateway - group: gateway.networking.kuberenetes.io + group: gateway.networking.kubernetes.io sectionName: to-server override: jwt: @@ -256,4 +256,4 @@ spec: - "roles" - "perm" value: "user" -``` \ No newline at end of file +``` diff --git a/website/content/docs/connect/gateways/api-gateway/configuration/routes.mdx b/website/content/docs/connect/gateways/api-gateway/configuration/routes.mdx index afa333dd2c..6723931290 100644 --- a/website/content/docs/connect/gateways/api-gateway/configuration/routes.mdx +++ b/website/content/docs/connect/gateways/api-gateway/configuration/routes.mdx @@ -50,9 +50,9 @@ The following outline shows how to format the configurations for the `Route` obj - [`replacePrefixMatch`](#rules-filters-urlrewrite-path): string | required - [`type`](#rules-filters-urlrewrite-path): string | required - [`extensionRef`](#rules-filters-extensionref): map - - [`group`](#rultes-filters-extensionref): string | must be set to `consul.hashicorp.com` - - [`kind`](#rultes-filters-extensionref): string | must be set to `RouteAuthFilter` - - [`name`](#rultes-filters-extensionref): string | must be set to `consul.hashicorp.com` + - [`group`](#rules-filters-extensionref): string | must be set to `consul.hashicorp.com` + - [`kind`](#rules-filters-extensionref): string | must be set to `RouteAuthFilter` + - [`name`](#rules-filters-extensionref): string | must be set to `consul.hashicorp.com` - [`matches`](#rules-matches): array of objects | optional - [`path`](#rules-matches-path): list of objects | optional - [`type`](#rules-matches-path): string | required diff --git a/website/content/docs/connect/gateways/api-gateway/define-routes/routes-k8s.mdx b/website/content/docs/connect/gateways/api-gateway/define-routes/routes-k8s.mdx index 3e29ac2d34..13413e82bd 100644 --- a/website/content/docs/connect/gateways/api-gateway/define-routes/routes-k8s.mdx +++ b/website/content/docs/connect/gateways/api-gateway/define-routes/routes-k8s.mdx @@ -1,18 +1,18 @@ --- layout: docs page_title: Define API gateway routes on Kubernetes -description: Learn how to define and attach HTTP and TCP routes to Consul API gateway listeners in Kubernetes-orchestrated networks. +description: Learn how to define and attach HTTP and TCP routes to Consul API gateway listeners in Kubernetes-orchestrated networks. --- # Define API gateway routes on Kubernetes -This topic describes how to configure HTTP and TCP routes and attach them to Consul API gateway listeners in Kubernetes-orchestrated networks. Routes are rule-based configurations that allow external clients to send requests to services in the mesh. For information +This topic describes how to configure HTTP and TCP routes and attach them to Consul API gateway listeners in Kubernetes-orchestrated networks. Routes are rule-based configurations that allow external clients to send requests to services in the mesh. For information ## Overview The following steps describe the general workflow for defining and deploying routes: -1. Define a route configuration that specifies the protocol type, name of the gateway to attach to, and rules for routing requests. +1. Define a route configuration that specifies the protocol type, name of the gateway to attach to, and rules for routing requests. 1. Deploy the configuration to create the routes and attach them to the gateway. Routes and the gateways they are attached to are eventually-consistent objects. They provide feedback about their current state through a series of status conditions. As a result, you must manually check the route status to determine if the route successfully bound to the gateway. @@ -23,7 +23,7 @@ Verify that your environment meets the requirements specified in [Technical spec ### OpenShift -If your Kubernetes-orchestrated network runs on OpenShift, verify that OpenShift is enabled for your Consul installation. Refer to [OpenShift requirements](/consul/docs/connect/gateways/api-gateway/tech-specs#openshift-requirements) for additional information. +If your Kubernetes-orchestrated network runs on OpenShift, verify that OpenShift is enabled for your Consul installation. Refer to [OpenShift requirements](/consul/docs/connect/gateways/api-gateway/tech-specs#openshift-requirements) for additional information. ## Define routes @@ -31,12 +31,12 @@ Define route configurations and bind them to listeners configured on the gateway 1. Create a configuration file and specify the following fields: - - `apiVersion`: Specifies the Kuberenetes API gateway version. This must be set to `gateway.networking.k8s.io/v1beta1` + - `apiVersion`: Specifies the Kubernetes API gateway version. This must be set to `gateway.networking.k8s.io/v1beta1` - `kind`: Set to `HTTPRoute` or `TCPRoute`. - `metadata.name`: Specify a name for the route. The name is metadata that you can use to reference the configuration when performing Consul operations. - - `spec.parentRefs.name`: Specifies a list of API gateways that the route binds to. + - `spec.parentRefs.name`: Specifies a list of API gateways that the route binds to. - `spec. rules`: Specifies a list of routing rules for constructing a routing table that maps listeners to services. - + Refer to the [`Routes` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/routes) for details about configuring route rules. 1. Configure any additional fields necessary for your use case, such as the namespace or admin partition. diff --git a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx index 97c6eb30cb..7aaded1fe2 100644 --- a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx +++ b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx @@ -41,7 +41,7 @@ Create a `GatewayPolicy` values file and configure the following fields to defin - `metadata.name`: Specifies a name for the policy. - `spec.targetRef.name`: Specifies the name of the API gateway to attach the policy to. - `spec.targetRef.kind`: Specifies the kind of resource to attach to the policy to. Must be set to `Gateway`. -- `spec.targetRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kuberenetes.io`. +- `spec.targetRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kubernetes.io`. - `spec.targetRef.sectionName`: Specifies a part of the gateway that the policy applies to. - `spec.targetRef.override.jwt.providers`: Specifies a list of providers and claims used to verify requests to the gateway. The override settings take precedence over the default and route-specific JWT verification settings. - `spec.targetRef.default.jwt.providers`: Specifies a list of default providers and claims used to verify requests to the gateway. @@ -60,7 +60,7 @@ Create an `RouteAuthFilter` values file and configure the following fields. Refe In the `filters` field of your HTTP route configuration, add the following fields. Refer to the [`extensionRef` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/routes#rules-filters-extensionref) for details: - `type: extensionRef`: Declare list of extension references. -- `extensionRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kuberenetes.io`. +- `extensionRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kubernetes.io`. - `extensionRef.kind`: Specifies the type of extension reference to attach to the route. Must be `RouteAuthFilter` - `extensionRef.name`: Specifies the name of the auth filter. diff --git a/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx b/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx index e7cc1d37ea..5dd4d5fdcd 100644 --- a/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx +++ b/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx @@ -40,7 +40,7 @@ Refer to the following topics for additional information: ### Security context constraints -OpenShift requires a security context constraint (SCC) configuration, which restricts pods to specific groups. You can create a custom SCC or use one of the default constraints. Refer to the [OpenShift documentation](https://docs.openshift.com/container-platform/4.13/authentication/managing-security-context-constraints.html) for additional information. +OpenShift requires a security context constraint (SCC) configuration, which restricts pods to specific groups. You can create a custom SCC or use one of the default constraints. Refer to the [OpenShift documentation](https://docs.openshift.com/container-platform/4.13/authentication/managing-security-context-constraints.html) for additional information. By default, the SCC is set to `restricted-v2` for the `managedGatewayClass` that Consul automatically creates. The `restricted-v2` SCC is one of OpenShifts default SCCs, but you can specify a different SCC in the `openshiftSCCName` parameter: @@ -52,12 +52,12 @@ connectInject: ``` ### Privileged container ports - + Containers cannot use privileged ports when OpenShift is enabled. Privileged ports are 1 through 1024, and serving applications from that range is a security risk. To allow gateway listeners to use privileged port numbers, specify an integer value in the `mapPrivilegedContainerPorts` field of your Consul values configuration. Consul adds the value to listener port numbers that are set to a number in the privileged container range. Consul maps the configured port number to the total port number so that traffic sent to the configured port number is correctly forwarded to the service. -For example, if a gateway listener is configured to port `80` and the `mapPrivilegedContainerPorts` field is configured to `2000`, then the actual port number on the underlying container is `2080`. +For example, if a gateway listener is configured to port `80` and the `mapPrivilegedContainerPorts` field is configured to `2000`, then the actual port number on the underlying container is `2080`. You can set the `mapPrivilegedContainerPorts` parameter in the following map in your Consul values file: @@ -74,29 +74,29 @@ Refer to the [release notes](/consul/docs/release-notes) for your version of Con ## Supported Kubernetes gateway specification features -Consul API gateways for Kuberentes support a subset of the Kubernetes Gateway API specification. For a complete list of features, including the list of gateway and route statuses and an explanation on how they -are used, refer to the [documentation in our GitHub repo](https://github.com/hashicorp/consul-api-gateway/blob/main/dev/docs/supported-features.md): +Consul API gateways for Kubernetes support a subset of the Kubernetes Gateway API specification. For a complete list of features, including the list of gateway and route statuses and an explanation on how they +are used, refer to the [documentation in our GitHub repo](https://github.com/hashicorp/consul-api-gateway/blob/main/dev/docs/supported-features.md): ### `GatewayClass` -The `GatewayClass` resource describes a class of gateway configurations to use a template for creating `Gateway` resources. You can also specify custom API gateway configurations in a `GatewayClassConfig` CRD and attach them to resource to the `GatewayClass` using the `parametersRef` field. +The `GatewayClass` resource describes a class of gateway configurations to use a template for creating `Gateway` resources. You can also specify custom API gateway configurations in a `GatewayClassConfig` CRD and attach them to resource to the `GatewayClass` using the `parametersRef` field. You must specify the `"hashicorp.com/consul-api-gateway-controller"` controller so that Consul can manage gateways generated by the `GatewayClass`. Refer to the [Kubernetes `GatewayClass` documentation](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.GatewayClass) for additional information. -### `Gateway` +### `Gateway` -The `Gateway` resource is the core API gateway component. Gateways have one or more listeners that can route `HTTP`, `HTTPS`, or `TCP` traffic. You can define header-based hostname matching for listeners, but SNI is not supported. +The `Gateway` resource is the core API gateway component. Gateways have one or more listeners that can route `HTTP`, `HTTPS`, or `TCP` traffic. You can define header-based hostname matching for listeners, but SNI is not supported. You can apply filters to add, remove, and set header values on incoming requests. Gateways support the `terminate` TLS mode and `core/v1/Secret` TLS certificates. Extended option support includes TLS version and cipher constraints. Refer to the [Kubernetes `Gateway` documentation](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.Gateway) for additional information. ### `HTTPRoute` -`HTTPRoute` configurations determine HTTP paths between listeners defined on the gateway and services in the mesh. You can specify weights to load balance traffic, as well as define rules for matching request paths, headers, queries, and methods to ensure that traffic is routed appropriately. You can apply filters to add, remove, and set header values on requests sent through th route. +`HTTPRoute` configurations determine HTTP paths between listeners defined on the gateway and services in the mesh. You can specify weights to load balance traffic, as well as define rules for matching request paths, headers, queries, and methods to ensure that traffic is routed appropriately. You can apply filters to add, remove, and set header values on requests sent through th route. Routes support the following backend types: -- `core/v1/Service` backend types when the route maps to service registered with Consul. -- `api-gateway.consul.hashicorp.com/v1alpha1/MeshService`. +- `core/v1/Service` backend types when the route maps to service registered with Consul. +- `api-gateway.consul.hashicorp.com/v1alpha1/MeshService`. Refer to [Kubernetes `HTTPRoute` documentation](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute) for additional information. @@ -104,8 +104,8 @@ Refer to [Kubernetes `HTTPRoute` documentation](https://gateway-api.sigs.k8s.io/ `TCPRoute` configurations determine TCP paths between listeners defined on the gateway and services in the mesh. Routes support the following backend types: -- `core/v1/Service` backend types when the route maps to service registered with Consul. -- `api-gateway.consul.hashicorp.com/v1alpha1/MeshService`. +- `core/v1/Service` backend types when the route maps to service registered with Consul. +- `api-gateway.consul.hashicorp.com/v1alpha1/MeshService`. Refer to [Kubernetes `TCPRoute` documentation](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute) for additional information. diff --git a/website/content/docs/connect/manage-traffic/failover/sameness.mdx b/website/content/docs/connect/manage-traffic/failover/sameness.mdx index 75a7e769f9..ac8c8745fe 100644 --- a/website/content/docs/connect/manage-traffic/failover/sameness.mdx +++ b/website/content/docs/connect/manage-traffic/failover/sameness.mdx @@ -6,13 +6,13 @@ description: You can configure sameness groups so that when a service instance f # Failover with sameness groups -This page describes how to use sameness groups to automatically redirect service traffic to healthy instances in failover scenarios. Sameness groups are a user-defined set of Consul admin partitions with identical registered services. These admin paritions typically belong to Consul datacenters in different cloud regions, which enables sameness groups to participate in several service failover configuration strategies. +This page describes how to use sameness groups to automatically redirect service traffic to healthy instances in failover scenarios. Sameness groups are a user-defined set of Consul admin partitions with identical registered services. These admin partitions typically belong to Consul datacenters in different cloud regions, which enables sameness groups to participate in several service failover configuration strategies. To create a sameness group and configure each Consul datacenter to allow traffic from other members of the group, refer to [create sameness groups](/consul/docs/connect/cluster-peering/usage/create-sameness-groups). ## Failover strategies -You can edit a sameness group configuration entry so that all services failover to healthy instances on other members of a sameness group by default. You can also reference the sameness group in other configuration entries to enact other failover strategies for your network. +You can edit a sameness group configuration entry so that all services failover to healthy instances on other members of a sameness group by default. You can also reference the sameness group in other configuration entries to enact other failover strategies for your network. You can establish a failover strategy by configuring sameness group behavior in the following locations: @@ -33,9 +33,9 @@ In the following example configuration entry, datacenter `dc1` has two partition ```hcl -Kind = "sameness-group" +Kind = "sameness-group" Name = "example-sg" -Partition = "partition-1" +Partition = "partition-1" DefaultForFailover = true Members = [ {Partition = "partition-1"}, @@ -50,8 +50,8 @@ Members = [ ``` { - "Kind": "sameness-group", - "Name": "example-sg", + "Kind": "sameness-group", + "Name": "example-sg", "Partition": "partition-1", "DefaultForFailover": true, "Members": [ @@ -74,12 +74,12 @@ Members = [ ```yaml apiVersion: consul.hashicorp.com/v1alpha1 -kind: SamenessGroup +kind: SamenessGroup metadata: name: example-sg spec: defaultForFailover: true - members: + members: - partition: partition-1 - partition: partition-2 - peer: dc2-partition-1 @@ -132,8 +132,8 @@ Failover { ``` { - "Kind": "service-resolver", - "Name": "db", + "Kind": "service-resolver", + "Name": "db", "DefaultSubset": "v1", "Subsets": { "v1": { @@ -142,7 +142,7 @@ Failover { "v2": { "Filter": "Service.Meta.version == v2" } - }, + }, "Failover": { "v1": { "SamenessGroup": "product-group" diff --git a/website/content/docs/connect/manage-traffic/route-to-local-upstreams.mdx b/website/content/docs/connect/manage-traffic/route-to-local-upstreams.mdx index b2e891734c..4d5be2e5b5 100644 --- a/website/content/docs/connect/manage-traffic/route-to-local-upstreams.mdx +++ b/website/content/docs/connect/manage-traffic/route-to-local-upstreams.mdx @@ -32,17 +32,17 @@ For networks deployed to virtual machines, complete the following steps to route If you deployed Consul to a Kubernetes or ECS environment using `consul-k8s` or `consul-ecs`, service instance locality information is inherited from the host machine. As a result, you do not need to specify the regions and zones on containerized platforms unless you are implementing a custom deployment. -On Kubernetes, Consul automatically populates geographic information about service instances using the `topology.kubernetes.io/region` and `topology.kubernetes.io/zone` labels from the Kubernetes nodes. On AWS ECS, Consul uses the `AWS_REGION` environment variable and `AvailabilityZone` attribute of the ECS task meta. +On Kubernetes, Consul automatically populates geographic information about service instances using the `topology.kubernetes.io/region` and `topology.kubernetes.io/zone` labels from the Kubernetes nodes. On AWS ECS, Consul uses the `AWS_REGION` environment variable and `AvailabilityZone` attribute of the ECS task meta. ### Requirements -You should only enable locality-aware routing when each set of external upstream instances within the same zone and region have enough capacity to handle requests from downstream service instances in their respective zones. Locality-aware routing is an advanced feature that may adversely impact service capacity if used incorrectly. When enabled, Consul routes all traffic to the nearest set of service instances and only fails over when no healthy instances are available in the nearest set. +You should only enable locality-aware routing when each set of external upstream instances within the same zone and region have enough capacity to handle requests from downstream service instances in their respective zones. Locality-aware routing is an advanced feature that may adversely impact service capacity if used incorrectly. When enabled, Consul routes all traffic to the nearest set of service instances and only fails over when no healthy instances are available in the nearest set. ## Specify the locality of your Consul agents The `locality` configuration on a Consul client applies to all services registered to the client. -1. Configure the `locality` block in your Consul client agent configuration files. The `locality` block is a map containing the `region` and `zone` parameters. +1. Configure the `locality` block in your Consul client agent configuration files. The `locality` block is a map containing the `region` and `zone` parameters. The parameters should match the values for regions and zones defined in your network. Refer to [`locality`](/consul/docs/agent/config/config-files#locality) in the agent configuration reference for additional information. @@ -59,7 +59,7 @@ locality = { ## Specify the localities of your service instances (optional) -This step is optional in most scenarios. Refer to [Workflow](#workflow) for additional information. +This step is optional in most scenarios. Refer to [Workflow](#workflow) for additional information. 1. Configure the `locality` block in your service definition for both downstream (client) and upstream services. The `locality` block is a map containing the `region` and `zone` parameters. When you start a proxy for the service, Consul passes the locality to the proxy so that it can route traffic accordingly. @@ -70,7 +70,7 @@ Register or re-register the service to apply the configuration. Refer to [Regist In the following example, the `web` service is available in the `us-west-1` region and `us-west-1a` zone on AWS: -```hcl +```hcl service { id = "web" locality = { @@ -172,7 +172,7 @@ Apply the configuration by either running the [`consul config write` CLI command - + ```hcl Kind = "service-resolver" Name = "api" @@ -182,10 +182,10 @@ Apply the configuration by either running the [`consul config write` CLI command ``` - + - + ```json { "kind": "service-resolver", @@ -199,7 +199,7 @@ Apply the configuration by either running the [`consul config write` CLI command - + ```yaml apiversion: consul.hashicorp.com/v1alpha1 kind: ServiceResolver @@ -209,7 +209,7 @@ Apply the configuration by either running the [`consul config write` CLI command prioritizeByLocality: mode: failover ``` - + @@ -218,32 +218,32 @@ Apply the configuration by either running the [`consul config write` CLI command - + ```shell-session $ consul config write api-resolver.hcl ``` - + - + - + ```shell-session $ kubectl apply -f api-resolver.yaml ``` - + - + ```shell-session $ curl --request PUT --data @api-resolver.hcl http://127.0.0.1:8500/v1/config ``` - + ### Configure locality on Kubernetes test clusters explicitly -You can explicitly configure locality for each Kubernetes node so that you can test locality-aware routing with a local Kubernetes cluster or in an environment where `topology.kubernetes.io` labels are not set. +You can explicitly configure locality for each Kubernetes node so that you can test locality-aware routing with a local Kubernetes cluster or in an environment where `topology.kubernetes.io` labels are not set. Run the `kubectl label node` command and specify the locality as arguments. The following example specifies the `us-east-1` region and `us-east-1a` zone for the node: @@ -261,7 +261,7 @@ Consul configures Envoy's built-in [`overprovisioning_factor`](https://www.envoy To verify that locality-aware routing and failover configurations, you can inspect Envoy's xDS configuration dump for a downstream proxy. Refer to the [consul-k8s CLI docs](https://developer.hashicorp.com/consul/docs/k8s/k8s-cli#proxy-read) for details on how to obtain the xDS configuration dump on Kubernetes. For other workloads, use the Envoy [admin interface](https://www.envoyproxy.io/docs/envoy/latest/operations/admin) and ensure that you [include EDS](https://www.envoyproxy.io/docs/envoy/latest/operations/admin#get--config_dump?include_eds). -Inspect the [priority](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/priority#arch-overview-load-balancing-priority-levels) on each set of endpoints under the upstream `ClusterLoadAssignment` in the `EndpointsConfigDump`. Alternatively, the same priorities should be visibile within the output of the [`/clusters?format=json`](https://www.envoyproxy.io/docs/envoy/latest/operations/admin#get--clusters?format=json) admin endpoint. +Inspect the [priority](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/priority#arch-overview-load-balancing-priority-levels) on each set of endpoints under the upstream `ClusterLoadAssignment` in the `EndpointsConfigDump`. Alternatively, the same priorities should be visible within the output of the [`/clusters?format=json`](https://www.envoyproxy.io/docs/envoy/latest/operations/admin#get--clusters?format=json) admin endpoint. ```json { diff --git a/website/content/docs/connect/proxies/deploy-service-mesh-proxies.mdx b/website/content/docs/connect/proxies/deploy-service-mesh-proxies.mdx index 630da4a131..0bb3f7df03 100644 --- a/website/content/docs/connect/proxies/deploy-service-mesh-proxies.mdx +++ b/website/content/docs/connect/proxies/deploy-service-mesh-proxies.mdx @@ -1,13 +1,13 @@ --- layout: docs page_title: Deploy service mesh proxies -description: >- +description: >- Envoy and other proxies in Consul service mesh enable service-to-service communication across your network. Learn how to deploy service mesh proxies in this topic. --- # Deploy service mesh proxies services -This topic describes how to create, register, and start service mesh proxies in Consul. Refer to [Service mesh proxies overview](/consul/docs/connect/proxies) for additional information about how proxies enable Consul functionalities. +This topic describes how to create, register, and start service mesh proxies in Consul. Refer to [Service mesh proxies overview](/consul/docs/connect/proxies) for additional information about how proxies enable Consul functionalities. For information about deploying proxies as sidecars for service instances, refer to [Deploy sidecar proxy services](/consul/docs/connect/proxies/deploy-sidecar-services). @@ -15,7 +15,7 @@ For information about deploying proxies as sidecars for service instances, refer Complete the following steps to deploy a service mesh proxy: -1. It is not required, but you can create a proxy defaults configuration entry that contains global passthrough settings for all Envoy proxies. +1. It is not required, but you can create a proxy defaults configuration entry that contains global passthrough settings for all Envoy proxies. 1. Create a service definition file and specify the proxy configurations in the `proxy` block. 1. Register the service using the API or CLI. 1. Start the proxy service. Proxies appear in the list of services registered to Consul, but they must be started before they begin to route traffic in your service mesh. @@ -31,29 +31,29 @@ If you want to define global passthrough settings for all Envoy proxies, create 1. Create a proxy defaults configuration entry and specify the following parameters: - `Kind`: Must be set to `proxy-defaults` - `Name`: Must be set to `global` -1. Configure any additional settings you want to apply to all proxies. Refer to [Proxy defaults configuration entry reference](/consul/docs/connect/config-entries/proxy-defaults) for details about all settings available in the configuraiton entry. +1. Configure any additional settings you want to apply to all proxies. Refer to [Proxy defaults configuration entry reference](/consul/docs/connect/config-entries/proxy-defaults) for details about all settings available in the configuration entry. 1. Apply the configuration by either calling the [`/config` HTTP API endpoint](/consul/api-docs/config) or running the [`consul config write` CLI command](/consul/commands/config/write). The following example writes a proxy defaults configuration entry from a local HCL file using the CLI: ```shell-session $ consul config write proxy-defaults.hcl ``` -## Define service mesh proxy +## Define service mesh proxy Create a service definition file and configure the following fields to define a service mesh proxy: 1. Set the `kind` field to `connect-proxy`. Refer to the [services configuration reference](/consul/docs/services/configuration/services-configuration-reference#kind) for information about other kinds of proxies you can declare. 1. Specify a name for the proxy service in the `name` field. Consul applies the configurations to any proxies you bootstrap with the same name. -1. In the `proxy.destination_service_name` field, specify the name of the service that the proxy represents. -1. Configure any additional proxy behaviors that you want to implement in the `proxy` block. Refer to the [Service mesh proxy configuration reference](/consul/docs/connect/proxies/proxy-config-reference) for information about all parameters. +1. In the `proxy.destination_service_name` field, specify the name of the service that the proxy represents. +1. Configure any additional proxy behaviors that you want to implement in the `proxy` block. Refer to the [Service mesh proxy configuration reference](/consul/docs/connect/proxies/proxy-config-reference) for information about all parameters. 1. Specify a port number where other services registered with Consul can discover and connect to the proxies service in the `port` field. To ensure that services only allow external connections established through the service mesh protocol, you should configure all services to only accept connections on a loopback address. Refer to the [Service mesh proxy configuration reference](/consul/docs/connect/proxies/proxy-config-reference) for example configurations. -## Register the service +## Register the service Provide the service definition to the Consul agent to register your proxy service. You can use the same methods for registering proxy services as you do for registering application services: - + - Place the service definition in a Consul agent's configuration directory and start, restart, or reload the agent. Use this method when implementing changes to an existing proxy service. - Use the `consul services register` command to register the proxy service with a running Consul agent. - Call the `/agent/service/register` HTTP API endpoint to register the proxy service with a running Consul agent. @@ -68,7 +68,7 @@ $ consul services register proxy.hcl ## Start the proxy -Envoy requires a bootstrap configuration file before it can start. Use the [`consul connect envoy` command](/consul/commands/connect/envoy) to create the Envoy bootstrap configuration and start the proxy service. Specify the ID of the proxy you want to start with the `-proxy-id` option. +Envoy requires a bootstrap configuration file before it can start. Use the [`consul connect envoy` command](/consul/commands/connect/envoy) to create the Envoy bootstrap configuration and start the proxy service. Specify the ID of the proxy you want to start with the `-proxy-id` option. The following example command starts an Envoy proxy for the `web-proxy` service: @@ -76,4 +76,4 @@ The following example command starts an Envoy proxy for the `web-proxy` service: $ consul connect envoy -proxy-id=web-proxy ``` -For details about operating an Envoy proxy in Consul, refer to the [Envoy proxy reference](/consul/docs/connect/proxies/envoy). +For details about operating an Envoy proxy in Consul, refer to the [Envoy proxy reference](/consul/docs/connect/proxies/envoy). diff --git a/website/content/docs/connect/proxies/deploy-sidecar-services.mdx b/website/content/docs/connect/proxies/deploy-sidecar-services.mdx index ad533b5946..c42a5b2c7f 100644 --- a/website/content/docs/connect/proxies/deploy-sidecar-services.mdx +++ b/website/content/docs/connect/proxies/deploy-sidecar-services.mdx @@ -11,15 +11,15 @@ This topic describes how to create, register, and start sidecar proxy services i ## Overview -Sidecar proxies run on the same node as the single service instance that they handle traffic for. -They may be on the same VM or running as a separate container in the same network namespace. +Sidecar proxies run on the same node as the single service instance that they handle traffic for. +They may be on the same VM or running as a separate container in the same network namespace. You can attach a sidecar proxy to a service you want to deploy to your mesh: -1. It is not required, but you can create a proxy defaults configuration entry that contains global passthrough settings for all Envoy proxies. +1. It is not required, but you can create a proxy defaults configuration entry that contains global passthrough settings for all Envoy proxies. 1. Create the service definition and include the `connect` block. The `connect` block contains the sidecar proxy configurations that allow the service to interact with other services in the mesh. 1. Register the service using either the API or CLI. -1. Start the sidecar proxy service. +1. Start the sidecar proxy service. ## Requirements @@ -32,21 +32,21 @@ If you want to define global passthrough settings for all Envoy proxies, create 1. Create a proxy defaults configuration entry and specify the following parameters: - `Kind`: Must be set to `proxy-defaults` - `Name`: Must be set to `global` -1. Configure any additional settings you want to apply to all proxies. Refer to [Proxy defaults configuration entry reference](/consul/docs/connect/config-entries/proxy-defaults) for details about all settings available in the configuraiton entry. +1. Configure any additional settings you want to apply to all proxies. Refer to [Proxy defaults configuration entry reference](/consul/docs/connect/config-entries/proxy-defaults) for details about all settings available in the configuration entry. 1. Apply the configuration by either calling the [`/config` API endpoint](/consul/api-docs/config) or running the [`consul config write` CLI command](/consul/commands/config/write). The following example writes a proxy defaults configuration entry from a local HCL file using the CLI: ```shell-session $ consul config write proxy-defaults.hcl ``` -## Define service mesh proxy +## Define service mesh proxy -Create a service definition and configure the following fields: +Create a service definition and configure the following fields: -1. `name`: Specify a name for the service you want to attach a sidecar proxy to in the `name` field. This field is required for all services you want to register in Consul. +1. `name`: Specify a name for the service you want to attach a sidecar proxy to in the `name` field. This field is required for all services you want to register in Consul. 1. `port`: Specify a port number where other services registered with Consul can discover and connect to the service in the `port` field. This field is required for all services you want to register in Consul. 1. `connect`: Set the `connect` field to `{ sidecar_service: {} }`. The `{ sidecar_service: {} }` value is a macro that applies a set of default configurations that enable you to quickly implement a sidecar. Refer to [Sidecar service defaults](#sidecar-service-defaults) for additional information. -1. Configure any additional options for your service. Refer to [Services configuration reference](/consul/docs/services/configuration/services-configuration-reference) for details. +1. Configure any additional options for your service. Refer to [Services configuration reference](/consul/docs/services/configuration/services-configuration-reference) for details. In the following example, a service named `web` is configured with a sidecar proxy: @@ -60,7 +60,7 @@ service = { port = 8080 connect = { sidecar_service = {} } } -``` +``` @@ -89,7 +89,7 @@ When Consul processes the service definition, it generates the following configu ```hcl -services = [ +services = [ { name = "web" port = 8080 @@ -114,7 +114,7 @@ services = [ } ] -``` +``` @@ -156,12 +156,12 @@ services = [ - + -## Register the service +## Register the service Provide the service definition to the Consul agent to register your proxy service. You can use the same methods for registering proxy services as you do for registering application services: - + - Place the service definition in a Consul agent's configuration directory and start, restart, or reload the agent. Use this method when implementing changes to an existing proxy service. - Use the `consul services register` command to register the proxy service with a running Consul agent. - Call the `/agent/service/register` HTTP API endpoint to register the proxy service with a running Consul agent. @@ -176,7 +176,7 @@ $ consul services register proxy.hcl ## Start the proxy -Envoy requires a bootstrap configuration file before it can start. Use the [`consul connect envoy` command](/consul/commands/connect/envoy) to create the Envoy bootstrap configuration and start the proxy service. Specify the name of the service with the attached proxy with the `-sidecar-for` option. +Envoy requires a bootstrap configuration file before it can start. Use the [`consul connect envoy` command](/consul/commands/connect/envoy) to create the Envoy bootstrap configuration and start the proxy service. Specify the name of the service with the attached proxy with the `-sidecar-for` option. The following example command starts an Envoy sidecar proxy for the `web` service: @@ -184,11 +184,11 @@ The following example command starts an Envoy sidecar proxy for the `web` servic $ consul connect envoy -sidecar-for=web ``` -For details about operating an Envoy proxy in Consul, refer to [](/consul/docs/connect/proxies/envoy) +For details about operating an Envoy proxy in Consul, refer to [](/consul/docs/connect/proxies/envoy) ## Configuration reference -The `sidecar_service` block is a service definition that can contain most regular service definition fields. Refer to [Limitations](#limitations) for information about unsupported service definition fields for sidecar proxies. +The `sidecar_service` block is a service definition that can contain most regular service definition fields. Refer to [Limitations](#limitations) for information about unsupported service definition fields for sidecar proxies. Consul treats sidecar proxy service definitions as a root-level service definition. All fields are optional in nested definitions, which default to opinionated settings that are intended to reduce burden of setting up a sidecar proxy. @@ -224,7 +224,7 @@ proxy. In the following example, the `sidecar_service` macro sets baselines configurations for the proxy, but the [proxy upstreams](/consul/docs/connect/proxies/proxy-config-reference#upstream-configuration-reference) and [built-in proxy -configuration](/consul/docs/connect/proxies/built-in) fields contain custom values: +configuration](/consul/docs/connect/proxies/built-in) fields contain custom values: ```json { @@ -281,4 +281,4 @@ service's ID, which enables the following behavior. - When reloading the configuration files, if a service definition changes its ID, then a new service instance and a new sidecar instance are registered. The old instance and proxy are removed because they are no longer found in - the configuration files. \ No newline at end of file + the configuration files. diff --git a/website/content/docs/ecs/deploy/manual.mdx b/website/content/docs/ecs/deploy/manual.mdx index 52b0bda05b..9b54aa0579 100644 --- a/website/content/docs/ecs/deploy/manual.mdx +++ b/website/content/docs/ecs/deploy/manual.mdx @@ -18,24 +18,24 @@ You should have some familiarity with AWS ECS. Refer to [What is Amazon Elastic You must meet the following requirements and prerequisites to enable security features in Consul service mesh: - Enable [TLS encryption](https://developer.hashicorp.com/consul/docs/security/encryption#rpc-encryption-with-tls) on your Consul servers so that they can communicate security with Consul dataplane containers over gRPC. -- Enable [access control lists (ACLs)](/consul/docs/security/acl) on your Consul servers. ALCs provide authentication and authorization for access to Consul servers on the mesh. +- Enable [access control lists (ACLs)](/consul/docs/security/acl) on your Consul servers. ACLs provide authentication and authorization for access to Consul servers on the mesh. - You should be familiar with specifying sensitive data on ECS. Refer to [Passing sensitive data to a container](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html) in the AWS documentation for additional information. You should be familiar with configuring Consul's secure features, including how to create ACL tokens and policies. Refer to the following resources: - [Create a service token](/consul/docs/security/acl/tokens/create/create-a-service-token) - [Day 1: Security tutorial](https://developer.hashicorp.com/consul/tutorials/security) for additional information. -Consul requires a unique IAM role for each ECS task family. Task IAM roles cannot be shared by different task families because the task family is unique to each Consul service. +Consul requires a unique IAM role for each ECS task family. Task IAM roles cannot be shared by different task families because the task family is unique to each Consul service. ## Configure ECS task definition file -Create a JSON file for the task definition. The task definition is the ECS blueprint for your software services on AWS. Refer to the [ECS task definitions in the AWS documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) for additional information. +Create a JSON file for the task definition. The task definition is the ECS blueprint for your software services on AWS. Refer to the [ECS task definitions in the AWS documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) for additional information. In addition to your application container, add configurations to your task definition that creates the following Consul containers: - Dataplane container - Control-plane container -- ECS controller container +- ECS controller container ## Top-level fields @@ -46,7 +46,7 @@ The following table describes the top-level fields you must include in the task | `family` | The task family name. This is used as the Consul service name by default. | string | | `networkMode` | Must be `awsvpc`, which is the only network mode supported by Consul on ECS. | string | | `volumes` | Volumes on the host for sharing configuration between containers for initial task setup. You must define a `consul_data` and `consul_binary` bind mount. Bind mounts can be mounted into one or more containers in order to share files among containers. For Consul on ECS, certain binaries and configuration are shared among containers during task startup. | list | -| `containerDefinitions` | Defines the application container that runs in the task. Refer to [Define your application container](#define-your-application-container). | list | +| `containerDefinitions` | Defines the application container that runs in the task. Refer to [Define your application container](#define-your-application-container). | list | The following example shows the top-level fields: @@ -81,7 +81,7 @@ The following example shows the top-level fields: The `tags` list must include the following tags if you are using the ECS controller in a [secure configuration](/consul/docs/ecs/deploy/manual#secure-configuration-requirements). Without these tags, the ACL controller is unable to provision a service token for the task. -| Tag | Description | Type | Default | +| Tag | Description | Type | Default | | --- | --- | --- | --- | | `consul.hashicorp.com/mesh` | Enables the ECS controller. Set to `false` to disable the ECS controller. | String | `true` | | `consul.hashicorp.com/service-name` | Specifies the name of the Consul service associated with this task. Required if the service name is different than the task `family`. | String | None | @@ -96,7 +96,7 @@ Specify your application container configurations in the `containerDefinitions` | --- | --- | --- | | `name` | The name of your application container. | string | | `image` | The container image used to run your application. | string | -| `essential` | Must be `true` to ensure the health of your application container affects the health status of the task. | boolean | +| `essential` | Must be `true` to ensure the health of your application container affects the health status of the task. | boolean | | `dependsOn` | Specifies container dependencies that ensure your application container starts after service mesh setup is complete. Refer to [Application container dependency configuration](#application-container-dependency-configuration) for details. | list | Refer to the [ECS Task Definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html) documentation for a complete reference. @@ -120,7 +120,7 @@ The `dependsOn` list must include the following maps: } ``` -## Configure the dataplane container +## Configure the dataplane container The dataplane container runs Envoy proxy for Consul service mesh. Specify the fields described in the following table to declare a dataplane container: @@ -174,7 +174,7 @@ Specify the fields described in the following table to declare the control-plane | --- | --- | --- | | `name` | Specifies the name of the container. This must be `control-plane`. | string | | `image` | Specifies the `consul-ecs` image. Specify the following public AWS registry to avoid rate limits: `public.ecr.aws/hashicorp/consul-ecs` | string | -| `mountPoints` | Specifies a shared volume to store the Envoy bootstrap configuration file that the dataplane container can access and consume. The keys and values in this configuration must be defined as described in [Control-plane shared volume configuration](#control-plane-shared-volume-configuration). | list | +| `mountPoints` | Specifies a shared volume to store the Envoy bootstrap configuration file that the dataplane container can access and consume. The keys and values in this configuration must be defined as described in [Control-plane shared volume configuration](#control-plane-shared-volume-configuration). | list | | `command` | Set to `["control-plane"]` so that the container runs the `control-plane` command. | list | | `environment` | Specifies the `CONSUL_ECS_CONFIG_JSON` environment variable, which configures the container to connect to the Consul servers. Refer to [Control-plane to Consul servers configuration](#control-plane-to-Consul-servers-configuration) for details. | list | @@ -199,7 +199,7 @@ The `mountPoints` configuration defines a volume and path where the control-plan ### Control-plane to Consul servers configuration -Provide Consul server connection settings to the mesh task module so that the module can configure the control-plane and ECS controller containers to connect to the servers. +Provide Consul server connection settings to the mesh task module so that the module can configure the control-plane and ECS controller containers to connect to the servers. 1. In your `variables.tf` file, define variables for the host URL and TLS settings for gRPC and HTTP traffic. Refer to the [mesh task module reference](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task?tab=inputs) for information about the variables you can define. In the following example, the Consul server address is defined in the `consul_server_hosts` variable: @@ -210,7 +210,7 @@ Provide Consul server connection settings to the mesh task module so that the mo } ``` -1. Add an `environment` block to the control-plane and ECS controller containers definition +1. Add an `environment` block to the control-plane and ECS controller containers definition. 1. Set the `environment.name` field to the `CONSUL_ECS_CONFIG_JSON` environment variable and the value to `local.encoded_config`. ```hcl @@ -223,7 +223,7 @@ Provide Consul server connection settings to the mesh task module so that the mo ``` When you apply the configuration, the mesh task module interpolates the server configuration variables, builds a `config.tf` file, and injects the settings into the appropriate containers. -For additional information about the `config.tf` file, refer to the [JSON schema reference documentation](/consul/docs/ecs/reference/config-json-schema). +For additional information about the `config.tf` file, refer to the [JSON schema reference documentation](/consul/docs/ecs/reference/config-json-schema). ## Register the task definition configuration @@ -245,8 +245,8 @@ Verify that you have completed the prerequisites described in [Secure configurat On the Consul server, create a policy that grants the following access for the controller: -- `acl:write` -- `operator:write` +- `acl:write` +- `operator:write` - `node:write` - `service:write` @@ -260,7 +260,7 @@ The policy allows Consul to generate a token linked to the policy. Refer to [Cre ### Configure the auth method for service tokens -Run the `consul acl auth-method create` command on a Consul server to create an instance of the auth method for service tokens. +Run the `consul acl auth-method create` command on a Consul server to create an instance of the auth method for service tokens. The following example command configures the auth method to associate a service identity to each token created during login to this auth method instance. @@ -303,9 +303,9 @@ You must specify the following configuration in the `-config` flag: Refer to the [auth method configuration parameters documentation](/consul/docs/security/acl/auth-methods/aws-iam#config-parameters) for additional information. -### Create the binding rule +### Create the binding rule -Run the `consul acl binding-rule create` command on a Consul server to create a binding rule. The rule associates a service identity with each token created on successful login to this instance of the auth method. +Run the `consul acl binding-rule create` command on a Consul server to create a binding rule. The rule associates a service identity with each token created on successful login to this instance of the auth method. In the following example, Consul takes the service identity name from the `consul.hashicorp.com.service-name` tag specified for authenticating IAM role identity. @@ -336,7 +336,7 @@ You can reference stored secrets using their ARN. The examples show ARNs for sec You can configure Consul servers connected to your ECS workloads to capture a log of authenticated events. Refer to [Audit Logging](/consul/docs/enterprise/audit-logging) for details. ## Next steps - + After deploying the Consul service mesh infrastructure, you must still define routes between service instances as well as configure the bind address for your applications so that they only receive traffic through the mesh. Refer to the following topics: - [Configure routes between ECS tasks](/consul/docs/ecs/deploy/configure-routes) diff --git a/website/content/docs/ecs/deploy/migrate-existing-tasks.mdx b/website/content/docs/ecs/deploy/migrate-existing-tasks.mdx index 77ab4ded7f..cb405e518a 100644 --- a/website/content/docs/ecs/deploy/migrate-existing-tasks.mdx +++ b/website/content/docs/ecs/deploy/migrate-existing-tasks.mdx @@ -5,13 +5,13 @@ description: >- You can migrate tasks in existing Amazon Web Services ECS deployments to a service mesh deployed with Terraform. Learn how to convert a task specified as an ECS task definition into a `mesh-task` Terraform module. --- -# Migrate existing tasks to Consul on ECS with Terraform +# Migrate existing tasks to Consul on ECS with Terraform -To migrate existing tasks to Consul, rewrite the existing Terraform code for your tasks so that the container definitions include the [`mesh-task` Terraform module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task). +To migrate existing tasks to Consul, rewrite the existing Terraform code for your tasks so that the container definitions include the [`mesh-task` Terraform module](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/mesh-task). Your tasks must already be defined in Terraform using the `ecs_task_definition` resource so that they can then be converted to use the `mesh-task` module. -## Example +## Example The following example shows an existing task definition configured in Terraform: @@ -93,7 +93,7 @@ module "my_task" { Note the following differences: - The `execution_role_arn` and `task_role_arn` fields are removed. The `mesh-task` module creates the task and execution roles by default. If you need to use existing IAM roles, set the `task_role` and `execution_role` fields to pass in existing roles. -- The `port` field specifes the port that your application listens on. If your application has no listening port, set `outbound_only = true` and remove the `port` field. +- The `port` field specifies the port that your application listens on. If your application has no listening port, set `outbound_only = true` and remove the `port` field. - The `jsonencode()` function is removed from the `container_definitions` field. -The `mesh-task` module creates a new version of your task definition with the necessary dataplane containers so you can delete your existing `aws_ecs_task_definition` resource. \ No newline at end of file +The `mesh-task` module creates a new version of your task definition with the necessary dataplane containers so you can delete your existing `aws_ecs_task_definition` resource. diff --git a/website/content/docs/ecs/deploy/terraform.mdx b/website/content/docs/ecs/deploy/terraform.mdx index c091ff4596..5d5574a967 100644 --- a/website/content/docs/ecs/deploy/terraform.mdx +++ b/website/content/docs/ecs/deploy/terraform.mdx @@ -11,17 +11,17 @@ This topic describes how to create a Terraform configuration that deploys Consul ## Overview -Create a Terraform configuration file that includes the ECS task definition and Terraform modules that build the Consul service mesh components. The task definition is the ECS blueprint for your software services on AWS. Refer to the [ECS task definitions documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) for additional information. +Create a Terraform configuration file that includes the ECS task definition and Terraform modules that build the Consul service mesh components. The task definition is the ECS blueprint for your software services on AWS. Refer to the [ECS task definitions documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) for additional information. You can add the following modules and resources to your Terraform configuration: -- `mesh-task` module: Adds the Consul ECS control-plane and Consul dataplane containers to the task definition along with your application container. Envoy runs as a subprocess within the Consul dataplane container. +- `mesh-task` module: Adds the Consul ECS control-plane and Consul dataplane containers to the task definition along with your application container. Envoy runs as a subprocess within the Consul dataplane container. - `aws_ecs_service` resource: Adds an ECS service to run and maintain your task instance. - `gateway-task` module: Adds mesh gateway containers to the cluster. Mesh gateways enable service-to-service communication across different types of network areas. -To enable Consul security features for your production workloads, you must also deploy the `controller` module, which provisions ACL tokens for service mesh tasks. +To enable Consul security features for your production workloads, you must also deploy the `controller` module, which provisions ACL tokens for service mesh tasks. -After defining your Terraform configuration, use `terraform apply` to deploy Consul to your ECS cluster. +After defining your Terraform configuration, use `terraform apply` to deploy Consul to your ECS cluster. ## Requirements @@ -34,10 +34,10 @@ After defining your Terraform configuration, use `terraform apply` to deploy Con You must meet the following requirements and prerequisites to enable security features in Consul service mesh: - Enable [TLS encryption](/consul/docs/security/encryption#rpc-encryption-with-tls) on your Consul servers so that they can communicate securely with Consul containers over gRPC. -- Enable [access control lists (ACLs)](/consul/docs/security/acl) on your Consul servers. ALCs provide authentication and authorization for access to Consul servers on the mesh. +- Enable [access control lists (ACLs)](/consul/docs/security/acl) on your Consul servers. ACLs provide authentication and authorization for access to Consul servers on the mesh. - You should be familiar with specifying sensitive data on ECS. Refer to [Passing sensitive data to a container](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html) in the AWS documentation for additional information. -Additionally, Consul requires a unique IAM role for each ECS task family. Task IAM roles cannot be shared by different task families because the task family is unique to each Consul service. +Additionally, Consul requires a unique IAM role for each ECS task family. Task IAM roles cannot be shared by different task families because the task family is unique to each Consul service. You should be familiar with configuring Consul's secure features, including how to create ACL tokens and policies. Refer to the following resources for additional information: @@ -53,7 +53,7 @@ Create a Terraform configuration file and add your ECS task definition. The task Add a `module` block to your Terraform configuration and specify the following fields: - `source`: Specifies the location of the `mesh-task` module. This field must be set to `hashicorp/consul-ecs/aws//modules/mesh-task`. The `mesh-task` module automatically adds the Consul service mesh infrastructure when you apply the Terraform configuration. -- `version`: Specifies the version of the `mesh-task` module to use. +- `version`: Specifies the version of the `mesh-task` module to use. - `family`: Specifies the [ECS task definition family](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#family). Consul also uses the `family` value as the Consul service name by default. - `container_definitions`: Specifies a list of [container definitions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions) for the task definition. This field is where you include your application containers. @@ -99,7 +99,7 @@ The following fields are required. Refer to the [module reference documentation] ## Configure Consul server settings -Provide Consul server connection settings to the mesh task module so that the module can configure the control-plane and ECS controller containers to connect to the servers. +Provide Consul server connection settings to the mesh task module so that the module can configure the control-plane and ECS controller containers to connect to the servers. 1. In your `variables.tf` file, define variables for the host URL and the TLS settings for gRPC and HTTP traffic. Refer to the [mesh task module reference](https://registry.terraform.io/modules/hashicorp/consul-ecs/aws/latest/submodules/gateway-task?tab=inputs) for information about the variables you can define. In the following example, the Consul server address is defined in the `consul_server_hosts` variable: @@ -121,13 +121,13 @@ Provide Consul server connection settings to the mesh task module so that the mo ] ``` - When you apply the configuration, the mesh task module interpolates the server configuration variables, builds a `config.tf` file, and injects the settings into the appropriate containers. For additional information about the `config.tf` file, refer to the [JSON schema reference documentation](/consul/docs/ecs/reference/consul-server-json). + When you apply the configuration, the mesh task module interpolates the server configuration variables, builds a `config.tf` file, and injects the settings into the appropriate containers. For additional information about the `config.tf` file, refer to the [JSON schema reference documentation](/consul/docs/ecs/reference/consul-server-json). ## Configure an ECS service to run your task instances To start a task using the task definition, add the `aws_ecs_service` resource to your configuration to create an ECS service. [ECS services](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html) are one of the most common ways to start tasks using a task definition. -Reference the `mesh-task` module's `task_definition_arn` output value in your `aws_ecs_service` resource. The following example adds an ECS service for a task definition referenced in as `module.my_task.task_defintion_arn`: +Reference the `mesh-task` module's `task_definition_arn` output value in your `aws_ecs_service` resource. The following example adds an ECS service for a task definition referenced in as `module.my_task.task_definition_arn`: @@ -154,7 +154,7 @@ If you are deploying a test instance of your ECS application, you can apply your If you intend to leverage multi-datacenter Consul features, such as WAN federation and cluster peering, then you must add the `gateway-task` module for each Consul datacenter in your network. Refer to [Configure the gateway task module](#configure-the-gateway-task-module) for instructions. -## Configure the gateway task module +## Configure the gateway task module The `gateway-task` module deploys a mesh gateway, which enables service-to-service communication across network areas. Mesh gateways detect the server name indication (SNI) header from the service mesh session and route the connection to the appropriate destination. @@ -163,12 +163,12 @@ Refer to the following documentation for additional information: - [WAN Federation via Mesh Gateways](/consul/docs/connect/gateways/mesh-gateway/wan-federation-via-mesh-gateways) - [Service-to-service Traffic Across Datacenters](/consul/docs/connect/gateways/mesh-gateway/service-to-service-traffic-wan-datacenters) -To use mesh gateways, TLS must be enabled in your cluster. Refer to the [requirements section](#requirements) for additional information. +To use mesh gateways, TLS must be enabled in your cluster. Refer to the [requirements section](#requirements) for additional information. 1. Add a `module` block to your Terraform configuration file and specify a label. The label is a unique identifier for the gateway. 1. Add a `source` to the `module` and specify the location of the `gateway-task`. The value must be `hashicorp/consul-ecs/aws//modules/gateway-task`. 1. Specify the following required inputs: - - `ecs_cluster_arn`: The ARN of the ECS cluster for the gateway. + - `ecs_cluster_arn`: The ARN of the ECS cluster for the gateway. - `family`: Specifies a name for multiple versions of the task. Refer to the [AWS documentation](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#family) for details. - `kind`: Set to `mesh-gateway` - `subnets`: Specifies a list of subnet IDs where the gateway task should be deployed. @@ -200,9 +200,9 @@ Refer to [gateway-task module in the Terraform registry](https://registry.terraf Refer to the [gateway task configuration examples](#gateway-task-configuration-examples) for additional example configurations. -## Configure the ECS controller +## Configure the ECS controller -Deploy the ECS controller container to its own ECS task in the cluster. Refer to [ECS controller container](/consul/docs/ecs/reference/architecture#ecs-controller) for details about the container. +Deploy the ECS controller container to its own ECS task in the cluster. Refer to [ECS controller container](/consul/docs/ecs/reference/architecture#ecs-controller) for details about the container. Verify that you have completed the prerequisites described in [Secure configuration requirements](#secure-configuration-requirements) and complete the following steps to configure the controller container. @@ -211,16 +211,16 @@ Verify that you have completed the prerequisites described in [Secure configurat 1. On the Consul server, create a policy that grants the following access for the controller: - `acl:write` - - `operator:write` + - `operator:write` - `node:write` - `service:write` - + The policy allows Consul to generate a token linked to the policy. Refer to [Create a service token](/consul/docs/security/acl/tokens/create/create-a-service-token) for instructions. 1. Create a token and link it to the ACL controller policy. Refer to the [ACL tokens documentation](/consul/docs/security/acl/tokens) for instructions. ### Configure an AWS secrets manager secret -Add the `aws_secretsmanager_secret` resource to your Terraform configuration and specify values for retrieving the CA and TLS certificates. The resource enables services to communicate over TLS and present ACL tokens. The ECS controller also uses the secret manager to retrieve the value of the bootstrap token. +Add the `aws_secretsmanager_secret` resource to your Terraform configuration and specify values for retrieving the CA and TLS certificates. The resource enables services to communicate over TLS and present ACL tokens. The ECS controller also uses the secret manager to retrieve the value of the bootstrap token. In the following example, Terraform creates the CA certificates for gRPC and HTTPS in the secrets manager. Consul retrieves the CA certificate PEM file from the secret manager so that the mesh task can use TLS for HTTP and gRPC traffic: @@ -375,7 +375,7 @@ Terraform reads all files in the current directory that have a `.tf` file extens Refer to the [Terraform documentation](/terraform/docs) for more information and Terraform best practices. ## Next steps - + After deploying the Consul service mesh infrastructure, you must still define routes between service instances as well as configure the bind address for your applications so that they only receive traffic through the mesh. Refer to the following topics: - [Configure routes between ECS tasks](/consul/docs/ecs/deploy/configure-routes) diff --git a/website/content/docs/ecs/reference/consul-server-json.mdx b/website/content/docs/ecs/reference/consul-server-json.mdx index 30e41c207f..87401bbb2d 100644 --- a/website/content/docs/ecs/reference/consul-server-json.mdx +++ b/website/content/docs/ecs/reference/consul-server-json.mdx @@ -6,25 +6,25 @@ description: Learn about the fields available in the JSON scheme for configuring # Consul server configuration JSON schema reference -This topic provides reference information about the JSON schema used to build the `config.tf` file. Refer to [Configure Consul server settings](/consul/docs/ecs/deploy/terraform#configure-consul-server-settings) for information about how Consul on ECS uses the JSON schema. +This topic provides reference information about the JSON schema used to build the `config.tf` file. Refer to [Configure Consul server settings](/consul/docs/ecs/deploy/terraform#configure-consul-server-settings) for information about how Consul on ECS uses the JSON schema. ## Configuration model The following list describes the attributes, data types, and default values, if any, in the `config.tf` file. Click on a value to learn more about the attribute. -- [`consulServers`](#consulservers): map +- [`consulServers`](#consulservers): map - [`hosts`](#consulservers-hosts): string - [`skipServerWatch`](#consulservers-hosts): boolean | `false` - - [`defaults`](#consulservers-defaults): map - - [`caCertFile`](#consulservers-defaults): string - - [`tlsServerName`](#consulservers-defaults): string + - [`defaults`](#consulservers-defaults): map + - [`caCertFile`](#consulservers-defaults): string + - [`tlsServerName`](#consulservers-defaults): string - [`tls`](#consulservers-defaults): boolean | `false` - - [`grpc`](#consulservers-grpc): map - - [`port`](#consulservers-grpc): number - - [`caCertFile`](#consulservers-grpc): string - - [`tlsServerName`](#consulservers-grpc): string + - [`grpc`](#consulservers-grpc): map + - [`port`](#consulservers-grpc): number + - [`caCertFile`](#consulservers-grpc): string + - [`tlsServerName`](#consulservers-grpc): string - [`tls`](#consulservers-grpc): boolean | `false` - - [`http`](#consulservers-http): map + - [`http`](#consulservers-http): map - [`https`](#consulservers-http): boolean | `false` - [`port`](#consulservers-http): number - [`caCertFile`](#consulservers-http): string @@ -33,11 +33,11 @@ The following list describes the attributes, data types, and default values, if ## Specification -This section provides details about the attribes in the `config.tf` file. +This section provides details about the attributes in the `config.tf` file. ### `consulServers` -Parent-level attribute containing all of the server configurations. All other configuraitons in the file are children of the `consulServers` attribute. +Parent-level attribute containing all of the server configurations. All other configurations in the file are children of the `consulServers` attribute. #### Values @@ -47,7 +47,7 @@ Parent-level attribute containing all of the server configurations. All other co ### `consulServers.hosts` -Map that contains the `skipServerWatch` configuration for Consul server hosts. +Map that contains the `skipServerWatch` configuration for Consul server hosts. #### Values @@ -56,7 +56,7 @@ Map that contains the `skipServerWatch` configuration for Consul server hosts. ### `consulServers.hosts.skipServerWatch` -Boolean that disables watches on the Consul server. Set to `true` if the Consul server is already behind a load balancer. +Boolean that disables watches on the Consul server. Set to `true` if the Consul server is already behind a load balancer. #### Values @@ -65,7 +65,7 @@ Boolean that disables watches on the Consul server. Set to `true` if the Consul ### `consulServers.defaults` -Map of default server configurations. Defaults apply to gRPC and HTTP traffic. +Map of default server configurations. Defaults apply to gRPC and HTTP traffic. #### Values @@ -83,7 +83,7 @@ The following table describes the attributes available in the `defaults` configu ### `consulServers.grpc` -Map of server configuration for gRPC traffic that override attributes defined in `consulServers.defaults`. +Map of server configuration for gRPC traffic that override attributes defined in `consulServers.defaults`. #### Values @@ -101,7 +101,7 @@ The following table describes the attributes available in the `grpc` configurati ### `consulServers.http` -Map of server configuration for HTTP traffic that override attributes defined in `consulServers.defaults`. +Map of server configuration for HTTP traffic that override attributes defined in `consulServers.defaults`. #### Values diff --git a/website/content/docs/install/ports.mdx b/website/content/docs/install/ports.mdx index 3305fac86c..39cfea2ae9 100644 --- a/website/content/docs/install/ports.mdx +++ b/website/content/docs/install/ports.mdx @@ -47,7 +47,7 @@ The server's DNS port does not need to be open when DNS queries are sent to Cons If you configure recursors in Consul to upstream DNS servers, then you need outbound access to those servers on port `53`. -To resolve Consul DNS requests when using HCP Consul Dedicated, we recommend running Consul clients and resolving DNS against the clients. If your use case cannot accomodate this recommendation, open a support ticket. +To resolve Consul DNS requests when using HCP Consul Dedicated, we recommend running Consul clients and resolving DNS against the clients. If your use case cannot accommodate this recommendation, open a support ticket. ### HTTP diff --git a/website/content/docs/k8s/deployment-configurations/datadog.mdx b/website/content/docs/k8s/deployment-configurations/datadog.mdx index cc627cb59b..c3df799f4d 100644 --- a/website/content/docs/k8s/deployment-configurations/datadog.mdx +++ b/website/content/docs/k8s/deployment-configurations/datadog.mdx @@ -465,4 +465,4 @@ Use of this method maps to Datadog as described in [Mapping Prometheus Metrics t The integration, by default, uses a wildcard (`".*"`) to collect **_all_** metrics emitted from the `/v1/agent/metrics` endpoint. -Please refer to the [Agent Telemetry](https://developer.hashicorp.com/consul/docs/agent/telemetry) documentation for a full list and desription of the metrics data collected. +Please refer to the [Agent Telemetry](https://developer.hashicorp.com/consul/docs/agent/telemetry) documentation for a full list and description of the metrics data collected. diff --git a/website/content/docs/k8s/multiport/reference/grpcroute.mdx b/website/content/docs/k8s/multiport/reference/grpcroute.mdx index 1a8910c5b7..f76f758855 100644 --- a/website/content/docs/k8s/multiport/reference/grpcroute.mdx +++ b/website/content/docs/k8s/multiport/reference/grpcroute.mdx @@ -86,7 +86,7 @@ The following list outlines field hierarchy, language-specific data types, and r When every field is defined, a gRPC route resource CRD has the following form: ```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 # required +apiVersion: mesh.consul.hashicorp.com/v2beta1 # required kind: GRPCRoute # required metadata: name: @@ -96,7 +96,7 @@ spec: port: - ref: name: - type: + type: group: groupVersion: kind: @@ -128,7 +128,7 @@ spec: remove: name: value: - responseHeaderModifier: + responseHeaderModifier: add: name: value: @@ -269,7 +269,7 @@ Specifies the type of resource that the configuration applies to. To reference a | Parameter | Description | Data type | Default | | :------------ | :------------------------------------------------------------------- | :-------- | :------- | | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | ### `spec.rules` @@ -353,7 +353,7 @@ Specifies the type of resource that the configuration routes traffic to. To refe | Parameter | Description | Data type | Default | | --- | --- | --- | --- | | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | ### `spec.rules.backendRefs.filters` @@ -428,9 +428,9 @@ Specifies a path to modify the URL with when a request is forwarded. ### `spec.rules.backendRefs.weight` -Specifies the proportion of requests routed to the specified service. +Specifies the proportion of requests routed to the specified service. -This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. +This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. When this parameter is not specified, Consul defaults to `1`. @@ -634,7 +634,7 @@ Specifies Envoy conditions that cause an automatic retry attempt. - Default: None - Data type: Map of strings -### `spec.rules.retries.onConnnectFailure` +### `spec.rules.retries.onConnectFailure` Enables an automatic retry attempt when a connection failure error occurs. @@ -700,7 +700,7 @@ metadata: spec: parentRefs: - ref: - type: + type: group: catalog groupVersion: v2beta1 kind: Service @@ -710,7 +710,7 @@ spec: rules: - backendRefs: - backendRef: - ref: + ref: type: group: catalog groupVersion: v2beta1 @@ -720,7 +720,7 @@ spec: port: "80" weight: 50 - backendRef: - ref: + ref: type: group: catalog groupVersion: v2beta1 @@ -749,7 +749,7 @@ metadata: spec: parentRefs: - ref: - type: + type: group: catalog groupVersion: v2beta1 kind: Service @@ -805,4 +805,4 @@ spec: name: api-admin # The virtual port number for the "admin-workload" target port. port: "90" -``` \ No newline at end of file +``` diff --git a/website/content/docs/k8s/multiport/reference/httproute.mdx b/website/content/docs/k8s/multiport/reference/httproute.mdx index f739ecba84..434fea9032 100644 --- a/website/content/docs/k8s/multiport/reference/httproute.mdx +++ b/website/content/docs/k8s/multiport/reference/httproute.mdx @@ -90,7 +90,7 @@ The following list outlines field hierarchy, language-specific data types, and r When every field is defined, an HTTP route CRD has the following form: ```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 # required +apiVersion: mesh.consul.hashicorp.com/v2beta1 # required kind: HTTPRoute # required metadata: name: @@ -100,7 +100,7 @@ spec: port: - ref: name: - type: + type: group: groupVersion: kind: @@ -132,10 +132,10 @@ spec: remove: name: value: - responseHeaderModifier: + responseHeaderModifier: add: name: - value: + value: urlRewrite: pathPrefix: matches: @@ -144,7 +144,7 @@ spec: type: value: method: - path: + path: type: value: / queryParams: @@ -277,7 +277,7 @@ Specifies the type of resource that the configuration applies to. To reference a | Parameter | Description | Data type | Default | | :------------ | :------------------------------------------------------------------- | :-------- | :------- | | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | ### `spec.rules` @@ -360,7 +360,7 @@ Specifies the type of resource that the configuration routes traffic to. To refe | Parameter | Description | Data type | Default | | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | ### `spec.rules.backendRefs.filters` @@ -435,9 +435,9 @@ Specifies a path to modify the URL with when a request is forwarded. ### `spec.rules.backendRefs.weight` -Specifies the proportion of requests routed to the specified service. +Specifies the proportion of requests routed to the specified service. -This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. +This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. When this parameter is not specified, Consul defaults to `1`. @@ -687,7 +687,7 @@ Specifies Envoy conditions that cause an automatic retry attempt. - Default: None - Data type: Map of strings -### `spec.rules.retries.onConnnectFailure` +### `spec.rules.retries.onConnectFailure` Enables an automatic retry attempt when a connection failure error occurs. @@ -753,7 +753,7 @@ metadata: spec: parentRefs: - ref: - type: + type: group: catalog groupVersion: v2beta1 kind: Service @@ -763,7 +763,7 @@ spec: rules: - backendRefs: - backendRef: - ref: + ref: type: group: catalog groupVersion: v2beta1 @@ -773,7 +773,7 @@ spec: port: "80" weight: 50 - backendRef: - ref: + ref: type: group: catalog groupVersion: v2beta1 @@ -802,7 +802,7 @@ metadata: spec: parentRefs: - ref: - type: + type: group: catalog groupVersion: v2beta1 kind: Service @@ -876,7 +876,7 @@ metadata: spec: parentRefs: - ref: - type: + type: group: catalog groupVersion: v2beta1 kind: Service @@ -922,4 +922,4 @@ spec: name: api-admin # The virtual port number for the "admin-workload" target port. port: "90" -``` \ No newline at end of file +``` diff --git a/website/content/docs/k8s/multiport/reference/tcproute.mdx b/website/content/docs/k8s/multiport/reference/tcproute.mdx index dcf96517f7..b9cda7a7b4 100644 --- a/website/content/docs/k8s/multiport/reference/tcproute.mdx +++ b/website/content/docs/k8s/multiport/reference/tcproute.mdx @@ -53,7 +53,7 @@ The following list outlines field hierarchy, language-specific data types, and r When every field is defined, a TCP route CRD has the following form: ```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 # required +apiVersion: mesh.consul.hashicorp.com/v2beta1 # required kind: TCPRoute # required metadata: name: @@ -63,7 +63,7 @@ spec: port: - ref: name: - type: + type: group: groupVersion: kind: @@ -196,7 +196,7 @@ Specifies the type of resource that the configuration applies to. To reference a | Parameter | Description | Data type | Default | | :------------ | :------------------------------------------------------------------- | :-------- | :------- | | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | ### `spec.rules` @@ -280,14 +280,14 @@ Specifies the type of resource that the configuration routes traffic to. To refe | Parameter | Description | Data type | Default | | :------------ | :------------------------------------------------------------------- | :-------- | :------- | | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | ### `spec.rules.backendRefs.weight` -Specifies the proportion of requests routed to the specified service. +Specifies the proportion of requests routed to the specified service. -This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. +This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. When this parameter is not specified, Consul defaults to `1`. @@ -313,7 +313,7 @@ metadata: spec: parentRefs: - ref: - type: + type: group: catalog groupVersion: v2beta1 kind: Service @@ -323,7 +323,7 @@ spec: rules: - backendRefs: - backendRef: - ref: + ref: type: group: catalog groupVersion: v2beta1 @@ -333,7 +333,7 @@ spec: port: "80" weight: 50 - backendRef: - ref: + ref: type: group: catalog groupVersion: v2beta1 @@ -342,4 +342,4 @@ spec: # The virtual port number for the "admin-workload" target port. port: "90" weight: 50 -``` \ No newline at end of file +``` diff --git a/website/content/docs/release-notes/consul/v1_18_x.mdx b/website/content/docs/release-notes/consul/v1_18_x.mdx index e419118f42..24c23d0608 100644 --- a/website/content/docs/release-notes/consul/v1_18_x.mdx +++ b/website/content/docs/release-notes/consul/v1_18_x.mdx @@ -11,11 +11,11 @@ We are pleased to announce the following Consul updates. ## Release highlights -- **Consul v2 Catalog API and Traffic Permission API updates:** Additional improvements were made to the v2 catalog API, which enables support for [multi-port services on Kubernetes](/consul/docs/k8s/multiport). End user facing changes include the ability to use a service's ports in xRoute configurations as opposed to the workload port for reference in the parentRef stanza of the xRoute configuration. In addition, the Traffic Permissions API was changed to only allow `ACTION_DENY` for Consul Enterprise as it will enable future governance related workflows. +- **Consul v2 Catalog API and Traffic Permission API updates:** Additional improvements were made to the v2 catalog API, which enables support for [multi-port services on Kubernetes](/consul/docs/k8s/multiport). End user facing changes include the ability to use a service's ports in xRoute configurations as opposed to the workload port for reference in the parentRef stanza of the xRoute configuration. In addition, the Traffic Permissions API was changed to only allow `ACTION_DENY` for Consul Enterprise as it will enable future governance related workflows. The v2 Catalog API is currently available for Consul on Kubernetes deployments only. Refer to [Consul v2 architecture](/consul/docs/architecture/v2) for more information. - The v2 Catalog API and the Traffic Permssions API are in beta and under active development, so we do not recommend using them in production. + The v2 Catalog API and the Traffic Permissions API are in beta and under active development, so we do not recommend using them in production. - **Consul Long Term Support (LTS) (Enterprise):** Consul Enterprise users can now receive Long Term Support for approximately 2 years on some Consul releases, starting with Consul Enterprise v1.15. During the LTS window, eligible fixes are provided through a new minor release on the affected LTS release branch. @@ -37,7 +37,7 @@ We are pleased to announce the following Consul updates. Refer to [transparent proxy overview](/consul/docs/k8s/connect/transparent-proxy) and [Consul on ECS overview](/consul/docs/ecs) for more information. -- **Downgrade from Consul Enterprise to Consul Community Edition**: Consul now provides the ability for enterprise users to migrate their deployments to Community edition and disable enterprise features for business continuity. Refer to [Downgrade from Consul Enterprise to the community edition](/consul/docs/enterprise/ent-to-ce-downgrades) for more information. +- **Downgrade from Consul Enterprise to Consul Community Edition**: Consul now provides the ability for enterprise users to migrate their deployments to Community edition and disable enterprise features for business continuity. Refer to [Downgrade from Consul Enterprise to the community edition](/consul/docs/enterprise/ent-to-ce-downgrades) for more information. - **Consul Snapshot Agent support for multiple destinations (Enterprise):** Consul Enterprise users can now specify [multiple local and remote destinations](/consul/commands/snapshot/agent) for Consul snapshot backups. diff --git a/website/content/docs/security/acl/acl-roles.mdx b/website/content/docs/security/acl/acl-roles.mdx index 5812703831..834e433349 100644 --- a/website/content/docs/security/acl/acl-roles.mdx +++ b/website/content/docs/security/acl/acl-roles.mdx @@ -62,7 +62,7 @@ Roles may contain the following attributes: - `Name`: A unique meaningful name for the role. You can specify the role `Name` when linking it to tokens. - `Description`: (Optional) A human-readable description of the role. - `Policies`: Specifies a the list of policies that are applicable for the role. The object can reference the policy `ID` or `Name` attribute. -- `TemplatedPolicies`: Specifies a list of templated polcicies that are applicable for the role. See [Templated Policies](#templated-policies) for details. +- `TemplatedPolicies`: Specifies a list of templated policies that are applicable for the role. See [Templated Policies](#templated-policies) for details. - `ServiceIdentities`: Specifies a list of services that are applicable for the role. See [Service Identities](#service-identities) for details. - `NodeIdentities`: Specifies a list of nodes that are applicable for the role. See [Node Identities](#node-identities) for details. - `Namespace`: The namespace that the policy resides in. Roles can only be linked to policies that are defined in the same namespace. See [Namespaces](/consul/docs/enterprise/namespaces) for additional information. Requires Consul Enterprise 1.7.0+ @@ -72,7 +72,7 @@ Roles may contain the following attributes: You can specify a templated policy when configuring roles or linking tokens to policies. Templated policies enable you to quickly construct policies for common Consul use cases, rather than creating identical policies for each use cases. -Consul uses templated policies during the authorization process to automatically generate a policy for the use case specified. Consul links the generated policy to the role or token so that it will have permission for the specific use case. +Consul uses templated policies during the authorization process to automatically generate a policy for the use case specified. Consul links the generated policy to the role or token so that it will have permission for the specific use case. ### Templated policy specification @@ -398,4 +398,4 @@ service_prefix "" { } ``` - \ No newline at end of file + diff --git a/website/content/docs/security/acl/acl-rules.mdx b/website/content/docs/security/acl/acl-rules.mdx index 24f6069c08..3503b589b9 100644 --- a/website/content/docs/security/acl/acl-rules.mdx +++ b/website/content/docs/security/acl/acl-rules.mdx @@ -638,7 +638,7 @@ Read access to all imported nodes is granted when either of the following rule s - `service:write` is granted to any service. - `node:read` is granted to all nodes. -For Consul Enterprise, either set of rules must be scoped to the requesting services's partition and at least one namespace. +For Consul Enterprise, either set of rules must be scoped to the requesting service's partition and at least one namespace. You may need similarly scoped [Service Rules](#reading-imported-services) to read Consul data, depending on the endpoint (e.g. `/v1/health/service/:name`). These permissions are satisfied when using a [service identity](/consul/docs/security/acl/acl-roles#service-identities). @@ -877,7 +877,7 @@ Read access to all imported services is granted when either of the following rul - `service:write` is granted to any service. - `service:read` is granted to all services. -For Consul Enterprise, either set of rules must be scoped to the requesting services's partition and at least one namespace. +For Consul Enterprise, either set of rules must be scoped to the requesting service's partition and at least one namespace. You may need similarly scoped [Node Rules](#reading-imported-nodes) to read Consul data, depending on the endpoint (e.g. `/v1/health/service/:name`). These permissions are satisfied when using a [service identity](/consul/docs/security/acl/acl-roles#service-identities). From 574f53d1763af70763fb44811a3e7ac8301f2a2a Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Thu, 23 May 2024 13:40:59 -0400 Subject: [PATCH 043/185] security: enable go stdlib scans (#20905) * security: enable go stdlib scans * security: enable go stdlib binary scan * Fix formating --- .release/security-scan.hcl | 1 + scan.hcl | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 8401764bc4..88b2c88117 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -56,6 +56,7 @@ container { binary { go_modules = true osv = true + go_stdlib = true # We can't enable npm for binary targets today because we don't yet embed the relevant file # (yarn.lock) in the Consul binary. This is something we may investigate in the future. diff --git a/scan.hcl b/scan.hcl index 82888d3be8..b0a1b924b4 100644 --- a/scan.hcl +++ b/scan.hcl @@ -15,9 +15,10 @@ # unlike the scans configured here, will block releases in CRT. repository { - go_modules = true - npm = true - osv = true + go_modules = true + npm = true + osv = true + go_stdlib_version_file = ".go-version" secrets { all = true From 912c5f5a3c73f434df2e4e8db4ef5ac05d091808 Mon Sep 17 00:00:00 2001 From: Krastin Krastev Date: Fri, 24 May 2024 14:29:22 +0200 Subject: [PATCH 044/185] docs: relocate Consul capacity planning page from waf/ to docs/ (#21088) * moving tutorials/waf/capacity-planning to docs/ * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * add metrics bullet links --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- .../docs/architecture/capacity-planning.mdx | 188 ++++++++++++++++++ website/data/docs-nav-data.json | 4 + 2 files changed, 192 insertions(+) create mode 100644 website/content/docs/architecture/capacity-planning.mdx diff --git a/website/content/docs/architecture/capacity-planning.mdx b/website/content/docs/architecture/capacity-planning.mdx new file mode 100644 index 0000000000..2f80c4cf28 --- /dev/null +++ b/website/content/docs/architecture/capacity-planning.mdx @@ -0,0 +1,188 @@ +--- +layout: docs +page_title: Consul capacity planning +description: >- + Learn how to maintain your Consul cluster in a healthy state by provisioning the correct resources. +--- + +# Consul capacity planning + +This page describes our capacity planning recommendations when deploying and maintaining a Consul cluster in production. When your organization designs a production environment, you should consider your available resources and their impact on network capacity. + +## Introduction + +It is important to select the correct size for your server instances. Consul server environments have a standard set of minimum requirements. However, these requirements may vary depending on what you are using Consul for. + +Insufficient resource allocations may cause network issues or degraded performance in general. When a slowdown in performance results in a Consul leader node that is unable to respond to requests in sufficient time, the Consul cluster triggers a new leader election. Consul pauses all network requests and Raft updates until the election ends. + +## Hardware requirements + +The minimum hardware requirements for Consul servers in production clusters as recommended by the [reference architecture](/consul/tutorials/production-deploy/reference-architecture#hardware-sizing-for-consul-servers) are: + +| CPU | Memory | Disk Capacity | Disk IO | Disk Throughput | Avg Round-Trip-Time | 99% Round-Trip-Time | +| --------- | ------------ | ------------- | ----------- | --------------- | ------------------- | ------------------- | +| 8-16 core | 32-64 GB RAM | 200+ GB | 7500+ IOPS | 250+ MB/s | Lower than 50ms | Lower than 100ms | + +For the major cloud providers, we recommend starting with one of the following instances that meet the minimum requirements. Then scale up as needed. We also recommend avoiding "burstable" CPU and storage options where performance may drop after a consistent load. + +| Provider | Size | Instance/VM Types | Disk Volume Specs | +| --------- | ----- | ------------------------------------- | --------------------------------- | +| **AWS** | Large | `m5.2xlarge`, `m5.4xlarge` | 200+GB `gp3`, 10000 IOPS, 250MB/s | +| **Azure** | Large | `Standard_D8s_v3`, `Standard_D16s_v3` | 2048GB `Premium SSD`, 7500 IOPS, 200MB/s | +| **GCP** | Large | `n2-standard-8`, `n2-standard-16` | 1000GB `pd-ssd`, 30000 IOPS, 480MB/s | + + +For HCP Consul Dedicated, cluster size is measured in the number of service instances supported. Find out more information in the [HCP Consul Dedicated pricing page](https://cloud.hashicorp.com/products/consul/pricing). + +## Workload input and output requirements + +Workloads are any actions that interact with the Consul cluster. These actions consist of key/value reads and writes, service registrations and deregistrations, adding or removing Consul client agents, and more. + +Input/output operations per second (IOPS) is a unit of measurement for the amount of reads and writes to non-adjacent storage locations. +For high workloads, ensure that the Consul server disks support a [high number of IOPS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-io-characteristics.html#ebs-io-iops) to keep up with the rapid Raft log update rate. +Unlike bare-metal environments, IOPS for virtual instances in cloud environments is often tied to storage sizing. More storage GBs typically grants you more IOPS. Therefore, we recommend deploying on [IOPS-optimized instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/provisioned-iops.html). + +Consul server agents are generally I/O bound for writes and CPU bound for reads. For additional tuning recommendations, refer to [raft tuning](#raft-tuning). + +## Memory requirements + +You should allocate RAM for server agents so that they contain 2 to 4 times the working set size. You can determine the working set size of a running cluster by noting the value of `consul.runtime.alloc_bytes` in the leader node's telemetry data. Inspect your monitoring solution for the telemetry value, or run the following commands with the [jq](https://stedolan.github.io/jq/download/) tool installed on your Consul leader instance. + + + +For Kubernetes, execute the command from the leader pod. `jq` is available in the Consul server containers. + + + +Set `$CONSUL_HTTP_TOKEN` to an ACL token with valid permissions, then retrieve the working set size. + +```shell-session +$ curl --silent --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" http://127.0.0.1:8500/v1/agent/metrics | jq '.Gauges[] | select(.Name=="consul.runtime.alloc_bytes") | .Value'` +616017920 +``` + +## Kubernetes storage requirements + +When you set up persistent volumes (PV) resources, you should define the correct server storage class parameter because the defaults are likely insufficient in performance. To set the [storageClass Helm chart parameter](/consul/docs/k8s/helm#v-server-storageclass), refer to the [Kubernetes documentation on storageClasses](https://kubernetes.io/docs/concepts/storage/storage-classes/) for more information about your specific cloud provider. + +## Read and write heavy workload recommendations + +In production, your use case may lead to Consul performing read-heavy workloads, write-heavy workloads, or both. Refer to the following table for specific resource recommendations for these types of workloads. + +| Workload type | Instance Recommendations | Workload element examples | Enterprise Feature Recommendations | +| ------------- | ------------------------- | ------------------------ | ------------------------ | +| Read-heavy | Instances of type `m5.4xlarge (AWS)`, `Standard_D16s_v3 (Azure)`, `n2-standard-16 (GCP)` | Raft RPCs calls, DNS queries, key/value retrieval | [Read replicas](/consul/docs/enterprise/read-scale) | +| Write-heavy | IOPS performance of `10 000+` | Consul agent joins and leaves, services registration and deregistration, key/value writes | [Network segments](/consul/docs/enterprise/network-segments/network-segments-overview) | + +For recommendations on troubleshooting issues with read-heavy or write-heavy workloads, refer to [Consul at Scale](/consul/docs/architecture/scale#resource-usage-and-metrics-recommendations). + +## Monitor performance + +Monitoring is critical to ensure that your Consul datacenter has sufficient resources to continue operations. A proactive monitoring strategy helps you find problems in your network before they impact your deployments. + +We recommend completing the [Monitor Consul server health and performance with metrics and logs](/consul/tutorials/observe-your-network/server-metrics-and-logs) tutorial as a starting point for Consul metrics and telemetry. The following tutorials guide you through specific monitoring solutions for your Consul cluster. + +- [Monitor Consul server health and performance with metrics and logs](/consul/tutorials/observe-your-network/server-metrics-and-logs) +- [Observe Consul service mesh traffic](/consul/tutorials/get-started-kubernetes/kubernetes-gs-observability) + +### Important metrics + +In production environments, create baselines for your Consul cluster's metrics. After you discover the baselines, you will be able to define alerts and receive notifications when there are unexpected values. For a detailed explanation on the metrics and their values, refer to [Consul Agent telemetry](/consul/docs/agent/telemetry). + +### Transaction metrics + +These metrics indicate how long it takes to complete write operations in various parts of the Consul cluster. + +- [`consul.kvs.apply`](/consul/docs/agent/monitor/telemetry#transaction-timing) measures the time it takes to complete an update to the KV store. +- [`consul.txn.apply`](/consul/docs/agent/monitor/telemetry#transaction-timing) measures the time spent applying a transaction operation. +- [`consul.raft.apply`](/consul/docs/agent/monitor/telemetry#transaction-timing) counts the number of Raft transactions applied during the measurement interval. This metric is only reported on the leader. +- [`consul.raft.commitTime`](/consul/docs/agent/monitor/telemetry#transaction-timing) measures the time it takes to commit a new entry to the Raft log on disk on the leader. + +### Memory metrics + +These performance indicators can help you diagnose if the current instance sizing is unable to handle the workload. + +- [`consul.runtime.alloc_bytes`](/consul/docs/agent/monitor/telemetry#memory-usage) measures the number of bytes allocated by the Consul process. +- [`consul.runtime.sys_bytes`](/consul/docs/agent/monitor/telemetry#memory-usage) measures the total number of bytes of memory obtained from the OS. +- [`consul.runtime.heap_objects`](/consul/docs/agent/monitor/telemetry#metrics-reference) measures the number of objects allocated on the heap and is a general memory pressure indicator. + +### Leadership metrics + +Leadership changes are not a cause for concern but frequent changes may be a symptom of a deeper problem. Frequent elections or leadership changes may indicate network issues between the Consul servers, or the Consul servers are unable to keep up with the load. + +- [`consul.raft.leader.lastContact`](/consul/docs/agent/monitor/telemetry#leadership-changes) measures the time since the leader was last able to contact the follower nodes when checking its leader lease. +- [`consul.raft.state.candidate`](/consul/docs/agent/monitor/telemetry#leadership-changes) increments whenever a Consul server starts an election. +- [`consul.raft.state.leader`](/consul/docs/agent/monitor/telemetry#leadership-changes) increments whenever a Consul server becomes a leader. +- [`consul.server.isLeader`](/consul/docs/agent/monitor/telemetry#leadership-changes) tracks whether a server is a leader. + +### Network metrics + +Network activity and RPC count measurements indicate the current load created from a Consul agent, including when the load becomes high enough to be rate limited. If an unusually high RPC count occurs, you should investigate before it overloads the cluster. + +- [`consul.client.rpc`](/consul/docs/agent/monitor/telemetry#network-activity-rpc-count) increments whenever a Consul agent in client mode makes an RPC request to a Consul server. +- [`consul.client.rpc.exceeded`](/consul/docs/agent/monitor/telemetry#network-activity-rpc-count) 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. +- [`consul.client.rpc.failed`](/consul/docs/agent/monitor/telemetry#network-activity-rpc-count) increments whenever a Consul agent in client mode makes an RPC request to a Consul server and fails. + +## Network constraints and alternate approaches + +If it is impossible for you to allocate the required resources, you can make changes to Consul's performance so that it operates with lower speed or resilience. These changes ensure that your cluster remains within its resource capacity. + +- Soft limits prevent your cluster from degrading due to overload. +- Raft tuning lets you compensate for unfavorable environments. + +### Soft limits + +The recommended maximum size for a single datacenter is 5,000 Consul client agents. This recommendation is based on a standard, non-tuned environment and considers a blast radius's risk management factor. The maximum number of agents may be lower, depending on how you use Consul. + +If you require more than 5,000 client agents, you should break up the single Consul datacenter into multiple smaller datacenters. + +- When the nodes are spread across separate physical locations such as different regions, you can model multiple datacenter structures based on physical locations. +- Use [network segments](/consul/docs/enterprise/network-segments/network-segments-overview) in a single available zone or region to lower overall resource usage in a single datacenter. + +When deploying [Consul in Kubernetes](/consul/docs/k8s), we recommend you set both _requests_ and _limits_ in the Helm chart. Refer to the [Helm chart documentation](/consul/docs/k8s/helm#v-server-resources) for more information. + +- Requests allocate the required resources for your Consul workloads. +- Limits prevent your pods from being terminated and restarted if they consume more resources than requested and Kubernetes needs to reclaim these resources. Limits can prevent outage situations where the Consul leader's container gets terminated and redeployed due to resource constraints. + +The following is an example Helm configuration that allocates 16 CPU cores and 64 gigabytes of memory: + + + +```yaml +global: + image: "hashicorp/consul" +## ... +resources: + requests: + memory: '64G' + cpu: '16000m' + limits: + memory: '64G' + cpu: '16000m' +``` + + + +### Raft tuning + +Consul uses the [Raft consensus algorithm](/consul/docs/architecture/consensus) to provide consistency. +You may need to adjust Raft to suit your specific environment. Adjust the [`raft_multiplier` configuration](/consul/docs/agent/config/config-files#raft_multiplier) to define the trade-off between leader stability and time to recover from a leader failure. + +- A lower multiplier minimizes failure detection and election time, but it may trigger frequently in high latency situations. +- A higher multiplier reduces the chances that failures cause leadership churn, but your cluster takes longer to detect real failures and restore availability. + +The value of `raft_multiplier` has a default value of 5. It is a scaling factor setting that directly affects the following parameters: + +| Parameter name | Default value | Derived from | +| --- | --- | --- | +| HeartbeatTimeout | 5000ms | 5 x 1000ms | +| ElectionTimeout | 5000ms | 5 x 1000ms | +| LeaderLeaseTimeout | 2500ms | 5 x 500ms | + +You can use the telemetry from [`consul.raft.leader.lastContact`](/consul/docs/agent/telemetry#leadership-changes) to observe Raft timing performance. + +Wide networks with more latency perform better with larger values of `raft_multiplier`, but cluster failure detection will take longer. If your network operates with low latency, we recommend that you do not set the Raft multiplier higher than 5. Instead, you should either replace the servers with more powerful ones or minimize the network latency between nodes. + +We recommend you start from a baseline and perform [chaos engineering testing](/consul/tutorials/resiliency/introduction-chaos-engineering?in=consul%2Fresiliency) with different values for the Raft multiplier to find the acceptable time for problem detection and recovery for the cluster. Then scale the cluster and its dedicated resources with the number of workloads handled. This approach gives you the best balance between pure resource growth and pure Raft tuning strategies because it lets you use Raft tuning as a backup plan if you cannot scale your resources. + +The types of workloads the Consul cluster handles also play an important role in Raft tuning. For example, if your Consul clusters are mostly static and do not handle many events, you should increase your Raft multiplier instead of scaling your resources because the risk of an important event happening while the cluster is converging or re-electing a leader is lower. diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 3d4000811d..7a8c32c4c7 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -150,6 +150,10 @@ { "title": "Consul at Scale", "path": "architecture/scale" + }, + { + "title": "Consul Capacity Planning", + "path": "architecture/capacity-planning" } ] }, From cf1c030043e877de3b6f6714c7c13fb2dd11d6ab Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 24 May 2024 13:26:07 -0400 Subject: [PATCH 045/185] feat: update supported envoy to 1.29 (#21142) --- .changelog/21142.txt | 3 + .../nightly-test-integ-peering_commontopo.yml | 2 +- .../workflows/nightly-test-integrations.yml | 10 +- .../workflows/test-integrations-windows.yml | 1219 ----------------- .github/workflows/test-integrations.yml | 6 +- Makefile | 2 +- .../xdscommon/envoy_versioning_test.go | 2 +- envoyextensions/xdscommon/proxysupport.go | 2 +- test/integration/connect/envoy/run-tests.sh | 2 +- .../content/docs/connect/proxies/envoy.mdx | 2 + 10 files changed, 18 insertions(+), 1232 deletions(-) create mode 100644 .changelog/21142.txt delete mode 100644 .github/workflows/test-integrations-windows.yml diff --git a/.changelog/21142.txt b/.changelog/21142.txt new file mode 100644 index 0000000000..6119fb2674 --- /dev/null +++ b/.changelog/21142.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +mesh: update supported envoy version 1.29.4 in addition to 1.28.3, 1.27.5, 1.26.8. +``` \ No newline at end of file diff --git a/.github/workflows/nightly-test-integ-peering_commontopo.yml b/.github/workflows/nightly-test-integ-peering_commontopo.yml index ab6554dc12..3d407a7c3c 100644 --- a/.github/workflows/nightly-test-integ-peering_commontopo.yml +++ b/.github/workflows/nightly-test-integ-peering_commontopo.yml @@ -62,7 +62,7 @@ jobs: name: '${{matrix.test-case}}' env: - ENVOY_VERSION: "1.24.6" + ENVOY_VERSION: "1.29.4" steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index 637dbdcf52..8634f7613a 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -71,7 +71,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.25.11", "1.26.8", "1.27.5", "1.28.3"] + # envoy-version: ["1.26.8", "1.27.5", "1.28.3", "1.29.4"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 8 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -106,7 +106,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.25.11", "1.26.8", "1.27.5", "1.28.3"] + envoy-version: ["1.26.8", "1.27.5", "1.28.3", "1.29.4"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -201,13 +201,13 @@ jobs: strategy: fail-fast: false matrix: - consul-version: [ "1.16", "1.17"] + consul-version: [ "1.17", "1.18"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} # ENVOY_VERSION should be the latest version upported by all # consul versions in the matrix.consul-version, since we are testing upgrade from - # an older consul version, e.g., 1.26.6 is supported by both 1.16 and 1.17. - ENVOY_VERSION: "1.26.6" + # an older consul version, e.g., 1.27.5 is supported by both 1.16 and 1.17. + ENVOY_VERSION: "1.27.5" steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/.github/workflows/test-integrations-windows.yml b/.github/workflows/test-integrations-windows.yml deleted file mode 100644 index 2ce980ae76..0000000000 --- a/.github/workflows/test-integrations-windows.yml +++ /dev/null @@ -1,1219 +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.11.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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - id: runners - run: .github/scripts/get_runner_classes_windows.sh - - get-go-version: - uses: ./.github/workflows/reusable-get-go-version.yml - - dev-build: - needs: - - setup - - get-go-version - 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' - go-version: ${{ needs.get-go-version.outputs.go-version }} - 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 - - get-go-version - - 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.28.3" ] - 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 - with: - go-version: ${{ needs.get-go-version.outputs.go-version }} - - - name: Fetch binary - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - 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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.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: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v3 - 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: ${{ !cancelled() && !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: ${{ !cancelled() && 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 3fc4031439..20f169d6f4 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -272,7 +272,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 2 based on these values: - # envoy-version: ["1.28.3"] + # envoy-version: ["1.29.4"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 2 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -307,7 +307,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.28.3"] + envoy-version: ["1.29.4"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -397,7 +397,7 @@ jobs: id-token: write # NOTE: this permission is explicitly required for Vault auth. contents: read env: - ENVOY_VERSION: "1.28.2" + ENVOY_VERSION: "1.29.4" CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi" steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/Makefile b/Makefile index 75a7b5b742..1e643d9e4a 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ CONSUL_IMAGE_VERSION?=latest # When changing the method of Go version detection, also update # version detection in CI workflows (reusable-get-go-version.yml). GOLANG_VERSION?=$(shell head -n 1 .go-version) -ENVOY_VERSION?='1.28.0' +ENVOY_VERSION?='1.29.4' CONSUL_DATAPLANE_IMAGE := $(or $(CONSUL_DATAPLANE_IMAGE),"docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi") DEPLOYER_CONSUL_DATAPLANE_IMAGE := $(or $(DEPLOYER_CONSUL_DATAPLANE_IMAGE), "docker.io/hashicorppreview/consul-dataplane:1.3-dev") diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go index e51918a255..ab3290e576 100644 --- a/envoyextensions/xdscommon/envoy_versioning_test.go +++ b/envoyextensions/xdscommon/envoy_versioning_test.go @@ -151,10 +151,10 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { } */ for _, v := range []string{ - "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.26.7", "1.26.8", "1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", "1.27.5", "1.28.0", "1.28.1", "1.28.2", "1.28.3", + "1.29.0", "1.29.1", "1.29.2", "1.29.3", "1.29.4", } { cases[v] = testcase{expect: SupportedProxyFeatures{}} } diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go index ded724b0a1..1f71770305 100644 --- a/envoyextensions/xdscommon/proxysupport.go +++ b/envoyextensions/xdscommon/proxysupport.go @@ -12,10 +12,10 @@ import "strings" // // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions var EnvoyVersions = []string{ + "1.29.4", "1.28.3", "1.27.5", "1.26.8", - "1.25.11", } // UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall diff --git a/test/integration/connect/envoy/run-tests.sh b/test/integration/connect/envoy/run-tests.sh index 720f6e32a2..0f0365215a 100755 --- a/test/integration/connect/envoy/run-tests.sh +++ b/test/integration/connect/envoy/run-tests.sh @@ -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.29.4"} export ENVOY_VERSION export DOCKER_BUILDKIT=1 diff --git a/website/content/docs/connect/proxies/envoy.mdx b/website/content/docs/connect/proxies/envoy.mdx index ccf2d16cc4..eb3ddd4fea 100644 --- a/website/content/docs/connect/proxies/envoy.mdx +++ b/website/content/docs/connect/proxies/envoy.mdx @@ -58,6 +58,7 @@ apply to both Consul Enterprise and Consul community edition (CE). | Consul Version | Compatible Envoy Versions | | -------------- | -------------------------------------- | +| 1.19.x CE | 1.29.4, 1.28.3, 1.27.5, 1.26.8 | | 1.18.x CE | 1.28.3, 1.27.5, 1.26.8, 1.25.11 | | 1.17.x | 1.27.5, 1.26.8, 1.25.11, 1.24.12 | | 1.16.x | 1.26.8, 1.25.11, 1.24.12, 1.23.12 | @@ -104,6 +105,7 @@ apply to both Consul Enterprise and Consul community edition (CE). | Consul Version | Default `consul-dataplane` Version | Other compatible `consul-dataplane` Versions | | -------------- | -------------------------------------|----------------------------------------------| +| 1.19.x CE | 1.5.x (Envoy 1.29.x) | 1.4.x (Envoy 1.28.x) | | 1.18.x CE | 1.4.x (Envoy 1.28.x) | 1.3.x (Envoy 1.27.x) | | 1.17.x | 1.3.x (Envoy 1.27.x) | 1.4.x (Envoy 1.28.x), 1.2.x (Envoy 1.26.x) | | 1.16.x | 1.2.x (Envoy 1.26.x) | 1.3.x (Envoy 1.27.x), 1.1.x (Envoy 1.25.x) | From d2b107ffe56afe797d5aebcd85e7cd02c00b162b Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Fri, 24 May 2024 13:52:38 -0400 Subject: [PATCH 046/185] ci: update BPA to disable inactive CE backports (#21214) Follow-up to #21094, which temporarily downgraded BPA to allow for old CE backport labels to be used during Consul's most recent patch release. Upgrading fully enforces the version manifest and prevents accidental backports to no-longer-active CE versions. --- .github/workflows/backport-assistant.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/backport-assistant.yml b/.github/workflows/backport-assistant.yml index 39a95c9a04..27d83e94f5 100644 --- a/.github/workflows/backport-assistant.yml +++ b/.github/workflows/backport-assistant.yml @@ -19,10 +19,7 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - # Temporarily use 0.4.0 to enable old + new label functionality prior - # to this fix in BPA that excludes CE labels: https://github.com/hashicorp/backport-assistant/pull/84 - # After the Consul May patches, this can be removed and the version updated to latest. - container: hashicorpdev/backport-assistant:0.4.0 + container: hashicorpdev/backport-assistant:0.4.1 steps: - name: Run Backport Assistant for release branches run: | From f70fcab2ab76f2308c209fba29e1fd227e5f0a23 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 24 May 2024 14:54:54 -0400 Subject: [PATCH 047/185] build: bandaid for action-go-build clean flag (#21217) --- .github/workflows/build.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0225ab28a9..7da5ca643e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -132,7 +132,7 @@ jobs: PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} CGO_ENABLED: "0" GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@v1 + uses: hashicorp/actions-go-build@make-clean-flag-optional with: product_name: ${{ env.PKG_NAME }} product_version: ${{ needs.set-product-version.outputs.product-version }} @@ -140,6 +140,7 @@ jobs: os: ${{ matrix.goos }} arch: ${{ matrix.goarch }} reproducible: report + clean: false instructions: |- cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -o "$BIN_PATH" -trimpath -buildvcs=false @@ -232,7 +233,7 @@ jobs: PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} CGO_ENABLED: "0" GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@v1 + uses: hashicorp/actions-go-build@make-clean-flag-optional with: product_name: ${{ env.PKG_NAME }} product_version: ${{ needs.set-product-version.outputs.product-version }} @@ -240,6 +241,7 @@ jobs: os: ${{ matrix.goos }} arch: ${{ matrix.goarch }} reproducible: report + clean: false instructions: |- cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -o "$BIN_PATH" -trimpath -buildvcs=false @@ -283,7 +285,7 @@ jobs: PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} CGO_ENABLED: "0" GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@v1 + uses: hashicorp/actions-go-build@make-clean-flag-optional with: product_name: ${{ env.PKG_NAME }} product_version: ${{ needs.set-product-version.outputs.product-version }} @@ -291,6 +293,7 @@ jobs: os: ${{ matrix.goos }} arch: ${{ matrix.goarch }} reproducible: report + clean: false instructions: |- cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -tags netcgo -o "$BIN_PATH" -trimpath -buildvcs=false From f3d1a8bc783e2437bbbb8665401647b503fc020b Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 24 May 2024 15:32:59 -0400 Subject: [PATCH 048/185] build: set go-build reproducible to false (#21218) --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7da5ca643e..1a80b57a59 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -139,7 +139,7 @@ jobs: go_version: ${{ needs.get-go-version.outputs.go-version }} os: ${{ matrix.goos }} arch: ${{ matrix.goarch }} - reproducible: report + reproducible: nope clean: false instructions: |- cp LICENSE $TARGET_DIR/LICENSE.txt @@ -240,7 +240,7 @@ jobs: go_version: ${{ needs.get-go-version.outputs.go-version }} os: ${{ matrix.goos }} arch: ${{ matrix.goarch }} - reproducible: report + reproducible: nope clean: false instructions: |- cp LICENSE $TARGET_DIR/LICENSE.txt @@ -292,7 +292,7 @@ jobs: go_version: ${{ needs.get-go-version.outputs.go-version }} os: ${{ matrix.goos }} arch: ${{ matrix.goarch }} - reproducible: report + reproducible: nope clean: false instructions: |- cp LICENSE $TARGET_DIR/LICENSE.txt From 54a545d0dbdbf59919e7707e4978863e2041ef6b Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 24 May 2024 22:00:14 -0400 Subject: [PATCH 049/185] build: prepare for 1.20.0 dev (#21219) --- ...t-1.16.x.yaml => nightly-test-1.18.x.yaml} | 18 +- .github/workflows/nightly-test-1.19.x.yaml | 234 ++++++++++ ...l => nightly-test-integrations-1.18.x.yml} | 107 ++++- .../nightly-test-integrations-1.19.x.yml | 440 ++++++++++++++++++ .release/versions.hcl | 5 +- version/VERSION | 2 +- 6 files changed, 786 insertions(+), 20 deletions(-) rename .github/workflows/{nightly-test-1.16.x.yaml => nightly-test-1.18.x.yaml} (96%) create mode 100644 .github/workflows/nightly-test-1.19.x.yaml rename .github/workflows/{nightly-test-integrations-1.16.x.yml => nightly-test-integrations-1.18.x.yml} (77%) create mode 100644 .github/workflows/nightly-test-integrations-1.19.x.yml diff --git a/.github/workflows/nightly-test-1.16.x.yaml b/.github/workflows/nightly-test-1.18.x.yaml similarity index 96% rename from .github/workflows/nightly-test-1.16.x.yaml rename to .github/workflows/nightly-test-1.18.x.yaml index 6dff72150f..88790e82b6 100644 --- a/.github/workflows/nightly-test-1.16.x.yaml +++ b/.github/workflows/nightly-test-1.18.x.yaml @@ -1,7 +1,7 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test 1.16.x +name: Nightly Frontend Test 1.18.x on: schedule: - cron: '0 4 * * *' @@ -9,8 +9,8 @@ on: 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 + BRANCH: "release/1.18.x" + BRANCH_NAME: "release-1.18.x" # Used for naming artifacts GOPRIVATE: github.com/hashicorp # Required for enterprise deps jobs: @@ -24,7 +24,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: - node-version: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -56,7 +56,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: - node-version: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -95,7 +95,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: - node-version: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -128,7 +128,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: - node-version: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -167,7 +167,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: - node-version: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -198,7 +198,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: - node-version: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock diff --git a/.github/workflows/nightly-test-1.19.x.yaml b/.github/workflows/nightly-test-1.19.x.yaml new file mode 100644 index 0000000000..2f5398596b --- /dev/null +++ b/.github/workflows/nightly-test-1.19.x.yaml @@ -0,0 +1,234 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +name: Nightly Frontend Test 1.19.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.19.x" + BRANCH_NAME: "release-1.19.x" # Used for naming artifacts + GOPRIVATE: github.com/hashicorp # Required for enterprise deps + +jobs: + frontend-test-workspace-node: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + + # Not necessary to use yarn, but enables caching + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: 'yarn' + cache-dependency-path: ./ui/yarn.lock + + - name: Install + id: install + working-directory: ./ui + run: make deps + + - name: Workspace Tests + id: workspace-test + working-directory: ./ui + run: make test-workspace + + - name: Node Tests + id: node-test + working-directory: ./ui/packages/consul-ui + run: make test-node + + frontend-build-ce: + runs-on: ubuntu-latest + env: + JOBS: 2 + CONSUL_NSPACES_ENABLED: 0 + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + + # Not necessary to use yarn, but enables caching + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: 'yarn' + cache-dependency-path: ./ui/yarn.lock + + - name: Install + id: install + working-directory: ./ui + run: make deps + + - name: Ember Build CE + id: build-ce + working-directory: ./ui/packages/consul-ui + run: make build-ci + + - name: Upload CE Frontend + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: frontend-ce-${{ env.BRANCH_NAME }} + path: ./ui/packages/consul-ui/dist + if-no-files-found: error + + frontend-test-ce: + runs-on: ubuntu-latest + needs: [frontend-build-ce] + strategy: + matrix: + partition: [ 1, 2, 3, 4 ] + env: + CONSUL_NSPACES_ENABLED: 0 + 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + + # Not necessary to use yarn, but enables caching + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: 'yarn' + cache-dependency-path: ./ui/yarn.lock + + - name: Install + id: install + working-directory: ./ui + run: make deps + + - name: Download CE Frontend + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: frontend-ce-${{ env.BRANCH_NAME }} + path: ./ui/packages/consul-ui/dist + + - name: Ember Test CE + id: cache + working-directory: ./ui/packages/consul-ui + run: node_modules/.bin/ember exam --split=$EMBER_PARTITION_TOTAL --partition=${{ matrix.partition }} --path dist --silent -r xunit + + frontend-build-ent: + runs-on: ubuntu-latest + env: + JOBS: 2 + CONSUL_NSPACES_ENABLED: 1 + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + + # Not necessary to use yarn, but enables caching + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: 'yarn' + cache-dependency-path: ./ui/yarn.lock + + - name: Install + id: install + working-directory: ./ui + run: make deps + + - name: Ember Build ENT + id: build-ce + working-directory: ./ui/packages/consul-ui + run: make build-ci + + - name: Upload ENT Frontend + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: frontend-ent-${{ env.BRANCH_NAME }} + path: ./ui/packages/consul-ui/dist + if-no-files-found: error + + frontend-test-ent: + runs-on: ubuntu-latest + needs: [frontend-build-ent] + strategy: + matrix: + partition: [ 1, 2, 3, 4 ] + env: + CONSUL_NSPACES_ENABLED: 1 + 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + + # Not necessary to use yarn, but enables caching + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: 'yarn' + cache-dependency-path: ./ui/yarn.lock + + - name: Install + id: install + working-directory: ./ui + run: make deps + + - name: Download ENT Frontend + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: frontend-ent-${{ env.BRANCH_NAME }} + path: ./ui/packages/consul-ui/dist + + - name: Ember Test ENT + id: cache + working-directory: ./ui/packages/consul-ui + run: node_modules/.bin/ember exam --split=$EMBER_PARTITION_TOTAL --partition=${{ matrix.partition }} --path dist --silent -r xunit + + frontend-test-coverage-ent: + runs-on: ubuntu-latest + needs: [frontend-build-ent] + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + + # Not necessary to use yarn, but enables caching + - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 + with: + node-version: 18 + cache: 'yarn' + cache-dependency-path: ./ui/yarn.lock + + - name: Install + id: install + working-directory: ./ui + run: make deps + + - name: Download ENT Frontend + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + with: + name: frontend-ent-${{ env.BRANCH_NAME }} + path: ./ui/packages/consul-ui/dist + + - name: Run ENT Code Coverage + working-directory: ./ui/packages/consul-ui + run: make test-coverage-ci + + slack-failure-notification: + runs-on: ubuntu-latest + needs: [frontend-test-ce, frontend-test-ent] + if: ${{ failure() }} + steps: + - name: Slack Notification + id: slack + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 + with: + payload: | + { + "message": "One or more nightly UI 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_UI_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-integrations-1.16.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml similarity index 77% rename from .github/workflows/nightly-test-integrations-1.16.x.yml rename to .github/workflows/nightly-test-integrations-1.18.x.yml index 9f7cee6713..9d6ec0d5fd 100644 --- a/.github/workflows/nightly-test-integrations-1.16.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -1,7 +1,7 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly test-integrations 1.16.x +name: Nightly test-integrations 1.18.x on: schedule: @@ -19,8 +19,8 @@ env: # 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 + BRANCH: "release/1.18.x" + BRANCH_NAME: "release-1.18.x" # Used for naming artifacts jobs: setup: @@ -52,7 +52,7 @@ jobs: runs-on: ${{ needs.setup.outputs.compute-large }} repository-name: ${{ github.repository }} uploaded-binary-name: 'consul-bin' - branch-name: "release/1.16.x" + branch-name: "release/1.17.x" go-version: ${{ needs.get-go-version.outputs.go-version }} secrets: elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} @@ -74,9 +74,9 @@ 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.23.12", "1.24.12", "1.25.11", "1.26.8"] + # envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] # xds-target: ["server", "client"] - TOTAL_RUNNERS: 8 + TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' run: | NUM_RUNNERS=$TOTAL_RUNNERS @@ -109,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.23.12", "1.24.12", "1.25.11", "1.26.8"] + envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -204,7 +204,7 @@ jobs: strategy: fail-fast: false matrix: - consul-version: ["1.14", "1.15", "1.16"] + consul-version: ["1.15", "1.16", "1.17"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} ENVOY_VERSION: "1.24.6" @@ -318,6 +318,96 @@ jobs: DD_ENV: ci run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml + upgrade-integration-test-deployer: + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} + needs: + - setup + - get-go-version + - 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 }} + steps: + - name: Checkout code + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + with: + go-version: ${{ needs.get-go-version.outputs.go-version }} + - run: go env + - name: Build image + run: make test-deployer-setup + - name: Upgrade Integration Tests + run: | + mkdir -p "${{ env.TEST_RESULTS_DIR }}" + export NOLOGBUFFER=1 + cd ./test-integ/upgrade + docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version + go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ + --raw-command \ + --format=standard-verbose \ + --debug \ + --packages="./..." \ + -- \ + go test \ + -tags "${{ env.GOTAGS }}" \ + -timeout=60m \ + -parallel=2 \ + -json \ + ./... \ + --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 }}" + 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: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: vault-auth + run: vault-auth + + # NOTE: ENT specific step as we store secrets in Vault. + - name: Fetch Secrets + if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: secrets + uses: hashicorp/vault-action@v3 + 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: ${{ !cancelled() && !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: ${{ !cancelled() && 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: @@ -326,6 +416,7 @@ jobs: - generate-envoy-job-matrices - envoy-integration-test - upgrade-integration-test + - upgrade-integration-test-deployer runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} if: ${{ always() }} steps: diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml new file mode 100644 index 0000000000..675f7583d4 --- /dev/null +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -0,0 +1,440 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +name: Nightly test-integrations 1.19.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.11.0" + 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.19.x" + BRANCH_NAME: "release-1.19.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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + - id: runners + run: .github/scripts/get_runner_classes.sh + + get-go-version: + uses: ./.github/workflows/reusable-get-go-version.yml + + dev-build: + needs: + - setup + - get-go-version + 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" + go-version: ${{ needs.get-go-version.outputs.go-version }} + 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + 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.8", "1.27.5"] + # 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 + - get-go-version + - 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.8", "1.27.5"] + 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ env.BRANCH }} + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + with: + go-version: ${{ needs.get-go-version.outputs.go-version }} + + - name: fetch binary + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + 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@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.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: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: vault-auth + run: vault-auth + + # NOTE: ENT specific step as we store secrets in Vault. + - name: Fetch Secrets + if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: secrets + uses: hashicorp/vault-action@v3 + 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: ${{ !cancelled() && !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: ${{ !cancelled() && 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 + - get-go-version + - 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + with: + go-version: ${{ needs.get-go-version.outputs.go-version }} + - run: go env + + # Get go binary from workspace + - name: fetch binary + uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + 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=github-actions \ + --rerun-fails \ + --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: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: vault-auth + run: vault-auth + + # NOTE: ENT specific step as we store secrets in Vault. + - name: Fetch Secrets + if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: secrets + uses: hashicorp/vault-action@v3 + 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: ${{ !cancelled() && !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: ${{ !cancelled() && 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-deployer: + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} + needs: + - setup + - get-go-version + - 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 }} + steps: + - name: Checkout code + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + 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@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + with: + go-version: ${{ needs.get-go-version.outputs.go-version }} + - run: go env + - name: Build image + run: make test-deployer-setup + - name: Upgrade Integration Tests + run: | + mkdir -p "${{ env.TEST_RESULTS_DIR }}" + export NOLOGBUFFER=1 + cd ./test-integ/upgrade + docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version + go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ + --raw-command \ + --format=standard-verbose \ + --debug \ + --packages="./..." \ + -- \ + go test \ + -tags "${{ env.GOTAGS }}" \ + -timeout=60m \ + -parallel=2 \ + -json \ + ./... \ + --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 }}" + 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: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: vault-auth + run: vault-auth + + # NOTE: ENT specific step as we store secrets in Vault. + - name: Fetch Secrets + if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} + id: secrets + uses: hashicorp/vault-action@v3 + 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: ${{ !cancelled() && !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: ${{ !cancelled() && 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 + - upgrade-integration-test-deployer + 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@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.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/.release/versions.hcl b/.release/versions.hcl index abdd7f3342..fdc0f2989d 100644 --- a/.release/versions.hcl +++ b/.release/versions.hcl @@ -6,12 +6,13 @@ schema = 1 active_versions { - version "1.18" { + version "1.19" { ce_active = true + } + version "1.18" { lts = true } version "1.17" {} - version "1.16" {} version "1.15" { lts = true } diff --git a/version/VERSION b/version/VERSION index ff32b92aad..734375f897 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -1.19.0-dev +1.20.0-dev From c1a7221406d9f0ac3aceb572b7f56586eb38de58 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 28 May 2024 11:43:36 -0400 Subject: [PATCH 050/185] [NET-9445] Re-enable 1.18 backports during 1.19 RC (#21223) Re-enable 1.18 backports during 1.19 RC Follow-up to #21219. --- .release/versions.hcl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.release/versions.hcl b/.release/versions.hcl index fdc0f2989d..d504b4bfae 100644 --- a/.release/versions.hcl +++ b/.release/versions.hcl @@ -10,6 +10,8 @@ active_versions { ce_active = true } version "1.18" { + # This release should remain active until 1.19 GA + ce_active = true lts = true } version "1.17" {} From 5f129ad5b27c1ff0ae519859abe030c2717b1c32 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Tue, 28 May 2024 09:54:38 -0700 Subject: [PATCH 051/185] docs: Fix heading errors in security models (#21227) fixes --- .../docs/security/security-models/core.mdx | 16 ++++++++-------- .../docs/security/security-models/index.mdx | 6 +++--- .../docs/security/security-models/nia.mdx | 16 ++++++++-------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/website/content/docs/security/security-models/core.mdx b/website/content/docs/security/security-models/core.mdx index 1140cdab30..1c57c6cc51 100644 --- a/website/content/docs/security/security-models/core.mdx +++ b/website/content/docs/security/security-models/core.mdx @@ -5,7 +5,7 @@ description: >- The security model for Consul Core details requirements and recommendations for securing your deployment of Consul. Learn about potential threats and how to protect Consul from malicious actors. --- -## Overview +# Consul security model overview Consul enables automation of network configurations, service discovery, and secure network connectivity across any cloud or runtime. @@ -32,7 +32,7 @@ environment, but the general mechanisms for a secure Consul deployment revolve a - **Sentinel Policies** - Sentinel policies enable policy-as-code for granular control over the built-in key-value store. -### Personas +## Personas It helps to consider the following types of personas when managing the security requirements of a Consul deployment. The granularity may change depending on your team's requirements. @@ -60,14 +60,14 @@ The granularity may change depending on your team's requirements. be public facing on the internet such as a web server, typically through a load-balancer, or ingress gateway. This is someone who should not have any network access to the Consul agent APIs. -### Secure Configuration +## Secure Configuration Consul's security model is applicable only if all parts of the system are running with a secure configuration; **Consul is not secure-by-default.** Without the following mechanisms enabled in Consul's configuration, it may be possible to abuse access to a cluster. Like all security considerations, administrators must determine what is appropriate for their environment and adapt these configurations accordingly. -#### Requirements +## Requirements - **mTLS** - Mutual authentication of both the TLS server and client x509 certificates prevents internal abuse through unauthorized access to Consul agents within the cluster. @@ -212,7 +212,7 @@ environment and adapt these configurations accordingly. commands across the cluster. This is disabled by default since 0.8.0. We recommend leaving it disabled. If enabled, extreme care must be taken to ensure correct ACLs restrict access to execute arbitrary code on the cluster. -#### Recommendations +## Recommendations - **Rotate Credentials** - Using short-lived credentials and rotating them frequently is highly recommended for production environments to limit the blast radius from potentially compromised secrets, and enabling basic auditing. @@ -307,7 +307,7 @@ environment and adapt these configurations accordingly. } ``` -### Threat Model +## Threat Model The following are parts of the core Consul threat model: @@ -381,7 +381,7 @@ The following are not part of the threat model for client agents: endpoint. If any of this isn't performed correctly, the proxy or service may allow unauthenticated or unauthorized connections. -#### Internal Threats +## Internal Threats - **Operator** - A malicious internal Consul operator with a valid mTLS certificate and ACL token may still be a threat to your cluster in certain situations, especially in multi-team deployments. They may accidentally or intentionally @@ -409,7 +409,7 @@ The following are not part of the threat model for client agents: information. When ACLs and HTTPS are enabled, the gRPC endpoint serving up the xDS service requires (m)TLS and a valid ACL token. -#### External Threats +## External Threats - **Agents** - External access to the Consul agent's various network endpoints should be considered including the gossip, HTTP, RPC, and gRPC ports. Furthermore, access through other services like SSH or `exec` functionality in diff --git a/website/content/docs/security/security-models/index.mdx b/website/content/docs/security/security-models/index.mdx index bcb8f639af..eea5cd6ab2 100644 --- a/website/content/docs/security/security-models/index.mdx +++ b/website/content/docs/security/security-models/index.mdx @@ -5,20 +5,20 @@ description: >- Security models are the set of requirements and recommendations for securely operating a Consul deployment. Learn about security models and how they differ between environments. --- -## Overview +# Security models overview Requirements and recommendations for operating a secure Consul deployment may vary drastically depending on your intended workloads, operating system, and environment. Consul is not secure by default, but can be configured to satisfy the security requirements for a wide-range of use cases from local developer environments without any configuration to container orchestrators in-production with ACL authorization, and mTLS authentication. -### Core +## Core The core Consul product provides several options for enabling encryption, authentication, and authorization controls for a cluster. You can read more about the various personas, recommendations, requirements, and threats [here](/consul/docs/security/security-models/core). -### NIA +## NIA [Network Infrastructure Automation](/consul/docs/nia) (NIA) enables dynamic updates to network infrastructure devices triggered by service changes. Both the core Consul product's configuration and the configuration for the `consul-terraform-sync` diff --git a/website/content/docs/security/security-models/nia.mdx b/website/content/docs/security/security-models/nia.mdx index 0e6de4982b..6770890654 100644 --- a/website/content/docs/security/security-models/nia.mdx +++ b/website/content/docs/security/security-models/nia.mdx @@ -5,7 +5,7 @@ description: >- The NIA security model details requirements and recommendations for securing your Consul-Terraform-Sync (CTS) deployment. Learn about potential threats and how to protect CTS from malicious actors. --- -## Overview +# Network Infrastructure Automation (NIA) overview Network Infrastructure Automation (NIA) enables dynamic updates to network infrastructure devices triggered by service changes using the [Consul Terraform Sync](https://github.com/hashicorp/consul-terraform-sync) (`consul-terraform-sync`) daemon. This daemon uses Consul's catalog to monitor networking information about services along with [Terraform](https://www.terraform.io/)'s provider ecosystem to apply relevant changes to network infrastructure. @@ -13,7 +13,7 @@ The [Secure Consul-Terraform-Sync for Production](/consul/tutorials/network-infr tutorial contains a checklist of best practices to secure your Consul-Terraform-Sync installation for a production environment. -### Personas +## Personas When considering Consul NIA's security model, it helps to think of the following personas. @@ -32,7 +32,7 @@ When considering Consul NIA's security model, it helps to think of the following have no knowledge or access to the daemon's API endpoints, ACL tokens, certificates, or any other piece of the system. -### Secure Configuration +## Secure Configuration Consul NIA's security model is applicable only if all parts of the system are running with a secure configuration; `consul-terraform-sync` is not secure-by-default. Without the following mechanisms enabled in the @@ -40,7 +40,7 @@ daemon's configuration, it may be possible to abuse access to the daemon. Like a considerations, one must determine what concerns are appropriate for their environment, and adapt these security concerns accordingly. -#### Requirements +## Requirements - **Protect Configuration Files and Directories** - A dedicated NIA user and group with limited permissions should be created for production, along with directory, and file permissions appropriately @@ -68,7 +68,7 @@ security concerns accordingly. - **Read** permission for Consul Catalog for all of the selected services to be monitored, and their namespaces. - **Read + Write** permission to update health checks, when using NIA health monitoring. -#### Recommendations +## Recommendations - **Use Dedicated Host** - The NIA daemon will potentially have access to critical secrets for your environment's network infrastructure. Using a hardened, dedicated host, for supporting these sensitive operations is highly recommended. @@ -85,7 +85,7 @@ security concerns accordingly. are configured with the NIA daemon should be audited to ensure you're only using providers from sources that you trust. -### Threat Model +## Threat Model The following are the parts of the NIA threat model: @@ -131,7 +131,7 @@ a production deployment: - **Access to the Consul-Terraform-Sync Binary** - Direct access to the system binary used to start the NIA daemon can allow an attacker to extract sensitive information. -#### Internal Threats +## Internal Threats - **NIA Operator** - Someone with access to the NIA Host, and it's related binaries or configuration files may be a threat to your deployment, especially considering multi-team deployments. They may accidentally or intentionally use a @@ -150,7 +150,7 @@ a production deployment: means. Extra steps to configuring OS, cluster, service, user, directory, and file permissions are essential steps for implementing defense-in-depth within a production environment. -#### External Threats +## External Threats - **Terraform Providers and Modules** - Potentially malicious providers or modules, or any malicious dependencies part of the Terraform ecosystem could cause harm to the network, and may have access to secrets in order to make necessary From 9fb50fa769839f531d75c691e564e438e789b6c7 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 28 May 2024 12:55:52 -0400 Subject: [PATCH 052/185] Fix Consul versions in nightly 1.19 int tests (#21226) We should be testing against n-2 + LTS, so we need to replace 1.16 with 1.18. --- .github/workflows/nightly-test-integrations-1.19.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml index 675f7583d4..7acb1903a9 100644 --- a/.github/workflows/nightly-test-integrations-1.19.x.yml +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -204,7 +204,7 @@ jobs: strategy: fail-fast: false matrix: - consul-version: ["1.15", "1.16", "1.17"] + consul-version: ["1.15", "1.17", "1.18"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} ENVOY_VERSION: "1.24.6" @@ -330,7 +330,7 @@ jobs: strategy: fail-fast: false matrix: - consul-version: [ "1.15", "1.16", "1.17"] + consul-version: ["1.15", "1.17", "1.18"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} steps: From ad9ada883cab2333df75155b8a7759c389fc7e57 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 28 May 2024 14:59:04 -0500 Subject: [PATCH 053/185] [NET-9510] Document known OpenShift issue for consul-k8s 1.2.x, 1.3.x and 1.4.x (#21224) * Add OpenShift networking issue to Known Issues for 1.2.x, 1.3.x and 1.4.x * Update website/content/docs/release-notes/consul-k8s/v1_2_x.mdx --- website/content/docs/release-notes/consul-k8s/v1_2_x.mdx | 8 ++++++++ website/content/docs/release-notes/consul-k8s/v1_3_x.mdx | 2 ++ website/content/docs/release-notes/consul-k8s/v1_4_x.mdx | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/website/content/docs/release-notes/consul-k8s/v1_2_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_2_x.mdx index 3f9ba28083..60c6597fd5 100644 --- a/website/content/docs/release-notes/consul-k8s/v1_2_x.mdx +++ b/website/content/docs/release-notes/consul-k8s/v1_2_x.mdx @@ -75,6 +75,14 @@ We are pleased to announce the following Consul updates. For more detailed information, please refer to the [upgrade details page](/consul/docs/upgrading/upgrade-specific) and the changelogs. +## Known Issues + +The following issues are known to exist in the v1.2.x releases. Refer to the changelog for more information. + +- v1.2.8 - Service-to-service networking is broken when deployed on OpenShift. OpenShift users are advised to avoid deploying this version of consul-k8s. + A fix is present in the v1.2.9 release [[GH-4038](https://github.com/hashicorp/consul-k8s/pull/4038)]. + + ## Changelogs The changelogs for this major release version and any maintenance versions are listed below. diff --git a/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx index 30edc3e165..4ac0284255 100644 --- a/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx +++ b/website/content/docs/release-notes/consul-k8s/v1_3_x.mdx @@ -45,6 +45,8 @@ For more detailed information, please refer to the [upgrade details page](/consu The following issues are known to exist in the v1.3.x releases. Refer to the changelog for more information. - When using the v2 API with transparent proxy, Kubernetes pods cannot use L7 liveness, readiness, or startup probes. +- v1.3.5 - Service-to-service networking is broken when deployed on OpenShift. OpenShift users are advised to avoid deploying this version of consul-k8s. + A fix is present in the v1.3.6 release [[GH-4037](https://github.com/hashicorp/consul-k8s/pull/4037)]. ## Changelogs diff --git a/website/content/docs/release-notes/consul-k8s/v1_4_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_4_x.mdx index 8d72391677..ec264b1359 100644 --- a/website/content/docs/release-notes/consul-k8s/v1_4_x.mdx +++ b/website/content/docs/release-notes/consul-k8s/v1_4_x.mdx @@ -41,6 +41,13 @@ Refer to [Supported Consul and Kubernetes versions](/consul/docs/v1.18.x/k8s/com For more detailed information, please refer to the [upgrade details page](/consul/docs/upgrading/upgrade-specific) and the changelogs. +## Known issues + +The following issues are known to exist in the v1.4.x releases: + +- v1.4.2 - Service-to-service networking is broken when deployed on OpenShift. OpenShift users are advised to avoid deploying this version of consul-k8s. + A fix is present in the v1.4.3 release [[GH-4034](https://github.com/hashicorp/consul-k8s/pull/4034)]. + ## Changelogs The changelogs for this major release version and any maintenance versions are listed below. From 11bcf521ae391397146b25a9da8e71830ed9bc53 Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 28 May 2024 16:20:59 -0600 Subject: [PATCH 054/185] dns v2 - both empty string and default should be allowed for namespace and partition in CE (#21230) * dns v2 - both empty string and default should be allowed for namespace and partition in Ce * add changelog * use default partition constant * use constants in validation. --------- Co-authored-by: Michael Zalimeni --- .changelog/21230.txt | 3 ++ acl/acl_ce.go | 23 +++++++-- agent/discovery/query_fetcher_v1_ce.go | 6 ++- agent/discovery/query_fetcher_v1_ce_test.go | 53 +++++++++++++++++++++ 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 .changelog/21230.txt diff --git a/.changelog/21230.txt b/.changelog/21230.txt new file mode 100644 index 0000000000..5a57333afa --- /dev/null +++ b/.changelog/21230.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +dns: new version was not supporting partition or namespace being set to 'default' in CE version. +``` \ No newline at end of file diff --git a/acl/acl_ce.go b/acl/acl_ce.go index 7d2b8513b8..0d207ad421 100644 --- a/acl/acl_ce.go +++ b/acl/acl_ce.go @@ -8,12 +8,25 @@ package acl const ( WildcardPartitionName = "" DefaultPartitionName = "" -) + // NonEmptyDefaultPartitionName is the name of the default partition that is + // not empty. An example of this being supplied is when a partition is specified + // in the request for DNS by consul-dataplane. This has been added to support + // DNS v1.5, which needs to be compatible with the original DNS subsystem which + // supports partition being "default" or empty. Otherwise, use DefaultPartitionName. + NonEmptyDefaultPartitionName = "default" -// Reviewer Note: This is a little bit strange; one might want it to be "" like partition name -// However in consul/structs/intention.go we define IntentionDefaultNamespace as 'default' and so -// we use the same here -const DefaultNamespaceName = "default" + // DefaultNamespaceName is used to mimic the behavior in consul/structs/intention.go, + // where we define IntentionDefaultNamespace as 'default' and so we use the same here. + // This is a little bit strange; one might want it to be "" like DefaultPartitionName. + DefaultNamespaceName = "default" + + // EmptyNamespaceName is the name of the default partition that is an empty string. + // An example of this being supplied is when a namespace is specifiedDNS v1. + // EmptyNamespaceName has been added to support DNS v1.5, which needs to be + // compatible with the original DNS subsystem which supports partition being "default" or empty. + // Otherwise, use DefaultNamespaceName. + EmptyNamespaceName = "" +) type EnterpriseConfig struct { // no fields in CE diff --git a/agent/discovery/query_fetcher_v1_ce.go b/agent/discovery/query_fetcher_v1_ce.go index 090db0e5f7..06299704bd 100644 --- a/agent/discovery/query_fetcher_v1_ce.go +++ b/agent/discovery/query_fetcher_v1_ce.go @@ -14,8 +14,12 @@ func (f *V1DataFetcher) NormalizeRequest(req *QueryPayload) { return } +// validateEnterpriseTenancy validates the tenancy fields for an enterprise request to +// make sure that they are either set to an empty string or "default" to align with the behavior +// in CE. func validateEnterpriseTenancy(req QueryTenancy) error { - if req.Namespace != "" || req.Partition != acl.DefaultPartitionName { + if !(req.Namespace == acl.EmptyNamespaceName || req.Namespace == acl.DefaultNamespaceName) || + !(req.Partition == acl.DefaultPartitionName || req.Partition == acl.NonEmptyDefaultPartitionName) { return ErrNotSupported } return nil diff --git a/agent/discovery/query_fetcher_v1_ce_test.go b/agent/discovery/query_fetcher_v1_ce_test.go index 717475c9dc..69cd2dea98 100644 --- a/agent/discovery/query_fetcher_v1_ce_test.go +++ b/agent/discovery/query_fetcher_v1_ce_test.go @@ -5,7 +5,60 @@ package discovery +import ( + "github.com/stretchr/testify/require" + "testing" +) + const ( defaultTestNamespace = "" defaultTestPartition = "" ) + +func Test_validateEnterpriseTenancy(t *testing.T) { + testCases := []struct { + name string + req QueryTenancy + expected error + }{ + { + name: "empty namespace and partition returns no error", + req: QueryTenancy{ + Namespace: defaultTestNamespace, + Partition: defaultTestPartition, + }, + expected: nil, + }, + { + name: "namespace and partition set to 'default' returns no error", + req: QueryTenancy{ + Namespace: "default", + Partition: "default", + }, + expected: nil, + }, + { + name: "namespace set to something other than empty string or `default` returns not supported error", + req: QueryTenancy{ + Namespace: "namespace-1", + Partition: "default", + }, + expected: ErrNotSupported, + }, + { + name: "partition set to something other than empty string or `default` returns not supported error", + req: QueryTenancy{ + Namespace: "default", + Partition: "partition-1", + }, + expected: ErrNotSupported, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := validateEnterpriseTenancy(tc.req) + require.Equal(t, tc.expected, err) + }) + } +} From 544ce7b9d4d9a9fd3efff70001b315ba1aaca1ea Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 30 May 2024 16:58:06 -0400 Subject: [PATCH 055/185] Restore 1.16 backports until 1.19 is released (#21240) --- .release/versions.hcl | 1 + 1 file changed, 1 insertion(+) diff --git a/.release/versions.hcl b/.release/versions.hcl index d504b4bfae..e593948bec 100644 --- a/.release/versions.hcl +++ b/.release/versions.hcl @@ -15,6 +15,7 @@ active_versions { lts = true } version "1.17" {} + version "1.16" {} version "1.15" { lts = true } From 6450b6a3b4fe16cf1ae07a5353b5eaeb7229d633 Mon Sep 17 00:00:00 2001 From: John Murret Date: Mon, 3 Jun 2024 12:10:38 -0600 Subject: [PATCH 056/185] update TestHTTPHandlers_AgentMetrics_LeaderShipMetrics to use 3 servers instead of 2 to allow quorum when leadership flails. (#21239) * update TestHTTPHandlers_AgentMetrics_LeaderShipMetrics to use 3 servers instead of 2 to allow quorom when leadership flails. * properly sequence defers --- agent/metrics_test.go | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/agent/metrics_test.go b/agent/metrics_test.go index fa1fc55aa2..c65fcc802d 100644 --- a/agent/metrics_test.go +++ b/agent/metrics_test.go @@ -229,6 +229,7 @@ func TestHTTPHandlers_AgentMetrics_LeaderShipMetrics(t *testing.T) { t.Run("check that metric isLeader is set properly on server", func(t *testing.T) { metricsPrefix1 := getUniqueMetricsPrefix() metricsPrefix2 := getUniqueMetricsPrefix() + metricsPrefix3 := getUniqueMetricsPrefix() hcl1 := fmt.Sprintf(` server = true @@ -248,16 +249,29 @@ func TestHTTPHandlers_AgentMetrics_LeaderShipMetrics(t *testing.T) { } `, metricsPrefix2) + hcl3 := fmt.Sprintf(` + server = true + telemetry = { + prometheus_retention_time = "25s", + disable_hostname = true + metrics_prefix = "%s" + } + `, metricsPrefix3) + overrides := ` bootstrap = false - bootstrap_expect = 2 + bootstrap_expect = 3 ` s1 := StartTestAgent(t, TestAgent{Name: "s1", HCL: hcl1, Overrides: overrides}) - s2 := StartTestAgent(t, TestAgent{Name: "s2", HCL: hcl2, Overrides: overrides}) defer s1.Shutdown() + + s2 := StartTestAgent(t, TestAgent{Name: "s2", HCL: hcl2, Overrides: overrides}) defer s2.Shutdown() + s3 := StartTestAgent(t, TestAgent{Name: "s3", HCL: hcl3, Overrides: overrides}) + defer s3.Shutdown() + // agent hasn't become a leader retry.RunWith(retry.ThirtySeconds(), t, func(r *testretry.R) { respRec := httptest.NewRecorder() @@ -268,8 +282,12 @@ func TestHTTPHandlers_AgentMetrics_LeaderShipMetrics(t *testing.T) { _, err := s2.JoinLAN([]string{s1.Config.SerfBindAddrLAN.String()}, nil) require.NoError(t, err) + _, err = s3.JoinLAN([]string{s1.Config.SerfBindAddrLAN.String()}, nil) + require.NoError(t, err) + testrpc.WaitForLeader(t, s1.RPC, "dc1") testrpc.WaitForLeader(t, s2.RPC, "dc1") + testrpc.WaitForLeader(t, s3.RPC, "dc1") // Verify agent's isLeader metrics is 1 retry.RunWith(retry.ThirtySeconds(), t, func(r *testretry.R) { @@ -281,7 +299,11 @@ func TestHTTPHandlers_AgentMetrics_LeaderShipMetrics(t *testing.T) { recordPromMetrics(r, s2, respRec2) found2 := strings.Contains(respRec2.Body.String(), metricsPrefix2+"_server_isLeader 1") - require.True(r, found1 || found2, "leader server should have isLeader 1") + respRec3 := httptest.NewRecorder() + recordPromMetrics(r, s3, respRec3) + found3 := strings.Contains(respRec3.Body.String(), metricsPrefix3+"_server_isLeader 1") + + require.True(r, found1 || found2 || found3, "leader server should have isLeader 1") }) }) } From 4edf3693138aa258119382da1998cd5413a0dbfe Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 3 Jun 2024 15:09:59 -0400 Subject: [PATCH 057/185] [NET-8953] ci: disable Ent-only nightly tests on CE (#21242) ci: disable Ent-only nightly tests on CE --- .github/workflows/nightly-test-1.14.x.yaml | 234 ------------------ .github/workflows/nightly-test-1.15.x.yaml | 9 + .github/workflows/nightly-test-1.17.x.yaml | 9 + .../nightly-test-integrations-1.15.x.yml | 10 +- .../nightly-test-integrations-1.17.x.yml | 10 +- 5 files changed, 36 insertions(+), 236 deletions(-) delete mode 100644 .github/workflows/nightly-test-1.14.x.yaml diff --git a/.github/workflows/nightly-test-1.14.x.yaml b/.github/workflows/nightly-test-1.14.x.yaml deleted file mode 100644 index 8e85e175c2..0000000000 --- a/.github/workflows/nightly-test-1.14.x.yaml +++ /dev/null @@ -1,234 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -name: Nightly Frontend 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 - BRANCH: "release/1.14.x" - BRANCH_NAME: "release-1.14.x" # Used for naming artifacts - GOPRIVATE: github.com/hashicorp # Required for enterprise deps - -jobs: - frontend-test-workspace-node: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: ${{ env.BRANCH }} - - # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 14 - cache: 'yarn' - cache-dependency-path: ./ui/yarn.lock - - - name: Install - id: install - working-directory: ./ui - run: make deps - - - name: Workspace Tests - id: workspace-test - working-directory: ./ui - run: make test-workspace - - - name: Node Tests - id: node-test - working-directory: ./ui/packages/consul-ui - run: make test-node - - frontend-build-ce: - runs-on: ubuntu-latest - env: - JOBS: 2 - CONSUL_NSPACES_ENABLED: 0 - steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: ${{ env.BRANCH }} - - # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 14 - cache: 'yarn' - cache-dependency-path: ./ui/yarn.lock - - - name: Install - id: install - working-directory: ./ui - run: make deps - - - name: Ember Build CE - id: build-ce - working-directory: ./ui/packages/consul-ui - run: make build-ci - - - name: Upload CE Frontend - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - with: - name: frontend-ce-${{ env.BRANCH_NAME }} - path: ./ui/packages/consul-ui/dist - if-no-files-found: error - - frontend-test-ce: - runs-on: ubuntu-latest - needs: [frontend-build-ce] - strategy: - matrix: - partition: [ 1, 2, 3, 4 ] - env: - CONSUL_NSPACES_ENABLED: 0 - 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: ${{ env.BRANCH }} - - # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 14 - cache: 'yarn' - cache-dependency-path: ./ui/yarn.lock - - - name: Install - id: install - working-directory: ./ui - run: make deps - - - name: Download CE Frontend - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - with: - name: frontend-ce-${{ env.BRANCH_NAME }} - path: ./ui/packages/consul-ui/dist - - - name: Ember Test CE - id: cache - working-directory: ./ui/packages/consul-ui - run: node_modules/.bin/ember exam --split=$EMBER_PARTITION_TOTAL --partition=${{ matrix.partition }} --path dist --silent -r xunit - - frontend-build-ent: - runs-on: ubuntu-latest - env: - JOBS: 2 - CONSUL_NSPACES_ENABLED: 1 - steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: ${{ env.BRANCH }} - - # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 14 - cache: 'yarn' - cache-dependency-path: ./ui/yarn.lock - - - name: Install - id: install - working-directory: ./ui - run: make deps - - - name: Ember Build ENT - id: build-ce - working-directory: ./ui/packages/consul-ui - run: make build-ci - - - name: Upload ENT Frontend - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - with: - name: frontend-ent-${{ env.BRANCH_NAME }} - path: ./ui/packages/consul-ui/dist - if-no-files-found: error - - frontend-test-ent: - runs-on: ubuntu-latest - needs: [frontend-build-ent] - strategy: - matrix: - partition: [ 1, 2, 3, 4 ] - env: - CONSUL_NSPACES_ENABLED: 1 - 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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: ${{ env.BRANCH }} - - # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 14 - cache: 'yarn' - cache-dependency-path: ./ui/yarn.lock - - - name: Install - id: install - working-directory: ./ui - run: make deps - - - name: Download ENT Frontend - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - with: - name: frontend-ent-${{ env.BRANCH_NAME }} - path: ./ui/packages/consul-ui/dist - - - name: Ember Test ENT - id: cache - working-directory: ./ui/packages/consul-ui - run: node_modules/.bin/ember exam --split=$EMBER_PARTITION_TOTAL --partition=${{ matrix.partition }} --path dist --silent -r xunit - - frontend-test-coverage-ent: - runs-on: ubuntu-latest - needs: [frontend-build-ent] - steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - with: - ref: ${{ env.BRANCH }} - - # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: 14 - cache: 'yarn' - cache-dependency-path: ./ui/yarn.lock - - - name: Install - id: install - working-directory: ./ui - run: make deps - - - name: Download ENT Frontend - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - with: - name: frontend-ent-${{ env.BRANCH_NAME }} - path: ./ui/packages/consul-ui/dist - - - name: Run ENT Code Coverage - working-directory: ./ui/packages/consul-ui - run: make test-coverage-ci - - slack-failure-notification: - runs-on: ubuntu-latest - needs: [frontend-test-ce, frontend-test-ent] - if: ${{ failure() }} - steps: - - name: Slack Notification - id: slack - uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 - with: - payload: | - { - "message": "One or more nightly UI 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_UI_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-1.15.x.yaml b/.github/workflows/nightly-test-1.15.x.yaml index c25e25ac57..f8dec0f82e 100644 --- a/.github/workflows/nightly-test-1.15.x.yaml +++ b/.github/workflows/nightly-test-1.15.x.yaml @@ -14,8 +14,15 @@ env: GOPRIVATE: github.com/hashicorp # Required for enterprise deps jobs: + check-ent: + runs-on: ubuntu-latest + if: ${{ endsWith(github.repository, '-enterprise') }} + steps: + - run: echo "Building Enterprise" + frontend-test-workspace-node: runs-on: ubuntu-latest + needs: [check-ent] steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: @@ -45,6 +52,7 @@ jobs: frontend-build-ce: runs-on: ubuntu-latest + needs: [check-ent] env: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 @@ -117,6 +125,7 @@ jobs: frontend-build-ent: runs-on: ubuntu-latest + needs: [check-ent] env: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 diff --git a/.github/workflows/nightly-test-1.17.x.yaml b/.github/workflows/nightly-test-1.17.x.yaml index ad6e49684d..10eb3d9e01 100644 --- a/.github/workflows/nightly-test-1.17.x.yaml +++ b/.github/workflows/nightly-test-1.17.x.yaml @@ -14,8 +14,15 @@ env: GOPRIVATE: github.com/hashicorp # Required for enterprise deps jobs: + check-ent: + runs-on: ubuntu-latest + if: ${{ endsWith(github.repository, '-enterprise') }} + steps: + - run: echo "Building Enterprise" + frontend-test-workspace-node: runs-on: ubuntu-latest + needs: [check-ent] steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: @@ -45,6 +52,7 @@ jobs: frontend-build-ce: runs-on: ubuntu-latest + needs: [check-ent] env: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 @@ -117,6 +125,7 @@ jobs: frontend-build-ent: runs-on: ubuntu-latest + needs: [check-ent] env: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index ead264db26..db72e7814c 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -23,8 +23,15 @@ env: BRANCH_NAME: "release-1.15.x" # Used for naming artifacts jobs: + check-ent: + runs-on: ubuntu-latest + if: ${{ endsWith(github.repository, '-enterprise') }} + steps: + - run: echo "Building Enterprise" + setup: runs-on: ubuntu-latest + needs: [check-ent] name: Setup outputs: compute-small: ${{ steps.runners.outputs.compute-small }} @@ -41,6 +48,7 @@ jobs: run: .github/scripts/get_runner_classes.sh get-go-version: + needs: [check-ent] uses: ./.github/workflows/reusable-get-go-version.yml dev-build: @@ -305,7 +313,7 @@ jobs: - envoy-integration-test - upgrade-integration-test runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} + if: ${{ always() && endsWith(github.repository, '-enterprise') }} steps: - name: evaluate upstream job results run: | diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index dadbb94e02..dfc15a78b7 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -23,8 +23,15 @@ env: BRANCH_NAME: "release-1.17.x" # Used for naming artifacts jobs: + check-ent: + runs-on: ubuntu-latest + if: ${{ endsWith(github.repository, '-enterprise') }} + steps: + - run: echo "Building Enterprise" + setup: runs-on: ubuntu-latest + needs: [check-ent] name: Setup outputs: compute-small: ${{ steps.runners.outputs.compute-small }} @@ -41,6 +48,7 @@ jobs: run: .github/scripts/get_runner_classes.sh get-go-version: + needs: [check-ent] uses: ./.github/workflows/reusable-get-go-version.yml dev-build: @@ -418,7 +426,7 @@ jobs: - upgrade-integration-test - upgrade-integration-test-deployer runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} + if: ${{ always() && endsWith(github.repository, '-enterprise') }} steps: - name: evaluate upstream job results run: | From d3ad840d8c0b1db3d499ced3ebeef694c57f6b15 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 4 Jun 2024 12:46:20 -0400 Subject: [PATCH 058/185] [NET-8953] docs: add backport policy section to CONTRIBUTING (#21252) docs: add backport policy section to CONTRIBUTING Add detail about Consul's backport policy w.r.t. LTS/CE. Also update label docs and remove defunct redirect .md files. --- .github/CONTRIBUTING.md | 19 +++++++++++++------ contributing/INTERNALS.md | 1 - contributing/README.md | 1 - 3 files changed, 13 insertions(+), 8 deletions(-) delete mode 100644 contributing/INTERNALS.md delete mode 100644 contributing/README.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index c6c09d402a..8d5dd6dc4b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -156,13 +156,16 @@ When you're ready to submit a pull request: 5. If there's any reason Consul users might need to know about this change, [add a changelog entry](../docs/contributing/add-a-changelog-entry.md). 6. Add labels to your pull request. A table of commonly use labels is below. - If you have any questions about which to apply, feel free to call it out in the PR or comments. - | Label | When to Use | - | --- | --- | - | `pr/no-changelog` | This PR does not have an intended changelog entry | + If you have any questions about which to apply, feel free to call it out in the PR or comments. Other labels may automatically be added by GitHub Actions CI. + + | Label | When to Use | + |----------------------| --- | + | `pr/no-changelog` | This PR does not have an intended changelog entry | + | `pr/no-backport` | This PR does not have an intended backport target | | `pr/no-metrics-test` | This PR does not require any testing for metrics | - | `backport/1.12.x` | Backport the changes in this PR to the targeted release branch. Consult the [Consul Release Notes](https://www.consul.io/docs/release-notes) page to view active releases. Website documentation merged to the latest release branch is deployed immediately | - Other labels may automatically be added by the Github Action CI. + | `backport/1.12.x` | Backport the changes in this PR to the targeted release branch. Consult the [Consul Release Notes](https://www.consul.io/docs/release-notes) page and [`versions.hcl`](/.release/versions.hcl) to view active releases. Website documentation merged to the latest release branch is deployed immediately. See [backport policy](#backport-policy) for more information. | + | `backport/all` | If contributing a bug fix or other change applicable to all branches, use `backport/all` to target all active branches automatically. See [backport policy](#backport-policy) for more information. | + 7. After you submit, the Consul maintainers team needs time to carefully review your contribution and ensure it is production-ready, considering factors such as: security, backwards-compatibility, potential regressions, etc. @@ -174,6 +177,10 @@ When you're ready to submit a pull request: Assuming the tests pass, the PR will be merged automatically. If the tests fail, it is you responsibility to resolve the issues with backports and request another reviewer. +### Backport Policy + +Consul is maintained as a Community Edition (CE) and an Enterprise product. Bug fixes and patches may be backported to the current major release in CE. In Enterprise, bug fixes and patches may be backported to all maintained releases: the N-2 releases and the 2 latest Long-Term Support (LTS) releases. For more information, refer to Consul’s [LTS documentation](https://developer.hashicorp.com/consul/docs/enterprise/long-term-support). + #### Checklists Some common changes that many PRs require are documented through checklists as diff --git a/contributing/INTERNALS.md b/contributing/INTERNALS.md deleted file mode 100644 index 0deb6675cb..0000000000 --- a/contributing/INTERNALS.md +++ /dev/null @@ -1 +0,0 @@ -Moved to [docs/README.md](../docs/README.md). diff --git a/contributing/README.md b/contributing/README.md deleted file mode 100644 index 5ab5e80d30..0000000000 --- a/contributing/README.md +++ /dev/null @@ -1 +0,0 @@ -Moved to [docs](../docs/README.md). From cb7ae646da7b522725030f5dbea635f85811c280 Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:30:53 -0400 Subject: [PATCH 059/185] docs: add a note for DNS resolver recommendations (#21250) * add a warning to DNS resolver configurations * Update website/content/docs/services/discovery/dns-configuration.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/services/discovery/dns-configuration.mdx Co-authored-by: Blake Covarrubias * add references todo --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: Blake Covarrubias --- website/content/docs/services/discovery/dns-configuration.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/website/content/docs/services/discovery/dns-configuration.mdx b/website/content/docs/services/discovery/dns-configuration.mdx index 3ce3205860..5e78494ce7 100644 --- a/website/content/docs/services/discovery/dns-configuration.mdx +++ b/website/content/docs/services/discovery/dns-configuration.mdx @@ -33,6 +33,8 @@ You can specify a list of addresses in the agent's [`recursors`](/consul/docs/ag Nodes that query records outside the `consul.` domain resolve to an upstream DNS. You can specify IP addresses or use `go-sockaddr` templates. Consul resolves IP addresses in the specified order and ignores duplicates. +We recommend that you configure DNS resolvers to point the `consul.` domain towards your Consul DNS servers. Misconfigurations may cause other DNS infrastructure to route queries for the `consul.` domain outside of your network instead, leaking DNS queries to root DNS servers. Refer to [Forward DNS for Consul Service Discovery](/consul/tutorials/networking/dns-forwarding) for instructions. + ### Enable non-Consul queries You enable non-Consul queries to be resolved by setting Consul as the DNS server for a node and providing a [`recursors`](/consul/docs/agent/config/config-files#recursors) configuration. @@ -66,4 +68,4 @@ Responses to pointer record (PTR) queries, such as `.in-addr.arpa.`, always ### Caching -By default, DNS results served by Consul are not cached. Refer to [DNS caching](/consul/docs/services/discovery/dns-cache) for instructions on how to enable caching. \ No newline at end of file +By default, DNS results served by Consul are not cached. Refer to [DNS caching](/consul/docs/services/discovery/dns-cache) for instructions on how to enable caching. From 68a7648d14c1ed1b25ce17c7aea7ba4f5800858f Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:55:53 -0400 Subject: [PATCH 060/185] security: resolve incorrect type conversions (#21251) * security: resolve incorrect type conversions * add changelog * fix more incorrect type conversions --- .changelog/21251.txt | 3 +++ agent/consul/leader_registrator_v2.go | 4 ++++ agent/xds/proxystateconverter/endpoints.go | 15 +++++++++------ agent/xds/proxystateconverter/listeners.go | 21 ++++++++++++--------- agent/xds/response/response.go | 17 ++++++++++------- agent/xds/testing.go | 6 +++--- api/api.go | 7 +++++++ 7 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 .changelog/21251.txt diff --git a/.changelog/21251.txt b/.changelog/21251.txt new file mode 100644 index 0000000000..ff4ef7cf23 --- /dev/null +++ b/.changelog/21251.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix multiple incorrect type conversion for potential overflows +``` diff --git a/agent/consul/leader_registrator_v2.go b/agent/consul/leader_registrator_v2.go index 97465e10d1..671fcc85d1 100644 --- a/agent/consul/leader_registrator_v2.go +++ b/agent/consul/leader_registrator_v2.go @@ -175,6 +175,10 @@ func (r V2ConsulRegistrator) createWorkloadFromMember(member serf.Member, parts workloadMeta["grpc_tls_port"] = strconv.Itoa(parts.ExternalGRPCTLSPort) } + if parts.Port < 0 || parts.Port > 65535 { + return nil, fmt.Errorf("invalid port: %d", parts.Port) + } + workload := &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ {Host: member.Addr.String(), Ports: []string{consulPortNameServer}}, diff --git a/agent/xds/proxystateconverter/endpoints.go b/agent/xds/proxystateconverter/endpoints.go index 2ed7164316..4e8f14d9cf 100644 --- a/agent/xds/proxystateconverter/endpoints.go +++ b/agent/xds/proxystateconverter/endpoints.go @@ -301,14 +301,17 @@ func (s *Converter) filterSubsetEndpoints(subset *structs.ServiceResolverSubset, // 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), + if port >= 0 && port <= 65535 { + return &pbproxystate.Endpoint{ + Address: &pbproxystate.Endpoint_HostPort{ + HostPort: &pbproxystate.HostPortAddress{ + Host: host, + Port: uint32(port), + }, }, - }, + } } + return nil } func makeUnixSocketEndpoint(path string) *pbproxystate.Endpoint { diff --git a/agent/xds/proxystateconverter/listeners.go b/agent/xds/proxystateconverter/listeners.go index 11e966223b..7b4faeade5 100644 --- a/agent/xds/proxystateconverter/listeners.go +++ b/agent/xds/proxystateconverter/listeners.go @@ -764,17 +764,20 @@ func makeListenerWithDefault(opts makeListenerOpts) *pbproxystate.Listener { // // 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), + if opts.port >= 0 && opts.port <= 65535 { + 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, + Direction: opts.direction, + } } + return nil } func makePipeListener(opts makeListenerOpts) *pbproxystate.Listener { diff --git a/agent/xds/response/response.go b/agent/xds/response/response.go index cc6f132eb6..5b5d8de364 100644 --- a/agent/xds/response/response.go +++ b/agent/xds/response/response.go @@ -53,16 +53,19 @@ func MakePipeAddress(path string, mode uint32) *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{ - Address: ip, - PortSpecifier: &envoy_core_v3.SocketAddress_PortValue{ - PortValue: uint32(port), + if port >= 0 && port <= 65535 { + return &envoy_core_v3.Address{ + Address: &envoy_core_v3.Address_SocketAddress{ + SocketAddress: &envoy_core_v3.SocketAddress{ + Address: ip, + PortSpecifier: &envoy_core_v3.SocketAddress_PortValue{ + PortValue: uint32(port), + }, }, }, - }, + } } + return nil } func MakeUint32Value(n int) *wrapperspb.UInt32Value { diff --git a/agent/xds/testing.go b/agent/xds/testing.go index 916bbd9b50..6d90005cd7 100644 --- a/agent/xds/testing.go +++ b/agent/xds/testing.go @@ -125,15 +125,15 @@ func stringToEnvoyVersion(vs string) (*envoy_type_v3.SemanticVersion, bool) { return nil, false } - major, err := strconv.Atoi(parts[0]) + major, err := strconv.ParseUint(parts[0], 10, 32) if err != nil { return nil, false } - minor, err := strconv.Atoi(parts[1]) + minor, err := strconv.ParseUint(parts[1], 10, 32) if err != nil { return nil, false } - patch, err := strconv.Atoi(parts[2]) + patch, err := strconv.ParseUint(parts[2], 10, 32) if err != nil { return nil, false } diff --git a/api/api.go b/api/api.go index b90a45d92b..d4d853d5d4 100644 --- a/api/api.go +++ b/api/api.go @@ -10,6 +10,7 @@ import ( "encoding/json" "fmt" "io" + "math" "net" "net/http" "net/url" @@ -1181,6 +1182,9 @@ func parseQueryMeta(resp *http.Response, q *QueryMeta) error { if err != nil { return fmt.Errorf("Failed to parse X-Consul-LastContact: %v", err) } + if last > math.MaxInt64 { + return fmt.Errorf("X-Consul-LastContact Header value is out of range: %d", last) + } q.LastContact = time.Duration(last) * time.Millisecond // Parse the X-Consul-KnownLeader @@ -1222,6 +1226,9 @@ func parseQueryMeta(resp *http.Response, q *QueryMeta) error { if err != nil { return fmt.Errorf("Failed to parse Age Header: %v", err) } + if age > math.MaxInt64 { + return fmt.Errorf("Age Header value is out of range: %d", last) + } q.CacheAge = time.Duration(age) * time.Second } From 9e23fa78403a50a624d22a5774e975ef2b019a37 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Wed, 5 Jun 2024 13:31:43 -0400 Subject: [PATCH 061/185] [NET-9445] chore: update submodule versions (#21263) chore: update submodule versions - Update submodule versions that were released - Add missing replace directive to troubleshoot submodule --- api/go.mod | 4 ++-- envoyextensions/go.mod | 4 ++-- go.mod | 10 +++++----- test-integ/go.mod | 6 +++--- test/integration/consul-container/go.mod | 8 ++++---- testing/deployer/go.mod | 4 ++-- troubleshoot/go.mod | 7 ++++--- troubleshoot/go.sum | 2 -- 8 files changed, 22 insertions(+), 23 deletions(-) diff --git a/api/go.mod b/api/go.mod index 611bc20695..0a1f7fee6f 100644 --- a/api/go.mod +++ b/api/go.mod @@ -11,8 +11,8 @@ retract v1.28.0 // tag was mutated require ( github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/proto-public v0.5.1 - github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 diff --git a/envoyextensions/go.mod b/envoyextensions/go.mod index 8531affc75..c9bb9cb6f0 100644 --- a/envoyextensions/go.mod +++ b/envoyextensions/go.mod @@ -11,8 +11,8 @@ replace ( require ( github.com/envoyproxy/go-control-plane v0.12.0 github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/api v1.29.1 + github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.2.1 diff --git a/go.mod b/go.mod index de1ee7a0c3..d658f8141b 100644 --- a/go.mod +++ b/go.mod @@ -43,11 +43,11 @@ require ( github.com/hashi-derek/grpc-proxy v0.0.0-20231207191910-191266484d75 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.26.1 - github.com/hashicorp/consul/envoyextensions v0.5.1 - github.com/hashicorp/consul/proto-public v0.5.1 - github.com/hashicorp/consul/sdk v0.15.0 - github.com/hashicorp/consul/troubleshoot v0.4.1 + github.com/hashicorp/consul/api v1.29.1 + github.com/hashicorp/consul/envoyextensions v0.7.0 + github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/sdk v0.16.1 + github.com/hashicorp/consul/troubleshoot v0.6.1 github.com/hashicorp/go-bexpr v0.1.2 github.com/hashicorp/go-checkpoint v0.5.0 github.com/hashicorp/go-cleanhttp v0.5.2 diff --git a/test-integ/go.mod b/test-integ/go.mod index c3f9f3a201..df821c307a 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -4,9 +4,9 @@ go 1.20 require ( github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/proto-public v0.5.1 - github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/api v1.29.1 + github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/sdk v0.16.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 diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index 4bd2e49e6b..b3fbbe068c 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -10,10 +10,10 @@ require ( github.com/evanphx/json-patch v4.12.0+incompatible github.com/go-jose/go-jose/v3 v3.0.3 github.com/hashicorp/consul v1.16.1 - github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/envoyextensions v0.5.1 - github.com/hashicorp/consul/proto-public v0.5.1 - github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/api v1.29.1 + github.com/hashicorp/consul/envoyextensions v0.7.0 + github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/sdk v0.16.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 diff --git a/testing/deployer/go.mod b/testing/deployer/go.mod index 50bec10ad4..0dd3855e3b 100644 --- a/testing/deployer/go.mod +++ b/testing/deployer/go.mod @@ -7,8 +7,8 @@ require ( github.com/google/go-cmp v0.5.9 github.com/hashicorp/consul-server-connection-manager v0.1.4 github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/proto-public v0.5.1 - github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 diff --git a/troubleshoot/go.mod b/troubleshoot/go.mod index fe9a0b36f7..9af318f62f 100644 --- a/troubleshoot/go.mod +++ b/troubleshoot/go.mod @@ -6,6 +6,7 @@ replace ( 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 ) exclude ( @@ -16,9 +17,9 @@ exclude ( require ( github.com/envoyproxy/go-control-plane v0.12.0 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e - github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/envoyextensions v0.5.1 - github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/api v1.29.1 + github.com/hashicorp/consul/envoyextensions v0.7.0 + github.com/hashicorp/consul/sdk v0.16.1 github.com/stretchr/testify v1.8.4 google.golang.org/protobuf v1.33.0 ) diff --git a/troubleshoot/go.sum b/troubleshoot/go.sum index c7b39b0299..eb39bb30fa 100644 --- a/troubleshoot/go.sum +++ b/troubleshoot/go.sum @@ -61,8 +61,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw 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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU= -github.com/hashicorp/consul/sdk v0.15.0/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo= 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= From 2631ec843a0f1d203f07dbbeac7d373b7b609010 Mon Sep 17 00:00:00 2001 From: Dhia Ayachi Date: Thu, 6 Jun 2024 10:46:05 -0400 Subject: [PATCH 062/185] update go version to 1.22.4 (#21265) * update go version to 1.22.4 * add changelog --- .changelog/21265.txt | 3 +++ .go-version | 2 +- go.mod | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .changelog/21265.txt diff --git a/.changelog/21265.txt b/.changelog/21265.txt new file mode 100644 index 0000000000..fdf600e70c --- /dev/null +++ b/.changelog/21265.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +upgrade go version to v1.22.4. +``` diff --git a/.go-version b/.go-version index 98f7da137c..2a0ba77cc5 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.22.3 \ No newline at end of file +1.22.4 diff --git a/go.mod b/go.mod index d658f8141b..bd1a87799a 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/hashicorp/consul go 1.20 -toolchain go1.22.3 +toolchain go1.22.4 replace ( github.com/hashicorp/consul/api => ./api From ffa7aff2073d91cd68559519be6a3ab64272dd1f Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 6 Jun 2024 12:20:05 -0400 Subject: [PATCH 063/185] [NET-8971] docs: update LTS Envoy versions to include 1.29.4 (#21271) docs: update LTS Envoy versions to include 1.29.4 --- website/content/docs/connect/proxies/envoy.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/connect/proxies/envoy.mdx b/website/content/docs/connect/proxies/envoy.mdx index eb3ddd4fea..79eab9e576 100644 --- a/website/content/docs/connect/proxies/envoy.mdx +++ b/website/content/docs/connect/proxies/envoy.mdx @@ -72,8 +72,8 @@ until the LTS release reaches its end of maintenance. | Consul Version | Compatible Envoy Versions | | -------------- | -----------------------------------------------------------------------------------| -| 1.18.x Ent | 1.28.3, 1.27.5, 1.26.8, 1.25.11 | -| 1.15.x Ent | 1.28.3, 1.27.5, 1.26.8, 1.25.11, 1.24.12, 1.23.12, 1.22.11 | +| 1.18.x Ent | 1.29.4, 1.28.3, 1.27.5, 1.26.8, 1.25.11 | +| 1.15.x Ent | 1.29.4, 1.27.5, 1.26.8, 1.25.11, 1.24.12, 1.23.12, 1.22.11 | ### Envoy and Consul Dataplane From 2cdc387bd36e0c68a7255aa9a54d581bb2eb179d Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Mon, 10 Jun 2024 10:29:26 -0500 Subject: [PATCH 064/185] Bump Envoy Versions (#21277) * update envoy versions * add changelog * update nightly integrations --- .changelog/21277.txt | 3 +++ .github/workflows/nightly-test-integ-peering_commontopo.yml | 2 +- .github/workflows/nightly-test-integrations-1.15.x.yml | 2 +- .github/workflows/nightly-test-integrations-1.17.x.yml | 2 +- .github/workflows/nightly-test-integrations-1.18.x.yml | 4 ++-- .github/workflows/nightly-test-integrations-1.19.x.yml | 4 ++-- .github/workflows/nightly-test-integrations.yml | 2 +- .github/workflows/test-integrations.yml | 6 +++--- Makefile | 2 +- envoyextensions/xdscommon/envoy_versioning_test.go | 6 +++--- envoyextensions/xdscommon/proxysupport.go | 6 +++--- test/integration/connect/envoy/run-tests.sh | 2 +- 12 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 .changelog/21277.txt diff --git a/.changelog/21277.txt b/.changelog/21277.txt new file mode 100644 index 0000000000..a14a5aab20 --- /dev/null +++ b/.changelog/21277.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +mesh: update supported envoy version 1.29.5 in addition to 1.28.4, 1.27.6. +``` \ No newline at end of file diff --git a/.github/workflows/nightly-test-integ-peering_commontopo.yml b/.github/workflows/nightly-test-integ-peering_commontopo.yml index 3d407a7c3c..84b8a97c1c 100644 --- a/.github/workflows/nightly-test-integ-peering_commontopo.yml +++ b/.github/workflows/nightly-test-integ-peering_commontopo.yml @@ -62,7 +62,7 @@ jobs: name: '${{matrix.test-case}}' env: - ENVOY_VERSION: "1.29.4" + ENVOY_VERSION: "1.29.5" steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index db72e7814c..db6607bda5 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -117,7 +117,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.5", "1.28.3"] + envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.6", "1.28.4"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index dfc15a78b7..c848c7f8fe 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -117,7 +117,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] + envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations-1.18.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml index 9d6ec0d5fd..ee39c4f499 100644 --- a/.github/workflows/nightly-test-integrations-1.18.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -74,7 +74,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.8", "1.27.5"] + # envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -109,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] + envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml index 7acb1903a9..876539046f 100644 --- a/.github/workflows/nightly-test-integrations-1.19.x.yml +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -74,7 +74,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.8", "1.27.5"] + # envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -109,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.5"] + envoy-version: ["1.26.8", "1.27.6", "1.28.5", "1.29.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index 8634f7613a..bf914f8893 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -106,7 +106,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.26.8", "1.27.5", "1.28.3", "1.29.4"] + envoy-version: ["1.26.8", "1.27.6", "1.28.4", "1.29.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 20f169d6f4..cae4e9f591 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -272,7 +272,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 2 based on these values: - # envoy-version: ["1.29.4"] + # envoy-version: ["1.29.5"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 2 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -307,7 +307,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.29.4"] + envoy-version: ["1.29.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -397,7 +397,7 @@ jobs: id-token: write # NOTE: this permission is explicitly required for Vault auth. contents: read env: - ENVOY_VERSION: "1.29.4" + ENVOY_VERSION: "1.29.5" CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi" steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/Makefile b/Makefile index 1e643d9e4a..b4bf3807b9 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ CONSUL_IMAGE_VERSION?=latest # When changing the method of Go version detection, also update # version detection in CI workflows (reusable-get-go-version.yml). GOLANG_VERSION?=$(shell head -n 1 .go-version) -ENVOY_VERSION?='1.29.4' +ENVOY_VERSION?='1.29.5' CONSUL_DATAPLANE_IMAGE := $(or $(CONSUL_DATAPLANE_IMAGE),"docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi") DEPLOYER_CONSUL_DATAPLANE_IMAGE := $(or $(DEPLOYER_CONSUL_DATAPLANE_IMAGE), "docker.io/hashicorppreview/consul-dataplane:1.3-dev") diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go index ab3290e576..cca8f88f78 100644 --- a/envoyextensions/xdscommon/envoy_versioning_test.go +++ b/envoyextensions/xdscommon/envoy_versioning_test.go @@ -152,9 +152,9 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { */ for _, v := range []string{ "1.26.0", "1.26.1", "1.26.2", "1.26.3", "1.26.4", "1.26.5", "1.26.6", "1.26.7", "1.26.8", - "1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", "1.27.5", - "1.28.0", "1.28.1", "1.28.2", "1.28.3", - "1.29.0", "1.29.1", "1.29.2", "1.29.3", "1.29.4", + "1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", "1.27.5", "1.27.6", + "1.28.0", "1.28.1", "1.28.2", "1.28.3", "1.28.4", + "1.29.0", "1.29.1", "1.29.2", "1.29.3", "1.29.4", "1.29.5", } { cases[v] = testcase{expect: SupportedProxyFeatures{}} } diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go index 1f71770305..77c1da0ad5 100644 --- a/envoyextensions/xdscommon/proxysupport.go +++ b/envoyextensions/xdscommon/proxysupport.go @@ -12,9 +12,9 @@ import "strings" // // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions var EnvoyVersions = []string{ - "1.29.4", - "1.28.3", - "1.27.5", + "1.29.5", + "1.28.4", + "1.27.6", "1.26.8", } diff --git a/test/integration/connect/envoy/run-tests.sh b/test/integration/connect/envoy/run-tests.sh index 0f0365215a..1f825268b0 100755 --- a/test/integration/connect/envoy/run-tests.sh +++ b/test/integration/connect/envoy/run-tests.sh @@ -15,7 +15,7 @@ DEBUG=${DEBUG:-} XDS_TARGET=${XDS_TARGET:-server} # ENVOY_VERSION to run each test against -ENVOY_VERSION=${ENVOY_VERSION:-"1.29.4"} +ENVOY_VERSION=${ENVOY_VERSION:-"1.29.5"} export ENVOY_VERSION export DOCKER_BUILDKIT=1 From 3c25956f61aeaab146bd11512a7fa78c48d6d3fd Mon Sep 17 00:00:00 2001 From: Will Jordan Date: Mon, 10 Jun 2024 11:41:48 -0700 Subject: [PATCH 065/185] Fix broken link in wal-logstore/index.mdx (#21286) Content was moved in #21099. --- website/content/docs/agent/wal-logstore/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/content/docs/agent/wal-logstore/index.mdx b/website/content/docs/agent/wal-logstore/index.mdx index 77dc1dd058..b215db158c 100644 --- a/website/content/docs/agent/wal-logstore/index.mdx +++ b/website/content/docs/agent/wal-logstore/index.mdx @@ -32,7 +32,7 @@ To mitigate risks associated with sudden bursts of log data, Consul tries to lim But the larger the file, the more likely it is to have a large freelist or suddenly form one after a burst of writes. For this reason, the many of Consul's default options associated with snapshots, truncating logs, and keeping the log history aggressively keep BoltDT small rather than using disk IO more efficiently. -Other reliability issues, such as [raft replication capacity issues](/consul/docs/agent/telemetry#raft-replication-capacity-issues), are much simpler to solve without the performance concerns caused by storing more logs in BoltDB. +Other reliability issues, such as [raft replication capacity issues](/consul/docs/agent/monitor/telemetry#raft-replication-capacity-issues), are much simpler to solve without the performance concerns caused by storing more logs in BoltDB. ### WAL approaches storage issues differently From fe2f8f1c722f883552bd44a783712f3b156865ee Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Mon, 10 Jun 2024 16:21:58 -0400 Subject: [PATCH 066/185] docs: remove multiport docs, add v1dns flag (#21278) * docs: remove multiport docs, add v1dns flag * v2 catalog notice + redirects * redirect fixes * Update website/content/docs/k8s/helm.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: boruszak Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- website/content/commands/resource.mdx | 391 -------- website/content/docs/architecture/catalog.mdx | 4 +- .../content/docs/architecture/v2/catalog.mdx | 61 -- .../content/docs/architecture/v2/groups.mdx | 51 - .../content/docs/architecture/v2/index.mdx | 77 -- website/content/docs/install/ports.mdx | 2 - website/content/docs/k8s/helm.mdx | 19 +- .../content/docs/k8s/multiport/configure.mdx | 491 ---------- website/content/docs/k8s/multiport/index.mdx | 70 -- .../k8s/multiport/reference/grpcroute.mdx | 808 --------------- .../k8s/multiport/reference/httproute.mdx | 925 ------------------ .../reference/proxyconfiguration.mdx | 691 ------------- .../docs/k8s/multiport/reference/tcproute.mdx | 345 ------- .../reference/trafficpermissions.mdx | 245 ----- .../docs/k8s/multiport/traffic-split.mdx | 113 --- .../docs/release-notes/consul/v1_17_x.mdx | 4 +- .../content/docs/security/acl/acl-rules.mdx | 43 - website/data/commands-nav-data.json | 9 - website/data/docs-nav-data.json | 59 -- website/redirects.js | 39 +- 20 files changed, 26 insertions(+), 4421 deletions(-) delete mode 100644 website/content/commands/resource.mdx delete mode 100644 website/content/docs/architecture/v2/catalog.mdx delete mode 100644 website/content/docs/architecture/v2/groups.mdx delete mode 100644 website/content/docs/architecture/v2/index.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/k8s/multiport/reference/grpcroute.mdx delete mode 100644 website/content/docs/k8s/multiport/reference/httproute.mdx delete mode 100644 website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx delete mode 100644 website/content/docs/k8s/multiport/reference/tcproute.mdx delete mode 100644 website/content/docs/k8s/multiport/reference/trafficpermissions.mdx delete mode 100644 website/content/docs/k8s/multiport/traffic-split.mdx diff --git a/website/content/commands/resource.mdx b/website/content/commands/resource.mdx deleted file mode 100644 index 80bc28d611..0000000000 --- a/website/content/commands/resource.mdx +++ /dev/null @@ -1,391 +0,0 @@ ---- -layout: commands -page_title: 'Commands: Resource' -description: >- - The `consul resource` command interacts with Consul's v2 catalog of services and its resources. It exposes top-level commands for reading and filtering data from the registry. ---- - -# Consul Resource - -Command: `consul resource` - - - -You must enable the [v2 catalog API](/consul/docs/concept/catalog/v2) to use this command. - - - -Use the `resource` command to apply, list, read, and delete resources when interacting with Consul's v2 catalog through the command line. For more information, refer to [v2 catalog API](/consul/docs/concept/catalog/v2). - -## Usage - -```text -Usage: consul resource [options] - - # ... - -Subcommands: - - apply Write or update resource information - delete Delete resource information - list Read all resources by type - read Read resource information -``` - -## Subcommands - -You can issue the following subcommands with the `consul resource` command. - -### `apply` - -`consul resource apply` writes or updates a resource at a given file path. - -The following table shows the required [ACLs permission](/consul/api-docs/api-structure#authentication) to run the `apply` command: - -| ACL Required | -| ------------ | -| `operator:write` | - -#### Command Options - -- `-f=` - (Required) The path to the file that defines the Consul resource. When the file that defines the resource is in the current working directory, you may optionally omit this flag and pass the resource filename only. - -#### Example usage - -The following command applies a traffic permissions resource to Consul that restricts service-to-service communication to authorized services only. - -```shell-session hideClipboard -$ consul resource apply -f=trafficpermissions.hcl -``` - -### `delete` - -`consul resource delete` removes a Consul resource at a given file path. - -The following table shows the required [ACL permissions](/consul/api-docs/api-structure#authentication) to run the `delete` command: - -| ACL Required | -| ------------ | -| `operator:write` | - -#### Command Options - -- `-f=` - (Required) The path to the file that defines the Consul resource. When the file that defines the resource is in the current working directory, you may optionally omit this flag and pass the resource filename only. - -#### Example usage - -The following command removes a traffic permissions resource from Consul that restricts service-to-service communication to authorized services only. - -```shell-session hideClipboard -$ consul resource delete -f=trafficpermissions.hcl -``` - -### `list` - -`consul resource list` outputs information about resources according to the type of resource and the location where the resource is applied. - -This command must be issued with a resource type. By formatting the type on the command line as `group.groupVersion.kind`, you can return all matching resources. For example, you can list information about services with `catalog.v2beta1.Service` and TCP routes with `mesh.v2beta1.TCPRoute`. Refer to [v2 catalog](/consul/docs/architecture/v2/catalog#catalog-structure) for more information. - -Do not include a resource name when listing resources. - -The following table shows the required [ACL permissions](/consul/api-docs/api-structure#authentication) to run the `list` command: - -| ACL Required | -| ------------ | -| `operator:read` | - -#### Command Options - -The following flags enable you to filter results. - -- `-partition=` - The partition where the resources apply. -- `-namespace=` - The namespace where the resources apply. - -#### Example usage - -The following command lists resources that apply to services registered with the v2 catalog API, and includes a sample output for the `api` and `web` services registered in [configure multi-port services](/consul/docs/k8s/multiport/configure): - -```shell-session hideClipboard -$ consul resource list catalog.v2beta1.Service - -{ - "resources": [ - { - "data": { - "ports": [ - { - "protocol": "PROTOCOL_TCP", - "targetPort": "api", - "virtualPort": 80 - }, - { - "protocol": "PROTOCOL_MESH", - "targetPort": "mesh" - } - ], - "virtualIps": [ - "10.96.216.242" - ], - "workloads": { - "prefixes": [ - "api-7c86cd8cb9" - ] - } - }, - "generation": "01HE8QWYFCTNEC2Q5JXKNXH6QW", - "id": { - "name": "api", - "tenancy": { - "namespace": "default", - "partition": "default", - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "Service" - }, - "uid": "01HE8QWYFCTNEC2Q5JXJ97M429" - }, - "metadata": { - "k8s-namespace": "default", - "managed-by": "consul-k8s-endpoints-controller-v2" - }, - "status": { - "consul.io/endpoint-manager": { - "conditions": [ - { - "message": "A valid workload selector is present within the service.", - "reason": "SelectorFound", - "state": "STATE_TRUE", - "type": "EndpointsManaged" - }, - { - "message": "Found workload identities associated with this service: \"api\".", - "reason": "WorkloadIdentitiesFound", - "state": "STATE_TRUE", - "type": "BoundIdentities" - } - ], - "observedGeneration": "01HE8QWYFCTNEC2Q5JXKNXH6QW", - "updatedAt": "2023-11-02T19:24:27.295564638Z" - } - }, - "version": "118" - }, - { - "data": { - "ports": [ - { - "protocol": "PROTOCOL_TCP", - "targetPort": "admin", - "virtualPort": 90 - }, - { - "protocol": "PROTOCOL_MESH", - "targetPort": "mesh" - } - ], - "virtualIps": [ - "10.96.231.41" - ], - "workloads": { - "prefixes": [ - "api-7c86cd8cb9" - ] - } - }, - "generation": "01HE8QWYFJCXYXT2F4SBZE95Q4", - "id": { - "name": "api-admin", - "tenancy": { - "namespace": "default", - "partition": "default", - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "Service" - }, - "uid": "01HE8QWYFJCXYXT2F4SAHV7KG8" - }, - "metadata": { - "k8s-namespace": "default", - "managed-by": "consul-k8s-endpoints-controller-v2" - }, - "status": { - "consul.io/endpoint-manager": { - "conditions": [ - { - "message": "A valid workload selector is present within the service.", - "reason": "SelectorFound", - "state": "STATE_TRUE", - "type": "EndpointsManaged" - }, - { - "message": "Found workload identities associated with this service: \"api\".", - "reason": "WorkloadIdentitiesFound", - "state": "STATE_TRUE", - "type": "BoundIdentities" - } - ], - "observedGeneration": "01HE8QWYFJCXYXT2F4SBZE95Q4", - "updatedAt": "2023-11-02T19:24:27.589881680Z" - } - }, - "version": "122" - }, - { - "data": { - "ports": [ - { - "protocol": "PROTOCOL_TCP", - "targetPort": "80", - "virtualPort": 80 - }, - { - "protocol": "PROTOCOL_MESH", - "targetPort": "mesh" - } - ], - "virtualIps": [ - "10.96.157.170" - ], - "workloads": { - "prefixes": [ - "web-6fd5c8bf57" - ] - } - }, - "generation": "01HE8QWYA9RSW2RS8GS5P538ZB", - "id": { - "name": "web", - "tenancy": { - "namespace": "default", - "partition": "default", - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "Service" - }, - "uid": "01HE8QWYA9RSW2RS8GS3922SK0" - }, - "metadata": { - "k8s-namespace": "default", - "managed-by": "consul-k8s-endpoints-controller-v2" - }, - "status": { - "consul.io/endpoint-manager": { - "conditions": [ - { - "message": "A valid workload selector is present within the service.", - "reason": "SelectorFound", - "state": "STATE_TRUE", - "type": "EndpointsManaged" - }, - { - "message": "Found workload identities associated with this service: \"web\".", - "reason": "WorkloadIdentitiesFound", - "state": "STATE_TRUE", - "type": "BoundIdentities" - } - ], - "observedGeneration": "01HE8QWYA9RSW2RS8GS5P538ZB", - "updatedAt": "2023-11-02T19:24:27.190972222Z" - } - }, - "version": "115" - } - ] -} -``` - -### `read` - -`consul resource read` outputs information about resources according to the type and name of the resource. - -This command must be issued with a resource type and a resource name. By formatting the type on the command line as `group.groupVersion.kind`, you can return all matching resources. For example, you can read information about services with `catalog.v2beta1.Service`, TCP routes with `mesh.v2beta1.TCPRoute`, and traffic permissions with `auth.v2beta1.TrafficPermissions`. Refer to [v2 catalog](/consul/docs/architecture/v2/catalog#catalog-structure) for more information. - -The following table shows the required [ACL permissions](/consul/api-docs/api-structure#authentication) to run the `read` command: - -| ACL Required | -| ------------ | -| `operator:read` | - -#### Command Options - -- `-partition=` - The partition where the resource applies. -- `-namespace=` - The namespace where the resource applies. -- `-stale` - Permits any Consul server to respond to the request. This flag enables for lower latency and higher throughput, but may result in stale data. This option has no effect on non-read operations. -- `-token` - A Consul ACL token to include with the request. - -#### Example usage - -The following example demonstrates a command to read the `web` service and includes an example output that includes information such as ports, virtual IPs, and status. - -```shell-session hideClipboard -$ consul resource read catalog.v2beta1.Service web - -{ - "data": { - "ports": [ - { - "protocol": "PROTOCOL_TCP", - "targetPort": "80", - "virtualPort": 80 - }, - { - "protocol": "PROTOCOL_MESH", - "targetPort": "mesh" - } - ], - "virtualIps": [ - "10.96.98.157" - ], - "workloads": { - "prefixes": [ - "web-6fd5c8bf57" - ] - } - }, - "generation": "01HE6MPDXC1J6ZMEMPN1460Z6K", - "id": { - "name": "web", - "tenancy": { - "namespace": "default", - "partition": "default", - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "Service" - }, - "uid": "01HE6MPDXC1J6ZMEMPN0648FVB" - }, - "metadata": { - "k8s-namespace": "default", - "managed-by": "consul-k8s-endpoints-controller-v2" - }, - "status": { - "consul.io/endpoint-manager": { - "conditions": [ - { - "message": "A valid workload selector is present within the service.", - "reason": "SelectorFound", - "state": "STATE_TRUE", - "type": "EndpointsManaged" - }, - { - "message": "Found workload identities associated with this service: \"web\".", - "reason": "WorkloadIdentitiesFound", - "state": "STATE_TRUE", - "type": "BoundIdentities" - } - ], - "observedGeneration": "01HE6MPDXC1J6ZMEMPN1460Z6K", - "updatedAt": "2023-11-01T23:49:59.172604219Z" - } - }, - "version": "137" -} -``` diff --git a/website/content/docs/architecture/catalog.mdx b/website/content/docs/architecture/catalog.mdx index ba3ee8933f..dad1ef9ace 100644 --- a/website/content/docs/architecture/catalog.mdx +++ b/website/content/docs/architecture/catalog.mdx @@ -14,7 +14,9 @@ For more information about the information returned when querying the catalog, i Consul tracks information about registered services through its catalog API. This API records user-defined information about the external services, such as their partitions and required health checks. It also records information that Consul assigns for its own operations, such as an ID for each service instance and the [Raft indices](/consul/docs/architecture/consensus) when the instance is registered and modified. -Consul uses v1 of the catalog API by default. Consul v1.17.0 and later ships with version 2 (v2) of the catalog API. V2 is intended for testing and development purposes. V1 and V2 of the catalog APIs cannot run concurrently in a Consul deployment. There is no migration path between catalog versions. For more information, refer to [Consul v2 Catalog API](/consul/docs/architecture/v2/catalog). +### v2 Catalog + +Consul introduced an experimental v2 Catalog API in v1.17.0. This API supported multi-port Service configurations on Kubernetes, and it was made available for testing and development purposes. The v2 catalog and its support for multiport Kubernetes Services were deprecated in the v1.19.0 release. ## Catalog structure diff --git a/website/content/docs/architecture/v2/catalog.mdx b/website/content/docs/architecture/v2/catalog.mdx deleted file mode 100644 index 2b31bbcbf6..0000000000 --- a/website/content/docs/architecture/v2/catalog.mdx +++ /dev/null @@ -1,61 +0,0 @@ ---- -layout: docs -page_title: Consul catalog v2 architecture -description: Learn about version 2 of the Consul catalog, which uses GAMMA specified resources. Learn how the v2 catalog corresponds to the v1 catalog. ---- - - - -The v2 catalog API and Traffic Permissions API are currently in beta. This documentation supports testing and development scenarios. Do not use these APIs in secure production environments. - - - -# Consul catalog v2 architecture - -This topic provides information about version 2 (v2) of the Consul catalog API. The catalog tracks registered services and their locations for both service discovery and service mesh use cases. - -Consul supports the v2 catalog for service mesh use cases on Kubernetes deployments only. For more information about Consul’s default catalog, refer to [v1 Catalog API](/consul/docs/architecture/catalog). - -## Introduction - -When Consul registers services, it records [user-defined and Consul-assigned information](/consul/docs/architecture/catalog#catalog-structure). To determine a service’s identity, v1 of the catalog API records the following information: - -- IDs of the specific _service instances_ that are registered -- Locations of the _nodes_ the instances run on -- Names of the _services_ the instances are associated with - -This information enables Consul to associate service names with the individual instances and their unique network addresses, which makes it essential to Consul’s service discovery and service mesh operations. - -The [Consul v1 catalog API](/consul/docs/architecture/catalog) was designed prior to the introduction of Consul’s service mesh features. One major implication of this design is that communication in Consul’s service mesh is secured through Consul's ACL system, which requires that a Kubernetes ServiceAccount resource match the Service name. As a result, only one Kubernetes Service can represent a service instance in the v1 catalog. - -The v2 catalog API aligns more closely with the [Kubernetes Gateway API's GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/), which conceptualizes a Kubernetes Service as having two facets: - -- The Service _front end_ is a combination of cluster IP and DNS name -- The Service _back end_ is a collection of endpoint IPs - -For more information about the differences between the two facets and their impact on how Kubernetes directs requests, refer to [The Different Facets of a Service](https://gateway-api.sigs.k8s.io/concepts/service-facets/) in the Kubernetes documentation. - -Consul's v2 catalog API makes a similar distinction, enabling it associate Kubernetes Pods with multiple Kubernetes Services. As a direct result of this change in catalog structure, Consul can register Services and Pods with multiple ports. For more information about how the differences between the catalog API impacts other Consul operations, refer to [changes to Consul's existing architecture](#changes-to-consul-s-existing-architecture). - -The v2 catalog API is available alongside the existing v1 catalog API, but the catalogs cannot be used simultaneously. The v2 catalog is disabled by default. This beta release is for testing and development purposes only. We do not recommend implementing v2 in production environments or migrating to v2 until the API is generally available. - -## Catalog structure - -Consul v1.17 introduces a new version of the catalog API designed to bridge differences between the Consul and Kubernetes data models. The v2 catalog API continues to track services and nodes for Consul, but it replaces service instances with _workloads_ and _workload identities_. - -### Catalog resources - -The following table describes resources in the v2 catalog, how they generally compare to the v1 catalog and Kubernetes resources, and whether they are created by Kubernetes or computed by Consul when it registers a service. - -| Catalog v2 resource | Resource group | Description | Catalog v1 analogue | Kubernetes analogue | Source | -| :------------------ | :------------- | :---------- | :--------------------------- | :--------------------------- | :----- | -| Service | `catalog` | The name of the service Consul registers a workload under. | Service | [Kubernetes Service](https://kubernetes.io/docs/concepts/services-networking/service/) | Created by Kubernetes | -| Node | `catalog` | The address of the Consul node where the workload runs. | Node | [Kubernetes Node](https://kubernetes.io/docs/concepts/architecture/nodes/) | Computed by Consul | -| Workload | `catalog` | An application instance running in a set of one or more Pods scheduled according to a Kubernetes Workload resource such as a Deployment or StatefulSet. | Service instance | [Kubernetes Pod](https://kubernetes.io/docs/concepts/workloads/pods/) | Created by Kubernetes | -| Workload identity | `auth` | Provides a distinct identity for a workload to assume. Each workload identity is tied to an Envoy proxy. This identity is used when Consul generates mTLS certificates. | Service name | [Kubernetes Service Accounts](https://kubernetes.io/docs/concepts/security/service-accounts/) | Created by Kubernetes | -| Service endpoint | Maps services to workload addresses and endpoints. | None | [Kubernetes Endpoints](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoints-v1/) | Computed by Consul | -| Health status | `catalog` | A resource for reporting the health status of a workload. | Service instance health status | [PodStatus](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodStatus) | Created by Kubernetes | -| Health check | None | A resource for defining the health checks for a workload. | [Service instance health check](/consul/docs/services/usage/checks) | [Liveness, Readiness, and Startup Probes](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes) | Created by Kubernetes | -| Proxy configuration | `mesh` | Represents a configuration for a sidecar or gateway proxy. | `Proxy` field in service definition | None | Created by Kubernetes or user CRD | -| Destinations | `catalog` | Represents explicit service upstreams. When using the v1 catalog, these upstreams are configured in Helm chart as [Upstream Service annotations](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-connect-service-upstreams) | [Proxy Configuration](/consul/docs/connect/proxies/envoy#envoy-proxy-configuration-for-service-mesh) | None | Created by Kubernetes | -| Traffic permissions| `auth` | Enables L4 traffic authorization according to workload identity instead of service identity. | [Service intentions](/consul/docs/connect/intentions) | None | Created by user CRD | diff --git a/website/content/docs/architecture/v2/groups.mdx b/website/content/docs/architecture/v2/groups.mdx deleted file mode 100644 index c5d141de06..0000000000 --- a/website/content/docs/architecture/v2/groups.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -layout: docs -page_title: Consul resource groups -description: Learn about resource groups in version 2 of Consul's internal architecture. The auth, catalog, and mesh groups structure Consul's ability to target individual workloads or an entire collection of workload endpoints. ---- - - - -The v2 catalog API and Traffic Permissions API are currently in beta. This documentation supports testing and development scenarios. Do not use these APIs in secure production environments. - - - -# Consul resource groups - -This topic provides an overview of resource groups in Consul's v2 architecture. - -Refer to the [`consul resource` CLI command reference](/consul/docs/commands/resource) to learn about using the Consul CLI to interact with resources. - -## Introduction - -Consul's v2 architecture manages workloads using _resources_. Each resource is part of a _resource group_. - -These resource groups structure Consul's ability to target either an _individual workload identity_ or an _entire collection of workload endpoints_ when managing service mesh traffic. There are three resource groups in the v2 API: - -- `auth` group: Resources apply to workload identity -- `catalog` group: Resources apply to all workloads associated with a service -- `mesh` group: Resources apply to either workload identities or all workloads - -For example, traffic permissions are part of the `auth` group. Permissions allow or deny traffic according to the other v2 catalog resource in the `auth` group, the workload identity. Meanwhile, when Consul routes service mesh traffic it applies rules to workloads based on the Service, which is a resource in the `catalog` group. - -One practical impact of resource groups is that the [HTTPRoute](/consul/docs/k8s/multiport/reference/httproute), [GRPCRoute](/consul/docs/k8s/multiport/reference/grpcroute), and [TCPRoute](/consul/docs/k8s/multiport/reference/tcproute) CRDs require you to specify a `name` and `type` in configuration blocks. The `catalog.v2beta1.Service` type indicates that the rules defined in these CRDs apply to all workloads registered in the Consul catalog under the given name. - -You can also use the `consul resource` command to return information about Consul resources in each group using a `group.groupVersion.kind` syntax. Refer to [`consul resource`](/consul/docs/commands/resource) for more information. - -## Resource group reference - -The following table describes the Consul resources that belong to each resource group and the resource's `group.groupVersion.kind` syntax. - -| Resource `group` | v2 resource | Consul resource syntax | -| :------------------ | :-------- | :---- | -| `auth` | Traffic permissions | `auth.v2beta1.TrafficPermissions` | -| `auth` | Workload identity | `auth.v2beta1.WorkloadIdentity` | -| `catalog` | Service | `catalog.v2beta1.Service` | -| `catalog` | Node | `catalog.v2beta1.Node` | -| `catalog` | Workload | `catalog.v2beta1.Workload` | -| `catalog` | Health status | `catalog.v2beta1.HealthStatus` | -| `catalog` | Destinations | `catalog.v2beta1.Destination` | -| `mesh` | GRPCRoute | `mesh.v2beta1.GRPCRoute` | -| `mesh` | HTTPRoute | `mesh.v2beta1.HTTPRoute` | -| `mesh` | Proxy configuration | `mesh.v2beta1.ProxyConfiguration` | -| `mesh` | TCPRoute | `mesh.v2beta1.TCPRoute` | diff --git a/website/content/docs/architecture/v2/index.mdx b/website/content/docs/architecture/v2/index.mdx deleted file mode 100644 index 03afb71aa2..0000000000 --- a/website/content/docs/architecture/v2/index.mdx +++ /dev/null @@ -1,77 +0,0 @@ ---- -layout: docs -page_title: Consul v2 architecture -description: Learn about version 2 of Consul's internal architecture, which replaces services and service instances with workloads and workload identities. ---- - - - -The v2 catalog API and Traffic Permissions API are currently in beta. This documentation supports testing and development scenarios. Do not use these APIs in secure production environments. - - - -# Consul v2 architecture - -This topic provides an overview of Consul's v2 architecture changes and their impact on Consul operations. - -In the v1.17.0 release, Consul introduced the option to enable the [v2 catalog API](/consul/docs/architecture/v2/catalog) for testing and development on Kubernetes deployments. The v2 catalog is one of several changes in development to simplify and streamline Consul's architecture. - -## Overview - -The v2 architecture changes include the following: - -- [v2 catalog API](/consul/docs/architecture/v2/catalog) -- [Resource groups](/consul/docs/architecture/v2/groups) - -## Differences between v1 and v2 - -The change in data models introduced by the v2 architecture impacts several aspects of Consul’s operations. - -### Traffic permissions resource replaces service intentions - -The most significant change to Consul’s architecture and operations when using the v2 catalog structure is the introduction of the traffic permissions resource. This resource replaces the service intentions configuration entry, and enables authorized service-to-service communication for both L4 and L7 applications. - -For more information about this resource, including example configurations, refer to [Traffic permissions configuration reference](/consul/docs/k8s/multiport/reference/trafficpermissions). - -### HTTPRoute, GRPCRoute, and TCPRoute resources for traffic management - -You can configure traffic management behavior such as service splitting in an `HTTPRoute`, `GRPCRoute`, or `TCPRoute` resource. In the v1 catalog, this behavior is defined in dedicated configuration entries. For examples, refer to [service splitter configuration entry reference](/consul/docs/connect/config-entries/service-splitter#examples). - -For more information about these resource, including specifications and example configurations, refer to [HTTPRoute resource configuration reference](/consul/docs/k8s/multiport/reference/httproute), [GRPCRoute resource configuration reference](/consul/docs/k8s/multiport/reference/grpcroute), and [TCPRoute resource configuration reference](/consul/docs/k8s/multiport/reference/tcproute). - -### New proxy configuration resource - -In the v1 catalog, a service’s sidecar proxy and its behavior is [defined in the `Proxy` field of the service definition](/consul/docs/services/usage/define-services). You can also separately [define a service mesh proxy](/consul/docs/connect/proxies/deploy-service-mesh-proxies) and [configure proxy defaults](/consul/docs/connect/config-entries/proxy-defaults). - -In the v2 catalog, the `ProxyConfiguration` resource configures a workload's sidecar proxy behavior according to Consul workload identity. Refer to [ProxyConfiguration resource configuration reference](/consul/docs/k8s/multiport/reference/proxyconfiguration) for more information. - -## Constraints and limitations - -Be aware of the following constraints and technical limitations on the v2 catalog API: - -- The v2 catalog API only supports deployments using [Consul dataplanes](/consul/docs/connect/dataplane) instead of client agents. Consul on Kubernetes uses dataplanes by default. -- The v1 and v2 catalog APIs cannot run concurrently. Because configuration entries are part of the v1 catalog, you cannot use them when the v2 catalog is enabled. Use v2 resources instead. -- The Consul UI does not support the v2 catalog API in this release. You must disable the UI in the Helm chart in order to use the v2 catalog API. -- Secondary datacenters in WAN-federated deployments cannot enable the v2 catalog API in this release. -- HCP Consul Dedicated does not support the v2 catalog API in this release. -- You cannot [link a self-managed cluster to HCP Consul Central](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. -- We do not recommend updating existing clusters to enable the v2 catalog in this release. Instead, deploy a new Consul cluster and [enable the v2 catalog in the Helm chart](/consul/docs/k8s/multiport/configure#enable-the-v2-catalog). - -## Guidance - -The following resources are available to help you use the v2 catalog API: - -### Usage documentation - -- [use the v2 Catalog API](/consul/docs/k8s/multiport) -- [Configure multi-port services](/consul/docs/k8s/multiport/configure) -- [Split TCP traffic between multiple ports](/consul/docs/k8s/multiport/traffic-split) - -### Reference documentation - -- [`consul resource` CLI command](/consul/docs/k8s/multiport/reference/resource-command) -- [GRPCRoute configuration reference](/consul/docs/k8s/multiport/reference/grpcroute) -- [HTTPRoute configuration reference](/consul/docs/k8s/multiport/reference/httproute) -- [ProxyConfiguration configuration reference](/consul/docs/k8s/multiport/reference/proxyconfiguration) -- [TCPRoute configuration reference](/consul/docs/k8s/multiport/reference/tcproute) -- [TrafficPermissions configuration reference](/consul/docs/k8s/multiport/reference/trafficpermissions) diff --git a/website/content/docs/install/ports.mdx b/website/content/docs/install/ports.mdx index 39cfea2ae9..dea835f51b 100644 --- a/website/content/docs/install/ports.mdx +++ b/website/content/docs/install/ports.mdx @@ -115,8 +115,6 @@ In both local and remote cases, incoming traffic comes from the mesh gateways. HCP Consul Dedicated assigns port `8502` to clusters, instead of the default `8503`. -When the [v2 catalog](/consul/docs/architecture/v2/catalog) is enabled, all API calls from external systems, such as the Consul CLI and Terraform provider, use this port. - ### Server RPC The following table lists information about the Server RPC port defaults: diff --git a/website/content/docs/k8s/helm.mdx b/website/content/docs/k8s/helm.mdx index 1bdbd57630..1890f7eeb0 100644 --- a/website/content/docs/k8s/helm.mdx +++ b/website/content/docs/k8s/helm.mdx @@ -763,25 +763,14 @@ Use these links to navigate to a particular top-level stanza. - `experiments` ((#v-global-experiments)) (`array: []`) - Consul feature flags that will be enabled across components. Supported feature flags: - - `resource-apis`: - _**Warning**_! This feature is under active development. It is not - recommended for production use. Setting this flag during an - upgrade could risk breaking your Consul cluster. - If this flag is set, Consul components will use the - V2 resources APIs for all operations. - - `v2tenancy`: - _**Warning**_! This feature is under active development. It is not - recommended for production use. Setting this flag during an - upgrade could risk breaking your Consul cluster. - If this flag is set, Consul V2 resources (catalog, mesh, auth, etc) - will use V2 implementations for tenancy (partitions and namesapces) - instead of bridging to the existing V1 implementations. The - `resource-apis` feature flag must also be set. + - `v1dns`: + When this flag is set, Consul agents use the legacy DNS implementation. + This setting exists in the case a DNS bug is found after the refactoring introduced in v1.19.0. Example: ```yaml - experiments: [ "resource-apis" ] + experiments: [ "v1dns" ] ``` ### server ((#h-server)) diff --git a/website/content/docs/k8s/multiport/configure.mdx b/website/content/docs/k8s/multiport/configure.mdx deleted file mode 100644 index e8fd916468..0000000000 --- a/website/content/docs/k8s/multiport/configure.mdx +++ /dev/null @@ -1,491 +0,0 @@ ---- -layout: docs -page_title: Configure multi-port services -description: Learn how to enable the v2 catalog and configure services to support multiple ports in Consul on Kubernetes. You can configure multiple ports on a single service or multiple services and ports in a single container. ---- - -# Configure multi-port services - - - -The v2 catalog API and Traffic Permissions API are currently in beta. This documentation supports testing and development scenarios. Do not use these APIs in secure production environments. - - - - - -Multi-port services and selecting workloads using multiple services require enabling [Consul's v2 architecture](/consul/docs/architecture/v2). - - - -This page describes the process for integrating a service that uses multiple ports in a single container when running Consul on Kubernetes deployments. It includes example configurations to demonstrate an end-to-end deployment test of Consul's multi-port features. - -## Requirements - -Registering multi-port services with Consul requires Kubernetes. Multi-port services are not supported on VM deployments. - -### Version requirements - -Consul deployments that use the v2 catalog enabled must meet the following minimum version requirements: - -- `consul` v1.18.0 -- `consul-k8s` CLI v1.4.0 or `hashicorp/consul` Helm chart release v1.4.0 -- `consul-dataplane` v1.4.0 - -To install or update the `consul-k8s CLI`, refer to [install the latest version](/consul/docs/k8s/installation/install-cli#install-the-latest-version) or [upgrade the CLI](/consul/docs/k8s/upgrade/upgrade-cli#upgrade-the-cli). - -The required version of Consul dataplanes deploy automatically when using the latest version of `consul-k8s`. Dataplane version is configured manually when you [modify `imageConsulDataplane`](/consul/docs/k8s/helm#v-global-imageconsuldataplane) in the Helm chart. - -For more information about upgrading Helm charts, refer to [Upgrade Helm chart version](/consul/docs/k8s/upgrade#upgrade-helm-chart-version). - -### Annotation requirements - -The examples on this page include the following required annotations in Kubernetes Deployment resources: - -```yaml -spec: - template: - metadata: - annotations: - "consul.hashicorp.com/mesh-inject": "true" - "consul.hashicorp.com/transparent-proxy": "true" -``` - -These annotations inject Consul dataplanes and enable transparent proxy mode so that the services can curl each other on ports configured in the Kubernetes Service resource. Refer to [annotations and labels](/consul/docs/k8s/annotations-and-labels) for more information. - -## Enable the v2 catalog - -To enable the v2 catalog and its support for multi-port services, set `global.experiments: ["resource-apis"]` and `ui.enabled: false`. The following example includes these parameters in a Helm chart with additional configurations for the Consul installation: - - - -```yaml -global: - enabled: true - name: consul - image: hashicorp/consul:1.18.0 - datacenter: dc1 - tls: - enabled: true - acls: - manageSystemACLs: true - experiments: ["resource-apis"] -server: - enabled: true - replicas: 1 -connectInject: - enabled: true -ui: - enabled: false -``` - - - -Then install Consul to your Kubernetes cluster using either the `consul-k8s` CLI or Helm. - - - - - -```shell-session -$ consul-k8s install -config-file=values.yaml -``` - - - - - -```shell-session -$ helm install consul hashicorp/consul --create-namespace --namespace consul --version 1.4.0 --values values.yaml -``` - - - - -## Define the multi-port service - -Consul's v2 catalog supports two new methods for registering services on the mesh in Kubernetes: - -- **Method 1**: Register a Kubernetes service that select workloads which expose multiple ports -- **Method 2**: Register multiple Kubernetes Services that direct traffic to an explicit port on the same workload - -These methods affect how the Services are addressed in Kubernetes. - -Each tab in the following example contains a configuration that defines an `api` service using one of these methods. Both definitions schedule a Pod running two containers that each support traffic to one of the ports exposed by the Service. In `Method 1`, both services are addressed using `api` because both services are exposed by a single service. In `Method 2`, `api` and `api-admin` are defined as separate services and can be addressed using distinct names. - - - - - - - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: api ---- -apiVersion: v1 -kind: Service -metadata: - name: api -spec: - selector: - app: api - ports: - - name: api - port: 80 - targetPort: api - - name: admin - port: 90 - targetPort: admin ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: api -spec: - replicas: 1 - selector: - matchLabels: - app: api - template: - metadata: - labels: - app: api - annotations: - "consul.hashicorp.com/mesh-inject": "true" - "consul.hashicorp.com/transparent-proxy": "true" - spec: - containers: - - name: api - image: hashicorp/http-echo:latest - args: - - -text="hello world" - - -listen=:8080 - ports: - - containerPort: 8080 - name: api - - name: api-admin - image: hashicorp/http-echo:latest - args: - - -text="hello world from 9090 admin" - - -listen=:9090 - ports: - - containerPort: 9090 - name: admin - serviceAccountName: api -``` - - - - - - - - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: api ---- -apiVersion: v1 -kind: Service -metadata: - name: api -spec: - selector: - app: api - ports: - - name: api - port: 80 - targetPort: api ---- -apiVersion: v1 -kind: Service -metadata: - name: api-admin -spec: - selector: - app: api - ports: - - name: admin - port: 90 - targetPort: admin ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: api -spec: - replicas: 1 - selector: - matchLabels: - app: api - template: - metadata: - labels: - app: api - annotations: - "consul.hashicorp.com/mesh-inject": "true" - "consul.hashicorp.com/transparent-proxy": "true" - spec: - containers: - - name: api - image: hashicorp/http-echo:latest - args: - - -text="hello world" - - -listen=:8080 - ports: - - containerPort: 8080 - name: api - - name: api-admin - image: hashicorp/http-echo:latest - args: - - -text="hello world from 9090 admin" - - -listen=:9090 - ports: - - containerPort: 9090 - name: admin - serviceAccountName: api -``` - - - - - -For testing purposes, the following example defines a Service to function as a static client that you can use to verify that the multi-port services function correctly. - - - -```yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: web ---- -apiVersion: v1 -kind: Service -metadata: - name: web -spec: - selector: - app: web - ports: - - port: 80 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: web -spec: - replicas: 1 - selector: - matchLabels: - app: web - template: - metadata: - labels: - app: web - annotations: - "consul.hashicorp.com/mesh-inject": "true" - "consul.hashicorp.com/transparent-proxy": "true" - spec: - containers: - - name: web - image: curlimages/curl:latest - # Just spin & wait forever, we'll use `kubectl exec` to demo - command: ['/bin/sh', '-c', '--'] - args: ['while true; do sleep 30; done;'] - serviceAccountName: web -``` - - - -To apply these services to your Kubernetes deployment and register them with Consul, run the following command: - -```shell-session -$ kubectl apply -f api.yaml -f web.yaml -``` - -## Configure traffic permissions - -Consul uses traffic permissions to validate communication between services based on L4 identity. When ACLs are enabled for the service mesh, traffic permissions deny all services by default. In order to allow traffic between the static client and the multi-port service, create CRDs that allow traffic to each port. - -The following examples create Consul CRDs that allow traffic to only one port of the multi-port service. Each resource separately denies `web` permission when it is a source of traffic to one of the services. These traffic permissions work with either method for defining a multi-port service. When following the instructions on this page, apply these permissions individually when you validate the ports. - - - - - -```yaml -apiVersion: auth.consul.hashicorp.com/v2beta1 -kind: TrafficPermissions -metadata: - name: web-to-api -spec: - destination: - identityName: api - action: ACTION_ALLOW - permissions: - - sources: - - identityName: web - destinationRules: - - portNames: ["api"] -``` - - - - - -```yaml -apiVersion: auth.consul.hashicorp.com/v2beta1 -kind: TrafficPermissions -metadata: - name: web-to-admin -spec: - destination: - identityName: api - action: ACTION_ALLOW - permissions: - - sources: - - identityName: web - destinationRules: - - portNames: ["admin"] -``` - - - - -## Validate multi-port connection - -To open a shell to the `web` container, you need the name of the Pod it currently runs on. Run the following command to return a list of Pods: - -```shell-session -$ kubectl get pods -NAME READY STATUS RESTARTS AGE -api-5784b54bcc-tp98l 3/3 Running 0 6m55s -web-6dcbd684bc-gk8n5 2/2 Running 0 6m55s -``` - -Set environment variables to remember the pod name for the web workload for use in future commands. - - - -```shell-session -$ export WEB_POD=web-6dcbd684bc-gk8n5 -``` - - - -### Apply traffic permissions - -Use the `web` Pod's name to open a shell session and test the `api` service on both ports. When ACLs are enabled, these commands fail until you apply a traffic permissions resource. - - - - - -Test the `api` service on port 80. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -``` - -Then test the `api` service on port 90. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:90 -``` - - - - - -Test the `api` service on port 80. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -``` - -Then test the `api-admin` service on port 90. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90 -``` - - - - -Apply the CRD to allow traffic to port 80: - -```shell-session -$ kubectl apply -f allow-80.yaml -``` - - - - - -Then, open a shell session in the `web` container and test the `api` service on port 80. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -hello world -``` - - - - -Then, open a shell session in the `web` container and test the `api` service on port 80. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -hello world -``` - - - - -Apply the CRD to allow traffic to port 90: - -```shell-session -$ kubectl apply -f allow-90.yaml -``` - - - - - -Then, open a shell session in the `web` container and test the `api` service on port 90. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:90 -hello world from 9090 admin -``` - - - - - -Then, open a shell session in the `web` container and test the `api-admin` service on port 90. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90 -hello world from 9090 admin -``` - - - - -## Next steps - -After applying traffic permissions and validating service-to-service communication within your service mesh, you can manage traffic between multi-port services, filter traffic between ports based on L7 header information, or direct match HTTP query parameters to a specific port. - -Refer to the following pages for more information: - -- [Split traffic between services](/consul/docs/k8s/multiport/traffic-split) -- [gRPC route example: route traffic by matching header](/consul/docs/k8s/multiport/reference/httproute#route-traffic-by-matching-header) -- [HTTP route example: route traffic by matching header](/consul/docs/k8s/multiport/reference/httproute#route-traffic-by-matching-header) -- [HTTP route example: route traffic by matching header and query parameter](/consul/docs/k8s/multiport/reference/httproute#route-traffic-by-matching-header-and-query-parameter) diff --git a/website/content/docs/k8s/multiport/index.mdx b/website/content/docs/k8s/multiport/index.mdx deleted file mode 100644 index acef6abc7c..0000000000 --- a/website/content/docs/k8s/multiport/index.mdx +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: docs -page_title: Use the v2 Catalog API -description: Consul on Kubernetes supports the Catalog V2 API, which unlocks new service discovery and service mesh workflows. Learn how Consul’s Catalog V2 API supports workloads with multiple ports and selecting a workload using multiple services. ---- - - - -The v2 catalog API and Traffic Permissions API are currently in beta. This documentation supports testing and development scenarios. Do not use these APIs in secure production environments. - - - -# Use the v2 Catalog API - -This topic describes the process to use the v2 catalog API to register a service with multiple ports or select a workload using multiple services on Kubernetes deployments. For information about the v2 catalog’s contents and structure, refer to [v2 catalog architecture](/consul/docs/architecture/v2/catalog). - -## Workflow - -To use a multi-port service in Consul on Kubernetes deployments, complete the following steps: - -1. Enable the v2 catalog with ACLs enabled. Add `global.experiments: ["resource-apis"]`, `ui.enabled: false`, and `manageSystemACLs: true` to a cluster's Helm chart before deploying Consul. -1. Use the `"consul.hashicorp.com/mesh-inject": "true"` and `"consul.hashicorp.com/transparent-proxy": "true"` annotations so that Consul automatically registers the service with transparent proxy mode enabled when Kubernetes deploys containers. -1. Configure traffic permissions. When ACLs are enabled, Consul denies all traffic by default. You can use the `TrafficPermissions` CRD to allow traffic to services. - -For an example configuration and instructions for each of the steps in this workflow, refer to [configure multi-port services](/consul/docs/k8s/multiport/configure). - -### Advanced proxy and route configuration workflow - -You can also configure Envoy proxies and sidecar behavior with the proxy configurations resource, and manage traffic between services at the L4 and L7 networking layers with the TCP, HTTP, and gRPC route resources. After you [configure multi-port services](/consul/docs/k8s/multiport/configure), complete the following steps: - -1. Define the resource's behavior in a custom resource definition (CRD). For specifications and example configurations, refer to the [configuration reference](#reference-documentation) for each resource. -1. Apply the resource to your cluster. - -For an example configuration and instructions for each of the steps in this workflow, refer to [split TCP service traffic between ports](/consul/docs/k8s/multiport/traffic-split). - -## Constraints and limitations - -Be aware of the following constraints and technical limitations on using multi-port services and the v2 catalog API: - -- Multi-port services are available for deployments using [Consul dataplanes](/consul/docs/connect/dataplane) instead of client agents. Consul on Kubernetes uses dataplanes by default. -- When running the v2 catalog for multi-port services, you cannot run the v1 catalog API at the same time. -- Because configuration entries are part of the v1 catalog, you cannot use them when the v2 catalog is enabled. Use v2 resources instead to configure multi-port service behavior in the service mesh. -- The Consul UI does not support multi-port services in this release. You must disable the UI in the Helm chart in order to use multi-port services. -- HCP Consul Dedicated does not support multi-port services in this release. -- You cannot [link a self-managed Enterprise cluster to HCP Consul Central](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. -- We do not recommend updating existing clusters to enable the v2 catalog in this release. To register multi-port services, deploy a new Consul cluster that enables the v2 catalog. - -## Guidance - -The following resources are available to help you use the v2 Catalog API: - -### Architecture - -- [v2 architecture overview](/consul/docs/architecture/v2/catalog) -- [v2 Consul catalog](/consul/docs/architecture/v2/catalog) -- [v2 resource groups](/consul/docs/architecture/v2/catalog) - -### Usage documentation - -- [Configure v2 services with multiple ports](/consul/docs/k8s/multiport/configure) -- [Split TCP traffic between v2 services with multiple ports](/consul/docs/k8s/multiport/traffic-split) - -### Reference documentation - -- [`consul resource` CLI command](/consul/commands/resource) -- [`GRPCRoute` resource configuration reference](/consul/docs/k8s/multiport/reference/grpcroute) -- [`HTTPRoute` resource configuration reference](/consul/docs/k8s/multiport/reference/httproute) -- [`ProxyConfiguration` resource configuration reference](/consul/docs/k8s/multiport/reference/proxyconfiguration) -- [`TCPRoute` resource configuration reference](/consul/docs/k8s/multiport/reference/tcproute) -- [`TrafficPermissions` resource configuration reference](/consul/docs/k8s/multiport/reference/trafficpermissions) diff --git a/website/content/docs/k8s/multiport/reference/grpcroute.mdx b/website/content/docs/k8s/multiport/reference/grpcroute.mdx deleted file mode 100644 index f76f758855..0000000000 --- a/website/content/docs/k8s/multiport/reference/grpcroute.mdx +++ /dev/null @@ -1,808 +0,0 @@ ---- -layout: docs -page_title: GRPCRoute resource configuration reference -description: The GRPCRoute resource CRD configures L7 gRPC traffic behavior within the service mesh. GRPCRoute requires the v2 catalog API. Learn how to configure the GRPCRoute CRD with specifications and example configurations. ---- - -# GRPCRoute resource configuration reference - -This page provides reference information for the `GRPCRoute` resource, which defines L7 gRPC traffic within the service mesh. - -This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/v2/catalog). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/). - -## Configuration model - -The following list outlines field hierarchy, language-specific data types, and requirements in a gRPC route CRD. Click on a property name to view additional details, including default values. - -- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1` -- [`kind`](#kind): string | required | must be set to `GRPCRoute` -- [`metadata`](#metadata): map | required - - [`name`](#metadata-name): string | required - - [`namespace`](#metadata-namespace): string | optional -- [`spec`](#spec): map | required - - [`parentRefs`](#spec-parentrefs): map | required - - [`port`](#spec-parentrefs-port): string - - [`ref`](#spec-parentrefs-ref): string | required - - [`name`](#spec-parentrefs-ref-name): string - - [`type`](#spec-parentrefs-ref-type): map - - [`group`](#spec-parentrefs-ref-type): string - - [`groupVersion`](#spec-parentrefs-ref-type): string - - [`kind`](#spec-parentrefs-ref-type): string - - [`rules`](#spec-rules): map | required - - [`backendRefs`](#spec-rules-backendrefs): map - - [`backendRef`](#spec-rules-backendrefs-backendref): map - - [`datacenter`](#spec-rules-backendrefs-backendref-datacenter): string - - [`port`](#spec-rules-backendrefs-backendref-port): string - - [`ref`](#spec-rules-backendrefs-backendref-ref): map - - [`name`](#spec-rules-backendrefs-backendref-ref-name): string - - [`type`](#spec-rules-backendrefs-backendref-ref-type): map - - [`group`](#spec-rules-backendrefs-backendref-ref-type): string - - [`groupVersion`](#spec-rules-backendrefs-backendref-ref-type): string - - [`kind`](#spec-rules-backendrefs-backendref-ref-type): string - - [`filters`](#spec-rules-backendrefs-filters): map - - [`requestHeaderModifier`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`add`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`set`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`remove`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`responseHeaderModifier`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`add`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`set`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`remove`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`urlRewrite`](#spec-rules-backendrefs-filters-urlrewrite): map - - [`pathPrefix`](#spec-rules-backendrefs-filters-urlrewrite): string - - [`weight`](#spec-rules-backendrefs-weight): number | `1` - - [`filters`](#spec-rules-filters): map - - [`requestHeaderModifier`](#spec-rules-filters-requestheadermodifier): map - - [`add`](#spec-rules-filters-requestheadermodifier): map - - [`set`](#spec-rules-filters-requestheadermodifier): map - - [`remove`](#spec-rules-filters-requestheadermodifier): map - - [`responseHeaderModifier`](#spec-rules-filters-responseheadermodifier): map - - [`add`](#spec-rules-filters-responseheadermodifier): map - - [`set`](#spec-rules-filters-responseheadermodifier): map - - [`remove`](#spec-rules-filters-responseheadermodifier): map - - [`urlRewrite`](#spec-rules-filters-urlrewrite): map - - [`pathPrefix`](#spec-rules-filters-urlrewrite): string - - [`matches`](#spec-rules-matches): map - - [`headers`](#spec-rules-matches-headers): map - - [`name`](#spec-rules-matches-headers-name): string - - [`type`](#spec-rules-matches-headers-type): string - - [`value`](#spec-rules-matches-headers-value): string - - [`method`](#spec-rules-matches-method): map - - [`method`](#spec-rules-matches-method-method): string - - [`service`](#spec-rules-matches-method-service): string - - [`type`](#spec-rules-matches-method-type): string - - [`retries`](#spec-rules-retries): map - - [`number`](#spec-rules-retries-number): map - - [`value`](#spec-rules-retries-number): number - - [`onConditions`](#spec-rules-retries-onconditions): map of strings - - [`onConnectFailure`](#spec-rules-retries-onconnectfailure): boolean | `false` - - [`onStatusCodes`](#spec-rules-retries-onconditions): map of numbers - - [`timeouts`](#spec-rules-timeouts): map - - [`idle`](#spec-rules-timeouts-idle): string - - [`request`](#spec-rules-timeouts-request): string - -## Complete configuration - -When every field is defined, a gRPC route resource CRD has the following form: - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 # required -kind: GRPCRoute # required -metadata: - name: - namespace: -spec: - parentRefs: - port: - - ref: - name: - type: - group: - groupVersion: - kind: - rules: - - backendRefs: - - backendRef: - datacenter: - port: "" - ref: - name: - type: - group: - groupVersion: - kind: - filters: - - requestHeaderModifier: - add: - name: - value: - - responseHeaderModifier: - set: - name: - value: - urlRewrite: - pathPrefix: - weight: 1 - filters: - requestHeaderModifier: - remove: - name: - value: - responseHeaderModifier: - add: - name: - value: - urlRewrite: - pathPrefix: - matches: - headers: - name: - type: - value: - method: - method: - service: - type: - retries: - number: - value: 1 - onConditions: ["cancelled", "unavailable"] - onConnectFailure: false - onStatusCodes: [400, 404] - timeouts: - idle: <1s> - request: <1s> -``` - -## Specification - -This section provides details about the fields you can configure in the `GRPCRoute` custom resource definition (CRD). - -### `apiVersion` - -Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`. - -#### Values - -- Default: None -- This field is required. -- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`. - -### `kind` - -Specifies the type of CRD to implement. Must be set to `GRPCRoute`. - -#### Values - -- Default: None -- This field is required. -- Data type: String value that must be set to `GRPCRoute`. - -### `metadata` - -Map that contains an arbitrary name for the CRD and the namespace it applies to. - -#### Values - -- Default: None -- Data type: Map - -### `metadata.name` - -Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information. - -#### Values - -- Default: None -- This field is required. -- Data type: String - -### `metadata.namespace` - -Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information. - -#### Values - -- Default: None -- Data type: String - -### `spec` - -Map that contains the details about the `GRPCRoute` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children. - -When using this CRD, the `spec` field closely resembles the `GRPCRoute` GAMMA resource. Refer to [GRPCRoute in the Kubernetes documentation](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute). - -#### Values - -- Default: None -- This field is required. -- Data type: Map - -### `spec.parentRefs` - -Specifies the services and other resources to attach the route to. You can only define one `parentsRefs` configuration for each route. To attach the route to multiple resources, specify additional [`spec.parentRefs.ref`](#spec-parentrefs-ref) configurations in the `parentsRefs` block. You can only specify the name of one port for the route. Any resources that send traffic through the route use the same port. - -#### Values - -- Default: None -- This field is required. -- Data type: Map - -### `spec.parentRefs.port` - -Specifies the port for the Consul service that the configuration applies to. This parameter can be either a virtual port number, such as a Kubernetes service port, or a non-numeric target port value representing a named workload port. - -If you are not targeting a virtual port, specify the workload port name directly. - -#### Values - -- Default: None -- Data type: String - -### `spec.parentRefs.ref` - -Specifies the resource that the route attaches to. - -#### Values - -- Default: None -- Data type: Map - -### `spec.parentRefs.ref.name` - -Specifies the user-defined name of the resource that the configuration applies to. - -#### Values - -- Default: None -- Data type: String - -### `spec.parentRefs.ref.type` - -Specifies the type of resource that the configuration applies to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. - -#### Values - -- Default: None -- Data type: Map containing the following parameters: - - | Parameter | Description | Data type | Default | - | :------------ | :------------------------------------------------------------------- | :-------- | :------- | - | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | - | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | - -### `spec.rules` - -Specifies rules for sidecar proxies to direct a service's gRPC traffic within the service mesh, including filtering, retry, and timeout behavior. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs` - -Specifies the Kubernetes Service backend to direct GRPC traffic to when a request matches the service described in [`spec.parentRefs`](#spec-parentrefs). The Service backend is the collection of endpoint IPs for the service. Refer to [the Kubernetes Gateway API specification](https://gateway-api.sigs.k8s.io/concepts/gamma/#an-overview-of-the-gateway-api-for-service-mesh) for more information about Service backends. - -When a valid Service backend cannot be reached and no additional filters apply, traffic that matches the rule returns a 500 status code. - -When different Service backends are specified in [`spec.rules.backendRefs.weight`](#spec-rules-backendrefs-weight) and one of the backends is invalid, Consul continues to apply the specified weights instead of adjusting the relative weights to exclude traffic to the invalid backend. For example, when traffic is configured in a 50-50 split between `api` and `admin` and no valid endpoints for `admin` can be reached, the 50% of traffic intended for `admin` returns with a 500 status code. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.backendRef` - -Specifies an individual Service backend where matching requests should be sent. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.backendRef.datacenter` - -Specifies the name of the Consul datacenter that registered the Service backend that the configuration routes traffic to. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.backendRefs.backendRef.port` - -Specifies the port for the Consul service that the configuration routes traffic to. This parameter can be either a virtual port number, such as a Kubernetes service port, or a non-numeric target port value representing a named workload port. - -If you are not targeting a virtual port, specify the workload port name directly. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.backendRefs.backendRef.ref` - -The Consul service that the configuration routes traffic to. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.backendRef.ref.name` - -Specifies the user-defined name of the resource that the configuration routes traffic to. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.backendRefs.backendRef.ref.type` - -Specifies the type of resource that the configuration routes traffic to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. - -#### Values - -- Default: None -- Data type: Map containing the following parameters: - - | Parameter | Description | Data type | Default | - | --- | --- | --- | --- | - | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | - | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | - -### `spec.rules.backendRefs.filters` - -Specifies filtering behavior for services configured in the same [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.filters.requestHeaderModifier` - -Specifies a set of header modification rules applied to requests routed with the gRPC route resource. - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.backendRefs.filters.responseHeaderModifier` - -Specifies a set of header modification rules applied to responses routed with the gRPC route resource. - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.backendRefs.filters.urlRewrite` - -Specifies a path to modify the URL with when a request is forwarded. - -#### Values - -- Default: None -- Data type: Map containing the following parameter: - - | Parameter | Description | Data type | Default | - | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | - | `pathPrefix` | Specifies the path that is prepended to the URL. | String | None | - -### `spec.rules.backendRefs.weight` - -Specifies the proportion of requests routed to the specified service. - -This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. - -When this parameter is not specified, Consul defaults to `1`. - -#### Values - -- Default: `1` -- Data type: Integer - -### `spec.rules.filters` - -Specifies filtering behavior for all requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.filters.requestHeaderModifier` - -Specifies a set of header modification rules applied to requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.filters.responseHeaderModifier` - -Specifies a set of header modification rules applied to responses from services matching [`spec.parentRefs`](#spec-parent-refs). - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.filters.urlRewrite` - -Specifies a path to modify the URL with when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. - -#### Values - -- Default: None -- Data type: Map containing the following parameter: - - | Parameter | Description | Data type | Default | - | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | - | `pathPrefix` | Specifies a path to prepend to the URL when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. | String | None | - -### `spec.rules.matches` - -Specifies rules for matching traffic to services described in [`spec.parentRefs`](#spec-parent-refs) according to the request header or method. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.headers` - -Specifies criteria for matching gRPC request headers. - -When [`spec.rules.matches.headers.value`] is specified multiple times, a request must match all of the specified values for the route to be selected. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.headers.name` - -Specifies the name of a gRPC request header to match on. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.headers.type` - -Specifies a type of match to perform on the gRPC request header. Supported match types include: unspecified, exact, regex, present, prefix, and suffix. - -#### Values - -- Default: None -- Data type: String that should match one of the following values: - - - `HEADER_MATCH_TYPE_UNSPECIFIED` - - `HEADER_MATCH_TYPE_EXACT` - - `HEADER_MATCH_TYPE_REGEX` - - `HEADER_MATCH_TYPE_PRESENT` - - `HEADER_MATCH_TYPE_PREFIX` - - `HEADER_MATCH_TYPE_SUFFIX` - -### `spec.rules.matches.headers.value` - -Specifies the value of the gRPC request header to match. When this field is specified multiple times, a request must match all of the specified values for the route to be selected. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.method` - -Specifies criteria for matching a service and a gRPC request method. When configuring this field, either [`spec.rules.matches.method.method`](#spec-rules-matches-method-method) or [`spec.rules.matches.method.service`](#spec-rules-matches-method-service) must be a non-empty string. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.method.method` - -Specifies the value of the method to match. When empty or omitted, all methods match. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.method.service` - -Specifies the value of the service to match. When empty or omitted, all services match. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.method.type` - -Specifies a type of match to perform on the gRPC request method. Supported match types include: unspecified, exact, and regex. - -#### Values - -- Default: None -- Data type: String that should match one of the following values: - - - `GRPC_METHOD_MATCH_TYPE_UNSPECIFIED` - - `GRPC_METHOD_MATCH_TYPE_EXACT` - - `GRPC_METHOD_MATCH_TYPE_REGEX` - -### `spec.rules.retries` - -Specifies retry logic for routing gRPC traffic. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.retries.number` - -Specifies the number of retries to attempt when a request fails. - -#### Values - -- Default: None -- Data type: Map that contains the following parameter: - - | Parameter | Description | Data type | Default | - | :-------- | :------------------------------------------- | --------- | ------- | - | `value` | Specifies the number of retries to attempt. | Integer | None | - -### `spec.rules.retries.onConditions` - -Specifies Envoy conditions that cause an automatic retry attempt. - -#### Values - -- Default: None -- Data type: Map of strings - -### `spec.rules.retries.onConnectFailure` - -Enables an automatic retry attempt when a connection failure error occurs. - -#### Values - -- Default: `false` -- Data type: Boolean - -### `spec.rules.retries.onStatusCodes` - -Specifies the response status codes that are eligible for retry attempts. - -#### Values - -- Default: None -- Data type: Map of integers - -### `spec.rules.timeouts` - -Specifies timeout logic when routing gRPC traffic - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.timeouts.idle` - -Specifies the total amount of time permitted for the request stream to be idle before a timeout occurs. - -This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.timeouts.request` - -Specifies the total amount of time spent processing the entire downstream request, including retries, before triggering a timeout. - -This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. - -#### Values - -- Default: None -- Data type: String - -## Examples - -The following examples demonstrate common GRPCRoute CRD configuration patterns for specific use cases. - -### Split gRPC traffic between two ports - -The following example splits traffic for the `api` service. GRPC traffic for services registered to the Consul catalog that are available at the `api-workload` port is split so that 50% of the traffic routes to the service at the `api-workload` port and 50% routes to the service at the `admin-workload` port. - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: GRPCRoute -metadata: - name: api-split - namespace: default -spec: - parentRefs: - - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - rules: - - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - weight: 50 - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "admin-workload" target port. - port: "90" - weight: 50 -``` - -### Route traffic by matching header - -The following example routes gRPC traffic for the `api` service according to its header. GRPC traffic for services registered to the Consul catalog that are available at the `api-workload` port are routed according to the following criteria: - -- For traffic with a header that contains a `x-debug` value of exactly `1`, Consul modifies the response and request headers and routes to the `api` service at the `api-workload` port. -- For traffic with a header that contains a `x-debug` value of exactly `2`, Consul modifies the response and request headers and routes to the `api-admin` service at the `admin-workload` port. - -This example also includes how to include filters that modify request or response headers. - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: GRPCRoute -metadata: - name: api-match-split - namespace: default -spec: - parentRefs: - - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - rules: - - matches: - - headers: - - type: "HEADER_MATCH_TYPE_EXACT" - name: "x-debug" - value: "1" - filters: - - requestHeaderModifier: - add: - - name: "request-foo" - value: "request-bar" - - responseHeaderModifier: - add: - - name: "response-foo" - value: "response-bar" - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - - matches: - - headers: - - type: "HEADER_MATCH_TYPE_EXACT" - name: "x-debug" - value: "2" - filters: - - requestHeaderModifier: - add: - - name: "request-foo" - value: "request-bar" - - responseHeaderModifier: - add: - - name: "response-foo" - value: "response-bar" - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api-admin - # The virtual port number for the "admin-workload" target port. - port: "90" -``` diff --git a/website/content/docs/k8s/multiport/reference/httproute.mdx b/website/content/docs/k8s/multiport/reference/httproute.mdx deleted file mode 100644 index 434fea9032..0000000000 --- a/website/content/docs/k8s/multiport/reference/httproute.mdx +++ /dev/null @@ -1,925 +0,0 @@ ---- -layout: docs -page_title: HTTPRoute resource configuration reference -description: The HTTPRoute resource CRD configures L7 HTTP traffic behavior within the service mesh. HTTPRoute is a GAMMA resource that requires the v2 catalog API. Learn how to configure the HTTPRoute CRD with specifications and example configurations. ---- - -# HTTPRoute resource configuration reference - -This page provides reference information for the `HTTPRoute` resource, which defines behavior for L7 HTTP traffic within the service mesh. - -This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/v2/catalog). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/). - -## Configuration model - -The following list outlines field hierarchy, language-specific data types, and requirements in an HTTP route CRD. Click on a property name to view additional details, including default values. - -- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1` -- [`kind`](#kind): string | required | must be set to `HTTPRoute` -- [`metadata`](#metadata): map | required - - [`name`](#metadata-name): string | required - - [`namespace`](#metadata-namespace): string | optional -- [`spec`](#spec): map | required - - [`parentRefs`](#spec-parentrefs): map | required - - [`port`](#spec-parentrefs-port): string - - [`ref`](#spec-parentrefs-ref): string | required - - [`name`](#spec-parentrefs-ref-name): string - - [`type`](#spec-parentrefs-ref-type): map - - [`group`](#spec-parentrefs-ref-type): string - - [`groupVersion`](#spec-parentrefs-ref-type): string - - [`kind`](#spec-parentrefs-ref-type): string - - [`rules`](#spec-rules): map | required - - [`backendRefs`](#spec-rules-backendrefs): map - - [`backendRef`](#spec-rules-backendrefs-backendref): map - - [`datacenter`](#spec-rules-backendrefs-backendref-datacenter): string - - [`port`](#spec-rules-backendrefs-backendref-port): string - - [`ref`](#spec-rules-backendrefs-backendref-ref): map - - [`name`](#spec-rules-backendrefs-backendref-ref-name): string - - [`type`](#spec-rules-backendrefs-backendref-ref-type): map - - [`group`](#spec-rules-backendrefs-backendref-ref-type): string - - [`groupVersion`](#spec-rules-backendrefs-backendref-ref-type): string - - [`kind`](#spec-rules-backendrefs-backendref-ref-type): string - - [`filters`](#spec-rules-backendrefs-filters): map - - [`requestHeaderModifier`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`add`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`set`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`remove`](#spec-rules-backendrefs-filters-requestheadermodifier): map - - [`responseHeaderModifier`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`add`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`set`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`remove`](#spec-rules-backendrefs-filters-responseheadermodifier): map - - [`urlRewrite`](#spec-rules-backendrefs-filters-urlrewrite): map - - [`pathPrefix`](#spec-rules-backendrefs-filters-urlrewrite): string - - [`weight`](#spec-rules-backendrefs-weight): number | `1` - - [`filters`](#spec-rules-filters): map - - [`requestHeaderModifier`](#spec-rules-filters-requestheadermodifier): map - - [`add`](#spec-rules-filters-requestheadermodifier): map - - [`set`](#spec-rules-filters-requestheadermodifier): map - - [`remove`](#spec-rules-filters-requestheadermodifier): map - - [`responseHeaderModifier`](#spec-rules-filters-responseheadermodifier): map - - [`add`](#spec-rules-filters-responseheadermodifier): map - - [`set`](#spec-rules-filters-responseheadermodifier): map - - [`remove`](#spec-rules-filters-responseheadermodifier): map - - [`urlRewrite`](#spec-rules-filters-urlrewrite): map - - [`pathPrefix`](#spec-rules-filters-urlrewrite): string - - [`matches`](#spec-rules-matches): map - - [`headers`](#spec-rules-matches-headers): map - - [`name`](#spec-rules-matches-headers-name): string - - [`type`](#spec-rules-matches-headers-type): string - - [`value`](#spec-rules-matches-headers-value): string - - [`method`](#spec-rules-matches-method): string - - [`path`](#spec-rules-matches-path): map - - [`type`](#spec-rules-matches-path-type): string - - [`value`](#spec-rules-matches-path-value): string - - [`queryParams`](#spec-rules-matches-queryparams): map - - [`name`](#spec-rules-matches-queryparams-name): string - - [`type`](#spec-rules-matches-queryparams-type): string - - [`value`](#spec-rules-matches-queryparams-value): string - - [`retries`](#spec-rules-retries): map - - [`number`](#spec-rules-retries-number): map - - [`value`](#spec-rules-retries-number): number - - [`onConditions`](#spec-rules-retries-onconditions): map of strings - - [`onConnectFailure`](#spec-rules-retries-onconnectfailure): boolean | `false` - - [`onStatusCodes`](#spec-rules-retries-onconditions): map of integers - - [`timeouts`](#spec-rules-timeouts): map - - [`idle`](#spec-rules-timeouts-idle): string - - [`request`](#spec-rules-timeouts-request): string - -## Complete configuration - -When every field is defined, an HTTP route CRD has the following form: - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 # required -kind: HTTPRoute # required -metadata: - name: - namespace: -spec: - parentRefs: - port: - - ref: - name: - type: - group: - groupVersion: - kind: - rules: - - backendRefs: - - backendRef: - datacenter: - port: - ref: - name: - type: - group: - groupVersion: - kind: - filters: - - requestHeaderModifier: - add: - name: - value: - - responseHeaderModifier: - set: - name: - value: - urlRewrite: - pathPrefix: - weight: 1 - filters: - requestHeaderModifier: - remove: - name: - value: - responseHeaderModifier: - add: - name: - value: - urlRewrite: - pathPrefix: - matches: - headers: - name: - type: - value: - method: - path: - type: - value: / - queryParams: - name: - type: - value: - retries: - number: - value: 1 - onConditions: ["cancelled", "unavailable"] - onConnectFailure: false - onStatusCodes: [400, 404] - timeouts: - idle: <1s> - request: <1s> -``` - -## Specification - -This section provides details about the fields you can configure in the `HTTPRoute` custom resource definition (CRD). - -### `apiVersion` - -Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`. - -#### Values - -- Default: None -- This field is required. -- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`. - -### `kind` - -Specifies the type of CRD to implement. Must be set to `HTTPRoute`. - -#### Values - -- Default: None -- This field is required. -- Data type: String value that must be set to `HTTPRoute`. - -### `metadata` - -Map that contains an arbitrary name for the CRD and the namespace it applies to. - -#### Values - -- Default: None -- Data type: Map - -### `metadata.name` - -Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information. - -#### Values - -- Default: None -- This field is required. -- Data type: String - -### `metadata.namespace` - -Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information. - -#### Values - -- Default: None -- Data type: String - -### `spec` - -Map that contains the details about the `HTTPRoute` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children. - -When using this CRD, the `spec` field closely resembles the `HTTPRoute` GAMMA resource. Refer to [HTTPRoute in the Kubernetes documentation](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute). - -#### Values - -- Default: None -- This field is required. -- Data type: Map - -### `spec.parentRefs` - -Specifies the services and other resources to attach the route to. You can only define one `parentsRefs` configuration for each route. To attach the route to multiple resources, specify additional [`spec.parentRefs.ref`](#spec-parentrefs-ref) configurations in the `parentsRefs` block. You can only specify the name of one port for the route. Any resources that send traffic through the route use the same port. - -#### Values - -- Default: None -- This field is required. -- Data type: Map - -### `spec.parentRefs.port` - -Specifies the port for the Consul service that the configuration applies to. This parameter can be either a virtual port number, such as a Kubernetes service port, or a non-numeric target port value representing a named workload port. - -If you are not targeting a virtual port, specify the workload port name directly. - -#### Values - -- Default: None -- Data type: String - -### `spec.parentRefs.ref` - -Specifies the resource that the route attaches to. - -#### Values - -- Default: None -- Data type: Map - -### `spec.parentRefs.ref.name` - -Specifies the user-defined name of the resource that the configuration applies to. - -#### Values - -- Default: None -- Data type: String - -### `spec.parentRefs.ref.type` - -Specifies the type of resource that the configuration applies to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. - -#### Values - -- Default: None -- Data type: Map containing the following parameters: - - | Parameter | Description | Data type | Default | - | :------------ | :------------------------------------------------------------------- | :-------- | :------- | - | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | - | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | - -### `spec.rules` - -Specifies rules for sidecar proxies to direct a service's HTTP traffic within the service mesh, including filtering, retry, and timeout behavior. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs` - -Specifies the Kubernetes Service backend to direct HTTP traffic to when a request matches the service described in [`spec.parentRefs`](#spec-parentrefs). The Service backend is the collection of endpoint IPs for the service. Refer to [the Kubernetes Gateway API specification](https://gateway-api.sigs.k8s.io/concepts/gamma/#an-overview-of-the-gateway-api-for-service-mesh) for more information about Service backends. - -When a valid Service backend cannot be reached and no additional filters apply, traffic that matches the rule returns a 500 status code. - -When different Service backends are specified in [`spec.rules.backendRefs.weight`](#spec-rules-backendrefs-weight) and one of the backends is invalid, Consul continues to apply the specified weights instead of adjusting the relative weights to exclude traffic to the invalid backend. For example, when traffic is configured in a 50-50 split between `api` and `admin` and no valid endpoints for `admin` can be reached, the 50% of traffic intended for `admin` returns with a 500 status code. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.backendRef` - -Specifies an individual Service backend where matching requests should be sent. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.backendRef.datacenter` - -Specifies the name of the Consul datacenter that registered the Service backend that the configuration routes traffic to. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.backendRefs.backendRef.port` - -Specifies the name of the port for the Consul service that the configuration routes traffic to. This parameter can be either a virtual port number, such as a Kubernetes service port, or a non-numeric target port value representing a named workload port. - -If you are not targeting a virtual port, specify the workload port name directly. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.backendRefs.backendRef.ref` - -The Consul service that the configuration routes traffic to. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.backendRef.ref.name` - -Specifies the user-defined name of the resource that the configuration routes traffic to. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.backendRefs.backendRef.ref.type` - -Specifies the type of resource that the configuration routes traffic to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. - -#### Values - -- Default: None -- Data type: Map containing the following parameters: - - | Parameter | Description | Data type | Default | - | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | - | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | - | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | - -### `spec.rules.backendRefs.filters` - -Specifies filtering behavior for services configured in the same [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.backendRefs.filters.requestHeaderModifier` - -Specifies a set of header modification rules applied to requests routed with the HTTPRoute resource. - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.backendRefs.filters.responseHeaderModifier` - -Specifies a set of header modification rules applied to responses routed with the HTTPRoute resource. - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.backendRefs.filters.urlRewrite` - -Specifies a path to modify the URL with when a request is forwarded. - -#### Values - -- Default: None -- Data type: Map containing the following parameter: - - | Parameter | Description | Data type | Default | - | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | - | `pathPrefix` | Specifies the path that is prepended to the URL. | String | None | - -### `spec.rules.backendRefs.weight` - -Specifies the proportion of requests routed to the specified service. - -This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. - -When this parameter is not specified, Consul defaults to `1`. - -#### Values - -- Default: `1` -- Data type: Integer - -### `spec.rules.filters` - -Specifies filtering behavior for all requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.filters.requestHeaderModifier` - -Specifies a set of header modification rules applied to requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.filters.responseHeaderModifier` - -Specifies a set of header modification rules applied to responses from services matching [`spec.parentRefs`](#spec-parent-refs). - -#### Values - -- Default: None -- Values: Object containing one or more fields that define header modification rules: - - `add`: Map of one or more key-value pairs. - - `set`: Map of one or more key-value pairs. - - `remove`: Map of one or more key-value pairs. - -The following table describes how to configure values for request headers: - -| Rule | Description | Type | -| --- | --- | --- | -| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | -| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | - -##### Use variable placeholders - -For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. - -### `spec.rules.filters.urlRewrite` - -Specifies a path to modify the URL with when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. - -#### Values - -- Default: None -- Data type: Map containing the following parameter: - - | Parameter | Description | Data type | Default | - | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | - | `pathPrefix` | Specifies a path to prepend to the URL when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. | String | None | - -### `spec.rules.matches` - -Specifies rules for matching traffic to services described in [`spec.parentRefs`](#spec-parent-refs) according to the request header or method. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.headers` - -Specifies criteria for matching HTTP request headers. - -When [`spec.rules.matches.headers.value`] is specified multiple times, a request must match all of the specified values for the route to be selected. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.headers.name` - -Specifies the name of a HTTP request header to match on. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.headers.type` - -Specifies a type of match to perform on the HTTP request header. Supported match types include: unspecified, exact, regex, present, prefix, and suffix. - -#### Values - -- Default: None -- Data type: String that should match one of the following values: - - - `HEADER_MATCH_TYPE_UNSPECIFIED` - - `HEADER_MATCH_TYPE_EXACT` - - `HEADER_MATCH_TYPE_REGEX` - - `HEADER_MATCH_TYPE_PRESENT` - - `HEADER_MATCH_TYPE_PREFIX` - - `HEADER_MATCH_TYPE_SUFFIX` - -### `spec.rules.matches.headers.value` - -Specifies the value of the HTTP request header to match. When this field is specified multiple times, a request must match all of the specified values for the route to be selected. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.method` - -Specifies the value of the HTTP method to match. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.path` - -Specifies an HTTP request path to match. When this field is not specified, the CRD matches on the `/` path by default. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.path.type` - -Specifies a type of match to perform on the HTTP path. Supported match types include: unspecified, exact, prefix, and regex. - -#### Values - -- Default: None -- Data type: String that should match one of the following values: - -- `PATH_MATCH_TYPE_UNSPECIFIED` -- `PATH_MATCH_TYPE_EXACT` -- `PATH_MATCH_TYPE_PREFIX` -- `PATH_MATCH_TYPE_REGEX` - -### `spec.rules.matches.path.value` - -Value of the HTTP path to match on. - -#### Values - -- Default: `/` -- Data type: String - -### `spec.rules.matches.queryParams` - -Specifies HTTP query parameters to match on. When [`spec.rules.matches.queryParams.value`] is specified multiple times, a request must match all of the specified values for the route to be selected. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.matches.queryParams.name` - -Specifies the name of the HTTP query parameter to match. Query parameters matches require exact matches between strings. - -If multiple entries specify identical query parameter names, only the first entry with an equivalent name matches. Subsequent entries with an equivalent query parameter name are ignored. If an HTTP request repeats a query parameter, the behavior is intentionally undefined because different data planes have different capabilities. However, we recommend that matching against the first value of the parameter if the data plane supports it, as this behavior is expected in other load balancing contexts. - -Do not route traffic based on repeated query parameters, as differences in data plane implementations may produce errors. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.matches.queryParams.type` - -Specifies a type of match to perform on the HTTP request header. Supported match types include: unspecified, exact, regex, and present. - -#### Values - -- Default: None -- Data type: String that should match one of the following values: - - - `HEADER_MATCH_TYPE_UNSPECIFIED` - - `HEADER_MATCH_TYPE_EXACT` - - `HEADER_MATCH_TYPE_REGEX` - - `HEADER_MATCH_TYPE_PRESENT` - -### `spec.rules.matches.queryParams.value` - -Specifies the value of the HTTP query parameter to match. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.retries` - -Specifies retry logic for routing HTTP traffic. - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.retries.number` - -Specifies the number of retries to attempt when a request fails. - -#### Values - -- Default: None -- Data type: Map that contains the following parameter: - - | Parameter | Description | Data type | Default | - | :-------- | :------------------------------------------- | --------- | ------- | - | `value` | Specifies the number of retries to attempt. | Integer | None | - -### `spec.rules.retries.onConditions` - -Specifies Envoy conditions that cause an automatic retry attempt. - -#### Values - -- Default: None -- Data type: Map of strings - -### `spec.rules.retries.onConnectFailure` - -Enables an automatic retry attempt when a connection failure error occurs. - -#### Values - -- Default: `false` -- Data type: Boolean - -### `spec.rules.retries.onStatusCodes` - -Specifies the response status codes that are eligible for retry attempts. - -#### Values - -- Default: None -- Data type: Map of integers - -### `spec.rules.timeouts` - -Specifies timeout logic when routing HTTP traffic - -#### Values - -- Default: None -- Data type: Map - -### `spec.rules.timeouts.idle` - -Specifies the total amount of time permitted for the request stream to be idle before a timeout occurs. - -This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. - -#### Values - -- Default: None -- Data type: String - -### `spec.rules.timeouts.request` - -Specifies the total amount of time spent processing the entire downstream request, including retries, before triggering a timeout. - -This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. - -#### Values - -- Default: None -- Data type: String - -## Examples - -The following examples demonstrate common HTTP route CRD configuration patterns for specific use cases. - -### Split HTTP traffic between two ports - -The following example splits traffic for the `api` service. HTTP traffic for services registered to the Consul catalog that are available at the `api` port is split so that 50% of the traffic routes to the service at the `api` port and 50% routes to the service at the `admin` port. - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: HTTPRoute -metadata: - name: api-split - namespace: default -spec: - parentRefs: - - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - rules: - - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - weight: 50 - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "admin-workload" target port. - port: "90" - weight: 50 -``` - -### Route traffic by matching header - -The following examples routes HTTP traffic for the `api` service according to its header HTTP traffic for services registered to the Consul catalog that are available at the `api-workload` port are routed according to the following criteria: - -- For traffic with a header that contains a `x-debug` value of exactly `1`, Consul routes to the `api` service at the `api-workload` port. -- For traffic with a header that contains a `x-debug` value of exactly `2`, Consul routes to the `api-admin` service at the `admin-workload` port. - -This example also configures Consul to modify request and response headers when routing traffic. - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: HTTPRoute -metadata: - name: api-filter - namespace: default -spec: - parentRefs: - - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - rules: - - matches: - - headers: - - type: "HEADER_MATCH_TYPE_EXACT" - name: "x-debug" - value: "1" - filters: - - requestHeaderModifier: - add: - - name: "request-foo" - value: "request-bar" - - responseHeaderModifier: - add: - - name: "response-foo" - value: "response-bar" - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - - matches: - - headers: - - type: "HEADER_MATCH_TYPE_EXACT" - name: "x-debug" - value: "2" - filters: - - requestHeaderModifier: - add: - - name: "request-foo" - value: "request-bar" - - responseHeaderModifier: - add: - - name: "response-foo" - value: "response-bar" - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api-admin - # The virtual port number for the "admin-workload" target port. - port: "90" -``` - -### Route traffic by matching header and query parameter - -The following examples routes HTTP traffic for the `api` service according to its header HTTP traffic for services registered to the Consul catalog that are available at the `api-workload` port are routed according to the following criteria: - -- For traffic with a header _and_ a query parameter that both contain `x-debug` values of exactly `1`, Consul routes to the `api` service at the `api-workload` port. -- For traffic with a header _and_ a query parameter that both contain `x-debug` values of exactly `2`, Consul routes to the `api-admin` service at the `admin-workload` port. - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: HTTPRoute -metadata: - name: api-match-split - namespace: default -spec: - parentRefs: - - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - rules: - - matches: - - headers: - - type: "HEADER_MATCH_TYPE_EXACT" - name: "x-debug" - value: "1" - queryParams: - - type: "QUERY_PARAM_MATCH_TYPE_EXACT" - name: "x-debug" - value: "1" - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api - # The virtual port number for the "api-workload" target port. - port: "80" - - matches: - - headers: - - type: "HEADER_MATCH_TYPE_EXACT" - name: "x-debug" - value: "2" - queryParams: - - type: "QUERY_PARAM_MATCH_TYPE_EXACT" - name: "x-debug" - value: "2" - backendRefs: - - backendRef: - ref: - type: - group: catalog - groupVersion: v2beta1 - kind: Service - name: api-admin - # The virtual port number for the "admin-workload" target port. - port: "90" -``` diff --git a/website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx b/website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx deleted file mode 100644 index 2ad24cc4b9..0000000000 --- a/website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx +++ /dev/null @@ -1,691 +0,0 @@ ---- -layout: docs -page_title: ProxyConfiguration resource configuration reference -description: The ProxyConfiguration resource CRD configures sidecar proxy behavior within the service mesh. Learn how to configure bootstrap and dynamic configurations for proxies according to Workload characteristics with specifications and example configurations. ---- - -# ProxyConfiguration resource configuration reference - -This page provides reference information for the `ProxyConfigurations` resource, which defines proxy behavior for traffic within the service mesh. The resource specifies both bootstrap and dynamic configurations for proxies. - -This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/v2/catalog). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/). - -## Configuration model - -The following list outlines field hierarchy, language-specific data types, and requirements in a ProxyConfiguration CRD. Click on a property name to view additional details, including default values. - -- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1` -- [`kind`](#kind): string | required | must be set to `ProxyConfiguration` -- [`metadata`](#metadata): map | required - - [`name`](#metadata-name): string | required - - [`namespace`](#metadata-namespace): string | optional -- [`spec`](#spec): map | required - - [`workloads`](#spec-workloads): map - - [`filter`](#spec-workloads): string - - [`names`](#spec-workloads): array of strings - - [`prefixes`](#spec-workloads): array of strings - - [`bootstrapConfig`](#spec-bootstrapconfig): map - - [`dogstatsdUrl`](#spec-bootstrapconfig): string - - [`overrideJsonTpl`](#spec-bootstrapconfig): string - - [`prometheusBindAddr`](#spec-bootstrapconfig): string - - [`readyBindAddr`](#spec-bootstrapconfig): string - - [`staticClustersJson`](#spec-bootstrapconfig): string - - [`staticListenersJson`](#spec-bootstrapconfig): string - - [`statsBindAddr`](#spec-bootstrapconfig): string - - [`statsConfigJson`](#spec-bootstrapconfig): string - - [`statsFlushInterval`](#spec-bootstrapconfig): string - - [`statsSinksJson`](#spec-bootstrapconfig): string - - [`statsTags`](#spec-bootstrapconfig): array of strings - - [`statsdUrl`](#spec-bootstrapconfig): string - - [`telemetryCollectorBindSocketDir`](#spec-bootstrapconfig): string - - [`tracingConfigJson`](#spec-bootstrapconfig): string - - [`dynamicConfig`](#spec-dynamicconfig): map - - [`accessLogs`](#spec-dynamicconfig-accesslogs): map - - [`enabled`](#spec-dynamicconfig-accesslogs-enabled): boolean | `false` - - [`disableListenerLogs`](#spec-dynamicconfig-accesslogs-disablelistenerlogs): boolean | `false` - - [`jsonFormat`](#spec-dynamicconfig-accesslogs-jsonformat): string - - [`path`](#spec-dynamicconfig-accesslogs-path): string - - [`textFormat`](#spec-dynamicconfig-accesslogs-textformat): string - - [`type`](#spec-dynamicconfig-accesslogs-type): string - - [`exposeConfig`](#spec-dynamicconfig-exposeconfig): map - - [`exposePaths`](#spec-dynamicconfig-exposeconfig-exposepaths): map - - [`listenerPort`](#spec-dynamicconfig-exposeconfig-exposepaths-listenerport): integer - - [`localPathPort`](#spec-dynamicconfig-exposeconfig-exposepaths-localpathport): integer - - [`path`](#spec-dynamicconfig-exposeconfig-exposepaths-path): string - - [`protocol`](#spec-dynamicconfig-exposeconfig-exposepaths-protocol): string - - [`inboundConnections`](#spec-dynamicconfig-inboundconnections): map - - [`balanceInboundConnections`](#spec-dynamicconfig-inboundconnections-balanceinboundconnections): string - - [`maxInboundConnections`](#spec-dynamicconfig-exposeconfig-inboundconnections-maxinboundconnections): integer - - [`listenerTracingJson`](#spec-dynamicconfig-listenertracingjson): string - - [`localClusterJson`](#spec-dynamicconfig-localclusterjson): string - - [`localConnection`](#spec-dynamicconfig-localconnection): map - - [`connectTimeout`](#spec-dynamicconfig-localconnection-connecttimeout): string - - [`requestTimeout`](#spec-dynamicconfig-localconnection-requesttimeout): string - - [`meshGatewayMode`](#spec-dynamicconfig-meshgatewaymode): string - - [`mode`](#spec-dynamicconfig-mode): string - - [`publicListenerJson`](#spec-dynamicconfig-publiclistenerjson): string - - [`transparentProxy`](#spec-dynamicconfig-transparentproxy): map - - [`dialedDirectly`](#spec-dynamicconfig-transparentproxy-dialeddirectly): boolean | `false` - - [`outboundListenerPort`](#spec-dynamicconfig-transparentproxy-outboundlistenerport): integer | `15001` - -## Complete configuration - -When every field is defined, an ProxyConfigurations CRD has the following form: - -```yaml -apiVersion: mesh.consul.hashicorp.com/v2beta1 # required -kind: ProxyConfiguration # required -metadata: - name: - namespace: -spec: - workloads: # required - filter: "Service.Meta.version == v1" - names: ["api", "admin"] - prefixes: ["
", ""]
-  bootstrapConfig: 
-    dogstatsdUrl: 
-    overrideJsonTpl: 
-    prometheusBindAddr: <0.0.0.0>
-    readyBindAddr: 
-    staticClustersJson: 
-    staticListenersJson: 
-    statsBindAddr: <0.0.0.0>
-    statsConfigJson: 
-    statsFlushInterval: 5000ms
-    statsSinkJson: 
-    statsTags:
-      - 
-    statsdUrl: 
-    telemetryCollectorBindSocketDir: 
-    tracingConfigJson: 
-  dynamicConfig:
-    accessLogs:
-      enabled: false
-      disableListenerLogs: false
-      jsonFormat: 
-      path: 
-      textFormat: 
-      type: 
-    exposeConfig:
-      exposePaths:
-        listenerPort: 42
-        localPathPort: 4242
-        path: 
-        protocol: 
-      inboundConnections:
-        balanceInboundConnections: 
-        maxInboundConnections: 1024
-    listenerTracingJson: 
-    localClusterJson: 
-    localConnection:
-      connectTimeout: <1s>
-      requestTimeout: <1s>
-    meshGatewayMode: 
-    mode: 
-    publicListenerJson: 
-    transparentProxy:
-      dialedDirectly: false
-      outboundListenerPort: 15001
-```
-
-## Specification
-
-This section provides details about the fields you can configure in the `ProxyConfiguration` custom resource definition (CRD).
-
-### `apiVersion`
-
-Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`.
-
-#### Values
-
-- Default: None
-- This field is required.
-- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`.
-
-### `kind`
-
-Specifies the type of CRD to implement. Must be set to `ProxyConfiguration`.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: String value that must be set to `ProxyConfiguration`.
-
-### `metadata`
-
-Map that contains an arbitrary name for the CRD and the namespace it applies to.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `metadata.name`
-
-Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: String
-
-### `metadata.namespace` 
-
-Specifies the namespace that the proxy configuration applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec`
-
-Map that contains the details about the `ProxyConfiguration` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: Map
-
-### `spec.workloads`
-
-Specifies the workloads that the proxy configuration applies to. You can select workloads by name, prefix, or by using a filter expression.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: Map that can contain the following parameters:
-
- | Parameter     | Description                                                                                                                                                                                                                                                                                   | Data type | Default |
-    | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
-    | `filter`      | Specifies an expression that filters workloads.  For more information about creating and using expressions to filter, refer to [filtering](/consul/api-docs/features/filtering).   | String    | None    |
-    | `names` | Specifies one or more names of workloads the proxy configuration applies to. | Array of strings | None |
-    | `prefixes` | Specifies one or more prefixes. Proxy configurations apply to workloads with one of the prefixes. | Array of strings | None |
-
-### `spec.bootstrapConfig`
-
-Specifies initial bootstrap settings for the Envoy proxy, as well as proxy configuration settings that require the proxy to restart when applied. For more information, refer to [Envoy proxy bootstrap configuration](/consul/docs/connect/proxies/envoy#bootstrap-configuration).
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.bootstrapConfig.dogstatsdUrl`
-
-Specifies a URL that identifies a DataDog DogStatsD listener. Envoy sends metrics to this listener.
-
-Format the URL as `udp://ip:port` or `unix://uds/path`. For example, `udp://127.0.0.1:8125` configures a local UDP DogStatsD listener for every host. TCP is not supported.
-
-The UDP URL must use an IP address. DNS names are not supported.
-
-For more information about configuring a UNIX domain socket with DogStatsD, refer to [the DataDog documentation](https://docs.datadoghq.com/developers/dogstatsd/unix_socket?tab=kubernetes#setup).
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.overrideJsonTpl`
-
-
-This field offers complete control of the proxy's bootstrap. Be aware that major deviations from the default template may break Consul's ability to correctly manage the proxy or enforce its security model.
-
-
-Specifies a template in Go template syntax to use in place of [the default template](https://github.com/hashicorp/consul/blob/71d45a34601423abdfc0a64d44c6a55cf88fa2fc/command/connect/envoy/bootstrap_tpl.go#L129) when generating the bootstrap configuration using the [`consul connect envoy` command](/consul/commands/connect/envoy). For information about the variables Consul can interpolate in the template, refer to the [documentation in `bootstrap_tpl.go`](https://github.com/hashicorp/consul/blob/71d45a34601423abdfc0a64d44c6a55cf88fa2fc/command/connect/envoy/bootstrap_tpl.go#L5).
-
-Refer to [Envoy proxy escape-hatch overrides](/consul/docs/connect/proxies/envoy#escape-hatch-overrides) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.prometheusBindAddr`
-
-Configures the proxy to expose a Prometheus metrics endpoint to the public network. Format the endpoint as `ip:port`. The port and IP and port combination must be free within the network namespace where the proxy runs. The IP `0.0.0.0` binds to all available interfaces or a pod IP address if supported by your existing network settings.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.readyBindAddr`
-
-Specifies the location to configure the proxy's readiness probe. Format as `ip:port`. 
-
- By default, the proxy does not have a readiness probe configured on it.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.staticClustersJson`
-
-Specifies one or more [Envoy clusters](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/cluster/v3/cluster.proto) to append to the array of [static clusters](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-staticresources-clusters) in the bootstrap configuration.
-
-This field enables you to add custom clusters, such as tracing sinks, to the bootstrap configuration. In order to configure a single cluster, specify a single JSON object with the cluster details.
-
-Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.staticListenersJson`
-
-Specifies one or more [Envoy listeners](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/listener/v3/listener.proto) to append to the array of [static listeners](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-staticresources-listeners) definitions.
-
-You can use this field to set up limited access that bypasses the service mesh's mTLS or authorization for health checks or metrics.
-
-Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.statsBindAddr`
-
-Specifies that the proxy should expose the `/stats` prefix to the _public_ network at the `ip:port` provided. The IP and port combination must be free within the network namespace where the proxy runs. The IP `0.0.0.0` binds to all available interfaces or a pod IP address if supported by your existing network settings.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.statsConfigJson`
-
-Specifies a complete [stats config](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-stats-config).
-
-When provided, this field overrides [`spec.bootstrapConfig.statsTags`](#spec-bootstrapconfig-statstags) and enables full control over dynamic tag replacements.
-
-Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.statsFlushInterval`
-
- Configures Envoy's [`stats_flush_interval`](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-stats-flush-interval), which measures the length of the interval between stats sink flushes.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.statsSinkJson`
-
-Specifies one or more [stats sinks](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-stats-sinks) to append to sinks defined using [`spec.bootstrapConfig.statsdUrl`](#spec-bootstrapconfig-statsdurl) or [`spec.bootstrapConfig.dogstatsdUrl`](#spec-bootstrapconfig-dogstatsdurl).
-
-Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.statsTags`
-
-Specifies one or more static tags to add to all metrics produced by the proxy.
-
-#### Values
-
-- Default: None
-- Data type: Array of strings
-
-### `spec.bootstrapConfig.statsdUrl`
-
-Specifies a URL that identifies a StatsD listener. Envoy sends metrics to this listener.
-
-Format the URL as `udp://ip:port`. For example, `udp://127.0.0.1:8125` configures a local StatsD listener for every host. TCP is not supported.
-
-The URL must use an IP address. DNS names are not supported.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.telemetryCollectorBindSocketDir`
-
-Specifies the directory of the Unix socket Envoy sends metrics to so that the Consul telemetry collector can collect them.
-
-The socket is not configured by default.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.bootstrapConfig.tracingConfigJson`
-
-Specifies a configuration for an external tracing provider as described in [the Envoy documentation](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-tracing). Most tracing providers also require adding static clusters to define the endpoints to send tracing data to.
-
-Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig`
-
-Specifies configuration settings for the Envoy proxy that are applied without restarting the proxy. For more information, refer to [Envoy proxy dynamic configuration](/consul/docs/connect/proxies/envoy#dynamic-configuration).
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.accessLogs`
-
-Specifies the format and output for the proxy's access logs.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.accessLogs.enabled`
-
-When set to `true`, this parameter enables access logs for the proxy.
-
-#### Values
-
-- Default: `false`
-- Data type: Boolean
-
-### `spec.dynamicConfig.accessLogs.usableListenerLogs`
-
-When set to `true`, this parameter disables listener logs for connections that the proxy rejected because they did not have a matching listener filter.
-
-#### Values
-
-- Default: `false`
-- Data type: Boolean
-
-### `spec.dynamicConfig.accessLogs.jsonFormat`
-
-Specifies a JSON format dictionary for the access logs. Refer to [format dictionaries in the Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#format-dictionaries) for more information.
-
-When this field is specified, you cannot also specify [`spec.dynamicConfig.accessLogs.textFormat`](#spec-dynamicconfig-accesslogs-textformat) in the same configuration.
-
-### `spec.dynamicConfig.accessLogs.path`
-
-Specifies a file output path for the access logs.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.accessLogs.textFormat`
-
-Specifies a format string for the access logs. Refer to [default format string in the Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string) for more information.
-
-When this field is specified, you cannot also specify [`spec.dynamicConfig.accessLogs.jsonFormat`](#spec-dynamicconfig-accesslogs-jsonformat) in the same configuration.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.accessLogs.type`
-
-Specifies the output type for the access logs.
-
-#### Values
-
-- Default: None
-- Data type: String containing one of the following values:
-
-  - `LOG_SINK_TYPE_DEFAULT`
-  - `LOG_SINK_TYPE_FILE`
-  - `LOG_SINK_TYPE_STDERR`
-  - `LOG_SINK_TYPE_STDOUT`
-
-### `spec.dynamicConfig.exposeConfig`
-
-Specifies configurations for exposing the proxy.
-
-Refer to [expose paths configuration reference](/consul/docs/connect/proxies/proxy-config-reference#expose-paths-configuration-reference) for more information.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.exposeConfig.exposePaths`
-
-Specifies a configuration for exposing an HTTP path through the proxy.
-
-Refer to [expose paths configuration reference](/consul/docs/connect/proxies/proxy-config-reference#expose-paths-configuration-reference) for more information.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.exposeConfig.exposePaths.listenerPort`
-
-Specifies the port where the proxy listens for connections. This port must be available for the listener to be set up. If the port is not free, Envoy does not expose a listener for the path but the proxy registration does not fail.
-
-#### Values
-
-- Default: None
-- Data type: Integer
-
-### `spec.dynamicConfig.exposeConfig.exposePaths.localPathPort`
-
-Specifies the port where the local service is listening for connections to the path.
-
-#### Values
-
-- Default: None
-- Data type: Integer
-
-### `spec.dynamicConfig.exposeConfig.exposePaths.path`
-
-The HTTP path to expose. Prefix the path with a slash. For example, `/metrics`.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.exposeConfig.exposePaths.protocol`
-
-Specifies the protocol of the listener, either HTTP or HTTP/2. For gRPC, use HTTP/2.
-
-#### Values
-
-- Default: None
-- Data type: String containing one of the following values:
-
-  - `EXPOSE_PATH_PROTOCOL_HTTP`
-  - `EXPOSE_PATH_PROTOCOL_HTTP2`
-
-### `spec.dynamicConfig.inboundConnections`
-
-Specifies configurations for how the proxy handles inbound connections.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.inboundConnections.balanceInboundConnections`
-
-Specifies the strategy for balancing inbound connections across Envoy worker threads. Consul's service mesh Envoy integration supports the following values:
-
-| Value | Description |
-| :---- | :---------- |
-| Empty string | Inbound connections are not balanced. |
-| `exact_balance` | Balances inbound connections with [Envoy's Exact Balance Strategy](https://cloudnative.to/envoy/api-v3/config/listener/v3/listener.proto.html#config-listener-v3-listener-connectionbalanceconfig-exactbalance). |
-
-#### Values
-
-- Default: `""`
-- Data type: String
-
-### `spec.dynamicConfig.inboundConnections.maxInboundConnections`
-
-Specifies the maximum number of concurrent inbound connections to the local application instance. If not specified, inherits the Envoy default of `1024`.
-
-#### Values
-
-- Default: `1024`
-- Data type: Integer
-
-### `spec.dynamicConfig.listenerTracingJson`
-
-Specifies a tracing configuration to be inserted in the proxy's public and upstreams listeners. Refer to [the Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-msg-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-tracing) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.localClusterJson`
-
-Specifies a complete Envoy cluster to be delivered in place of the local application cluster. Use this field to customize timeouts, rate limits, and load balancing strategy.
-
-Refer to [cluster configuration in the Envoy documentation](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/cluster/v3/cluster.proto) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.localConnection`
-
-Specifies timeout settings for the proxy's connection to the local application. Apply settings separately for each port.
-
-Specify this field as a map containing a key/value. The map keys correspond to port names on the workload. The value contains this parameter's sub-fields.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.localConnection.connectTimeout`
-
-Specifies the length of time the proxy is allowed to attempt connections to the local application instance before timing out.
-
-This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.localConnection.requestTimeout`
-
-Specifies the length of time the proxy is allowed to attempt HTTP requests to the local application instance. Applies to HTTP-based protocols only.
-
-This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.meshGatewayMode`
-
-Specifies the proxy's mode of operation for resolving upstreams in remote datacenter destinations. Refer to [Mesh gateway configuration reference](/consul/docs/connect/proxies/proxy-config-reference#mesh-gateway-configuration-reference) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String containing one of the following values:
-
-  - `MESH_GATEWAY_MODE_UNSPECIFIED`
-  - `MESH_GATEWAY_MODE_NONE`
-  - `MESH_GATEWAY_MODE_LOCAL`
-  - `MESH_GATEWAY_MODE_REMOTE`
-
-### `spec.dynamicConfig.mode`
-
-Configures the proxy to operate in transparent, direct, or default mode. Refer to [proxy modes](/consul/docs/connect/proxies/proxy-config-reference#proxy-modes) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String containing one of the following values:
-
-  - `PROXY_MODE_DEFAULT`
-  - `PROXY_MODE_TRANSPARENT`
-  - `PROXY_MODE_DIRECT`
-
-### `spec.dynamicConfig.publicListenerJson`
-
-Specifies a complete Envoy listener for Consul to deliver in place of the main public listener that the proxy uses to accept inbound connections. Refer to [escape-hatch overrides](/consul/docs/connect/proxies/envoy#escape-hatch-overrides) for more information
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.dynamicConfig.transparentProxy`
-
-Specifies additional configurations for operating proxies in transparent proxy mode.  Refer to [transparent proxy configuration reference](/consul/docs/connect/proxies/proxy-config-reference#transparent-proxy-configuration-reference) for more information.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.dynamicConfig.transparentProxy.dialedDirectly`
-
-Determines whether this proxy instance's IP address can be dialed directly by transparent proxies. Transparent proxies typically dial upstreams using the _virtual_ tagged address, which load balances across instances. A database cluster with a leader is an example where dialing individual instances can be helpful.
-
-#### Values
-
-- Default: `false`
-- Data type: Boolean
-
-### `spec.dynamicConfig.transparentProxy.outboundListenerPort`
-
-Specifies the port the proxy listens on for outbound traffic to capture and redirect.
-
-#### Values
-
-- Default: `15001`
-- Data type: Integer
-
-## Examples
-
-The following examples demonstrate common ProxyConfiguration CRD configuration patterns for specific use cases.
-
-### Set a timeout on a subset of proxies
-
-The following example configures sidecar proxies scheduled with workloads whose names begin with `static-server-`. When these workloads attempt connections with the local `web` application, both requests and responses time out after 123 second.
-
-```yaml
-apiVersion: mesh.consul.hashicorp.com/v2beta1
-kind: ProxyConfiguration
-metadata:
-  name: static-server-override-one
-spec:
-  workloads:
-    prefixes:
-    - "static-server-"
-  bootstrapConfig:
-    statsBindAddr: "127.0.0.1:6666"
-  dynamicConfig:
-    # Only the web port should be enabled using the TPs
-    localConnection:
-      web:
-        connectTimeout: "123s" # This ALWAYS has to end in 's'. If you want ms, you need to use "0.123s"
-        requestTimeout: "123s"
-```
diff --git a/website/content/docs/k8s/multiport/reference/tcproute.mdx b/website/content/docs/k8s/multiport/reference/tcproute.mdx
deleted file mode 100644
index b9cda7a7b4..0000000000
--- a/website/content/docs/k8s/multiport/reference/tcproute.mdx
+++ /dev/null
@@ -1,345 +0,0 @@
----
-layout: docs
-page_title: TCPRoute resource configuration reference
-description: The TCPRoute resource CRD configures L4 TCP behavior within the service mesh. TCPRoute is a GAMMA resource that requires the v2 catalog API. Learn how to configure the TCPRoute CRD with specifications and example configurations.
----
-
-# TCPRoute resource configuration reference
-
-This page provides reference information for the `TCPRoute` resource, which defines Transport Layer (L4) TCP traffic within the service mesh.
-
-This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/v2/catalog). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/).
-
-## Configuration model
-
-The following list outlines field hierarchy, language-specific data types, and requirements in an TCP route CRD. Click on a property name to view additional details, including default values.
-
-
-
-
-
-- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1`
-- [`kind`](#kind): string | required | must be set to `TCPRoute`
-- [`metadata`](#metadata): map  | required
-  - [`name`](#metadata-name): string | required
-  - [`namespace`](#metadata-namespace): string | optional 
-- [`spec`](#spec): map | required
-  - [`parentRefs`](#spec-parentrefs): map | required
-    - [`port`](#spec-parentrefs-port): string
-    - [`ref`](#spec-parentrefs-ref):  string | required
-      - [`name`](#spec-parentrefs-ref-name): string
-      - [`type`](#spec-parentrefs-ref-type): map
-         - [`group`](#spec-parentrefs-ref-type): string
-         - [`groupVersion`](#spec-parentrefs-ref-type): string
-         - [`kind`](#spec-parentrefs-ref-type): string
-  - [`rules`](#spec-rules): map | required
-    - [`backendRefs`](#spec-rules-backendrefs): map
-      - [`backendRef`](#spec-rules-backendrefs-backendref): map
-        - [`datacenter`](#spec-rules-backendrefs-backendref-datacenter): string
-        - [`port`](#spec-rules-backendrefs-backendref-port): string
-        - [`ref`](#spec-rules-backendrefs-backendref-ref): map
-          - [`name`](#spec-rules-backendrefs-backendref-ref-name): string
-          - [`type`](#spec-rules-backendrefs-backendref-ref-type): map
-            - [`group`](#spec-rules-backendrefs-backendref-ref-type): string
-            - [`groupVersion`](#spec-rules-backendrefs-backendref-ref-type): string
-            - [`kind`](#spec-rules-backendrefs-backendref-ref-type): string
-      - [`weight`](#spec-rules-backendrefs-weight): number
-
-
-
-
-## Complete configuration
-
-When every field is defined, a TCP route CRD has the following form:
-
-```yaml
-apiVersion: mesh.consul.hashicorp.com/v2beta1        # required
-kind: TCPRoute                                       # required
-metadata:
-  name: 
-  namespace: 
-spec:
-  parentRefs:
-    port: 
-    - ref:
-      name: 
-      type:
-        group: 
-        groupVersion: 
-        kind: 
-  rules:
-    - backendRefs:
-      - backendRef:
-        datacenter: 
-        port: 
-        ref:
-          name: 
-          type:
-            group: 
-            groupVersion: 
-            kind: 
-      weight: 1
-```
-
-## Specification
-
-This section provides details about the fields you can configure in the `TCPRoute` custom resource definition (CRD).
-
-### `apiVersion`
-
-Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`.
-
-#### Values
-
-- Default: None
-- This field is required.
-- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`.
-
-### `kind`
-
-Specifies the type of CRD to implement. Must be set to `TCPRoute`.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: String value that must be set to `TCPRoute`.
-
-### `metadata`
-
-Map that contains an arbitrary name for the CRD and the namespace it applies to.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `metadata.name`
-
-Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: String
-
-### `metadata.namespace` 
-
-Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec`
-
-Map that contains the details about the `TCPRoute` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children.
-
-When using this CRD, the `spec` field closely resembles the `TCPRoute` GAMMA resource.  Refer to [TCPRoute in the Kubernetes documentation](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute).
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: Map
-
-### `spec.parentRefs`
-
-Specifies the services and other resources to attach the route to. You can only define one `parentsRefs` configuration for each route. To attach the route to multiple resources, specify additional [`spec.parentRefs.ref`](#spec-parentrefs-ref) configurations in the `parentsRefs` block. You can only specify one port for the route. Any resources that send traffic through the route use the same port.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: Map
-
-### `spec.parentRefs.port`
-
-Specifies the port for the Consul service that the configuration applies to. This parameter can be either a virtual port number, such as a Kubernetes service port, or a non-numeric target port value representing a named workload port.
-
-If you are not targeting a virtual port, specify the workload port name directly.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.parentRefs.ref`
-
-Specifies the resource that the route attaches to.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.parentRefs.ref.name`
-
-Specifies the user-defined name of the resource that the configuration applies to.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.parentRefs.ref.type`
-
-Specifies the type of resource that the configuration applies to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`.
-
-#### Values
-
-- Default: None
-- Data type: Map containing the following parameters:
-
-  | Parameter     | Description                                                          | Data type | Default  |
-  | :------------ | :------------------------------------------------------------------- | :-------- | :------- |
-  | `group`   | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String    | None     |
-  | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None     |
-  | `kind`    | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`.                | String    | None     |
-
-### `spec.rules`
-
-Specifies rules for sidecar proxies to direct a service's TCP traffic within the service mesh.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.rules.backendRefs`
-
-Specifies the Kubernetes Service backend to direct TCP traffic to when a request matches the service described in [`spec.parentRefs`](#spec-parentrefs). The Service backend is the collection of endpoint IPs for the service. Refer to [the Kubernetes Gateway API specification](https://gateway-api.sigs.k8s.io/concepts/gamma/#an-overview-of-the-gateway-api-for-service-mesh) for more information about Service backends.
-
-When a valid Service backend cannot be reached and no additional filters apply, traffic that matches the rule returns a 500 status code.
-
-When different Service backends are specified in [`spec.rules.backendRefs.weight`](#spec-rules-backendrefs-weight) and one of the backends is invalid, Consul continues to apply the specified weights instead of adjusting the relative weights to exclude traffic to the invalid backend. For example, when traffic is configured in a 50-50 split between `api` and `admin` and no valid endpoints for `admin` can be reached, the 50% of traffic intended for `admin` returns with a 500 status code.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.rules.backendRefs.backendRef`
-
-Specifies an individual Service backend where matching requests should be sent.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.rules.backendRefs.backendRef.datacenter`
-
-Specifies the name of the Consul datacenter that registered the Service backend that the configuration routes traffic to.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.rules.backendRefs.backendRef.port`
-
-Specifies the port for the Consul service that the configuration routes traffic to. This parameter can be either a virtual port number, such as a Kubernetes service port, or a non-numeric target port value representing a named workload port.
-
-If you are not targeting a virtual port, specify the workload port name directly.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.rules.backendRefs.backendRef.ref`
-
-The Consul service that the configuration routes traffic to.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.rules.backendRefs.backendRef.ref.name`
-
-Specifies the user-defined name of the resource that the configuration routes traffic to.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.rules.backendRefs.backendRef.ref.type`
-
-Specifies the type of resource that the configuration routes traffic to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`.
-
-#### Values
-
-- Default: None
-- Data type: Map containing the following parameters:
-
-  | Parameter     | Description                                                          | Data type | Default  |
-  | :------------ | :------------------------------------------------------------------- | :-------- | :------- |
-  | `group`   | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String    | None     |
-  | `groupVersion` | Specifies a groupVersion for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None     |
-  | `kind`    | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`.                | String    | None     |
-
-### `spec.rules.backendRefs.weight`
-
-Specifies the proportion of requests routed to the specified service.
-
-This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend.
-
-When this parameter is not specified, Consul defaults to `1`.
-
-#### Values
-
-- Default: `1`
-- Data type: Integer
-
-## Examples
-
-The following examples demonstrate common TCPRoute CRD configuration patterns for specific use cases.
-
-### Split TCP traffic between two ports
-
-The following example splits traffic for the `api` service. TCP traffic for services registered to the Consul catalog that are available at the `api-workload` port is split so that 50% of the traffic routes to the service at the `api-workload` port and 50% routes to the service at the `admin-workload` port.
-
-```yaml
-apiVersion: mesh.consul.hashicorp.com/v2beta1
-kind: TCPRoute
-metadata:
-  name: api-split
-  namespace: default
-spec:
-  parentRefs:
-    - ref:
-        type:
-          group: catalog
-          groupVersion: v2beta1
-          kind: Service
-        name: api
-      # The virtual port number for the "api-workload" target port.
-      port: "80"
-  rules:
-    - backendRefs:
-      - backendRef:
-          ref:
-            type:
-              group: catalog
-              groupVersion: v2beta1
-              kind: Service
-            name: api
-          # The virtual port number for the "api-workload" target port.
-          port: "80"
-        weight: 50
-      - backendRef:
-          ref:
-            type:
-              group: catalog
-              groupVersion: v2beta1
-              kind: Service
-            name: api
-          # The virtual port number for the "admin-workload" target port.
-          port: "90"
-        weight: 50
-```
diff --git a/website/content/docs/k8s/multiport/reference/trafficpermissions.mdx b/website/content/docs/k8s/multiport/reference/trafficpermissions.mdx
deleted file mode 100644
index 58a58fee6f..0000000000
--- a/website/content/docs/k8s/multiport/reference/trafficpermissions.mdx
+++ /dev/null
@@ -1,245 +0,0 @@
----
-layout: docs
-page_title: TrafficPermissions resource configuration reference
-description: The TrafficPermissions CRD defines rules for allowing and denying traffic between services within the service mesh. Learn how to configure traffic permissions for the v2 catalog to authorize service-to-service communication in a network with zero-trust security.
----
-
-# TrafficPermissions configuration reference
-
-This page provides reference information for the `TrafficPermissions` resource, which authorizes east-west traffic between services within the service mesh. The traffic permissions CRD replaces the service intentions CRD when using the v2 catalog API. Refer to [changes to Consul's existing architecture](/consul/docs/architecture/v2/catalog#changes-to-consul-s-existing-architecture) for more information.
-
-This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/v2/catalog). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/).
-
-## Configuration model
-
-The following list outlines field hierarchy, language-specific data types, and requirements in a traffic permissions CRD. Click on a property name to view additional details, including default values.
-
-- [`apiVersion`](#apiversion): string | required | must be set to `auth.consul.hashicorp.com/v2beta1`
-- [`kind`](#kind): string | required | must be set to `TrafficPermissions`
-- [`metadata`](#metadata): map | required
-  - [`name`](#metadata-name): string | required
-  - [`namespace`](#metadata-namespace): string | optional 
-- [`spec`](#spec): map | required
-  - [`destination`](#spec-destination): map
-    - [`identityName`](#spec-destination-identityname): string
-  - [`action`](#spec-action): string
-  - [`permissions`](#spec-permissions): list of maps
-    - [`sources`](#spec-permissions-sources): list of maps
-      - [`identityName`](#spec-permissions-sources-identityname): string
-    - [`destinationRules`](#spec-permissions-destinationrules): list of maps
-      - [`portNames`](#spec-permissions-destinationrules-portnames): array of strings
-
-## Complete configuration
-
-When every field is defined, a traffic permissions CRD has the following form:
-
-```yaml
-apiVersion: auth.consul.hashicorp.com/v2beta1    # required
-kind: TrafficPermissions                         # required
-metadata:
-  name: 
-  namespace: 
-spec:
-  destination:
-    identityName: 
-  action: allow
-  permissions:
-    - sources:
-        - identityName: 
-      destinationRules:
-        - portNames:
-            - 
-```
-
-## Specification
-
-This section provides details about the fields you can configure in the `TrafficPermissions` custom resource definition (CRD).
-
-### `apiVersion`
-
-Specifies the version of the Consul API for integrating with Kubernetes. The value must be `auth.consul.hashicorp.com/v2beta1`.
-
-#### Values
-
-- Default: None
-- This field is required.
-- String value that must be set to `auth.consul.hashicorp.com/v2beta1`.
-
-### `kind`
-
-Specifies the type of CRD to implement. Must be set to `TrafficPermissions`.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: String value that must be set to `TrafficPermissions`.
-
-### `metadata`
-
-Map that contains an arbitrary name for the CRD and the namespace it applies to.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `metadata.name`
-
-Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: String
-
-### `metadata.namespace` 
-
-Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec`
-
-Map that contains the details about the `TrafficPermissions` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children.
-
-#### Values
-
-- Default: None
-- This field is required.
-- Data type: Map
-
-### `spec.destination`
-
-Specifies the proxies of the services where these traffic permissions apply.
-
-#### Values
-
-- Default: None
-- Data type: Map
-
-### `spec.destination.identityName`
-
-Specifies the Workload identity for a service. The permissions you configure in this `TrafficPermissions` CRD apply to sidecar proxies when a request has this identity as their destination.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.action`
-
-Specifies whether the proxy should _allow traffic_ or _deny traffic_ between the destination in [`spec.destination`](#spec-destination) and the sources in [`spec.permissions.sources`](#spec-permissions-sources).
-
-`ACTION_DENY` is a governance feature available in Consul Enterprise that cannot be overridden by another `ACTION_ALLOW`.
-
-By default, Consul allows traffic between all services. When the Helm value `global.acls.manageSystemACLs` is set to `true`, then Consul operates in "default-deny" mode. In this mode, `TrafficPermissions` CRDs that allow traffic between services are required for service-to-service traffic.
-
-#### Values
-
-- Default: None
-- Data type: String that must contain one of the following values:
-
-  - `ACTION_ALLOW`
-  - `ACTION_DENY` 
-
-### `spec.permissions`
-
-Permissions is a list of the traffic permissions Consul evaluates requests against. When the list contains more than one permission, Consul follows OR semantics to select the permission.
-
-#### Values
-
-- Default: None
-- Data type: List of maps
-
-### `spec.permissions.sources`
-
-Lists sources for traffic in the permission. This block contains information Consul uses to evaluate the service that originated the request when the sidecar proxy authorizes incoming traffic.
-
-To specify wildcard references in this block using `*`, omit all other fields. For example, you can apply traffic permissions to all namespaces using the wildcard, but you cannot specify an identity name, partition, peer, or sameness group in the same source.
-
-#### Values
-
-- Default: None
-- Data type: List of maps
-
-### `spec.permissions.sources.identityName`
-
-Specifies the Workload identity for the service that originates the request.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-### `spec.permissions.destinationRules`
-
-Specifies L7 properties to match against when Consul enforces traffic permissions.
-
-When [`spec.action`](#spec-action) _allows traffic_, Consul authorizes requests to the destination service when the request matches one or more rules defined in this block. Requests that do not match any rules are denied.
-
-When [`spec.action`](#spec-action) _denies traffic_, Consul denies authorization to requests that match one or more rules defined in this block. Requests that do not match any rules are allowed.
-
-#### Values
-
-- Default: None
-- Data type: List of maps
-
-### `spec.permissions.destinationRules.portNames`
-
-Specifies a port name that the Kubernetes Pod's container exposes at the destination.
-
-#### Values
-
-- Default: None
-- Data type: String
-
-## Examples
-
-The following examples demonstrate common `TrafficPermissions` CRD configuration patterns for specific use cases.
-
-### Allow traffic to multiple ports
-
-The following example configures traffic permissions to allow traffic when the `web` service makes a request to the `api` service on the `api` port or `admin` port.
-
-```yaml
-apiVersion: auth.consul.hashicorp.com/v2beta1
-kind: TrafficPermissions
-metadata:
-  name: api-allow-web-all
-spec:
-  destination:
-    identityName: "api"
-  action: ACTION_ALLOW
-  permissions:
-    - sources:
-        - identityName: "web"
-      destinationRules:
-        - portNames: ["api", "admin"]
-
-```
-
-### Deny traffic between a service and a specific port 
-
-The following example configures traffic permissions to deny traffic when the `web` service makes a request to the `api` service on the `admin` port.
-This `ACTION_DENY` cannot be overridden by another `ACTION_ALLOW`.
-
-```yaml
-apiVersion: auth.consul.hashicorp.com/v2beta1
-kind: TrafficPermissions
-metadata:
-  name: web-to-admin-port-deny
-spec:
-  destination:
-    identityName: api
-  action: ACTION_DENY
-  permissions:
-    - sources:
-        - identityName: web
-      destinationRules:
-        - portNames: ["admin"]
-```
diff --git a/website/content/docs/k8s/multiport/traffic-split.mdx b/website/content/docs/k8s/multiport/traffic-split.mdx
deleted file mode 100644
index 4493c3d792..0000000000
--- a/website/content/docs/k8s/multiport/traffic-split.mdx
+++ /dev/null
@@ -1,113 +0,0 @@
----
-layout: docs
-page_title: Split traffic between multi-port services 
-description: Learn how to configure Consul to split TCP traffic between two ports of a multi-port service using the TCPRoute resource and the v2 catalog API
----
-
-# Split TCP traffic between multi-port services
-
-
-
-The v2 catalog API is currently in beta. This documentation supports testing and development scenarios. Do not use the v2 catalog API in secure production environments.
-
-
-
-This page describes the process for splitting TCP, HTTP, and gRPC traffic between two ports of a multi-port service. It includes an example TCPRoute resource configuration to demonstrate Consul's multi-port features.
-
-## Prerequisites
-
-Splitting traffic between two ports of a multi-port service requires the [v2 catalog API](/consul/docs/architecture/v2/catalog).
-
-In addition, they are two different workflows for registering Services in Kubernetes using the v2 catalog API. The instructions on this page offer examples for two configuration methods:
-
-- **Method 1**: Register a Kubernetes service that select workloads which expose multiple ports
-- **Method 2**: Register multiple Kubernetes Services that direct traffic to an explicit port on the same workload
-
-For guidance on enabling the v2 catalog, deploying multi-port services using these methods, and applying traffic permissions to the services, refer to [configure multi-port services](/consul/docs/k8s/multiport/configure).
-
-## Overview
-
-Complete the following steps to implement a split in TCP traffic between two services:
-
-1. Define the resource's behavior in a custom resource definition (CRD).
-1. Apply the resource to your cluster.
-
-## Define route resource
-
-The following example splits traffic for the `api` service. TCP traffic for services registered to the Consul catalog that are available at the `api-workload` port is split so that 50% of the traffic routes to the service at the `api-workload` port and 50% routes to the service at the `admin-workload` port.
-
-
-
-```yaml
-apiVersion: mesh.consul.hashicorp.com/v2beta1
-kind: TCPRoute
-metadata:
-  name: api-split
-spec:
-  parentRefs:
-    - ref:
-        type:
-          group: catalog
-          groupVersion: v2beta1
-          kind: Service
-        name: api
-      # The virtual port number for the "api-workload" target port.
-      port: "80"
-  rules:
-    - backendRefs:
-      - backendRef:
-          ref:
-            type:
-              group: catalog
-              groupVersion: v2beta1
-              kind: Service
-            name: api
-          # The virtual port number for the "api-workload" target port.
-          port: "80"
-        weight: 50
-      - backendRef:
-          ref:
-            type:
-              group: catalog
-              groupVersion: v2beta1
-              kind: Service
-            name: api
-          # The virtual port number for the "admin-workload" target port.
-          port: "90"
-        weight: 50
-```
-
-
-
-## Apply the resource
-
-Use the `kubectl` command to apply the resource to your Consul cluster.
-
-```shell-session
-$ kubectl apply -f api-split.yaml
-```
-
-
-
-
-
-Then, open a shell session in the `web` container and test the `api` service on port 90.
-
-```shell-session
-$ kubectl exec -it ${WEB_POD} -c web -- curl api:90
-```
-
-
-
-
-
-Then, open a shell session in the `web` container and test the `api-admin` service on port 90.
-
-```shell-session
-$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90
-```
-
-
-
-
-Half of the traffic should respond with the `hello world` response from port 80, instead of port 90's response of `hello world from 9090 admin`. Repeat the command several times to verify that you receive both responses.
diff --git a/website/content/docs/release-notes/consul/v1_17_x.mdx b/website/content/docs/release-notes/consul/v1_17_x.mdx
index da782d234b..378df6721e 100644
--- a/website/content/docs/release-notes/consul/v1_17_x.mdx
+++ b/website/content/docs/release-notes/consul/v1_17_x.mdx
@@ -15,13 +15,13 @@ We are pleased to announce the following Consul updates.
 
   These APIs are the foundation for future versions of Consul and enable new functionalities, such as multi-port and host-name-based canary routing and routing traffic through headless services in native Kubernetes deployments.
 
-  For more information, refer to the [Catalog API v2](/consul/docs/k8s/multiport#catalog-api-v2-beta) section in the documentation.
+  For more information, refer to the [Catalog API v2](/consul/docs/v1.17.x/k8s/multiport#catalog-api-v2-beta) section in the documentation.
 
    These APIs are in beta and under active development, so we do not recommend using them in production. 
 
 - **Multi-port services in Consul:** You can now register services with multiple ports per service. The v2 catalog API enables a single sidecar proxy to support workloads on different ports. This significantly reduces the operational overhead for managing Consul service mesh. Support for other runtimes outside of Kubernetes is planned for future releases of Consul.
 
-  Refer to the [Multi-port services for service mesh](/consul/docs/k8s/multiport#catalog-api-v2-beta) and [Configure multi-port services](/consul/docs/k8s/multiport/configure) for more information.
+  Refer to the [Multi-port services for service mesh](/consul/docs/v1.17.x/k8s/multiport#catalog-api-v2-beta) and [Configure multi-port services](/consul/docs/k8s/multiport/configure) for more information.
 
    Multi-port is currently a beta feature in Consul v1.17. 
 
diff --git a/website/content/docs/security/acl/acl-rules.mdx b/website/content/docs/security/acl/acl-rules.mdx
index 3503b589b9..a89985d528 100644
--- a/website/content/docs/security/acl/acl-rules.mdx
+++ b/website/content/docs/security/acl/acl-rules.mdx
@@ -19,7 +19,6 @@ The following table provides an overview of the resources you can use to create
 | `partition`
`partition_prefix` | Controls access to one or more admin partitions.
See [Admin Partition Rules](#admin-partition-rules) for details. | Yes | | `agent`
`agent_prefix` | Controls access to the utility operations in the [Agent API](/consul/api-docs/agent), such as `join` and `leave`.
See [Agent Rules](#agent-rules) for details. | Yes | | `event`
`event_prefix` | Controls access to event operations in the [Event API](/consul/api-docs/event), such as firing and listing events.
See [Event Rules](#event-rules) for details. | Yes | -| `identity`
`identity_prefix` | Controls access to workload identity operations in the [Catalog v2 group](/consul/docs/architecture/v2/catalog). | `key`
`key_prefix`   | Controls access to key/value store operations in the [KV API](/consul/api-docs/kv).
Can also use the `list` access level when setting the policy disposition.
Has additional value options in Consul Enterprise for integrating with [Sentinel](https://docs.hashicorp.com/sentinel/consul).
See [Key/Value Rules](#key-value-rules) for details. | Yes | | `keyring`       | Controls access to keyring operations in the [Keyring API](/consul/api-docs/operator/keyring).
See [Keyring Rules](#keyring-rules) for details. | No | | `mesh`       | Provides operator-level permissions for resources in the admin partition, such as ingress gateways or mesh proxy defaults. See [Mesh Rules](#mesh-rules) for details. | No | @@ -248,48 +247,6 @@ operation, so to enable this feature in a Consul environment with ACLs enabled, give agents a token with access to this event prefix, in addition to configuring [`disable_remote_exec`](/consul/docs/agent/config/config-files#disable_remote_exec) to `false`. -## Identity Rules - -The `identity` and `identity_prefix` resources control workload-identity-level registration and read access to the [Catalog v2 API group](/consul/docs/architecture/v2/catalog). -Specify the resource label in identity rules to set the scope of the rule. -The resource label in the following example is empty. As a result, the rules allow read-only access to any workload identity name with the empty prefix. -The rules also allow read-write access to the `app` identity and deny all access to the `admin` identity: - - - -```hcl -identity_prefix "" { - policy = "read" -} -identity "app" { - policy = "write" -} -identity "admin" { - policy = "deny" -} -``` - -```json -{ - "identity_prefix": { - "": { - "policy": "read" - } - }, - "identity": { - "app": { - "policy": "write" - }, - "admin": { - "policy": "deny" - } - } -} -``` - - - - ## Key/Value Rules The `key` and `key_prefix` resources control access to key/value store operations in the [KV API](/consul/api-docs/kv). diff --git a/website/data/commands-nav-data.json b/website/data/commands-nav-data.json index 8e35ee0beb..2199c036df 100644 --- a/website/data/commands-nav-data.json +++ b/website/data/commands-nav-data.json @@ -494,15 +494,6 @@ "title": "reload", "path": "reload" }, - { - "title": "resource", - "path": "resource", - "badge": { - "text": "v2", - "type": "outlined", - "color": "neutral" - } - }, { "title": "rtt", "path": "rtt" diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 7a8c32c4c7..5fcbc5394c 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -106,23 +106,6 @@ "title": "v1 Catalog", "path": "architecture/catalog" }, - { - "title": "v2 architecture", - "routes": [ - { - "title": "Overview", - "path": "architecture/v2" - }, - { - "title": "Catalog", - "path": "architecture/v2/catalog" - }, - { - "title": "Resource groups", - "path": "architecture/v2/groups" - } - ] - }, { "title": "Improving Consul Resilience", "path": "architecture/improving-consul-resilience" @@ -1601,48 +1584,6 @@ } ] }, - { - "title": "V2 Catalog API", - "routes": [ - { - "title": "Overview", - "path": "k8s/multiport" - }, - { - "title": "Configure multi-port services", - "path": "k8s/multiport/configure" - }, - { - "title": "Split TCP traffic between multiple ports", - "path": "k8s/multiport/traffic-split" - }, - { - "title": "Reference", - "routes": [ - { - "title": "GRPCRoute resource", - "path": "k8s/multiport/reference/grpcroute" - }, - { - "title": "HTTPRoute resource", - "path": "k8s/multiport/reference/httproute" - }, - { - "title": "ProxyConfiguration resource", - "path": "k8s/multiport/reference/proxyconfiguration" - }, - { - "title": "TCPRoute resource", - "path": "k8s/multiport/reference/tcproute" - }, - { - "title": "TrafficPermissions resource", - "path": "k8s/multiport/reference/trafficpermissions" - } - ] - } - ] - }, { "title": "L7 traffic management", "routes": [ diff --git a/website/redirects.js b/website/redirects.js index aabd6e1d78..362b3526af 100644 --- a/website/redirects.js +++ b/website/redirects.js @@ -212,16 +212,6 @@ module.exports = [ destination: '/consul/docs/v1.8.x/agent/config-entries/:slug', permanent: true, }, - { - source: '/consul/docs/k8s/multiport/reference/resource-command/:slug', - destination: '/consul/commands/resource/:slug', - permanent: true, - }, - { - source: '/consul/commands/:version(v1\.(?:8|9|10|11|12|13|14|15|16|17)\.x)/resource/:slug*', - destination: '/consul/docs/:version/k8s/multiport/reference/resource-command/:slug', - permanent: true - }, { source: '/consul/docs/architecture/catalog/v1/:slug', destination: '/consul/docs/architecture/catalog/:slug', @@ -230,26 +220,31 @@ module.exports = [ { source: '/consul/docs/:version(v1\.(?:8|9|10|11|12|13|14|15|16|17)\.x)/architecture/catalog/:slug*', destination: '/consul/docs/:version/architecture/catalog/v1/:slug', - permanent: true - }, - { - source: '/consul/docs/architecture/catalog/v2/:slug', - destination: '/consul/docs/architecture/v2/catalog/:slug', permanent: true, }, - { - source: '/consul/docs/:version(v1\.(?:8|9|10|11|12|13|14|15|16|17)\.x)/architecture/v2/catalog/:slug*', - destination: '/consul/docs/:version/architecture/catalog/v2/:slug', - permanent: true - }, { source: '/consul/docs/nia/network-drivers/terraform-cloud', destination: '/consul/docs/nia/network-drivers/hcp-terraform', - permanent: true + permanent: true, }, { source: '/consul/docs/:version(v1\.(?:8|9|10|11|12|13|14|15|16|17)\.x)/nia/network-drivers/hcp-terraform', destination: '/consul/docs/:version/nia/network-drivers/terraform-cloud', - permanent: true + permanent: true, + }, + { + source: '/consul/docs/k8s/multiport/:slug', + destination: '/consul/docs/architecture/catalog#v2-catalog', + permanent: true, + }, + { + source: 'consul/docs/architecture/v2/:slug*', + destination: '/consul/docs/architecture/catalog#v2-catalog', + permanent: true, + }, + { + source: '/consul/commands/resource/:slug', + destination: '/consul/docs/architecture/catalog#v2-catalog', + permanent: true, }, ] From 3ee6816d8db51884d2dcd5b956cdc1f141a73dec Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 10 Jun 2024 18:28:54 -0400 Subject: [PATCH 067/185] ci: fix nightly cron schedules to run once (#21296) Several of our nightly cron jobs are actually running repeatedly back-to-back during the designated hour. Change the cron to run them once as intended. --- .github/workflows/nightly-test-integ-peering_commontopo.yml | 2 +- .github/workflows/nightly-test-integrations-1.15.x.yml | 2 +- .github/workflows/nightly-test-integrations-1.17.x.yml | 2 +- .github/workflows/nightly-test-integrations-1.18.x.yml | 2 +- .github/workflows/nightly-test-integrations-1.19.x.yml | 2 +- .github/workflows/nightly-test-integrations.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nightly-test-integ-peering_commontopo.yml b/.github/workflows/nightly-test-integ-peering_commontopo.yml index 84b8a97c1c..ce55159233 100644 --- a/.github/workflows/nightly-test-integ-peering_commontopo.yml +++ b/.github/workflows/nightly-test-integ-peering_commontopo.yml @@ -6,7 +6,7 @@ name: Nightly test integrations - peering_common_topo on: schedule: # Run nightly at 12AM UTC/8PM EST/5PM PST - - cron: '* 0 * * *' + - cron: '0 0 * * *' workflow_dispatch: {} env: diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index db6607bda5..5bef4c85fa 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -6,7 +6,7 @@ name: Nightly test-integrations 1.15.x on: schedule: # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' + - cron: '0 1 * * *' workflow_dispatch: {} env: diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index c848c7f8fe..4bc89cab7c 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -6,7 +6,7 @@ name: Nightly test-integrations 1.17.x on: schedule: # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' + - cron: '0 1 * * *' workflow_dispatch: {} env: diff --git a/.github/workflows/nightly-test-integrations-1.18.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml index ee39c4f499..4ae1508c7a 100644 --- a/.github/workflows/nightly-test-integrations-1.18.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -6,7 +6,7 @@ name: Nightly test-integrations 1.18.x on: schedule: # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' + - cron: '0 1 * * *' workflow_dispatch: {} env: diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml index 876539046f..4648ec46b1 100644 --- a/.github/workflows/nightly-test-integrations-1.19.x.yml +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -6,7 +6,7 @@ name: Nightly test-integrations 1.19.x on: schedule: # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' + - cron: '0 1 * * *' workflow_dispatch: {} env: diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index bf914f8893..49fd9fc4e2 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -6,7 +6,7 @@ name: Nightly test-integrations on: schedule: # Run nightly at 12AM UTC/8PM EST/5PM PST - - cron: '* 0 * * *' + - cron: '0 0 * * *' workflow_dispatch: {} env: From 7ac9b1f9855ba15463e70530ab56d14cbac81430 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 11 Jun 2024 10:44:52 -0400 Subject: [PATCH 068/185] ci: fix a few missed Envoy version changes in latest bump (#21300) --- .github/workflows/nightly-test-integrations-1.19.x.yml | 2 +- .github/workflows/nightly-test-integrations.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml index 4648ec46b1..eb1f759e8f 100644 --- a/.github/workflows/nightly-test-integrations-1.19.x.yml +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -109,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.26.8", "1.27.6", "1.28.5", "1.29.5"] + envoy-version: ["1.26.8", "1.27.6", "1.28.4", "1.29.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index 49fd9fc4e2..fdb63d0738 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -206,8 +206,8 @@ jobs: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} # ENVOY_VERSION should be the latest version upported by all # consul versions in the matrix.consul-version, since we are testing upgrade from - # an older consul version, e.g., 1.27.5 is supported by both 1.16 and 1.17. - ENVOY_VERSION: "1.27.5" + # an older consul version, e.g., 1.27.x is supported by both 1.17 and 1.18. + ENVOY_VERSION: "1.27.6" steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 @@ -329,7 +329,7 @@ jobs: strategy: fail-fast: false matrix: - consul-version: [ "1.16", "1.17"] + consul-version: [ "1.17", "1.18"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} steps: From 04d95d2edacda654fef6102bf5c73ce0d32fbdd4 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 11 Jun 2024 11:35:41 -0500 Subject: [PATCH 069/185] Use text/template instead of html/template for ACL template policy generation (#21303) --- agent/structs/acl_templated_policy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent/structs/acl_templated_policy.go b/agent/structs/acl_templated_policy.go index 04c85515ff..52bdb0d66f 100644 --- a/agent/structs/acl_templated_policy.go +++ b/agent/structs/acl_templated_policy.go @@ -9,7 +9,7 @@ import ( "fmt" "hash" "hash/fnv" - "html/template" + "text/template" "github.com/hashicorp/go-multierror" "github.com/xeipuuv/gojsonschema" From 970353419cf69192c495165e6923eb4a3a9a3f22 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:58:01 -0700 Subject: [PATCH 070/185] docs: File System Certificates (#21259) * Reference page updates * Inline certificate config entry updates * API Gateway configuration page * K8s page updates * Apply suggestions from code review Co-authored-by: Blake Covarrubias Co-authored-by: danielehc <40759828+danielehc@users.noreply.github.com> * Daniele's suggestions * Encrypt VMs suggestions * Apply suggestions from code review Co-authored-by: Blake Covarrubias --------- Co-authored-by: Blake Covarrubias Co-authored-by: danielehc <40759828+danielehc@users.noreply.github.com> --- .../connect/config-entries/api-gateway.mdx | 8 +- .../control-plane-request-limit.mdx | 4 +- .../config-entries/exported-services.mdx | 4 +- .../file-system-certificate.mdx | 85 ++++++++++++++----- .../connect/config-entries/http-route.mdx | 2 +- .../config-entries/ingress-gateway.mdx | 4 +- .../config-entries/inline-certificate.mdx | 56 ++++++++++-- .../connect/config-entries/jwt-provider.mdx | 4 +- .../connect/config-entries/sameness-group.mdx | 4 +- .../config-entries/service-defaults.mdx | 2 +- .../config-entries/service-intentions.mdx | 4 +- .../config-entries/service-resolver.mdx | 4 +- .../connect/config-entries/service-router.mdx | 4 +- .../config-entries/service-splitter.mdx | 4 +- .../docs/connect/config-entries/tcp-route.mdx | 4 +- .../connect/gateways/api-gateway/index.mdx | 3 +- .../secure-traffic/encrypt-vms.mdx | 39 +++++++-- .../gateways/api-gateway/tech-specs.mdx | 5 +- 18 files changed, 172 insertions(+), 68 deletions(-) diff --git a/website/content/docs/connect/config-entries/api-gateway.mdx b/website/content/docs/connect/config-entries/api-gateway.mdx index 58c8167bd4..dc5d6f63e2 100644 --- a/website/content/docs/connect/config-entries/api-gateway.mdx +++ b/website/content/docs/connect/config-entries/api-gateway.mdx @@ -1,10 +1,10 @@ --- layout: docs -page_title: API Gateway Configuration Entry Reference +page_title: API Gateway configuration reference description: Learn how to configure a Consul API gateway on VMs. --- -# API gateway configuration entry reference +# API gateway configuration reference This topic provides reference information for the API gateway configuration entry that you can deploy to networks in virtual machine (VM) environments. For reference information about configuring Consul API gateways on Kubernetes, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). @@ -349,7 +349,7 @@ Specifies a list of cipher suites that the listener supports when negotiating co ### `Listeners[].TLS.Certificates[]` -The list of references to file system or inline certificates that the listener uses for TLS termination. +The list of references to [file system](/consul/docs/connect/config-entries/file-system-certificate) or [inline certificates](/consul/docs/connect/config-entries/inline-certificate) that the listener uses for TLS termination. You should create the configuration entry for the certificate separately and then reference the configuration entry in the `Name` field. #### Values @@ -372,7 +372,7 @@ The list of references to certificates that the listener uses for TLS terminatio ### `Listeners[].TLS.Certificates[].Name` -Specifies the name of the file system or inline certificate that the listener uses for TLS termination. +Specifies the name of the [file system certificate](/consul/docs/connect/config-entries/file-system-certificate) or [inline certificate](/consul/docs/connect/config-entries/inline-certificate) that the listener uses for TLS termination. #### Values diff --git a/website/content/docs/connect/config-entries/control-plane-request-limit.mdx b/website/content/docs/connect/config-entries/control-plane-request-limit.mdx index d6e828e670..53404c0d3f 100644 --- a/website/content/docs/connect/config-entries/control-plane-request-limit.mdx +++ b/website/content/docs/connect/config-entries/control-plane-request-limit.mdx @@ -1,10 +1,10 @@ --- layout: docs -page_title: Control Plane Request Limit Configuration Entry Configuration Reference +page_title: Control Plane Request Limit configuration reference description: Learn how to configure the control-plane-request-limit configuration entry, which defines how Consul agents limit read and request traffic rate limits. --- -# Control Plane Request Limit Configuration Entry Configuration Reference +# Control Plane Request Limit configuration reference This topic describes the configuration options for the `control-plane-request-limit` configuration entry. You can only write the `control-plane-request-limit` configuration entry to the `default` partition, but the configuration entry applies to all client requests that target any partition. diff --git a/website/content/docs/connect/config-entries/exported-services.mdx b/website/content/docs/connect/config-entries/exported-services.mdx index 7a268aeb77..ba783b4837 100644 --- a/website/content/docs/connect/config-entries/exported-services.mdx +++ b/website/content/docs/connect/config-entries/exported-services.mdx @@ -1,11 +1,11 @@ --- layout: docs -page_title: Exported Services - Configuration Entry Reference +page_title: Exported Services configuration reference description: >- An exported services configuration entry defines the availability of a cluster's services to cluster peers and local admin partitions. Learn about `""exported-services""` config entry parameters and exporting services to other datacenters. --- -# Exported Services Configuration Entry +# Exported Services configuration reference This topic describes the `exported-services` configuration entry type. The `exported-services` configuration entry enables Consul to export service instances to other clusters from a single file and connect services across clusters. For additional information, refer to [Cluster Peering](/consul/docs/connect/cluster-peering) and [Admin Partitions](/consul/docs/enterprise/admin-partitions). diff --git a/website/content/docs/connect/config-entries/file-system-certificate.mdx b/website/content/docs/connect/config-entries/file-system-certificate.mdx index a2c37eb3a6..d633139a77 100644 --- a/website/content/docs/connect/config-entries/file-system-certificate.mdx +++ b/website/content/docs/connect/config-entries/file-system-certificate.mdx @@ -1,13 +1,15 @@ --- layout: docs -page_title: File System Certificate Configuration Reference +page_title: File system certificate configuration reference description: Learn how to configure a file system certificate bound to an API Gateway on VMs. --- # File system certificate configuration reference -This topic provides reference information for the gateway file system certificate -configuration entry. For information about certificate configuration for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). +This topic provides reference information for the file system certificate +configuration entry. The file system certificate is a more secure alternative to the [inline certificate configuration entry](/consul/docs/connect/config-entries/inline-certificate) when using Consul API Gateway on VMs because it references a local filepath instead of including sensitive information in the configuration entry itself. File system certificates also include a file system watch that implements certificate and key changes without restarting the gateway. + +Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates without additional configuration. To learn about configuring certificates for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). ## Configuration model @@ -15,7 +17,7 @@ The following list outlines field hierarchy, language-specific data types, and requirements in a `file-system-certificate` configuration entry. Click on a property name to view additional details, including default values. -- [`Kind`](#kind): string | must be `"file-system-certificate"` +- [`Kind`](#kind): string | must be set to `"file-system-certificate"` - [`Name`](#name): string | no default - [`Namespace`](#namespace): string | no default - [`Partition`](#partition): string | no default @@ -27,33 +29,43 @@ to view additional details, including default values. When every field is defined, a `file-system-certificate` configuration entry has the following form: - + -```HCL + + +```hcl Kind = "file-system-certificate" Name = "" - +Namespace = "ns" +Partition = "default" Meta = { - "" = "" + "" = "" } -Certificate = "" -PrivateKey = "" +Certificate = "" +PrivateKey = "" ``` -```JSON + + + + +```json { "Kind": "file-system-certificate", "Name": "", + "Namespace": "ns", + "Partition": "default", "Meta": { - "any key": "any value" - } - "Certificate": "", - "PrivateKey": "" + "key": "value" + }, + "Certificate": "", + "PrivateKey": "" } ``` - + + ## Specification @@ -63,7 +75,7 @@ Specifies the type of configuration entry to implement. #### Values -- Default: none +- Default: None - This field is required. - Data type: string that must equal `"file-system-certificate"` @@ -75,7 +87,7 @@ as applying a configuration entry to a specific cluster. #### Values -- Default: none +- Default: None - This field is required. - Data type: string @@ -103,12 +115,12 @@ Specifies an arbitrary set of key-value pairs to associate with the gateway. #### Values -- Default: none +- Default: None - Data type: map containing one or more keys and string values. ### `Certificate` -Specifies the filepath to a public certificate to use for TLS. This filepath must be accessible to the API gateway proxy at runtime. +Specifies the path to a file that contains a public certificate to use for TLS. This filepath must be accessible to the API gateway proxy at runtime. #### Values @@ -118,10 +130,41 @@ Specifies the filepath to a public certificate to use for TLS. This filepath mus ### `PrivateKey` -Specifies the filepath to a private key to use for TLS. This filepath must be accessible to the API gateway proxy at runtime. +Specifies the path to a file that contains a private key to use for TLS. This filepath must be accessible to the API gateway proxy at runtime. #### Values - Default: none - This field is required. - Data type: string value of the filepath to a private key + +## Examples + +The following example demonstrates a file system certificate configuration. + + + + + +```hcl +Kind = "file-system-certificate" +Name = "tls-certificate" +Certificate = "/opt/consul/tls/api-gateway.crt" +PrivateKey = "/opt/consul/tls/api-gateway.key" +``` + + + + + +```json +{ + "Kind": "file-system-certificate", + "Name": "tls-certificate", + "Certificate": "opt/consul/tls/api-gateway.crt", + "PrivateKey": "/opt/consul/tls/api-gateway.key" +} +``` + + + \ No newline at end of file diff --git a/website/content/docs/connect/config-entries/http-route.mdx b/website/content/docs/connect/config-entries/http-route.mdx index 2240088b1a..6265930b3e 100644 --- a/website/content/docs/connect/config-entries/http-route.mdx +++ b/website/content/docs/connect/config-entries/http-route.mdx @@ -1,6 +1,6 @@ --- layout: docs -page_title: HTTP Route Configuration +page_title: HTTP Route configuration reference description: Learn how to configure an HTTP Route bound to an API Gateway on VMs. --- diff --git a/website/content/docs/connect/config-entries/ingress-gateway.mdx b/website/content/docs/connect/config-entries/ingress-gateway.mdx index 07339ffb52..cd8eaf326f 100644 --- a/website/content/docs/connect/config-entries/ingress-gateway.mdx +++ b/website/content/docs/connect/config-entries/ingress-gateway.mdx @@ -1,11 +1,11 @@ --- layout: docs -page_title: Ingress gateway configuration entry reference +page_title: Ingress gateway configuration reference description: >- The ingress gateway configuration entry kind defines behavior for securing incoming communication between the service mesh and external sources. Learn about `""ingress-gateway""` config entry parameters for exposing TCP and HTTP listeners. --- -# Ingress gateway configuration entry reference +# Ingress gateway configuration reference diff --git a/website/content/docs/connect/config-entries/inline-certificate.mdx b/website/content/docs/connect/config-entries/inline-certificate.mdx index 496650f859..abf68dc9b2 100644 --- a/website/content/docs/connect/config-entries/inline-certificate.mdx +++ b/website/content/docs/connect/config-entries/inline-certificate.mdx @@ -1,13 +1,15 @@ --- layout: docs -page_title: Inline Certificate Configuration Reference +page_title: Inline certificate configuration reference description: Learn how to configure an inline certificate bound to an API Gateway on VMs. --- # Inline certificate configuration reference -This topic provides reference information for the gateway inline certificate -configuration entry. For information about certificate configuration for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). +This topic provides reference information for the inline certificate +configuration entry. The inline certificate secures TLS for the Consul API gateway on VMs. In production environments, we recommend you use the more secure [file system certificate configuration entry](/consul/docs/connect/config-entries/file-system-certificate) instead. + +The inline certificate configuration entry is not used for Consul on Kubernetes deployments. To learn about configuring certificates for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). ## Configuration model @@ -27,9 +29,11 @@ to view additional details, including default values. When every field is defined, an `inline-certificate` configuration entry has the following form: - + -```HCL + + +```hcl Kind = "inline-certificate" Name = "" @@ -41,19 +45,24 @@ Certificate = "" PrivateKey = "" ``` -```JSON + + + + +```json { "Kind": "inline-certificate", "Name": "", "Meta": { "any key": "any value" - } + }, "Certificate": "", "PrivateKey": "" } ``` - + + ## Specification @@ -125,3 +134,34 @@ Specifies the inline private key to use for TLS. - Default: none - This field is required. - Data type: string value of the private key + +## Examples + +The following example demonstrates an inline certificate configuration. + + + + + +```hcl +Kind = "inline-certificate" +Name = "tls-certificate" +Certificate = "" +PrivateKey = "" +``` + + + + + +```json +{ + "Kind": "inline-certificate", + "Name": "tls-certificate", + "Certificate": "", + "PrivateKey": "" +} +``` + + + \ No newline at end of file diff --git a/website/content/docs/connect/config-entries/jwt-provider.mdx b/website/content/docs/connect/config-entries/jwt-provider.mdx index 9ea7ce40ba..d1bedd9355 100644 --- a/website/content/docs/connect/config-entries/jwt-provider.mdx +++ b/website/content/docs/connect/config-entries/jwt-provider.mdx @@ -1,10 +1,10 @@ --- -page_title: JWT provider configuration entry reference +page_title: JWT provider configuration reference description: |- JWT provider configuration entries add JSON Web Token token validation to intentions in the service mesh. Learn how to write `jwt-provider` config entries in HCL or YAML with a specification reference, configuration model, a complete example, and example code by use case. --- -# JWT provider configuration entry reference +# JWT provider configuration reference This page provides reference information for the JWT provider configuration entry, which configures Consul to use a JSON Web Token (JWT) and JSON Web Key Set (JWKS) in order to add JWT validation to proxies in the service mesh. Refer to [Use JWT authorization with service intentions](/consul/docs/connect/intentions/jwt-authorization) for more information. diff --git a/website/content/docs/connect/config-entries/sameness-group.mdx b/website/content/docs/connect/config-entries/sameness-group.mdx index e74c513fcb..6f3eec9db3 100644 --- a/website/content/docs/connect/config-entries/sameness-group.mdx +++ b/website/content/docs/connect/config-entries/sameness-group.mdx @@ -1,10 +1,10 @@ --- -page_title: Sameness group configuration entry reference +page_title: Sameness group configuration reference description: |- Sameness groups enable Consul to associate service instances with the same name deployed to the same namespace as identical services. Learn how to configure a `sameness-group` configuration entry to enable failover between partitions and cluster peers in non-federated networks. --- -# Sameness groups configuration entry reference +# Sameness groups configuration reference This page provides reference information for sameness group configuration entries. Sameness groups associate identical admin partitions to facilitate traffic between identical services. When partitions are part of the same Consul datacenter, you can create a sameness group by listing them in the `Members[].Partition` field. When partitions are located on remote clusters, you must establish cluster peering connections between remote partitions in order to add them to a sameness group in the `Members[].Peer` field. diff --git a/website/content/docs/connect/config-entries/service-defaults.mdx b/website/content/docs/connect/config-entries/service-defaults.mdx index 697aa36745..271256bbae 100644 --- a/website/content/docs/connect/config-entries/service-defaults.mdx +++ b/website/content/docs/connect/config-entries/service-defaults.mdx @@ -1,6 +1,6 @@ --- layout: docs -page_title: Service defaults configuration entry reference +page_title: Service defaults configuration reference description: -> Use the service-defaults configuration entry to set default configurations for services, such as upstreams, protocols, and namespaces. Learn how to configure service-defaults. --- diff --git a/website/content/docs/connect/config-entries/service-intentions.mdx b/website/content/docs/connect/config-entries/service-intentions.mdx index ff633dca3d..929f9e2e60 100644 --- a/website/content/docs/connect/config-entries/service-intentions.mdx +++ b/website/content/docs/connect/config-entries/service-intentions.mdx @@ -1,11 +1,11 @@ --- layout: docs -page_title: Service intentions configuration entry reference +page_title: Service intentions configuration reference description: >- Use the service intentions configuration entry to allow or deny traffic to services in the mesh from specific sources. Learn how to configure `service-intention` config entries --- -# Service intentions configuration entry reference +# Service intentions configuration reference This topic provides reference information for the service intentions configuration entry. Intentions are configurations for controlling access between services in the service mesh. A single service intentions configuration entry specifies one destination service and one or more L4 traffic sources, L7 traffic sources, or combination of traffic sources. Refer to [Service mesh intentions overview](/consul/docs/connect/intentions) for additional information. diff --git a/website/content/docs/connect/config-entries/service-resolver.mdx b/website/content/docs/connect/config-entries/service-resolver.mdx index 4358e49b1c..bce568514d 100644 --- a/website/content/docs/connect/config-entries/service-resolver.mdx +++ b/website/content/docs/connect/config-entries/service-resolver.mdx @@ -1,11 +1,11 @@ --- layout: docs -page_title: Service Resolver Configuration Entry Reference +page_title: Service Resolver configuration reference description: >- Service resolver configuration entries are L7 traffic management tools for defining sets of service instances that resolve upstream requests and Consul’s behavior when resolving them. Learn how to write `service-resolver` config entries in HCL or YAML with a specification reference, configuration model, a complete example, and example code by use case. --- -# Service resolver configuration entry reference +# Service resolver configuration reference This page provides reference information for service resolver configuration entries. Configure and apply service resolvers to create named subsets of service instances and define their behavior when satisfying upstream requests. diff --git a/website/content/docs/connect/config-entries/service-router.mdx b/website/content/docs/connect/config-entries/service-router.mdx index 814763957c..d384b83be3 100644 --- a/website/content/docs/connect/config-entries/service-router.mdx +++ b/website/content/docs/connect/config-entries/service-router.mdx @@ -1,11 +1,11 @@ --- layout: docs -page_title: Service Router Configuration Entry Reference +page_title: Service Router configuration reference description: >- Service router configuration entries are L7 traffic management tools for redirecting requests for a service to a particular instance or set of instances. Learn how to write `service-router` config entries in HCL or YAML with a specification reference, configuration model, a complete example, and example code by use case. --- -# Service router configuration entry reference +# Service router configuration reference This page provides reference information for service router configuration entries. Service routers use L7 network information to redirect a traffic request for a service to one or more specific service instances. diff --git a/website/content/docs/connect/config-entries/service-splitter.mdx b/website/content/docs/connect/config-entries/service-splitter.mdx index 5d94a4e38a..f7247be924 100644 --- a/website/content/docs/connect/config-entries/service-splitter.mdx +++ b/website/content/docs/connect/config-entries/service-splitter.mdx @@ -1,13 +1,13 @@ --- layout: docs -page_title: Service Splitter Configuration Entry Reference +page_title: Service Splitter configuration reference description: >- Service splitter configuration entries are L7 traffic management tools for redirecting requests for a service to multiple instances. Learn how to write `service-splitter` config entries in HCL or YAML with a specification reference, configuration model, a complete example, and example code by use case. --- -# Service Splitter Configuration Reference +# Service Splitter configuration reference This reference page describes the structure and contents of service splitter configuration entries. Configure and apply service splitters to redirect a percentage of incoming traffic requests for a service to one or more specific service instances. diff --git a/website/content/docs/connect/config-entries/tcp-route.mdx b/website/content/docs/connect/config-entries/tcp-route.mdx index e573a0183a..e7eda8c1cc 100644 --- a/website/content/docs/connect/config-entries/tcp-route.mdx +++ b/website/content/docs/connect/config-entries/tcp-route.mdx @@ -1,10 +1,10 @@ --- layout: docs -page_title: TCP Route Configuration Reference +page_title: TCP Route configuration reference description: Learn how to configure a TCP Route that is bound to an API gateway on VMs. --- -# TCP route configuration Reference +# TCP route configuration reference This topic provides reference information for the gateway TCP routes configuration entry. Refer to [Route Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/routes) for information diff --git a/website/content/docs/connect/gateways/api-gateway/index.mdx b/website/content/docs/connect/gateways/api-gateway/index.mdx index 5b29311bbc..c6202d898b 100644 --- a/website/content/docs/connect/gateways/api-gateway/index.mdx +++ b/website/content/docs/connect/gateways/api-gateway/index.mdx @@ -26,7 +26,8 @@ You can deploy API gateways to networks that implement a variety of computing en The following steps describe the general workflow for deploying a Consul API gateways: 1. For Kubernetes-orchestrated services, install Consul on your cluster. For Kubernetes-orchestrated services on OpenShift, you must also enable the `openShift.enabled` parameter. Refer to [Install Consul on Kubernetes](/consul/docs/connect/gateways/api-gateway/install-k8s) for additional information. -1. Define and deploy the API gateway configurations to create the API gateway artifacts. For VM-hosted services, create configuration entries for the gateway service, listeners configurations, and references to TLS certificates. For Kubernetes-orchestrated, configurations also include `GatewayClassConfig`s and `parametersRef`s. +1. Define and deploy the API gateway configurations to create the API gateway artifacts. For VM-hosted services, create configuration entries for the gateway service, listeners configurations, and TLS certificates. For Kubernetes-orchestrated services, configurations also include `GatewayClassConfig` and `parametersRef`. All Consul API Gateways created in Kubernetes with the `consul-k8s` Helm chart v1.5.0 or later use file system certificates when TLS is enabled. + 1. Define and deploy routes between the gateway listeners and services in the mesh. Gateway configurations are modular, so you can define and attach routes and inline certificates to multiple gateways. diff --git a/website/content/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms.mdx b/website/content/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms.mdx index 3520dfbc2e..fd1cdfe86c 100644 --- a/website/content/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms.mdx +++ b/website/content/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms.mdx @@ -1,7 +1,7 @@ --- layout: docs page_title: Encrypt API gateway traffic on virtual machines -description: Learn how to define inline certificate config entries and deploy them to Consul. Inline certificate configuration entries enable you to attach TLS certificates and keys to gateway listeners so that traffic between external clients and gateway listeners is encrypted. +description: Learn how to define inline certificate config entries and deploy them to Consul. Inline certificate and file system certificate configuration entries enable you to attach TLS certificates and keys to gateway listeners so that traffic between external clients and gateway listeners is encrypted. --- # Encrypt API gateway traffic on virtual machines @@ -10,8 +10,9 @@ This topic describes how to make TLS certificates available to API gateways so t ## Requirements -- Consul 1.15 or later -- You must have a certificate and key from your CA +- Consul v1.15 or later is required to use the Consul API gateway on VMs + - Consul v1.19 or later is required to use the [file system certificate configuration entry](/consul/docs/connect/config-entries/file-system-certificate) +- You must have a certificate and key from your CA - A Consul cluster with service mesh enabled. Refer to [`connect`](/consul/docs/agent/config/config-files#connect) - Network connectivity between the machine deploying the API gateway and a Consul cluster agent or server @@ -30,14 +31,20 @@ with Consul API gateway configurations. ## Define TLS certificates -1. Create an [`inline-certificate` configuration entry](/consul/docs/connect/gateways/api-gateway/configuration/inline-certificate) and specify the following fields: - - `Kind`: Specifies the type of configuration entry. This must be set to `inline-certificate`. +1. Create a [file system certificate](/consul/docs/connect/config-entries/file-system-certificate) or [inline certificate](/consul/docs/connect/config-entries/inline-certificate) and specify the following fields: + - `Kind`: Specifies the type of configuration entry. This must be set to `file-system-certificate` or `inline-certificate`. - `Name`: Specify the name in the [API gateway listener configuration](/consul/docs/connect/gateways/api-gateway/configuration/api-gateway#listeners) to bind the certificate to that listener. - - `Certificate`: Specifies the inline public certificate to use for TLS as plain text. - - `PrivateKey`: Specifies the inline private key to use for TLS as plain text. -1. Configure any additional fields necessary for your use case, such as the namespace or admin partition. Refer to the [`inline-certificate` configuration entry](/consul/docs/connect/gateways/api-gateway/configuration/inline-certificate) reference for additional information. + - `Certificate`: Specifies the filepath to the certificate on the local system or the inline public certificate as plain text. + - `PrivateKey`: Specifies the filepath to private key on the local system or the inline private key to as plain text. +1. Configure any additional fields necessary for your use case, such as the namespace or admin partition. Refer to the [file system certificate configuration reference](/consul/docs/connect/config-entries/file-system-certificate) or [inline certificate configuration reference](/consul/docs/connect/config-entries/inline-certificate) for more information. 1. Save the configuration. +### Examples + + + + + The following example defines a certificate named `my-certificate`. API gateway configurations that specify `inline-certificate` in the `Certificate.Kind` field and `my-certificate` in the `Certificate.Name` field are able to use the certificate. ```hcl @@ -57,6 +64,22 @@ PrivateKey = < + + + +The following example defines a certificate named `my-certificate`. API gateway configurations that specify `file-system-certificate` in the `Certificate.Kind` field and `my-certificate` in the `Certificate.Name` field are able to use the certificate. + +```hcl +Kind = "file-system-certificate" +Name = "my-certificate" +Certificate = "/opt/consul/tls/api-gateway.crt" +PrivateKey = "/opt/consul/tls/api-gateway.key" +``` + + + + ## Deploy the configuration to Consul Run the `consul config write` command to enable listeners to use the certificate. The following example writes a configuration called `my-certificate.hcl`: diff --git a/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx b/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx index 5dd4d5fdcd..9a79f75ca1 100644 --- a/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx +++ b/website/content/docs/connect/gateways/api-gateway/tech-specs.mdx @@ -87,7 +87,7 @@ You must specify the `"hashicorp.com/consul-api-gateway-controller"` controller The `Gateway` resource is the core API gateway component. Gateways have one or more listeners that can route `HTTP`, `HTTPS`, or `TCP` traffic. You can define header-based hostname matching for listeners, but SNI is not supported. -You can apply filters to add, remove, and set header values on incoming requests. Gateways support the `terminate` TLS mode and `core/v1/Secret` TLS certificates. Extended option support includes TLS version and cipher constraints. Refer to the [Kubernetes `Gateway` documentation](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.Gateway) for additional information. +You can apply filters to add, remove, and set header values on incoming requests. Gateways support the `terminate` TLS mode and `core/v1/Secret` TLS certificates. Extended option support includes TLS version and cipher constraints. Refer to [Kubernetes `Gateway` resource configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/gateway) for more information. ### `HTTPRoute` @@ -152,6 +152,3 @@ The following resources are allocated for each component of the API gateway. - **CPU**: None. Either the namespace or cluster default is allocated, depending on the Kubernetes cluster configuration. - **Memory**: None. Either the namespace or cluster default is allocated, depending on the Kubernetes cluster configuration. - - - From 963cee200b439d6d5192f6b9b608997fc777a1e3 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:58:12 -0700 Subject: [PATCH 071/185] docs: External Services CRD (#21264) * Initial reference page structure * Most specifications * Reference page details complete * Enterprise alerts * Overview page * Overview page * TGW note * fixes * Apply suggestions from code review Co-authored-by: Blake Covarrubias * Update website/content/docs/k8s/deployment-configurations/external-service.mdx Co-authored-by: Blake Covarrubias * Update website/content/docs/connect/config-entries/registration.mdx * Update website/content/docs/connect/config-entries/registration.mdx --------- Co-authored-by: Blake Covarrubias --- .../connect/config-entries/registration.mdx | 670 ++++++++++++++++++ .../connect/config-entries/sameness-group.mdx | 2 +- .../docs/k8s/connect/terminating-gateways.mdx | 6 + website/content/docs/k8s/crds/index.mdx | 1 + .../external-service.mdx | 35 + website/data/docs-nav-data.json | 8 + 6 files changed, 721 insertions(+), 1 deletion(-) create mode 100644 website/content/docs/connect/config-entries/registration.mdx create mode 100644 website/content/docs/k8s/deployment-configurations/external-service.mdx diff --git a/website/content/docs/connect/config-entries/registration.mdx b/website/content/docs/connect/config-entries/registration.mdx new file mode 100644 index 0000000000..95740cb084 --- /dev/null +++ b/website/content/docs/connect/config-entries/registration.mdx @@ -0,0 +1,670 @@ +--- +layout: docs +page_title: Registration CRD configuration reference +description: The Registration CRD enables Consul on Kubernetes to register an external service without a terminating gateway. Learn how to configure a Registration CRD in YAML with a specification reference, configuration model, a complete example, and example code. +--- + +# Registration CRD configuration reference + +This topic provides reference information for `Registration` custom resource definitions (CRDs). You can use this CRD to register an external service with Consul on Kubernetes. For more information. Refer to [Register services running on external nodes to Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/external-service) for more information. + +## Configuration model + +The following list outlines field hierarchy, language-specific data types, and requirements in a `Registration` CRD. Click on a property name to view additional details, including default values. + +- [`apiVersion`](#apiversion): string | required | must be set to `consul.hashicorp.com/v1alpha1` +- [`kind`](#kind): string | required | must be set to `Registration` +- [`metadata`](#metadata): map + - [`name`](#metadata-name): string +- [`spec`](#spec): map | required + - [`address`](#spec-address): string + - [`check`](#spec-check): map + - [`checkId`](#spec-check-checkid): string + - [`definition`](#spec-check-definition): map + - [`body`](#spec-check-definition): string + - [`deregisterCriticalServiceAfterDuration`](#spec-check-definition): string + - [`grpc`](#spec-check-definition): string + - [`grpcUseTLS`](#spec-check-definition): boolean | `false` + - [`header`](#spec-check-definition): map of strings + - [`http`](#spec-check-definition): string + - [`intervalDuration`](#spec-check-definition): string + - [`method`](#spec-check-definition): string + - [`osService`](#spec-check-definition): string + - [`tcp`](#spec-check-definition): string + - [`tcpUseTLS`](#spec-check-definition): boolean + - [`timeoutDuration`](#spec-check-definition): string + - [`tlsServerName`](#spec-check-definition): string + - [`tlsSkipVerify`](#spec-check-definition): boolean | `false` + - [`udp`](#spec-check-definition): string + - [`exposedPort`](#spec-check-exposed-port): integer + - [`name`](#spec-check-name): string + - [`namespace`](#spec-check-namespace): string + - [`node`](#spec-check-node): string + - [`notes`](#spec-check-notes): string + - [`output`](#spec-check-output): string + - [`partition`](#spec-check-partition): string + - [`serviceId`](#spec-check-serviceid): string + - [`serviceName`](#spec-check-servicename): string + - [`status`](#spec-check-status): string + - [`type`](#spec-check-type): string + - [`datacenter`](#spec-datacenter): string + - [`id`](#spec-id): string + - [`locality`](#spec-locality): map + - [`region`](#spec-locality): string + - [`zone`](#spec-locality): string + - [`node`](#spec-node): string + - [`nodeMeta`](#spec-nodemeta): map of strings + - [`partition`](#spec-partition): string + - [`service`](#spec-service): map + - [`address`](#spec-service-address): string + - [`enableTagOverride`](#spec-service-enabletagoverride): boolean | `false` + - [`id`](#spec-service-id): string + - [`locality`](#spec-service-locality): map + - [`region`](#spec-service-locality): string + - [`zone`](#spec-service-locality): string + - [`meta`](#spec-service-meta): map of strings + - [`name`](#spec-service-name): string + - [`namespace`](#spec-service-namespace): string + - [`partition`](#spec-service-partition): string + - [`port`](#spec-service-port): integer + - [`socketPath`](#spec-service-socketpath): string + - [`taggedAddresses`](#spec-service-taggedaddresses): map + - [`address`](#spec-service-taggedaddresses): string + - [`port`](#spec-service-port): integer + - [`tags`](#spec-service-tags): map of strings + - [`weights`](#spec-service-weights): map + - [`passing`](#spec-service-weights): integer | `1` + - [`warning`](#spec-service-weights): integer | `1` + - [`skipNodeUpdate`](#spec-skipnodeupdate): boolean | `false` + - [`taggedAddresses`](#spec-taggedaddresses): map of strings + +## Complete configuration + +When every field is defined, a `Registration` CRD has the following form: + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 # required +kind: Registration # required +metadata: + name: +spec: + address: 10.0.0.1 + check: + name: external-health-check + checkId: unique-id + definition: + body: "{\"custom\": \"json\"}" + deregisterCriticalServiceAfterDuration: false + grpc: 127.0.0.1:443 + grpcUseTLS: false + header: + name: + intervalDuration: "5s" + method: "GET" + osService: + tcp: 127.0.0.1:4242 + tcpUseTLS: false + timeoutDuration: 10s + tlsServerName: + tlsSkipVerify: false + udp: 127.0.0.1:80 + exposedPort: 200 + namespace: default + notes: "Human readable description" + output: "Human readable output" + partition: default + serviceId: + serviceName: + status: critical + type: HTTP + datacenter: dc1 + id: + locality: + region: us-east-1 + zone: us-east-1a + node: + nodeMeta: + - key: value + partition: default + service: + address: "10.0.0.1:8300" + enableTagOverride: false + id: + locality: + region: us-east-1 + zone: us-east-1a + meta: + key: value + name: + namespace: default + partition: default + port: 5400 + socketPath: /folder/socket + taggedAddresses: + lan: + address: 127.0.1.0 + port: 80 + tags: + - "v2" + - "primary" + weights: + passing: 1 + warning: 1 + skipNodeUpdate: false + taggedAddresses: + lan: "192.168.10.10" +``` + +## Specification + +This section provides details about the fields you can configure in the `Registration` CRD. + +### `apiVersion` + +Specifies the version of the Consul API for integrating with Kubernetes. The value must be `consul.hashicorp.com/v1alpha1`. + +#### Values + +- Default: None +- This field is required. +- String value that must be set to `consul.hashicorp.com/v1alpha1`. + +### `kind` + +Specifies the type of configuration entry to implement. Must be set to `Registration`. + +#### Values + +- Default: None +- This field is required. +- Data type: String value that must be set to `Registration`. + +### `metadata` + +Map that contains an arbitrary name for the configuration entry and the namespace it applies to. + +#### Values + +- Default: None +- Data type: Map + +### `metadata.name` + +Specifies a name for the configuration entry that is used to identify the sameness group. To ensure consistency, use descriptive names and make sure that the same name is used when creating configuration entries to add each member to the sameness group. + +#### Values + +- Default: None +- This field is required. +- Data type: String + +### `spec` + +Map that contains the details about the `Registration` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children. + +#### Values + +- Default: None +- This field is required. +- Data type: Map + +### `spec.address` + +Specifies the IP address where the external service is available. + +#### Values + +- Default: None +- Data type: String + +### `spec.check` + +Specifies details for a health check. Health checks perform several safety functions, such as allowing a web balancer to gracefully remove failing nodes and allowing a database to replace a failed secondary. You can configure health checks to monitor the health of the entire node. + +For more information about configuring health checks for Consul, refer to [health check configuration reference](/consul/docs/services/configuration/checks-configuration-reference). + +#### Values + +- Default: None +- Data type: Map + +### `spec.check.checkId` + +Specifies an ID for the health check. When `name` values conflict, provide a unique identifier to avoid overwriting existing checks. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.definition` + +Specifies additional configuration details for the health check. + +Requires child parameters `deregisterCriticalServiceAfterDuration`, `intervalDuration`, and `timeoutDuration`. + +#### Values + +- Default: None +- Data type: Map that can contain the following parameters: + +| Parameter | Description | Type | Default | +| :------------------------------------------------------------- | :---------- | :---------- | :---------- | +| `spec.check.definition.body` | Specifies JSON attributes to send in HTTP check requests. You must escape the quotation marks around the keys and values for each attribute. | String | None | +| `spec.check.definition.deregisterCriticalServiceAfterDuration` | Specifies how long a service and its associated checks are allowed to be in a `critical` state. Consul deregisters services if they are `critical` for the specified amount of time. This parameter is required to configure `spec.check.definition`. | String | `"30s"` | +| `spec.check.definition.grpc` | Specifies the gRPC endpoint, including port number, to send requests to. Append the endpoint with `:/` and a service identifier to check a specific service. The endpoint must support the [gRPC health checking protocol](https://github.com/grpc/grpc/blob/master/doc/health-checking.md). | String | None | +| `spec.check.definition.grpcUseTLS` | Enables TLS for gRPC checks when set to `true`. | Boolean | `false` | +| `spec.check.definition.header` | Specifies header fields to send in HTTP check requests. | Map of strings | None | +| `spec.check.definition.http` | Specifies an HTTP endpoint to send requests to. | String | None | +| `spec.check.definition.intervalDuration` | Specifies how frequently to run the health check. This parameter is required to configure `spec.check.definition`. | String | `"5s"` | +| `spec.check.definition.method` | Specifies the request method to send during HTTP checks. | String | `GET` | +| `spec.check.definition.osService` | Specifies the name of the name of a service to check during an OSService check. | String | None | +| `spec.check.definition.tcp` | Specifies an IP address or host and port number that the check establishes a TCP connection with. | String | None | +| `spec.check.definition.tcpUseTLS` | Enables TLS for TCP checks when set to `true`. | Boolean | `false` | +| `spec.check.definition.timeoutDuration` | Specifies how long unsuccessful requests take to end with a timeout. This parameter is required to configure `spec.check.definition`. | String | `"10s"` | +| `spec.check.definition.tlsServerName` | Specifies the server name used to verify the hostname on the returned certificates unless `tls_skip_verify` is configured. This value is also included in the client's handshake to support SNI. It is recommended that this field be left unspecified. Refer to [health check configuration reference](/consul/docs/services/configuration/checks-configuration-reference#check-block) for more information. | String | None | +| `spec.check.definition.tlsSkipVerify` | Determines if the check verifies the chain and hostname of the certificate that the server presents. Set to `true` to disable verification. We recommend setting to `false` in production environments. | Boolean | `false` | +| `spec.check.definition.udp` | Specifies an IP address or host and port number for the check to send UDP datagrams to. | String | None | + +### `spec.check.exposedPort` + +Specifies the port the service exposes to health checks. + +#### Values + +- Default: None +- Data type: Integer + +### `spec.check.name` + +Specifies a name for the health check. Defaults to [`spec.service.id`](#spec-service-id). + +#### Values + +- Default: None +- Data type: String + +### `spec.check.namespace` + +Specifies the Consul namespace the health check applies to. Refer to [namespaces](/consul/docs/enterprise/namespace) for more information. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.node` + +Specifies the name of the node the health check applies to. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.notes` + +Provides a human-readable description of the health check. The contents are not visible to Consul. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.output` + +Specifies human readable output in response to a health check. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.partition` + +Specifies the Consul admin partition the health check applies to. Refer to [admin partitions](/consul/docs/enterprise/admin-partitions) for more information. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.serviceId` + +Specifies the ID of the service to perform the health check on. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.serviceName` + +Specifies the name of the service to perform the health check on. + +#### Values + +- Default: None +- Data type: String + +### `spec.check.status` + +Specifies the initial status of the health check. The default value for this field is `critical`, which requires services to pass a health check before making them available for service disocvery. You can specify one the following values: + +- `critical` +- `warning` +- `passing` + +#### Values + +- Default: `critical` +- Data type: String + +### `spec.check.type` + +Specifies the type health check in the form of a Kubernetes probe. + +#### Values + +- Default: None +- Data type: String + +### `spec.datacenter` + +Specifies the datacenter to register the service's node in, which defaults to the agent's datacenter if not provided. + +#### Values + +- Default: None +- Data type: String + +### `spec.id` + +Specifies a unique ID for the node to register. This optional ID must be a 36-character UUID-formatted string. + +#### Values + +- Default: None +- Data type: String + +### `spec.locality` + +Specifies the cloud region and zone where the node is available. + +#### Values + +- Default: None +- Data type: Map that can contain the following parameters: + +| Parameter | Description | Data type | Default | +| :-------- | :---------- | :-------- | :------ | +| `spec.locality.region` | Specifies the region where the node is running. Consul assigns this value to services registered to that agent. When service proxy regions match, Consul is able to prioritize routes between service instances in the same region over instances in other regions. You must specify values that are consistent with how regions are defined in your network, for example `us-west-1` for networks in AWS. | String | None | +| `spec.locality.zone` | Specifies the availability zone where the node is running. Consul assigns this value to services registered to that agent. When service proxy regions match, Consul is able to prioritize routes between service instances in the same region and zone over instances in other regions and zones. When healthy service instances are available in multiple zones within the most-local region, Consul prioritizes instances that also match the downstream proxy's `zone`. You must specify values that are consistent with how zones are defined in your network, for example `us-west-1a` for networks in AWS. | String | None | + +### `spec.node` + +Specifies the name of the node to register. + +#### Values + +- Default: None +- Data type: String + +### `spec.nodeMeta` + +Specifies arbitrary KV metadata pairs for filtering purposes. + +#### Values + +- Default: None +- Data type: Map of strings + +### `spec.partition` + +Specifies the admin partition of the node to register. + +#### Values + +- Default: None +- Data type: String + +### `spec.service` + +Specifies the service to register. The `Service.Service` field is required. If `Service.ID` is not provided, the default is the `Service.Service`. + +You can only specify one service with a given `ID` per node. We recommend using valid DNS labels for service definition names. Refer to [Internet Engineering Task Force's RFC 1123](https://datatracker.ietf.org/doc/html/rfc1123#page-72) for additional information. Service names that conform to standard usage ensures compatibility with external DNSs. Refer to [Services Configuration Reference](/consul/docs/services/configuration/services-configuration-reference#name) for more information. + +#### Values + +- Default: None +- Data type: Map + +### `spec.service.address` + +Specifies a service-specific IP address or hostname. If no value is specified, the IP address of the agent node is used by default. There is no service-side validation of this parameter. + +#### Values + +- Default: None +- Data type: String + +### `spec.service.enableTagOverride` + +Setermines if the anti-entropy feature for the service is enabled. + +Set to `true` to allow external Consul agents to modify tags on the services in the Consul catalog. The local Consul agent ignores updated tags during subsequent sync operations. + +This parameter only applies to the locally-registered service. When multiple nodes register a service with the same name, the `enable_tag_override` configuration and all other service configuration items operate independently. + +Refer to [Modify anti-entropy synchronization](/consul/docs/services/usage/define-services#modify-anti-entropy-synchronization) for additional information. + +#### Values + +- Default: `false` +- Data type: Boolean + +### `spec.service.id` + +Specifies an ID for the service. Services on the same node must have unique IDs. We recommend specifying unique values if the default name conflicts with other services. + +#### Values + +- Default: None +- Data type: String + +### `spec.service.locality` + +Specifies the region and zone in the cloud service provider (CSP) where the service is available. Configure this field to enable Consul to route traffic to the nearest physical service instance. Services inherit the `locality` configuration of the Consul agent they are registered with, but you can explicitly define locality for your service instances if an override is needed. Refer to [Route traffic to local upstreams](/consul/docs/connect/manage-traffic/route-to-local-upstreams) for additional information. + +#### Values + +- Default: None +- Data type: Map that can contain the following parameters: + +| Parameter | Description | Data type | Default | +| :-------- | :---------- | :-------- | :------ | +| `spec.service.locality.region` | Specifies the region where the Consul agent is running. Consul assigns this value to services registered to that agent. When service proxy regions match, Consul is able to prioritize routes between service instances in the same region over instances in other regions. You must specify values that are consistent with how regions are defined in your network, for example `us-west-1` for networks in AWS. | String | None | +| `spec.service.locality.zone` | Specifies the availability zone where the Consul agent is running. Consul assigns this value to services registered to that agent. When service proxy regions match, Consul is able to prioritize routes between service instances in the same region and zone over instances in other regions and zones. When healthy service instances are available in multiple zones within the most-local region, Consul prioritizes instances that also match the downstream proxy's `zone`. You must specify values that are consistent with how zones are defined in your network, for example `us-west-1a` for networks in AWS. | String | None | + +### `spec.service.meta` + +Specifies custom key-value pairs that associate semantic metadata with the service. You can specify up to 64 pairs that meet the following requirements: + +- Keys and values must be strings. +- Keys can only contain ASCII characters (`A` -` Z`, `a`- `z`, `0` - `9`, `_`, and `-`). +- Keys can not have special characters. +- Keys are limited to 128 characters. +- Values are limited to 512 characters. + +#### Values + +- Default: None +- Data type: Map of strings + +### `spec.service.name` + +Specifies a name for the service. We recommend using valid DNS labels for service definition names for compatibility with external DNSs. The value of this parameter is also used as the service ID if the `spec.service.id` parameter is not specified. + +#### Values + +- Default: None +- Data type: String + +### `spec.service.namespace` + +Specifies the Consul namespace to register the service in. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information. + +#### Values + +- Default: None +- Data type: String + +### `spec.service.partition` + +Specifies the Consul admin partition to register the service in. Refer to [admin partitions](/consul/docs/enterprise/admin-partitions) for more information. + +#### Values + +- Default: None +- Data type: String + +### `spec.service.port` + +Specifies a port number for the service. To improve service discoverability, we recommend specifying the port number, as well as an address in the tagged_addresses parameter. + +#### Values + +- Default: None +- Data type: Integer + +### `spec.service.socketPath` + +Specifies the path to the service socket. Specify this parameter to expose the service to the mesh if the service listens on a Unix Domain socket. + +#### Values + +- Default: None +- Data type: String + +### `spec.service.taggedAddresses` + +Configures additional addresses for a node or service. Remote agents and services can communicate with the service using a tagged address as an alternative to the address specified in [`spec.service.address`](#spec-serviceaddress). You can configure multiple addresses for a node or service. The following tags are supported: + +- `lan`: IPv4 LAN address where the node or service is accessible. +- `lan_ipv4`: IPv4 LAN address where the node or service is accessible. +- `lan_ipv6`: IPv6 LAN address where the node or service is accessible. +- `virtual`: A fixed address for the instances of a given logical service. +- `wan`: IPv4 WAN address where the node or service is accessible when dialed from a remote data center. +- `wan_ipv4`: IPv4 WAN address where the node or service is accessible when dialed from a remote data center. +- `wan_ipv6`: IPv6 WAN address at which the node or service is accessible when being dialed from a remote data center. + +#### Values + +- Default: None +- Data type: Map that contains a supported tag and a child map containing the following fields: + +| Parameter | Description | Type | Default | +| :------------------------------------- | :---------------------------- | :---------- | :---------- | +| `spec.service.taggedAddresses.address` | The address saved in the tag. | String | None | +| `spec.service.taggedAddresses.port` | The port saved in the tag. | String | None | + +### `spec.service.tags` + +Specifies a list of string values that add service-level labels. Tag values are opaque to Consul. We recommend using valid DNS labels for service definition IDs for compatibility with external DNSs. In the following example, the service is tagged as `v2` and `primary`: + +```yaml +spec: + service: + tags: ["v2", "primary"] +``` + +Consul uses tags as an anti-entropy mechanism to maintain the state of the cluster. You can disable the anti-entropy feature for a service using [`spec.service.enable_tag_override`](#spec-service-enabletagoverride), which enables external agents to modify tags on services in the catalog. Refer to [Modify anti-entropy synchronization](/consul/docs/services/usage/define-services#modify-anti-entropy-synchronization) for additional usage information. + +#### Values + +- Default: None +- Data type: Map of strings + +### `spec.service.weights` + +Configures how a service instance is weighted in a DNS SRV request based on the service's health status. Configuring tells DNS clients to direct more traffic to instances with a higher weight. A use case would be adjusting the weight higher for an instance with large capacity. It could also be used to reduce the load on services with checks in `warning` status by favoring passing instances with a higher weight. + +Larger integer values increase the weight state. + +You can specify one or more of the following states and configure an integer value indicating its weight: + +- `passing` +- `warning` + +Services in a `critical` state are excluded from DNS responses. Services with `warning` checks are included in responses by default. + +#### Values + +- Default: None +- Data type: Map containing the following parameters: + +| Parameter | Description | Type | Default | +| :----------------------------- | :---------------------------- | :---------- | :---------- | +| `spec.service.weights.passing` | Higher values increases the likelihood that a request is routed to a service in a `passing` state. | Integer | `1` | +| `spec.service.weights.warning` | Higher values increases the likelihood that a request is routed to a service in a `warning` state. | Integer | `1` | + +### `spec.skipNodeUpdate` + +Specifies whether to skip updating the node's information in the registration. This field is useful in casew where only a health check or service entry on a node needs to be updated or when a register request is intended to update a service entry or health check. In both use cases, node information is not be overwritten, if the node is already registered. Note, if the parameter is enabled for a node that does not exist, it is still be created. + +#### Values + +- Default: `false` +- Data type: Boolean + +### `spec.taggedAddresses` + +Specifies tagged addresses for the node. Remote agents and services can communicate with the service using a tagged address as an alternative to the address specified in [`spec.address`](#spec-serviceaddress). You can configure multiple addresses for a node or service. The following tags are supported: + +- `lan`: IPv4 LAN address where the node or service is accessible. +- `lan_ipv4`: IPv4 LAN address where the node or service is accessible. +- `lan_ipv6`: IPv6 LAN address where the node or service is accessible. +- `virtual`: A fixed address for the instances of a given logical service. +- `wan`: IPv4 WAN address where the node or service is accessible when dialed from a remote data center. +- `wan_ipv4`: IPv4 WAN address where the node or service is accessible when dialed from a remote data center. +- `wan_ipv6`: IPv6 WAN address at which the node or service is accessible when being dialed from a remote data center. + +#### Values + +- Default: None +- Data type: Map of strings + +## Examples + +The following example demonstrates a common `Registration` CRD configuration pattern. In this example, Consul registers a database service available at the IP address `10.96.32.66` that runs outside of the Kubernetes cluster where Consul is deployed. Consul runs an HTTP health check on this service every 10 seconds. + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: Registration +metadata: + name: external-database +spec: + node: node-virtual + check: + node: node-virtual + checkId: db-check + name: db + serviceName: db + serviceId: db-external + notes: "Runs the external health check for the database." + status: "passing" + definition: + http: "10.96.32.66:8081/health" + intervalDuration: "10s" + timeoutDuration: "10s" + deregisterCriticalServiceAfterDuration: "30s" + service: + name: db + id: db-external + address: "10.96.32.66" + port: 8081 + weights: + passing: 1 + warning: 1 + address: 10.96.32.66 +``` \ No newline at end of file diff --git a/website/content/docs/connect/config-entries/sameness-group.mdx b/website/content/docs/connect/config-entries/sameness-group.mdx index 6f3eec9db3..f9fdffcd7a 100644 --- a/website/content/docs/connect/config-entries/sameness-group.mdx +++ b/website/content/docs/connect/config-entries/sameness-group.mdx @@ -230,7 +230,7 @@ Specifies the type of configuration entry to implement. Must be set to `Sameness - This field is required. - Data type: String value that must be set to `SamenessGroup`. -## `metadata` +### `metadata` Map that contains an arbitrary name for the configuration entry and the namespace it applies to. diff --git a/website/content/docs/k8s/connect/terminating-gateways.mdx b/website/content/docs/k8s/connect/terminating-gateways.mdx index 3ed8f71e5c..78f7813087 100644 --- a/website/content/docs/k8s/connect/terminating-gateways.mdx +++ b/website/content/docs/k8s/connect/terminating-gateways.mdx @@ -84,6 +84,12 @@ $ export CONSUL_HTTP_TOKEN=$(kubectl get secret consul-bootstrap-acl-token --tem ## Register external services with Consul + + +Consul on Kubernetes now supports the `Registration` CRD to register services running on external nodes without a terminating gateway. We recommend registering services with this CRD instead of deploying a terminating gateway. For more information, refer to [Register services running on external nodes to Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/external-service). + + + Registering the external services with Consul is a multi-step process: - Register external services with Consul diff --git a/website/content/docs/k8s/crds/index.mdx b/website/content/docs/k8s/crds/index.mdx index b2ed48854f..3db8edaf2f 100644 --- a/website/content/docs/k8s/crds/index.mdx +++ b/website/content/docs/k8s/crds/index.mdx @@ -19,6 +19,7 @@ You can specify the following values in the `kind` field. Click on a configurati - [`PeeringAcceptor`](/consul/docs/k8s/connect/cluster-peering/tech-specs#peeringacceptor) - [`PeeringDialer`](/consul/docs/k8s/connect/cluster-peering/tech-specs#peeringdialer) - [`ProxyDefaults`](/consul/docs/connect/config-entries/proxy-defaults) +- [`Registration`](/consul/docs/connect/config-entries/registration) - [`SamenessGroup`](/consul/docs/connect/config-entries/sameness-group) - [`ServiceDefaults`](/consul/docs/connect/config-entries/service-defaults) - [`ServiceSplitter`](/consul/docs/connect/config-entries/service-splitter) diff --git a/website/content/docs/k8s/deployment-configurations/external-service.mdx b/website/content/docs/k8s/deployment-configurations/external-service.mdx new file mode 100644 index 0000000000..3a55c254af --- /dev/null +++ b/website/content/docs/k8s/deployment-configurations/external-service.mdx @@ -0,0 +1,35 @@ +--- +layout: docs +page_title: Register services running on external nodes to Consul on Kubernetes +description: >- + Learn how to register a service running on an external node to the Consul catalog when running Consul on Kubernetes. +--- + +# Register services running on external nodes to Consul on Kubernetes + +This page provides an overview for registering services in the Consul catalog when the service runs on a node that is not part of the Kubernetes cluster. + +## Introduction + +Because Kubernetes has built-in service discovery capabilities, Consul on Kubernetes includes components such as [Consul dataplanes](/consul/docs/connect/dataplane) and [service sync](/consul/docs/k8s/service-sync) so that operators can continue to use Kubernetes tools and processes. However, this approach to service networking still requires a service to run on a node that Consul is aware of, either through a local Consul client agent or the Kubernetes cluster. We call services that run on external nodes that Consul cannot automatically recognize _external services_. + +Previously, the only way to register an external service when running Consul on Kubernetes was using Consul's HTTP API. This approach requires additional ACLs and direct access to Consul's HTTP API endpoint. Consul now supports registering external services and their associated health checks in the Consul catalog using a [`Registration` custom resource definition (CRD)](/consul/docs/connect/config-entries/registration) that follows the format of [Consul's service definitions](/consul/docs/services/configuration/services-configuration-reference). + +## Workflows + +The process to register an external service in Consul on Kubernetes consists of the following steps: + +1. Define the external service and its health checks in a [`Registration` CRD](/consul/docs/connect/config-entries/registration). +1. Apply the CRD to your Kubernetes cluster. Internally, this action triggers an API call to Consul's [`/catalog/register` endpoint](/consul/api-docs/catalog#register-entity) to register the service. +1. When using Consul's service mesh, define [service intentions](/consul/docs/connect/intentions) between the external service and services it communicates with. + +## Guidance + +The following resources are available to help you register external services to Consul on Kubernetes. + +### Reference + +- [`Registration` custom resource definition (CRD) configuration reference](/consul/docs/connect/config-entries/registration) +- [`/catalog/register` HTTP API endpoint reference](/consul/api-docs/catalog#register-entity) +- [Service configuration reference](/consul/docs/services/configuration/services-configuration-reference) +- [Health check configuration reference](/consul/docs/services/configuration/checks-configuration-reference) \ No newline at end of file diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 5fcbc5394c..d5bc1ad83e 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -484,6 +484,10 @@ "title": "Proxy defaults", "path": "connect/config-entries/proxy-defaults" }, + { + "title": "Registration", + "path": "connect/config-entries/registration" + }, { "title": "Sameness Group", "path": "connect/config-entries/sameness-group" @@ -1455,6 +1459,10 @@ { "title": "Datadog metrics", "path": "k8s/deployment-configurations/datadog" + }, + { + "title": "Register external services", + "path": "k8s/deployment-configurations/external-service" } ] }, From 14e409ef543723dbc805026e377fcdcd7fdcdd16 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 11 Jun 2024 15:17:12 -0500 Subject: [PATCH 072/185] Configure linter to forbid use of html/template (#21307) * Configure linter to forbid use of html/template We should never use html/template due to the performance penalty and the fact that we are highly unlikely to ever be generating HTML templates. * Link to PR explaining the format of forbidigo.forbid --- .golangci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.golangci.yml b/.golangci.yml index 3a6f56ec99..e530ce70bd 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -75,7 +75,9 @@ linters-settings: simplify: true forbidigo: # Forbid the following identifiers (list of regexp). + # Format includes custom message based on https://github.com/ashanbrown/forbidigo/pull/11 forbid: + - '\bhtml\/template\b(# Use text/template instead)?' - '\bioutil\b(# Use io and os packages instead of ioutil)?' - '\brequire\.New\b(# Use package-level functions with explicit TestingT)?' - '\bassert\.New\b(# Use package-level functions with explicit TestingT)?' From bba8dcba806f47cfb5c44195ab6a7666ca2022de Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:25:18 -0700 Subject: [PATCH 073/185] docs: Consul v1.19 Release Notes (#21279) * Initial release notes * Draft of release notes * spacing fix * Apply suggestions from code review Co-authored-by: Aimee Ukasick * Update website/content/docs/release-notes/consul/v1_19_x.mdx --------- Co-authored-by: Aimee Ukasick --- consul-k8s | 1 + .../content/docs/release-notes/consul/v1_19_x.mdx | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 160000 consul-k8s diff --git a/consul-k8s b/consul-k8s new file mode 160000 index 0000000000..0d85bbc313 --- /dev/null +++ b/consul-k8s @@ -0,0 +1 @@ +Subproject commit 0d85bbc3131ce8be23c57e30b213ba6056623976 diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index f89cdc71b6..bb724aa290 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -11,7 +11,17 @@ We are pleased to announce the following Consul updates. ## Release highlights -- TBD +- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). The CRD removes the requirement to deploy a terminating gateway in order to register a service running on an external node in Consul on Kubernetes. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. + +- **Transparent Proxy on Nomad**: Consul’s CNI plugin enables the use of transparent proxy for seamlessly redirecting traffic through the Envoy proxy without requiring application changes, or elevated network privileges for the workload. As a result, you can onboard applications without additional configuration between a service and its upstreams. + +- **API Gateway metrics**: The Consul API Gateway now provides a Prometheus metrics endpoint you can use to gather information about the health of the gateway, as well as traffic for proxied connections or requests. + +- **File system certificate configuration entry**: A new [`file-system-certificate` configuration entry](/consul/docs/connect/config-entries/file-system-certificate) supports specifying a filepath to the certificate and private key for Consul API Gateway on VMs on the local system. Previously, the certificate and private key were specified directly in the `inline-certificate` configuration entry. When using the file system certificates, the Consul server never sees the contents of these files. + + File system certificates also include a file system watch that implements certificate and key changes without restarting the gateway. They also require that you have access to the gateway's file system in order to place the certificate or update it. + + Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates without additional configuration. For more information, refer to [File system certificate configuration reference](/consul/docs/connect/config-entries/file-system-certificate). ## What's deprecated From ed962e8b5e7a3f89c6878cc822ad5d2ac050eb85 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Wed, 12 Jun 2024 08:50:29 -0700 Subject: [PATCH 074/185] docs: External CRD fast follow (#21313) * ESM * TGW note --- website/content/docs/k8s/connect/terminating-gateways.mdx | 2 +- .../docs/k8s/deployment-configurations/external-service.mdx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/website/content/docs/k8s/connect/terminating-gateways.mdx b/website/content/docs/k8s/connect/terminating-gateways.mdx index 78f7813087..1f1b8f9ff4 100644 --- a/website/content/docs/k8s/connect/terminating-gateways.mdx +++ b/website/content/docs/k8s/connect/terminating-gateways.mdx @@ -86,7 +86,7 @@ $ export CONSUL_HTTP_TOKEN=$(kubectl get secret consul-bootstrap-acl-token --tem -Consul on Kubernetes now supports the `Registration` CRD to register services running on external nodes without a terminating gateway. We recommend registering services with this CRD instead of deploying a terminating gateway. For more information, refer to [Register services running on external nodes to Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/external-service). +Consul on Kubernetes now supports the `Registration` CRD to register services running on external nodes with a terminating gateway. We recommend registering services with this CRD. For more information, refer to [Register services running on external nodes to Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/external-service). diff --git a/website/content/docs/k8s/deployment-configurations/external-service.mdx b/website/content/docs/k8s/deployment-configurations/external-service.mdx index 3a55c254af..5bb1448857 100644 --- a/website/content/docs/k8s/deployment-configurations/external-service.mdx +++ b/website/content/docs/k8s/deployment-configurations/external-service.mdx @@ -19,6 +19,7 @@ Previously, the only way to register an external service when running Consul on The process to register an external service in Consul on Kubernetes consists of the following steps: +1. [Start Consul ESM](/consul/tutorials/connect-services/service-registration-external-services#monitor-the-external-service-with-consul-esm). You must use Consul ESM to run health checks on external services. 1. Define the external service and its health checks in a [`Registration` CRD](/consul/docs/connect/config-entries/registration). 1. Apply the CRD to your Kubernetes cluster. Internally, this action triggers an API call to Consul's [`/catalog/register` endpoint](/consul/api-docs/catalog#register-entity) to register the service. 1. When using Consul's service mesh, define [service intentions](/consul/docs/connect/intentions) between the external service and services it communicates with. From e0ef34661393ffdc4e52c245bd65127757b52a25 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Wed, 12 Jun 2024 12:51:38 -0400 Subject: [PATCH 075/185] docs: update changelog.md for 1.19.0 (#21317) --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6834dd84a3..bd5c2584c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,46 @@ +## 1.19.0 (June 12, 2024) + +BREAKING CHANGES: + +* telemetry: State store usage metrics with a double `consul` element in the metric name have been removed. Please use the same metric without the second `consul` instead. As an example instead of `consul.consul.state.config_entries` use `consul.state.config_entries` [[GH-20674](https://github.com/hashicorp/consul/issues/20674)] + +SECURITY: + +* Upgrade to support Envoy `1.27.5 and 1.28.3`. This resolves CVE +[CVE-2024-32475](https://nvd.nist.gov/vuln/detail/CVE-2024-32475) (`auto_sni`). [[GH-21017](https://github.com/hashicorp/consul/issues/21017)] +* Upgrade to support k8s.io/apimachinery `v0.18.7 or higher`. This resolves CVE +[CVE-2020-8559](https://nvd.nist.gov/vuln/detail/CVE-2020-8559). [[GH-21017](https://github.com/hashicorp/consul/issues/21017)] + +FEATURES: + +* dns: queries now default to a refactored DNS server that is v1 and v2 Catalog compatible. +Use `v1dns` in the `experiments` agent config to disable. +The legacy server will be removed in a future release of Consul. +See the [Consul 1.19.x Release Notes](https://developer.hashicorp.com/consul/docs/release-notes/consul/v1_19_x) for removed DNS features. [[GH-20715](https://github.com/hashicorp/consul/issues/20715)] +* gateways: api-gateway can leverage listener TLS certificates available on the gateway's local filesystem by specifying the public certificate and private key path in the new file-system-certificate configuration entry [[GH-20873](https://github.com/hashicorp/consul/issues/20873)] + +IMPROVEMENTS: + +* dns: new version was not supporting partition or namespace being set to 'default' in CE version. [[GH-21230](https://github.com/hashicorp/consul/issues/21230)] +* mesh: update supported envoy version 1.29.4 in addition to 1.28.3, 1.27.5, 1.26.8. [[GH-21142](https://github.com/hashicorp/consul/issues/21142)] +* upgrade go version to v1.22.4. [[GH-21265](https://github.com/hashicorp/consul/issues/21265)] +* Upgrade `github.com/envoyproxy/go-control-plane` to 0.12.0. [[GH-20973](https://github.com/hashicorp/consul/issues/20973)] +* dns: DNS-over-grpc when using `consul-dataplane` now accepts partition, namespace, token as metadata to default those query parameters. +`consul-dataplane` v1.5+ will send this information automatically. [[GH-20899](https://github.com/hashicorp/consul/issues/20899)] +* snapshot: Add `consul snapshot decode` CLI command to output a JSON object stream of all the snapshots data. [[GH-20824](https://github.com/hashicorp/consul/issues/20824)] +* telemetry: Add `telemetry.disable_per_tenancy_usage_metrics` in agent configuration to disable setting tenancy labels on usage metrics. This significantly decreases CPU utilization in clusters with many admin partitions or namespaces. +* telemetry: Improved the performance usage metrics emission by not outputting redundant metrics. [[GH-20674](https://github.com/hashicorp/consul/issues/20674)] + +DEPRECATIONS: + +* snapshot agent: **(Enterprise only)** Top level single snapshot destinations `local_storage`, `aws_storage`, `azure_blob_storage`, and `google_storage` in snapshot agent configuration files are now deprecated. Use the `backup_destinations` config object instead. + +BUG FIXES: + +* docs: Consul DNS Forwarding configuration for OpenShift update for [Resolve Consul DNS Requests in Kubernetes](https://developer.hashicorp.com/consul/docs/k8s/dns) [[GH-20439](https://github.com/hashicorp/consul/issues/20439)] +* hcp: fix error logs when failing to push metrics [[GH-20514](https://github.com/hashicorp/consul/issues/20514)] +* streaming: Handle ACL errors consistently when blocking query timeout is reached. [[GH-20876](https://github.com/hashicorp/consul/issues/20876)] + ## 1.18.2 (May 14, 2024) **Enterprise LTS**: Consul Enterprise 1.18 is a Long-Term Support (LTS) release. From 28c5eaf997f539a10ee48d7f9f415de6b1d9e111 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Wed, 12 Jun 2024 13:29:50 -0400 Subject: [PATCH 076/185] chore: update versions.hcl for 1.19.0 release (#21319) --- .release/versions.hcl | 3 --- 1 file changed, 3 deletions(-) diff --git a/.release/versions.hcl b/.release/versions.hcl index e593948bec..fdc0f2989d 100644 --- a/.release/versions.hcl +++ b/.release/versions.hcl @@ -10,12 +10,9 @@ active_versions { ce_active = true } version "1.18" { - # This release should remain active until 1.19 GA - ce_active = true lts = true } version "1.17" {} - version "1.16" {} version "1.15" { lts = true } From e9c983f36107b044fcd889f738b3d5ba2b922e7a Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:44:35 -0700 Subject: [PATCH 077/185] docs: consul-k8s v1.5.0 release notes (#21320) * consul-k8s 1.5.0 release notes * Nav Entry * Envoy version bumps * Version updates/corrections * external crd description update --- .../content/docs/connect/proxies/envoy.mdx | 2 + .../docs/release-notes/consul-k8s/v1_5_x.mdx | 46 +++++++++++++++++++ .../docs/release-notes/consul/v1_19_x.mdx | 4 +- website/data/docs-nav-data.json | 4 ++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 website/content/docs/release-notes/consul-k8s/v1_5_x.mdx diff --git a/website/content/docs/connect/proxies/envoy.mdx b/website/content/docs/connect/proxies/envoy.mdx index 79eab9e576..0962ccbb29 100644 --- a/website/content/docs/connect/proxies/envoy.mdx +++ b/website/content/docs/connect/proxies/envoy.mdx @@ -119,6 +119,7 @@ until the LTS release reaches its end of maintenance. | Consul Version | Default `consul-dataplane` Version | Other compatible `consul-dataplane` Versions | | -------------- | -------------------------------------|----------------------------------------------| +| 1.19.x Ent | 1.5.x (Envoy 1.29.x) | 1.4.x (Envoy 1.28.x) | | 1.18.x Ent | 1.4.x (Envoy 1.28.x) | 1.3.x (Envoy 1.27.x) | | 1.15.x Ent | 1.1.x (Envoy 1.26.x) | 1.4.x (Envoy 1.28.x) - 1.0.x (Envoy 1.24.x) | @@ -131,6 +132,7 @@ of Consul dataplane use a maintained version of Envoy. | `consul-dataplane` Version Range | Associated Consul Enterprise LTS version | Contained Envoy Binary Version | | -------------------------------- | ---------------------------------------- | ------------------------------ | +| 1.5.0 - 1.5.latest | 1.18.x Ent | Envoy 1.29.x | | 1.4.0 - 1.4.latest | 1.18.x Ent | Envoy 1.28.x | | 1.1.9 - 1.1.latest | 1.15.x Ent | Envoy 1.26.x | | 1.1.0 - 1.1.8 | 1.15.x Ent | Envoy 1.25.x | diff --git a/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx new file mode 100644 index 0000000000..d46bc0bb2f --- /dev/null +++ b/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx @@ -0,0 +1,46 @@ +--- +layout: docs +page_title: 1.5.x +description: >- + Consul on Kubernetes release notes for version 1.5.x +--- + +# Consul on Kubernetes 1.5.0 + +We are pleased to announce the following Consul updates. + +## Release highlights + +- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). The CRD removes the requirement to deploy a terminating gateway in order to register a service running on an external node in Consul on Kubernetes, but a terminating gateway is still required to make the external service available to downstream services in the service mesh. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. + +- **File system certificate**: A new [`file-system-certificate` configuration entry](/consul/docs/connect/config-entries/file-system-certificate) for Consul API Gateway on VMs supports specifying a filepath to the certificate and private key on the local system. Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates instead of inline certificates without additional configuration. For information about certificate configuration for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). + +- **v2 catalog API deprecation**: Consul introduced an experimental v2 Catalog API in v1.17.0. This API supported multi-port Service configurations on Kubernetes, and it was made available for testing and development purposes. The v2 catalog and its support for multiport Kubernetes Services were deprecated in the v1.19.0 release. + +## Supported software + +This version of Consul on Kubernetes supports the following software versions: + +- Consul v1.19.x +- Consul Dataplane v1.5.x. Refer to [Envoy and Consul Dataplane](/consul/docs/v1.19.x/connect/proxies/envoy#envoy-and-consul-dataplane) for details about Consul Dataplane versions and the available packaged Envoy version. +- Kubernetes 1.27.x - 1.30.x +- kubectl 1.27.x - 1.30.x +- Helm 3.11.3+ + +Refer to [Supported Consul and Kubernetes versions](/consul/docs/v1.19.x/k8s/compatibility#supported-consul-and-kubernetes-versions) for more information. + +## Upgrading + +For more detailed information, please refer to the [upgrade details page](/consul/docs/upgrading/upgrade-specific) and the changelogs. + +## Known issues + +The following issues are known to exist in the v1.5.x releases: + +## Changelogs + +The changelogs for this major release version and any maintenance versions are listed below. + + These links take you to the changelogs on the GitHub website. + +- [1.5.0](https://github.com/hashicorp/consul-k8s/releases/tag/v1.5.0) diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index bb724aa290..5423ce0dba 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -11,7 +11,7 @@ We are pleased to announce the following Consul updates. ## Release highlights -- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). The CRD removes the requirement to deploy a terminating gateway in order to register a service running on an external node in Consul on Kubernetes. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. +- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). The CRD removes the requirement to deploy a terminating gateway in order to register a service running on an external node in Consul on Kubernetes, but a terminating gateway is still required to make the external service available to downstream services in the service mesh. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. - **Transparent Proxy on Nomad**: Consul’s CNI plugin enables the use of transparent proxy for seamlessly redirecting traffic through the Envoy proxy without requiring application changes, or elevated network privileges for the workload. As a result, you can onboard applications without additional configuration between a service and its upstreams. @@ -19,7 +19,7 @@ We are pleased to announce the following Consul updates. - **File system certificate configuration entry**: A new [`file-system-certificate` configuration entry](/consul/docs/connect/config-entries/file-system-certificate) supports specifying a filepath to the certificate and private key for Consul API Gateway on VMs on the local system. Previously, the certificate and private key were specified directly in the `inline-certificate` configuration entry. When using the file system certificates, the Consul server never sees the contents of these files. - File system certificates also include a file system watch that implements certificate and key changes without restarting the gateway. They also require that you have access to the gateway's file system in order to place the certificate or update it. + File system certificates also include a file system watch that allows for changing the certificate and key without restarting the gateway. This feature requires that you have access to the gateway’s file system in order to place the certificate or update it. Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates without additional configuration. For more information, refer to [File system certificate configuration reference](/consul/docs/connect/config-entries/file-system-certificate). diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index d5bc1ad83e..6f44bfd983 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -202,6 +202,10 @@ { "title": "Consul K8s", "routes": [ + { + "title": "v1.5.x", + "path": "release-notes/consul-k8s/v1_5_x" + }, { "title": "v1.4.x", "path": "release-notes/consul-k8s/v1_4_x" From 895e7f86f3d6f0560fdf96233184c91d369e9d32 Mon Sep 17 00:00:00 2001 From: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:14:57 -0700 Subject: [PATCH 078/185] docs: v1.19 corrections (#21324) * release notes * Usage pages fixes --- website/content/docs/k8s/connect/terminating-gateways.mdx | 2 +- .../docs/k8s/deployment-configurations/external-service.mdx | 4 +++- website/content/docs/release-notes/consul-k8s/v1_5_x.mdx | 2 +- website/content/docs/release-notes/consul/v1_19_x.mdx | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/website/content/docs/k8s/connect/terminating-gateways.mdx b/website/content/docs/k8s/connect/terminating-gateways.mdx index 1f1b8f9ff4..4cac88da67 100644 --- a/website/content/docs/k8s/connect/terminating-gateways.mdx +++ b/website/content/docs/k8s/connect/terminating-gateways.mdx @@ -102,7 +102,7 @@ Registering the external services with Consul is a multi-step process: You may register an external service with Consul using `ServiceDefaults` if [`TransparentProxy`](/consul/docs/connect/transparent-proxy) is enabled. Otherwise, -you may register the service as a node in the Consul catalog. +you may register the service as a node in the Consul catalog using the [`Registration` CRD](/consul/docs/connect/config-entries/registration). diff --git a/website/content/docs/k8s/deployment-configurations/external-service.mdx b/website/content/docs/k8s/deployment-configurations/external-service.mdx index 5bb1448857..711f016408 100644 --- a/website/content/docs/k8s/deployment-configurations/external-service.mdx +++ b/website/content/docs/k8s/deployment-configurations/external-service.mdx @@ -22,7 +22,9 @@ The process to register an external service in Consul on Kubernetes consists of 1. [Start Consul ESM](/consul/tutorials/connect-services/service-registration-external-services#monitor-the-external-service-with-consul-esm). You must use Consul ESM to run health checks on external services. 1. Define the external service and its health checks in a [`Registration` CRD](/consul/docs/connect/config-entries/registration). 1. Apply the CRD to your Kubernetes cluster. Internally, this action triggers an API call to Consul's [`/catalog/register` endpoint](/consul/api-docs/catalog#register-entity) to register the service. -1. When using Consul's service mesh, define [service intentions](/consul/docs/connect/intentions) between the external service and services it communicates with. +1. When using Consul's service mesh, you should also: + - Deploy a [terminating gateway](/consul/docs/k8s/connect/terminating-gateways) so that downstream services can communicate with the external service. + - Define [service intentions](/consul/docs/connect/intentions) for the external service and the downstream services that communicate with it. ## Guidance diff --git a/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx index d46bc0bb2f..e2010670db 100644 --- a/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx +++ b/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx @@ -11,7 +11,7 @@ We are pleased to announce the following Consul updates. ## Release highlights -- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). The CRD removes the requirement to deploy a terminating gateway in order to register a service running on an external node in Consul on Kubernetes, but a terminating gateway is still required to make the external service available to downstream services in the service mesh. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. +- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). This CRD changes the workflow to register a service running on an external node with the Consul catalog. A terminating gateway is still required to enable downstream services in the service mesh to communicate with external services. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. - **File system certificate**: A new [`file-system-certificate` configuration entry](/consul/docs/connect/config-entries/file-system-certificate) for Consul API Gateway on VMs supports specifying a filepath to the certificate and private key on the local system. Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates instead of inline certificates without additional configuration. For information about certificate configuration for Kubernetes environments, refer to [Gateway Resource Configuration](/consul/docs/connect/gateways/api-gateway/configuration/gateway). diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index 5423ce0dba..e7fb83728e 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -11,7 +11,7 @@ We are pleased to announce the following Consul updates. ## Release highlights -- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). The CRD removes the requirement to deploy a terminating gateway in order to register a service running on an external node in Consul on Kubernetes, but a terminating gateway is still required to make the external service available to downstream services in the service mesh. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. +- **External Services CRD**: You can now configure and register external services, including their health checks, alongside existing Kubernetes application manifests with the new [`Registration` Custom Resource Definition (CRD)](/consul/docs/connect/config-entries/registration). This CRD changes the workflow to register a service running on an external node with the Consul catalog. A terminating gateway is still required to enable downstream services in the service mesh to communicate with external services. Refer to [Register external services on Kubernetes overview](/consul/docs/k8s/deployment-configurations/external-service) for more information. - **Transparent Proxy on Nomad**: Consul’s CNI plugin enables the use of transparent proxy for seamlessly redirecting traffic through the Envoy proxy without requiring application changes, or elevated network privileges for the workload. As a result, you can onboard applications without additional configuration between a service and its upstreams. From 45cb834185ab281e59fbd068bb0878dac09c6d93 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Thu, 13 Jun 2024 15:45:55 -0400 Subject: [PATCH 079/185] docs: k8s updates for the 1.5.0 release (#21329) --- website/content/docs/k8s/compatibility.mdx | 2 +- website/content/docs/k8s/helm.mdx | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/website/content/docs/k8s/compatibility.mdx b/website/content/docs/k8s/compatibility.mdx index eee92512e3..950cd0a2ed 100644 --- a/website/content/docs/k8s/compatibility.mdx +++ b/website/content/docs/k8s/compatibility.mdx @@ -29,9 +29,9 @@ apply to both Consul Enterprise and Consul community edition (CE). | Consul version | Compatible `consul-k8s` versions | Compatible Kubernetes versions | Compatible OpenShift versions | | -------------- | -------------------------------- | -------------------------------| -------------------------------------- | +| 1.19.x | 1.5.x | 1.27.x - 1.29.x | 4.13.x - 4.15.x (4.16.x not available) | | 1.18.x CE | 1.4.x | 1.26.x - 1.29.x | 4.13.x - 4.15.x (4.16.x not available) | | 1.17.x | 1.3.x | 1.25.x - 1.28.x | 4.12.x - 4.15.x | -| 1.16.x | 1.2.x | 1.24.x - 1.27.x | 4.11.x - 4.14.x | #### Enterprise Long Term Support releases diff --git a/website/content/docs/k8s/helm.mdx b/website/content/docs/k8s/helm.mdx index 1890f7eeb0..624dce732b 100644 --- a/website/content/docs/k8s/helm.mdx +++ b/website/content/docs/k8s/helm.mdx @@ -108,6 +108,9 @@ Use these links to navigate to a particular top-level stanza. image that is used for functionality such as catalog sync. This can be overridden per component. + - `imagePullPolicy` ((#v-global-imagepullpolicy)) (`string: ""`) - The image pull policy used globally for images controlled by Consul (consul, consul-dataplane, consul-k8s, consul-telemetry-collector). + One of "IfNotPresent", "Always", "Never", and "". Refer to https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy + - `datacenter` ((#v-global-datacenter)) (`string: dc1`) - The name of the datacenter that the agents should register as. This can't be changed once the Consul cluster is up and running since Consul doesn't support an automatic way to change this value currently: @@ -1784,6 +1787,9 @@ Use these links to navigate to a particular top-level stanza. or may not be broadly accessible depending on your Kubernetes cluster. Set this to false to skip syncing ClusterIP services. + - `syncLoadBalancerEndpoints` ((#v-synccatalog-syncloadbalancerendpoints)) (`boolean: false`) - If true, LoadBalancer service endpoints instead of ingress addresses will be synced to Consul. + If false, LoadBalancer endpoints are not synced to Consul. + - `ingress` ((#v-synccatalog-ingress)) - `enabled` ((#v-synccatalog-ingress-enabled)) (`boolean: false`) - Syncs the hostname from a Kubernetes Ingress resource to service registrations @@ -1954,6 +1960,15 @@ Use these links to navigate to a particular top-level stanza. - external-dns.alpha.kubernetes.io/hostname ``` + - `metrics` ((#v-connectinject-apigateway-managedgatewayclass-metrics)) - Metrics settings for gateways created with this gateway class configuration. + + - `enabled` ((#v-connectinject-apigateway-managedgatewayclass-metrics-enabled)) (`boolean: -`) - This value enables or disables metrics collection on a gateway, overriding the global gateway metrics collection settings. + + - `port` ((#v-connectinject-apigateway-managedgatewayclass-metrics-port)) (`int: null`) - This value sets the port to use for scraping gateway metrics via prometheus, defaults to 20200 if not set. Must be in the port + range of 1024-65535. + + - `path` ((#v-connectinject-apigateway-managedgatewayclass-metrics-path)) (`string: null`) - This value sets the path to use for scraping gateway metrics via prometheus, defaults to /metrics if not set. + - `resources` ((#v-connectinject-apigateway-managedgatewayclass-resources)) (`map`) - The resource settings for Pods handling traffic for Gateway API. - `deployment` ((#v-connectinject-apigateway-managedgatewayclass-deployment)) - This value defines the number of pods to deploy for each Gateway as well as a min and max number of pods for all Gateways @@ -2298,8 +2313,10 @@ Use these links to navigate to a particular top-level stanza. - `consul.hashicorp.com/enable-sidecar-proxy-lifecycle` - `consul.hashicorp.com/enable-sidecar-proxy-shutdown-drain-listeners` - `consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds` + - `consul.hashicorp.com/sidecar-proxy-lifecycle-startup-grace-period-seconds` - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-port` - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-shutdown-path` + - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-startup-path` - `defaultEnabled` ((#v-connectinject-sidecarproxy-lifecycle-defaultenabled)) (`boolean: true`) @@ -2307,10 +2324,14 @@ Use these links to navigate to a particular top-level stanza. - `defaultShutdownGracePeriodSeconds` ((#v-connectinject-sidecarproxy-lifecycle-defaultshutdowngraceperiodseconds)) (`integer: 30`) + - `defaultStartupGracePeriodSeconds` ((#v-connectinject-sidecarproxy-lifecycle-defaultstartupgraceperiodseconds)) (`integer: 0`) + - `defaultGracefulPort` ((#v-connectinject-sidecarproxy-lifecycle-defaultgracefulport)) (`integer: 20600`) - `defaultGracefulShutdownPath` ((#v-connectinject-sidecarproxy-lifecycle-defaultgracefulshutdownpath)) (`string: /graceful_shutdown`) + - `defaultGracefulStartupPath` ((#v-connectinject-sidecarproxy-lifecycle-defaultgracefulstartuppath)) (`string: /graceful_startup`) + - `defaultStartupFailureSeconds` ((#v-connectinject-sidecarproxy-defaultstartupfailureseconds)) (`integer: 0`) - Configures how long the k8s startup probe will wait before the proxy is considered to be unhealthy and the container is restarted. A value of zero disables the probe. From 78715ef7180b077f3cf0bdca189ae99272788ceb Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 13 Jun 2024 16:10:59 -0400 Subject: [PATCH 080/185] docs: simplify Envoy version support docs (#21295) Consistently use `.x` to denote implicit support for Envoy minor versions under a supported major version unless otherwise noted. This will clarify for operators that we support new Envoy minor versions without requiring a docs update on each new release, and will reduce the maintenance burden for these docs going forward. --- website/content/docs/connect/proxies/envoy.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/content/docs/connect/proxies/envoy.mdx b/website/content/docs/connect/proxies/envoy.mdx index 0962ccbb29..2d2436df20 100644 --- a/website/content/docs/connect/proxies/envoy.mdx +++ b/website/content/docs/connect/proxies/envoy.mdx @@ -58,10 +58,10 @@ apply to both Consul Enterprise and Consul community edition (CE). | Consul Version | Compatible Envoy Versions | | -------------- | -------------------------------------- | -| 1.19.x CE | 1.29.4, 1.28.3, 1.27.5, 1.26.8 | -| 1.18.x CE | 1.28.3, 1.27.5, 1.26.8, 1.25.11 | -| 1.17.x | 1.27.5, 1.26.8, 1.25.11, 1.24.12 | -| 1.16.x | 1.26.8, 1.25.11, 1.24.12, 1.23.12 | +| 1.19.x CE | 1.29.x, 1.28.x, 1.27.x, 1.26.x | +| 1.18.x CE | 1.28.x, 1.27.x, 1.26.x, 1.25.x | +| 1.17.x | 1.27.x, 1.26.x, 1.25.x, 1.24.x | +| 1.16.x | 1.26.x, 1.25.x, 1.24.x, 1.23.x | #### Enterprise Long Term Support releases @@ -72,8 +72,8 @@ until the LTS release reaches its end of maintenance. | Consul Version | Compatible Envoy Versions | | -------------- | -----------------------------------------------------------------------------------| -| 1.18.x Ent | 1.29.4, 1.28.3, 1.27.5, 1.26.8, 1.25.11 | -| 1.15.x Ent | 1.29.4, 1.27.5, 1.26.8, 1.25.11, 1.24.12, 1.23.12, 1.22.11 | +| 1.18.x Ent | 1.29.x, 1.28.x, 1.27.x, 1.26.x, 1.25.x | +| 1.15.x Ent | 1.29.x, 1.28.x, 1.27.x, 1.26.x, 1.25.x, 1.24.x, 1.23.x, 1.22.x | ### Envoy and Consul Dataplane From 6302ef31fc60556af4d599dce7b220491dcab302 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 14 Jun 2024 10:47:43 -0400 Subject: [PATCH 081/185] docs: known issue with v2dns SRV requests (#21331) * docs: known issue with v2dns SRV requests * Update website/content/docs/release-notes/consul/v1_19_x.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- website/content/docs/release-notes/consul/v1_19_x.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index e7fb83728e..e78d9a51a7 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -35,6 +35,12 @@ For more detailed information, please refer to the [upgrade details page](/consu The following issues are known to exist in the v1.19.x releases: +- v1.19.0 - DNS SRV records for registrations that specify a service address instead of a node address return identical `.service` hostnames instead of unique `.addr` addresses. + As a result, it is impossible to resolve the individual service addresses. + This bug can affect Nomad installations using Consul for service discovery because the service address field is always specified to Consul. + To revert to the old DNS behavior, set `experiments: [ "v1dns" ]` in the agent configuration. + We plan to include a fix in a future release of Consul v1.19.1 [[GH-21325](https://github.com/hashicorp/consul/issues/21325)]. + ## Changelogs The changelogs for this major release version and any maintenance versions are listed below. From 7a19d2e7a48ffc7a6b16889adad63b121e98d82c Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:03:10 -0400 Subject: [PATCH 082/185] security: fix AliasCheck panic (#21339) * security: fix AliasCheck panic * add changelog --- .changelog/21339.txt | 3 +++ agent/checks/alias.go | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 .changelog/21339.txt diff --git a/.changelog/21339.txt b/.changelog/21339.txt new file mode 100644 index 0000000000..8e8379ada0 --- /dev/null +++ b/.changelog/21339.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: Fix panic runtime error on AliasCheck +``` diff --git a/agent/checks/alias.go b/agent/checks/alias.go index f75c05b958..3b0226b9f4 100644 --- a/agent/checks/alias.go +++ b/agent/checks/alias.go @@ -144,6 +144,9 @@ func (c *CheckAlias) runLocal(stopCh chan struct{}) { type CheckIfServiceIDExists func(*structs.ServiceID) bool func (c *CheckAlias) checkServiceExistsOnRemoteServer(serviceID *structs.ServiceID) (bool, error) { + if serviceID == nil { + return false, fmt.Errorf("serviceID cannot be nil") + } args := c.RPCReq args.Node = c.Node args.AllowStale = true From c18c911ac8ec1ce9b7ba1e5a00cb38201910cf9a Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:54:37 -0500 Subject: [PATCH 083/185] [Security] Close cross scripting vulnerability (#21342) * close vulnerability * add changelog --- .changelog/21342.txt | 3 +++ agent/kvs_endpoint.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .changelog/21342.txt diff --git a/.changelog/21342.txt b/.changelog/21342.txt new file mode 100644 index 0000000000..d2850bc4fd --- /dev/null +++ b/.changelog/21342.txt @@ -0,0 +1,3 @@ +```release-note:security +agent: removed reflected cross-site scripting vulnerability +``` \ No newline at end of file diff --git a/agent/kvs_endpoint.go b/agent/kvs_endpoint.go index e60567cd5b..65ec443078 100644 --- a/agent/kvs_endpoint.go +++ b/agent/kvs_endpoint.go @@ -293,7 +293,7 @@ func conflictingFlags(resp http.ResponseWriter, req *http.Request, flags ...stri if _, ok := params[conflict]; ok { if found { resp.WriteHeader(http.StatusBadRequest) - fmt.Fprint(resp, "Conflicting flags: "+params.Encode()) + fmt.Fprintf(resp, "Conflicting flags: %v\n", params.Encode()) return true } found = true From a16bfc6a3c58224f5ffd7aa6e5361ce8c31a4300 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 18 Jun 2024 15:08:42 -0400 Subject: [PATCH 084/185] ci: skip 1.18 nightly int tests on CE (#21349) This version is no longer active in CE. --- .github/workflows/nightly-test-1.18.x.yaml | 9 +++++++++ .github/workflows/nightly-test-integrations-1.18.x.yml | 10 +++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly-test-1.18.x.yaml b/.github/workflows/nightly-test-1.18.x.yaml index 88790e82b6..ca627b0139 100644 --- a/.github/workflows/nightly-test-1.18.x.yaml +++ b/.github/workflows/nightly-test-1.18.x.yaml @@ -14,8 +14,15 @@ env: GOPRIVATE: github.com/hashicorp # Required for enterprise deps jobs: + check-ent: + runs-on: ubuntu-latest + if: ${{ endsWith(github.repository, '-enterprise') }} + steps: + - run: echo "Building Enterprise" + frontend-test-workspace-node: runs-on: ubuntu-latest + needs: [check-ent] steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: @@ -45,6 +52,7 @@ jobs: frontend-build-ce: runs-on: ubuntu-latest + needs: [check-ent] env: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 @@ -117,6 +125,7 @@ jobs: frontend-build-ent: runs-on: ubuntu-latest + needs: [check-ent] env: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 diff --git a/.github/workflows/nightly-test-integrations-1.18.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml index 4ae1508c7a..9986b54e81 100644 --- a/.github/workflows/nightly-test-integrations-1.18.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -23,8 +23,15 @@ env: BRANCH_NAME: "release-1.18.x" # Used for naming artifacts jobs: + check-ent: + runs-on: ubuntu-latest + if: ${{ endsWith(github.repository, '-enterprise') }} + steps: + - run: echo "Building Enterprise" + setup: runs-on: ubuntu-latest + needs: [check-ent] name: Setup outputs: compute-small: ${{ steps.runners.outputs.compute-small }} @@ -41,6 +48,7 @@ jobs: run: .github/scripts/get_runner_classes.sh get-go-version: + needs: [check-ent] uses: ./.github/workflows/reusable-get-go-version.yml dev-build: @@ -418,7 +426,7 @@ jobs: - upgrade-integration-test - upgrade-integration-test-deployer runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} + if: ${{ always() && endsWith(github.repository, '-enterprise') }} steps: - name: evaluate upstream job results run: | From 830d1bf77f10c418b0ec54bc9a06ca2d974e0b5f Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 18 Jun 2024 15:38:35 -0400 Subject: [PATCH 085/185] ci: fix file parsing in conditional-skip script (#21343) Ensure files are split rather than compared as a single list for accuracy and easier debugging. Also adopt minor changes and file name from introduction of similar check `consul-dataplane` and `consul-k8s` for clarity. --- ...nged_files_go_test.sh => check_skip_ci.sh} | 31 ++++++++++++------- .github/workflows/go-tests.yml | 4 +-- .github/workflows/security-scan.yml | 2 +- .github/workflows/test-integrations.yml | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) rename .github/scripts/{filter_changed_files_go_test.sh => check_skip_ci.sh} (55%) diff --git a/.github/scripts/filter_changed_files_go_test.sh b/.github/scripts/check_skip_ci.sh similarity index 55% rename from .github/scripts/filter_changed_files_go_test.sh rename to .github/scripts/check_skip_ci.sh index bdd0e3f77f..628d8489df 100755 --- a/.github/scripts/filter_changed_files_go_test.sh +++ b/.github/scripts/check_skip_ci.sh @@ -5,7 +5,7 @@ set -euo pipefail # Get the list of changed files -# Using `git merge-base` ensures that we're always comparing against the correct branch point. +# Using `git merge-base` ensures that we're always comparing against the correct branch point. #For example, given the commits: # # A---B---C---D---W---X---Y---Z # origin/main @@ -16,27 +16,34 @@ set -euo pipefail files_to_check=$(git diff --name-only "$(git merge-base origin/$SKIP_CHECK_BRANCH HEAD~)"...HEAD) # Define the directories to check -skipped_directories=("docs/" "ui/" "website/" "grafana/") +skipped_directories=("docs/" "ui/" "website/" "grafana/" ".changelog/") # Loop through the changed files and find directories/files outside the skipped ones -for file_to_check in "${files_to_check[@]}"; do +files_to_check_array=($files_to_check) +for file_to_check in "${files_to_check_array[@]}"; do file_is_skipped=false + echo "checking file: $file_to_check" + + # Allow changes to: + # - This script + # - Files in the skipped directories + # - Markdown files for dir in "${skipped_directories[@]}"; do - if [[ "$file_to_check" == "$dir"* ]] || [[ "$file_to_check" == *.md && "$dir" == *"/" ]]; then + if [[ "$file_to_check" == */check_skip_ci.sh ]] || + [[ "$file_to_check" == "$dir"* ]] || + [[ "$file_to_check" == *.md ]]; then file_is_skipped=true break fi done + if [ "$file_is_skipped" != "true" ]; then - echo -e $file_to_check - SKIP_CI=false - echo "Changes detected in non-documentation files - skip-ci: $SKIP_CI" - echo "skip-ci=$SKIP_CI" >> "$GITHUB_OUTPUT" + echo -e "non-skippable file changed: $file_to_check" + echo "Changes detected in non-documentation files - will not skip tests and build" + echo "skip-ci=false" >> "$GITHUB_OUTPUT" exit 0 ## if file is outside of the skipped_directory exit script fi done -echo -e "$files_to_check" -SKIP_CI=true -echo "Changes detected in only documentation files - skip-ci: $SKIP_CI" -echo "skip-ci=$SKIP_CI" >> "$GITHUB_OUTPUT" \ No newline at end of file +echo "Changes detected in only documentation files - skipping tests and build" +echo "skip-ci=true" >> "$GITHUB_OUTPUT" \ No newline at end of file diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 10ee2325c5..6ea14b4fab 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -38,10 +38,10 @@ jobs: steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: - fetch-depth: 0 + fetch-depth: 0 - name: Get changed files id: read-files - run: ./.github/scripts/filter_changed_files_go_test.sh + run: ./.github/scripts/check_skip_ci.sh setup: needs: [conditional-skip] diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 8c7af7a4f9..427acd02bb 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 - name: Get changed files id: read-files - run: ./.github/scripts/filter_changed_files_go_test.sh + run: ./.github/scripts/check_skip_ci.sh setup: needs: [conditional-skip] diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index cae4e9f591..b106c30a53 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -42,7 +42,7 @@ jobs: fetch-depth: 0 - name: Get changed files id: read-files - run: ./.github/scripts/filter_changed_files_go_test.sh + run: ./.github/scripts/check_skip_ci.sh setup: needs: [conditional-skip] From 596a4cd4c5749adf7ffd3ff75a9b6f80aff999b9 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Mon, 24 Jun 2024 19:32:52 -0400 Subject: [PATCH 086/185] Create documentation for Argo Rollouts Plugin. (#20680) * Create documentation for Argo Rollouts Plugin. * Create documentation for Argo Rollouts Plugin. * Apply suggestions from code review Co-authored-by: David Yu * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update docs based on feedback * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx * Update website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx --------- Co-authored-by: David Yu Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> --- .../argo-rollouts-configuration.mdx | 262 ++++++++++++++++++ website/data/docs-nav-data.json | 4 + 2 files changed, 266 insertions(+) create mode 100644 website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx diff --git a/website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx b/website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx new file mode 100644 index 0000000000..5bd2a1e44d --- /dev/null +++ b/website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx @@ -0,0 +1,262 @@ +--- +layout: docs +page_title: Argo Rollouts Progressive Delivery with Consul on Kubernetes +description: >- + Configure the Argo Rollouts Controller to enable Canary deployments for subset-based routing. Learn how k8s Rollouts integrate with Consul's service mesh. +--- + +# Argo Rollouts Progressive Delivery with Consul on Kubernetes + +This page describes the process to configure and use the [Argo Rollouts Controller](https://argo-rollouts.readthedocs.io/en/stable/) with Consul on Kubernetes to manage advanced subset-based routing for Canary deployments. + +Consul's support for Argo Rollouts is currently limited to subset-based routing. + +## Install Argo Rollouts Controller + +There are three methods for installing the Argo Rollouts Controller with Consul on Kubernetes: + +1. [Install Rollouts Using Helm and init containers](#install-rollouts-using-helm-and-binary). We recommend installing the Argo Rollouts Controllor using this method. +1. [Install Rollouts Using Helm and binary](#install-rollouts-using-helm-and-binary) +1. [Standalone installation](#stand-alone-installation) + +After installing the controller, you must [apply the RBAC CRD](https://raw.githubusercontent.com/argoproj-labs/rollouts-plugin-trafficrouter-consul/main/yaml/rbac.yaml) to your Kubernetes cluster. + +### Install Rollouts Using Helm and init containers + +We recommend using this method to install this plugin. + +Add the following code to your `values.yaml` file to configure the plugin: + +```yaml +controller: + initContainers: + - name: copy-consul-plugin + image: hashicorp/rollouts-plugin-trafficrouter-consul + command: ["/bin/sh", "-c"] + args: + # Copy the binary from the image to the rollout container + - cp /bin/rollouts-plugin-trafficrouter-consul /plugin-bin/hashicorp + volumeMounts: + - name: consul-plugin + mountPath: /plugin-bin/hashicorp + trafficRouterPlugins: + trafficRouterPlugins: |- + - name: "hashicorp/consul" + location: "file:///plugin-bin/hashicorp/rollouts-plugin-trafficrouter-consul" + volumes: + - name: consul-plugin + emptyDir: {} + volumeMounts: + - name: consul-plugin + mountPath: /plugin-bin/hashicorp +``` + +Then install the `argo-rollouts` and apply your updated values using Helm: + +```shell-session +$ helm install argo-rollouts argo/argo-rollouts -f values.yaml -n argo-rollouts +``` + +### Install Rollouts Using Helm and binary + +To build the binary and install Rollouts, complete the following steps: + +1. Build this plugin using your preferred tool. For example, `make build`. +1. Mount the built plugin onto the `argo-rollouts` container. +1. Add the following code to your `values.yaml` file to configure the plugin: + +```yaml +controller: + trafficRouterPlugins: + trafficRouterPlugins: |- + - name: "argoproj-labs/consul" + location: "file:///plugin-bin/hashicorp/rollouts-plugin-trafficrouter-consul" + volumes: + - name: consul-route-plugin + hostPath: + # The path being mounted to, change this depending on your mount path + path: /rollouts-plugin-trafficrouter-consul + type: DirectoryOrCreate + volumeMounts: + - name: consul-route-plugin + mountPath: /plugin-bin/hashicorp +``` + +Then install the `argo-rollouts` and apply your updated values using Helm: + +```shell-session + $ helm install argo-rollouts argo/argo-rollouts -f values.yaml -n argo-rollouts +``` + +### Stand-alone installation + +This section describes the process to create a stand-alone installation. These instructions are for illustrative purposes. We recommend using init containers to create and install this plugin. + +To create a stand-alone installation of the Rollouts plugin, complete the following steps: + +1. Build this plugin. +1. Put the plugin on the path and mount it to the `argo-rollouts`container. +1. Create a `ConfigMap` to configure `argo-rollouts` with the plugin's location. + +The following example schedules a Deployment and mounts it to the `argo-rollouts` container: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argo-rollouts + namespace: argo-rollouts +spec: + selector: + matchLabels: + app.kubernetes.io/name: argo-rollouts + template: + spec: + # ... + volumes: + # ... + - name: consul-plugin + hostPath: + path: /plugin-bin/hashicorp/rollouts-plugin-trafficrouter-consul + type: DirectoryOrCreate + containers: + - name: argo-rollouts + # ... + volumeMounts: + - name: consul-route-plugin + mountPath: /plugin-bin/hashicorp + +``` + +The following example creates the `ConfigMap` with the location of the plugin: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argo-rollouts-config + namespace: argo-rollouts +data: + trafficRouterPlugins: |- + - name: "argoproj-labs/consul" + location: "file:///plugin-bin/hashicorp/rollouts-plugin-trafficrouter-consul" +binaryData: {} +``` + +### Install the RBAC + +After either mounting the binary or using an init container, configure an RBAC using [Argo Rollout Consul plugin `rbac.yaml`](https://raw.githubusercontent.com/argoproj-labs/rollouts-plugin-trafficrouter-consul/main/yaml/rbac.yaml): + +```shell-session +$ kubectl apply -f https://raw.githubusercontent.com/argoproj-labs/rollouts-plugin-trafficrouter-consul/main/yaml/rbac.yaml +``` + +## Use the Argo Rollouts Consul plugin + +Schedule the Kubernetes Service utilized by the service being rolled out. Additionally, configure any service defaults and proxy defaults required for the service. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: test-service +spec: + selector: + app: test-service + ports: + - name: http + port: 80 + targetPort: 8080 +``` + +Next, create the service resolver and service splitter CRDs for your stable service. Argo automatically modifies these CRDs during canary deployments. + +The following example demonstrates the configuration of the service resolver CRD, which creates service subsets and sets the stable subset as the default: + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceResolver +metadata: + name: test-service +spec: + subsets: + stable: + filter: Service.Meta.version == 1 + canary: + filter: "" + defaultSubset: stable +``` + +The following example demonstrates the configuration of the service splitter CRD, which initially sends 100% of traffic to the stable deployment: + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceSplitter +metadata: + name: test-service +spec: + splits: + - weight: 100 + serviceSubset: stable + - weight: 0 + serviceSubset: canary +``` + +Then configure your Argo Rollout resource to incrementally rollout the canary deployment: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: test-service +spec: + replicas: 3 + selector: + matchLabels: + app: test-service + template: + metadata: + labels: + app: test-service + annotations: + consul.hashicorp.com/connect-inject: "true" + consul.hashicorp.com/service-meta-version: "1" + consul.hashicorp.com/service-tags: "v1" + spec: + containers: + - name: test-service + # Using alpine vs latest as there is a build issue with M1s. Also other tests in multiport-app reference + # alpine so standardizing this. + image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine + args: + - -text="I am v1" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + serviceAccountName: test-service + terminationGracePeriodSeconds: 0 # so deletion is quick + strategy: + canary: + trafficRouting: + plugins: + hashicorp/consul: + stableSubsetName: stable # subset name of the stable service + canarySubsetName: canary # subset name of the canary service + serviceName: test-service + steps: + - setWeight: 20 + - pause: {} + - setWeight: 40 + - pause: {duration: 10} + - setWeight: 60 + - pause: {duration: 10} + - setWeight: 80 + - pause: {duration: 10} +``` + +Finally, perform the Rollout operation using the Argo Rollouts Kubectl plugin. + +```shell-session +$ kubectl argo rollouts promote test-service +``` diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 6f44bfd983..38126b547e 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -1381,6 +1381,10 @@ "title": "Consul Enterprise", "path": "k8s/deployment-configurations/consul-enterprise" }, + { + "title": "Argo Rollouts Progressive Delivery", + "path": "k8s/deployment-configurations/argo-rollouts-configuration" + }, { "title": "Multi-Cluster Federation", "routes": [ From a04cc5aeaefcd58e5dd12c7f52d5ada123dcf59c Mon Sep 17 00:00:00 2001 From: David Yu Date: Tue, 25 Jun 2024 09:12:33 -0700 Subject: [PATCH 087/185] docs: Add argo rollouts to 1.19.x release notes (#21363) * Update v1_19_x.mdx * Update website/content/docs/release-notes/consul/v1_19_x.mdx * Update v1_5_x.mdx --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- website/content/docs/release-notes/consul-k8s/v1_5_x.mdx | 2 ++ website/content/docs/release-notes/consul/v1_19_x.mdx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx b/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx index e2010670db..005a21df37 100644 --- a/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx +++ b/website/content/docs/release-notes/consul-k8s/v1_5_x.mdx @@ -17,6 +17,8 @@ We are pleased to announce the following Consul updates. - **v2 catalog API deprecation**: Consul introduced an experimental v2 Catalog API in v1.17.0. This API supported multi-port Service configurations on Kubernetes, and it was made available for testing and development purposes. The v2 catalog and its support for multiport Kubernetes Services were deprecated in the v1.19.0 release. +- **Argo Rollouts Plugin**: A new Argo Rollouts plugin for progressive delivery is now available for `consul-k8s`. This plugin supports canary deployments by allowing you to incrementally release and test new versions of applications and roll back to previous versions by splitting traffic between subsets of services. Refer to [Argo Rollouts Progressive Delivery with Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/argo-rollouts-configuration) for more information. + ## Supported software This version of Consul on Kubernetes supports the following software versions: diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index e78d9a51a7..af7731b131 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -23,6 +23,8 @@ We are pleased to announce the following Consul updates. Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates without additional configuration. For more information, refer to [File system certificate configuration reference](/consul/docs/connect/config-entries/file-system-certificate). +- **Argo Rollouts Plugin**: A new Argo Rollouts plugin for progressive delivery is now available for `consul-k8s`. This plugin supports canary deployments by allowing you to incrementally release and test new versions of applications and roll back to previous versions by splitting traffic between subsets of services. Refer to [Argo Rollouts Progressive Delivery with Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/argo-rollouts-configuration) for more information. + ## What's deprecated - **Snapshot Agent (Enterprise):** Starting with this release, top level single snapshot destinations `local_storage`, `aws_storage`, `azure_blob_storage`, and `google_storage` in snapshot agent configuration files are deprecated. Use the [`backup_destinations`](/consul/commands/snapshot/agent#config-file) config object instead. From a4a3aec567c504c04192f8c76e4e0faec123133d Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Tue, 25 Jun 2024 13:42:25 -0400 Subject: [PATCH 088/185] fix(dns): bug with standard lookup tags not working; SRV questions returning duplicate hostnames (#21361) --- .changelog/21361.txt | 8 + agent/dns/discovery_results_fetcher.go | 44 +++++- agent/dns/discovery_results_fetcher_test.go | 116 ++++++++++++++ agent/dns/message_serializer.go | 33 ++-- agent/dns/router_service_test.go | 73 +++++++++ agent/dns/router_v2_services_test.go | 2 +- agent/dns_service_lookup_test.go | 142 ++++++++++++++++++ .../docs/release-notes/consul/v1_19_x.mdx | 14 +- 8 files changed, 400 insertions(+), 32 deletions(-) create mode 100644 .changelog/21361.txt diff --git a/.changelog/21361.txt b/.changelog/21361.txt new file mode 100644 index 0000000000..5cfa906bcd --- /dev/null +++ b/.changelog/21361.txt @@ -0,0 +1,8 @@ +```release-note:bug +dns: Fix a regression where DNS tags using the standard lookup syntax, `tag.name.service.consul`, were being disregarded. +``` + +```release-note:bug +dns: Fix a regression where DNS SRV questions were returning duplicate hostnames instead of encoded IPs. +This affected Nomad integrations with Consul. +``` \ No newline at end of file diff --git a/agent/dns/discovery_results_fetcher.go b/agent/dns/discovery_results_fetcher.go index f0012b9f77..97b91c12aa 100644 --- a/agent/dns/discovery_results_fetcher.go +++ b/agent/dns/discovery_results_fetcher.go @@ -106,7 +106,10 @@ func buildQueryFromDNSMessage(req *dns.Msg, reqCtx Context, domain, altDomain st return nil, err } - name, tag := getQueryNameAndTagFromParts(queryType, queryParts) + name, tag, err := getQueryNameAndTagFromParts(queryType, queryParts) + if err != nil { + return nil, err + } portName := parsePort(queryParts) @@ -157,14 +160,28 @@ func buildAddressResults(req *dns.Msg) ([]*discovery.Result, error) { } // getQueryNameAndTagFromParts returns the query name and tag from the query parts that are taken from the original dns question. -func getQueryNameAndTagFromParts(queryType discovery.QueryType, queryParts []string) (string, string) { +// +// Valid Query Parts: +// [.] +// [.port.] +// _._ // RFC 2782 style +func getQueryNameAndTagFromParts(queryType discovery.QueryType, queryParts []string) (string, string, error) { n := len(queryParts) if n == 0 { - return "", "" + return "", "", errInvalidQuestion } switch queryType { case discovery.QueryTypeService: + if n > 3 { + // Having this many fields is never valid. + return "", "", errInvalidQuestion + } + if n == 3 && queryParts[n-2] != "port" { + // This probably means that someone was trying to use a tag name with a period. + // This was deprecated in Consul 0.3. + return "", "", errInvalidQuestion + } // Support RFC 2782 style syntax if n == 2 && strings.HasPrefix(queryParts[1], "_") && strings.HasPrefix(queryParts[0], "_") { // Grab the tag since we make nuke it if it's tcp @@ -177,9 +194,14 @@ func getQueryNameAndTagFromParts(queryType discovery.QueryType, queryParts []str name := queryParts[0][1:] // _name._tag.service.consul - return name, tag + return name, tag, nil } - return queryParts[n-1], "" + // Standard-style lookup w/ tag + if n == 2 { + return queryParts[1], queryParts[0], nil + } + // This works for the v1 and v2 catalog queries, even if a port name was specified. + return queryParts[n-1], "", nil case discovery.QueryTypePreparedQuery: name := "" @@ -197,9 +219,17 @@ func getQueryNameAndTagFromParts(queryType discovery.QueryType, queryParts []str // Allow a "." in the query name, just join all the parts. name = strings.Join(queryParts, ".") } - return name, "" + + if name == "" { + return "", "", errInvalidQuestion + } + return name, "", nil } - return queryParts[n-1], "" + name := queryParts[n-1] + if name == "" { + return "", "", errInvalidQuestion + } + return queryParts[n-1], "", nil } // getQueryTenancy returns a discovery.QueryTenancy from a DNS message. diff --git a/agent/dns/discovery_results_fetcher_test.go b/agent/dns/discovery_results_fetcher_test.go index 01792a0646..4c219b5a62 100644 --- a/agent/dns/discovery_results_fetcher_test.go +++ b/agent/dns/discovery_results_fetcher_test.go @@ -19,6 +19,7 @@ type testCaseBuildQueryFromDNSMessage struct { request *dns.Msg requestContext *Context expectedQuery *discovery.Query + expectedError string } // Test_buildQueryFromDNSMessage tests the buildQueryFromDNSMessage function. @@ -123,6 +124,114 @@ func Test_buildQueryFromDNSMessage(t *testing.T) { }, }, }, + // V1 Service Queries + { + name: "test A 'service.' standard query with tag", + request: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Opcode: dns.OpcodeQuery, + }, + Question: []dns.Question{ + { + Name: "primary.db.service.dc1.consul", // "intentionally missing the trailing dot" + Qtype: dns.TypeA, + Qclass: dns.ClassINET, + }, + }, + }, + expectedQuery: &discovery.Query{ + QueryType: discovery.QueryTypeService, + QueryPayload: discovery.QueryPayload{ + Name: "db", + Tag: "primary", + Tenancy: discovery.QueryTenancy{ + Datacenter: "dc1", + }, + }, + }, + }, + { + name: "test A 'service.' RFC 2782 query with tag", + request: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Opcode: dns.OpcodeQuery, + }, + Question: []dns.Question{ + { + Name: "_db._primary.service.dc1.consul", // "intentionally missing the trailing dot" + Qtype: dns.TypeA, + Qclass: dns.ClassINET, + }, + }, + }, + expectedQuery: &discovery.Query{ + QueryType: discovery.QueryTypeService, + QueryPayload: discovery.QueryPayload{ + Name: "db", + Tag: "primary", + Tenancy: discovery.QueryTenancy{ + Datacenter: "dc1", + }, + }, + }, + }, + { + name: "test A 'service.' RFC 2782 query", + request: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Opcode: dns.OpcodeQuery, + }, + Question: []dns.Question{ + { + Name: "_db._tcp.service.dc1.consul", // the `tcp` tag should be ignored + Qtype: dns.TypeA, + Qclass: dns.ClassINET, + }, + }, + }, + expectedQuery: &discovery.Query{ + QueryType: discovery.QueryTypeService, + QueryPayload: discovery.QueryPayload{ + Name: "db", + Tenancy: discovery.QueryTenancy{ + Datacenter: "dc1", + }, + }, + }, + }, + { + name: "test A 'service.' with too many query parts (RFC 2782 style)", + request: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Opcode: dns.OpcodeQuery, + }, + Question: []dns.Question{ + { + Name: "nope._db._tcp.service.dc1.consul", // the `tcp` tag should be ignored + Qtype: dns.TypeA, + Qclass: dns.ClassINET, + }, + }, + }, + expectedError: "invalid question", + }, + { + name: "test A 'service.' with too many query parts (standard style)", + request: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Opcode: dns.OpcodeQuery, + }, + Question: []dns.Question{ + { + Name: "too.many.parts.service.dc1.consul.", + Qtype: dns.TypeA, + Qclass: dns.ClassINET, + }, + }, + }, + expectedError: "invalid question", + }, + // V2 Catalog Queries { name: "test A 'workload.'", request: &dns.Msg{ @@ -213,6 +322,13 @@ func Test_buildQueryFromDNSMessage(t *testing.T) { context = &Context{} } query, err := buildQueryFromDNSMessage(tc.request, *context, "consul.", ".", nil) + + if tc.expectedError != "" { + require.Error(t, err) + assert.Contains(t, err.Error(), tc.expectedError) + return + } + require.NoError(t, err) assert.Equal(t, tc.expectedQuery, query) }) diff --git a/agent/dns/message_serializer.go b/agent/dns/message_serializer.go index 2369b28319..15e301fc8b 100644 --- a/agent/dns/message_serializer.go +++ b/agent/dns/message_serializer.go @@ -235,11 +235,7 @@ func (d messageSerializer) getAnswerExtraAndNs(opts *getAnswerExtraAndNsOptions) ns = append(ns, opts.dnsRecordMaker.makeNS(opts.responseDomain, fqdn, opts.ttl)) extra = append(extra, extraRecord) case qType == dns.TypeSRV: - // We put A/AAAA/CNAME records in the additional section for SRV requests - a, e := d.getAnswerExtrasForAddressAndTarget(nodeAddress, serviceAddress, opts) - answer = append(answer, a...) - extra = append(extra, e...) - + fallthrough default: a, e := d.getAnswerExtrasForAddressAndTarget(nodeAddress, serviceAddress, opts) answer = append(answer, a...) @@ -291,16 +287,14 @@ func (d messageSerializer) getAnswerExtrasForAddressAndTarget(nodeAddress *dnsAd switch { case (reqType == requestTypeAddress || opts.result.Type == discovery.ResultTypeVirtual) && serviceAddress.IsEmptyString() && nodeAddress.IsIP(): - a, e := getAnswerExtrasForIP(qName, nodeAddress, opts.req.Question[0], - reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker) + a, e := getAnswerExtrasForIP(qName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) answer = append(answer, a...) extra = append(extra, e...) case opts.result.Type == discovery.ResultTypeNode && nodeAddress.IsIP(): canonicalNodeName := canonicalNameForResult(opts.result.Type, opts.result.Node.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, - opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker) + a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) answer = append(answer, a...) extra = append(extra, e...) @@ -320,8 +314,7 @@ func (d messageSerializer) getAnswerExtrasForAddressAndTarget(nodeAddress *dnsAd } canonicalNodeName := canonicalNameForResult(resultType, opts.result.Node.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], - reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker) + a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, nodeAddress.String() == opts.result.Node.Address) // We compare the node address to the result to detect changes from the WAN translation answer = append(answer, a...) extra = append(extra, e...) @@ -331,12 +324,16 @@ func (d messageSerializer) getAnswerExtrasForAddressAndTarget(nodeAddress *dnsAd answer = append(answer, a...) extra = append(extra, e...) + case serviceAddress.IsIP() && opts.req.Question[0].Qtype == dns.TypeSRV: + a, e := getAnswerExtrasForIP(qName, serviceAddress, opts.req.Question[0], requestTypeName, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) + answer = append(answer, a...) + extra = append(extra, e...) + // The service address is an IP case serviceAddress.IsIP(): canonicalServiceName := canonicalNameForResult(discovery.ResultTypeService, opts.result.Service.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalServiceName, serviceAddress, - opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker) + a, e := getAnswerExtrasForIP(canonicalServiceName, serviceAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) answer = append(answer, a...) extra = append(extra, e...) @@ -345,8 +342,7 @@ func (d messageSerializer) getAnswerExtrasForAddressAndTarget(nodeAddress *dnsAd case serviceAddress.FQDN() == opts.req.Question[0].Name && nodeAddress.IsIP(): canonicalNodeName := canonicalNameForResult(discovery.ResultTypeNode, opts.result.Node.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], - reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker) + a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, nodeAddress.String() == opts.result.Node.Address) // We compare the node address to the result to detect changes from the WAN translation answer = append(answer, a...) extra = append(extra, e...) @@ -463,9 +459,7 @@ func shouldAppendTXTRecord(query *discovery.Query, cfg *RouterDynamicConfig, req } // getAnswerExtrasForIP creates the dns answer and extra from IP dnsAddress pairs. -func getAnswerExtrasForIP(name string, addr *dnsAddress, question dns.Question, - reqType requestType, result *discovery.Result, ttl uint32, domain string, - port *discovery.Port, maker dnsRecordMaker) (answer []dns.RR, extra []dns.RR) { +func getAnswerExtrasForIP(name string, addr *dnsAddress, question dns.Question, reqType requestType, result *discovery.Result, ttl uint32, domain string, port *discovery.Port, maker dnsRecordMaker, addressOverridden bool) (answer []dns.RR, extra []dns.RR) { qType := question.Qtype canReturnARecord := qType == dns.TypeSRV || qType == dns.TypeA || qType == dns.TypeANY || qType == dns.TypeNS || qType == dns.TypeTXT canReturnAAAARecord := qType == dns.TypeSRV || qType == dns.TypeAAAA || qType == dns.TypeANY || qType == dns.TypeNS || qType == dns.TypeTXT @@ -493,7 +487,8 @@ func getAnswerExtrasForIP(name string, addr *dnsAddress, question dns.Question, } if reqType != requestTypeAddress && qType == dns.TypeSRV { - if result.Type == discovery.ResultTypeService && addr.IsIP() && result.Node.Address != addr.String() { + + if addr.IsIP() && question.Name == name && !addressOverridden { // encode the ip to be used in the header of the A/AAAA record // as well as the target of the SRV record. recHdrName = encodeIPAsFqdn(result, addr.IP(), domain) diff --git a/agent/dns/router_service_test.go b/agent/dns/router_service_test.go index cf78f8687a..0738d376e1 100644 --- a/agent/dns/router_service_test.go +++ b/agent/dns/router_service_test.go @@ -158,6 +158,79 @@ func Test_HandleRequest_ServiceQuestions(t *testing.T) { }, }, }, + { + name: "req type: service / question type: SRV / CNAME required: no - multiple results without Node address + tags", + request: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Opcode: dns.OpcodeQuery, + }, + Question: []dns.Question{ + { + Name: "tag.foo.service.consul.", + Qtype: dns.TypeSRV, + }, + }, + }, + configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { + fetcher.(*discovery.MockCatalogDataFetcher). + On("FetchEndpoints", mock.Anything, + &discovery.QueryPayload{ + Name: "foo", + Tenancy: discovery.QueryTenancy{}, + Tag: "tag", + }, discovery.LookupTypeService). + Return([]*discovery.Result{ + { + // This result emulates an allocation registration with Nomad. + // The node name is generated by Consul and shares the service IP + Type: discovery.ResultTypeService, + Service: &discovery.Location{Name: "foo", Address: "127.0.0.1"}, + Node: &discovery.Location{Name: "Node-9e46a487-f5be-2f40-ad60-5a10e32237ed", Address: "127.0.0.1"}, + Tenancy: discovery.ResultTenancy{ + Datacenter: "dc1", + }, + }, + }, + nil).On("ValidateRequest", mock.Anything, + mock.Anything).Return(nil).On("NormalizeRequest", mock.Anything) + }, + response: &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Response: true, + Authoritative: true, + }, + Compress: true, + Question: []dns.Question{ + { + Name: "tag.foo.service.consul.", + Qtype: dns.TypeSRV, + }, + }, + Answer: []dns.RR{ + &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "tag.foo.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + Ttl: 123, + }, + Target: "7f000001.addr.dc1.consul.", + Priority: 1, + }, + }, + Extra: []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{ + Name: "7f000001.addr.dc1.consul.", + Rrtype: dns.TypeA, + Class: dns.ClassINET, + Ttl: 123, + }, + A: net.ParseIP("127.0.0.1"), + }, + }, + }, + }, } for _, tc := range testCases { diff --git a/agent/dns/router_v2_services_test.go b/agent/dns/router_v2_services_test.go index 45cb98b615..7b7b84f32a 100644 --- a/agent/dns/router_v2_services_test.go +++ b/agent/dns/router_v2_services_test.go @@ -462,7 +462,7 @@ func Test_HandleRequest_V2Services(t *testing.T) { }, }, { - name: "SRV Query with a multi-port service that has workloads w/ hostnames (no recursor)", + name: "SRV Query with a multi-port service that has workloads w/ hostnames (with recursor)", request: &dns.Msg{ MsgHdr: dns.MsgHdr{ Opcode: dns.OpcodeQuery, diff --git a/agent/dns_service_lookup_test.go b/agent/dns_service_lookup_test.go index 7905100aa6..dcad04696d 100644 --- a/agent/dns_service_lookup_test.go +++ b/agent/dns_service_lookup_test.go @@ -381,6 +381,105 @@ func TestDNS_ServiceLookup(t *testing.T) { } } +// TestDNS_ServiceAddressWithTagLookup tests some specific cases that Nomad would exercise, +// Like registering a service w/o a Node. https://github.com/hashicorp/nomad/blob/1174019676ff3d65b39323eb0c7234fb1e09b80c/command/agent/consul/service_client.go#L1366-L1381 +// Errors with this were reported in https://github.com/hashicorp/consul/issues/21325#issuecomment-2166845574 +// Also we test that only one tag is valid in the URL. +func TestDNS_ServiceAddressWithTagLookup(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + for name, experimentsHCL := range getVersionHCL(true) { + t.Run(name, func(t *testing.T) { + a := NewTestAgent(t, experimentsHCL) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + { + // This emulates a Nomad service registration. + // Using an internal RPC for Catalog.Register will not trigger the same condition. + err := a.Client().Agent().ServiceRegister(&api.AgentServiceRegistration{ + Kind: api.ServiceKindTypical, + ID: "db-1", + Name: "db", + Tags: []string{"primary"}, + Address: "127.0.0.1", + Port: 12345, + Checks: make([]*api.AgentServiceCheck, 0), + }) + require.NoError(t, err) + } + + { + err := a.Client().Agent().ServiceRegister(&api.AgentServiceRegistration{ + Kind: api.ServiceKindTypical, + ID: "db-2", + Name: "db", + Tags: []string{"secondary"}, + Address: "127.0.0.2", // The address here has to be different, or the DNS server will dedupe it. + Port: 12345, + Checks: make([]*api.AgentServiceCheck, 0), + }) + require.NoError(t, err) + } + + // Query the service using a tag - this also checks that we're filtering correctly + questions := []string{ + "_db._primary.service.dc1.consul.", // w/ RFC 2782 style syntax + "primary.db.service.dc1.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 1, "Expected only one result in the Answer section") + + srvRec, ok := in.Answer[0].(*dns.SRV) + require.True(t, ok, "Expected an SRV record in the Answer section") + require.Equal(t, uint16(12345), srvRec.Port) + require.Equal(t, "7f000001.addr.dc1.consul.", srvRec.Target) + + aRec, ok := in.Extra[0].(*dns.A) + require.True(t, ok, "Expected an A record in the Extra section") + require.Equal(t, "7f000001.addr.dc1.consul.", aRec.Hdr.Name) + require.Equal(t, "127.0.0.1", aRec.A.String()) + + if strings.Contains(question, "query") { + // The query should have the TTL associated with the query registration. + require.Equal(t, uint32(3), srvRec.Hdr.Ttl) + require.Equal(t, uint32(3), aRec.Hdr.Ttl) + } else { + require.Equal(t, uint32(0), srvRec.Hdr.Ttl) + require.Equal(t, uint32(0), aRec.Hdr.Ttl) + } + } + + // Multiple tags are not supported in the legacy DNS server + questions = []string{ + "banana._db._primary.service.dc1.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 0, "Expected no results in the Answer section") + + // For v1dns, we combine the tags with a period, which results in NXDOMAIN + // For v2dns, we are also return NXDomain + // The reported issue says that v2dns this is returning valid results. + require.Equal(t, dns.RcodeNameError, in.Rcode) + } + }) + } +} + func TestDNS_ServiceLookupWithInternalServiceAddress(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") @@ -1839,6 +1938,49 @@ func TestDNS_ServiceLookup_TagPeriod(t *testing.T) { } } +// TestDNS_ServiceLookup_ExtraTags tests tag behavior. +// With v1dns, we still support period tags, but if a tag is not found it's an NXDOMAIN code. +// With v2dns, we do not support period tags, so it's an NXDOMAIN code because the name is not valid. +func TestDNS_ServiceLookup_ExtraTags(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + for name, experimentsHCL := range getVersionHCL(true) { + t.Run(name, func(t *testing.T) { + a := NewTestAgent(t, experimentsHCL) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m1 := new(dns.Msg) + m1.SetQuestion("dummy.primary.db.service.consul.", dns.TypeSRV) + + c1 := new(dns.Client) + in, _, err := c1.Exchange(m1, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 0, "Expected no answer") + require.Equal(t, dns.RcodeNameError, in.Rcode) + }) + } +} + func TestDNS_ServiceLookup_PreparedQueryNamePeriod(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index af7731b131..5c8851112a 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -37,11 +37,15 @@ For more detailed information, please refer to the [upgrade details page](/consu The following issues are known to exist in the v1.19.x releases: -- v1.19.0 - DNS SRV records for registrations that specify a service address instead of a node address return identical `.service` hostnames instead of unique `.addr` addresses. - As a result, it is impossible to resolve the individual service addresses. - This bug can affect Nomad installations using Consul for service discovery because the service address field is always specified to Consul. - To revert to the old DNS behavior, set `experiments: [ "v1dns" ]` in the agent configuration. - We plan to include a fix in a future release of Consul v1.19.1 [[GH-21325](https://github.com/hashicorp/consul/issues/21325)]. +- v1.19.0 - There are known issues with the new DNS server implementation. +To revert to the old DNS behavior, set `experiments: [ "v1dns" ]` in the agent configuration. +Fixes will be included in Consul v1.19.1. + - DNS SRV records for registrations that specify a service address instead of a node address return identical `.service` hostnames instead of unique `.addr` addresses. + As a result, it is impossible to resolve the individual service addresses. + This bug can affect Nomad installations using Consul for service discovery because the service address field is always specified to Consul. + [[GH-21325](https://github.com/hashicorp/consul/issues/21325)]. + - DNS Tags are not resolved when using the Standard query format, `tag.name.service.consul`. + [[GH-21326](https://github.com/hashicorp/consul/issues/21336)]. ## Changelogs From cec66f07431191f8ddab5b74de15db36b34c9055 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Wed, 26 Jun 2024 12:13:57 -0400 Subject: [PATCH 089/185] build: cross compile darwin builds (#21326) --- .github/workflows/build.yml | 80 +------------------------------------ 1 file changed, 2 insertions(+), 78 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a80b57a59..78481f2a20 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,6 +95,8 @@ jobs: - {goos: "linux", goarch: "amd64"} - {goos: "linux", goarch: "arm"} - {goos: "linux", goarch: "arm64"} + - {goos: "darwin", goarch: "amd64"} + - {goos: "darwin", goarch: "arm64"} - {goos: "freebsd", goarch: "386"} - {goos: "freebsd", goarch: "amd64"} - {goos: "windows", goarch: "386"} @@ -246,58 +248,6 @@ jobs: cp LICENSE $TARGET_DIR/LICENSE.txt go build -ldflags="$GOLDFLAGS" -o "$BIN_PATH" -trimpath -buildvcs=false - build-darwin: - needs: - - set-product-version - - get-go-version - runs-on: macos-latest - strategy: - matrix: - goos: [ darwin ] - goarch: [ "amd64", "arm64" ] - fail-fast: true - - name: Go ${{ needs.get-go-version.outputs.go-version }} ${{ matrix.goos }} ${{ matrix.goarch }} build - steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - - name: Setup with node and yarn - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 - with: - node-version: '18' - cache: 'yarn' - cache-dependency-path: 'ui/yarn.lock' - - - name: Build UI - run: | - CONSUL_VERSION=${{ needs.set-product-version.outputs.product-version }} - CONSUL_BINARY_TYPE=${CONSUL_BINARY_TYPE} - CONSUL_COPYRIGHT_YEAR=$(git show -s --format=%cd --date=format:%Y HEAD) - echo "consul_version is ${CONSUL_VERSION}" - echo "consul binary type is ${CONSUL_BINARY_TYPE}" - echo "consul copyright year is ${CONSUL_COPYRIGHT_YEAR}" - cd ui && make && cd .. - rm -rf agent/uiserver/dist - mv ui/packages/consul-ui/dist agent/uiserver/ - - name: Go Build - env: - PRODUCT_VERSION: ${{ needs.set-product-version.outputs.product-version }} - PRERELEASE_VERSION: ${{ needs.set-product-version.outputs.pre-version }} - CGO_ENABLED: "0" - GOLDFLAGS: "${{needs.set-product-version.outputs.shared-ldflags}}" - uses: hashicorp/actions-go-build@make-clean-flag-optional - with: - product_name: ${{ env.PKG_NAME }} - product_version: ${{ needs.set-product-version.outputs.product-version }} - go_version: ${{ needs.get-go-version.outputs.go-version }} - os: ${{ matrix.goos }} - arch: ${{ matrix.goarch }} - reproducible: nope - clean: false - instructions: |- - cp LICENSE $TARGET_DIR/LICENSE.txt - go build -ldflags="$GOLDFLAGS" -tags netcgo -o "$BIN_PATH" -trimpath -buildvcs=false - build-docker: name: Docker ${{ matrix.arch }} build needs: @@ -420,32 +370,6 @@ jobs: if: ${{ endsWith(github.repository, '-enterprise') || matrix.arch != 's390x' }} run: .github/scripts/verify_artifact.sh ${{ env.zip_name }} v${{ env.version }} - verify-darwin: - needs: - - set-product-version - - build-darwin - runs-on: macos-latest - strategy: - fail-fast: true - env: - version: ${{needs.set-product-version.outputs.product-version}} - zip_name: consul_${{ needs.set-product-version.outputs.product-version }}_darwin_amd64.zip - - name: Verify amd64 darwin binary - steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - - - name: Download amd64 darwin zip - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 - with: - name: ${{ env.zip_name }} - - - name: Unzip amd64 darwin zip - run: unzip ${{ env.zip_name }} - - - name: Run verification for amd64 darwin binary - run: .github/scripts/verify_bin.sh ./consul v${{ env.version }} - verify-linux-packages-deb: needs: - build From 6f31bfebbe5230d19b35a074fb92384a2004344a Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:12:13 -0500 Subject: [PATCH 090/185] Update retryable-http-client to resolve CVE-2024-6104 (#21384) * update retryable-http-client * changelog --- .changelog/21384.txt | 3 +++ go.mod | 6 +++--- go.sum | 11 ++++++----- test-integ/go.mod | 4 ++-- test-integ/go.sum | 8 ++++---- test/integration/consul-container/go.mod | 4 ++-- test/integration/consul-container/go.sum | 8 ++++---- 7 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 .changelog/21384.txt diff --git a/.changelog/21384.txt b/.changelog/21384.txt new file mode 100644 index 0000000000..c5ba2347e5 --- /dev/null +++ b/.changelog/21384.txt @@ -0,0 +1,3 @@ +```release-note:security +Upgrade go-retryablehttp to address [CVE-2024-6104](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-6104) +``` \ No newline at end of file diff --git a/go.mod b/go.mod index bd1a87799a..40dfce90cc 100644 --- a/go.mod +++ b/go.mod @@ -53,13 +53,13 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-connlimit v0.3.0 github.com/hashicorp/go-discover v0.0.0-20230724184603-e89ebd1b2f65 - github.com/hashicorp/go-hclog v1.5.0 + github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-immutable-radix v1.3.1 github.com/hashicorp/go-immutable-radix/v2 v2.1.0 github.com/hashicorp/go-memdb v1.3.4 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-retryablehttp v0.7.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 @@ -120,7 +120,7 @@ require ( golang.org/x/net v0.24.0 golang.org/x/oauth2 v0.15.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.19.0 + golang.org/x/sys v0.20.0 golang.org/x/time v0.3.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 google.golang.org/grpc v1.58.3 diff --git a/go.sum b/go.sum index 6ef73b225c..886a25dcf5 100644 --- a/go.sum +++ b/go.sum @@ -423,8 +423,9 @@ github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj 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-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= @@ -448,8 +449,8 @@ github.com/hashicorp/go-raftchunking v0.7.0 h1:APNMnCXmTOhumkFv/GpJIbq7HteWF7EnG 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-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= 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= @@ -1118,8 +1119,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= diff --git a/test-integ/go.mod b/test-integ/go.mod index df821c307a..4e06d2f16f 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -52,7 +52,7 @@ require ( github.com/hashicorp/consul v1.16.1 // indirect github.com/hashicorp/consul-server-connection-manager v0.1.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -100,7 +100,7 @@ require ( golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/sys v0.19.0 // indirect + golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect diff --git a/test-integ/go.sum b/test-integ/go.sum index b2d37902b9..5428aef74d 100644 --- a/test-integ/go.sum +++ b/test-integ/go.sum @@ -106,8 +106,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv 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-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -368,8 +368,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index b3fbbe068c..e4671b8cd9 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -61,7 +61,7 @@ require ( github.com/google/uuid v1.4.0 // indirect github.com/hashicorp/consul-server-connection-manager v0.1.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/go-netaddrs v0.1.0 // indirect @@ -95,7 +95,7 @@ require ( golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/net v0.24.0 // indirect - golang.org/x/sys v0.19.0 // indirect + golang.org/x/sys v0.20.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index 450c6765da..28082f92c6 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -115,8 +115,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv 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-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -376,8 +376,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= From 88bade6cc0a735cf26c82c871762032e044b2a74 Mon Sep 17 00:00:00 2001 From: Kiran Naidoo Date: Wed, 3 Jul 2024 15:48:08 +0100 Subject: [PATCH 091/185] security: fix AliasCheck panic (update) (#21510) Updated `checkServiceExistsOnRemoteServer` to ensure there are services returned from the specified node before proceeding with the service matcher. --- agent/checks/alias.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/agent/checks/alias.go b/agent/checks/alias.go index 3b0226b9f4..200176364e 100644 --- a/agent/checks/alias.go +++ b/agent/checks/alias.go @@ -164,6 +164,12 @@ RETRY_CALL: } return false, err } + + // Do not proceed for nil returned services. + if out.NodeServices == nil { + return false, fmt.Errorf("no services found on node") + } + for _, srv := range out.NodeServices.Services { if serviceID.Matches(srv.CompoundServiceID()) { return true, nil From f3649e16a7875e90b7ece8259bf6e4a343019a94 Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Wed, 3 Jul 2024 12:47:20 -0500 Subject: [PATCH 092/185] NET-10288-Bump-go-to-resolve-CVE-2024-24791 (#21507) * bump go version * changelog * Update .changelog/21507.txt * Update go.mod Co-authored-by: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> * go mod tidy --------- Co-authored-by: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> --- .changelog/21507.txt | 3 +++ .go-version | 2 +- go.mod | 4 ++-- go.sum | 12 ++++++++++++ test-integ/go.mod | 4 +++- test-integ/go.sum | 16 ++++++++++++++++ test/integration/consul-container/go.mod | 4 +++- test/integration/consul-container/go.sum | 14 ++++++++++++++ 8 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 .changelog/21507.txt diff --git a/.changelog/21507.txt b/.changelog/21507.txt new file mode 100644 index 0000000000..e06736fdbc --- /dev/null +++ b/.changelog/21507.txt @@ -0,0 +1,3 @@ +```release-note:security +Upgrade go version to 1.22.5 to address [CVE-2024-24791](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-24791) +``` \ No newline at end of file diff --git a/.go-version b/.go-version index 2a0ba77cc5..054c858fbf 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.22.4 +1.22.5 \ No newline at end of file diff --git a/go.mod b/go.mod index 40dfce90cc..a6ebcbaabd 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/hashicorp/consul -go 1.20 +go 1.22 -toolchain go1.22.4 +toolchain go1.22.5 replace ( github.com/hashicorp/consul/api => ./api diff --git a/go.sum b/go.sum index 886a25dcf5..86dbf3e57d 100644 --- a/go.sum +++ b/go.sum @@ -195,6 +195,7 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -226,6 +227,7 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -289,6 +291,7 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -513,6 +516,7 @@ github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/Uy 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 v0.0.0-20220329195025-15018e9b97e0/go.mod h1:nTakvJ4XYq45UXtn0DbwR4aU9ZdjlnIenpbs6Cd+FM0= 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= @@ -547,6 +551,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk= +github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= @@ -584,11 +589,13 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= @@ -683,7 +690,9 @@ github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:v github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= +github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= 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= @@ -751,6 +760,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L 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.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -767,6 +777,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg 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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= @@ -1373,6 +1384,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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-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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= diff --git a/test-integ/go.mod b/test-integ/go.mod index 4e06d2f16f..072dda44ac 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -1,6 +1,8 @@ module github.com/hashicorp/consul/test-integ -go 1.20 +go 1.22 + +toolchain go1.22.5 require ( github.com/google/go-cmp v0.5.9 diff --git a/test-integ/go.sum b/test-integ/go.sum index 5428aef74d..a7b09dfb83 100644 --- a/test-integ/go.sum +++ b/test-integ/go.sum @@ -1,6 +1,7 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o= +fortio.org/assert v1.1.4/go.mod h1:039mG+/iYDPO8Ibx8TrNuJCm2T2SuhwRI3uL9nHTTls= 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= @@ -12,12 +13,14 @@ 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/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= 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/DataDog/datadog-go v3.2.0+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/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= 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= @@ -51,7 +54,9 @@ github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+ 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.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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= @@ -161,10 +166,13 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv 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/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/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -225,6 +233,7 @@ github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh 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/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= 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= @@ -261,11 +270,13 @@ github.com/rboyer/blankspace v0.2.1/go.mod h1:GhnCkDlx1SYD6m4XCde73ncQ8pFTLSJvlC 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/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/ryanuber/columnize v2.1.0+incompatible/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/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= 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/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -273,6 +284,7 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs 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/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= @@ -335,6 +347,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -385,6 +398,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -410,6 +424,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks 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/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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= @@ -418,3 +433,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C 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.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index e4671b8cd9..d1e077db52 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -1,6 +1,8 @@ module github.com/hashicorp/consul/test/integration/consul-container -go 1.20 +go 1.22 + +toolchain go1.22.5 require ( fortio.org/fortio v1.54.0 diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index 28082f92c6..a418b57d6d 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -2,6 +2,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o= +fortio.org/assert v1.1.4/go.mod h1:039mG+/iYDPO8Ibx8TrNuJCm2T2SuhwRI3uL9nHTTls= 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= @@ -13,6 +14,7 @@ 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/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= 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= @@ -20,6 +22,7 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 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/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= 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= @@ -53,7 +56,9 @@ github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+ 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.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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= @@ -168,9 +173,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv 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.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -229,6 +236,7 @@ github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh 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/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= 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= @@ -262,6 +270,7 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx 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/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/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -273,6 +282,7 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs 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/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= @@ -342,6 +352,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.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= @@ -393,6 +404,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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= @@ -431,6 +443,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks 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/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 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= @@ -439,5 +452,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C 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.0/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-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From b3f15b91d32e6637f5295ed2b8ca250621b0e962 Mon Sep 17 00:00:00 2001 From: Maciej Lisowski <39798354+MaciejDromin@users.noreply.github.com> Date: Wed, 3 Jul 2024 23:43:29 +0200 Subject: [PATCH 093/185] docs: Remove duplicate 'to' word (#21222) Signed-off-by: Maciej Lisowski Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- .../services/usage/register-services-checks.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/content/docs/services/usage/register-services-checks.mdx b/website/content/docs/services/usage/register-services-checks.mdx index 07a3f20ad9..3cfe03c852 100644 --- a/website/content/docs/services/usage/register-services-checks.mdx +++ b/website/content/docs/services/usage/register-services-checks.mdx @@ -2,25 +2,25 @@ layout: docs page_title: Register services and health checks description: -> - Learn how to register services and health checks with Consul agents. + Learn how to register services and health checks with Consul agents. --- # Register services and health checks -This topic describes how to register services and health checks with Consul in networks running on virtual machines (VM). Refer to [Define Services](/consul/docs/services/usage/define-services) and [Define Health Checks](/consul/docs/services/usage/checks) for information about how to define services and health checks. +This topic describes how to register services and health checks with Consul in networks running on virtual machines (VM). Refer to [Define Services](/consul/docs/services/usage/define-services) and [Define Health Checks](/consul/docs/services/usage/checks) for information about how to define services and health checks. ## Overview Register services and health checks in VM environments by providing the service definition to a Consul agent. You can use several different methods to register services and health checks. - Start a Consul agent and pass the service definition in the [agent's configuration directory](/consul/docs/agent#configuring-consul-agents). - Reload the a running Consul agent and pass the service definition in the [agent's configuration directory](/consul/docs/agent#configuring-consul-agents). Use this method when implementing changes to an existing service or health check definition. -- Use the [`consul services register` command](/consul/commands/services/register) to register new service and health checks with a running Consul agent. -- Call the [`/agent/service/register`](/consul/api-docs/agent/service#register-service) HTTP API endpoint to to register new service and health checks with a running Consul agent. +- Use the [`consul services register` command](/consul/commands/services/register) to register new service and health checks with a running Consul agent. +- Call the [`/agent/service/register`](/consul/api-docs/agent/service#register-service) HTTP API endpoint to register new service and health checks with a running Consul agent. - Call the [`/agent/check/register`](/consul/api-docs/agent/check#register-check) HTTP API endpoint to register a health check independent from the service. -When a service is registered using the HTTP API endpoint or CLI command, the checks persist in the Consul data folder. If the agent restarts, Consul uses the service and check configurations in the configuration directory to start the services. +When a service is registered using the HTTP API endpoint or CLI command, the checks persist in the Consul data folder. If the agent restarts, Consul uses the service and check configurations in the configuration directory to start the services. -Note that health checks associated with a service are application-level checks. +Note that health checks associated with a service are application-level checks. ## Start an agent We recommend registering services on startup because the service persists if the agent fails. Specify the directory containing the service definition with the `-config-dir` option on startup. When the Consul agent starts, it processes all configurations in the directory and registers any services contained in the configurations. In the following example, the Consul agent starts and loads the configurations contained in the `configs` directory: @@ -48,7 +48,7 @@ Refer to [Consul Agent Service Registration](/consul/commands/services/register) Use the following methods to register services and health checks using the HTTP API. ### Register services -Send a `PUT` request to the `/agent/service/register` API endpoint to dynamically register a service and its associated health checks. To register health checks independently, [call the checks API endpoint](#call-the-checks-http-api-endpoint). +Send a `PUT` request to the `/agent/service/register` API endpoint to dynamically register a service and its associated health checks. To register health checks independently, [call the checks API endpoint](#call-the-checks-http-api-endpoint). The following example request registers the service defined in the `service.json` file. From 763cd0bffb6e40d9c8813dd2a9cf0bed28427667 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 5 Jul 2024 14:51:20 -0400 Subject: [PATCH 094/185] fix(txn): validate verbs (#21519) * fix(txn): validate verbs * changelog --- .changelog/21519.txt | 3 + agent/consul/kvs_endpoint.go | 7 +- agent/consul/state/txn.go | 56 +++++++++---- agent/consul/state/txn_test.go | 70 ++++++++++++++--- agent/consul/txn_endpoint.go | 119 ++++++++++++++++++++++++++-- agent/consul/txn_endpoint_test.go | 125 ++++++++++++++++++++++++++++++ 6 files changed, 350 insertions(+), 30 deletions(-) create mode 100644 .changelog/21519.txt diff --git a/.changelog/21519.txt b/.changelog/21519.txt new file mode 100644 index 0000000000..2913443b1c --- /dev/null +++ b/.changelog/21519.txt @@ -0,0 +1,3 @@ +```release-note:bug +txn: Fix a bug where mismatched Consul server versions could result in undetected data loss for when using newer Transaction verbs. +``` diff --git a/agent/consul/kvs_endpoint.go b/agent/consul/kvs_endpoint.go index 65dc2cd56d..bfad9fa193 100644 --- a/agent/consul/kvs_endpoint.go +++ b/agent/consul/kvs_endpoint.go @@ -42,7 +42,8 @@ func kvsPreApply(logger hclog.Logger, srv *Server, authz resolver.Result, op api return false, fmt.Errorf("Must provide key") } - // Apply the ACL policy if any. + // Apply the ACL policy if any, and validate operation. + // enumcover:api.KVOp switch op { case api.KVDeleteTree: var authzContext acl.AuthorizerContext @@ -66,13 +67,15 @@ func kvsPreApply(logger hclog.Logger, srv *Server, authz resolver.Result, op api return false, err } - default: + case api.KVCheckNotExists, api.KVUnlock, api.KVLock, api.KVCAS, api.KVDeleteCAS, api.KVDelete, api.KVSet: var authzContext acl.AuthorizerContext dirEnt.FillAuthzContext(&authzContext) if err := authz.ToAllowAuthorizer().KeyWriteAllowed(dirEnt.Key, &authzContext); err != nil { return false, err } + default: + return false, fmt.Errorf("unknown KV operation: %s", op) } // If this is a lock, we must check for a lock-delay. Since lock-delay diff --git a/agent/consul/state/txn.go b/agent/consul/state/txn.go index 30189fc1ed..66cc4bb33d 100644 --- a/agent/consul/state/txn.go +++ b/agent/consul/state/txn.go @@ -4,17 +4,31 @@ package state import ( + "errors" "fmt" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" ) +type UnsupportedFSMApplyPanicError struct { + Wrapped error +} + +func (e *UnsupportedFSMApplyPanicError) Unwrap() error { + return e.Wrapped +} + +func (e *UnsupportedFSMApplyPanicError) Error() string { + return e.Wrapped.Error() +} + // txnKVS handles all KV-related operations. func (s *Store) txnKVS(tx WriteTxn, idx uint64, op *structs.TxnKVOp) (structs.TxnResults, error) { var entry *structs.DirEntry var err error + // enumcover: api.KVOp switch op.Verb { case api.KVSet: entry = &op.DirEnt @@ -95,7 +109,7 @@ func (s *Store) txnKVS(tx WriteTxn, idx uint64, op *structs.TxnKVOp) (structs.Tx } default: - err = fmt.Errorf("unknown KV verb %q", op.Verb) + err = &UnsupportedFSMApplyPanicError{fmt.Errorf("unknown KV verb %q", op.Verb)} } if err != nil { return nil, err @@ -123,11 +137,12 @@ func (s *Store) txnKVS(tx WriteTxn, idx uint64, op *structs.TxnKVOp) (structs.Tx func txnSession(tx WriteTxn, idx uint64, op *structs.TxnSessionOp) error { var err error + // enumcover: api.SessionOp switch op.Verb { case api.SessionDelete: err = sessionDeleteWithSession(tx, &op.Session, idx) default: - err = fmt.Errorf("unknown Session verb %q", op.Verb) + return &UnsupportedFSMApplyPanicError{fmt.Errorf("unknown session verb %q", op.Verb)} } if err != nil { return fmt.Errorf("failed to delete session: %v", err) @@ -146,11 +161,17 @@ func txnLegacyIntention(tx WriteTxn, idx uint64, op *structs.TxnIntentionOp) err case structs.IntentionOpDelete: return legacyIntentionDeleteTxn(tx, idx, op.Intention.ID) case structs.IntentionOpDeleteAll: - fallthrough // deliberately not available via this api + // deliberately not available via this api + return fmt.Errorf("Intention op not supported %q", op.Op) case structs.IntentionOpUpsert: - fallthrough // deliberately not available via this api + // deliberately not available via this api + return fmt.Errorf("Intention op not supported %q", op.Op) default: - return fmt.Errorf("unknown Intention op %q", op.Op) + // If we've gotten to this point, the unknown verb has slipped by + // endpoint validation. This means it could be a mismatch in Server versions + // that are sending known verbs as part of Raft logs. We panic rather than silently + // swallowing the error during Raft Apply. + panic(fmt.Sprintf("unknown Intention op %q", op.Op)) } } @@ -202,7 +223,7 @@ func (s *Store) txnNode(tx WriteTxn, idx uint64, op *structs.TxnNodeOp) (structs } default: - err = fmt.Errorf("unknown Node verb %q", op.Verb) + err = &UnsupportedFSMApplyPanicError{fmt.Errorf("unknown Node verb %q", op.Verb)} } if err != nil { return nil, err @@ -271,7 +292,7 @@ func (s *Store) txnService(tx WriteTxn, idx uint64, op *structs.TxnServiceOp) (s return nil, err default: - return nil, fmt.Errorf("unknown Service verb %q", op.Verb) + return nil, &UnsupportedFSMApplyPanicError{fmt.Errorf("unknown Service verb %q", op.Verb)} } } @@ -326,7 +347,7 @@ func (s *Store) txnCheck(tx WriteTxn, idx uint64, op *structs.TxnCheckOp) (struc } default: - err = fmt.Errorf("unknown Check verb %q", op.Verb) + err = &UnsupportedFSMApplyPanicError{fmt.Errorf("unknown check verb %q", op.Verb)} } if err != nil { return nil, err @@ -352,7 +373,7 @@ func (s *Store) txnCheck(tx WriteTxn, idx uint64, op *structs.TxnCheckOp) (struc // txnDispatch runs the given operations inside the state store transaction. func (s *Store) txnDispatch(tx WriteTxn, idx uint64, ops structs.TxnOps) (structs.TxnResults, structs.TxnErrors) { results := make(structs.TxnResults, 0, len(ops)) - errors := make(structs.TxnErrors, 0, len(ops)) + errs := make(structs.TxnErrors, 0, len(ops)) for i, op := range ops { var ret structs.TxnResults var err error @@ -374,24 +395,33 @@ func (s *Store) txnDispatch(tx WriteTxn, idx uint64, ops structs.TxnOps) (struct // compatibility with pre-1.9.0 raft logs and during upgrades. err = txnLegacyIntention(tx, idx, op.Intention) default: - err = fmt.Errorf("no operation specified") + panic("no operation specified") } // Accumulate the results. results = append(results, ret...) + var panicErr *UnsupportedFSMApplyPanicError + if errors.As(err, &panicErr) { + // If we've gotten to this point, the unknown verb has slipped by + // endpoint validation. This means it could be a mismatch in Server versions + // that are sending known verbs as part of Raft logs. We panic rather than silently + // swallowing the error during Raft Apply. See NET-9016 for historical context. + panic(panicErr.Wrapped) + } + // Capture any error along with the index of the operation that // failed. if err != nil { - errors = append(errors, &structs.TxnError{ + errs = append(errs, &structs.TxnError{ OpIndex: i, What: err.Error(), }) } } - if len(errors) > 0 { - return nil, errors + if len(errs) > 0 { + return nil, errs } return results, nil diff --git a/agent/consul/state/txn_test.go b/agent/consul/state/txn_test.go index bda004a63a..c3d95a4efe 100644 --- a/agent/consul/state/txn_test.go +++ b/agent/consul/state/txn_test.go @@ -1058,14 +1058,6 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) { }, }, }, - &structs.TxnOp{ - KV: &structs.TxnKVOp{ - Verb: "nope", - DirEnt: structs.DirEntry{ - Key: "foo/delete", - }, - }, - }, } results, errors := s.TxnRW(7, ops) if len(errors) != len(ops) { @@ -1086,7 +1078,6 @@ func TestStateStore_Txn_KVS_Rollback(t *testing.T) { `key "nope" doesn't exist`, "current modify index", `key "nope" doesn't exist`, - "unknown KV verb", } if len(errors) != len(expected) { t.Fatalf("bad len: %d != %d", len(errors), len(expected)) @@ -1415,3 +1406,64 @@ func TestStateStore_Txn_KVS_ModifyIndexes(t *testing.T) { } } } + +// TestStateStore_UnknownTxnOperationsPanic validates that unknown txn operations panic. +// If we error in this case this is from an FSM Apply, the state store of this agent could potentially be out of +// sync with other agents that applied the operation. In the case of responding to a local endpoint, we require +// that the operation type be validated prior to being sent to the state store. +// See NET-9016 for historical context. +func TestStateStore_UnknownTxnOperationsPanic(t *testing.T) { + s := testStateStore(t) + + testCases := []structs.TxnOps{ + { + &structs.TxnOp{ + KV: &structs.TxnKVOp{ + Verb: "sand-the-floor", + DirEnt: structs.DirEntry{ + Key: "foo/a", + }, + }, + }, + }, + { + &structs.TxnOp{ + Node: &structs.TxnNodeOp{ + Verb: "wax-the-car", + }, + }, + }, + { + &structs.TxnOp{ + Service: &structs.TxnServiceOp{ + Verb: "paint-the-house", + }, + }, + }, + { + &structs.TxnOp{ + Check: &structs.TxnCheckOp{ + Verb: "paint-the-fence", + }, + }, + }, + { + &structs.TxnOp{ + Session: &structs.TxnSessionOp{ + Verb: "sweep-the-knee", + }, + }, + }, + { + &structs.TxnOp{ + Intention: &structs.TxnIntentionOp{ // nolint:staticcheck // SA1019 intentional use of deprecated field + Op: "flying-crane-kick", + }, + }, + }, + } + + for _, tc := range testCases { + require.Panics(t, func() { s.TxnRW(3, tc) }) + } +} diff --git a/agent/consul/txn_endpoint.go b/agent/consul/txn_endpoint.go index f39cd502cb..e704c9a2ed 100644 --- a/agent/consul/txn_endpoint.go +++ b/agent/consul/txn_endpoint.go @@ -57,8 +57,15 @@ func (t *Txn) preCheck(authorizer resolver.Result, ops structs.TxnOps) structs.T }) } case op.Node != nil: - // Skip the pre-apply checks if this is a GET. - if op.Node.Verb == api.NodeGet { + requiresPreApply, err := nodeVerbValidate(op.Node.Verb) + if err != nil { + errors = append(errors, &structs.TxnError{ + OpIndex: i, + What: err.Error(), + }) + break + } + if !requiresPreApply { break } @@ -79,8 +86,15 @@ func (t *Txn) preCheck(authorizer resolver.Result, ops structs.TxnOps) structs.T }) } case op.Service != nil: - // Skip the pre-apply checks if this is a GET. - if op.Service.Verb == api.ServiceGet { + requiresPreApply, err := serviceVerbValidate(op.Service.Verb) + if err != nil { + errors = append(errors, &structs.TxnError{ + OpIndex: i, + What: err.Error(), + }) + break + } + if !requiresPreApply { break } @@ -92,8 +106,15 @@ func (t *Txn) preCheck(authorizer resolver.Result, ops structs.TxnOps) structs.T }) } case op.Check != nil: - // Skip the pre-apply checks if this is a GET. - if op.Check.Verb == api.CheckGet { + requiresPreApply, err := checkVerbValidate(op.Check.Verb) + if err != nil { + errors = append(errors, &structs.TxnError{ + OpIndex: i, + What: err.Error(), + }) + break + } + if !requiresPreApply { break } @@ -106,6 +127,25 @@ func (t *Txn) preCheck(authorizer resolver.Result, ops structs.TxnOps) structs.T What: err.Error(), }) } + case op.Intention != nil: + if err := intentionVerbValidate(op.Intention.Op); err != nil { + errors = append(errors, &structs.TxnError{ + OpIndex: i, + What: err.Error(), + }) + } + case op.Session != nil: + if err := sessionVerbValidate(op.Session.Verb); err != nil { + errors = append(errors, &structs.TxnError{ + OpIndex: i, + What: err.Error(), + }) + } + default: + errors = append(errors, &structs.TxnError{ + OpIndex: i, + What: "unknown operation type", + }) } } @@ -224,3 +264,70 @@ func (t *Txn) Read(args *structs.TxnReadRequest, reply *structs.TxnReadResponse) return nil } + +// nodeVerbValidate checks for a known operation type. For certain operations, +// it also indicated if further "preApply" checks are required. +func nodeVerbValidate(op api.NodeOp) (bool, error) { + // enumcover: api.NodeOp + switch op { + // Skip the pre-apply checks if this is a GET. + case api.NodeGet: + return false, nil + case api.NodeSet, api.NodeCAS, api.NodeDelete, api.NodeDeleteCAS: + return true, nil + default: + return false, fmt.Errorf("unknown node operation: %s", op) + } +} + +// serviceVerbValidate checks for a known operation type. For certain operations, +// it also indicated if further "preApply" checks are required. +func serviceVerbValidate(op api.ServiceOp) (bool, error) { + // enumcover: api.ServiceOp + switch op { + // Skip the pre-apply checks if this is a GET. + case api.ServiceGet: + return false, nil + case api.ServiceSet, api.ServiceCAS, api.ServiceDelete, api.ServiceDeleteCAS: + return true, nil + default: + return false, fmt.Errorf("unknown service operation: %s", op) + } +} + +// checkVerbValidate checks for a known operation type. For certain operations, +// it also indicated if further "preApply" checks are required. +func checkVerbValidate(op api.CheckOp) (bool, error) { + // enumcover: api.CheckOp + switch op { + // Skip the pre-apply checks if this is a GET. + case api.CheckGet: + return false, nil + case api.CheckSet, api.CheckCAS, api.CheckDelete, api.CheckDeleteCAS: + return true, nil + default: + return false, fmt.Errorf("unknown check operation: %s", op) + } +} + +// intentionVerbValidate checks for a known operation type. +func intentionVerbValidate(op structs.IntentionOp) error { + // enumcover: structs.IntentionOp + switch op { + case structs.IntentionOpCreate, structs.IntentionOpDelete, structs.IntentionOpUpdate, structs.IntentionOpDeleteAll, structs.IntentionOpUpsert: + return nil + default: + return fmt.Errorf("unknown intention operation: %s", op) + } +} + +// sessionVerbValidate checks for a known operation type. +func sessionVerbValidate(op api.SessionOp) error { + // enumcover: api.SessionOp + switch op { + case api.SessionDelete: + return nil + default: + return fmt.Errorf("unknown session operation: %s", op) + } +} diff --git a/agent/consul/txn_endpoint_test.go b/agent/consul/txn_endpoint_test.go index ef2ecd13a3..03bccf95ff 100644 --- a/agent/consul/txn_endpoint_test.go +++ b/agent/consul/txn_endpoint_test.go @@ -946,3 +946,128 @@ func TestTxn_Read_ACLDeny(t *testing.T) { require.Empty(t, out.Results) }) } + +// TestTxn_Validation works across RW and RO Txn endpoints validating the "preCheck()" operation consistently +// validates operations provided in the request. +func TestTxn_Validation(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + t.Parallel() + + dir1, s1 := testServer(t) + defer os.RemoveAll(dir1) + defer s1.Shutdown() + codec := rpcClient(t, s1) + defer codec.Close() + + testrpc.WaitForLeader(t, s1.RPC, "dc1") + + // Each one of these test cases should error as invalid. + testCases := []struct { + request structs.TxnReadRequest + expectedError string + }{ + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + KV: &structs.TxnKVOp{ + Verb: "tick", + DirEnt: structs.DirEntry{ + Key: "nope", + }, + }, + }, + }, + }, + expectedError: "unknown KV operation", + }, + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + Node: &structs.TxnNodeOp{ + Verb: "tick", + }, + }, + }, + }, + expectedError: "unknown node operation", + }, + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + Service: &structs.TxnServiceOp{ + Verb: "tick", + }, + }, + }, + }, + expectedError: "unknown service operation", + }, + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + Check: &structs.TxnCheckOp{ + Verb: "tick", + }, + }, + }, + }, + expectedError: "unknown check operation", + }, + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + Session: &structs.TxnSessionOp{ + Verb: "tick", + }, + }, + }, + }, + expectedError: "unknown session operation", + }, + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + Intention: &structs.TxnIntentionOp{ // nolint:staticcheck // SA1019 intentional use of deprecated field + Op: "BOOM!", + }, + }, + }, + }, + expectedError: "unknown intention operation", + }, + { + request: structs.TxnReadRequest{ + Datacenter: "dc1", + Ops: structs.TxnOps{ + &structs.TxnOp{ + // Intentionally Empty + }, + }, + }, + expectedError: "unknown operation type", + }, + } + + for _, tc := range testCases { + var out structs.TxnReadResponse + err := msgpackrpc.CallWithCodec(codec, "Txn.Read", &tc.request, &out) + require.NoError(t, err) + require.Greater(t, len(out.Errors), 0) + require.Contains(t, out.Errors[0].Error(), tc.expectedError) + } +} From 40ca4ad6d04c02e479bd768093d593c711e09f0b Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Fri, 5 Jul 2024 15:19:23 -0400 Subject: [PATCH 095/185] [NET-5622] build: consolidate Envoy version management (#21245) * build: consolidate Envoy version management Simplify Envoy version management by consolidating all runtime, build, and CI sources of Envoy versions into a single plaintext file. The goal of this change is to avoid common mistakes missing an update of some Envoy versions (both in general and due to release branch inconsistency), and enable automated Envoy version updates in the future. * ci: add missing ref argument for get-go-version Supports nightly tests. --- .../nightly-test-integ-peering_commontopo.yml | 10 +- .../nightly-test-integrations-1.15.x.yml | 50 +++++--- .../nightly-test-integrations-1.17.x.yml | 50 +++++--- .../nightly-test-integrations-1.18.x.yml | 51 +++++--- .../nightly-test-integrations-1.19.x.yml | 50 +++++--- .../workflows/nightly-test-integrations.yml | 52 +++++--- .../workflows/reusable-get-envoy-versions.yml | 71 +++++++++++ .github/workflows/reusable-get-go-version.yml | 9 ++ .github/workflows/test-integrations.yml | 35 ++--- Makefile | 3 +- command/connect/envoy/envoy.go | 4 +- command/connect/envoy/envoy_test.go | 2 +- envoyextensions/xdscommon/ENVOY_VERSIONS | 14 ++ envoyextensions/xdscommon/envoy_versioning.go | 2 +- .../xdscommon/envoy_versioning_test.go | 120 ++++++------------ envoyextensions/xdscommon/proxysupport.go | 92 +++++++++++--- .../xdscommon/proxysupport_test.go | 51 ++++++++ test/integration/connect/envoy/helpers.bash | 10 -- test/integration/connect/envoy/run-tests.sh | 5 +- 19 files changed, 460 insertions(+), 221 deletions(-) create mode 100644 .github/workflows/reusable-get-envoy-versions.yml create mode 100644 envoyextensions/xdscommon/ENVOY_VERSIONS diff --git a/.github/workflows/nightly-test-integ-peering_commontopo.yml b/.github/workflows/nightly-test-integ-peering_commontopo.yml index ce55159233..5c7f5fa23b 100644 --- a/.github/workflows/nightly-test-integ-peering_commontopo.yml +++ b/.github/workflows/nightly-test-integ-peering_commontopo.yml @@ -39,12 +39,20 @@ jobs: get-go-version: uses: ./.github/workflows/reusable-get-go-version.yml + with: + ref: ${{ inputs.branch }} + + get-envoy-versions: + uses: ./.github/workflows/reusable-get-envoy-versions.yml + with: + ref: ${{ inputs.branch }} tests: runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl ) }} needs: - setup - get-go-version + - get-envoy-versions permissions: id-token: write # NOTE: this permission is explicitly required for Vault auth. contents: read @@ -62,7 +70,7 @@ jobs: name: '${{matrix.test-case}}' env: - ENVOY_VERSION: "1.29.5" + ENVOY_VERSION: ${{ needs.get-envoy-versions.outputs.max-envoy-version }} steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index 5bef4c85fa..8ac92f282f 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -50,6 +50,14 @@ jobs: get-go-version: needs: [check-ent] uses: ./.github/workflows/reusable-get-go-version.yml + with: + ref: release/1.15.x + + get-envoy-versions: + needs: [check-ent] + uses: ./.github/workflows/reusable-get-envoy-versions.yml + with: + ref: release/1.15.x dev-build: needs: @@ -79,36 +87,34 @@ jobs: - 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 - # 14 based on these values: - # envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.5", "1.28.3"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 7 + # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be + # further multiplied in envoy-integration tests by the other dimensions in the matrix + # to determine the total number of runners used. + TEST_SPLITS: 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)) + if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then + echo "TEST_SPLITS is larger than the number of tests/packages to split." + TEST_SPLITS=$((NUM_DIRS-1)) fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) + # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS. + TEST_SPLITS=$((TEST_SPLITS-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 --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" - + envoy-integration-test: runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - get-go-version + - get-envoy-versions - generate-envoy-job-matrices - dev-build permissions: @@ -117,7 +123,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11", "1.26.8", "1.27.6", "1.28.4"] + envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }} xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -196,7 +202,7 @@ jobs: 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: @@ -212,7 +218,17 @@ jobs: consul-version: ["1.14", "1.15"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" + # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the + # matrix.consul-version, since we are testing upgrade from an older Consul version. + # In practice, this should be the highest Envoy version supported by the lowest non-LTS + # Consul version in the matrix (LTS versions receive additional Envoy version support). + # + # This value should be kept current in new nightly test workflows, and updated any time + # a new major Envoy release is added to the set supported by Consul versions in + # matrix.consul-version (i.e. whenever the highest common Envoy version across active + # Consul versions changes). The minor Envoy version does not necessarily need to be + # kept current for the purpose of these tests, but the major (1.N) version should be. + ENVOY_VERSION: "1.24.12" steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index 4bc89cab7c..df952d8234 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -50,6 +50,14 @@ jobs: get-go-version: needs: [check-ent] uses: ./.github/workflows/reusable-get-go-version.yml + with: + ref: release/1.17.x + + get-envoy-versions: + needs: [check-ent] + uses: ./.github/workflows/reusable-get-envoy-versions.yml + with: + ref: release/1.17.x dev-build: needs: @@ -79,36 +87,34 @@ jobs: - 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.8", "1.27.5"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 + # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be + # further multiplied in envoy-integration tests by the other dimensions in the matrix + # to determine the total number of runners used. + TEST_SPLITS: 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)) + if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then + echo "TEST_SPLITS is larger than the number of tests/packages to split." + TEST_SPLITS=$((NUM_DIRS-1)) fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) + # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS. + TEST_SPLITS=$((TEST_SPLITS-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 --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" - + envoy-integration-test: runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - get-go-version + - get-envoy-versions - generate-envoy-job-matrices - dev-build permissions: @@ -117,7 +123,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] + envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }} xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -199,7 +205,7 @@ jobs: 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: @@ -215,7 +221,17 @@ jobs: consul-version: ["1.15", "1.16", "1.17"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" + # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the + # matrix.consul-version, since we are testing upgrade from an older Consul version. + # In practice, this should be the highest Envoy version supported by the lowest non-LTS + # Consul version in the matrix (LTS versions receive additional Envoy version support). + # + # This value should be kept current in new nightly test workflows, and updated any time + # a new major Envoy release is added to the set supported by Consul versions in + # matrix.consul-version (i.e. whenever the highest common Envoy version across active + # Consul versions changes). The minor Envoy version does not necessarily need to be + # kept current for the purpose of these tests, but the major (1.N) version should be. + ENVOY_VERSION: 1.27.6 steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/.github/workflows/nightly-test-integrations-1.18.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml index 9986b54e81..c432dc1c09 100644 --- a/.github/workflows/nightly-test-integrations-1.18.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -50,6 +50,13 @@ jobs: get-go-version: needs: [check-ent] uses: ./.github/workflows/reusable-get-go-version.yml + with: + ref: release/1.18.x + + get-envoy-versions: + uses: ./.github/workflows/reusable-get-envoy-versions.yml + with: + ref: release/1.18.x dev-build: needs: @@ -79,36 +86,34 @@ jobs: - 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.8", "1.27.6"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 + # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be + # further multiplied in envoy-integration tests by the other dimensions in the matrix + # to determine the total number of runners used. + TEST_SPLITS: 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)) + if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then + echo "TEST_SPLITS is larger than the number of tests/packages to split." + TEST_SPLITS=$((NUM_DIRS-1)) fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) + # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS. + TEST_SPLITS=$((TEST_SPLITS-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 --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" - + envoy-integration-test: runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - get-go-version + - get-envoy-versions - generate-envoy-job-matrices - dev-build permissions: @@ -117,7 +122,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.8", "1.27.6"] + envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }} xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -199,7 +204,7 @@ jobs: 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: @@ -212,10 +217,20 @@ jobs: strategy: fail-fast: false matrix: - consul-version: ["1.15", "1.16", "1.17"] + consul-version: ["1.15", "1.16", "1.17", "1.18"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" + # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the + # matrix.consul-version, since we are testing upgrade from an older Consul version. + # In practice, this should be the highest Envoy version supported by the lowest non-LTS + # Consul version in the matrix (LTS versions receive additional Envoy version support). + # + # This value should be kept current in new nightly test workflows, and updated any time + # a new major Envoy release is added to the set supported by Consul versions in + # matrix.consul-version (i.e. whenever the highest common Envoy version across active + # Consul versions changes). The minor Envoy version does not necessarily need to be + # kept current for the purpose of these tests, but the major (1.N) version should be. + ENVOY_VERSION: 1.27.6 steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml index eb1f759e8f..452d174e1e 100644 --- a/.github/workflows/nightly-test-integrations-1.19.x.yml +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -42,6 +42,13 @@ jobs: get-go-version: uses: ./.github/workflows/reusable-get-go-version.yml + with: + ref: release/1.19.x + + get-envoy-versions: + uses: ./.github/workflows/reusable-get-envoy-versions.yml + with: + ref: release/1.19.x dev-build: needs: @@ -71,36 +78,34 @@ jobs: - 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.8", "1.27.6"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 + # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be + # further multiplied in envoy-integration tests by the other dimensions in the matrix + # to determine the total number of runners used. + TEST_SPLITS: 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)) + if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then + echo "TEST_SPLITS is larger than the number of tests/packages to split." + TEST_SPLITS=$((NUM_DIRS-1)) fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) + # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS. + TEST_SPLITS=$((TEST_SPLITS-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 --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" - + envoy-integration-test: runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - get-go-version + - get-envoy-versions - generate-envoy-job-matrices - dev-build permissions: @@ -109,7 +114,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.26.8", "1.27.6", "1.28.4", "1.29.5"] + envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }} xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -197,6 +202,7 @@ jobs: needs: - setup - get-go-version + - get-envoy-versions - dev-build permissions: id-token: write # NOTE: this permission is explicitly required for Vault auth. @@ -204,10 +210,20 @@ jobs: strategy: fail-fast: false matrix: - consul-version: ["1.15", "1.17", "1.18"] + consul-version: ["1.15", "1.17", "1.18", "1.19"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" + # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the + # matrix.consul-version, since we are testing upgrade from an older Consul version. + # In practice, this should be the highest Envoy version supported by the lowest non-LTS + # Consul version in the matrix (LTS versions receive additional Envoy version support). + # + # This value should be kept current in new nightly test workflows, and updated any time + # a new major Envoy release is added to the set supported by Consul versions in + # matrix.consul-version (i.e. whenever the highest common Envoy version across active + # Consul versions changes). The minor Envoy version does not necessarily need to be + # kept current for the purpose of these tests, but the major (1.N) version should be. + ENVOY_VERSION: 1.27.6 steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index fdb63d0738..cfaa253030 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -41,6 +41,9 @@ jobs: get-go-version: uses: ./.github/workflows/reusable-get-go-version.yml + get-envoy-versions: + uses: ./.github/workflows/reusable-get-envoy-versions.yml + dev-build: needs: - setup @@ -55,7 +58,9 @@ jobs: elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} generate-envoy-job-matrices: - needs: [setup] + needs: + - setup + - get-envoy-versions runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} name: Generate Envoy Job Matrices outputs: @@ -68,28 +73,25 @@ jobs: - 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.26.8", "1.27.5", "1.28.3", "1.29.4"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 8 + # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be + # further multiplied in envoy-integration tests by the other dimensions in the matrix + # to determine the total number of runners used. + TEST_SPLITS: 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)) + if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then + echo "TEST_SPLITS is larger than the number of tests/packages to split." + TEST_SPLITS=$((NUM_DIRS-1)) fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) + # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS. + TEST_SPLITS=$((TEST_SPLITS-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 --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" @@ -98,6 +100,7 @@ jobs: needs: - setup - get-go-version + - get-envoy-versions - generate-envoy-job-matrices - dev-build permissions: @@ -106,7 +109,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.26.8", "1.27.6", "1.28.4", "1.29.5"] + envoy-version: ${{ fromJSON(needs.get-envoy-versions.outputs.envoy-versions-json) }} xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -188,7 +191,7 @@ jobs: 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: @@ -201,13 +204,20 @@ jobs: strategy: fail-fast: false matrix: - consul-version: [ "1.17", "1.18"] + consul-version: ["1.17", "1.18", "1.19"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - # ENVOY_VERSION should be the latest version upported by all - # consul versions in the matrix.consul-version, since we are testing upgrade from - # an older consul version, e.g., 1.27.x is supported by both 1.17 and 1.18. - ENVOY_VERSION: "1.27.6" + # ENVOY_VERSION should be the latest version supported by _all_ Consul versions in the + # matrix.consul-version, since we are testing upgrade from an older Consul version. + # In practice, this should be the highest Envoy version supported by the lowest non-LTS + # Consul version in the matrix (LTS versions receive additional Envoy version support). + # + # This value should be kept current in new nightly test workflows, and updated any time + # a new major Envoy release is added to the set supported by Consul versions in + # matrix.consul-version (i.e. whenever the highest common Envoy version across active + # Consul versions changes). The minor Envoy version does not necessarily need to be + # kept current for the purpose of these tests, but the major (1.N) version should be. + ENVOY_VERSION: 1.27.6 steps: - name: Checkout code uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 diff --git a/.github/workflows/reusable-get-envoy-versions.yml b/.github/workflows/reusable-get-envoy-versions.yml new file mode 100644 index 0000000000..1d40587cd7 --- /dev/null +++ b/.github/workflows/reusable-get-envoy-versions.yml @@ -0,0 +1,71 @@ +name: get-envoy-versions + +# Reads the canonical ENVOY_VERSIONS file for either the current branch or a specified version of Consul, +# and returns both the max and all supported Envoy versions. + +on: + workflow_call: + inputs: + ref: + description: | + The Consul ref/branch (e.g. release/1.18.x) for which to determine supported Envoy versions. + If not provided, the default actions/checkout value (current ref) is used. + type: string + outputs: + max-envoy-version: + description: The max supported Envoy version for the specified Consul version + value: ${{ jobs.get-envoy-versions.outputs.max-envoy-version }} + envoy-versions: + description: | + All supported Envoy versions for the specified Consul version (formatted as multiline string with one version + per line, in descending order) + value: ${{ jobs.get-envoy-versions.outputs.envoy-versions }} + envoy-versions-json: + description: | + All supported Envoy versions for the specified Consul version (formatted as JSON array) + value: ${{ jobs.get-envoy-versions.outputs.envoy-versions-json }} + +jobs: + get-envoy-versions: + name: "Determine supported Envoy versions" + runs-on: ubuntu-latest + outputs: + max-envoy-version: ${{ steps.get-envoy-versions.outputs.max-envoy-version }} + envoy-versions: ${{ steps.get-envoy-versions.outputs.envoy-versions }} + envoy-versions-json: ${{ steps.get-envoy-versions.outputs.envoy-versions-json }} + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + # If not set, will default to current branch. + ref: ${{ inputs.ref }} + - name: Determine Envoy versions + id: get-envoy-versions + # Note that this script assumes that the ENVOY_VERSIONS file is in the envoyextensions/xdscommon directory. + # If in the future this file moves between branches, we could introduce a workflow input for the path that + # defaults to the new value, and manually configure the old value as needed. + run: | + MAX_ENVOY_VERSION=$(cat envoyextensions/xdscommon/ENVOY_VERSIONS | grep '^[[:digit:]]' | sort -nr | head -n 1) + ENVOY_VERSIONS=$(cat envoyextensions/xdscommon/ENVOY_VERSIONS | grep '^[[:digit:]]' | sort -nr) + ENVOY_VERSIONS_JSON=$(echo -n '[' && echo "${ENVOY_VERSIONS}" | awk '{printf "\"%s\",", $0}' | sed 's/,$//' && echo -n ']') + + # Loop through each line of ENVOY_VERSIONS and compare it to the regex + while IFS= read -r version; do + if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo 'Invalid version in ENVOY_VERSIONS: '$version' does not match the pattern ^[0-9]+\.[0-9]+\.[0-9]+$' + exit 1 + fi + done <<< "$ENVOY_VERSIONS" + if ! [[ $MAX_ENVOY_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo 'Invalid MAX_ENVOY_VERSION: '$MAX_ENVOY_VERSION' does not match the pattern ^[0-9]+\.[0-9]+\.[0-9]+$' + exit 1 + fi + + echo "Supported Envoy versions:" + echo "${ENVOY_VERSIONS}" + echo "envoy-versions<> $GITHUB_OUTPUT + echo "${ENVOY_VERSIONS}" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "Supported Envoy versions JSON: ${ENVOY_VERSIONS_JSON}" + echo "envoy-versions-json=${ENVOY_VERSIONS_JSON}" >> $GITHUB_OUTPUT + echo "Max supported Envoy version: ${MAX_ENVOY_VERSION}" + echo "max-envoy-version=${MAX_ENVOY_VERSION}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/reusable-get-go-version.yml b/.github/workflows/reusable-get-go-version.yml index 2fac43b9da..91e870c73c 100644 --- a/.github/workflows/reusable-get-go-version.yml +++ b/.github/workflows/reusable-get-go-version.yml @@ -2,6 +2,12 @@ name: get-go-version on: workflow_call: + inputs: + ref: + description: | + The Consul ref/branch (e.g. release/1.18.x) for which to determine the Go version. + If not provided, the default actions/checkout value (current ref) is used. + type: string outputs: go-version: description: "The Go version detected by this workflow" @@ -19,6 +25,9 @@ jobs: go-version-previous: ${{ steps.get-go-version.outputs.go-version-previous }} steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + # If not set, will default to current branch. + ref: ${{ inputs.ref }} - name: Determine Go version id: get-go-version # We use .go-version as our source of truth for current Go diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index b106c30a53..3d57c90994 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -63,6 +63,9 @@ jobs: get-go-version: uses: ./.github/workflows/reusable-get-go-version.yml + get-envoy-versions: + uses: ./.github/workflows/reusable-get-envoy-versions.yml + dev-build: needs: - setup @@ -269,28 +272,25 @@ jobs: - 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 2 based on these values: - # envoy-version: ["1.29.5"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 2 + # TEST_SPLITS sets the number of test case splits to use in the matrix. This will be + # further multiplied in envoy-integration tests by the other dimensions in the matrix + # to determine the total number of runners used. + TEST_SPLITS: 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)) + if [ "$NUM_DIRS" -lt "$TEST_SPLITS" ]; then + echo "TEST_SPLITS is larger than the number of tests/packages to split." + TEST_SPLITS=$((NUM_DIRS-1)) fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) + # fix issue where test splitting calculation generates 1 more split than TEST_SPLITS. + TEST_SPLITS=$((TEST_SPLITS-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 --raw-input --argjson runnercount "$TEST_SPLITS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" @@ -299,6 +299,7 @@ jobs: needs: - setup - get-go-version + - get-envoy-versions - generate-envoy-job-matrices - dev-build permissions: @@ -307,11 +308,10 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.29.5"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: - ENVOY_VERSION: ${{ matrix.envoy-version }} + ENVOY_VERSION: ${{ needs.get-envoy-versions.outputs.max-envoy-version }} XDS_TARGET: ${{ matrix.xds-target }} AWS_LAMBDA_REGION: us-west-2 steps: @@ -392,13 +392,14 @@ jobs: needs: - setup - get-go-version + - get-envoy-versions - dev-build permissions: id-token: write # NOTE: this permission is explicitly required for Vault auth. contents: read env: - ENVOY_VERSION: "1.29.5" - CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi" + ENVOY_VERSION: ${{ needs.get-envoy-versions.outputs.max-envoy-version }} + CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.5-dev-ubi" steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. diff --git a/Makefile b/Makefile index b4bf3807b9..71dcbef074 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,8 @@ CONSUL_IMAGE_VERSION?=latest # When changing the method of Go version detection, also update # version detection in CI workflows (reusable-get-go-version.yml). GOLANG_VERSION?=$(shell head -n 1 .go-version) -ENVOY_VERSION?='1.29.5' +# Takes the highest version from the ENVOY_VERSIONS file. +ENVOY_VERSION?=$(shell cat envoyextensions/xdscommon/ENVOY_VERSIONS | grep '^[[:digit:]]' | sort -nr | head -n 1) CONSUL_DATAPLANE_IMAGE := $(or $(CONSUL_DATAPLANE_IMAGE),"docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi") DEPLOYER_CONSUL_DATAPLANE_IMAGE := $(or $(DEPLOYER_CONSUL_DATAPLANE_IMAGE), "docker.io/hashicorppreview/consul-dataplane:1.3-dev") diff --git a/command/connect/envoy/envoy.go b/command/connect/envoy/envoy.go index 3489f1017a..b974a525e9 100644 --- a/command/connect/envoy/envoy.go +++ b/command/connect/envoy/envoy.go @@ -1052,7 +1052,7 @@ func checkEnvoyVersionCompatibility(envoyVersion string, unsupportedList []strin // Next build the constraint string using the bounds, make sure that we are less than but not equal to // maxSupported since we will add 1. Need to add one to the max minor version so that we accept all patches - splitS := strings.Split(xdscommon.GetMaxEnvoyMinorVersion(), ".") + splitS := strings.Split(xdscommon.GetMaxEnvoyMajorVersion(), ".") minor, err := strconv.Atoi(splitS[1]) if err != nil { return envoyCompat{}, err @@ -1061,7 +1061,7 @@ func checkEnvoyVersionCompatibility(envoyVersion string, unsupportedList []strin maxSupported := fmt.Sprintf("%s.%d", splitS[0], minor) cs.Reset() - cs.WriteString(fmt.Sprintf(">= %s, < %s", xdscommon.GetMinEnvoyMinorVersion(), maxSupported)) + cs.WriteString(fmt.Sprintf(">= %s, < %s", xdscommon.GetMinEnvoyMajorVersion(), maxSupported)) constraints, err := version.NewConstraint(cs.String()) if err != nil { return envoyCompat{}, err diff --git a/command/connect/envoy/envoy_test.go b/command/connect/envoy/envoy_test.go index 6f4237af52..64fd46c158 100644 --- a/command/connect/envoy/envoy_test.go +++ b/command/connect/envoy/envoy_test.go @@ -1850,7 +1850,7 @@ func TestCheckEnvoyVersionCompatibility(t *testing.T) { }, { name: "supported-at-max", - envoyVersion: xdscommon.GetMaxEnvoyMinorVersion(), + envoyVersion: xdscommon.GetMaxEnvoyMajorVersion(), unsupportedList: xdscommon.UnsupportedEnvoyVersions, expectedCompat: envoyCompat{ isCompatible: true, diff --git a/envoyextensions/xdscommon/ENVOY_VERSIONS b/envoyextensions/xdscommon/ENVOY_VERSIONS new file mode 100644 index 0000000000..c604e79dc1 --- /dev/null +++ b/envoyextensions/xdscommon/ENVOY_VERSIONS @@ -0,0 +1,14 @@ +# This file represents the canonical list of supported Envoy versions for this version of Consul. +# +# Every line must contain a valid version number in the format "x.y.z" where x, y, and z are integers. +# All other lines must be comments beginning with a "#", or a blank line. +# +# Every prior "minor" version for a given "major" (x.y) version is implicitly supported unless excluded by +# `xdscommon.UnsupportedEnvoyVersions`. For example, 1.28.3 implies support for 1.28.0, 1.28.1, and 1.28.2. +# +# See https://www.consul.io/docs/connect/proxies/envoy#supported-versions for more information on Consul's Envoy +# version support. +1.29.5 +1.28.4 +1.27.6 +1.26.8 \ No newline at end of file diff --git a/envoyextensions/xdscommon/envoy_versioning.go b/envoyextensions/xdscommon/envoy_versioning.go index c5f9d4798c..4b95e1bf2c 100644 --- a/envoyextensions/xdscommon/envoy_versioning.go +++ b/envoyextensions/xdscommon/envoy_versioning.go @@ -13,7 +13,7 @@ import ( var ( // minSupportedVersion is the oldest mainline version we support. This should always be // the zero'th point release of the last element of xdscommon.EnvoyVersions. - minSupportedVersion = version.Must(version.NewVersion(GetMinEnvoyMinorVersion())) + minSupportedVersion = version.Must(version.NewVersion(GetMinEnvoyMajorVersion())) specificUnsupportedVersions = []unsupportedVersion{} ) diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go index cca8f88f78..8b0b42fc8c 100644 --- a/envoyextensions/xdscommon/envoy_versioning_test.go +++ b/envoyextensions/xdscommon/envoy_versioning_test.go @@ -4,6 +4,8 @@ package xdscommon import ( + "fmt" + "slices" "testing" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" @@ -70,99 +72,53 @@ func TestDetermineEnvoyVersionFromNode(t *testing.T) { } func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { - const ( - errTooOld = "is too old and is not supported by Consul" - ) + const errTooOld = "is too old and is not supported by Consul" type testcase struct { + name string expect SupportedProxyFeatures expectErr string } + var cases []testcase - // Just the bad versions - cases := map[string]testcase{ - "1.9.0": {expectErr: "Envoy 1.9.0 " + errTooOld}, - "1.10.0": {expectErr: "Envoy 1.10.0 " + errTooOld}, - "1.11.0": {expectErr: "Envoy 1.11.0 " + errTooOld}, - "1.12.0": {expectErr: "Envoy 1.12.0 " + errTooOld}, - "1.12.1": {expectErr: "Envoy 1.12.1 " + errTooOld}, - "1.12.2": {expectErr: "Envoy 1.12.2 " + errTooOld}, - "1.12.3": {expectErr: "Envoy 1.12.3 " + errTooOld}, - "1.12.4": {expectErr: "Envoy 1.12.4 " + errTooOld}, - "1.12.5": {expectErr: "Envoy 1.12.5 " + errTooOld}, - "1.12.6": {expectErr: "Envoy 1.12.6 " + errTooOld}, - "1.12.7": {expectErr: "Envoy 1.12.7 " + errTooOld}, - "1.13.0": {expectErr: "Envoy 1.13.0 " + errTooOld}, - "1.13.1": {expectErr: "Envoy 1.13.1 " + errTooOld}, - "1.13.2": {expectErr: "Envoy 1.13.2 " + errTooOld}, - "1.13.3": {expectErr: "Envoy 1.13.3 " + errTooOld}, - "1.13.4": {expectErr: "Envoy 1.13.4 " + errTooOld}, - "1.13.5": {expectErr: "Envoy 1.13.5 " + errTooOld}, - "1.13.6": {expectErr: "Envoy 1.13.6 " + errTooOld}, - "1.13.7": {expectErr: "Envoy 1.13.7 " + errTooOld}, - "1.14.0": {expectErr: "Envoy 1.14.0 " + errTooOld}, - "1.14.1": {expectErr: "Envoy 1.14.1 " + errTooOld}, - "1.14.2": {expectErr: "Envoy 1.14.2 " + errTooOld}, - "1.14.3": {expectErr: "Envoy 1.14.3 " + errTooOld}, - "1.14.4": {expectErr: "Envoy 1.14.4 " + errTooOld}, - "1.14.5": {expectErr: "Envoy 1.14.5 " + errTooOld}, - "1.14.6": {expectErr: "Envoy 1.14.6 " + errTooOld}, - "1.14.7": {expectErr: "Envoy 1.14.7 " + errTooOld}, - "1.15.0": {expectErr: "Envoy 1.15.0 " + errTooOld}, - "1.15.1": {expectErr: "Envoy 1.15.1 " + errTooOld}, - "1.15.2": {expectErr: "Envoy 1.15.2 " + errTooOld}, - "1.15.3": {expectErr: "Envoy 1.15.3 " + errTooOld}, - "1.15.4": {expectErr: "Envoy 1.15.4 " + errTooOld}, - "1.15.5": {expectErr: "Envoy 1.15.5 " + errTooOld}, - "1.16.1": {expectErr: "Envoy 1.16.1 " + errTooOld}, - "1.16.2": {expectErr: "Envoy 1.16.2 " + errTooOld}, - "1.16.3": {expectErr: "Envoy 1.16.3 " + errTooOld}, - "1.16.4": {expectErr: "Envoy 1.16.4 " + errTooOld}, - "1.16.5": {expectErr: "Envoy 1.16.5 " + errTooOld}, - "1.16.6": {expectErr: "Envoy 1.16.6 " + errTooOld}, - "1.17.4": {expectErr: "Envoy 1.17.4 " + errTooOld}, - "1.18.6": {expectErr: "Envoy 1.18.6 " + errTooOld}, - "1.19.5": {expectErr: "Envoy 1.19.5 " + errTooOld}, - "1.20.7": {expectErr: "Envoy 1.20.7 " + errTooOld}, - "1.21.5": {expectErr: "Envoy 1.21.5 " + errTooOld}, - "1.22.0": {expectErr: "Envoy 1.22.0 " + errTooOld}, - "1.22.1": {expectErr: "Envoy 1.22.1 " + errTooOld}, - "1.22.2": {expectErr: "Envoy 1.22.2 " + errTooOld}, - "1.22.3": {expectErr: "Envoy 1.22.3 " + errTooOld}, - "1.22.4": {expectErr: "Envoy 1.22.4 " + errTooOld}, - "1.22.5": {expectErr: "Envoy 1.22.5 " + errTooOld}, - "1.22.6": {expectErr: "Envoy 1.22.6 " + errTooOld}, - "1.22.7": {expectErr: "Envoy 1.22.7 " + errTooOld}, - "1.22.8": {expectErr: "Envoy 1.22.8 " + errTooOld}, - "1.22.9": {expectErr: "Envoy 1.22.9 " + errTooOld}, - "1.22.10": {expectErr: "Envoy 1.22.10 " + errTooOld}, - "1.22.11": {expectErr: "Envoy 1.22.11 " + errTooOld}, + // Bad versions. + minMajorVersion := version.Must(version.NewVersion(getMinEnvoyVersion())) + minMajorVersionMajorPart := minMajorVersion.Segments()[len(minMajorVersion.Segments())-2] + for major := 9; major < minMajorVersionMajorPart; major++ { + for minor := 0; minor < 10; minor++ { + cases = append(cases, testcase{ + name: version.Must(version.NewVersion(fmt.Sprintf("1.%d.%d", major, minor))).String(), + expectErr: errTooOld, + }) + } } - // Insert a bunch of valid versions. - // Populate feature flags here when appropriate. See consul 1.10.x for reference. - /* Example from 1.18 - for _, v := range []string{ - "1.18.0", "1.18.1", "1.18.2", "1.18.3", "1.18.4", "1.18.5", "1.18.6", - } { - cases[v] = testcase{expect: SupportedProxyFeatures{ - ForceLDSandCDSToAlwaysUseWildcardsOnReconnect: true, - }} - } - */ - for _, v := range []string{ - "1.26.0", "1.26.1", "1.26.2", "1.26.3", "1.26.4", "1.26.5", "1.26.6", "1.26.7", "1.26.8", - "1.27.0", "1.27.1", "1.27.2", "1.27.3", "1.27.4", "1.27.5", "1.27.6", - "1.28.0", "1.28.1", "1.28.2", "1.28.3", "1.28.4", - "1.29.0", "1.29.1", "1.29.2", "1.29.3", "1.29.4", "1.29.5", - } { - cases[v] = testcase{expect: SupportedProxyFeatures{}} + // Good versions. + // Sort ascending so test output is ordered like bad cases above. + var supportedVersionsAscending []string + supportedVersionsAscending = append(supportedVersionsAscending, EnvoyVersions...) + slices.Reverse(supportedVersionsAscending) + for _, v := range supportedVersionsAscending { + envoyVersion := version.Must(version.NewVersion(v)) + // e.g. this is 27 in 1.27.4 + versionMajorPart := envoyVersion.Segments()[len(envoyVersion.Segments())-2] + // e.g. this is 4 in 1.27.4 + versionMinorPart := envoyVersion.Segments()[len(envoyVersion.Segments())-1] + + // Create synthetic minor versions from .0 through the actual configured version. + for minor := 0; minor <= versionMinorPart; minor++ { + minorVersion := version.Must(version.NewVersion(fmt.Sprintf("1.%d.%d", versionMajorPart, minor))) + cases = append(cases, testcase{ + name: minorVersion.String(), + expect: SupportedProxyFeatures{}, + }) + } } - for name, tc := range cases { + for _, tc := range cases { tc := tc - t.Run(name, func(t *testing.T) { - sf, err := DetermineSupportedProxyFeaturesFromString(name) + t.Run(tc.name, func(t *testing.T) { + sf, err := DetermineSupportedProxyFeaturesFromString(tc.name) if tc.expectErr == "" { require.NoError(t, err) require.Equal(t, tc.expect, sf) diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go index 77c1da0ad5..d0afcc7390 100644 --- a/envoyextensions/xdscommon/proxysupport.go +++ b/envoyextensions/xdscommon/proxysupport.go @@ -3,7 +3,64 @@ package xdscommon -import "strings" +import ( + _ "embed" + "fmt" + "slices" + "strconv" + "strings" +) + +// File containing the canonical range of supported Envoy versions for this version of Consul. +// This file should contain exactly one point release for each major release of Envoy, per line. +// All other contents must be blank lines or comments. Comments must be on their own line starting with '#'. +// +//go:embed ENVOY_VERSIONS +var envoyVersionsRaw string + +// initEnvoyVersions calls parseEnvoyVersions and panics if it returns an error. Used to set EnvoyVersions. +func initEnvoyVersions() []string { + versions, err := parseEnvoyVersions(envoyVersionsRaw) + if err != nil { + panic(err) + } + return versions +} + +// parseEnvoyVersions parses the ENVOY_VERSIONS file and returns a list of supported Envoy versions. +func parseEnvoyVersions(raw string) ([]string, error) { + lines := strings.Split(raw, "\n") + var versionLines []string + for _, line := range lines { + trimmed := strings.TrimSpace(line) + if trimmed == "" || strings.HasPrefix(trimmed, "#") { + continue // skip empty lines and comments + } + + // Assume all remaining lines are valid Envoy versions in the format "X.Y.Z". + versionParts := strings.Split(trimmed, ".") + if len(versionParts) != 3 { + return nil, fmt.Errorf("invalid version in ENVOY_VERSIONS: %s", line) + } + for _, v := range versionParts { + if _, err := strconv.Atoi(v); err != nil { + return nil, fmt.Errorf("invalid version in ENVOY_VERSIONS: %s", line) + } + } + versionLines = append(versionLines, trimmed) + } + + // Ensure sorted in descending order. + // We do this here as well as tests because other code (e.g. Makefile) may depend on the order + // of these values, so we want early detection in case tests are not run before compilation. + if !slices.IsSortedFunc(versionLines, func(v1, v2 string) int { + return strings.Compare(v2, v1) + }) { + return nil, fmt.Errorf("ENVOY_VERSIONS must be sorted in descending order") + } + + return versionLines, nil +} // EnvoyVersions lists the latest officially supported versions of envoy. // @@ -11,12 +68,7 @@ import "strings" // each major release should be present. // // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions -var EnvoyVersions = []string{ - "1.29.5", - "1.28.4", - "1.27.6", - "1.26.8", -} +var EnvoyVersions = initEnvoyVersions() // UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall // within the range of EnvoyVersions above. @@ -27,18 +79,28 @@ var EnvoyVersions = []string{ // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions var UnsupportedEnvoyVersions = []string{} -// GetMaxEnvoyMinorVersion grabs the first value in EnvoyVersions and strips the patch number off in order -// to return the maximum supported Envoy minor version +// GetMaxEnvoyMajorVersion grabs the first value in EnvoyVersions and strips the last number off in order +// to return the maximum supported Envoy "major" version. // For example, if the input string is "1.14.1", the function would return "1.14". -func GetMaxEnvoyMinorVersion() string { - s := strings.Split(EnvoyVersions[0], ".") +func GetMaxEnvoyMajorVersion() string { + s := strings.Split(getMaxEnvoyVersion(), ".") return s[0] + "." + s[1] } -// GetMinEnvoyMinorVersion grabs the last value in EnvoyVersions and strips the patch number off in order -// to return the minimum supported Envoy minor version +// GetMinEnvoyMajorVersion grabs the last value in EnvoyVersions and strips the patch number off in order +// to return the minimum supported Envoy "major" version. // For example, if the input string is "1.12.1", the function would return "1.12". -func GetMinEnvoyMinorVersion() string { - s := strings.Split(EnvoyVersions[len(EnvoyVersions)-1], ".") +func GetMinEnvoyMajorVersion() string { + s := strings.Split(getMinEnvoyVersion(), ".") return s[0] + "." + s[1] } + +// getMaxEnvoyVersion returns the first (highest) value in EnvoyVersions. +func getMaxEnvoyVersion() string { + return EnvoyVersions[0] +} + +// getMinEnvoyVersion returns the last (lowest) value in EnvoyVersions. +func getMinEnvoyVersion() string { + return EnvoyVersions[len(EnvoyVersions)-1] +} diff --git a/envoyextensions/xdscommon/proxysupport_test.go b/envoyextensions/xdscommon/proxysupport_test.go index cc90b726c9..d618478345 100644 --- a/envoyextensions/xdscommon/proxysupport_test.go +++ b/envoyextensions/xdscommon/proxysupport_test.go @@ -4,6 +4,7 @@ package xdscommon import ( + "slices" "sort" "testing" @@ -11,11 +12,17 @@ import ( "github.com/stretchr/testify/assert" ) +// TestProxySupportOrder tests that the values in EnvoyVersions are valid (X.Y.Z), contiguous by "major" (X.Y) version, +// and sorted in descending order. func TestProxySupportOrder(t *testing.T) { versions := make([]*version.Version, len(EnvoyVersions)) beforeSort := make([]*version.Version, len(EnvoyVersions)) for i, raw := range EnvoyVersions { v, _ := version.NewVersion(raw) + if v.Segments()[0] != 1 { + // If this fails, we need to add support for a new semver-major (x in x.y.z) version of Envoy + t.Fatalf("Expected major version to be 1, got: %v", v.Segments()[0]) + } versions[i] = v beforeSort[i] = v } @@ -30,4 +37,48 @@ func TestProxySupportOrder(t *testing.T) { for i := range EnvoyVersions { assert.True(t, versions[i].Equal(beforeSort[i])) } + + // Check that we have a continues set of versions + for i := 1; i < len(versions); i++ { + previousMajorVersion := getMajorVersion(versions[i-1]) + majorVersion := getMajorVersion(versions[i]) + assert.True(t, majorVersion == previousMajorVersion-1, + "Expected Envoy major version following %d.%d to be %d.%d, got %d.%d", + versions[i-1].Segments()[0], + previousMajorVersion, + versions[i-1].Segments()[0], + previousMajorVersion-1, + versions[i].Segments()[0], + majorVersion) + } +} + +func TestParseEnvoyVersions(t *testing.T) { + // Test with valid versions, comments, and blank lines + raw := "# Comment\n1.29.4\n\n# More\n# comments\n1.28.3\n\n1.27.5\n1.26.8\n\n" + expected := []string{"1.29.4", "1.28.3", "1.27.5", "1.26.8"} + + versions, err := parseEnvoyVersions(raw) + assert.NoError(t, err) + + if !slices.Equal(versions, expected) { + t.Fatalf("Expected %v, got: %v", expected, versions) + } + + // Test with invalid version + raw = "1.29.4\n1.26.8\nfoo" + + _, err = parseEnvoyVersions(raw) + assert.EqualError(t, err, "invalid version in ENVOY_VERSIONS: foo") + + // Test with out-of-order values + raw = "1.29.4\n1.26.8\n1.27.5" + + _, err = parseEnvoyVersions(raw) + assert.EqualError(t, err, "ENVOY_VERSIONS must be sorted in descending order") +} + +// getMajorVersion returns the "major" (Y in X.Y.Z) version of the given Envoy version. +func getMajorVersion(version *version.Version) int { + return version.Segments()[1] } diff --git a/test/integration/connect/envoy/helpers.bash b/test/integration/connect/envoy/helpers.bash index dad6508930..3efcd38e82 100755 --- a/test/integration/connect/envoy/helpers.bash +++ b/test/integration/connect/envoy/helpers.bash @@ -182,16 +182,6 @@ function assert_envoy_version { 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/" } diff --git a/test/integration/connect/envoy/run-tests.sh b/test/integration/connect/envoy/run-tests.sh index 1f825268b0..46dcb9965f 100755 --- a/test/integration/connect/envoy/run-tests.sh +++ b/test/integration/connect/envoy/run-tests.sh @@ -15,7 +15,10 @@ DEBUG=${DEBUG:-} XDS_TARGET=${XDS_TARGET:-server} # ENVOY_VERSION to run each test against -ENVOY_VERSION=${ENVOY_VERSION:-"1.29.5"} +if [[ -z "${ENVOY_VERSION:-}" ]]; then + echo "please set Envoy version via ENVOY_VERSION" + exit 1 +fi export ENVOY_VERSION export DOCKER_BUILDKIT=1 From a251f8ad80fec049cc5ab3e8e3c8ddf1ae9b7e2d Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Mon, 8 Jul 2024 10:34:00 -0400 Subject: [PATCH 096/185] fix(dns): spam ttl logs for prepared queries (#21381) --- .changelog/21381.txt | 4 ++++ agent/discovery/query_fetcher_v1.go | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changelog/21381.txt diff --git a/.changelog/21381.txt b/.changelog/21381.txt new file mode 100644 index 0000000000..e69989f032 --- /dev/null +++ b/.changelog/21381.txt @@ -0,0 +1,4 @@ +```release-note:bug +dns: Fixes a spam log message "Failed to parse TTL for prepared query..." +that was always being logged on each prepared query evaluation. +``` \ No newline at end of file diff --git a/agent/discovery/query_fetcher_v1.go b/agent/discovery/query_fetcher_v1.go index da76d744dd..31f74c0119 100644 --- a/agent/discovery/query_fetcher_v1.go +++ b/agent/discovery/query_fetcher_v1.go @@ -363,11 +363,12 @@ func (f *V1DataFetcher) FetchPreparedQuery(ctx Context, req *QueryPayload) ([]*R if err == nil { ttlSec := uint32(ttl / time.Second) ttlOverride = &ttlSec + } else { + f.logger.Warn("Failed to parse TTL for prepared query , ignoring", + "ttl", out.DNS.TTL, + "prepared_query", req.Name, + ) } - f.logger.Warn("Failed to parse TTL for prepared query , ignoring", - "ttl", out.DNS.TTL, - "prepared_query", req.Name, - ) } // If we have no nodes, return not found! From dce6241869b348a8ad03efd4f78c3ad0843ab409 Mon Sep 17 00:00:00 2001 From: Phil Renaud Date: Mon, 8 Jul 2024 16:36:29 -0400 Subject: [PATCH 097/185] [ui] File-specified deps for consul-ui (#21378) * Namespaced and file-specified deps * Pinning to a specific version of tailwind and setting config for js packages to come from npmjs * Pin glob instead of reverting tailwind or any other (grand)parent dependency * ember-cli-build fixed path resolution for now-namespaced submodules * Dropping the namespace prefix and relying on relative pathing --- .changelog/21378.txt | 3 + ui/.yarnrc | 1 + ui/package.json | 3 +- ui/packages/consul-ui/package.json | 10 +- ui/yarn.lock | 7898 +++++++++++++++------------- 5 files changed, 4126 insertions(+), 3789 deletions(-) create mode 100644 .changelog/21378.txt create mode 100644 ui/.yarnrc diff --git a/.changelog/21378.txt b/.changelog/21378.txt new file mode 100644 index 0000000000..c9fd8820dc --- /dev/null +++ b/.changelog/21378.txt @@ -0,0 +1,3 @@ +```release-note:security +ui: Pin and namespace sub-module dependencies related to the Consul UI +``` diff --git a/ui/.yarnrc b/ui/.yarnrc new file mode 100644 index 0000000000..19bac4f6d1 --- /dev/null +++ b/ui/.yarnrc @@ -0,0 +1 @@ +registry: https://registry.npmjs.org/ diff --git a/ui/package.json b/ui/package.json index ea0babf050..5fbcacd8e0 100644 --- a/ui/package.json +++ b/ui/package.json @@ -21,7 +21,8 @@ }, "resolutions": { "xmlhttprequest-ssl": "^1.6.3", - "ember-basic-dropdown": "3.0.21" + "ember-basic-dropdown": "3.0.21", + "glob": "7.2.3" }, "engines": { "node": "18" diff --git a/ui/packages/consul-ui/package.json b/ui/packages/consul-ui/package.json index 2218dc819f..76c2a55105 100644 --- a/ui/packages/consul-ui/package.json +++ b/ui/packages/consul-ui/package.json @@ -90,11 +90,11 @@ "broccoli-merge-trees": "^4.2.0", "chalk": "^4.1.0", "clipboard": "^2.0.11", - "consul-acls": "*", - "consul-lock-sessions": "*", - "consul-nspaces": "*", - "consul-partitions": "*", - "consul-peerings": "*", + "consul-acls": "file:../consul-acls", + "consul-lock-sessions": "file:../consul-lock-sessions", + "consul-nspaces": "file:../consul-nspaces", + "consul-partitions": "file:../consul-partitions", + "consul-peerings": "file:../consul-peerings", "css": "^3.0.0", "css.escape": "^1.5.1", "d3-array": "^2.8.0", diff --git a/ui/yarn.lock b/ui/yarn.lock index 225993b749..3f052af293 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2,395 +2,349 @@ # yarn lockfile v1 +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + "@ampproject/remapping@^2.2.0": - version "2.2.0" - resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + version "2.3.0" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" "@babel/code-frame@7.12.11": version "7.12.11" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz" - integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz#d23bbea508c3883ba8251fb4164982c36ea577ed" + integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw== "@babel/core@^7.0.0", "@babel/core@^7.1.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.10", "@babel/core@^7.13.8", "@babel/core@^7.16.7", "@babel/core@^7.2.2", "@babel/core@^7.3.4": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz" - integrity sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA== + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz#b676450141e0b52a3d43bc91da86aa608f950ac4" + integrity sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.21.0" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-module-transforms" "^7.21.0" - "@babel/helpers" "^7.21.0" - "@babel/parser" "^7.21.0" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.0" - "@babel/types" "^7.21.0" - convert-source-map "^1.7.0" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helpers" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/template" "^7.24.7" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" + json5 "^2.2.3" + semver "^6.3.1" -"@babel/generator@^7.21.0", "@babel/generator@^7.21.1": - version "7.21.1" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz" - integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA== +"@babel/generator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz#1654d01de20ad66b4b4d99c135471bc654c55e6d" + integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== dependencies: - "@babel/types" "^7.21.0" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" + "@babel/types" "^7.24.7" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== +"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" + integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz#37d66feb012024f2422b762b9b2a7cfe27c7fba3" + integrity sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" "@babel/helper-call-delegate@^7.10.1": version "7.12.13" - resolved "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.12.13.tgz" + resolved "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.12.13.tgz#119ef367451f90bed006c685816ba60fc33fee78" integrity sha512-K1kF0RXK/GpdS9OZDlBllG0+RQQtyzG/TC+nk0VkrUry4l4Xh2T7HdDsDOVlXQY/KcqvE/JQ84pKjKucdrg3FQ== dependencies: "@babel/helper-hoist-variables" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.12.0", "@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0", "@babel/helper-compilation-targets@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz" - integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== +"@babel/helper-compilation-targets@^7.12.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz#4eb6c4a80d6ffeac25ab8cd9a21b5dfa48d503a9" + integrity sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg== dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" + "@babel/compat-data" "^7.24.7" + "@babel/helper-validator-option" "^7.24.7" + browserslist "^4.22.2" lru-cache "^5.1.1" - semver "^6.3.0" + semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.8.3": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz" - integrity sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.24.7", "@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.8.3": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz#2eaed36b3a1c11c53bdf80d53838b293c52f5b3b" + integrity sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-member-expression-to-functions" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.7" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz" - integrity sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz#be4f435a80dc2b053c76eeb4b7d16dd22cfc89da" + integrity sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.24.7" regexpu-core "^5.3.1" + semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== +"@babel/helper-define-polyfill-provider@^0.6.1", "@babel/helper-define-polyfill-provider@^0.6.2": + version "0.6.2" + resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" + integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== +"@babel/helper-environment-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" + integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== +"@babel/helper-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" + integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helper-hoist-variables@^7.12.13", "@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== +"@babel/helper-hoist-variables@^7.12.13", "@babel/helper-hoist-variables@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" + integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz" - integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== +"@babel/helper-member-expression-to-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz#67613d068615a70e4ed5101099affc7a41c5225f" + integrity sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w== dependencies: - "@babel/types" "^7.21.0" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.8.3": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== +"@babel/helper-module-imports@^7.24.7", "@babel/helper-module-imports@^7.8.3": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== dependencies: - "@babel/types" "^7.18.6" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.0", "@babel/helper-module-transforms@^7.21.2": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz" - integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== +"@babel/helper-module-transforms@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz#31b6c9a2930679498db65b685b1698bfd6c7daf8" + integrity sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.2" - "@babel/types" "^7.21.2" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== +"@babel/helper-optimise-call-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" + integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0" + integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg== -"@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== +"@babel/helper-remap-async-to-generator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz#b3f0f203628522713849d49403f1a414468be4c7" + integrity sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-wrap-function" "^7.24.7" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz" - integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== +"@babel/helper-replace-supers@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz#f933b7eed81a1c0265740edc91491ce51250f765" + integrity sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.7" + "@babel/helper-optimise-call-expression" "^7.24.7" -"@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== dependencies: - "@babel/types" "^7.20.2" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" + integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== dependencies: - "@babel/types" "^7.20.0" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helper-split-export-declaration@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" + integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== +"@babel/helper-string-parser@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2" + integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== -"@babel/helper-validator-option@^7.18.6": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz" - integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== +"@babel/helper-validator-option@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6" + integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw== -"@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz" - integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== +"@babel/helper-wrap-function@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz#52d893af7e42edca7c6d2c6764549826336aae1f" + integrity sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw== dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" + "@babel/helper-function-name" "^7.24.7" + "@babel/template" "^7.24.7" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helpers@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz" - integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== +"@babel/helpers@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz#aa2ccda29f62185acb5d42fb4a3a1b1082107416" + integrity sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg== dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.0" - "@babel/types" "^7.21.0" + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" js-tokens "^4.0.0" + picocolors "^1.0.0" -"@babel/parser@^7.12.3", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0", "@babel/parser@^7.21.2", "@babel/parser@^7.4.5", "@babel/parser@^7.7.0": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz" - integrity sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ== +"@babel/parser@^7.12.3", "@babel/parser@^7.14.7", "@babel/parser@^7.24.7", "@babel/parser@^7.4.5", "@babel/parser@^7.7.0": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" + integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz#fd059fd27b184ea2b4c7e646868a9a381bbc3055" + integrity sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz#468096ca44bbcbe8fcc570574e12eb1950e18107" + integrity sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz#e4eabdd5109acc399b38d7999b2ef66fc2022f89" + integrity sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/plugin-transform-optional-chaining" "^7.24.7" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz#71b21bb0286d5810e63a1538aa901c58e87375ec" + integrity sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.10.1", "@babel/plugin-proposal-class-properties@^7.16.5", "@babel/plugin-proposal-class-properties@^7.16.7": version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz" - integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.7" - -"@babel/plugin-proposal-async-generator-functions@^7.20.1": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz" - integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.10.1", "@babel/plugin-proposal-class-properties@^7.16.5", "@babel/plugin-proposal-class-properties@^7.16.7", "@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz" - integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw== +"@babel/plugin-proposal-decorators@^7.13.5", "@babel/plugin-proposal-decorators@^7.16.7", "@babel/plugin-proposal-decorators@^7.20.13": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz#7e2dcfeda4a42596b57c4c9de1f5176bbfc532e3" + integrity sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-decorators" "^7.24.7" -"@babel/plugin-proposal-decorators@^7.13.5", "@babel/plugin-proposal-decorators@^7.16.7": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz" - integrity sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.21.0" - -"@babel/plugin-proposal-dynamic-import@^7.18.6": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.4.4": version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz" - integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6", "@babel/plugin-proposal-nullish-coalescing-operator@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.20.2", "@babel/plugin-proposal-object-rest-spread@^7.5.5": +"@babel/plugin-proposal-object-rest-spread@^7.5.5": version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== dependencies: "@babel/compat-data" "^7.20.5" @@ -399,435 +353,567 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.20.7" -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - -"@babel/plugin-proposal-optional-chaining@^7.18.9", "@babel/plugin-proposal-optional-chaining@^7.20.7", "@babel/plugin-proposal-optional-chaining@^7.6.0": +"@babel/plugin-proposal-optional-chaining@^7.6.0": version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== dependencies: "@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.16.5", "@babel/plugin-proposal-private-methods@^7.18.6": +"@babel/plugin-proposal-private-methods@^7.16.5", "@babel/plugin-proposal-private-methods@^7.16.7": version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== dependencies: "@babel/helper-create-class-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-private-property-in-object@^7.16.5", "@babel/plugin-proposal-private-property-in-object@^7.18.6": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz" - integrity sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw== +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-proposal-private-property-in-object@^7.16.5", "@babel/plugin-proposal-private-property-in-object@^7.20.5": + version "7.21.11" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" + integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== dependencies: "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-create-class-features-plugin" "^7.21.0" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz" - integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-class-static-block@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.21.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz" - integrity sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w== +"@babel/plugin-syntax-decorators@^7.23.3", "@babel/plugin-syntax-decorators@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz#e4f8a0a8778ccec669611cd5aed1ed8e6e3a6fcf" + integrity sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== +"@babel/plugin-syntax-import-assertions@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz#2a0b406b5871a20a841240586b1300ce2088a778" + integrity sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz#b4f9ea95a79e6912480c4b626739f86a076624ca" + integrity sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-private-property-in-object@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-top-level-await@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.2.0", "@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.8.3": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz" - integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== +"@babel/plugin-syntax-typescript@^7.2.0", "@babel/plugin-syntax-typescript@^7.24.7", "@babel/plugin-syntax-typescript@^7.8.3": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz#58d458271b4d3b6bb27ee6ac9525acbb259bad1c" + integrity sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-arrow-functions@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz" - integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz" - integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== - dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - -"@babel/plugin-transform-block-scoped-functions@^7.18.6": +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-block-scoping@^7.20.2", "@babel/plugin-transform-block-scoping@^7.8.3": - version "7.23.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz" - integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-classes@^7.20.2": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz" - integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz" - integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/template" "^7.20.7" - -"@babel/plugin-transform-destructuring@^7.20.2": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz" - integrity sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + resolved "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-arrow-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz#4f6886c11e423bd69f3ce51dbf42424a5f275514" + integrity sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-async-generator-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz#7330a5c50e05181ca52351b8fd01642000c96cfd" + integrity sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-remap-async-to-generator" "^7.24.7" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-for-of@^7.18.8": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz" - integrity sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ== +"@babel/plugin-transform-async-to-generator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz#72a3af6c451d575842a7e9b5a02863414355bdcc" + integrity sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-remap-async-to-generator" "^7.24.7" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-block-scoped-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz#a4251d98ea0c0f399dafe1a35801eaba455bbf1f" + integrity sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-block-scoping@^7.24.7", "@babel/plugin-transform-block-scoping@^7.8.3": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz#42063e4deb850c7bd7c55e626bf4e7ab48e6ce02" + integrity sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-class-properties@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz#256879467b57b0b68c7ddfc5b76584f398cd6834" + integrity sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.13.0", "@babel/plugin-transform-modules-amd@^7.19.6": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz" - integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g== +"@babel/plugin-transform-class-static-block@^7.16.7", "@babel/plugin-transform-class-static-block@^7.22.11", "@babel/plugin-transform-class-static-block@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz#c82027ebb7010bc33c116d4b5044fbbf8c05484d" + integrity sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ== dependencies: - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-modules-commonjs@^7.19.6": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz" - integrity sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA== +"@babel/plugin-transform-classes@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.7.tgz#4ae6ef43a12492134138c1e45913f7c46c41b4bf" + integrity sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw== dependencies: - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + globals "^11.1.0" -"@babel/plugin-transform-modules-systemjs@^7.19.6": - version "7.20.11" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz" - integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw== +"@babel/plugin-transform-computed-properties@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz#4cab3214e80bc71fae3853238d13d097b004c707" + integrity sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/template" "^7.24.7" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-destructuring@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.7.tgz#a097f25292defb6e6cc16d6333a4cfc1e3c72d9e" + integrity sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz" - integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== +"@babel/plugin-transform-dotall-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz#5f8bf8a680f2116a7207e16288a5f974ad47a7a0" + integrity sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-duplicate-keys@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz#dd20102897c9a2324e5adfffb67ff3610359a8ee" + integrity sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-dynamic-import@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz#4d8b95e3bae2b037673091aa09cd33fecd6419f4" + integrity sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz#b629ee22645f412024297d5245bce425c31f9b0d" + integrity sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-export-namespace-from@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz#176d52d8d8ed516aeae7013ee9556d540c53f197" + integrity sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" + integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + +"@babel/plugin-transform-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz#6d8601fbffe665c894440ab4470bc721dd9131d6" + integrity sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w== + dependencies: + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-json-strings@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz#f3e9c37c0a373fee86e36880d45b3664cedaf73a" + integrity sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-transform-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz#36b505c1e655151a9d7607799a9988fc5467d06c" + integrity sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-logical-assignment-operators@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" + integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz#3b4454fb0e302e18ba4945ba3246acb1248315df" + integrity sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.13.0", "@babel/plugin-transform-modules-amd@^7.20.11", "@babel/plugin-transform-modules-amd@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz#65090ed493c4a834976a3ca1cde776e6ccff32d7" + integrity sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg== + dependencies: + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-modules-commonjs@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz#9fd5f7fdadee9085886b183f1ad13d1ab260f4ab" + integrity sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ== + dependencies: + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + +"@babel/plugin-transform-modules-systemjs@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz#f8012316c5098f6e8dee6ecd58e2bc6f003d0ce7" + integrity sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw== + dependencies: + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + +"@babel/plugin-transform-modules-umd@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz#edd9f43ec549099620df7df24e7ba13b5c76efc8" + integrity sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A== + dependencies: + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz#9042e9b856bc6b3688c0c2e4060e9e10b1460923" + integrity sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-new-target@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz#31ff54c4e0555cc549d5816e4ab39241dfb6ab00" + integrity sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" + integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" + integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-transform-object-assign@^7.8.3": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.18.6.tgz" - integrity sha512-mQisZ3JfqWh2gVXvfqYCAAyRs6+7oev+myBsTwW5RnPhYXOTuCEw2oe3YgxlXMViXUS53lG8koulI7mJ+8JE+A== + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.24.7.tgz#9d2cc7ee1482bd208fcc51974ca4f7649662c899" + integrity sha512-DOzAi77P9jSyPijHS7Z8vH0wLRcZH6wWxuIZgLAiy8FWOkcKMJmnyHjy2JM94k6A0QxlA/hlLh+R9T3GEryjNQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-object-rest-spread@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" + integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.24.7" -"@babel/plugin-transform-parameters@^7.20.1", "@babel/plugin-transform-parameters@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz" - integrity sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA== +"@babel/plugin-transform-object-super@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz#66eeaff7830bba945dd8989b632a40c04ed625be" + integrity sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-optional-catch-binding@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" + integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.20.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz" - integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ== +"@babel/plugin-transform-optional-chaining@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.7.tgz#b8f6848a80cf2da98a8a204429bec04756c6d454" + integrity sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - regenerator-transform "^0.15.1" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" + integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-private-methods@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz#e6318746b2ae70a59d023d5cc1344a2ba7a75f5e" + integrity sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-private-property-in-object@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz#4eec6bc701288c1fab5f72e6a4bbc9d67faca061" + integrity sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz#f0d2ed8380dfbed949c42d4d790266525d63bbdc" + integrity sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-regenerator@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" + integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz#80037fe4fbf031fc1125022178ff3938bb3743a4" + integrity sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-transform-runtime@^7.12.1", "@babel/plugin-transform-runtime@^7.13.9": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz" - integrity sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg== + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz#00a5bfaf8c43cf5c8703a8a6e82b59d9c58f38ca" + integrity sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.1" + babel-plugin-polyfill-regenerator "^0.6.1" + semver "^6.3.1" -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-shorthand-properties@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz#85448c6b996e122fa9e289746140aaa99da64e73" + integrity sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-spread@^7.19.0": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz" - integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== +"@babel/plugin-transform-spread@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz#e8a38c0fde7882e0fb8f160378f74bd885cc7bb3" + integrity sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== +"@babel/plugin-transform-sticky-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz#96ae80d7a7e5251f657b5cf18f1ea6bf926f5feb" + integrity sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/plugin-transform-template-literals@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz#a05debb4a9072ae8f985bcf77f3f215434c8f8c8" + integrity sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/plugin-transform-typeof-symbol@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.7.tgz#f074be466580d47d6e6b27473a840c9f9ca08fb0" + integrity sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-typescript@^7.13.0": - version "7.21.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz" - integrity sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg== +"@babel/plugin-transform-typescript@^7.13.0", "@babel/plugin-transform-typescript@^7.20.13": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz#b006b3e0094bf0813d505e0c5485679eeaf4a881" + integrity sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-typescript" "^7.20.0" + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-typescript" "^7.24.7" "@babel/plugin-transform-typescript@~7.4.0": version "7.4.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz#ab3351ba35307b79981993536c93ff8be050ba28" integrity sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -835,7 +921,7 @@ "@babel/plugin-transform-typescript@~7.5.0": version "7.5.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== dependencies: "@babel/helper-create-class-features-plugin" "^7.5.5" @@ -844,68 +930,74 @@ "@babel/plugin-transform-typescript@~7.8.0": version "7.8.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.7.tgz" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.7.tgz#48bccff331108a7b3a28c3a4adc89e036dc3efda" integrity sha512-7O0UsPQVNKqpHeHLpfvOG4uXmlw+MOxYvUv6Otc9uH5SYMIxvF6eBdjkWvC3f9G+VXe0RsNExyAQBeTRug/wqQ== dependencies: "@babel/helper-create-class-features-plugin" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-typescript" "^7.8.3" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/plugin-transform-unicode-escapes@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz#2023a82ced1fb4971630a2e079764502c4148e0e" + integrity sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@babel/plugin-transform-unicode-property-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz#9073a4cd13b86ea71c3264659590ac086605bbcd" + integrity sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-unicode-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz#dfc3d4a51127108099b19817c0963be6a2adf19f" + integrity sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-transform-unicode-sets-regex@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz#d40705d67523803a576e29c63cef6e516b858ed9" + integrity sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/polyfill@^7.11.5": version "7.12.1" - resolved "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz" + resolved "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz#1f2d6371d1261bbd961f3c5d5909150e12d0bd96" integrity sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g== dependencies: core-js "^2.6.5" regenerator-runtime "^0.13.4" -"@babel/preset-env@^7.10.2", "@babel/preset-env@^7.16.5", "@babel/preset-env@^7.16.7": - version "7.20.2" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz" - integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== +"@babel/preset-env@^7.10.2", "@babel/preset-env@^7.16.5", "@babel/preset-env@^7.16.7", "@babel/preset-env@^7.20.2": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz#ff067b4e30ba4a72f225f12f123173e77b987f37" + integrity sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ== dependencies: - "@babel/compat-data" "^7.20.1" - "@babel/helper-compilation-targets" "^7.20.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.20.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/compat-data" "^7.24.7" + "@babel/helper-compilation-targets" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-validator-option" "^7.24.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.7" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-import-assertions" "^7.24.7" + "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -915,113 +1007,127 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.20.2" - "@babel/plugin-transform-classes" "^7.20.2" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.20.2" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.19.6" - "@babel/plugin-transform-modules-commonjs" "^7.19.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.6" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.20.1" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.24.7" + "@babel/plugin-transform-async-generator-functions" "^7.24.7" + "@babel/plugin-transform-async-to-generator" "^7.24.7" + "@babel/plugin-transform-block-scoped-functions" "^7.24.7" + "@babel/plugin-transform-block-scoping" "^7.24.7" + "@babel/plugin-transform-class-properties" "^7.24.7" + "@babel/plugin-transform-class-static-block" "^7.24.7" + "@babel/plugin-transform-classes" "^7.24.7" + "@babel/plugin-transform-computed-properties" "^7.24.7" + "@babel/plugin-transform-destructuring" "^7.24.7" + "@babel/plugin-transform-dotall-regex" "^7.24.7" + "@babel/plugin-transform-duplicate-keys" "^7.24.7" + "@babel/plugin-transform-dynamic-import" "^7.24.7" + "@babel/plugin-transform-exponentiation-operator" "^7.24.7" + "@babel/plugin-transform-export-namespace-from" "^7.24.7" + "@babel/plugin-transform-for-of" "^7.24.7" + "@babel/plugin-transform-function-name" "^7.24.7" + "@babel/plugin-transform-json-strings" "^7.24.7" + "@babel/plugin-transform-literals" "^7.24.7" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" + "@babel/plugin-transform-member-expression-literals" "^7.24.7" + "@babel/plugin-transform-modules-amd" "^7.24.7" + "@babel/plugin-transform-modules-commonjs" "^7.24.7" + "@babel/plugin-transform-modules-systemjs" "^7.24.7" + "@babel/plugin-transform-modules-umd" "^7.24.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" + "@babel/plugin-transform-new-target" "^7.24.7" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" + "@babel/plugin-transform-numeric-separator" "^7.24.7" + "@babel/plugin-transform-object-rest-spread" "^7.24.7" + "@babel/plugin-transform-object-super" "^7.24.7" + "@babel/plugin-transform-optional-catch-binding" "^7.24.7" + "@babel/plugin-transform-optional-chaining" "^7.24.7" + "@babel/plugin-transform-parameters" "^7.24.7" + "@babel/plugin-transform-private-methods" "^7.24.7" + "@babel/plugin-transform-private-property-in-object" "^7.24.7" + "@babel/plugin-transform-property-literals" "^7.24.7" + "@babel/plugin-transform-regenerator" "^7.24.7" + "@babel/plugin-transform-reserved-words" "^7.24.7" + "@babel/plugin-transform-shorthand-properties" "^7.24.7" + "@babel/plugin-transform-spread" "^7.24.7" + "@babel/plugin-transform-sticky-regex" "^7.24.7" + "@babel/plugin-transform-template-literals" "^7.24.7" + "@babel/plugin-transform-typeof-symbol" "^7.24.7" + "@babel/plugin-transform-unicode-escapes" "^7.24.7" + "@babel/plugin-transform-unicode-property-regex" "^7.24.7" + "@babel/plugin-transform-unicode-regex" "^7.24.7" + "@babel/plugin-transform-unicode-sets-regex" "^7.24.7" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.4" + babel-plugin-polyfill-regenerator "^0.6.1" + core-js-compat "^3.31.0" + semver "^6.3.1" -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" "@babel/types" "^7.4.4" esutils "^2.0.2" "@babel/regjsgen@^0.8.0": version "0.8.0" - resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" + resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@7.12.18", "@babel/runtime@^7.12.5", "@babel/runtime@^7.8.4": +"@babel/runtime@7.12.18": version "7.12.18" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.18.tgz" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.18.tgz#af137bd7e7d9705a412b3caaf991fe6aaa97831b" integrity sha512-BogPQ7ciE6SYAUPtlm9tWbgI9+2AgqSam6QivMgXgAT+fKbgppaj4ZX15MHeLC1PVF5sNk70huBu20XxWOs8Cg== dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.17.8": - version "7.23.2" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz" - integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== +"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.8.4": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" + integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.18.10", "@babel/template@^7.20.7": - version "7.20.7" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== +"@babel/template@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" + integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.1", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz" - integrity sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw== +"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.1", "@babel/traverse@^7.24.7", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5" + integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.21.1" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.21.2" - "@babel/types" "^7.21.2" - debug "^4.1.0" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.1.6", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": - version "7.21.2" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz" - integrity sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw== +"@babel/types@^7.1.6", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.24.7", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.7.2": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2" + integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-string-parser" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" "@cnakazawa/watch@^1.0.3": version "1.0.4" - resolved "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz" + resolved "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== dependencies: exec-sh "^0.3.2" @@ -1029,26 +1135,26 @@ "@colors/colors@1.5.0": version "1.5.0" - resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" + resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== "@csstools/postcss-sass@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@csstools/postcss-sass/-/postcss-sass-5.0.1.tgz" - integrity sha512-GgQAOe6KfABEIHGh9KFqn/7sX2Dmx554PElvyhRFNADo2QV2N/CzlS+QHrrJmVJzaBn829f4JFcOd67mmYb5Eg== + version "5.1.1" + resolved "https://registry.npmjs.org/@csstools/postcss-sass/-/postcss-sass-5.1.1.tgz#135921df13bc56bee50c7470a66e4e9f3d5c89ae" + integrity sha512-La7bgTcM6YwPBLqlaXg7lMLry82iLv1a+S1RmgvHq2mH2Zd57L2anjZvJC8ACUHWc4M9fXws93dq6gaK0kZyAw== dependencies: "@csstools/sass-import-resolve" "^1.0.0" - sass "^1.49.7" - source-map "~0.7.3" + sass "^1.69.5" + source-map "~0.7.4" "@csstools/sass-import-resolve@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz" + resolved "https://registry.npmjs.org/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz#32c3cdb2f7af3cd8f0dca357b592e7271f3831b5" integrity sha512-pH4KCsbtBLLe7eqUrw8brcuFO8IZlN36JjdKlOublibVdAIPHCzEnpBWOVUXK5sCf+DpBi8ZtuWtjF0srybdeA== "@docfy/core@^0.4.4": version "0.4.4" - resolved "https://registry.npmjs.org/@docfy/core/-/core-0.4.4.tgz" + resolved "https://registry.npmjs.org/@docfy/core/-/core-0.4.4.tgz#041157870abcde99e64068cdbd79767b2c1a97b4" integrity sha512-m1q0KsRQZepXO5xZouOPXH9K8KJS7lnM6eDutHbYJsiUOG8e4ZpYYGJ+ckOTGzLKSXJGYFoRJRxO82Y9yaPhMA== dependencies: debug "^4.3.1" @@ -1074,7 +1180,7 @@ "@docfy/ember@^0.4.1": version "0.4.8" - resolved "https://registry.npmjs.org/@docfy/ember/-/ember-0.4.8.tgz" + resolved "https://registry.npmjs.org/@docfy/ember/-/ember-0.4.8.tgz#8fe3c525b0d44790bdc801bc3b5f588a27c840bd" integrity sha512-IxkLQJp4/pn4HvW6mxnd9ezErbrKM5i/maNUPCa3ixxFgPFMWRmwn05EP+6Y2ZAqOHaJXtkDMxllCg6tdFFFBQ== dependencies: "@docfy/core" "^0.4.4" @@ -1099,7 +1205,7 @@ "@ember-data/adapter@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/adapter/-/adapter-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/adapter/-/adapter-3.28.13.tgz#3b921365046a329f3eb1c72fc4964c6aff06e53b" integrity sha512-AwLJTs+GvxX72vfP3edV0hoMLD9oPWJNbnqxakXVN9xGTuk6/TeGQLMrVU3222GCoMMNrJ357Nip7kZeFo4IdA== dependencies: "@ember-data/private-build-infra" "3.28.13" @@ -1112,7 +1218,7 @@ "@ember-data/canary-features@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/canary-features/-/canary-features-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/canary-features/-/canary-features-3.28.13.tgz#59cd75b94bfff86f85affb42e66016c71f45f02e" integrity sha512-fgpcB0wmtUjZeqcIKkfP/MclQjY5r8ft8YZhPlvQh2MIx+3d3nCNRXB6lEUdRdQphFEag2towONFEIsiOAgs3Q== dependencies: ember-cli-babel "^7.26.6" @@ -1120,7 +1226,7 @@ "@ember-data/debug@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/debug/-/debug-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/debug/-/debug-3.28.13.tgz#eb20779de83429f5d493d3c8e81ced468fa5974d" integrity sha512-ofny/Grpqx1lM6KWy5q75/b2/B+zQ4B4Ynk7SrQ//sFvpX3gjuP8iN07SKTHSN07vedlC+7QNhNJdCQwyqK1Fg== dependencies: "@ember-data/private-build-infra" "3.28.13" @@ -1132,7 +1238,7 @@ "@ember-data/model@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/model/-/model-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/model/-/model-3.28.13.tgz#50ac1bd5783e7cc51344767d5ff46f84198f4d1a" integrity sha512-V5Hgzz5grNWTSrKGksY9xeOsTDLN/d3qsVMu26FWWHP5uqyWT0Cd4LSRpNxs14PsTFDcbrtGKaZv3YVksZfFEQ== dependencies: "@ember-data/canary-features" "3.28.13" @@ -1150,7 +1256,7 @@ "@ember-data/private-build-infra@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/private-build-infra/-/private-build-infra-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/private-build-infra/-/private-build-infra-3.28.13.tgz#828a27e724240b1ef70ae5dd8ab8be1f61275929" integrity sha512-8gT3/gnmbNgFIMVdHBpl3xFGJefJE26VUIidFHTF1/N1aumVUlEhnXH0BSPxvxTnFXz/klGSTOMs+sDsx3jw6A== dependencies: "@babel/plugin-transform-block-scoping" "^7.8.3" @@ -1182,7 +1288,7 @@ "@ember-data/record-data@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/record-data/-/record-data-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/record-data/-/record-data-3.28.13.tgz#2bf169404732e126489d3b3a8dc6c0dfca8b5f5f" integrity sha512-0qYOxQr901eZ0JoYVt/IiszZYuNefqO6yiwKw0VH2dmWhVniQSp+Da9YnoKN9U2KgR4NdxKiUs2j9ZLNZ+bH7g== dependencies: "@ember-data/canary-features" "3.28.13" @@ -1195,12 +1301,12 @@ "@ember-data/rfc395-data@^0.0.4": version "0.0.4" - resolved "https://registry.npmjs.org/@ember-data/rfc395-data/-/rfc395-data-0.0.4.tgz" + resolved "https://registry.npmjs.org/@ember-data/rfc395-data/-/rfc395-data-0.0.4.tgz#ecb86efdf5d7733a76ff14ea651a1b0ed1f8a843" integrity sha512-tGRdvgC9/QMQSuSuJV45xoyhI0Pzjm7A9o/MVVA3HakXIImJbbzx/k/6dO9CUEQXIyS2y0fW6C1XaYOG7rY0FQ== "@ember-data/serializer@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/serializer/-/serializer-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/serializer/-/serializer-3.28.13.tgz#6dfa8ba17c0ea192313134643dbe56adf45a722a" integrity sha512-BlYXi8ObH0B5G7QeWtkf9u8PrhdlfAxOAsOuOPZPCTzWsQlmyzV6M9KvBmIAvJtM2IQ3a5BX2o71eP6/7MJDUg== dependencies: "@ember-data/private-build-infra" "3.28.13" @@ -1211,7 +1317,7 @@ "@ember-data/store@3.28.13": version "3.28.13" - resolved "https://registry.npmjs.org/@ember-data/store/-/store-3.28.13.tgz" + resolved "https://registry.npmjs.org/@ember-data/store/-/store-3.28.13.tgz#be3c3fca03d155767af72422f6a3c6dcd6147be8" integrity sha512-y1ddWLfR20l3NN9fNfIAFWCmREnC6hjKCZERDgkvBgZOCAKcs+6bVJGyMmKBcsp4W7kanqKn71tX7Y63jp+jXQ== dependencies: "@ember-data/canary-features" "3.28.13" @@ -1225,7 +1331,7 @@ "@ember-decorators/component@^6.1.1": version "6.1.1" - resolved "https://registry.npmjs.org/@ember-decorators/component/-/component-6.1.1.tgz" + resolved "https://registry.npmjs.org/@ember-decorators/component/-/component-6.1.1.tgz#b360dc4fa8e576ee1c840879399ef1745fd96e06" integrity sha512-Cj8tY/c0MC/rsipqsiWLh3YVN72DK92edPYamD/HzvftwzC6oDwawWk8RmStiBnG9PG/vntAt41l3S7HSSA+1Q== dependencies: "@ember-decorators/utils" "^6.1.1" @@ -1233,7 +1339,7 @@ "@ember-decorators/object@^6.1.1": version "6.1.1" - resolved "https://registry.npmjs.org/@ember-decorators/object/-/object-6.1.1.tgz" + resolved "https://registry.npmjs.org/@ember-decorators/object/-/object-6.1.1.tgz#50c922f5ac9af3ddd381cb6a43a031dfd9a70c7a" integrity sha512-cb4CNR9sRoA31J3FCOFLDuR9ztM4wO9w1WlS4JeNRS7Z69SlB/XSXB/vplA3i9OOaXEy/zKWbu5ndZrHz0gvLw== dependencies: "@ember-decorators/utils" "^6.1.1" @@ -1241,31 +1347,31 @@ "@ember-decorators/utils@^6.1.0", "@ember-decorators/utils@^6.1.1": version "6.1.1" - resolved "https://registry.npmjs.org/@ember-decorators/utils/-/utils-6.1.1.tgz" + resolved "https://registry.npmjs.org/@ember-decorators/utils/-/utils-6.1.1.tgz#6b619814942b4fb3747cfa9f540c9f05283d7c5e" integrity sha512-0KqnoeoLKb6AyoSU65TRF5T85wmS4uDn06oARddwNPxxf/lt5jQlh41uX3W7V/fWL9tPu8x1L1Vvpc80MN1+YA== dependencies: ember-cli-babel "^7.1.3" "@ember/edition-utils@^1.2.0": version "1.2.0" - resolved "https://registry.npmjs.org/@ember/edition-utils/-/edition-utils-1.2.0.tgz" + resolved "https://registry.npmjs.org/@ember/edition-utils/-/edition-utils-1.2.0.tgz#a039f542dc14c8e8299c81cd5abba95e2459cfa6" integrity sha512-VmVq/8saCaPdesQmftPqbFtxJWrzxNGSQ+e8x8LLe3Hjm36pJ04Q8LeORGZkAeOhldoUX9seLGmSaHeXkIqoog== "@ember/optional-features@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@ember/optional-features/-/optional-features-2.0.0.tgz" - integrity sha512-4gkvuGRYfpAh1nwAz306cmMeC1mG7wxZnbsBZ09mMaMX/W7IyKOKc/38JwrDPUFUalmNEM7q7JEPcmew2M3Dog== + version "2.1.0" + resolved "https://registry.npmjs.org/@ember/optional-features/-/optional-features-2.1.0.tgz#8e15672ca342b5ca6d4d8a00558dc696db0d6f16" + integrity sha512-IXjDpTFhsjPk9h3OXwXjlRfhM/Wjtw2E71Xos/81ZsTTwZMB9H+DWhsxePXOkzYy7Jvw4TIzKbMfcnT8mrtwWQ== dependencies: - chalk "^4.1.0" - ember-cli-version-checker "^5.1.1" - glob "^7.1.6" + chalk "^4.1.2" + ember-cli-version-checker "^5.1.2" + glob "^7.1.7" inquirer "^7.3.3" mkdirp "^1.0.4" silent-error "^1.1.1" "@ember/render-modifiers@^1.0.2": version "1.0.2" - resolved "https://registry.npmjs.org/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz" + resolved "https://registry.npmjs.org/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz#2e87c48db49d922ce4850d707215caaac60d8444" integrity sha512-6tEnHl5+62NTSAG2mwhGMFPhUrJQjoVqV+slsn+rlTknm2Zik+iwxBQEbwaiQOU1FUYxkS8RWcieovRNMR8inQ== dependencies: ember-cli-babel "^7.10.0" @@ -1273,24 +1379,24 @@ "@ember/render-modifiers@^2.0.0", "@ember/render-modifiers@^2.0.5": version "2.1.0" - resolved "https://registry.npmjs.org/@ember/render-modifiers/-/render-modifiers-2.1.0.tgz" + resolved "https://registry.npmjs.org/@ember/render-modifiers/-/render-modifiers-2.1.0.tgz#f4fff95a8b5cfbe947ec46644732d511711c5bf9" integrity sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ== dependencies: "@embroider/macros" "^1.0.0" ember-cli-babel "^7.26.11" ember-modifier-manager-polyfill "^1.2.0" -"@ember/string@^3.0.0": +"@ember/string@^3.0.0", "@ember/string@^3.1.1": version "3.1.1" - resolved "https://registry.npmjs.org/@ember/string/-/string-3.1.1.tgz" + resolved "https://registry.npmjs.org/@ember/string/-/string-3.1.1.tgz#0a5ac0d1e4925259e41d5c8d55ef616117d47ff0" integrity sha512-UbXJ+k3QOrYN4SRPHgXCqYIJ+yWWUg1+vr0H4DhdQPTy8LJfyqwZ2tc5uqpSSnEXE+/1KopHBE5J8GDagAg5cg== dependencies: ember-cli-babel "^7.26.6" "@ember/test-helpers@^2.6.0": - version "2.9.3" - resolved "https://registry.npmjs.org/@ember/test-helpers/-/test-helpers-2.9.3.tgz" - integrity sha512-ejVg4Dj+G/6zyLvQsYOvmGiOLU6AS94tY4ClaO1E2oVvjjtVJIRmVLFN61I+DuyBg9hS3cFoPjQRTZB9MRIbxQ== + version "2.9.4" + resolved "https://registry.npmjs.org/@ember/test-helpers/-/test-helpers-2.9.4.tgz#985022e9ba05cfc918bcf08b77cbb355f85b723e" + integrity sha512-z+Qs1NYWyIVDmrY6WdmOS5mdG1lJ5CFfzh6dRhLfs9lq45deDaDrVNcaCYhnNeJZTvUBK2XR2SvPcZm0RloXdA== dependencies: "@ember/test-waiters" "^3.0.0" "@embroider/macros" "^1.10.0" @@ -1301,36 +1407,29 @@ ember-cli-htmlbars "^6.1.1" ember-destroyable-polyfill "^2.0.3" -"@ember/test-waiters@^3.0.0", "@ember/test-waiters@^3.0.2": - version "3.0.2" - resolved "https://registry.npmjs.org/@ember/test-waiters/-/test-waiters-3.0.2.tgz" - integrity sha512-H8Q3Xy9rlqhDKnQpwt2pzAYDouww4TZIGSI1pZJhM7mQIGufQKuB0ijzn/yugA6Z+bNdjYp1HioP8Y4hn2zazQ== +"@ember/test-waiters@^3.0.0", "@ember/test-waiters@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@ember/test-waiters/-/test-waiters-3.1.0.tgz#61399919cbf793978da0b8bfdfdb7bca0cb80e9e" + integrity sha512-bb9h95ktG2wKY9+ja1sdsFBdOms2lB19VWs8wmNpzgHv1NCetonBoV5jHBV4DHt0uS1tg9z66cZqhUVlYs96KQ== dependencies: calculate-cache-key-for-tree "^2.0.0" ember-cli-babel "^7.26.6" ember-cli-version-checker "^5.1.2" semver "^7.3.5" -"@embroider/addon-shim@1.8.3": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@embroider/addon-shim/-/addon-shim-1.8.3.tgz#2368510b8ce42d50d02cb3289c32e260dfa34bd9" - integrity sha512-7pyHwzT6ESXc3nZsB8rfnirLkUhQWdvj6CkYH+0MUPN74mX4rslf7pnBqZE/KZkW3uBIaBYvU8fxi0hcKC/Paw== +"@embroider/addon-shim@^1.0.0", "@embroider/addon-shim@^1.2.0", "@embroider/addon-shim@^1.8.3", "@embroider/addon-shim@^1.8.4", "@embroider/addon-shim@^1.8.7": + version "1.8.9" + resolved "https://registry.npmjs.org/@embroider/addon-shim/-/addon-shim-1.8.9.tgz#ef37eba069d391b2d2a80aa62880c469051c4d43" + integrity sha512-qyN64T1jMHZ99ihlk7VFHCWHYZHLE1DOdHi0J7lmn5waV1DoW7gD8JLi1i7FregzXtKhbDc7shyEmTmWPTs8MQ== dependencies: - "@embroider/shared-internals" "^1.8.3" - semver "^7.3.5" - -"@embroider/addon-shim@^1.0.0", "@embroider/addon-shim@^1.2.0", "@embroider/addon-shim@^1.8.4": - version "1.8.4" - resolved "https://registry.npmjs.org/@embroider/addon-shim/-/addon-shim-1.8.4.tgz" - integrity sha512-sFhfWC0vI18KxVenmswQ/ShIvBg4juL8ubI+Q3NTSdkCTeaPQ/DIOUF6oR5DCQ8eO/TkIaw+kdG3FkTY6yNJqA== - dependencies: - "@embroider/shared-internals" "^2.0.0" + "@embroider/shared-internals" "^2.6.0" broccoli-funnel "^3.0.8" + common-ancestor-path "^1.0.1" semver "^7.3.8" "@embroider/core@0.36.0": version "0.36.0" - resolved "https://registry.npmjs.org/@embroider/core/-/core-0.36.0.tgz" + resolved "https://registry.npmjs.org/@embroider/core/-/core-0.36.0.tgz#fbbd60d29c3fcbe02b4e3e63e6043a43de2b9ce3" integrity sha512-J6esENP+aNt+/r070cF1RCJyCi/Rn1I6uFp37vxyLWwvGDuT0E7wGcaPU29VBkBFqxi4Z1n4F796BaGHv+kX6w== dependencies: "@babel/core" "^7.12.3" @@ -1369,7 +1468,7 @@ "@embroider/macros@0.36.0", "@embroider/macros@^0.36.0": version "0.36.0" - resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.36.0.tgz" + resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.36.0.tgz#5330f1e6f12112f0f68e34b3e4855dc7dd3c69a5" integrity sha512-w37G4uXG+Wi3K3EHSFBSr/n6kGFXYG8nzZ9ptzDOC7LP3Oh5/MskBnVZW3+JkHXUPEqKsDGlxPxCVpPl1kQyjQ== dependencies: "@babel/core" "^7.12.3" @@ -1384,7 +1483,7 @@ "@embroider/macros@0.41.0", "@embroider/macros@^0.41.0": version "0.41.0" - resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.41.0.tgz" + resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.41.0.tgz#3e78b6f388d7229906abf4c75edfff8bb0208aca" integrity sha512-QISzwEEfLsskZeL0jyZDs1RoQSotwBWj+4upTogNHuxQP5j/9H3IMG/3QB1gh8GEpbudATb/cS4NDYK3UBxufw== dependencies: "@embroider/shared-internals" "0.41.0" @@ -1396,7 +1495,7 @@ "@embroider/macros@0.47.2", "@embroider/macros@^0.47.0": version "0.47.2" - resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.47.2.tgz" + resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.47.2.tgz#23cbe92cac3c24747f054e1eea2a22538bf7ebd0" integrity sha512-ViNWluJCeM5OPlM3rs8kdOz3RV5rpfXX5D2rDnc/q86xRS0xf4NFEjYRV7W6fBcD0b3v5jSHDTwrjq9Kee4rHg== dependencies: "@embroider/shared-internals" "0.47.2" @@ -1409,7 +1508,7 @@ "@embroider/macros@^0.42.3": version "0.42.3" - resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.42.3.tgz" + resolved "https://registry.npmjs.org/@embroider/macros/-/macros-0.42.3.tgz#eb4dc35c43f1cb1d14298219ba037f8cead06081" integrity sha512-4I+Sde8FU7QMwNQ3gYtj8fdBTqUeoPDn61XuV4Xng7p9LszQksGDXtyEhWrf9KWU3G+NtrZotY5LICd5P+E3tw== dependencies: "@embroider/shared-internals" "0.42.3" @@ -1419,12 +1518,12 @@ resolve "^1.20.0" semver "^7.3.2" -"@embroider/macros@^0.50.0 || ^1.0.0", "@embroider/macros@^1.13.0", "@embroider/macros@^1.2.0": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.13.2.tgz#07dda11313a2539f403404881b729e622a80ca17" - integrity sha512-AUgJ71xG8kjuTx8XB1AQNBiebJuXRfhcHr318dCwnQz9VRXdYSnEEqf38XRvGYIoCvIyn/3c72LrSwzaJqknOA== +"@embroider/macros@^0.50.0 || ^1.0.0", "@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0", "@embroider/macros@^1.16.1", "@embroider/macros@^1.2.0": + version "1.16.5" + resolved "https://registry.npmjs.org/@embroider/macros/-/macros-1.16.5.tgz#871addab2103b554c6b6a3a337c00e3f0a0462ac" + integrity sha512-Oz8bUZvZzOV1Gk3qSgIzZJJzs6acclSTcEFyB+KdKbKqjTC3uebn53aU2gAlLU7/YdTRZrg2gNbQuwAp+tGkGg== dependencies: - "@embroider/shared-internals" "2.5.0" + "@embroider/shared-internals" "2.6.2" assert-never "^1.2.1" babel-import-util "^2.0.0" ember-cli-babel "^7.26.6" @@ -1433,23 +1532,9 @@ resolve "^1.20.0" semver "^7.3.2" -"@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0": - version "1.10.0" - resolved "https://registry.npmjs.org/@embroider/macros/-/macros-1.10.0.tgz" - integrity sha512-LMbfQGk/a+f6xtvAv5fq/wf2LRxETnbgSCLUf/z6ebzmuskOUxrke+uP55chF/loWrARi9g6erFQ7RDOUoBMSg== - dependencies: - "@embroider/shared-internals" "2.0.0" - assert-never "^1.2.1" - babel-import-util "^1.1.0" - ember-cli-babel "^7.26.6" - find-up "^5.0.0" - lodash "^4.17.21" - resolve "^1.20.0" - semver "^7.3.2" - "@embroider/shared-internals@0.41.0": version "0.41.0" - resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-0.41.0.tgz" + resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-0.41.0.tgz#2553f026d4f48ea1fd11235501feb63bf49fa306" integrity sha512-fiqUVB6cfh2UBEFE4yhT5EzagkZ1Q26+OhBV0nJszFEJZx4DqVIb3pxSSZ8P+HhpxuJsQ2XpMA/j02ZPFZfbdQ== dependencies: ember-rfc176-data "^0.3.17" @@ -1462,7 +1547,7 @@ "@embroider/shared-internals@0.42.3": version "0.42.3" - resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-0.42.3.tgz" + resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-0.42.3.tgz#65224fe86c55790417078b267add8f54148b59e3" integrity sha512-AIFRumaGxzhzzSswtk97Z0ttu0dyRhXoDuOi6kPYHoprUdtt7biRAksrsbutWWdFapve7vKHFZdYVuiG8IbX0A== dependencies: ember-rfc176-data "^0.3.17" @@ -1475,7 +1560,7 @@ "@embroider/shared-internals@0.47.2": version "0.47.2" - resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-0.47.2.tgz" + resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-0.47.2.tgz#24e9fa0dd9c529d5c996ee1325729ea08d1fa19f" integrity sha512-SxdZYjAE0fiM5zGDz+12euWIsQZ1tsfR1k+NKmiWMyLhA5T3pNgbR2/Djvx/cVIxOtEavGGSllYbzRKBtV4xMg== dependencies: babel-import-util "^0.2.0" @@ -1486,24 +1571,10 @@ semver "^7.3.5" typescript-memoize "^1.0.1" -"@embroider/shared-internals@2.0.0", "@embroider/shared-internals@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-2.0.0.tgz" - integrity sha512-qZ2/xky9mWm5YC6noOa6AiAwgISEQ78YTZNv4SNu2PFgEK/H+Ha/3ddngzGSsnXkVnIHZyxIBzhxETonQYHY9g== - dependencies: - babel-import-util "^1.1.0" - ember-rfc176-data "^0.3.17" - fs-extra "^9.1.0" - js-string-escape "^1.0.1" - lodash "^4.17.21" - resolve-package-path "^4.0.1" - semver "^7.3.5" - typescript-memoize "^1.0.1" - -"@embroider/shared-internals@2.5.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@embroider/shared-internals/-/shared-internals-2.5.0.tgz#4a0b5127c589718fae60fc22f81374ed558b944a" - integrity sha512-7qzrb7GVIyNqeY0umxoeIvjDC+ay1b+wb2yCVuYTUYrFfLAkLEy9FNI3iWCi3RdQ9OFjgcAxAnwsAiPIMZZ3pQ== +"@embroider/shared-internals@2.6.2", "@embroider/shared-internals@^2.0.0", "@embroider/shared-internals@^2.6.0": + version "2.6.2" + resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-2.6.2.tgz#66297a8606587108f9dbcbaa1a9dcc6b4a4ca605" + integrity sha512-jL3Bjn8C73AUBlTex+VixP7YmqvPNN/BZFB85odTstzLFOuR8y2mmGiuWbq17qNuFyoxc6xtndMnAeqwCXBNkA== dependencies: babel-import-util "^2.0.0" debug "^4.3.2" @@ -1511,13 +1582,14 @@ fs-extra "^9.1.0" js-string-escape "^1.0.1" lodash "^4.17.21" + minimatch "^3.0.4" resolve-package-path "^4.0.1" semver "^7.3.5" typescript-memoize "^1.0.1" -"@embroider/shared-internals@^1.0.0", "@embroider/shared-internals@^1.8.3": +"@embroider/shared-internals@^1.0.0": version "1.8.3" - resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-1.8.3.tgz" + resolved "https://registry.npmjs.org/@embroider/shared-internals/-/shared-internals-1.8.3.tgz#52d868dc80016e9fe983552c0e516f437bf9b9f9" integrity sha512-N5Gho6Qk8z5u+mxLCcMYAoQMbN4MmH+z2jXwQHVs859bxuZTxwF6kKtsybDAASCtd2YGxEmzcc1Ja/wM28824w== dependencies: babel-import-util "^1.1.0" @@ -1531,43 +1603,34 @@ "@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0": version "0.41.0" - resolved "https://registry.npmjs.org/@embroider/util/-/util-0.41.0.tgz" + resolved "https://registry.npmjs.org/@embroider/util/-/util-0.41.0.tgz#5324cb4742aa4ed8d613c4f88a466f73e4e6acc1" integrity sha512-ytA3J/YfQh7FEUEBwz3ezTqQNm/S5et5rZw3INBIy4Ak4x0NXV/VXLjyL8mv3txL8fGknZTBdXEhDsHUKIq8SQ== dependencies: "@embroider/macros" "0.41.0" broccoli-funnel "^3.0.5" ember-cli-babel "^7.23.1" -"@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0", "@embroider/util@^1.0.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@embroider/util/-/util-1.12.0.tgz#4b7828650b55f8498f1e78bb63e27e77835e926f" - integrity sha512-P4M1QADEH9ceIYC9mwHeV+6DDgEIQQYFfZi728nVKqTAxakXoiLgu/BCyQmEGyow9fYEPYaC1boDCZxW2JQAXg== +"@embroider/util@^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0", "@embroider/util@^1.0.0", "@embroider/util@^1.9.0": + version "1.13.1" + resolved "https://registry.npmjs.org/@embroider/util/-/util-1.13.1.tgz#c6d4a569b331cbf805e68e7fa6602f248438bde6" + integrity sha512-MRbs2FPO4doQ31YHIYk+QKChEs7k15aTsMk8QmO4eKiuQq9OT0sr1oasObZyGB8cVVbr29WWRWmsNirxzQtHIg== dependencies: - "@embroider/macros" "^1.13.0" + "@embroider/macros" "^1.16.1" broccoli-funnel "^3.0.5" ember-cli-babel "^7.26.11" "@embroider/util@^0.47.0": version "0.47.2" - resolved "https://registry.npmjs.org/@embroider/util/-/util-0.47.2.tgz" + resolved "https://registry.npmjs.org/@embroider/util/-/util-0.47.2.tgz#d06497b4b84c07ed9c7b628293bb019c533f4556" integrity sha512-g9OqnFJPktGu9NS0Ug3Pxz1JE3jeDceeVE4IrlxDrVmBXMA/GrBvpwjolWgl6jh97cMJyExdz62jIvPHV4256Q== dependencies: "@embroider/macros" "0.47.2" broccoli-funnel "^3.0.5" ember-cli-babel "^7.23.1" -"@embroider/util@^1.9.0": - version "1.10.0" - resolved "https://registry.npmjs.org/@embroider/util/-/util-1.10.0.tgz" - integrity sha512-utAFKoq6ajI27jyqjvX3PiGL4m+ZyGVlVNbSbE/nOqi2llRyAkh5ltH1WkIK7jhdwQFJouo1NpOSj9J3/HDa3A== - dependencies: - "@embroider/macros" "^1.10.0" - broccoli-funnel "^3.0.5" - ember-cli-babel "^7.26.11" - "@eslint/eslintrc@^0.4.3": version "0.4.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== dependencies: ajv "^6.12.4" @@ -1582,7 +1645,7 @@ "@formatjs/ecma402-abstract@1.11.4": version "1.11.4" - resolved "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz" + resolved "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz#b962dfc4ae84361f9f08fbce411b4e4340930eda" integrity sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw== dependencies: "@formatjs/intl-localematcher" "0.2.25" @@ -1590,21 +1653,21 @@ "@formatjs/ecma402-abstract@1.6.4": version "1.6.4" - resolved "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.6.4.tgz" + resolved "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.6.4.tgz#cff5ef03837fb6bae70b16d04940213c17e87884" integrity sha512-ukFjGD9dLsxcD9D5AEshJqQElPQeUAlTALT/lzIV6OcYojyuU81gw/uXDUOrs6XW79jtOJwQDkLqHbCJBJMOTw== dependencies: tslib "^2.1.0" "@formatjs/fast-memoize@1.2.1": version "1.2.1" - resolved "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz" + resolved "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz#e6f5aee2e4fd0ca5edba6eba7668e2d855e0fc21" integrity sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg== dependencies: tslib "^2.1.0" "@formatjs/icu-messageformat-parser@2.1.0": version "2.1.0" - resolved "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz" + resolved "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz#a54293dd7f098d6a6f6a084ab08b6d54a3e8c12d" integrity sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw== dependencies: "@formatjs/ecma402-abstract" "1.11.4" @@ -1613,7 +1676,7 @@ "@formatjs/icu-skeleton-parser@1.3.6": version "1.3.6" - resolved "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz" + resolved "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz#4ce8c0737d6f07b735288177049e97acbf2e8964" integrity sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg== dependencies: "@formatjs/ecma402-abstract" "1.11.4" @@ -1621,14 +1684,14 @@ "@formatjs/intl-localematcher@0.2.25": version "0.2.25" - resolved "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz" + resolved "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz#60892fe1b271ec35ba07a2eb018a2dd7bca6ea3a" integrity sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA== dependencies: tslib "^2.1.0" "@glimmer/component@^1.0.0", "@glimmer/component@^1.0.4", "@glimmer/component@^1.1.2": version "1.1.2" - resolved "https://registry.npmjs.org/@glimmer/component/-/component-1.1.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/component/-/component-1.1.2.tgz#892ec0c9f0b6b3e41c112be502fde073cf24d17c" integrity sha512-XyAsEEa4kWOPy+gIdMjJ8XlzA3qrGH55ZDv6nA16ibalCR17k74BI0CztxuRds+Rm6CtbUVgheCVlcCULuqD7A== dependencies: "@glimmer/di" "^0.1.9" @@ -1648,12 +1711,12 @@ "@glimmer/di@^0.1.9": version "0.1.11" - resolved "https://registry.npmjs.org/@glimmer/di/-/di-0.1.11.tgz" + resolved "https://registry.npmjs.org/@glimmer/di/-/di-0.1.11.tgz#a6878c07a13a2c2c76fcde598a5c97637bfc4280" integrity sha512-moRwafNDwHTnTHzyyZC9D+mUSvYrs1Ak0tRPjjmCghdoHHIvMshVbEnwKb/1WmW5CUlKc2eL9rlAV32n3GiItg== "@glimmer/encoder@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/encoder/-/encoder-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/encoder/-/encoder-0.42.2.tgz#d3ba3dc9f1d4fa582d1d18b63da100fc5c664057" integrity sha512-8xkdly0i0BP5HMI0suPB9ly0AnEq8x9Z8j3Gee1HYIovM5VLNtmh7a8HsaHYRs/xHmBEZcqtr8JV89w6F59YMQ== dependencies: "@glimmer/interfaces" "^0.42.2" @@ -1661,43 +1724,43 @@ "@glimmer/env@0.1.7", "@glimmer/env@^0.1.7": version "0.1.7" - resolved "https://registry.npmjs.org/@glimmer/env/-/env-0.1.7.tgz" + resolved "https://registry.npmjs.org/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha512-JKF/a9I9jw6fGoz8kA7LEQslrwJ5jms5CXhu/aqkBWk+PmZ6pTl8mlb/eJ/5ujBGTiQzBhy5AIWF712iA+4/mw== "@glimmer/global-context@0.65.4": version "0.65.4" - resolved "https://registry.npmjs.org/@glimmer/global-context/-/global-context-0.65.4.tgz" + resolved "https://registry.npmjs.org/@glimmer/global-context/-/global-context-0.65.4.tgz#1da1d59dd4260ce912c40e474cd39c2e82de51b8" integrity sha512-RSYCPG/uVR5XCDcPREBclncU7R0zkjACbADP+n3FWAH1TfWbXRMDIkvO/ZlwHkjHoCZf6tIM6p5S/MoFzfJEJA== dependencies: "@glimmer/env" "^0.1.7" "@glimmer/interfaces@0.65.4": version "0.65.4" - resolved "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.65.4.tgz" + resolved "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.65.4.tgz#d298cc2b12b8ebcf269f39246ca7ab92816f6680" integrity sha512-R0kby79tGNKZOojVJa/7y0JH9Eq4SV+L1s6GcZy30QUZ1g1AAGS5XwCIXc9Sc09coGcv//q+6NLeSw7nlx1y4A== dependencies: "@simple-dom/interface" "^1.4.0" "@glimmer/interfaces@0.84.3": version "0.84.3" - resolved "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.84.3.tgz" + resolved "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.84.3.tgz#629777a4abe373b0785656f6c8d08989f5784805" integrity sha512-dk32ykoNojt0mvEaIW6Vli5MGTbQo58uy3Epj7ahCgTHmWOKuw/0G83f2UmFprRwFx689YTXG38I/vbpltEjzg== dependencies: "@simple-dom/interface" "^1.4.0" "@glimmer/interfaces@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.42.2.tgz#9cf8d6f8f5eee6bfcfa36919ca68ae716e1f78db" integrity sha512-7LOuQd02cxxNNHChzdHMAU8/qOeQvTro141CU5tXITP7z6aOv2D2gkFdau97lLQiVxezGrh8J7h8GCuF7TEqtg== "@glimmer/low-level@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/low-level/-/low-level-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/low-level/-/low-level-0.42.2.tgz#52c745414d1d04c4245c369bd132c0e786c816ef" integrity sha512-s+Q44SnKdTBTnkgX0deBlVNnNPVas+Pg8xEnwky9VrUqOHKsIZRrPgfVULeC6bIdFXtXOKm5CjTajhb9qnQbXQ== "@glimmer/program@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/program/-/program-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/program/-/program-0.42.2.tgz#fe504679ca4df6251dd5fcf3003699bb51fa41fa" integrity sha512-XpQ6EYzA1VL9ESKoih5XW5JftFmlRvwy3bF/I1ABOa3yLIh8mApEwrRI/sIHK0Nv5s1j0uW4itVF196WxnJXgw== dependencies: "@glimmer/encoder" "^0.42.2" @@ -1706,14 +1769,14 @@ "@glimmer/reference@^0.42.1", "@glimmer/reference@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/reference/-/reference-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/reference/-/reference-0.42.2.tgz#57874e27c825fb7041b5295b5eb153f3f3f92f8f" integrity sha512-XuhbRjr3M9Q/DP892jGxVfPE6jaGGHu5w9ppGMnuTY7Vm/x+A+68MCiaREhDcEwJlzGg4UkfVjU3fdgmUIrc5Q== dependencies: "@glimmer/util" "^0.42.2" "@glimmer/reference@^0.65.0": version "0.65.4" - resolved "https://registry.npmjs.org/@glimmer/reference/-/reference-0.65.4.tgz" + resolved "https://registry.npmjs.org/@glimmer/reference/-/reference-0.65.4.tgz#bbc8becd6a1bf01fc189b6489e27446437194711" integrity sha512-yuRVE4qyqrlCndDMrHKDWUbDmGDCjPzsFtlTmxxnhDMJAdQsnr2cRLITHvQRDm1tXfigVvyKnomeuYhRRbBqYQ== dependencies: "@glimmer/env" "^0.1.7" @@ -1724,7 +1787,7 @@ "@glimmer/runtime@^0.42.1": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/runtime/-/runtime-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/runtime/-/runtime-0.42.2.tgz#50e7da5d3cf9144248048a7478be3c489784a4bb" integrity sha512-52LVZJsLKM3GzI3TEmYcw2LdI9Uk0jotISc3w2ozQBWvkKoYxjDNvI/gsjyMpenj4s7FcG2ggOq0x4tNFqm1GA== dependencies: "@glimmer/interfaces" "^0.42.2" @@ -1737,7 +1800,7 @@ "@glimmer/syntax@^0.42.1": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.42.2.tgz#89bb3cb787285b84665dc0d8907d94b008e5be9a" integrity sha512-SR26SmF/Mb5o2cc4eLHpOyoX5kwwXP4KRhq4fbWfrvan74xVWA38PLspPCzwGhyVH/JsE7tUEPMjSo2DcJge/Q== dependencies: "@glimmer/interfaces" "^0.42.2" @@ -1747,7 +1810,7 @@ "@glimmer/syntax@^0.65.0": version "0.65.4" - resolved "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.65.4.tgz" + resolved "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.65.4.tgz#49164de5dc9e8b67084ec009bdd865e379d8a971" integrity sha512-y+/C3e8w96efk3a/Z5If9o4ztKJwrr8RtDpbhV2J8X+DUsn5ic2N3IIdlThbt/Zn6tkP1K3dY6uaFUx3pGTvVQ== dependencies: "@glimmer/interfaces" "0.65.4" @@ -1757,7 +1820,7 @@ "@glimmer/syntax@^0.84.3": version "0.84.3" - resolved "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.84.3.tgz" + resolved "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.84.3.tgz#4045a1708cef7fd810cff42fe6deeba40c7286d0" integrity sha512-ioVbTic6ZisLxqTgRBL2PCjYZTFIwobifCustrozRU2xGDiYvVIL0vt25h2c1ioDsX59UgVlDkIK4YTAQQSd2A== dependencies: "@glimmer/interfaces" "0.84.3" @@ -1767,7 +1830,7 @@ "@glimmer/tracking@^1.0.0", "@glimmer/tracking@^1.0.1", "@glimmer/tracking@^1.0.4": version "1.1.2" - resolved "https://registry.npmjs.org/@glimmer/tracking/-/tracking-1.1.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/tracking/-/tracking-1.1.2.tgz#74e71be07b0a7066518d24044d2665d0cf8281eb" integrity sha512-cyV32zsHh+CnftuRX84ALZpd2rpbDrhLhJnTXn9W//QpqdRZ5rdMsxSY9fOsj0CKEc706tmEU299oNnDc0d7tA== dependencies: "@glimmer/env" "^0.1.7" @@ -1775,7 +1838,7 @@ "@glimmer/util@0.65.4": version "0.65.4" - resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.65.4.tgz" + resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.65.4.tgz#e464145078f3f40da9013ff2590a6016515455d2" integrity sha512-aofe+rdBhkREKP2GZta6jy1UcbRRMfWx7M18zxGxspPoeD08NscD04Kx+WiOKXmC1TcrfITr8jvqMfrKrMzYWQ== dependencies: "@glimmer/env" "0.1.7" @@ -1784,7 +1847,7 @@ "@glimmer/util@0.84.3": version "0.84.3" - resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.84.3.tgz" + resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.84.3.tgz#9ae0166982c0b48aa94b02d6ba8c2c81976ade4b" integrity sha512-qFkh6s16ZSRuu2rfz3T4Wp0fylFj3HBsONGXQcrAdZjdUaIS6v3pNj6mecJ71qRgcym9Hbaq/7/fefIwECUiKw== dependencies: "@glimmer/env" "0.1.7" @@ -1793,17 +1856,17 @@ "@glimmer/util@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.42.2.tgz#9ca1631e42766ea6059f4b49d0bdfb6095aad2c4" integrity sha512-Heck0baFSaWDanCYtmOcLeaz7v+rSqI8ovS7twrp2/FWEteb3Ze5sWQ2BEuSAG23L/k/lzVwYM/MY7ZugxBpaA== "@glimmer/util@^0.44.0": version "0.44.0" - resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.44.0.tgz" + resolved "https://registry.npmjs.org/@glimmer/util/-/util-0.44.0.tgz#45df98d73812440206ae7bda87cfe04aaae21ed9" integrity sha512-duAsm30uVK9jSysElCbLyU6QQYO2X9iLDLBIBUcCqck9qN1o3tK2qWiHbGK5d6g8E2AJ4H88UrfElkyaJlGrwg== "@glimmer/validator@0.65.4", "@glimmer/validator@^0.65.0": version "0.65.4" - resolved "https://registry.npmjs.org/@glimmer/validator/-/validator-0.65.4.tgz" + resolved "https://registry.npmjs.org/@glimmer/validator/-/validator-0.65.4.tgz#12c27a9a63706c60e6499fd687940e9d1affb32c" integrity sha512-0YUjAyo45DF5JkQxdv5kHn96nMNhvZiEwsAD4Jme0kk5Q9MQcPOUtN76pQAS4f+C6GdF9DeUr2yGXZLFMmb+LA== dependencies: "@glimmer/env" "^0.1.7" @@ -1811,19 +1874,19 @@ "@glimmer/validator@^0.44.0": version "0.44.0" - resolved "https://registry.npmjs.org/@glimmer/validator/-/validator-0.44.0.tgz" + resolved "https://registry.npmjs.org/@glimmer/validator/-/validator-0.44.0.tgz#03d127097dc9cb23052cdb7fcae59d0a9dca53e1" integrity sha512-i01plR0EgFVz69GDrEuFgq1NheIjZcyTy3c7q+w7d096ddPVeVcRzU3LKaqCfovvLJ+6lJx40j45ecycASUUyw== "@glimmer/vm-babel-plugins@0.80.3": version "0.80.3" - resolved "https://registry.npmjs.org/@glimmer/vm-babel-plugins/-/vm-babel-plugins-0.80.3.tgz" + resolved "https://registry.npmjs.org/@glimmer/vm-babel-plugins/-/vm-babel-plugins-0.80.3.tgz#434b62172318cac43830d3ac29818cf2c5f111c1" integrity sha512-9ej6xlm5MzHBJ5am2l0dbbn8Z0wJoYoMpM8FcrGMlUP6SPMLWxvxpMsApgQo8u6dvZRCjR3/bw3fdf7GOy0AFw== dependencies: babel-plugin-debug-macros "^0.3.4" "@glimmer/vm@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/vm/-/vm-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/vm/-/vm-0.42.2.tgz#492a4f05eac587c3a37371b3c62593f20bef553d" integrity sha512-D2MNU5glICLqvet5SfVPrv+l6JNK2TR+CdQhch1Ew+btOoqlW+2LIJIF/5wLb1POjIMEkt+78t/7RN0mDFXGzw== dependencies: "@glimmer/interfaces" "^0.42.2" @@ -1831,7 +1894,7 @@ "@glimmer/wire-format@^0.42.2": version "0.42.2" - resolved "https://registry.npmjs.org/@glimmer/wire-format/-/wire-format-0.42.2.tgz" + resolved "https://registry.npmjs.org/@glimmer/wire-format/-/wire-format-0.42.2.tgz#b95062b594dddeb8bd11cba3a6a0accbfabc9930" integrity sha512-IqUo6mdJ7GRsK7KCyZxrc17ioSg9RBniEnb418ZMQxsV/WBv9NQ359MuClUck2M24z1AOXo4TerUw0U7+pb1/A== dependencies: "@glimmer/interfaces" "^0.42.2" @@ -1839,17 +1902,17 @@ "@handlebars/parser@^1.1.0": version "1.1.0" - resolved "https://registry.npmjs.org/@handlebars/parser/-/parser-1.1.0.tgz" + resolved "https://registry.npmjs.org/@handlebars/parser/-/parser-1.1.0.tgz#d6dbc7574774b238114582410e8fee0dc3532bdf" integrity sha512-rR7tJoSwJ2eooOpYGxGGW95sLq6GXUaS1UtWvN7pei6n2/okYvCGld9vsUTvkl2migxbkszsycwtMf/GEc1k1A== "@handlebars/parser@~2.0.0": version "2.0.0" - resolved "https://registry.npmjs.org/@handlebars/parser/-/parser-2.0.0.tgz" + resolved "https://registry.npmjs.org/@handlebars/parser/-/parser-2.0.0.tgz#5e8b7298f31ff8f7b260e6b7363c7e9ceed7d9c5" integrity sha512-EP9uEDZv/L5Qh9IWuMUGJRfwhXJ4h1dqKTT4/3+tY0eu7sPis7xh23j61SYUnNF4vqCQvvUXpDo9Bh/+q1zASA== "@hashicorp/api-double@^1.6.1": version "1.6.1" - resolved "https://registry.npmjs.org/@hashicorp/api-double/-/api-double-1.6.1.tgz" + resolved "https://registry.npmjs.org/@hashicorp/api-double/-/api-double-1.6.1.tgz#67c4c4c5cbf9f51f3b8bc992ab2df21acf63b318" integrity sha512-JkQZIsH/2B9T2oK5SQNDakvqlHjxQHu0I9ftmmrxqkxYvYoLN+Whp7dzQ8HswOp1vIJyqbvUhSw06XfH/eimZA== dependencies: array-range "^1.0.1" @@ -1861,39 +1924,40 @@ js-yaml "^3.13.1" "@hashicorp/design-system-components@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@hashicorp/design-system-components/-/design-system-components-3.0.2.tgz#f9bf18f0f20f6396d4afc2ed138056c27dff8a38" - integrity sha512-Pt3dgCxzutIJ3LDtVgT0NSU5oTV8OFzgK9Nx1tTzIpMOfbCRzZuBmJB06ZPCdyP9Vs7lQVrn/kKzZaKJejrXiQ== + version "3.6.0" + resolved "https://registry.npmjs.org/@hashicorp/design-system-components/-/design-system-components-3.6.0.tgz#e678123f9d88eef7df2edfdf1666997214fe3273" + integrity sha512-HV8Wa9fTFCfwCCze7gzg2+U3oSmwNkwYtnrrxln7MXzEKRWl1E2p4BM7ZdyaXu3n092R3wcjy04VwaVSmQqrLw== dependencies: "@ember/render-modifiers" "^2.0.5" - "@ember/test-waiters" "^3.0.2" - "@hashicorp/design-system-tokens" "^1.9.0" - "@hashicorp/ember-flight-icons" "^4.0.1" + "@ember/string" "^3.1.1" + "@ember/test-waiters" "^3.1.0" + "@hashicorp/design-system-tokens" "^1.11.0" + "@hashicorp/ember-flight-icons" "^4.1.0" dialog-polyfill "^0.5.6" ember-a11y-refocus "^3.0.2" ember-auto-import "^2.6.3" - ember-cached-decorator-polyfill "^0.1.4" - ember-cli-babel "^7.26.11" - ember-cli-htmlbars "^6.2.0" - ember-cli-sass "^10.0.1" - ember-composable-helpers "^4.5.0" + ember-cli-babel "^8.2.0" + ember-cli-htmlbars "^6.3.0" + ember-cli-sass "^11.0.1" + ember-composable-helpers "^5.0.0" ember-element-helper "^0.8.5" - ember-focus-trap "^1.0.2" - ember-keyboard "^8.2.0" + ember-focus-trap "^1.1.0" + ember-keyboard "^8.2.1" ember-stargate "^0.4.3" ember-style-modifier "^3.0.1" ember-truth-helpers "^3.1.1" - sass "^1.62.1" + prismjs "^1.29.0" + sass "^1.69.5" tippy.js "^6.3.7" -"@hashicorp/design-system-tokens@^1.9.0": - version "1.9.0" - resolved "https://registry.npmjs.org/@hashicorp/design-system-tokens/-/design-system-tokens-1.9.0.tgz" - integrity sha512-zmMpnKv4vulhVFVCpqf3oAAR5fQeDDnMxbeJIZllLFCgF2JFoL6C/Irghx4WnBAG8GkLs8CbxjPVtFjSYq+V8w== +"@hashicorp/design-system-tokens@^1.11.0", "@hashicorp/design-system-tokens@^1.9.0": + version "1.11.0" + resolved "https://registry.npmjs.org/@hashicorp/design-system-tokens/-/design-system-tokens-1.11.0.tgz#0ae68d06d4297e891ce4ba63465d1f6e742e5554" + integrity sha512-LPj8IAznpEEhKrrosg3+sW9ss6fVKt8zOC9Ic4Kt5/KZPWLFaP6S8pff5ytvede+cZrAzY3UzZF55u+ev5J9GQ== "@hashicorp/ember-cli-api-double@^4.0.0": version "4.0.0" - resolved "https://registry.npmjs.org/@hashicorp/ember-cli-api-double/-/ember-cli-api-double-4.0.0.tgz" + resolved "https://registry.npmjs.org/@hashicorp/ember-cli-api-double/-/ember-cli-api-double-4.0.0.tgz#fd6181229c589b4db93f1784d022db064c61ec76" integrity sha512-ana8k6MjyXgwflAgVJxrgab1vKz/v6212HOHO6Gsz6NaDwzQt0DUuT4dB3VpbiZ6K8D1M7xd0znsmnvR795goA== dependencies: "@hashicorp/api-double" "^1.6.1" @@ -1906,25 +1970,25 @@ pretender "^3.2.0" recursive-readdir-sync "^1.0.6" -"@hashicorp/ember-flight-icons@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@hashicorp/ember-flight-icons/-/ember-flight-icons-4.0.1.tgz#08499f495f8f9ff9eb9eb6c439f1861f8411c047" - integrity sha512-8xkU+2ATX/a5pofmwO51YXgwHamG6YUpxOXxcPbA+9/TKNn1HFbrk3TWJBuDIwz2kdk9hXRZBri2XIR18BFrTA== +"@hashicorp/ember-flight-icons@^4.0.1", "@hashicorp/ember-flight-icons@^4.1.0": + version "4.1.0" + resolved "https://registry.npmjs.org/@hashicorp/ember-flight-icons/-/ember-flight-icons-4.1.0.tgz#4f73fc6145c94ecd46ef38802722ea2d1fe0e876" + integrity sha512-X1AL475EPuGu6UkZiS/zqRFgymnIhGfgpY1HwPdavePARmgMr9CcPSwsTeZeV+OXq6yUxMzidijSJUAfEpLb5Q== dependencies: - "@hashicorp/flight-icons" "^2.20.0" + "@hashicorp/flight-icons" "^3.0.0" ember-auto-import "^2.6.3" - ember-cli-babel "^7.26.11" - ember-cli-htmlbars "^6.2.0" + ember-cli-babel "^8.2.0" + ember-cli-htmlbars "^6.3.0" ember-get-config "^2.1.1" -"@hashicorp/flight-icons@^2.20.0": - version "2.20.0" - resolved "https://registry.npmjs.org/@hashicorp/flight-icons/-/flight-icons-2.20.0.tgz" - integrity sha512-CYIY5yAkYzi8Q+w86Mk41IK1/1X+AoQUtxK3Yt48ZHzulsz3Wlvg91YvnOGntxjqcp7AGwpOYnq7xM2W4bummQ== +"@hashicorp/flight-icons@^3.0.0": + version "3.4.0" + resolved "https://registry.npmjs.org/@hashicorp/flight-icons/-/flight-icons-3.4.0.tgz#fbd30a9748c36d92934784623e93ce9af48ce957" + integrity sha512-ddbiKkaXW3LMlXE1MZz0fsaO0rJvpbLQ2Js+Qa1e2yWKQbtSvJluAu9V8mg5jvOlR3HFDskTm8knSxVRd0VjGw== "@html-next/vertical-collection@^4.0.0": version "4.0.2" - resolved "https://registry.npmjs.org/@html-next/vertical-collection/-/vertical-collection-4.0.2.tgz" + resolved "https://registry.npmjs.org/@html-next/vertical-collection/-/vertical-collection-4.0.2.tgz#7e9885423eb8c445bce0cc110ac3be281ca6ff87" integrity sha512-S8cgntEDdXrOwdylVGDh1BFe+nX5uuUzzb3teh1FE++/kbqsOfUpXOYRUsEzsqb0fRqcm6eLxvtNb282Zr67rQ== dependencies: babel6-plugin-strip-class-callcheck "^6.0.0" @@ -1938,7 +2002,7 @@ "@humanwhocodes/config-array@^0.5.0": version "0.5.0" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== dependencies: "@humanwhocodes/object-schema" "^1.2.0" @@ -1947,12 +2011,12 @@ "@humanwhocodes/object-schema@^1.2.0": version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" - resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: camelcase "^5.3.1" @@ -1963,72 +2027,79 @@ "@istanbuljs/schema@^0.1.2": version "0.1.3" - resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== +"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== dependencies: - "@jridgewell/set-array" "^1.0.0" + "@jridgewell/set-array" "^1.2.1" "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@lit-labs/ssr-dom-shim@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz" - integrity sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw== + version "1.2.0" + resolved "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz#353ce4a76c83fadec272ea5674ede767650762fd" + integrity sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g== "@lit/reactive-element@^1.2.1": - version "1.6.1" - resolved "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.1.tgz" - integrity sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA== + version "1.6.3" + resolved "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz#25b4eece2592132845d303e091bad9b04cdcfe03" + integrity sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ== dependencies: "@lit-labs/ssr-dom-shim" "^1.0.0" +"@ljharb/resumer@^0.1.3": + version "0.1.3" + resolved "https://registry.npmjs.org/@ljharb/resumer/-/resumer-0.1.3.tgz#5ef4a4958da1b4e71ffea8ef33499cc622672d89" + integrity sha512-d+tsDgfkj9X5QTriqM4lKesCkMMJC3IrbPKHvayP00ELx2axdXvDfWkqjxrLXIzGcQzmj7VAUT1wopqARTvafw== + dependencies: + "@ljharb/through" "^2.3.13" + call-bind "^1.0.7" + +"@ljharb/through@^2.3.13": + version "2.3.13" + resolved "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz#b7e4766e0b65aa82e529be945ab078de79874edc" + integrity sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ== + dependencies: + call-bind "^1.0.7" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" - resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz" + resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== dependencies: call-me-maybe "^1.0.1" @@ -2036,7 +2107,7 @@ "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -2044,49 +2115,49 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.stat@^1.1.2": version "1.1.3" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" "@popperjs/core@^2.9.0": - version "2.11.6" - resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz" - integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== + version "2.11.8" + resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== "@simple-dom/interface@^1.4.0": version "1.4.0" - resolved "https://registry.npmjs.org/@simple-dom/interface/-/interface-1.4.0.tgz" + resolved "https://registry.npmjs.org/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" integrity sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA== "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1": version "1.8.6" - resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== dependencies: type-detect "4.0.8" "@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1": version "6.0.1" - resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== dependencies: "@sinonjs/commons" "^1.7.0" "@sinonjs/samsam@^5.3.1": version "5.3.1" - resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz" + resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg== dependencies: "@sinonjs/commons" "^1.6.0" @@ -2095,22 +2166,22 @@ "@sinonjs/text-encoding@^0.7.1": version "0.7.2" - resolved "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz" + resolved "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== "@socket.io/component-emitter@~3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz" - integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== + version "3.1.2" + resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" + integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== "@textlint/ast-node-types@^12.6.1": version "12.6.1" - resolved "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-12.6.1.tgz" + resolved "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-12.6.1.tgz#35ecefe74e701d7f632c083d4fda89cab1b89012" integrity sha512-uzlJ+ZsCAyJm+lBi7j0UeBbj+Oy6w/VWoGJ3iHRHE5eZ8Z4iK66mq+PG/spupmbllLtz77OJbY89BYqgFyjXmA== "@textlint/markdown-to-ast@^12.1.1": version "12.6.1" - resolved "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-12.6.1.tgz" + resolved "https://registry.npmjs.org/@textlint/markdown-to-ast/-/markdown-to-ast-12.6.1.tgz#fcccb5733b3e76cd0db78a323763ab101f2d803b" integrity sha512-T0HO+VrU9VbLRiEx/kH4+gwGMHNMIGkp0Pok+p0I33saOOLyhfGvwOKQgvt2qkxzQEV2L5MtGB8EnW4r5d3CqQ== dependencies: "@textlint/ast-node-types" "^12.6.1" @@ -2125,89 +2196,90 @@ "@tootallnate/once@1": version "1.1.2" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/body-parser@*": - version "1.19.2" - resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + version "1.19.5" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" "@types/node" "*" "@types/broccoli-plugin@^3.0.0": version "3.0.0" - resolved "https://registry.npmjs.org/@types/broccoli-plugin/-/broccoli-plugin-3.0.0.tgz" + resolved "https://registry.npmjs.org/@types/broccoli-plugin/-/broccoli-plugin-3.0.0.tgz#290fda2270c47a568edfd0cefab8bb840d8bb7b2" integrity sha512-f+TcsARR2PovfFRKFdCX0kfH/QoM3ZVD2h1rl2mNvrKO0fq2uBNCBsTU3JanfU4COCt5cXpTfARyUsERlC8vIw== dependencies: broccoli-plugin "*" "@types/chai-as-promised@^7.1.2": - version "7.1.5" - resolved "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== + version "7.1.8" + resolved "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz#f2b3d82d53c59626b5d6bbc087667ccb4b677fe9" + integrity sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw== dependencies: "@types/chai" "*" "@types/chai@*", "@types/chai@^4.2.9": - version "4.3.4" - resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz" - integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== + version "4.3.16" + resolved "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz#b1572967f0b8b60bf3f87fe1d854a5604ea70c82" + integrity sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ== "@types/connect@*": - version "3.4.35" - resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + version "3.4.38" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/cookie@^0.4.1": version "0.4.1" - resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz" + resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== "@types/cors@^2.8.12": - version "2.8.13" - resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz" - integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + version "2.8.17" + resolved "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b" + integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== dependencies: "@types/node" "*" "@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + version "3.7.7" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.21.1" - resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.1.tgz" - integrity sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ== + version "8.56.10" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz#eb2370a73bf04a901eeba8f22595c7ee0f7eb58d" + integrity sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@*", "@types/estree@^1.0.5": + version "1.0.5" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/express-serve-static-core@^4.17.33": - version "4.17.33" - resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz" - integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA== + version "4.19.5" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz#218064e321126fcf9048d1ca25dd2465da55d9c6" + integrity sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" + "@types/send" "*" "@types/express@^4.17.2": - version "4.17.17" - resolved "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz" - integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + version "4.17.21" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -2216,21 +2288,21 @@ "@types/fs-extra@^5.0.5": version "5.1.0" - resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" integrity sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ== dependencies: "@types/node" "*" "@types/fs-extra@^8.1.0": - version "8.1.2" - resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz" - integrity sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg== + version "8.1.5" + resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz#33aae2962d3b3ec9219b5aca2555ee00274f5927" + integrity sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ== dependencies: "@types/node" "*" "@types/glob@*": version "8.1.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz" + resolved "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" integrity sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w== dependencies: "@types/minimatch" "^5.1.2" @@ -2238,190 +2310,206 @@ "@types/glob@^7.1.1": version "7.2.0" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" "@types/node" "*" "@types/hast@^2.0.0": - version "2.3.4" - resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz" - integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + version "2.3.10" + resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz#5c9d9e0b304bbb8879b857225c5ebab2d81d7643" + integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw== dependencies: - "@types/unist" "*" + "@types/unist" "^2" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== "@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + version "7.0.15" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/mdast@^3.0.0", "@types/mdast@^3.0.3": - version "3.0.10" - resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz" - integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== + version "3.0.15" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" + integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== dependencies: - "@types/unist" "*" + "@types/unist" "^2" -"@types/mime@*": - version "3.0.1" - resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz" - integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== -"@types/minimatch@*", "@types/minimatch@^3.0.3", "@types/minimatch@^3.0.4": - version "3.0.5" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/minimatch@^5.1.2": +"@types/minimatch@*", "@types/minimatch@^5.1.2": version "5.1.2" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== +"@types/minimatch@^3.0.3", "@types/minimatch@^3.0.4": + version "3.0.5" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + "@types/node@*", "@types/node@>=10.0.0": - version "18.15.0" - resolved "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz" - integrity sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w== + version "20.14.10" + resolved "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a" + integrity sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ== + dependencies: + undici-types "~5.26.4" "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "4.0.2" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/qs@*": - version "6.9.7" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + version "6.9.15" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" + integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg== "@types/range-parser@*": - version "1.2.4" - resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + version "1.2.7" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/rimraf@^2.0.2", "@types/rimraf@^2.0.3": version "2.0.5" - resolved "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.5.tgz" + resolved "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.5.tgz#368fb04d59630b727fc05a74d2ca557f64a8ef98" integrity sha512-YyP+VfeaqAyFmXoTh3HChxOQMyjByRMsHU7kc5KOJkSlXudhMhQIALbYV7rHh/l8d2lX3VUQzprrcAgWdRuU8g== dependencies: "@types/glob" "*" "@types/node" "*" -"@types/serve-static@*": - version "1.15.1" - resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz" - integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== +"@types/send@*": + version "0.17.4" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: - "@types/mime" "*" + "@types/mime" "^1" "@types/node" "*" -"@types/symlink-or-copy@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz" - integrity sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg== - -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.6" - resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@types/serve-static@*": + version "1.15.7" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "*" + +"@types/symlink-or-copy@^1.2.0": + version "1.2.2" + resolved "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.2.tgz#51b1c00b516a5774ada5d611e65eb123f988ef8d" + integrity sha512-MQ1AnmTLOncwEf9IVU+B2e4Hchrku5N67NkgcAHW0p3sdzPe0FNMANxEm6OJUzPniEQGkeT3OROLlCwZJLWFZA== + +"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": + version "2.0.10" + resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" + integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== + +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ast@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== dependencies: "@webassemblyjs/helper-module-context" "1.9.0" "@webassemblyjs/helper-wasm-bytecode" "1.9.0" "@webassemblyjs/wast-parser" "1.9.0" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== "@webassemblyjs/floating-point-hex-parser@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== "@webassemblyjs/helper-api-error@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== "@webassemblyjs/helper-buffer@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== "@webassemblyjs/helper-code-frame@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== dependencies: "@webassemblyjs/wast-printer" "1.9.0" "@webassemblyjs/helper-fsm@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== "@webassemblyjs/helper-module-context@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== dependencies: "@webassemblyjs/ast" "1.9.0" -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== "@webassemblyjs/helper-wasm-bytecode@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/helper-wasm-section@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2429,61 +2517,47 @@ "@webassemblyjs/helper-wasm-bytecode" "1.9.0" "@webassemblyjs/wasm-gen" "1.9.0" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" "@webassemblyjs/ieee754@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" "@webassemblyjs/leb128@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== "@webassemblyjs/utf8@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - "@webassemblyjs/wasm-edit@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2495,20 +2569,34 @@ "@webassemblyjs/wasm-parser" "1.9.0" "@webassemblyjs/wast-printer" "1.9.0" -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" "@webassemblyjs/wasm-gen@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2517,19 +2605,19 @@ "@webassemblyjs/leb128" "1.9.0" "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" "@webassemblyjs/wasm-opt@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2537,21 +2625,21 @@ "@webassemblyjs/wasm-gen" "1.9.0" "@webassemblyjs/wasm-parser" "1.9.0" -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" "@webassemblyjs/wasm-parser@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2563,7 +2651,7 @@ "@webassemblyjs/wast-parser@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2573,17 +2661,17 @@ "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== dependencies: - "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@webassemblyjs/wast-printer@1.9.0": version "1.9.0" - resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: "@webassemblyjs/ast" "1.9.0" @@ -2591,50 +2679,50 @@ "@xtuc/long" "4.2.2" "@xmldom/xmldom@^0.8.0": - version "0.8.6" - resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.6.tgz" - integrity sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg== + version "0.8.10" + resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== "@xstate/fsm@^1.4.0": version "1.6.5" - resolved "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz" + resolved "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz#f599e301997ad7e3c572a0b1ff0696898081bea5" integrity sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw== "@xtuc/ieee754@^1.2.0": version "1.2.0" - resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== "@xtuc/long@4.2.2": version "4.2.2" - resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== JSV@^4.0.x: version "4.0.2" - resolved "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz" + resolved "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" integrity sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw== a11y-dialog@^6.0.1: - version "6.1.1" - resolved "https://registry.npmjs.org/a11y-dialog/-/a11y-dialog-6.1.1.tgz" - integrity sha512-bMvrxCupDFZJVHNVZFibO+qL6/BMmGI3d9oRIKpzwFpuidwe9czIrHXw256dieA0nCRadqm0GlMaK2JfqcLDkA== + version "6.1.2" + resolved "https://registry.npmjs.org/a11y-dialog/-/a11y-dialog-6.1.2.tgz#7c6a1d3720462db2f2fde6badba63478fd3cc871" + integrity sha512-mBKuYGXb3tZOztkQjdCXC+ryqbqGXHmIIqxdto/1jfDlSc7eBRGrS1XqL5KJpSCnG2VTSPsP4ONve1HPu4lmQw== dependencies: focusable-selectors "^0.3.0" abab@^2.0.3, abab@^2.0.5: version "2.0.6" - resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz" + resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== abbrev@1: version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: mime-types "~2.1.34" @@ -2642,61 +2730,52 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: acorn-globals@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz" + resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== dependencies: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn-jsx@^5.3.1: version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-node@^1.8.2: - version "1.8.2" - resolved "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz" - integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== - dependencies: - acorn "^7.0.0" - acorn-walk "^7.0.0" - xtend "^4.0.2" - -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.1.1: version "7.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn@^6.4.1: version "6.4.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" + resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" + resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2: + version "8.12.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== agent-base@6: version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -2704,31 +2783,31 @@ aggregate-error@^3.0.0: ajv-errors@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz" + resolved "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-formats@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" + resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== dependencies: ajv "^8.0.0" ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: +ajv-keywords@^5.1.0: version "5.1.0" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -2736,26 +2815,26 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0: - version "8.12.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== +ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0: + version "8.16.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz#22e2a92b94f005f7e0f9c9d39652ef0b8f6f0cb4" + integrity sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw== dependencies: - fast-deep-equal "^3.1.1" + fast-deep-equal "^3.1.3" json-schema-traverse "^1.0.0" require-from-string "^2.0.2" - uri-js "^4.2.2" + uri-js "^4.4.1" amd-name-resolver@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/amd-name-resolver/-/amd-name-resolver-1.2.0.tgz" + resolved "https://registry.npmjs.org/amd-name-resolver/-/amd-name-resolver-1.2.0.tgz#fc41b3848824b557313897d71f8d5a0184fbe679" integrity sha512-hlSTWGS1t6/xq5YCed7YALg7tKZL3rkl7UwEZ/eCIkn8JxmM6fU6Qs/1hwtjQqfuYxlffuUcgYEm0f5xP4YKaA== dependencies: ensure-posix-path "^1.0.1" amd-name-resolver@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/amd-name-resolver/-/amd-name-resolver-1.3.1.tgz" + resolved "https://registry.npmjs.org/amd-name-resolver/-/amd-name-resolver-1.3.1.tgz#ffe71c683c6e7191fc4ae1bb3aaed15abea135d9" integrity sha512-26qTEWqZQ+cxSYygZ4Cf8tsjDBLceJahhtewxtKZA3SRa4PluuqYCuheemDQD+7Mf5B7sr+zhTDWAHDh02a1Dw== dependencies: ensure-posix-path "^1.0.1" @@ -2763,97 +2842,102 @@ amd-name-resolver@^1.3.1: amdefine@>=0.0.4: version "1.0.1" - resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz" + resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== anchor-markdown-header@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.6.0.tgz" + resolved "https://registry.npmjs.org/anchor-markdown-header/-/anchor-markdown-header-0.6.0.tgz#908f2031281766f44ac350380ca0de77ab7065b8" integrity sha512-v7HJMtE1X7wTpNFseRhxsY/pivP4uAJbidVhPT+yhz4i/vV1+qx371IXuV9V7bN6KjFtheLJxqaSm0Y/8neJTA== dependencies: emoji-regex "~10.1.0" ansi-colors@^4.1.1: version "4.1.3" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-escapes@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-html@^0.0.7: version "0.0.7" - resolved "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz" + resolved "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" integrity sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA== ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== ansi-regex@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== ansi-regex@^4.1.0: version "4.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== ansi-styles@^3.0.0, ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" ansi-styles@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" integrity sha512-3iF4FIKdxaVYT3JqQuY3Wat/T2t7TRbbQ94Fu50ZUCbLy4TFbTzr90NOHQodQkNqmeEGCw8WbeP78WNi6SKYUA== ansi-to-html@^0.6.15, ansi-to-html@^0.6.6: version "0.6.15" - resolved "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.15.tgz" + resolved "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7" integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ== dependencies: entities "^2.0.0" ansicolors@~0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz" + resolved "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" integrity sha512-tOIuy1/SK/dr94ZA0ckDohKXNeBNqZ4us6PjMVLs5h1w2GBB6uPtOknp2+VF4F/zcy9LI70W+Z+pE2Soajky1w== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + anymatch@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== dependencies: micromatch "^3.1.4" @@ -2861,7 +2945,7 @@ anymatch@^2.0.0: anymatch@~3.1.2: version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -2869,19 +2953,24 @@ anymatch@~3.1.2: aot-test-generators@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/aot-test-generators/-/aot-test-generators-0.1.0.tgz" + resolved "https://registry.npmjs.org/aot-test-generators/-/aot-test-generators-0.1.0.tgz#43f0f615f97cb298d7919c1b0b4e6b7310b03cd0" integrity sha512-PKyBQsPgkrCbUZS0PexdnyS3pVfYe4U1dLLQOf3is5RcYSaxbA7fsnnj6i8hcubsz+iS0miGPSJlONv/tXjfiA== dependencies: jsesc "^2.5.0" -aproba@^1.0.3, "aproba@^1.0.3 || ^2.0.0", aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" + resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + are-we-there-yet@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== dependencies: delegates "^1.0.0" @@ -2889,7 +2978,7 @@ are-we-there-yet@^3.0.0: are-we-there-yet@~1.1.2: version "1.1.7" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== dependencies: delegates "^1.0.0" @@ -2897,134 +2986,156 @@ are-we-there-yet@~1.1.2: arg@^5.0.2: version "5.0.2" - resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" + resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== argparse@^1.0.7: version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== arr-diff@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== arr-flatten@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== +array-buffer-byte-length@^1.0.0, array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz" - integrity sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA== + version "1.0.2" + resolved "https://registry.npmjs.org/array-equal/-/array-equal-1.0.2.tgz#a8572e64e822358271250b9156d20d96ef5dec04" + integrity sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA== array-find-index@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz" + resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== array-flatten@1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== array-range@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/array-range/-/array-range-1.0.1.tgz" + resolved "https://registry.npmjs.org/array-range/-/array-range-1.0.1.tgz#f56e46591843611c6a56f77ef02eda7c50089bfc" integrity sha512-shdaI1zT3CVNL2hnx9c0JMc0ZogGaxDs5e85akgHWKYa0yVbIyp06Ind3dVkTj/uuFrzaHBOyqFzo+VV6aXgtA== array-to-error@^1.0.0: version "1.1.1" - resolved "https://registry.npmjs.org/array-to-error/-/array-to-error-1.1.1.tgz" + resolved "https://registry.npmjs.org/array-to-error/-/array-to-error-1.1.1.tgz#d68812926d14097a205579a667eeaf1856a44c07" integrity sha512-kqcQ8s7uQfg3UViYON3kCMcck3A9exxgq+riVuKy08Mx00VN4EJhK30L2VpjE58LQHKhcE/GRpvbVUhqTvqzGQ== dependencies: array-to-sentence "^1.1.0" array-to-sentence@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/array-to-sentence/-/array-to-sentence-1.1.0.tgz" + resolved "https://registry.npmjs.org/array-to-sentence/-/array-to-sentence-1.1.0.tgz#c804956dafa53232495b205a9452753a258d39fc" integrity sha512-YkwkMmPA2+GSGvXj1s9NZ6cc2LBtR+uSeWTy2IGi5MR1Wag4DdrcjTxA/YV/Fw+qKlBeXomneZgThEbm/wvZbw== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== array-unique@^0.3.2: version "0.3.2" - resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== -array.prototype.every@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/array.prototype.every/-/array.prototype.every-1.1.4.tgz" - integrity sha512-Aui35iRZk1HHLRAyF7QP0KAnOnduaQ6fo6k1NVWfRc0xTs2AZ70ytlXvOmkC6Di4JmUs2Wv3DYzGtCQFSk5uGg== +array.prototype.every@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/array.prototype.every/-/array.prototype.every-1.1.6.tgz#1717b407d019913250317300d814a1b6660f10d7" + integrity sha512-gNEqZD97w6bfQRNmHkFv7rNnGM+VWyHZT+h/rf9C+22owcXuENr66Lfo0phItpU5KoXW6Owb34q2+8MnSIZ57w== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" is-string "^1.0.7" +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== + dependencies: + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" + asap@^2.0.0: version "2.0.6" - resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== -asn1.js@^5.2.0: - version "5.4.1" - resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz" - integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== +asn1.js@^4.10.1: + version "4.10.1" + resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== dependencies: bn.js "^4.0.0" inherits "^2.0.1" minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" assert-never@^1.1.0, assert-never@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz" - integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== + version "1.3.0" + resolved "https://registry.npmjs.org/assert-never/-/assert-never-1.3.0.tgz#c53cf3ad8fcdb67f400a941dea66dac7fe82dd2e" + integrity sha512-9Z3vxQ+berkL/JJo0dK+EY3Lp0s3NtSnP3VCLsh5HDcZPrh0M+KQRK5sWhUeyPPH+/RCxZqOxLMR+YC6vlviEQ== assert@^1.1.1: - version "1.5.0" - resolved "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + version "1.5.1" + resolved "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz#038ab248e4ff078e7bc2485ba6e6388466c78f76" + integrity sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A== dependencies: - object-assign "^4.1.1" - util "0.10.3" + object.assign "^4.1.4" + util "^0.10.4" assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== ast-types@0.13.3: version "0.13.3" - resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.3.tgz" + resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.3.tgz#50da3f28d17bdbc7969a3a2d83a0e4a72ae755a7" integrity sha512-XTZ7xGML849LkQP86sWdQzfhwbt3YwIO6MqbX9mUNYY98VKaaVZP7YNNm70IpwecbkkxmfC5IYAzOQ/2p29zRA== astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async-disk-cache@^1.2.1: version "1.3.5" - resolved "https://registry.npmjs.org/async-disk-cache/-/async-disk-cache-1.3.5.tgz" + resolved "https://registry.npmjs.org/async-disk-cache/-/async-disk-cache-1.3.5.tgz#cc6206ed79bb6982b878fc52e0505e4f52b62a02" integrity sha512-VZpqfR0R7CEOJZ/0FOTgWq70lCrZyS1rkI8PXugDUkTKyyAUgZ2zQ09gLhMkEn+wN8LYeUTPxZdXtlX/kmbXKQ== dependencies: debug "^2.1.3" @@ -3037,7 +3148,7 @@ async-disk-cache@^1.2.1: async-disk-cache@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/async-disk-cache/-/async-disk-cache-2.1.0.tgz" + resolved "https://registry.npmjs.org/async-disk-cache/-/async-disk-cache-2.1.0.tgz#e0f37b187ed8c41a5991518a9556d206ae2843a2" integrity sha512-iH+boep2xivfD9wMaZWkywYIURSmsL96d6MoqrC94BnGSvXE4Quf8hnJiHGFYhw/nLeIa1XyRaf4vvcvkwAefg== dependencies: debug "^4.1.1" @@ -3050,12 +3161,12 @@ async-disk-cache@^2.0.0: async-each@^1.0.1: version "1.0.6" - resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz" + resolved "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/async-promise-queue/-/async-promise-queue-1.0.5.tgz" + resolved "https://registry.npmjs.org/async-promise-queue/-/async-promise-queue-1.0.5.tgz#cb23bce9fce903a133946a700cc85f27f09ea49d" integrity sha512-xi0aQ1rrjPWYmqbwr18rrSKbSaXIeIwSd1J4KAgVfkq8utNbdZoht7GfvfY6swFUAMJ9obkc4WPJmtGwl+B8dw== dependencies: async "^2.4.1" @@ -3063,51 +3174,53 @@ async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: async@^2.4.1, async@^2.6.4: version "2.6.4" - resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" + resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" async@~0.2.9: version "0.2.10" - resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz" + resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" integrity sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ== asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== at-least-node@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== atob@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^10.4.8: - version "10.4.14" - resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" - integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + version "10.4.19" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f" + integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew== dependencies: - browserslist "^4.21.5" - caniuse-lite "^1.0.30001464" - fraction.js "^4.2.0" + browserslist "^4.23.0" + caniuse-lite "^1.0.30001599" + fraction.js "^4.3.7" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" babel-code-frame@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g== dependencies: chalk "^1.1.3" @@ -3116,7 +3229,7 @@ babel-code-frame@^6.26.0: babel-core@^6.26.0, babel-core@^6.26.3: version "6.26.3" - resolved "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz" + resolved "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== dependencies: babel-code-frame "^6.26.0" @@ -3141,7 +3254,7 @@ babel-core@^6.26.0, babel-core@^6.26.3: babel-eslint@^10.0.3: version "10.1.0" - resolved "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz" + resolved "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== dependencies: "@babel/code-frame" "^7.0.0" @@ -3153,7 +3266,7 @@ babel-eslint@^10.0.3: babel-generator@^6.26.0: version "6.26.1" - resolved "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz" + resolved "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== dependencies: babel-messages "^6.23.0" @@ -3167,7 +3280,7 @@ babel-generator@^6.26.0: babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" integrity sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q== dependencies: babel-helper-explode-assignable-expression "^6.24.1" @@ -3176,7 +3289,7 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-helper-call-delegate@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" integrity sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ== dependencies: babel-helper-hoist-variables "^6.24.1" @@ -3186,7 +3299,7 @@ babel-helper-call-delegate@^6.24.1: babel-helper-define-map@^6.24.1: version "6.26.0" - resolved "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" integrity sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA== dependencies: babel-helper-function-name "^6.24.1" @@ -3196,7 +3309,7 @@ babel-helper-define-map@^6.24.1: babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" integrity sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ== dependencies: babel-runtime "^6.22.0" @@ -3205,7 +3318,7 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-helper-function-name@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" integrity sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q== dependencies: babel-helper-get-function-arity "^6.24.1" @@ -3216,7 +3329,7 @@ babel-helper-function-name@^6.24.1: babel-helper-get-function-arity@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" integrity sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng== dependencies: babel-runtime "^6.22.0" @@ -3224,7 +3337,7 @@ babel-helper-get-function-arity@^6.24.1: babel-helper-hoist-variables@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" integrity sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw== dependencies: babel-runtime "^6.22.0" @@ -3232,7 +3345,7 @@ babel-helper-hoist-variables@^6.24.1: babel-helper-optimise-call-expression@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" integrity sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA== dependencies: babel-runtime "^6.22.0" @@ -3240,7 +3353,7 @@ babel-helper-optimise-call-expression@^6.24.1: babel-helper-regex@^6.24.1: version "6.26.0" - resolved "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" integrity sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg== dependencies: babel-runtime "^6.26.0" @@ -3249,7 +3362,7 @@ babel-helper-regex@^6.24.1: babel-helper-remap-async-to-generator@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" integrity sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg== dependencies: babel-helper-function-name "^6.24.1" @@ -3260,7 +3373,7 @@ babel-helper-remap-async-to-generator@^6.24.1: babel-helper-replace-supers@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" integrity sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw== dependencies: babel-helper-optimise-call-expression "^6.24.1" @@ -3272,7 +3385,7 @@ babel-helper-replace-supers@^6.24.1: babel-helpers@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" integrity sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ== dependencies: babel-runtime "^6.22.0" @@ -3280,22 +3393,27 @@ babel-helpers@^6.24.1: babel-import-util@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-0.2.0.tgz" + resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-0.2.0.tgz#b468bb679919601a3570f9e317536c54f2862e23" integrity sha512-CtWYYHU/MgK88rxMrLfkD356dApswtR/kWZ/c6JifG1m10e7tBBrs/366dFzWMAoqYmG5/JSh+94tUSpIwh+ag== babel-import-util@^1.1.0: - version "1.3.0" - resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-1.3.0.tgz" - integrity sha512-PPzUT17eAI18zn6ek1R3sB4Krc/MbnmT1MkZQFmyhjoaEGBVwNABhfVU9+EKcDSKrrOm9OIpGhjxukx1GCiy1g== + version "1.4.1" + resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-1.4.1.tgz#1df6fd679845df45494bac9ca12461d49497fdd4" + integrity sha512-TNdiTQdPhXlx02pzG//UyVPSKE7SNWjY0n4So/ZnjQpWwaM5LvWBLkWa1JKll5u06HNscHD91XZPuwrMg1kadQ== babel-import-util@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-2.0.1.tgz" - integrity sha512-N1ZfNprtf/37x0R05J0QCW/9pCAcuI+bjZIK9tlu0JEkwEST7ssdD++gxHRbD58AiG5QE5OuNYhRoEFsc1wESw== + version "2.1.1" + resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-2.1.1.tgz#0f4905fe899abfb8cd835dd52f3df1966d1ffbb0" + integrity sha512-3qBQWRjzP9NreSH/YrOEU1Lj5F60+pWSLP0kIdCWxjFHH7pX2YPHIxQ67el4gnMNfYoDxSDGcT0zpVlZ+gVtQA== + +babel-import-util@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/babel-import-util/-/babel-import-util-3.0.0.tgz#5814c6a58e7b80e64156b48fdfd34d48e6e0b1df" + integrity sha512-4YNPkuVsxAW5lnSTa6cn4Wk49RX6GAB6vX+M6LqEtN0YePqoFczv1/x0EyLK/o+4E1j9jEuYj5Su7IEPab5JHQ== babel-loader@^8.0.6, babel-loader@^8.1.0: version "8.3.0" - resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz" + resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== dependencies: find-cache-dir "^3.3.1" @@ -3305,64 +3423,64 @@ babel-loader@^8.0.6, babel-loader@^8.1.0: babel-messages@^6.23.0: version "6.23.0" - resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz" + resolved "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" integrity sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w== dependencies: babel-runtime "^6.22.0" babel-plugin-check-es2015-constants@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" integrity sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA== dependencies: babel-runtime "^6.22.0" babel-plugin-debug-macros@^0.2.0, babel-plugin-debug-macros@^0.2.0-beta.6: version "0.2.0" - resolved "https://registry.npmjs.org/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.2.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.2.0.tgz#0120ac20ce06ccc57bf493b667cf24b85c28da7a" integrity sha512-Wpmw4TbhR3Eq2t3W51eBAQSdKlr+uAyF0GI4GtPfMCD12Y4cIdpKC9l0RjNTH/P9isFypSqqewMPm7//fnZlNA== dependencies: semver "^5.3.0" babel-plugin-debug-macros@^0.3.3, babel-plugin-debug-macros@^0.3.4: version "0.3.4" - resolved "https://registry.npmjs.org/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.3.4.tgz" + resolved "https://registry.npmjs.org/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.3.4.tgz#22961d0cb851a80654cece807a8b4b73d85c6075" integrity sha512-wfel/vb3pXfwIDZUrkoDrn5FHmlWI96PCJ3UCDv2a86poJ3EQrnArNW5KfHSVJ9IOgxHbo748cQt7sDU+0KCEw== dependencies: semver "^5.3.0" babel-plugin-ember-data-packages-polyfill@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/babel-plugin-ember-data-packages-polyfill/-/babel-plugin-ember-data-packages-polyfill-0.1.2.tgz" + resolved "https://registry.npmjs.org/babel-plugin-ember-data-packages-polyfill/-/babel-plugin-ember-data-packages-polyfill-0.1.2.tgz#21154c095ddc703722b1fb8bb06c126c0b6d77dc" integrity sha512-kTHnOwoOXfPXi00Z8yAgyD64+jdSXk3pknnS7NlqnCKAU6YDkXZ4Y7irl66kaZjZn0FBBt0P4YOZFZk85jYOww== dependencies: "@ember-data/rfc395-data" "^0.0.4" babel-plugin-ember-modules-api-polyfill@^2.6.0: version "2.13.4" - resolved "https://registry.npmjs.org/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.13.4.tgz" + resolved "https://registry.npmjs.org/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.13.4.tgz#cf62bc9bfd808c48d810d5194f4329e9453bd603" integrity sha512-uxQPkEQAzCYdwhZk16O9m1R4xtCRNy4oEUTBrccOPfzlIahRZJic/JeP/ZEL0BC6Mfq6r55eOg6gMF/zdFoCvA== dependencies: ember-rfc176-data "^0.3.13" babel-plugin-ember-modules-api-polyfill@^3.2.0, babel-plugin-ember-modules-api-polyfill@^3.5.0: version "3.5.0" - resolved "https://registry.npmjs.org/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-3.5.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-3.5.0.tgz#27b6087fac75661f779f32e60f94b14d0e9f6965" integrity sha512-pJajN/DkQUnStw0Az8c6khVcMQHgzqWr61lLNtVeu0g61LRW0k9jyK7vaedrHDWGe/Qe8sxG5wpiyW9NsMqFzA== dependencies: ember-rfc176-data "^0.3.17" babel-plugin-ember-template-compilation@^2.0.0, babel-plugin-ember-template-compilation@^2.0.1: - version "2.2.0" - resolved "https://registry.npmjs.org/babel-plugin-ember-template-compilation/-/babel-plugin-ember-template-compilation-2.2.0.tgz" - integrity sha512-1I7f5gf06h5wKdKUvaYEIaoSFur5RLUvTMQG4ak0c5Y11DWUxcoX9hrun1xe9fqfY2dtGFK+ZUM6sn6z8sqK/w== + version "2.2.5" + resolved "https://registry.npmjs.org/babel-plugin-ember-template-compilation/-/babel-plugin-ember-template-compilation-2.2.5.tgz#9f00cc88eeefdc7d228cfac63c2a40e59691fbf3" + integrity sha512-NQ2DT0DsYyHVrEpFQIy2U8S91JaKSE8NOSZzMd7KZFJVgA6KodJq3Uj852HcH9LsSfvwppnM+dRo1G8bzTnnFw== dependencies: "@glimmer/syntax" "^0.84.3" - babel-import-util "^2.0.0" + babel-import-util "^3.0.0" babel-plugin-filter-imports@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/babel-plugin-filter-imports/-/babel-plugin-filter-imports-4.0.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-filter-imports/-/babel-plugin-filter-imports-4.0.0.tgz#068f8da15236a96a9602c36dc6f4a6eeca70a4f4" integrity sha512-jDLlxI8QnfKd7PtieH6pl4tZJzymzfCDCPGdTq/grgbiYAikwDPp/oL0IlFJn0HQjLpcLkyYhPKkUVneRESw5w== dependencies: "@babel/types" "^7.7.2" @@ -3370,12 +3488,12 @@ babel-plugin-filter-imports@^4.0.0: babel-plugin-htmlbars-inline-precompile@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-3.2.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-3.2.0.tgz#c4882ea875d0f5683f0d91c1f72e29a4f14b5606" integrity sha512-IUeZmgs9tMUGXYu1vfke5I18yYJFldFGdNFQOWslXTnDWXzpwPih7QFduUqvT+awDpDuNtXpdt5JAf43Q1Hhzg== babel-plugin-htmlbars-inline-precompile@^5.0.0, babel-plugin-htmlbars-inline-precompile@^5.2.1, babel-plugin-htmlbars-inline-precompile@^5.3.0: version "5.3.1" - resolved "https://registry.npmjs.org/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-5.3.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-5.3.1.tgz#5ba272e2e4b6221522401f5f1d98a73b1de38787" integrity sha512-QWjjFgSKtSRIcsBhJmEwS2laIdrA6na8HAlc/pEAhjHgQsah/gMiBFRZvbQTy//hWxR4BMwV7/Mya7q5H8uHeA== dependencies: babel-plugin-ember-modules-api-polyfill "^3.5.0" @@ -3386,7 +3504,7 @@ babel-plugin-htmlbars-inline-precompile@^5.0.0, babel-plugin-htmlbars-inline-pre babel-plugin-istanbul@^6.0.0: version "6.1.1" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -3397,7 +3515,7 @@ babel-plugin-istanbul@^6.0.0: babel-plugin-module-resolver@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz#ddfa5e301e3b9aa12d852a9979f18b37881ff5a7" integrity sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA== dependencies: find-babel-config "^1.1.0" @@ -3408,7 +3526,7 @@ babel-plugin-module-resolver@^3.2.0: babel-plugin-module-resolver@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz#22a4f32f7441727ec1fbf4967b863e1e3e9f33e2" integrity sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA== dependencies: find-babel-config "^1.2.0" @@ -3417,58 +3535,69 @@ babel-plugin-module-resolver@^4.1.0: reselect "^4.0.0" resolve "^1.13.1" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-module-resolver@^5.0.0: + version "5.0.2" + resolved "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz#cdeac5d4aaa3b08dd1ac23ddbf516660ed2d293e" + integrity sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + find-babel-config "^2.1.1" + glob "^9.3.3" + pkg-up "^3.1.0" + reselect "^4.1.7" + resolve "^1.22.8" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs2@^0.4.10: + version "0.4.11" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" + integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.6.2" + semver "^6.3.1" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-corejs3@^0.10.1, babel-plugin-polyfill-corejs3@^0.10.4: + version "0.10.4" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz#789ac82405ad664c20476d0233b485281deb9c77" + integrity sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.6.1" + core-js-compat "^3.36.1" + +babel-plugin-polyfill-regenerator@^0.6.1: + version "0.6.2" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" + integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.2" babel-plugin-strip-function-call@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/babel-plugin-strip-function-call/-/babel-plugin-strip-function-call-1.0.2.tgz" + resolved "https://registry.npmjs.org/babel-plugin-strip-function-call/-/babel-plugin-strip-function-call-1.0.2.tgz#374a68b5648e16e2b6d1effd280c3abc88648e3a" integrity sha512-2K0dgOk0AMceFHEpizpQU35nVwZ3HdygyXDedVv88+UkxjAH88k7ns8giaRkc8Tfjw6fPDvHkTC40xbI3bpbUA== babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" integrity sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw== babel-plugin-syntax-dynamic-import@^6.18.0: version "6.18.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" integrity sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA== babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" integrity sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ== babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" integrity sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ== babel-plugin-transform-async-to-generator@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" integrity sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw== dependencies: babel-helper-remap-async-to-generator "^6.24.1" @@ -3477,21 +3606,21 @@ babel-plugin-transform-async-to-generator@^6.22.0: babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" integrity sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" integrity sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" integrity sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw== dependencies: babel-runtime "^6.26.0" @@ -3502,7 +3631,7 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0: babel-plugin-transform-es2015-classes@^6.23.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" integrity sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag== dependencies: babel-helper-define-map "^6.24.1" @@ -3517,7 +3646,7 @@ babel-plugin-transform-es2015-classes@^6.23.0: babel-plugin-transform-es2015-computed-properties@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" integrity sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw== dependencies: babel-runtime "^6.22.0" @@ -3525,14 +3654,14 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0: babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" integrity sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-duplicate-keys@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" integrity sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug== dependencies: babel-runtime "^6.22.0" @@ -3540,14 +3669,14 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0: babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" integrity sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-function-name@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" integrity sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg== dependencies: babel-helper-function-name "^6.24.1" @@ -3556,14 +3685,14 @@ babel-plugin-transform-es2015-function-name@^6.22.0: babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" integrity sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" integrity sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA== dependencies: babel-plugin-transform-es2015-modules-commonjs "^6.24.1" @@ -3572,7 +3701,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.2" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== dependencies: babel-plugin-transform-strict-mode "^6.24.1" @@ -3582,7 +3711,7 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e babel-plugin-transform-es2015-modules-systemjs@^6.23.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" integrity sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg== dependencies: babel-helper-hoist-variables "^6.24.1" @@ -3591,7 +3720,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.23.0: babel-plugin-transform-es2015-modules-umd@^6.23.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" integrity sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw== dependencies: babel-plugin-transform-es2015-modules-amd "^6.24.1" @@ -3600,7 +3729,7 @@ babel-plugin-transform-es2015-modules-umd@^6.23.0: babel-plugin-transform-es2015-object-super@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" integrity sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA== dependencies: babel-helper-replace-supers "^6.24.1" @@ -3608,7 +3737,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0: babel-plugin-transform-es2015-parameters@^6.23.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" integrity sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ== dependencies: babel-helper-call-delegate "^6.24.1" @@ -3620,7 +3749,7 @@ babel-plugin-transform-es2015-parameters@^6.23.0: babel-plugin-transform-es2015-shorthand-properties@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" integrity sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw== dependencies: babel-runtime "^6.22.0" @@ -3628,14 +3757,14 @@ babel-plugin-transform-es2015-shorthand-properties@^6.22.0: babel-plugin-transform-es2015-spread@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" integrity sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-sticky-regex@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" integrity sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ== dependencies: babel-helper-regex "^6.24.1" @@ -3644,21 +3773,21 @@ babel-plugin-transform-es2015-sticky-regex@^6.22.0: babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" integrity sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" integrity sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw== dependencies: babel-runtime "^6.22.0" babel-plugin-transform-es2015-unicode-regex@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" integrity sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ== dependencies: babel-helper-regex "^6.24.1" @@ -3667,7 +3796,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0: babel-plugin-transform-exponentiation-operator@^6.22.0: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" integrity sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ== dependencies: babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" @@ -3676,14 +3805,14 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" integrity sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg== dependencies: regenerator-transform "^0.10.0" babel-plugin-transform-strict-mode@^6.24.1: version "6.24.1" - resolved "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz" + resolved "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" integrity sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw== dependencies: babel-runtime "^6.22.0" @@ -3691,7 +3820,7 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-polyfill@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" integrity sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ== dependencies: babel-runtime "^6.26.0" @@ -3700,7 +3829,7 @@ babel-polyfill@^6.26.0: babel-preset-env@^1.7.0: version "1.7.0" - resolved "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz" + resolved "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== dependencies: babel-plugin-check-es2015-constants "^6.22.0" @@ -3736,7 +3865,7 @@ babel-preset-env@^1.7.0: babel-register@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" integrity sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A== dependencies: babel-core "^6.26.0" @@ -3749,7 +3878,7 @@ babel-register@^6.26.0: babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g== dependencies: core-js "^2.4.0" @@ -3757,7 +3886,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: babel-template@^6.24.1, babel-template@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" integrity sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg== dependencies: babel-runtime "^6.26.0" @@ -3768,7 +3897,7 @@ babel-template@^6.24.1, babel-template@^6.26.0: babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" integrity sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA== dependencies: babel-code-frame "^6.26.0" @@ -3783,7 +3912,7 @@ babel-traverse@^6.24.1, babel-traverse@^6.26.0: babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" - resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz" + resolved "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g== dependencies: babel-runtime "^6.26.0" @@ -3793,49 +3922,49 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: babel6-plugin-strip-class-callcheck@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/babel6-plugin-strip-class-callcheck/-/babel6-plugin-strip-class-callcheck-6.0.0.tgz" + resolved "https://registry.npmjs.org/babel6-plugin-strip-class-callcheck/-/babel6-plugin-strip-class-callcheck-6.0.0.tgz#de841c1abebbd39f78de0affb2c9a52ee228fddf" integrity sha512-biNFJ7JAK4+9BwswDGL0dmYpvXHvswOFR/iKg3Q/f+pNxPEa5bWZkLHI1fW4spPytkHGMe7f/XtYyhzml9hiWg== babylon@^6.18.0: version "6.18.0" - resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz" + resolved "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== backbone@^1.1.2: - version "1.4.1" - resolved "https://registry.npmjs.org/backbone/-/backbone-1.4.1.tgz" - integrity sha512-ADy1ztN074YkWbHi8ojJVFe3vAanO/lrzMGZWUClIP7oDD/Pjy2vrASraUP+2EVCfIiTtCW4FChVow01XneivA== + version "1.6.0" + resolved "https://registry.npmjs.org/backbone/-/backbone-1.6.0.tgz#5cdfa25257819b223109a77a74dde26d38995930" + integrity sha512-13PUjmsgw/49EowNcQvfG4gmczz1ximTMhUktj0Jfrjth0MVaTxehpU+qYYX4MxnuIuhmvBLC6/ayxuAGnOhbA== dependencies: underscore ">=1.8.3" backtick-template@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/backtick-template/-/backtick-template-0.2.0.tgz" + resolved "https://registry.npmjs.org/backtick-template/-/backtick-template-0.2.0.tgz#de33168260e70eff6435f565ad7aa8699d0b7fe9" integrity sha512-F5h0OHBy6gHJDA952velLcEuKQ+GTZHPsJEKyA1s+7aRTZ0i3V+gdLOxYenDKE19t0FDbMEFR3+Yvr64jtjShA== bail@^1.0.0: version "1.0.5" - resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz" + resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64id@2.0.0, base64id@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz" + resolved "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== base@^0.11.1: version "0.11.2" - resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" @@ -3848,41 +3977,41 @@ base@^0.11.1: basic-auth@~2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz" + resolved "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== dependencies: safe-buffer "5.1.2" big.js@^5.2.2: version "5.2.2" - resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^1.0.0: version "1.13.1" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== "binaryextensions@1 || 2", binaryextensions@^2.1.2: version "2.3.0" - resolved "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz" + resolved "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz#1d269cbf7e6243ea886aa41453c3651ccbe13c22" integrity sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg== bindings@^1.5.0: version "1.5.0" - resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" bl@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== dependencies: buffer "^5.5.0" @@ -3891,50 +4020,32 @@ bl@^4.1.0: blank-object@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/blank-object/-/blank-object-1.0.2.tgz" + resolved "https://registry.npmjs.org/blank-object/-/blank-object-1.0.2.tgz#f990793fbe9a8c8dd013fb3219420bec81d5f4b9" integrity sha512-kXQ19Xhoghiyw66CUiGypnuRpWlbHAzY/+NyvqTEdTfhfQGH1/dbEMYiXju7fYKIFePpzp/y9dsu5Cu/PkmawQ== bluebird@^3.4.6, bluebird@^3.5.5, bluebird@^3.7.2: version "3.7.2" - resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== blueimp-md5@^2.10.0: version "2.19.0" - resolved "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz" + resolved "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0" integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: version "4.12.0" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.0.0, bn.js@^5.1.1: +bn.js@^5.0.0, bn.js@^5.2.1: version "5.2.1" - resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -body-parser@^1.19.0: +body-parser@1.20.2, body-parser@^1.19.0: version "1.20.2" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" @@ -3952,7 +4063,7 @@ body-parser@^1.19.0: body@^5.1.0: version "5.1.0" - resolved "https://registry.npmjs.org/body/-/body-5.1.0.tgz" + resolved "https://registry.npmjs.org/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069" integrity sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ== dependencies: continuable-cache "^0.3.1" @@ -3962,7 +4073,7 @@ body@^5.1.0: bower-config@^1.4.3: version "1.4.3" - resolved "https://registry.npmjs.org/bower-config/-/bower-config-1.4.3.tgz" + resolved "https://registry.npmjs.org/bower-config/-/bower-config-1.4.3.tgz#3454fecdc5f08e7aa9cc6d556e492be0669689ae" integrity sha512-MVyyUk3d1S7d2cl6YISViwJBc2VXCkxF5AUFykvN0PQj5FsUiMNSgAYTso18oRFfyZ6XEtjrgg9MAaufHbOwNw== dependencies: graceful-fs "^4.1.3" @@ -3974,12 +4085,12 @@ bower-config@^1.4.3: bower-endpoint-parser@0.2.2: version "0.2.2" - resolved "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz" + resolved "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" integrity sha512-YWZHhWkPdXtIfH3VRu3QIV95sa75O9vrQWBOHjexWCLBCTy5qJvRr36LXTqFwTchSXVlzy5piYJOjzHr7qhsNg== brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -3987,7 +4098,7 @@ brace-expansion@^1.1.7: braces@^2.3.1, braces@^2.3.2: version "2.3.2" - resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: arr-flatten "^1.1.0" @@ -4001,16 +4112,16 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" broccoli-amd-funnel@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/broccoli-amd-funnel/-/broccoli-amd-funnel-2.0.1.tgz" + resolved "https://registry.npmjs.org/broccoli-amd-funnel/-/broccoli-amd-funnel-2.0.1.tgz#dbdbfd28841731342d538126567c25bea3f15310" integrity sha512-VRE+0PYAN4jQfkIq3GKRj4U/4UV9rVpLan5ll6fVYV4ziVg4OEfR5GUnILEg++QtR4xSaugRxCPU5XJLDy3bNQ== dependencies: broccoli-plugin "^1.3.0" @@ -4018,7 +4129,7 @@ broccoli-amd-funnel@^2.0.1: broccoli-asset-rev@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/broccoli-asset-rev/-/broccoli-asset-rev-3.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-asset-rev/-/broccoli-asset-rev-3.0.0.tgz#65a28c8a062d6ee2cffd91ed2a8309e0f8253ac6" integrity sha512-gAHQZnwvtl74tGevUqGuWoyOdJUdMMv0TjGSMzbdyGImr9fZcnM6xmggDA8bUawrMto9NFi00ZtNUgA4dQiUBw== dependencies: broccoli-asset-rewrite "^2.0.0" @@ -4030,14 +4141,14 @@ broccoli-asset-rev@^3.0.0: broccoli-asset-rewrite@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/broccoli-asset-rewrite/-/broccoli-asset-rewrite-2.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-asset-rewrite/-/broccoli-asset-rewrite-2.0.0.tgz#603c4a52d4c8987a2f681254436923ac0a9c94ab" integrity sha512-dqhxdQpooNi7LHe8J9Jdxp6o3YPFWl4vQmint6zrsn2sVbOo+wpyiX3erUSt0IBtjNkAxqJjuvS375o2cLBHTA== dependencies: broccoli-filter "^1.2.3" broccoli-babel-transpiler@^6.5.0: version "6.5.1" - resolved "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.5.1.tgz" + resolved "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.5.1.tgz#a4afc8d3b59b441518eb9a07bd44149476e30738" integrity sha512-w6GcnkxvHcNCte5FcLGEG1hUdQvlfvSN/6PtGWU/otg69Ugk8rUk51h41R0Ugoc+TNxyeFG1opRt2RlA87XzNw== dependencies: babel-core "^6.26.0" @@ -4053,7 +4164,7 @@ broccoli-babel-transpiler@^6.5.0: broccoli-babel-transpiler@^7.8.0: version "7.8.1" - resolved "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-7.8.1.tgz" + resolved "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-7.8.1.tgz#a5dc04cf4f59de98124fc128683ab2b83e5d28c1" integrity sha512-6IXBgfRt7HZ61g67ssBc6lBb3Smw3DPZ9dEYirgtvXWpRZ2A9M22nxy6opEwJDgDJzlu/bB7ToppW33OFkA1gA== dependencies: "@babel/core" "^7.12.0" @@ -4069,9 +4180,23 @@ broccoli-babel-transpiler@^7.8.0: rsvp "^4.8.4" workerpool "^3.1.1" +broccoli-babel-transpiler@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-8.0.0.tgz#07576728a95b840a99d5f0f9b07b71a737f69319" + integrity sha512-3HEp3flvasUKJGWERcrPgM1SWvHJ0O/fmbEtY9L4kDyMSnqjY6hTYvNvgWCIgbwXAYAUlZP0vjAQsmyLNGLwFw== + dependencies: + broccoli-persistent-filter "^3.0.0" + clone "^2.1.2" + hash-for-dep "^1.4.7" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.9" + json-stable-stringify "^1.0.1" + rsvp "^4.8.4" + workerpool "^6.0.2" + broccoli-bridge@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/broccoli-bridge/-/broccoli-bridge-1.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-bridge/-/broccoli-bridge-1.0.0.tgz#6223fd64b62062c31333539f0f3c42d0acd92fb1" integrity sha512-WvU6T6AJrtpFSScgyCVEFAajPAJTOYYIIpGvs/PbkSq9OUBvI3/IEUHg+Ipx376M/clGFwa7K9crEtpauqC66A== dependencies: broccoli-plugin "^1.3.0" @@ -4080,7 +4205,7 @@ broccoli-bridge@^1.0.0: broccoli-builder@^0.18.14: version "0.18.14" - resolved "https://registry.npmjs.org/broccoli-builder/-/broccoli-builder-0.18.14.tgz" + resolved "https://registry.npmjs.org/broccoli-builder/-/broccoli-builder-0.18.14.tgz#4b79e2f844de11a4e1b816c3f49c6df4776c312d" integrity sha512-YoUHeKnPi4xIGZ2XDVN9oHNA9k3xF5f5vlA+1wvrxIIDXqQU97gp2FxVAF503Zxdtt0C5CRB5n+47k2hlkaBzA== dependencies: broccoli-node-info "^1.1.0" @@ -4093,7 +4218,7 @@ broccoli-builder@^0.18.14: broccoli-caching-writer@^2.2.0: version "2.3.1" - resolved "https://registry.npmjs.org/broccoli-caching-writer/-/broccoli-caching-writer-2.3.1.tgz" + resolved "https://registry.npmjs.org/broccoli-caching-writer/-/broccoli-caching-writer-2.3.1.tgz#b93cf58f9264f003075868db05774f4e7f25bd07" integrity sha512-lfoDx98VaU8tG4mUXCxKdKyw2Lr+iSIGUjCgV83KC2zRC07SzYTGuSsMqpXFiOQlOGuoJxG3NRoyniBa1BWOqA== dependencies: broccoli-kitchen-sink-helpers "^0.2.5" @@ -4105,7 +4230,7 @@ broccoli-caching-writer@^2.2.0: broccoli-caching-writer@^3.0.3: version "3.0.3" - resolved "https://registry.npmjs.org/broccoli-caching-writer/-/broccoli-caching-writer-3.0.3.tgz" + resolved "https://registry.npmjs.org/broccoli-caching-writer/-/broccoli-caching-writer-3.0.3.tgz#0bd2c96a9738d6a6ab590f07ba35c5157d7db476" integrity sha512-g644Kb5uBPsy+6e2DvO3sOc+/cXZQQNgQt64QQzjA9TSdP0dl5qvetpoNIx4sy/XIjrPYG1smEidq9Z9r61INw== dependencies: broccoli-kitchen-sink-helpers "^0.3.1" @@ -4117,7 +4242,7 @@ broccoli-caching-writer@^3.0.3: broccoli-clean-css@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/broccoli-clean-css/-/broccoli-clean-css-1.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-clean-css/-/broccoli-clean-css-1.1.0.tgz#9db143d9af7e0ae79c26e3ac5a9bb2d720ea19fa" integrity sha512-S7/RWWX+lL42aGc5+fXVLnwDdMtS0QEWUFalDp03gJ9Na7zj1rWa351N2HZ687E2crM9g+eDWXKzD17cbcTepg== dependencies: broccoli-persistent-filter "^1.1.6" @@ -4127,7 +4252,7 @@ broccoli-clean-css@^1.1.0: broccoli-concat@^4.2.2, broccoli-concat@^4.2.4, broccoli-concat@^4.2.5: version "4.2.5" - resolved "https://registry.npmjs.org/broccoli-concat/-/broccoli-concat-4.2.5.tgz" + resolved "https://registry.npmjs.org/broccoli-concat/-/broccoli-concat-4.2.5.tgz#d578f00094048b5fc87195e82fbdbde20d838d29" integrity sha512-dFB5ATPwOyV8S2I7a07HxCoutoq23oY//LhM6Mou86cWUTB174rND5aQLR7Fu8FjFFLxoTbkk7y0VPITJ1IQrw== dependencies: broccoli-debug "^0.6.5" @@ -4144,14 +4269,14 @@ broccoli-concat@^4.2.2, broccoli-concat@^4.2.4, broccoli-concat@^4.2.5: broccoli-config-loader@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/broccoli-config-loader/-/broccoli-config-loader-1.0.1.tgz" + resolved "https://registry.npmjs.org/broccoli-config-loader/-/broccoli-config-loader-1.0.1.tgz#d10aaf8ebc0cb45c1da5baa82720e1d88d28c80a" integrity sha512-MDKYQ50rxhn+g17DYdfzfEM9DjTuSGu42Db37A8TQHQe8geYEcUZ4SQqZRgzdAI3aRQNlA1yBHJfOeGmOjhLIg== dependencies: broccoli-caching-writer "^3.0.3" broccoli-config-replace@^1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/broccoli-config-replace/-/broccoli-config-replace-1.1.2.tgz" + resolved "https://registry.npmjs.org/broccoli-config-replace/-/broccoli-config-replace-1.1.2.tgz#6ea879d92a5bad634d11329b51fc5f4aafda9c00" integrity sha512-qLlEY3V7p3ZWJNRPdPgwIM77iau1qR03S9BupMMFngjzBr7S6RSzcg96HbCYXmW9gfTbjRm9FC4CQT81SBusZg== dependencies: broccoli-kitchen-sink-helpers "^0.3.1" @@ -4161,7 +4286,7 @@ broccoli-config-replace@^1.1.2: broccoli-debug@^0.6.4, broccoli-debug@^0.6.5: version "0.6.5" - resolved "https://registry.npmjs.org/broccoli-debug/-/broccoli-debug-0.6.5.tgz" + resolved "https://registry.npmjs.org/broccoli-debug/-/broccoli-debug-0.6.5.tgz#164a5cdafd8936e525e702bf8f91f39d758e2e78" integrity sha512-RIVjHvNar9EMCLDW/FggxFRXqpjhncM/3qq87bn/y+/zR9tqEkHvTqbyOc4QnB97NO2m6342w4wGkemkaeOuWg== dependencies: broccoli-plugin "^1.2.1" @@ -4173,7 +4298,7 @@ broccoli-debug@^0.6.4, broccoli-debug@^0.6.5: broccoli-file-creator@^1.1.1: version "1.2.0" - resolved "https://registry.npmjs.org/broccoli-file-creator/-/broccoli-file-creator-1.2.0.tgz" + resolved "https://registry.npmjs.org/broccoli-file-creator/-/broccoli-file-creator-1.2.0.tgz#27f1b25b1b00e7bb7bf3d5d7abed5f4d5388df4d" integrity sha512-l9zthHg6bAtnOfRr/ieZ1srRQEsufMZID7xGYRW3aBDv3u/3Eux+Iawl10tAGYE5pL9YB4n5X4vxkp6iNOoZ9g== dependencies: broccoli-plugin "^1.1.0" @@ -4181,7 +4306,7 @@ broccoli-file-creator@^1.1.1: broccoli-file-creator@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/broccoli-file-creator/-/broccoli-file-creator-2.1.1.tgz" + resolved "https://registry.npmjs.org/broccoli-file-creator/-/broccoli-file-creator-2.1.1.tgz#7351dd2496c762cfce7736ce9b49e3fce0c7b7db" integrity sha512-YpjOExWr92C5vhnK0kmD81kM7U09kdIRZk9w4ZDCDHuHXW+VE/x6AGEOQQW3loBQQ6Jk+k+TSm8dESy4uZsnjw== dependencies: broccoli-plugin "^1.1.0" @@ -4189,7 +4314,7 @@ broccoli-file-creator@^2.1.1: broccoli-filter@^1.2.2, broccoli-filter@^1.2.3: version "1.3.0" - resolved "https://registry.npmjs.org/broccoli-filter/-/broccoli-filter-1.3.0.tgz" + resolved "https://registry.npmjs.org/broccoli-filter/-/broccoli-filter-1.3.0.tgz#71e3a8e32a17f309e12261919c5b1006d6766de6" integrity sha512-VXJXw7eBfG82CFxaBDjYmyN7V72D4In2zwLVQJd/h3mBfF3CMdRTsv2L20lmRTtCv1sAHcB+LgMso90e/KYiLw== dependencies: broccoli-kitchen-sink-helpers "^0.3.1" @@ -4204,12 +4329,12 @@ broccoli-filter@^1.2.2, broccoli-filter@^1.2.3: broccoli-funnel-reducer@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz#11365b2a785aec9b17972a36df87eef24c5cc0ea" integrity sha512-SaOCEdh+wnt2jFUV2Qb32m7LXyElvFwW3NKNaEJyi5PGQNwxfqpkc0KI6AbQANKgdj/40U2UC0WuGThFwuEUaA== broccoli-funnel@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-2.0.1.tgz" + resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-2.0.1.tgz#6823c73b675ef78fffa7ab800f083e768b51d449" integrity sha512-C8Lnp9TVsSSiZMGEF16C0dCiNg2oJqUKwuZ1K4kVC6qRPG/2Cj/rtB5kRCC9qEbwqhX71bDbfHROx0L3J7zXQg== dependencies: array-equal "^1.0.0" @@ -4228,7 +4353,7 @@ broccoli-funnel@2.0.1: broccoli-funnel@^1.0.1, broccoli-funnel@^1.1.0: version "1.2.0" - resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz" + resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz#cddc3afc5ff1685a8023488fff74ce6fb5a51296" integrity sha512-0pbFNUA5Ml+gPPd58Rj/M26OS21+bMiV0F+m6+9OVzAhAdppVLxylSsXfWAt2WOD3kS+D8UsDv6GSmnZhbw/dw== dependencies: array-equal "^1.0.0" @@ -4248,7 +4373,7 @@ broccoli-funnel@^1.0.1, broccoli-funnel@^1.1.0: broccoli-funnel@^2.0.0, broccoli-funnel@^2.0.1, broccoli-funnel@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-2.0.2.tgz" + resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-2.0.2.tgz#0edf629569bc10bd02cc525f74b9a38e71366a75" integrity sha512-/vDTqtv7ipjEZQOVqO4vGDVAOZyuYzQ/EgGoyewfOgh1M7IQAToBKZI0oAQPgMBeFPPlIbfMuAngk+ohPBuaHQ== dependencies: array-equal "^1.0.0" @@ -4267,7 +4392,7 @@ broccoli-funnel@^2.0.0, broccoli-funnel@^2.0.1, broccoli-funnel@^2.0.2: broccoli-funnel@^3.0.0, broccoli-funnel@^3.0.2, broccoli-funnel@^3.0.3, broccoli-funnel@^3.0.5, broccoli-funnel@^3.0.8: version "3.0.8" - resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-3.0.8.tgz" + resolved "https://registry.npmjs.org/broccoli-funnel/-/broccoli-funnel-3.0.8.tgz#f5b62e2763c3918026a15a3c833edc889971279b" integrity sha512-ng4eIhPYiXqMw6SyGoxPHR3YAwEd2lr9FgBI1CyTbspl4txZovOsmzFkMkGAlu88xyvYXJqHiM2crfLa65T1BQ== dependencies: array-equal "^1.0.0" @@ -4280,7 +4405,7 @@ broccoli-funnel@^3.0.0, broccoli-funnel@^3.0.2, broccoli-funnel@^3.0.3, broccoli broccoli-kitchen-sink-helpers@^0.2.5: version "0.2.9" - resolved "https://registry.npmjs.org/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz" + resolved "https://registry.npmjs.org/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz#a5e0986ed8d76fb5984b68c3f0450d3a96e36ecc" integrity sha512-C+oEqivDofZv/h80rgN4WJkbZkbfwkrIeu8vFn4bb4m4jPd3ICNNplhkXGl3ps439pzc2yjZ1qIwz0yy8uHcQg== dependencies: glob "^5.0.10" @@ -4288,7 +4413,7 @@ broccoli-kitchen-sink-helpers@^0.2.5: broccoli-kitchen-sink-helpers@^0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.3.1.tgz" + resolved "https://registry.npmjs.org/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.3.1.tgz#77c7c18194b9664163ec4fcee2793444926e0c06" integrity sha512-gqYnKSJxBSjj/uJqeuRAzYVbmjWhG0mOZ8jrp6+fnUIOgLN6MvI7XxBECDHkYMIFPJ8Smf4xaI066Q2FqQDnXg== dependencies: glob "^5.0.10" @@ -4296,7 +4421,7 @@ broccoli-kitchen-sink-helpers@^0.3.1: broccoli-merge-files@^0.8.0: version "0.8.0" - resolved "https://registry.npmjs.org/broccoli-merge-files/-/broccoli-merge-files-0.8.0.tgz" + resolved "https://registry.npmjs.org/broccoli-merge-files/-/broccoli-merge-files-0.8.0.tgz#65ed9d6888548d44bf95208bc7759ac1d10bd382" integrity sha512-S6dXHECbDkr7YMuCitAAQT8EZeW/kXom0Y8+QmQfiSkWspkKDGrr4vXgEZJjWqfa/FSx/Y18NEEOuMmbIW+XNQ== dependencies: broccoli-plugin "^1.3.0" @@ -4306,7 +4431,7 @@ broccoli-merge-files@^0.8.0: broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.1: version "1.2.4" - resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-1.2.4.tgz" + resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-1.2.4.tgz#a001519bb5067f06589d91afa2942445a2d0fdb5" integrity sha512-RXJAleytlED0dxXGEo2EXwrg5cCesY8LQzzGRogwGQmluoz+ijzxajpyWAW6wu/AyuQZj1vgnIqnld8jvuuXtQ== dependencies: broccoli-plugin "^1.3.0" @@ -4320,7 +4445,7 @@ broccoli-merge-trees@^1.0.0, broccoli-merge-trees@^1.1.1: broccoli-merge-trees@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-2.0.1.tgz" + resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-2.0.1.tgz#14d4b7fc1a90318c12b16f843e6ba2693808100c" integrity sha512-WjaexJ+I8BxP5V5RNn6um/qDRSmKoiBC/QkRi79FT9ClHfldxRyCDs9mcV7mmoaPlsshmmPaUz5jdtcKA6DClQ== dependencies: broccoli-plugin "^1.3.0" @@ -4328,7 +4453,7 @@ broccoli-merge-trees@^2.0.0: broccoli-merge-trees@^3.0.0, broccoli-merge-trees@^3.0.1, broccoli-merge-trees@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-3.0.2.tgz" + resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-3.0.2.tgz#f33b451994225522b5c9bcf27d59decfd8ba537d" integrity sha512-ZyPAwrOdlCddduFbsMyyFzJUrvW6b04pMvDiAQZrCwghlvgowJDY+EfoXn+eR1RRA5nmGHJ+B68T63VnpRiT1A== dependencies: broccoli-plugin "^1.3.0" @@ -4336,7 +4461,7 @@ broccoli-merge-trees@^3.0.0, broccoli-merge-trees@^3.0.1, broccoli-merge-trees@^ broccoli-merge-trees@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-4.2.0.tgz" + resolved "https://registry.npmjs.org/broccoli-merge-trees/-/broccoli-merge-trees-4.2.0.tgz#692d3c163ecea08c5714a9434d664e628919f47c" integrity sha512-nTrQe5AQtCrW4enLRvbD/vTLHqyW2tz+vsLXQe4IEaUhepuMGVKJJr+I8n34Vu6fPjmPLwTjzNC8izMIDMtHPw== dependencies: broccoli-plugin "^4.0.2" @@ -4344,7 +4469,7 @@ broccoli-merge-trees@^4.2.0: broccoli-middleware@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/broccoli-middleware/-/broccoli-middleware-2.1.1.tgz" + resolved "https://registry.npmjs.org/broccoli-middleware/-/broccoli-middleware-2.1.1.tgz#183635bbef4dc1241533ee001a162f013d776cb9" integrity sha512-BK8aPhQpOLsHWiftrqXQr84XsvzUqeaN4PlCQOYg5yM0M+WKAHtX2WFXmicSQZOVgKDyh5aeoNTFkHjBAEBzwQ== dependencies: ansi-html "^0.0.7" @@ -4354,29 +4479,29 @@ broccoli-middleware@^2.1.1: broccoli-node-api@^1.6.0, broccoli-node-api@^1.7.0: version "1.7.0" - resolved "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz" + resolved "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz#391aa6edecd2a42c63c111b4162956b2fa288cb6" integrity sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw== broccoli-node-info@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-1.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-1.1.0.tgz#3aa2e31e07e5bdb516dd25214f7c45ba1c459412" integrity sha512-DUohSZCdfXli/3iN6SmxPbck1OVG8xCkrLx47R25his06xVc1ZmmrOsrThiM8BsCWirwyocODiYJqNP5W2Hg1A== broccoli-node-info@^2.1.0: version "2.2.0" - resolved "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz" + resolved "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz#feb01c13020792f429e01d7f7845dc5b3a7932b3" integrity sha512-VabSGRpKIzpmC+r+tJueCE5h8k6vON7EIMMWu6d/FyPdtijwLQ7QvzShEw+m3mHoDzUaj/kiZsDYrS8X2adsBg== broccoli-output-wrapper@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-2.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-2.0.0.tgz#f1e0b9b2f259a67fd41a380141c3c20b096828e6" integrity sha512-V/ozejo+snzNf75i/a6iTmp71k+rlvqjE3+jYfimuMwR1tjNNRdtfno+NGNQB2An9bIAeqZnKhMDurAznHAdtA== dependencies: heimdalljs-logger "^0.1.10" broccoli-output-wrapper@^3.2.5: version "3.2.5" - resolved "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz" + resolved "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz#514b17801c92922a2c2f87fd145df2a25a11bc5f" integrity sha512-bQAtwjSrF4Nu0CK0JOy5OZqw9t5U0zzv2555EA/cF8/a8SLDTIetk9UgrtMVw7qKLKdSpOZ2liZNeZZDaKgayw== dependencies: fs-extra "^8.1.0" @@ -4385,7 +4510,7 @@ broccoli-output-wrapper@^3.2.5: broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.4.3: version "1.4.6" - resolved "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.6.tgz" + resolved "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.6.tgz#80762d19000880a77da33c34373299c0f6a3e615" integrity sha512-0RejLwoC95kv4kta8KAa+FmECJCK78Qgm8SRDEK7YyU0N9Cx6KpY3UCDy9WELl3mCXLN8TokNxc7/hp3lL4lfw== dependencies: async-disk-cache "^1.2.1" @@ -4404,7 +4529,7 @@ broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.4.3: broccoli-persistent-filter@^2.1.0, broccoli-persistent-filter@^2.2.1, broccoli-persistent-filter@^2.3.0, broccoli-persistent-filter@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-2.3.1.tgz" + resolved "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-2.3.1.tgz#4a052e0e0868b344c3a2977e35a3d497aa9eca72" integrity sha512-hVsmIgCDrl2NFM+3Gs4Cr2TA6UPaIZip99hN8mtkaUPgM8UeVnCbxelCvBjUBHo0oaaqP5jzqqnRVvb568Yu5g== dependencies: async-disk-cache "^1.2.1" @@ -4422,9 +4547,9 @@ broccoli-persistent-filter@^2.1.0, broccoli-persistent-filter@^2.2.1, broccoli-p sync-disk-cache "^1.3.3" walk-sync "^1.0.0" -broccoli-persistent-filter@^3.1.1, broccoli-persistent-filter@^3.1.2: +broccoli-persistent-filter@^3.0.0, broccoli-persistent-filter@^3.1.1, broccoli-persistent-filter@^3.1.2: version "3.1.3" - resolved "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-3.1.3.tgz" + resolved "https://registry.npmjs.org/broccoli-persistent-filter/-/broccoli-persistent-filter-3.1.3.tgz#aca815bf3e3b0247bd0a7b567fdb0d0e08c99cc2" integrity sha512-Q+8iezprZzL9voaBsDY3rQVl7c7H5h+bvv8SpzCZXPZgfBFCbx7KFQ2c3rZR6lW5k4Kwoqt7jG+rZMUg67Gwxw== dependencies: async-disk-cache "^2.0.0" @@ -4441,7 +4566,7 @@ broccoli-persistent-filter@^3.1.1, broccoli-persistent-filter@^3.1.2: broccoli-plugin@*, broccoli-plugin@^4.0.0, broccoli-plugin@^4.0.1, broccoli-plugin@^4.0.2, broccoli-plugin@^4.0.3, broccoli-plugin@^4.0.5, broccoli-plugin@^4.0.7: version "4.0.7" - resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz" + resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz#dd176a85efe915ed557d913744b181abe05047db" integrity sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg== dependencies: broccoli-node-api "^1.7.0" @@ -4454,7 +4579,7 @@ broccoli-plugin@*, broccoli-plugin@^4.0.0, broccoli-plugin@^4.0.1, broccoli-plug broccoli-plugin@1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-1.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-1.1.0.tgz#73e2cfa05f8ea1e3fc1420c40c3d9e7dc724bf02" integrity sha512-dY1QsA20of9wWEto8yhN7JQjpfjySmgeIMsvnQ9aBAv1wEJJCe04B0ekdgq7Bduyx9yWXdoC5CngGy81swmp2w== dependencies: promise-map-series "^0.2.1" @@ -4464,7 +4589,7 @@ broccoli-plugin@1.1.0: broccoli-plugin@^1.0.0, broccoli-plugin@^1.1.0, broccoli-plugin@^1.2.0, broccoli-plugin@^1.2.1, broccoli-plugin@^1.3.0: version "1.3.1" - resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-1.3.1.tgz" + resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-1.3.1.tgz#a26315732fb99ed2d9fb58f12a1e14e986b4fabd" integrity sha512-DW8XASZkmorp+q7J4EeDEZz+LoyKLAd2XZULXyD9l4m9/hAKV3vjHmB1kiUshcWAYMgTP1m2i4NnqCE/23h6AQ== dependencies: promise-map-series "^0.2.1" @@ -4474,7 +4599,7 @@ broccoli-plugin@^1.0.0, broccoli-plugin@^1.1.0, broccoli-plugin@^1.2.0, broccoli broccoli-plugin@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-2.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-2.1.0.tgz#2fab6c578219cfcc64f773e9616073313fc8b334" integrity sha512-ElE4caljW4slapyEhSD9jU9Uayc8SoSABWdmY9SqbV8DHNxU6xg1jJsPcMm+cXOvggR3+G+OXAYQeFjWVnznaw== dependencies: promise-map-series "^0.2.1" @@ -4484,7 +4609,7 @@ broccoli-plugin@^2.1.0: broccoli-plugin@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-3.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-3.1.0.tgz#54ba6dd90a42ec3db5624063292610e326b1e542" integrity sha512-7w7FP8WJYjLvb0eaw27LO678TGGaom++49O1VYIuzjhXjK5kn2+AMlDm7CaUFw4F7CLGoVQeZ84d8gICMJa4lA== dependencies: broccoli-node-api "^1.6.0" @@ -4497,7 +4622,7 @@ broccoli-plugin@^3.1.0: broccoli-postcss-single@^5.0.1: version "5.0.2" - resolved "https://registry.npmjs.org/broccoli-postcss-single/-/broccoli-postcss-single-5.0.2.tgz" + resolved "https://registry.npmjs.org/broccoli-postcss-single/-/broccoli-postcss-single-5.0.2.tgz#f23661b3011494d8a2dbd8ff39eb394e80313682" integrity sha512-r4eWtz/5uihtHwOszViWwV6weJr9VryvaqtVo1DOh4gL+TbTyU+NX+Y+t9TqUw99OtuivMz4uHLLH7zZECbZmw== dependencies: broccoli-caching-writer "^3.0.3" @@ -4509,7 +4634,7 @@ broccoli-postcss-single@^5.0.1: broccoli-postcss@^6.0.1: version "6.1.0" - resolved "https://registry.npmjs.org/broccoli-postcss/-/broccoli-postcss-6.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-postcss/-/broccoli-postcss-6.1.0.tgz#1e15c5e8a65a984544224f083cbd1e6763691b60" integrity sha512-I8+DHq5xcCBHU0PpCtDMayAmSUVx07CqAquUpdlNUHckXeD//cUFf4aFQllnZBhF8Z86YLhuA+j7qvCYYgBXRg== dependencies: broccoli-funnel "^3.0.0" @@ -4520,7 +4645,7 @@ broccoli-postcss@^6.0.1: broccoli-rollup@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/broccoli-rollup/-/broccoli-rollup-5.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-rollup/-/broccoli-rollup-5.0.0.tgz#a77b53bcef1b70e988913fee82265c0a4ca530da" integrity sha512-QdMuXHwsdz/LOS8zu4HP91Sfi4ofimrOXoYP/lrPdRh7lJYD87Lfq4WzzUhGHsxMfzANIEvl/7qVHKD3cFJ4tA== dependencies: "@types/broccoli-plugin" "^3.0.0" @@ -4534,9 +4659,9 @@ broccoli-rollup@^5.0.0: walk-sync "^2.2.0" broccoli-sass-source-maps@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/broccoli-sass-source-maps/-/broccoli-sass-source-maps-4.1.0.tgz" - integrity sha512-So3gTlP9AEJTponlRoL9Ti+xaMX1LnJUWD52mVT0Oq6PI8nIjX97XMW91JfY/4CXsprIDyGe/7rkiauE+XHdPQ== + version "4.2.4" + resolved "https://registry.npmjs.org/broccoli-sass-source-maps/-/broccoli-sass-source-maps-4.2.4.tgz#14bdb5f23c05a38bec33d4953aaabdf3e93eca93" + integrity sha512-MHwqLkgYW24T9k2OzprdYtERCAaO3wuSGqKna8QcAzCjDxYyoojisg2lfSWj9k2G72PlACUjUg8O39jttE84og== dependencies: broccoli-caching-writer "^3.0.3" include-path-searcher "^0.1.0" @@ -4544,31 +4669,31 @@ broccoli-sass-source-maps@^4.0.0: broccoli-slow-trees@^3.0.1, broccoli-slow-trees@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/broccoli-slow-trees/-/broccoli-slow-trees-3.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-slow-trees/-/broccoli-slow-trees-3.1.0.tgz#8e48903f59e061bf1213963733b9e61dec2ee5d7" integrity sha512-FRI7mRTk2wjIDrdNJd6znS7Kmmne4VkAkl8Ix1R/VoePFMD0g0tEl671xswzFqaRjpT9Qu+CC4hdXDLDJBuzMw== dependencies: heimdalljs "^0.2.1" broccoli-source@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/broccoli-source/-/broccoli-source-1.1.0.tgz" + resolved "https://registry.npmjs.org/broccoli-source/-/broccoli-source-1.1.0.tgz#54f0e82c8b73f46580cbbc4f578f0b32fca8f809" integrity sha512-ahvqmwF6Yvh6l+sTJJdey4o4ynwSH8swSSBSGmUXGSPPCqBWvquWB/4rWN65ZArKilBFq/29O0yQnZNIf//sTg== broccoli-source@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/broccoli-source/-/broccoli-source-2.1.2.tgz" + resolved "https://registry.npmjs.org/broccoli-source/-/broccoli-source-2.1.2.tgz#e9ae834f143b607e9ec114ade66731500c38b90b" integrity sha512-1lLayO4wfS0c0Sj50VfHJXNWf94FYY0WUhxj0R77thbs6uWI7USiOWFqQV5dRmhAJnoKaGN4WyLGQbgjgiYFwQ== -broccoli-source@^3.0.0: +broccoli-source@^3.0.0, broccoli-source@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/broccoli-source/-/broccoli-source-3.0.1.tgz" + resolved "https://registry.npmjs.org/broccoli-source/-/broccoli-source-3.0.1.tgz#fd581b2f3877ca1338f724f6ef70acec8c7e1444" integrity sha512-ZbGVQjivWi0k220fEeIUioN6Y68xjMy0xiLAc0LdieHI99gw+tafU8w0CggBDYVNsJMKUr006AZaM7gNEwCxEg== dependencies: broccoli-node-api "^1.6.0" broccoli-sri-hash@^2.1.0: version "2.1.2" - resolved "https://registry.npmjs.org/broccoli-sri-hash/-/broccoli-sri-hash-2.1.2.tgz" + resolved "https://registry.npmjs.org/broccoli-sri-hash/-/broccoli-sri-hash-2.1.2.tgz#bc69905ed7a381ad325cc0d02ded071328ebf3f3" integrity sha512-toLD/v7ut2ajcH8JsdCMG2Bpq2qkwTcKM6CMzVMSAJjaz/KpK69fR+gSqe1dsjh+QTdxG0yVvkq3Sij/XMzV6A== dependencies: broccoli-caching-writer "^2.2.0" @@ -4579,7 +4704,7 @@ broccoli-sri-hash@^2.1.0: broccoli-stew@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/broccoli-stew/-/broccoli-stew-3.0.0.tgz" + resolved "https://registry.npmjs.org/broccoli-stew/-/broccoli-stew-3.0.0.tgz#fd1d19d162ad9490b42e5c563b78c26eb1e80b95" integrity sha512-NXfi+Vas24n3Ivo21GvENTI55qxKu7OwKRnCLWXld8MiLiQKQlWIq28eoARaFj0lTUFwUa4jKZeA7fW9PiWQeg== dependencies: broccoli-debug "^0.6.5" @@ -4598,24 +4723,24 @@ broccoli-stew@^3.0.0: walk-sync "^1.1.3" broccoli-terser-sourcemap@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/broccoli-terser-sourcemap/-/broccoli-terser-sourcemap-4.1.0.tgz" - integrity sha512-zkNnjsAbP+M5rG2aMM1EE4BmXPUSxFKmtLUkUs2D1DLTOJQoF1xlOjGWjjKYCFy5tw8t4+tgGJ+HVa2ucJZ8sw== + version "4.1.1" + resolved "https://registry.npmjs.org/broccoli-terser-sourcemap/-/broccoli-terser-sourcemap-4.1.1.tgz#4c26696e07a822e1fc91fb48c5b6d6c70d5ca9b2" + integrity sha512-8sbpRf0/+XeszBJQM7vph2UNj4Kal0lCI/yubcrBIzb2NvYj5gjTHJABXOdxx5mKNmlCMu2hx2kvOtMpQsxrfg== dependencies: async-promise-queue "^1.0.5" - broccoli-plugin "^4.0.3" - debug "^4.1.0" + broccoli-plugin "^4.0.7" + convert-source-map "^2.0.0" + debug "^4.3.1" lodash.defaultsdeep "^4.6.1" matcher-collection "^2.0.1" - source-map-url "^0.4.0" symlink-or-copy "^1.3.1" - terser "^5.3.0" + terser "^5.7.0" walk-sync "^2.2.0" - workerpool "^6.0.0" + workerpool "^6.1.5" broccoli@^3.5.1: version "3.5.2" - resolved "https://registry.npmjs.org/broccoli/-/broccoli-3.5.2.tgz" + resolved "https://registry.npmjs.org/broccoli/-/broccoli-3.5.2.tgz#60921167d57b43fb5bad527420d62fe532595ef4" integrity sha512-sWi3b3fTUSVPDsz5KsQ5eCQNVAtLgkIE/HYFkEZXR/07clqmd4E/gFiuwSaqa9b+QTXc1Uemfb7TVWbEIURWDg== dependencies: "@types/chai" "^4.2.9" @@ -4645,17 +4770,17 @@ broccoli@^3.5.1: brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" + resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== browser-process-hrtime@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz" + resolved "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserify-aes@^1.0.0, browserify-aes@^1.0.4: +browserify-aes@^1.0.4, browserify-aes@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz" + resolved "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== dependencies: buffer-xor "^1.0.3" @@ -4667,7 +4792,7 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: browserify-cipher@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz" + resolved "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== dependencies: browserify-aes "^1.0.4" @@ -4676,7 +4801,7 @@ browserify-cipher@^1.0.0: browserify-des@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz" + resolved "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== dependencies: cipher-base "^1.0.1" @@ -4684,74 +4809,75 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz" + resolved "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + version "4.2.3" + resolved "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz#7afe4c01ec7ee59a89a558a4b75bd85ae62d4208" + integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw== dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" + bn.js "^5.2.1" + browserify-rsa "^4.1.0" create-hash "^1.2.0" create-hmac "^1.1.7" - elliptic "^6.5.3" + elliptic "^6.5.5" + hash-base "~3.0" inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" + parse-asn1 "^5.1.7" + readable-stream "^2.3.8" + safe-buffer "^5.2.1" browserify-zlib@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz" + resolved "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: pako "~1.0.5" browserslist@^3.2.6: version "3.2.8" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== dependencies: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.5: - version "4.21.5" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== +browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0: + version "4.23.1" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz#ce4af0534b3d37db5c1a4ca98b9080f985041e96" + integrity sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + caniuse-lite "^1.0.30001629" + electron-to-chromium "^1.4.796" + node-releases "^2.0.14" + update-browserslist-db "^1.0.16" bser@2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== dependencies: node-int64 "^0.4.0" buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-xor@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz" + resolved "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== buffer@^4.3.0: version "4.9.2" - resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== dependencies: base64-js "^1.0.2" @@ -4760,7 +4886,7 @@ buffer@^4.3.0: buffer@^5.5.0: version "5.7.1" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" @@ -4768,32 +4894,32 @@ buffer@^5.5.0: builtin-status-codes@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz" + resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== builtins@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz" + resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== bytes@1: version "1.0.0" - resolved "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz" + resolved "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" integrity sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ== bytes@3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== bytes@3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacache@^12.0.2: version "12.0.4" - resolved "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz" + resolved "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== dependencies: bluebird "^3.5.5" @@ -4814,7 +4940,7 @@ cacache@^12.0.2: cache-base@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" @@ -4829,68 +4955,71 @@ cache-base@^1.0.1: calculate-cache-key-for-tree@2.0.0, calculate-cache-key-for-tree@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-2.0.0.tgz" + resolved "https://registry.npmjs.org/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-2.0.0.tgz#7ac57f149a4188eacb0a45b210689215d3fef8d6" integrity sha512-Quw8a6y8CPmRd6eU+mwypktYCwUcf8yVFIRbNZ6tPQEckX9yd+EBVEPC/GSZZrMWH9e7Vz4pT7XhpmyApRByLQ== dependencies: json-stable-stringify "^1.0.1" calculate-cache-key-for-tree@^1.1.0: version "1.2.3" - resolved "https://registry.npmjs.org/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-1.2.3.tgz" + resolved "https://registry.npmjs.org/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-1.2.3.tgz#5a5e4fcfa2d374a63e47fe967593f179e8282825" integrity sha512-PPQorvdNw8K8k7UftCeradwOmKDSDJs8wcqYTtJPEt3fHbZyK8QsorybJA+lOmk0dgE61vX6R+5Kd3W9h4EMGg== dependencies: json-stable-stringify "^1.0.1" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" call-me-maybe@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz" + resolved "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase-css@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" + resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== can-symlink@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/can-symlink/-/can-symlink-1.0.0.tgz" + resolved "https://registry.npmjs.org/can-symlink/-/can-symlink-1.0.0.tgz#97b607d8a84bb6c6e228b902d864ecb594b9d219" integrity sha512-RbsNrFyhwkx+6psk/0fK/Q9orOUr9VMxohGd8vTa4djf4TGLfblBgUfqZChrZuW0Q+mz2eBPFLusw9Jfukzmhg== dependencies: tmp "0.0.28" -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: - version "1.0.30001464" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001464.tgz" - integrity sha512-oww27MtUmusatpRpCGSOneQk2/l5czXANDSFvsc7VuOQ86s3ANhZetpwXNf1zY/zdfP63Xvjz325DAdAoES13g== +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001599, caniuse-lite@^1.0.30001629: + version "1.0.30001640" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz#32c467d4bf1f1a0faa63fc793c2ba81169e7652f" + integrity sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA== capture-exit@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz" + resolved "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== dependencies: rsvp "^4.8.4" cardinal@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz" + resolved "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9" integrity sha512-INsuF4GyiFLk8C91FPokbKTc/rwHqV4JnfatVZ6GPhguP1qmkRWX2dp5tepYboYdPpGWisLVLI+KsXoXFPRSMg== dependencies: ansicolors "~0.2.1" @@ -4898,17 +5027,17 @@ cardinal@^1.0.0: ccount@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz" + resolved "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== ceibo@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ceibo/-/ceibo-2.0.0.tgz" + resolved "https://registry.npmjs.org/ceibo/-/ceibo-2.0.0.tgz#9a61eb054a91c09934588d4e45d9dd2c3bf04eee" integrity sha512-Zt+Nhkzd1s9hsOhEmCMkmzAn1AmjQ/RuEnXOF3H46NYlkrQoApA8PIiacz/YASdxeFse1F50B7eoppw4pPie6g== chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" + resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== dependencies: ansi-styles "^2.2.1" @@ -4917,9 +5046,9 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -4928,15 +5057,15 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4 chalk@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz" + resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -4944,7 +5073,7 @@ chalk@^4.0.0, chalk@^4.1.0: chalk@~0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz" + resolved "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" integrity sha512-sQfYDlfv2DGVtjdoQqxS0cEZDroyG8h6TamA6rvxwlrU5BaSLDx9xhatBYl2pxZ7gmpNaPFVwBtdGdu5rQ+tYQ== dependencies: ansi-styles "~1.0.0" @@ -4953,40 +5082,40 @@ chalk@~0.4.0: character-entities-html4@^1.0.0: version "1.1.4" - resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125" integrity sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g== character-entities-legacy@^1.0.0: version "1.1.4" - resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== character-entities@^1.0.0: version "1.2.4" - resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== character-reference-invalid@^1.0.0: version "1.1.4" - resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== chardet@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz" + resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== charm@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz" + resolved "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz#8add367153a6d9a581331052c4090991da995e35" integrity sha512-wqW3VdPnlSWT4eRiYX+hcs+C6ViBPUWk1qTCd+37qw9kEm/a5n2qcyQDMBWvSYKN/ctqZzeXNQaeBjOetJJUkw== dependencies: inherits "^2.0.1" "chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.1, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + version "3.6.0" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -5000,7 +5129,7 @@ charm@^1.0.0: chokidar@^2.1.8: version "2.1.8" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" @@ -5019,22 +5148,22 @@ chokidar@^2.1.8: chownr@^1.1.1: version "1.1.4" - resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + version "1.0.4" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== ci-info@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz" + resolved "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== dependencies: inherits "^2.0.1" @@ -5042,7 +5171,7 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: class-utils@^0.3.5: version "0.3.6" - resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" @@ -5052,17 +5181,17 @@ class-utils@^0.3.5: cldr-core@^36.0.0: version "36.0.0" - resolved "https://registry.npmjs.org/cldr-core/-/cldr-core-36.0.0.tgz" + resolved "https://registry.npmjs.org/cldr-core/-/cldr-core-36.0.0.tgz#1d2148ed6802411845baeeb21432d7bbfde7d4f7" integrity sha512-QLnAjt20rZe38c8h8OJ9jPND+O4o5O8Nw0TK/P3KpNn1cmOhMu0rk6Kc3ap96c5OStQ9gAngs9+Be2sum26NOw== clean-base-url@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/clean-base-url/-/clean-base-url-1.0.0.tgz" + resolved "https://registry.npmjs.org/clean-base-url/-/clean-base-url-1.0.0.tgz#c901cf0a20b972435b0eccd52d056824a4351b7b" integrity sha512-9q6ZvUAhbKOSRFY7A/irCQ/rF0KIpa3uXpx6izm8+fp7b2H4hLeUJ+F1YYk9+gDQ/X8Q0MEyYs+tG3cht//HTg== clean-css-promise@^0.1.0: version "0.1.1" - resolved "https://registry.npmjs.org/clean-css-promise/-/clean-css-promise-0.1.1.tgz" + resolved "https://registry.npmjs.org/clean-css-promise/-/clean-css-promise-0.1.1.tgz#43f3d2c8dfcb2bf071481252cd9b76433c08eecb" integrity sha512-tzWkANXMD70ETa/wAu2TXAAxYWS0ZjVUFM2dVik8RQBoAbGMFJv4iVluz3RpcoEbo++fX4RV/BXfgGoOjp8o3Q== dependencies: array-to-error "^1.0.0" @@ -5071,7 +5200,7 @@ clean-css-promise@^0.1.0: clean-css@^3.4.5: version "3.4.28" - resolved "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz" + resolved "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" integrity sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw== dependencies: commander "2.8.x" @@ -5079,37 +5208,37 @@ clean-css@^3.4.5: clean-stack@^2.0.0, clean-stack@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== clean-up-path@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/clean-up-path/-/clean-up-path-1.0.0.tgz" + resolved "https://registry.npmjs.org/clean-up-path/-/clean-up-path-1.0.0.tgz#de9e8196519912e749c9eaf67c13d64fac72a3e5" integrity sha512-PHGlEF0Z6976qQyN6gM7kKH6EH0RdfZcc8V+QhFe36eRxV0SMH5OUBZG7Bxa9YcreNzyNbK63cGiZxdSZgosRw== cli-cursor@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw== dependencies: restore-cursor "^2.0.0" cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-spinners@^2.0.0, cli-spinners@^2.5.0: - version "2.7.0" - resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz" - integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== + version "2.9.2" + resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@^0.6.0: - version "0.6.3" - resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + version "0.6.5" + resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f" + integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ== dependencies: string-width "^4.2.0" optionalDependencies: @@ -5117,14 +5246,14 @@ cli-table3@^0.6.0: cli-table@^0.3.1: version "0.3.11" - resolved "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz" + resolved "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz#ac69cdecbe81dccdba4889b9a18b7da312a9d3ee" integrity sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ== dependencies: colors "1.0.3" cli-truncate@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== dependencies: slice-ansi "^3.0.0" @@ -5132,17 +5261,17 @@ cli-truncate@^2.1.0: cli-width@^2.0.0: version "2.2.1" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== cli-width@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" + resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== clipboard@^2.0.11: version "2.0.11" - resolved "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz" + resolved "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz#62180360b97dd668b6b3a84ec226975762a70be5" integrity sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw== dependencies: good-listener "^1.2.2" @@ -5151,7 +5280,7 @@ clipboard@^2.0.11: cliui@^7.0.2: version "7.0.4" - resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" + resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== dependencies: string-width "^4.2.0" @@ -5160,27 +5289,27 @@ cliui@^7.0.2: clone@^1.0.2: version "1.0.4" - resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" + resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== clone@^2.0.0, clone@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" + resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== code-point-at@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== codemirror@~5.15.0: version "5.15.2" - resolved "https://registry.npmjs.org/codemirror/-/codemirror-5.15.2.tgz" + resolved "https://registry.npmjs.org/codemirror/-/codemirror-5.15.2.tgz#58b3dc732c6d10d7aae806f4c7cdd56a9b87fe8f" integrity sha512-QHZClCGimKVK86/+K1YcKwa2/9pzy5OfAsv0nsXlPxxoWOhGc+HxPWQISnIrYMHwA5QCtiObxo5O/tmV4fzOSQ== collection-visit@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== dependencies: map-visit "^1.0.0" @@ -5188,117 +5317,122 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@^1.1.4, color-name@~1.1.4: +color-name@~1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== color-support@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" + resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== colorette@^2.0.16: - version "2.0.19" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + version "2.0.20" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== colors@1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" + resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw== colors@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" + resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" comma-separated-tokens@^1.0.0: version "1.0.8" - resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== commander@2.8.x: version "2.8.1" - resolved "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz" + resolved "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" integrity sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ== dependencies: graceful-readlink ">= 1.0.0" commander@7.2.0: version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== commander@^2.20.0, commander@^2.6.0: version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^4.1.1: +commander@^4.0.0, commander@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" + resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== commander@^6.2.0, commander@^6.2.1: version "6.2.1" - resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" + resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +common-ancestor-path@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" + integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w== + common-tags@^1.8.0: version "1.8.2" - resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz" + resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== commondir@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== compare-versions@^3.6.0: version "3.6.0" - resolved "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz" + resolved "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + version "1.3.1" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== compressible@~2.0.16: version "2.0.18" - resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== dependencies: mime-db ">= 1.43.0 < 2" compression@^1.7.4: version "1.7.4" - resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== dependencies: accepts "~1.3.5" @@ -5311,12 +5445,12 @@ compression@^1.7.4: concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-stream@^1.5.0: version "1.6.2" - resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== dependencies: buffer-from "^1.0.0" @@ -5326,7 +5460,7 @@ concat-stream@^1.5.0: configstore@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz" + resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== dependencies: dot-prop "^5.2.0" @@ -5338,7 +5472,7 @@ configstore@^5.0.1: connect@^3.6.6: version "3.7.0" - resolved "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz" + resolved "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== dependencies: debug "2.6.9" @@ -5348,17 +5482,17 @@ connect@^3.6.6: console-browserify@^1.1.0: version "1.2.0" - resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz" + resolved "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== console-ui@^3.0.4, console-ui@^3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/console-ui/-/console-ui-3.1.2.tgz" + resolved "https://registry.npmjs.org/console-ui/-/console-ui-3.1.2.tgz#51aef616ff02013c85ccee6a6d77ef7a94202e7a" integrity sha512-+5j3R4wZJcEYZeXk30whc4ZU/+fWW9JMTNntVuMYpjZJ9n26Cxr0tUBXco1NRjVZRpRVvZ4DDKKKIHNYeUG9Dw== dependencies: chalk "^2.1.0" @@ -5369,41 +5503,61 @@ console-ui@^3.0.4, console-ui@^3.1.2: consolidate@^0.16.0: version "0.16.0" - resolved "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz" + resolved "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== dependencies: bluebird "^3.7.2" constants-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz" + resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== +"consul-acls@file:packages/consul-acls": + version "0.1.0" + +"consul-lock-sessions@file:packages/consul-lock-sessions": + version "0.1.0" + +"consul-nspaces@file:packages/consul-nspaces": + version "0.1.0" + +"consul-partitions@file:packages/consul-partitions": + version "0.1.0" + +"consul-peerings@file:packages/consul-peerings": + version "0.1.0" + content-disposition@0.5.4: version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== continuable-cache@^0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz" + resolved "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" integrity sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA== -convert-source-map@^1.5.1, convert-source-map@^1.7.0: +convert-source-map@^1.5.1: version "1.9.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-parser@^1.4.4: version "1.4.6" - resolved "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz" + resolved "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz#3ac3a7d35a7a03bbc7e365073a26074824214594" integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== dependencies: cookie "0.4.1" @@ -5411,22 +5565,27 @@ cookie-parser@^1.4.4: cookie-signature@1.0.6: version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.4.1, cookie@~0.4.1: +cookie@0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +cookie@~0.4.1: + version "0.4.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== copy-concurrently@^1.0.0: version "1.0.5" - resolved "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz" + resolved "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== dependencies: aproba "^1.1.1" @@ -5438,41 +5597,41 @@ copy-concurrently@^1.0.0: copy-dereference@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/copy-dereference/-/copy-dereference-1.0.0.tgz" + resolved "https://registry.npmjs.org/copy-dereference/-/copy-dereference-1.0.0.tgz#6b131865420fd81b413ba994b44d3655311152b6" integrity sha512-40TSLuhhbiKeszZhK9LfNdazC67Ue4kq/gGwN5sdxEUWPXTIMmKmGmgD9mPfNKVAeecEW+NfEIpBaZoACCQLLw== copy-descriptor@^0.1.0: version "0.1.1" - resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -core-js-compat@^3.25.1: - version "3.29.0" - resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.29.0.tgz" - integrity sha512-ScMn3uZNAFhK2DGoEfErguoiAHhV2Ju+oJo/jK08p7B3f3UhocUrCCkTvnZaiS+edl5nlIoiBXKcwMc6elv4KQ== +core-js-compat@^3.31.0, core-js-compat@^3.36.1: + version "3.37.1" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz#c844310c7852f4bdf49b8d339730b97e17ff09ee" + integrity sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg== dependencies: - browserslist "^4.21.5" + browserslist "^4.23.0" core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: version "2.6.12" - resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz" + resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-object@^3.1.5: version "3.1.5" - resolved "https://registry.npmjs.org/core-object/-/core-object-3.1.5.tgz" + resolved "https://registry.npmjs.org/core-object/-/core-object-3.1.5.tgz#fa627b87502adc98045e44678e9a8ec3b9c0d2a9" integrity sha512-sA2/4+/PZ/KV6CKgjrVrrUVBKCkdDO02CUlQ0YKTQoYUwPYNOtOAcWlbYhd5v/1JqYaA6oZ4sDlOU4ppVw6Wbg== dependencies: chalk "^2.0.0" core-util-is@~1.0.0: version "1.0.3" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cors@~2.8.5: version "2.8.5" - resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" + resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== dependencies: object-assign "^4" @@ -5480,7 +5639,7 @@ cors@~2.8.5: cosmiconfig@^7.0.0: version "7.1.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" @@ -5491,7 +5650,7 @@ cosmiconfig@^7.0.0: create-ecdh@^4.0.0: version "4.0.4" - resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz" + resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== dependencies: bn.js "^4.1.0" @@ -5499,7 +5658,7 @@ create-ecdh@^4.0.0: create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz" + resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== dependencies: cipher-base "^1.0.1" @@ -5510,7 +5669,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" - resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz" + resolved "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== dependencies: cipher-base "^1.0.3" @@ -5522,7 +5681,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: nice-try "^1.0.4" @@ -5533,7 +5692,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -5542,7 +5701,7 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: crypto-browserify@^3.11.0: version "3.12.0" - resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz" + resolved "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: browserify-cipher "^1.0.0" @@ -5559,12 +5718,12 @@ crypto-browserify@^3.11.0: crypto-random-string@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz" + resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== css-loader@^5.2.0: version "5.2.7" - resolved "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz" + resolved "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== dependencies: icss-utils "^5.1.0" @@ -5580,7 +5739,7 @@ css-loader@^5.2.0: css-tree@^2.0.4: version "2.3.1" - resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz" + resolved "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== dependencies: mdn-data "2.0.30" @@ -5588,12 +5747,12 @@ css-tree@^2.0.4: css.escape@^1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz" + resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== css@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/css/-/css-3.0.0.tgz" + resolved "https://registry.npmjs.org/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== dependencies: inherits "^2.0.4" @@ -5602,63 +5761,63 @@ css@^3.0.0: cssesc@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== cssom@^0.4.4: version "0.4.4" - resolved "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== cssom@~0.3.6: version "0.3.8" - resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== cssstyle@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz" + resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: cssom "~0.3.6" cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz" - integrity sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A== + version "1.0.2" + resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" + integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== d3-array@2, d3-array@^2.3.0, d3-array@^2.8.0: version "2.12.1" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== dependencies: internmap "^1.0.0" "d3-color@1 - 2": version "2.0.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== "d3-format@1 - 2": version "2.0.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== "d3-interpolate@1 - 2", "d3-interpolate@1.2.0 - 2": version "2.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== dependencies: d3-color "1 - 2" "d3-path@1 - 2": version "2.0.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== d3-scale-chromatic@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz" + resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz#c13f3af86685ff91323dc2f0ebd2dabbd72d8bab" integrity sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA== dependencies: d3-color "1 - 2" @@ -5666,7 +5825,7 @@ d3-scale-chromatic@^2.0.0: d3-scale@^3.2.3: version "3.3.0" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== dependencies: d3-array "^2.3.0" @@ -5677,100 +5836,136 @@ d3-scale@^3.2.3: d3-selection@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz#94a11638ea2141b7565f883780dabc7ef6a61066" integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA== d3-shape@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f" integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA== dependencies: d3-path "1 - 2" "d3-time-format@2 - 3": version "3.0.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== dependencies: d3-time "1 - 2" "d3-time@1 - 2", d3-time@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== dependencies: d3-array "2" dag-map@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/dag-map/-/dag-map-2.0.2.tgz" + resolved "https://registry.npmjs.org/dag-map/-/dag-map-2.0.2.tgz#9714b472de82a1843de2fba9b6876938cab44c68" integrity sha512-xnsprIzYuDeiyu5zSKwilV/ajRHxnoMlAhEREfyfTgTSViMVY2fGP1ZcHJbtwup26oCkofySU/m6oKJ3HrkW7w== data-urls@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz" + resolved "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== dependencies: abab "^2.0.3" whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + dayjs@^1.9.3: - version "1.11.7" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz" - integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + version "1.11.11" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz#dfe0e9d54c5f8b68ccf8ca5f72ac603e7e5ed59e" + integrity sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg== debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2, debug@~4.3.4: + version "4.3.5" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== dependencies: ms "2.1.2" debug@^3.0.1, debug@^3.1.0, debug@^3.2.7: version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debuglog@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz" + resolved "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw== decimal.js@^10.2.1: version "10.4.3" - resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" + resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== decode-uri-component@^0.2.0: version "0.2.2" - resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== +decorator-transforms@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/decorator-transforms/-/decorator-transforms-2.0.0.tgz#4e9178a8905c81ff79f4078dc6dfb716244ecd37" + integrity sha512-ETfQccGcotK01YJsoB0AGTdUp7kS9jI93mBzrRY5Oyo+bOJfa2UKTSjCNf+iRNwAWBmBKlbiCcyL4tkY4C4dZQ== + dependencies: + "@babel/plugin-syntax-decorators" "^7.23.3" + babel-import-util "^3.0.0" + dedent@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== -deep-equal@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz" - integrity sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw== +deep-equal@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== dependencies: - call-bind "^1.0.2" - es-get-iterator "^1.1.2" - get-intrinsic "^1.1.3" + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.5" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.2" is-arguments "^1.1.1" - is-array-buffer "^3.0.1" + is-array-buffer "^3.0.2" is-date-object "^1.0.5" is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" @@ -5778,136 +5973,137 @@ deep-equal@^2.2.0: object-is "^1.1.5" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.1" side-channel "^1.0.4" which-boxed-primitive "^1.0.2" which-collection "^1.0.1" - which-typed-array "^1.1.9" + which-typed-array "^1.1.13" -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: - version "4.3.0" - resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz" - integrity sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og== + version "4.3.1" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== defaults@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz" + resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== dependencies: clone "^1.0.2" -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.2.0" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== +define-data-property@^1.0.1, define-data-property@^1.1.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" has-property-descriptors "^1.0.0" object-keys "^1.1.1" define-property@^0.2.5: version "0.2.5" - resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@^1.0.0, defined@^1.0.1: +defined@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz" + resolved "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== delegate@^3.1.2: version "3.2.0" - resolved "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz" + resolved "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== delegates@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== depd@2.0.0, depd@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== depd@~1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + version "1.1.0" + resolved "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" destroy@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-file@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz" + resolved "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q== detect-indent@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" integrity sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A== dependencies: repeating "^2.0.0" detect-indent@^6.0.0: version "6.1.0" - resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz" + resolved "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== detect-newline@3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detective@^5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz" - integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw== - dependencies: - acorn-node "^1.8.2" - defined "^1.0.0" - minimist "^1.2.6" - dezalgo@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz" + resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== dependencies: asap "^2.0.0" @@ -5915,27 +6111,27 @@ dezalgo@^1.0.0: dialog-polyfill@^0.5.6: version "0.5.6" - resolved "https://registry.npmjs.org/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz" + resolved "https://registry.npmjs.org/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz#7507b4c745a82fcee0fa07ce64d835979719599a" integrity sha512-ZbVDJI9uvxPAKze6z146rmfUZjBqNEwcnFTVamQzXH+svluiV7swmVIGr7miwADgfgt1G2JQIytypM9fbyhX4w== didyoumean@^1.2.2: version "1.2.2" - resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" + resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== diff@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== diff@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + version "5.2.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== diffie-hellman@^5.0.0: version "5.0.3" - resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz" + resolved "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== dependencies: bn.js "^4.1.0" @@ -5944,19 +6140,19 @@ diffie-hellman@^5.0.0: dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" dlv@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" + resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== doctoc@^2.0.0: version "2.2.1" - resolved "https://registry.npmjs.org/doctoc/-/doctoc-2.2.1.tgz" + resolved "https://registry.npmjs.org/doctoc/-/doctoc-2.2.1.tgz#83f6a6bf4df97defbe027c9a82d13091a138ffe2" integrity sha512-qNJ1gsuo7hH40vlXTVVrADm6pdg30bns/Mo7Nv1SxuXSM1bwF9b4xQ40a6EFT/L1cI+Yylbyi8MPI4G4y7XJzQ== dependencies: "@textlint/markdown-to-ast" "^12.1.1" @@ -5968,14 +6164,14 @@ doctoc@^2.0.0: doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-serializer@^1.0.1: version "1.4.1" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== dependencies: domelementtype "^2.0.1" @@ -5984,31 +6180,31 @@ dom-serializer@^1.0.1: domain-browser@^1.1.1: version "1.2.0" - resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz" + resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== domexception@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz" + resolved "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: webidl-conversions "^5.0.0" domhandler@^4.2.0, domhandler@^4.2.2: version "4.3.1" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== dependencies: domelementtype "^2.2.0" domutils@^2.8.0: version "2.8.0" - resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" + resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== dependencies: dom-serializer "^1.0.1" @@ -6017,7 +6213,7 @@ domutils@^2.8.0: dot-case@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" + resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== dependencies: no-case "^3.0.4" @@ -6025,21 +6221,21 @@ dot-case@^3.0.4: dot-prop@^5.2.0: version "5.3.0" - resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz" + resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: is-obj "^2.0.0" dotignore@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz" + resolved "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== dependencies: minimatch "^3.0.4" duplexify@^3.4.2, duplexify@^3.6.0: version "3.7.1" - resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz" + resolved "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== dependencies: end-of-stream "^1.0.0" @@ -6049,12 +6245,12 @@ duplexify@^3.4.2, duplexify@^3.6.0: editions@^1.1.1: version "1.3.4" - resolved "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz" + resolved "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== editions@^2.2.0: version "2.3.1" - resolved "https://registry.npmjs.org/editions/-/editions-2.3.1.tgz" + resolved "https://registry.npmjs.org/editions/-/editions-2.3.1.tgz#3bc9962f1978e801312fbd0aebfed63b49bfe698" integrity sha512-ptGvkwTvGdGfC0hfhKg0MT+TRLRKGtUiWGBInxOm5pz7ssADezahjCUaYuZ8Dr+C05FW0AECIIPt4WBxVINEhA== dependencies: errlop "^2.0.0" @@ -6062,18 +6258,18 @@ editions@^2.2.0: ee-first@1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.284: - version "1.4.328" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.328.tgz" - integrity sha512-DE9tTy2PNmy1v55AZAO542ui+MLC2cvINMK4P2LXGsJdput/ThVG9t+QGecPuAZZSgC8XoI+Jh9M1OG9IoNSCw== +electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.796: + version "1.4.818" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz#7762c8bfd15a07c3833b7f5deed990e9e5a4c24f" + integrity sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA== -elliptic@^6.5.3: - version "6.5.4" - resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== +elliptic@^6.5.3, elliptic@^6.5.5: + version "6.5.5" + resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded" + integrity sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw== dependencies: bn.js "^4.11.9" brorand "^1.1.0" @@ -6085,7 +6281,7 @@ elliptic@^6.5.3: ember-a11y-refocus@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/ember-a11y-refocus/-/ember-a11y-refocus-3.0.2.tgz" + resolved "https://registry.npmjs.org/ember-a11y-refocus/-/ember-a11y-refocus-3.0.2.tgz#e648c491d3a8d84cb594679bafc8430cd22b2ed4" integrity sha512-5T9kAvl0RUBF6SSeaaWpVS2WC8MTktgqiGdLAbxVjT2f2NGrDDPmv7riDVNMsuL5sHRwSKm0EHCIzZ4M3aFMow== dependencies: ember-cli-babel "^7.26.11" @@ -6093,14 +6289,14 @@ ember-a11y-refocus@^3.0.2: ember-array-fns@^1.4.0: version "1.4.2" - resolved "https://registry.npmjs.org/ember-array-fns/-/ember-array-fns-1.4.2.tgz" + resolved "https://registry.npmjs.org/ember-array-fns/-/ember-array-fns-1.4.2.tgz#7087cbedcde195dcae25576832920499171b1749" integrity sha512-ceUebR8CeU/dOSLwyXIAfLsxvve8FTD9O8m8XQqdCpY1mUh43dAz5INaF/PGPA+Rkbxrq67Cidvr5AewjwQlPg== dependencies: ember-cli-babel "^7.7.3" ember-assign-helper@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/ember-assign-helper/-/ember-assign-helper-0.3.0.tgz" + resolved "https://registry.npmjs.org/ember-assign-helper/-/ember-assign-helper-0.3.0.tgz#7a023dd165ef56b28f77f70fd20e88261380aca7" integrity sha512-kDY0IRP6PUSJjghM2gIq24OD7d6XcZ1666zmZrywxEVjCenhaR0Oi/BXUU8JEATrIcXIExMIu34GKrHHlCLw0Q== dependencies: ember-cli-babel "^7.19.0" @@ -6108,7 +6304,7 @@ ember-assign-helper@^0.3.0: ember-auto-import@^1.10.1, ember-auto-import@^1.11.3, ember-auto-import@^1.5.3: version "1.12.2" - resolved "https://registry.npmjs.org/ember-auto-import/-/ember-auto-import-1.12.2.tgz" + resolved "https://registry.npmjs.org/ember-auto-import/-/ember-auto-import-1.12.2.tgz#cc7298ee5c0654b0249267de68fb27a2861c3579" integrity sha512-gLqML2k77AuUiXxWNon1FSzuG1DV7PEPpCLCU5aJvf6fdL6rmFfElsZRh+8ELEB/qP9dT+LHjNEunVzd2dYc8A== dependencies: "@babel/core" "^7.1.6" @@ -6141,50 +6337,16 @@ ember-auto-import@^1.10.1, ember-auto-import@^1.11.3, ember-auto-import@^1.5.3: walk-sync "^0.3.3" webpack "^4.43.0" -ember-auto-import@^2.2.3, ember-auto-import@^2.4.2, ember-auto-import@^2.5.0: - version "2.6.1" - resolved "https://registry.npmjs.org/ember-auto-import/-/ember-auto-import-2.6.1.tgz" - integrity sha512-3bCRi/pXp4QslmuCXGlSz9xwR7DF5oDx3zZO5OXKzNZihtkqAM1xvGuRIdQSl46pvbAXOkp8Odl5fOen1i0dRw== - dependencies: - "@babel/core" "^7.16.7" - "@babel/plugin-proposal-class-properties" "^7.16.7" - "@babel/plugin-proposal-decorators" "^7.16.7" - "@babel/preset-env" "^7.16.7" - "@embroider/macros" "^1.0.0" - "@embroider/shared-internals" "^2.0.0" - babel-loader "^8.0.6" - babel-plugin-ember-modules-api-polyfill "^3.5.0" - babel-plugin-htmlbars-inline-precompile "^5.2.1" - babel-plugin-syntax-dynamic-import "^6.18.0" - broccoli-debug "^0.6.4" - broccoli-funnel "^3.0.8" - broccoli-merge-trees "^4.2.0" - broccoli-plugin "^4.0.0" - broccoli-source "^3.0.0" - css-loader "^5.2.0" - debug "^4.3.1" - fs-extra "^10.0.0" - fs-tree-diff "^2.0.0" - handlebars "^4.3.1" - js-string-escape "^1.0.1" - lodash "^4.17.19" - mini-css-extract-plugin "^2.5.2" - parse5 "^6.0.1" - resolve "^1.20.0" - resolve-package-path "^4.0.3" - semver "^7.3.4" - style-loader "^2.0.0" - typescript-memoize "^1.0.0-alpha.3" - walk-sync "^3.0.0" - -ember-auto-import@^2.6.3: - version "2.6.3" - resolved "https://registry.npmjs.org/ember-auto-import/-/ember-auto-import-2.6.3.tgz" - integrity sha512-uLhrRDJYWCRvQ4JQ1e64XlSrqAKSd6PXaJ9ZsZI6Tlms9T4DtQFxNXasqji2ZRJBVrxEoLCRYX3RTldsQ0vNGQ== +ember-auto-import@^2.2.3, ember-auto-import@^2.4.2, ember-auto-import@^2.5.0, ember-auto-import@^2.6.3: + version "2.7.4" + resolved "https://registry.npmjs.org/ember-auto-import/-/ember-auto-import-2.7.4.tgz#ca99570eb3d6165968df797a4750aa58073852b5" + integrity sha512-6CdXSegJJc8nwwK7+1lIcBUnMVrJRNd4ZdMgcKbCAwPvcGxMgRVBddSzrX/+q/UuflvTEO26Dk1g7Z6KHMXUhw== dependencies: "@babel/core" "^7.16.7" "@babel/plugin-proposal-class-properties" "^7.16.7" "@babel/plugin-proposal-decorators" "^7.16.7" + "@babel/plugin-proposal-private-methods" "^7.16.7" + "@babel/plugin-transform-class-static-block" "^7.16.7" "@babel/preset-env" "^7.16.7" "@embroider/macros" "^1.0.0" "@embroider/shared-internals" "^2.0.0" @@ -6206,6 +6368,7 @@ ember-auto-import@^2.6.3: js-string-escape "^1.0.1" lodash "^4.17.19" mini-css-extract-plugin "^2.5.2" + minimatch "^3.0.0" parse5 "^6.0.1" resolve "^1.20.0" resolve-package-path "^4.0.3" @@ -6216,7 +6379,7 @@ ember-auto-import@^2.6.3: ember-basic-dropdown@3.0.21, ember-basic-dropdown@^3.0.21: version "3.0.21" - resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-3.0.21.tgz#5711d071966919c9578d2d5ac2c6dcadbb5ea0e0" + resolved "https://registry.npmjs.org/ember-basic-dropdown/-/ember-basic-dropdown-3.0.21.tgz#5711d071966919c9578d2d5ac2c6dcadbb5ea0e0" integrity sha512-Wu9hJWyqorKo+ZT2PMSIO1BxAeAdaiIC2IjSic0+HcKjmMU47botvG0xbxlprimOWaS9vM+nHat6Pt3xPvcB0A== dependencies: "@ember/render-modifiers" "^2.0.0" @@ -6234,7 +6397,7 @@ ember-basic-dropdown@3.0.21, ember-basic-dropdown@^3.0.21: ember-cache-primitive-polyfill@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/ember-cache-primitive-polyfill/-/ember-cache-primitive-polyfill-1.0.1.tgz" + resolved "https://registry.npmjs.org/ember-cache-primitive-polyfill/-/ember-cache-primitive-polyfill-1.0.1.tgz#a27075443bd87e5af286c1cd8a7df24e3b9f6715" integrity sha512-hSPcvIKarA8wad2/b6jDd/eU+OtKmi6uP+iYQbzi5TQpjsqV6b4QdRqrLk7ClSRRKBAtdTuutx+m+X+WlEd2lw== dependencies: ember-cli-babel "^7.22.1" @@ -6244,7 +6407,7 @@ ember-cache-primitive-polyfill@^1.0.1: ember-cached-decorator-polyfill@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/ember-cached-decorator-polyfill/-/ember-cached-decorator-polyfill-0.1.4.tgz" + resolved "https://registry.npmjs.org/ember-cached-decorator-polyfill/-/ember-cached-decorator-polyfill-0.1.4.tgz#f1e2c65cc78d0d9c4ac0e047e643af477eb85ace" integrity sha512-JOK7kBCWsTVCzmCefK4nr9BACDJk0owt9oIUaVt6Q0UtQ4XeAHmoK5kQ/YtDcxQF1ZevHQFdGhsTR3JLaHNJgA== dependencies: "@glimmer/tracking" "^1.0.4" @@ -6254,7 +6417,7 @@ ember-cached-decorator-polyfill@^0.1.4: ember-can@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/ember-can/-/ember-can-4.2.0.tgz" + resolved "https://registry.npmjs.org/ember-can/-/ember-can-4.2.0.tgz#08bfec3b2b57aad3dc6e4dc36fe9692bd1794dab" integrity sha512-hiaWZspmI4zWeWmmFWgyw1+yEStSo6edGRHHUXCUPR+vBoqlT/hEfmndlfDGso2GFP8IV59DORMVY0KReMcO+w== dependencies: ember-cli-babel "^7.26.6" @@ -6263,7 +6426,7 @@ ember-can@^4.2.0: ember-changeset-validations@~3.15.2: version "3.15.2" - resolved "https://registry.npmjs.org/ember-changeset-validations/-/ember-changeset-validations-3.15.2.tgz" + resolved "https://registry.npmjs.org/ember-changeset-validations/-/ember-changeset-validations-3.15.2.tgz#c19a65661446c64088fd5daf4f95f0819ccc95af" integrity sha512-jPcX4aXRY9SLivHHRkrUZovL1xeEchAyoDR7lyOpverfjVJFr3p0qEp4L8pwKBeCQHnV0JcLM9r1DqpRoGLmkw== dependencies: ember-changeset "^3.14.1" @@ -6275,7 +6438,7 @@ ember-changeset-validations@~3.15.2: ember-changeset@^3.14.1: version "3.15.0" - resolved "https://registry.npmjs.org/ember-changeset/-/ember-changeset-3.15.0.tgz" + resolved "https://registry.npmjs.org/ember-changeset/-/ember-changeset-3.15.0.tgz#402bbb9b51dc44596415c1c7b0e3a4923b1d3e81" integrity sha512-yLyU3quV96EFjYzYUjIK4je5nnemZdbElYLFnXYJ5StXquCRjdFvL79gst/vs6ZjVFbkRKnLjsVP8YMkED0P2g== dependencies: "@embroider/macros" "^0.42.3" @@ -6286,7 +6449,7 @@ ember-changeset@^3.14.1: ember-cli-app-version@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/ember-cli-app-version/-/ember-cli-app-version-5.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-app-version/-/ember-cli-app-version-5.0.0.tgz#adad17c6f706f419b223707eec66dd1cd28530c3" integrity sha512-afhx/CXDOMNXzoe4NDPy5WUfxWmYYHUzMCiTyvPBxCDBXYcMrtxNWxvgaSaeqcoHVEmqzeyBj8V82tzmT1dcyw== dependencies: ember-cli-babel "^7.23.1" @@ -6294,12 +6457,12 @@ ember-cli-app-version@^5.0.0: ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.0, ember-cli-babel-plugin-helpers@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.1.tgz" + resolved "https://registry.npmjs.org/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.1.tgz#5016b80cdef37036c4282eef2d863e1d73576879" integrity sha512-sKvOiPNHr5F/60NLd7SFzMpYPte/nnGkq/tMIfXejfKHIhaiIkYFqX8Z9UFTKWLLn+V7NOaby6niNPZUdvKCRw== ember-cli-babel@^6.0.0, ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1, ember-cli-babel@^6.8.2: version "6.18.0" - resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz#3f6435fd275172edeff2b634ee7b29ce74318957" integrity sha512-7ceC8joNYxY2wES16iIBlbPSxwKDBhYwC8drU3ZEvuPDMwVv1KzxCNu1fvxyFEBWhwaRNTUxSCsEVoTd9nosGA== dependencies: amd-name-resolver "1.2.0" @@ -6316,9 +6479,9 @@ ember-cli-babel@^6.0.0, ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.6.0, e ember-cli-version-checker "^2.1.2" semver "^5.5.0" -ember-cli-babel@^7.0.0, ember-cli-babel@^7.1.3, ember-cli-babel@^7.10.0, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.17.2, ember-cli-babel@^7.18.0, ember-cli-babel@^7.19.0, ember-cli-babel@^7.20.0, ember-cli-babel@^7.21.0, ember-cli-babel@^7.22.1, ember-cli-babel@^7.23.0, ember-cli-babel@^7.23.1, ember-cli-babel@^7.26.0, ember-cli-babel@^7.26.1, ember-cli-babel@^7.26.10, ember-cli-babel@^7.26.11, ember-cli-babel@^7.26.3, ember-cli-babel@^7.26.4, ember-cli-babel@^7.26.5, ember-cli-babel@^7.26.6, ember-cli-babel@^7.7.3: +ember-cli-babel@^7.0.0, ember-cli-babel@^7.1.3, ember-cli-babel@^7.10.0, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.17.2, ember-cli-babel@^7.18.0, ember-cli-babel@^7.19.0, ember-cli-babel@^7.20.0, ember-cli-babel@^7.21.0, ember-cli-babel@^7.22.1, ember-cli-babel@^7.23.0, ember-cli-babel@^7.23.1, ember-cli-babel@^7.26.0, ember-cli-babel@^7.26.1, ember-cli-babel@^7.26.10, ember-cli-babel@^7.26.11, ember-cli-babel@^7.26.3, ember-cli-babel@^7.26.4, ember-cli-babel@^7.26.5, ember-cli-babel@^7.26.6, ember-cli-babel@^7.7.3: version "7.26.11" - resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-7.26.11.tgz" + resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-7.26.11.tgz#50da0fe4dcd99aada499843940fec75076249a9f" integrity sha512-JJYeYjiz/JTn34q7F5DSOjkkZqy8qwFOOxXfE6pe9yEJqWGu4qErKxlz8I22JoVEQ/aBUO+OcKTpmctvykM9YA== dependencies: "@babel/core" "^7.12.0" @@ -6352,9 +6515,42 @@ ember-cli-babel@^7.0.0, ember-cli-babel@^7.1.3, ember-cli-babel@^7.10.0, ember-c rimraf "^3.0.1" semver "^5.5.0" +ember-cli-babel@^8.2.0: + version "8.2.0" + resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-8.2.0.tgz#91e14c22ac22956177002385947724174553d41c" + integrity sha512-8H4+jQElCDo6tA7CamksE66NqBXWs7VNpS3a738L9pZCjg2kXIX4zoyHzkORUqCtr0Au7YsCnrlAMi1v2ALo7A== + dependencies: + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/plugin-proposal-class-properties" "^7.16.5" + "@babel/plugin-proposal-decorators" "^7.20.13" + "@babel/plugin-proposal-private-methods" "^7.16.5" + "@babel/plugin-proposal-private-property-in-object" "^7.20.5" + "@babel/plugin-transform-class-static-block" "^7.22.11" + "@babel/plugin-transform-modules-amd" "^7.20.11" + "@babel/plugin-transform-runtime" "^7.13.9" + "@babel/plugin-transform-typescript" "^7.20.13" + "@babel/preset-env" "^7.20.2" + "@babel/runtime" "7.12.18" + amd-name-resolver "^1.3.1" + babel-plugin-debug-macros "^0.3.4" + babel-plugin-ember-data-packages-polyfill "^0.1.2" + babel-plugin-ember-modules-api-polyfill "^3.5.0" + babel-plugin-module-resolver "^5.0.0" + broccoli-babel-transpiler "^8.0.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^3.0.8" + broccoli-source "^3.0.1" + calculate-cache-key-for-tree "^2.0.0" + clone "^2.1.2" + ember-cli-babel-plugin-helpers "^1.1.1" + ember-cli-version-checker "^5.1.2" + ensure-posix-path "^1.0.2" + resolve-package-path "^4.0.3" + semver "^7.3.8" + ember-cli-code-coverage@^1.0.0-beta.4: version "1.0.3" - resolved "https://registry.npmjs.org/ember-cli-code-coverage/-/ember-cli-code-coverage-1.0.3.tgz" + resolved "https://registry.npmjs.org/ember-cli-code-coverage/-/ember-cli-code-coverage-1.0.3.tgz#9a6e5e6350d70761eba749d68ebe2e0d9aa3492f" integrity sha512-tyWeQ22vxpDmfhIrRCMqZPq9Coppefg19hBgME4yb9Na2qslxCNK0USThigZhesb7hfw2ZgdrKJCrmCVNwkq7g== dependencies: babel-plugin-istanbul "^6.0.0" @@ -6368,29 +6564,29 @@ ember-cli-code-coverage@^1.0.0-beta.4: walk-sync "^2.1.0" ember-cli-dependency-checker@^3.2.0: - version "3.3.1" - resolved "https://registry.npmjs.org/ember-cli-dependency-checker/-/ember-cli-dependency-checker-3.3.1.tgz" - integrity sha512-Tg6OeijjXNKWkDm6057Tr0N9j9Vlz/ITewXWpn1A/+Wbt3EowBx5ZKfvoupqz05EznKgL1B/ecG0t+JN7Qm6MA== + version "3.3.2" + resolved "https://registry.npmjs.org/ember-cli-dependency-checker/-/ember-cli-dependency-checker-3.3.2.tgz#94ed7e8e3d47e494082eb9ccfaa489d603ab6017" + integrity sha512-PwkrW5oYsdPWwt+0Tojufmv/hxVETTjkrEdK7ANQB2VSnqpA5UcYubwpQM9ONuR2J8wyNDMwEHlqIrk/FYtBsQ== dependencies: - chalk "^2.3.0" - find-yarn-workspace-root "^1.1.0" + chalk "^2.4.2" + find-yarn-workspace-root "^1.2.1" is-git-url "^1.0.0" - resolve "^1.5.0" - semver "^5.3.0" + resolve "^1.22.0" + semver "^5.7.1" ember-cli-deprecation-workflow@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/ember-cli-deprecation-workflow/-/ember-cli-deprecation-workflow-2.1.0.tgz" - integrity sha512-Ay9P9iKMJdY4Gq5XPowh3HqqeAzLfwBRj1oB1ZKkDW1fryZQWBN4pZuRnjnB+3VWZjBnZif5e7Pacc7YNW9hWg== + version "2.2.0" + resolved "https://registry.npmjs.org/ember-cli-deprecation-workflow/-/ember-cli-deprecation-workflow-2.2.0.tgz#277d56bdafc15dbdb7a58dee598402cdf50e0d08" + integrity sha512-23bXZqZJBJSKBTfT0LK7qzSJX861TgafL6RVdMfn/iubpLnoZIWergYwEdgs24CNTUbuehVbHy2Q71o8jYfwfw== dependencies: + "@ember/string" "^3.0.0" broccoli-funnel "^3.0.3" broccoli-merge-trees "^4.2.0" broccoli-plugin "^4.0.5" - ember-cli-htmlbars "^5.3.2" ember-cli-flash@^2.1.1: version "2.2.2" - resolved "https://registry.npmjs.org/ember-cli-flash/-/ember-cli-flash-2.2.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-flash/-/ember-cli-flash-2.2.2.tgz#19b47f7704cac91a21a790be220eb021ac37c80d" integrity sha512-cHjChy9jYtXiprHwAZCVh8FbsfxBvvqKmz+XlAX6kqf/9uBdrxHzGR0jE0PR8aabX9tWAmjdR0hpT2IbbAwwAg== dependencies: "@ember/render-modifiers" "^1.0.2" @@ -6399,12 +6595,12 @@ ember-cli-flash@^2.1.1: ember-cli-get-component-path-option@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-cli-get-component-path-option/-/ember-cli-get-component-path-option-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-get-component-path-option/-/ember-cli-get-component-path-option-1.0.0.tgz#0d7b595559e2f9050abed804f1d8eff1b08bc771" integrity sha512-k47TDwcJ2zPideBCZE8sCiShSxQSpebY2BHcX2DdipMmBox5gsfyVrbKJWIHeSTTKyEUgmBIvQkqTOozEziCZA== ember-cli-htmlbars@^3.0.1: version "3.1.0" - resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-3.1.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-3.1.0.tgz#87806c2a0bca2ab52d4fb8af8e2215c1ca718a99" integrity sha512-cgvRJM73IT0aePUG7oQ/afB7vSRBV3N0wu9BrWhHX2zkR7A7cUBI7KC9VPk6tbctCXoM7BRGsCC4aIjF7yrfXA== dependencies: broccoli-persistent-filter "^2.3.1" @@ -6414,7 +6610,7 @@ ember-cli-htmlbars@^3.0.1: ember-cli-htmlbars@^4.3.1: version "4.5.0" - resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-4.5.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-4.5.0.tgz#d299e4f7eba6f30dc723ee086906cc550beb252e" integrity sha512-bYJpK1pqFu9AadDAGTw05g2LMNzY8xTCIqQm7dMJmKEoUpLRFbPf4SfHXrktzDh7Q5iggl6Skzf1M0bPlIxARw== dependencies: "@ember/edition-utils" "^1.2.0" @@ -6432,9 +6628,9 @@ ember-cli-htmlbars@^4.3.1: strip-bom "^4.0.0" walk-sync "^2.0.2" -ember-cli-htmlbars@^5.0.0, ember-cli-htmlbars@^5.1.0, ember-cli-htmlbars@^5.1.2, ember-cli-htmlbars@^5.3.1, ember-cli-htmlbars@^5.3.2, ember-cli-htmlbars@^5.7.1, ember-cli-htmlbars@^5.7.2: +ember-cli-htmlbars@^5.0.0, ember-cli-htmlbars@^5.1.0, ember-cli-htmlbars@^5.1.2, ember-cli-htmlbars@^5.3.1, ember-cli-htmlbars@^5.7.1, ember-cli-htmlbars@^5.7.2: version "5.7.2" - resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-5.7.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-5.7.2.tgz#e0cd2fb3c20d85fe4c3e228e6f0590ee1c645ba8" integrity sha512-Uj6R+3TtBV5RZoJY14oZn/sNPnc+UgmC8nb5rI4P3fR/gYoyTFIZSXiIM7zl++IpMoIrocxOrgt+mhonKphgGg== dependencies: "@ember/edition-utils" "^1.2.0" @@ -6454,10 +6650,10 @@ ember-cli-htmlbars@^5.0.0, ember-cli-htmlbars@^5.1.0, ember-cli-htmlbars@^5.1.2, strip-bom "^4.0.0" walk-sync "^2.2.0" -ember-cli-htmlbars@^6.0.0, ember-cli-htmlbars@^6.0.1, ember-cli-htmlbars@^6.1.1, ember-cli-htmlbars@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-6.2.0.tgz" - integrity sha512-j5EGixjGau23HrqRiW/JjoAovg5UBHfjbyN7wX5ekE90knIEqUUj1z/Mo/cTx/J2VepQ2lE6HdXW9LWQ/WdMtw== +ember-cli-htmlbars@^6.0.0, ember-cli-htmlbars@^6.0.1, ember-cli-htmlbars@^6.1.1, ember-cli-htmlbars@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/ember-cli-htmlbars/-/ember-cli-htmlbars-6.3.0.tgz#ac85f2bbd09788992ab7f9ca832cd044fb8e5798" + integrity sha512-N9Y80oZfcfWLsqickMfRd9YByVcTGyhYRnYQ2XVPVrp6jyUyOeRWmEAPh7ERSXpp8Ws4hr/JB9QVQrn/yZa+Ag== dependencies: "@ember/edition-utils" "^1.2.0" babel-plugin-ember-template-compilation "^2.0.0" @@ -6476,7 +6672,7 @@ ember-cli-htmlbars@^6.0.0, ember-cli-htmlbars@^6.0.1, ember-cli-htmlbars@^6.1.1, ember-cli-inject-live-reload@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-2.1.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-2.1.0.tgz#ef63c733c133024d5726405a3c247fa12e88a385" integrity sha512-YV5wYRD5PJHmxaxaJt18u6LE6Y+wo455BnmcpN+hGNlChy2piM9/GMvYgTAz/8Vin8RJ5KekqP/w/NEaRndc/A== dependencies: clean-base-url "^1.0.0" @@ -6484,17 +6680,17 @@ ember-cli-inject-live-reload@^2.1.0: ember-cli-is-package-missing@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-cli-is-package-missing/-/ember-cli-is-package-missing-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-is-package-missing/-/ember-cli-is-package-missing-1.0.0.tgz#6e6184cafb92635dd93ca6c946b104292d4e3390" integrity sha512-9hEoZj6Au5onlSDdcoBqYEPT8ehlYntZPxH8pBKV0GO7LNel88otSAQsCfXvbi2eKE+MaSeLG/gNaCI5UdWm9g== ember-cli-lodash-subset@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/ember-cli-lodash-subset/-/ember-cli-lodash-subset-2.0.1.tgz" + resolved "https://registry.npmjs.org/ember-cli-lodash-subset/-/ember-cli-lodash-subset-2.0.1.tgz#20cb68a790fe0fde2488ddfd8efbb7df6fe766f2" integrity sha512-QkLGcYv1WRK35g4MWu/uIeJ5Suk2eJXKtZ+8s+qE7C9INmpCPyPxzaqZABquYzcWNzIdw6kYwz3NWAFdKYFxwg== ember-cli-node-assets@^0.2.2: version "0.2.2" - resolved "https://registry.npmjs.org/ember-cli-node-assets/-/ember-cli-node-assets-0.2.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-node-assets/-/ember-cli-node-assets-0.2.2.tgz#d2d55626e7cc6619f882d7fe55751f9266022708" integrity sha512-pFyjlhzwx2FxAmkxSVJvP+i+MwHDhmgsmma1ZQbFLYwBeufo1GIzqSJUfStcpOE1NDg8fXm2yZVVzdZYf9lW2w== dependencies: broccoli-funnel "^1.0.1" @@ -6506,14 +6702,14 @@ ember-cli-node-assets@^0.2.2: ember-cli-normalize-entity-name@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-cli-normalize-entity-name/-/ember-cli-normalize-entity-name-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-normalize-entity-name/-/ember-cli-normalize-entity-name-1.0.0.tgz#0b14f7bcbc599aa117b5fddc81e4fd03c4bad5b7" integrity sha512-rF4P1rW2P1gVX1ynZYPmuIf7TnAFDiJmIUFI1Xz16VYykUAyiOCme0Y22LeZq8rTzwBMiwBwoE3RO4GYWehXZA== dependencies: silent-error "^1.0.0" ember-cli-page-object@^1.17.11: version "1.17.12" - resolved "https://registry.npmjs.org/ember-cli-page-object/-/ember-cli-page-object-1.17.12.tgz" + resolved "https://registry.npmjs.org/ember-cli-page-object/-/ember-cli-page-object-1.17.12.tgz#bb5e3b01e81798cbea064d218bbff8cd52e4229b" integrity sha512-G5HCIp8Fp2ywrlBoaxdKNsAsJClnLyG+6Xg7liygnJxYpjc2e9BNcCXShxVsfkG3thlEFhNRWm5TY2TXNguOVA== dependencies: broccoli-file-creator "^2.1.1" @@ -6527,12 +6723,12 @@ ember-cli-page-object@^1.17.11: ember-cli-path-utils@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-cli-path-utils/-/ember-cli-path-utils-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-path-utils/-/ember-cli-path-utils-1.0.0.tgz#4e39af8b55301cddc5017739b77a804fba2071ed" integrity sha512-Qq0vvquzf4cFHoDZavzkOy3Izc893r/5spspWgyzLCPTaG78fM3HsrjZm7UWEltbXUqwHHYrqZd/R0jS08NqSA== ember-cli-postcss@^8.1.0: version "8.2.0" - resolved "https://registry.npmjs.org/ember-cli-postcss/-/ember-cli-postcss-8.2.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-postcss/-/ember-cli-postcss-8.2.0.tgz#9cc1fee624d2d13c41633cf32d4e8cb8d5f88eff" integrity sha512-S2HQqmNtcezmLSt/OPZKCXg+aRV7yFoZp+tn1HCLSbR/eU95xl7MWxTjbj/wOIGMfhggy/hBT2+STDh8mGuVpw== dependencies: broccoli-merge-trees "^4.2.0" @@ -6543,7 +6739,7 @@ ember-cli-postcss@^8.1.0: ember-cli-preprocess-registry@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/ember-cli-preprocess-registry/-/ember-cli-preprocess-registry-3.3.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-preprocess-registry/-/ember-cli-preprocess-registry-3.3.0.tgz#685837a314fbe57224bd54b189f4b9c23907a2de" integrity sha512-60GYpw7VPeB7TvzTLZTuLTlHdOXvayxjAQ+IxM2T04Xkfyu75O2ItbWlftQW7NZVGkaCsXSRAmn22PG03VpLMA== dependencies: broccoli-clean-css "^1.1.0" @@ -6551,10 +6747,10 @@ ember-cli-preprocess-registry@^3.3.0: debug "^3.0.1" process-relative-require "^1.0.0" -ember-cli-sass@^10.0.1: - version "10.0.1" - resolved "https://registry.npmjs.org/ember-cli-sass/-/ember-cli-sass-10.0.1.tgz" - integrity sha512-dWVoX03O2Mot1dEB1AN3ofC8DDZb6iU4Kfkbr3WYi9S9bGVHrpR/ngsR7tuVBuTugTyG53FPtLLqYdqx7XjXdA== +ember-cli-sass@^11.0.1: + version "11.0.1" + resolved "https://registry.npmjs.org/ember-cli-sass/-/ember-cli-sass-11.0.1.tgz#dc565764213a76973a83c0db9583cb79ba187dc5" + integrity sha512-RMlFPMK4kaB+67seF/IIoY3EC4rRd+L58q+lyElrxB3FcQTgph/qmGwtqf9Up7m3SDbPiA7cccCOSmgReMgCXA== dependencies: broccoli-funnel "^2.0.1" broccoli-merge-trees "^3.0.1" @@ -6563,14 +6759,14 @@ ember-cli-sass@^10.0.1: ember-cli-sri@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/ember-cli-sri/-/ember-cli-sri-2.1.1.tgz" + resolved "https://registry.npmjs.org/ember-cli-sri/-/ember-cli-sri-2.1.1.tgz#971620934a4b9183cf7923cc03e178b83aa907fd" integrity sha512-YG/lojDxkur9Bnskt7xB6gUOtJ6aPl/+JyGYm9HNDk3GECVHB3SMN3rlGhDKHa1ndS5NK2W2TSLb9bzRbGlMdg== dependencies: broccoli-sri-hash "^2.1.0" ember-cli-string-helpers@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/ember-cli-string-helpers/-/ember-cli-string-helpers-6.1.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-string-helpers/-/ember-cli-string-helpers-6.1.0.tgz#aeb96112bb91c540b869ed8b9c680f7fd5859cb6" integrity sha512-Lw8B6MJx2n8CNF2TSIKs+hWLw0FqSYjr2/NRPyquyYA05qsl137WJSYW3ZqTsLgoinHat0DGF2qaCXocLhLmyA== dependencies: "@babel/core" "^7.13.10" @@ -6580,12 +6776,12 @@ ember-cli-string-helpers@^6.1.0: ember-cli-string-utils@^1.0.0, ember-cli-string-utils@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz#39b677fc2805f55173735376fcef278eaa4452a1" integrity sha512-PlJt4fUDyBrC/0X+4cOpaGCiMawaaB//qD85AXmDRikxhxVzfVdpuoec02HSiTGTTB85qCIzWBIh8lDOiMyyFg== ember-cli-template-lint@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/ember-cli-template-lint/-/ember-cli-template-lint-2.0.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-template-lint/-/ember-cli-template-lint-2.0.2.tgz#729436e71f45e31a9237bab4bbc9a9ef67401c24" integrity sha512-q/aXIYC9cxWRT3B+VX/45EPzYni5OuctxR9ePhZA1//bjaZtwcnKQtwYk7H4oEDrIKce5KMb0CMco2gvGYmAjA== dependencies: aot-test-generators "^0.1.0" @@ -6602,28 +6798,28 @@ ember-cli-template-lint@^2.0.1: ember-cli-terser@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/ember-cli-terser/-/ember-cli-terser-4.0.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-terser/-/ember-cli-terser-4.0.2.tgz#c436a9e4159f76a615b051cba0584844652b7dcd" integrity sha512-Ej77K+YhCZImotoi/CU2cfsoZaswoPlGaM5TB3LvjvPDlVPRhxUHO2RsaUVC5lsGeRLRiHCOxVtoJ6GyqexzFA== dependencies: broccoli-terser-sourcemap "^4.1.0" ember-cli-test-info@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-cli-test-info/-/ember-cli-test-info-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-test-info/-/ember-cli-test-info-1.0.0.tgz#ed4e960f249e97523cf891e4aed2072ce84577b4" integrity sha512-dEVTIpmUfCzweC97NGf6p7L6XKBwV2GmSM4elmzKvkttEp5P7AvGA9uGyN4GqFq+RwhW+2b0I2qlX00w+skm+A== dependencies: ember-cli-string-utils "^1.0.0" ember-cli-test-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/ember-cli-test-loader/-/ember-cli-test-loader-3.0.0.tgz" - integrity sha512-wfFRBrfO9gaKScYcdQxTfklx9yp1lWK6zv1rZRpkas9z2SHyJojF7NOQRWQgSB3ypm7vfpiF8VsFFVVr7VBzAQ== + version "3.1.0" + resolved "https://registry.npmjs.org/ember-cli-test-loader/-/ember-cli-test-loader-3.1.0.tgz#13abd43b7e07e2266a9f0fc5b9dc5455883b18ff" + integrity sha512-0aocZV9SIoOHiU3hrH3IuLR6busWhTX6UVXgd490hmJkIymmOXNH2+jJoC7Ebkeo3PiOfAdjqhb765QDlHSJOw== dependencies: - ember-cli-babel "^7.13.2" + ember-cli-babel "^7.23.0" ember-cli-typescript@3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-3.0.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-3.0.0.tgz#3b838d1ce9e4d22a98e68da22ceac6dc0cfd9bfc" integrity sha512-lo5YArbJzJi5ssvaGqTt6+FnhTALnSvYVuxM7lfyL1UCMudyNJ94ovH5C7n5il7ATd6WsNiAPRUO/v+s5Jq/aA== dependencies: "@babel/plugin-transform-typescript" "~7.5.0" @@ -6640,7 +6836,7 @@ ember-cli-typescript@3.0.0: ember-cli-typescript@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-2.0.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-2.0.2.tgz#464984131fbdc05655eb61d1c3cdd911d3137f0d" integrity sha512-7I5azCTxOgRDN8aSSnJZIKSqr+MGnT+jLTUbBYqF8wu6ojs2DUnTePxUcQMcvNh3Q3B1ySv7Q/uZFSjdU9gSjA== dependencies: "@babel/plugin-proposal-class-properties" "^7.1.0" @@ -6658,7 +6854,7 @@ ember-cli-typescript@^2.0.2: ember-cli-typescript@^3.1.3, ember-cli-typescript@^3.1.4: version "3.1.4" - resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-3.1.4.tgz" + resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-3.1.4.tgz#21d6ccd670d1f2e34c9cce68c6e32c442f46806b" integrity sha512-HJ73kL45OGRmIkPhBNFt31I1SGUvdZND+LCH21+qpq3pPlFpJG8GORyXpP+2ze8PbnITNLzwe5AwUrpyuRswdQ== dependencies: "@babel/plugin-proposal-nullish-coalescing-operator" "^7.4.4" @@ -6678,7 +6874,7 @@ ember-cli-typescript@^3.1.3, ember-cli-typescript@^3.1.4: ember-cli-typescript@^4.0.0, ember-cli-typescript@^4.1.0, ember-cli-typescript@^4.2.0, ember-cli-typescript@^4.2.1: version "4.2.1" - resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-4.2.1.tgz" + resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-4.2.1.tgz#54d08fc90318cc986f3ea562f93ce58a6cc4c24d" integrity sha512-0iKTZ+/wH6UB/VTWKvGuXlmwiE8HSIGcxHamwNhEC5x1mN3z8RfvsFZdQWYUzIWFN2Tek0gmepGRPTwWdBYl/A== dependencies: ansi-to-html "^0.6.15" @@ -6692,10 +6888,10 @@ ember-cli-typescript@^4.0.0, ember-cli-typescript@^4.1.0, ember-cli-typescript@^ stagehand "^1.0.0" walk-sync "^2.2.0" -ember-cli-typescript@^5.0.0, ember-cli-typescript@^5.1.0: - version "5.2.1" - resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-5.2.1.tgz" - integrity sha512-qqp5TAIuPHxHiGXJKL+78Euyhy0zSKQMovPh8sJpN/ZBYx0H90pONufHR3anaMcp1snVfx4B+mb9+7ijOik8ZA== +ember-cli-typescript@^5.0.0: + version "5.3.0" + resolved "https://registry.npmjs.org/ember-cli-typescript/-/ember-cli-typescript-5.3.0.tgz#c0f726c61e4309aa9ff49b388219c6729ea986cd" + integrity sha512-gFA+ZwmsvvFwo2Jz/B9GMduEn+fPoGb69qWGP0Tp3+Tu5xypDtIKVSZ5086I3Cr19cLXD4HkrOR3YQvdUKzAkQ== dependencies: ansi-to-html "^0.6.15" broccoli-stew "^3.0.0" @@ -6710,7 +6906,7 @@ ember-cli-typescript@^5.0.0, ember-cli-typescript@^5.1.0: ember-cli-version-checker@^2.1.0, ember-cli-version-checker@^2.1.2: version "2.2.0" - resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz#47771b731fe0962705e27c8199a9e3825709f3b3" integrity sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg== dependencies: resolve "^1.3.3" @@ -6718,7 +6914,7 @@ ember-cli-version-checker@^2.1.0, ember-cli-version-checker@^2.1.2: ember-cli-version-checker@^3.1.3: version "3.1.3" - resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-3.1.3.tgz" + resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-3.1.3.tgz#7c9b4f5ff30fdebcd480b1c06c4de43bb51c522c" integrity sha512-PZNSvpzwWgv68hcXxyjREpj3WWb81A7rtYNQq1lLEgrWIchF8ApKJjWP3NBpHjaatwILkZAV8klair5WFlXAKg== dependencies: resolve-package-path "^1.2.6" @@ -6726,7 +6922,7 @@ ember-cli-version-checker@^3.1.3: ember-cli-version-checker@^4.1.0: version "4.1.1" - resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-4.1.1.tgz" + resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-4.1.1.tgz#27b938228306cb0dbc4f74e95c536cdd6448e499" integrity sha512-bzEWsTMXUGEJfxcAGWPe6kI7oHEGD3jaxUWDYPTqzqGhNkgPwXTBgoWs9zG1RaSMaOPFnloWuxRcoHi4TrYS3Q== dependencies: resolve-package-path "^2.0.0" @@ -6735,7 +6931,7 @@ ember-cli-version-checker@^4.1.0: ember-cli-version-checker@^5.0.1, ember-cli-version-checker@^5.1.1, ember-cli-version-checker@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-5.1.2.tgz" + resolved "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-5.1.2.tgz#649c7b6404902e3b3d69c396e054cea964911ab0" integrity sha512-rk7GY+FmLn/2e22HsZs0Ycrz8HQ1W3Fv+2TFOuEFW9optnDXDgkntPBIl6gact/LHsfBM5RKbM3dHsIIeLgl0Q== dependencies: resolve-package-path "^3.1.0" @@ -6744,7 +6940,7 @@ ember-cli-version-checker@^5.0.1, ember-cli-version-checker@^5.1.1, ember-cli-ve ember-cli-yadda@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/ember-cli-yadda/-/ember-cli-yadda-0.7.0.tgz" + resolved "https://registry.npmjs.org/ember-cli-yadda/-/ember-cli-yadda-0.7.0.tgz#eff5583a886cd752343f74f485a4485ea6e37366" integrity sha512-NdolJAdNEOIHdTR8pbv8I6LUvP6QHAHvIdFSQP1kzqEqdFurFT7E7Vl5XqG45puNDty5FSTptdZkc+zrP9C8HQ== dependencies: broccoli-funnel "^3.0.8" @@ -6757,7 +6953,7 @@ ember-cli-yadda@^0.7.0: ember-cli@3.28.6: version "3.28.6" - resolved "https://registry.npmjs.org/ember-cli/-/ember-cli-3.28.6.tgz" + resolved "https://registry.npmjs.org/ember-cli/-/ember-cli-3.28.6.tgz#477a6a134501639d6cb03da6746158501c41efce" integrity sha512-aGHIDXM5KujhU+tHyfp1X5bUp3yj47sIWI0zgybyIw6vv6ErAu/eKWWMSib5PF8cQDdXG9vttBcXnvQ4QBNIPQ== dependencies: "@babel/core" "^7.13.8" @@ -6854,7 +7050,7 @@ ember-cli@3.28.6: ember-collection@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-collection/-/ember-collection-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-collection/-/ember-collection-1.0.0.tgz#2ec570a49b70098ab68fbaaca940f9302b39af98" integrity sha512-Yb7ZoPBc9rdDv1m72PDQeqbKzKVejAetkqRWUEXRa6tV75ud46ozGhX/1kyVJz2tNYL5XlgnqP8hg5UA9YNR0w== dependencies: ember-cli-babel "^7.7.3" @@ -6862,9 +7058,9 @@ ember-collection@^1.0.0: layout-bin-packer "^1.4.0" ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0, ember-compatibility-helpers@^1.2.1, ember-compatibility-helpers@^1.2.4, ember-compatibility-helpers@^1.2.5: - version "1.2.6" - resolved "https://registry.npmjs.org/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.6.tgz" - integrity sha512-2UBUa5SAuPg8/kRVaiOfTwlXdeVweal1zdNPibwItrhR0IvPrXpaqwJDlEZnWKEoB+h33V0JIfiWleSG6hGkkA== + version "1.2.7" + resolved "https://registry.npmjs.org/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.7.tgz#b4f138bba844f8f38f0b8f4d7e928841cd5e6591" + integrity sha512-BtkjulweiXo9c3yVWrtexw2dTmBrvavD/xixNC6TKOBdrixUwU+6nuOO9dufDWsMxoid7MvtmDpzc9+mE8PdaA== dependencies: babel-plugin-debug-macros "^0.2.0" ember-cli-version-checker "^5.1.1" @@ -6872,19 +7068,9 @@ ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0, ember-co fs-extra "^9.1.0" semver "^5.4.1" -ember-composable-helpers@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/ember-composable-helpers/-/ember-composable-helpers-4.5.0.tgz" - integrity sha512-XjpDLyVPsLCy6kd5dIxZonOECCO6AA5sY5Hr6tYUbJg3s5ghFAiFWaNcYraYC+fL2yPJQAswwpfwGlQORUJZkw== - dependencies: - "@babel/core" "^7.0.0" - broccoli-funnel "2.0.1" - ember-cli-babel "^7.26.3" - resolve "^1.10.0" - ember-composable-helpers@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/ember-composable-helpers/-/ember-composable-helpers-5.0.0.tgz" + resolved "https://registry.npmjs.org/ember-composable-helpers/-/ember-composable-helpers-5.0.0.tgz#055bab3a3e234ab2917499b1465e968c253ca885" integrity sha512-gyUrjiSju4QwNrsCLbBpP0FL6VDFZaELNW7Kbcp60xXhjvNjncYgzm4zzYXhT+i1lLA6WEgRZ3lOGgyBORYD0w== dependencies: "@babel/core" "^7.0.0" @@ -6894,7 +7080,7 @@ ember-composable-helpers@^5.0.0: ember-concurrency-decorators@^2.0.0: version "2.0.3" - resolved "https://registry.npmjs.org/ember-concurrency-decorators/-/ember-concurrency-decorators-2.0.3.tgz" + resolved "https://registry.npmjs.org/ember-concurrency-decorators/-/ember-concurrency-decorators-2.0.3.tgz#2816c9a0283b90ba5340fc5b4e0b92ea91f7d6e3" integrity sha512-r6O34YKI/slyYapVsuOPnmaKC4AsmBSwvgcadbdy+jHNj+mnryXPkm+3hhhRnFdlsKUKdEuXvl43lhjhYRLhhA== dependencies: "@ember-decorators/utils" "^6.1.0" @@ -6904,7 +7090,7 @@ ember-concurrency-decorators@^2.0.0: "ember-concurrency@>=1.0.0 <3": version "2.3.7" - resolved "https://registry.npmjs.org/ember-concurrency/-/ember-concurrency-2.3.7.tgz" + resolved "https://registry.npmjs.org/ember-concurrency/-/ember-concurrency-2.3.7.tgz#52d786e37704b9054da1952638797e23714ec0e1" integrity sha512-sz6sTIXN/CuLb5wdpauFa+rWXuvXXSnSHS4kuNzU5GSMDX1pLBWSuovoUk61FUe6CYRqBmT1/UushObwBGickQ== dependencies: "@babel/helper-plugin-utils" "^7.12.13" @@ -6918,14 +7104,14 @@ ember-concurrency-decorators@^2.0.0: ember-copy@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/ember-copy/-/ember-copy-2.0.1.tgz" + resolved "https://registry.npmjs.org/ember-copy/-/ember-copy-2.0.1.tgz#13192b12a250324bb4a8b4547a680b113f4e3041" integrity sha512-N/XFvZszrzyyX4IcNoeK4mJvIItNuONumhPLqi64T8NDjJkxBj4Pq61rvMkJx/9eZ8alzE4I8vYKOLxT0FvRuQ== dependencies: ember-cli-babel "^7.22.1" ember-data-model-fragments@5.0.0-beta.8: version "5.0.0-beta.8" - resolved "https://registry.npmjs.org/ember-data-model-fragments/-/ember-data-model-fragments-5.0.0-beta.8.tgz" + resolved "https://registry.npmjs.org/ember-data-model-fragments/-/ember-data-model-fragments-5.0.0-beta.8.tgz#d29e0f59a8ba0157fd9d616d50b3faec731bbeac" integrity sha512-vOt2UXyhsWoZXCB9XAUqAobdRLr3ydUG6L36Rd7Qsg/1kj0jApQIEJS4qfA+xlBgirKEJ322PZqlBOv8zQSS8w== dependencies: broccoli-file-creator "^2.1.1" @@ -6939,7 +7125,7 @@ ember-data-model-fragments@5.0.0-beta.8: ember-data@~3.28.6: version "3.28.13" - resolved "https://registry.npmjs.org/ember-data/-/ember-data-3.28.13.tgz" + resolved "https://registry.npmjs.org/ember-data/-/ember-data-3.28.13.tgz#68668d84924453c2baeeb0cf7d25f75b2c07e8b9" integrity sha512-j1YjPl2JNHxQwQW6Bgfis44XSr4WCtdwMXr/SPpLsF1oVeTWIn3kwefcDnbuCI8Spmt1B9ab3ZLKzf2KkGN/7g== dependencies: "@ember-data/adapter" "3.28.13" @@ -6959,7 +7145,7 @@ ember-data@~3.28.6: ember-decorators@^6.1.1: version "6.1.1" - resolved "https://registry.npmjs.org/ember-decorators/-/ember-decorators-6.1.1.tgz" + resolved "https://registry.npmjs.org/ember-decorators/-/ember-decorators-6.1.1.tgz#6d770f8999cf5a413a1ee459afd520838c0fc470" integrity sha512-63vZPntPn1aqMyeNRLoYjJD+8A8obd+c2iZkJflswpDRNVIsp2m7aQdSCtPt4G0U/TEq2251g+N10maHX3rnJQ== dependencies: "@ember-decorators/component" "^6.1.1" @@ -6968,7 +7154,7 @@ ember-decorators@^6.1.1: ember-destroyable-polyfill@^2.0.2, ember-destroyable-polyfill@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz" + resolved "https://registry.npmjs.org/ember-destroyable-polyfill/-/ember-destroyable-polyfill-2.0.3.tgz#1673ed66609a82268ef270a7d917ebd3647f11e1" integrity sha512-TovtNqCumzyAiW0/OisSkkVK93xnVF4NRU6+FN0ubpfwEOpRrmM2RqDwXI6YAChCgSHON1cz0DfQStpA1Gjuuw== dependencies: ember-cli-babel "^7.22.1" @@ -6977,7 +7163,7 @@ ember-destroyable-polyfill@^2.0.2, ember-destroyable-polyfill@^2.0.3: ember-element-helper@0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.6.1.tgz#a6fbc5be5f875b5c864ae61bf5c5f81d6de6d936" + resolved "https://registry.npmjs.org/ember-element-helper/-/ember-element-helper-0.6.1.tgz#a6fbc5be5f875b5c864ae61bf5c5f81d6de6d936" integrity sha512-YiOdAMlzYul4ulkIoNp8z7iHDfbT1fbut/9xGFRfxDwU/FmF8HtAUB2f1veu/w50HTeZNopa1OV2PCloZ76XlQ== dependencies: "@embroider/util" "^0.39.1 || ^0.40.0 || ^0.41.0 || ^1.0.0" @@ -6986,7 +7172,7 @@ ember-element-helper@0.6.1: ember-element-helper@^0.5.5: version "0.5.5" - resolved "https://registry.npmjs.org/ember-element-helper/-/ember-element-helper-0.5.5.tgz" + resolved "https://registry.npmjs.org/ember-element-helper/-/ember-element-helper-0.5.5.tgz#4a9ecb4dce57ee7f5ceb868a53c7b498c729f056" integrity sha512-Tu3hsI+/mjHBUvw62Qi+YDZtKkn59V66CjwbgfNTZZ7aHf4gFm1ow4zJ4WLnpnie8p9FvOmIUxwl5HvgPJIcFA== dependencies: "@embroider/util" "^0.39.1 || ^0.40.0 || ^0.41.0" @@ -6994,16 +7180,16 @@ ember-element-helper@^0.5.5: ember-cli-htmlbars "^5.1.0" ember-element-helper@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.8.5.tgz#5a53d4e3aa8379694c2002a3097269aeb7c2621b" - integrity sha512-yZYzuasn6ZC8Nwv0MpaLYGtm68ZxIBSNSe/CYxNWkDdgcuAb2lAG1gx37XkwBIiwPQET0W2agwq7++/HwdMF8g== + version "0.8.6" + resolved "https://registry.npmjs.org/ember-element-helper/-/ember-element-helper-0.8.6.tgz#564d63dbbb6130e4c69ff06b3bd8fbfb9cb4787a" + integrity sha512-WcbkJKgBZypRGwujeiPrQfZRhETVFLR0wvH2UxDaNBhLWncapt6KK+M/2i/eODoAQwgGxziejhXC6Cbqa9zA8g== dependencies: - "@embroider/addon-shim" "1.8.3" + "@embroider/addon-shim" "^1.8.3" "@embroider/util" "^1.0.0" ember-exam@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/ember-exam/-/ember-exam-6.1.0.tgz" + resolved "https://registry.npmjs.org/ember-exam/-/ember-exam-6.1.0.tgz#1ea2c0ece27ac8ad6a80d959b1c207611b7dfdd7" integrity sha512-H9tg7eUgqkjAsr1/15UzxGyZobGLgsyTi56Ng0ySnkYGCRfvVpwtVc3xgcNOFnUaa9RExUFpxC0adjW3K87Uxw== dependencies: "@embroider/macros" "^0.36.0" @@ -7023,19 +7209,19 @@ ember-exam@^6.1.0: ember-export-application-global@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/ember-export-application-global/-/ember-export-application-global-2.0.1.tgz" + resolved "https://registry.npmjs.org/ember-export-application-global/-/ember-export-application-global-2.0.1.tgz#b120a70e322ab208defc9e2daebe8d0dfc2dcd46" integrity sha512-B7wiurPgsxsSGzJuPFkpBWnaeuCu2PGpG2BjyrfA1VcL7//o+5RSnZqiCEY326y7qmxb2GoCgo0ft03KBU0rRw== ember-factory-for-polyfill@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/ember-factory-for-polyfill/-/ember-factory-for-polyfill-1.3.1.tgz" + resolved "https://registry.npmjs.org/ember-factory-for-polyfill/-/ember-factory-for-polyfill-1.3.1.tgz#b446ed64916d293c847a4955240eb2c993b86eae" integrity sha512-y3iG2iCzH96lZMTWQw6LWNLAfOmDC4pXKbZP6FxG8lt7GGaNFkZjwsf+Z5GAe7kxfD7UG4lVkF7x37K82rySGA== dependencies: ember-cli-version-checker "^2.1.0" -ember-focus-trap@^1.0.2: +ember-focus-trap@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/ember-focus-trap/-/ember-focus-trap-1.1.0.tgz" + resolved "https://registry.npmjs.org/ember-focus-trap/-/ember-focus-trap-1.1.0.tgz#e3c47c6e916e838af3884b43e2794e87088d2bac" integrity sha512-KxbCKpAJaBVZm+bW4tHPoBJAZThmxa6pI+WQusL+bj0RtAnGUNkWsVy6UBMZ5QqTQzf4EvGHkCVACVp5lbAWMQ== dependencies: "@embroider/addon-shim" "^1.0.0" @@ -7043,7 +7229,7 @@ ember-focus-trap@^1.0.2: ember-get-config@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/ember-get-config/-/ember-get-config-0.3.0.tgz" + resolved "https://registry.npmjs.org/ember-get-config/-/ember-get-config-0.3.0.tgz#a73a1a87b48d9dde4c66a0e52ed5260b8a48cfbd" integrity sha512-0e2pKzwW5lBZ4oJnvu9qHOht4sP1MWz/m3hyz8kpSoMdrlZVf62LDKZ6qfKgy8drcv5YhCMYE6QV7MhnqlrzEQ== dependencies: broccoli-file-creator "^1.1.1" @@ -7051,7 +7237,7 @@ ember-get-config@^0.3.0: ember-get-config@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/ember-get-config/-/ember-get-config-2.1.1.tgz" + resolved "https://registry.npmjs.org/ember-get-config/-/ember-get-config-2.1.1.tgz#bede76c25d95dbefab8d30064abf7aa00bc19235" integrity sha512-uNmv1cPG/4qsac8oIf5txJ2FZ8p88LEpG4P3dNcjsJS98Y8hd0GPMFwVqpnzI78Lz7VYRGQWY4jnE4qm5R3j4g== dependencies: "@embroider/macros" "^0.50.0 || ^1.0.0" @@ -7059,7 +7245,7 @@ ember-get-config@^2.1.1: ember-getowner-polyfill@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz" + resolved "https://registry.npmjs.org/ember-getowner-polyfill/-/ember-getowner-polyfill-2.2.0.tgz#38e7dccbcac69d5ec694000329ec0b2be651d2b2" integrity sha512-rwGMJgbGzxIAiWYjdpAh04Abvt0s3HuS/VjHzUFhVyVg2pzAuz45B9AzOxYXzkp88vFC7FPaiA4kE8NxNk4A4Q== dependencies: ember-cli-version-checker "^2.1.0" @@ -7067,7 +7253,7 @@ ember-getowner-polyfill@^2.0.0: ember-in-element-polyfill@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz" + resolved "https://registry.npmjs.org/ember-in-element-polyfill/-/ember-in-element-polyfill-1.0.1.tgz#143504445bb4301656a2eaad42644d684f5164dd" integrity sha512-eHs+7D7PuQr8a1DPqsJTsEyo3FZ1XuH6WEZaEBPDa9s0xLlwByCNKl8hi1EbXOgvgEZNHHi9Rh0vjxyfakrlgg== dependencies: debug "^4.3.1" @@ -7077,14 +7263,14 @@ ember-in-element-polyfill@^1.0.0: ember-inflector@^4.0.1, ember-inflector@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/ember-inflector/-/ember-inflector-4.0.2.tgz" + resolved "https://registry.npmjs.org/ember-inflector/-/ember-inflector-4.0.2.tgz#4494f1a5f61c1aca7702d59d54024cc92211d8ec" integrity sha512-+oRstEa52mm0jAFzhr51/xtEWpCEykB3SEBr7vUg8YnXUZJ5hKNBppP938q8Zzr9XfJEbzrtDSGjhKwJCJv6FQ== dependencies: ember-cli-babel "^7.26.5" ember-intl@^5.7.0: version "5.7.2" - resolved "https://registry.npmjs.org/ember-intl/-/ember-intl-5.7.2.tgz" + resolved "https://registry.npmjs.org/ember-intl/-/ember-intl-5.7.2.tgz#76d933f974f041448b01247888bc3bcc9261e812" integrity sha512-gs17uY1ywzMaUpx1gxfBkFQYRTWTSa/zbkL13MVtffG9aBLP+998MibytZOUxIipMtLCm4sr/g6/1aaKRr9/+g== dependencies: broccoli-caching-writer "^3.0.3" @@ -7112,9 +7298,9 @@ ember-intl@^5.7.0: mkdirp "^1.0.4" silent-error "^1.1.1" -ember-keyboard@^8.2.0: +ember-keyboard@^8.2.1: version "8.2.1" - resolved "https://registry.npmjs.org/ember-keyboard/-/ember-keyboard-8.2.1.tgz" + resolved "https://registry.npmjs.org/ember-keyboard/-/ember-keyboard-8.2.1.tgz#945a8a71068d81c06ad26851008ef81061db2a59" integrity sha512-wT9xpt3GKsiodGZoifKU4OyeRjXWlmKV9ZHHsp6wJBwMFpl4wWPjTNdINxivk2qg/WFNIh8nUiwuG4+soWXPdw== dependencies: "@embroider/addon-shim" "^1.8.4" @@ -7124,7 +7310,7 @@ ember-keyboard@^8.2.0: ember-load-initializers@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/ember-load-initializers/-/ember-load-initializers-2.1.2.tgz" + resolved "https://registry.npmjs.org/ember-load-initializers/-/ember-load-initializers-2.1.2.tgz#8a47a656c1f64f9b10cecdb4e22a9d52ad9c7efa" integrity sha512-CYR+U/wRxLbrfYN3dh+0Tb6mFaxJKfdyz+wNql6cqTrA0BBi9k6J3AaKXj273TqvEpyyXegQFFkZEiuZdYtgJw== dependencies: ember-cli-babel "^7.13.0" @@ -7132,7 +7318,7 @@ ember-load-initializers@^2.1.2: ember-math-helpers@^2.4.0: version "2.18.2" - resolved "https://registry.npmjs.org/ember-math-helpers/-/ember-math-helpers-2.18.2.tgz" + resolved "https://registry.npmjs.org/ember-math-helpers/-/ember-math-helpers-2.18.2.tgz#5778f0aae08f3502be8defbacd383794f42b177e" integrity sha512-ikAXlIiT0wk8X8uuMtHkrRYt8HnDt9Wk+iNoY9IoBmt6IRZjCD5BmuxrIPj5Eop2/afMfKmNKnc4L1StkXM3wg== dependencies: broccoli-funnel "^3.0.8" @@ -7141,7 +7327,7 @@ ember-math-helpers@^2.4.0: ember-maybe-import-regenerator@^0.1.6: version "0.1.6" - resolved "https://registry.npmjs.org/ember-maybe-import-regenerator/-/ember-maybe-import-regenerator-0.1.6.tgz" + resolved "https://registry.npmjs.org/ember-maybe-import-regenerator/-/ember-maybe-import-regenerator-0.1.6.tgz#35d41828afa6d6a59bc0da3ce47f34c573d776ca" integrity sha512-aX9UINiUXIjzsCNNna1ioASB/2lbnFgSHI63bBcd4MOVE9AqoLdOL7h+ocyylYXyYoBj2JDRwCzjWNf2Xbp5wg== dependencies: broccoli-funnel "^1.0.1" @@ -7151,7 +7337,7 @@ ember-maybe-import-regenerator@^0.1.6: ember-maybe-in-element@^2.0.3: version "2.1.0" - resolved "https://registry.npmjs.org/ember-maybe-in-element/-/ember-maybe-in-element-2.1.0.tgz" + resolved "https://registry.npmjs.org/ember-maybe-in-element/-/ember-maybe-in-element-2.1.0.tgz#f7bd8e41ca90a4f8038d919a9c135cbe7a7f271b" integrity sha512-6WAzPbf4BNQIQzkur2+zRJJJ/PKQoujIYgFjrpj3fOPy8iRlxVUm0/B41qbFyg1LE6bVbg0cWbuESWEvJ9Rswg== dependencies: ember-cli-babel "^7.26.11" @@ -7160,7 +7346,7 @@ ember-maybe-in-element@^2.0.3: ember-modifier-manager-polyfill@^1.1.0, ember-modifier-manager-polyfill@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz" + resolved "https://registry.npmjs.org/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz#cf4444e11a42ac84f5c8badd85e635df57565dda" integrity sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA== dependencies: ember-cli-babel "^7.10.0" @@ -7169,7 +7355,7 @@ ember-modifier-manager-polyfill@^1.1.0, ember-modifier-manager-polyfill@^1.2.0: ember-modifier@^2.1.0: version "2.1.2" - resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-2.1.2.tgz" + resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-2.1.2.tgz#62d18faedf972dcd9d34f90d5321fbc943d139b1" integrity sha512-3Lsu1fV1sIGa66HOW07RZc6EHISwKt5VA5AUnFss2HX6OTfpxTJ2qvPctt2Yt0XPQXJ4G6BQasr/F35CX7UGJA== dependencies: ember-cli-babel "^7.22.1" @@ -7181,17 +7367,18 @@ ember-modifier@^2.1.0: ember-modifier-manager-polyfill "^1.2.0" "ember-modifier@^2.1.2 || ^3.1.0 || ^4.0.0", "ember-modifier@^3.2.7 || ^4.0.0", ember-modifier@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-4.1.0.tgz" - integrity sha512-YFCNpEYj6jdyy3EjslRb2ehNiDvaOrXTilR9+ngq+iUqSHYto2zKV0rleiA1XJQ27ELM1q8RihT29U6Lq5EyqQ== + version "4.2.0" + resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-4.2.0.tgz#f99cb817b9b85c5188c63f853cd06aa62e8dde57" + integrity sha512-BJ48eTEGxD8J7+lofwVmee7xDgNDgpr5dd6+MSu4gk+I6xb35099RMNorXY5hjjwMJEyi/IRR6Yn3M7iJMz8Zw== dependencies: - "@embroider/addon-shim" "^1.8.4" + "@embroider/addon-shim" "^1.8.7" + decorator-transforms "^2.0.0" ember-cli-normalize-entity-name "^1.0.0" ember-cli-string-utils "^1.1.0" ember-modifier@^3.2.7: version "3.2.7" - resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-3.2.7.tgz" + resolved "https://registry.npmjs.org/ember-modifier/-/ember-modifier-3.2.7.tgz#f2d35b7c867cbfc549e1acd8d8903c5ecd02ea4b" integrity sha512-ezcPQhH8jUfcJQbbHji4/ZG/h0yyj1jRDknfYue/ypQS8fM8LrGcCMo0rjDZLzL1Vd11InjNs3BD7BdxFlzGoA== dependencies: ember-cli-babel "^7.26.6" @@ -7202,7 +7389,7 @@ ember-modifier@^3.2.7: ember-named-blocks-polyfill@^0.2.5: version "0.2.5" - resolved "https://registry.npmjs.org/ember-named-blocks-polyfill/-/ember-named-blocks-polyfill-0.2.5.tgz" + resolved "https://registry.npmjs.org/ember-named-blocks-polyfill/-/ember-named-blocks-polyfill-0.2.5.tgz#d5841406277026a221f479c815cfbac6cdcaeecb" integrity sha512-OVMxzkfqJrEvmiky7gFzmuTaImCGm7DOudHWTdMBPO7E+dQSunrcRsJMgO9ZZ56suqBIz/yXbEURrmGS+avHxA== dependencies: ember-cli-babel "^7.19.0" @@ -7210,7 +7397,7 @@ ember-named-blocks-polyfill@^0.2.5: ember-native-dom-helpers@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/ember-native-dom-helpers/-/ember-native-dom-helpers-0.7.0.tgz" + resolved "https://registry.npmjs.org/ember-native-dom-helpers/-/ember-native-dom-helpers-0.7.0.tgz#98a87c11a391cec5c12382a4857e59ea2fb4b00a" integrity sha512-ySJRGRhwYIWUAZKilB8xEcIatP9wKfEBX6JFG8bG4Ck7GvA0eau265hTGZz/+ntZuwcY4HrzSNkwimlHx4cM/A== dependencies: broccoli-funnel "^1.1.0" @@ -7218,14 +7405,14 @@ ember-native-dom-helpers@^0.7.0: ember-on-helper@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/ember-on-helper/-/ember-on-helper-0.1.0.tgz" + resolved "https://registry.npmjs.org/ember-on-helper/-/ember-on-helper-0.1.0.tgz#c8b1fef9173fc8546c4933b57ecd7ffbcebad99e" integrity sha512-jjafBnWfoA4VSSje476ft5G+urlvvuSDddwAJjKDCjKY9mbe3hAEsJiMBAaPObJRMm1FOglCuKjQZfwDDls6MQ== dependencies: ember-cli-babel "^7.7.3" ember-on-resize-modifier@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/ember-on-resize-modifier/-/ember-on-resize-modifier-2.0.2.tgz" + resolved "https://registry.npmjs.org/ember-on-resize-modifier/-/ember-on-resize-modifier-2.0.2.tgz#a1e2ab86e69c825a6851e63261263b1610ef9e15" integrity sha512-7mcD7CNbiCaZEIASWlRz/Wmn47afCMSFTdQJSSUe0WCgnXxn9DVoqZ39B7ZuddTHa0V6otTFrV/lIRYpggQ+eg== dependencies: ember-auto-import "^2.5.0" @@ -7236,14 +7423,14 @@ ember-on-resize-modifier@^2.0.2: ember-page-title@^6.2.2: version "6.2.2" - resolved "https://registry.npmjs.org/ember-page-title/-/ember-page-title-6.2.2.tgz" + resolved "https://registry.npmjs.org/ember-page-title/-/ember-page-title-6.2.2.tgz#980838c44e96cba1d00f42435d707936af627324" integrity sha512-YTXA+cylZrh9zO0zwjlaAGReT2MVOxAMnVO1OOygFrs1JBs4D6CKV3tImoilg3AvIXFBeJfFNNUbJOdRd9IGGg== dependencies: ember-cli-babel "^7.23.1" ember-power-select-with-create@^0.8.0: version "0.8.0" - resolved "https://registry.npmjs.org/ember-power-select-with-create/-/ember-power-select-with-create-0.8.0.tgz" + resolved "https://registry.npmjs.org/ember-power-select-with-create/-/ember-power-select-with-create-0.8.0.tgz#973e26db8f76c650a6d166ea1c03ec00453150be" integrity sha512-9xJTgaju4NyADJb6RjkUpIhLFx/5ORmAK3R/zuTyc2ILyOY7+SvDw8LuFNTnOVAFOcT3g+TJKEL8nzBuwnEi7g== dependencies: ember-cli-babel "^7.20.0" @@ -7252,7 +7439,7 @@ ember-power-select-with-create@^0.8.0: ember-power-select@^4.0.0, ember-power-select@^4.0.5: version "4.1.7" - resolved "https://registry.npmjs.org/ember-power-select/-/ember-power-select-4.1.7.tgz" + resolved "https://registry.npmjs.org/ember-power-select/-/ember-power-select-4.1.7.tgz#eb547dd37448357d8f3fa789db18ddbba43fb8ca" integrity sha512-Q4cjUudWb7JA6q7qe0jhcpLsipuFUHMwkYC05HxST5qm3MRMEzs6KfZ3Xd/TcrjBLSoWniw3Q61Quwcb41w5Jw== dependencies: "@glimmer/component" "^1.0.4" @@ -7269,7 +7456,7 @@ ember-power-select@^4.0.0, ember-power-select@^4.0.5: ember-qunit@^5.1.5: version "5.1.5" - resolved "https://registry.npmjs.org/ember-qunit/-/ember-qunit-5.1.5.tgz" + resolved "https://registry.npmjs.org/ember-qunit/-/ember-qunit-5.1.5.tgz#24a7850f052be24189ff597dfc31b923e684c444" integrity sha512-2cFA4oMygh43RtVcMaBrr086Tpdhgbn3fVZ2awLkzF/rnSN0D0PSRpd7hAD7OdBPerC/ZYRwzVyGXLoW/Zes4A== dependencies: broccoli-funnel "^3.0.8" @@ -7284,14 +7471,14 @@ ember-qunit@^5.1.5: ember-raf-scheduler@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/ember-raf-scheduler/-/ember-raf-scheduler-0.3.0.tgz" + resolved "https://registry.npmjs.org/ember-raf-scheduler/-/ember-raf-scheduler-0.3.0.tgz#7657ee5c1d54f852731e61e9d0e0750a9a22f5f4" integrity sha512-i8JWQidNCX7n5TOTIKRDR0bnsQN9aJh/GtOJKINz2Wr+I7L7sYVhli6MFqMYNGKC9j9e6iWsznfAIxddheyEow== dependencies: ember-cli-babel "^7.26.6" ember-ref-bucket@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/ember-ref-bucket/-/ember-ref-bucket-4.1.0.tgz" + resolved "https://registry.npmjs.org/ember-ref-bucket/-/ember-ref-bucket-4.1.0.tgz#2a52e72a395a14033d034c834fab648f26d74baa" integrity sha512-oEUU2mDtuYuMM039U9YEqrrOCVHH6rQfvbFOmh3WxOVEgubmLVyKEpGgU4P/6j0B/JxTqqTwM3ULTQyDto8dKg== dependencies: ember-cli-babel "^7.26.11" @@ -7300,7 +7487,7 @@ ember-ref-bucket@^4.1.0: ember-render-helpers@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/ember-render-helpers/-/ember-render-helpers-0.2.0.tgz" + resolved "https://registry.npmjs.org/ember-render-helpers/-/ember-render-helpers-0.2.0.tgz#5f7af8ee74ae29f85e0d156b2775edff23f6de21" integrity sha512-MnqGS8BnY3GJ+n5RZVVRqCwKjfXXMr5quKyqNu1vxft8oslOJuZ1f1dOesQouD+6LwD4Y9tWRVKNw+LOqM9ocw== dependencies: ember-cli-babel "^7.23.0" @@ -7308,7 +7495,7 @@ ember-render-helpers@^0.2.0: ember-resize-observer-service@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/ember-resize-observer-service/-/ember-resize-observer-service-1.1.0.tgz" + resolved "https://registry.npmjs.org/ember-resize-observer-service/-/ember-resize-observer-service-1.1.0.tgz#62729a9de656e8eade4b3e65bd9999840dc44f65" integrity sha512-/vbfxtHSyOGSNdjPKL8X3SyvUnYo3z88sJtD/bLJ0ZGhqVPaXCmtSkLyr/Fh75ckJDixRFxK4i4zEUSlrbk0PA== dependencies: ember-cli-babel "^7.26.6" @@ -7316,7 +7503,7 @@ ember-resize-observer-service@^1.1.0: ember-resolver@^8.0.3: version "8.1.0" - resolved "https://registry.npmjs.org/ember-resolver/-/ember-resolver-8.1.0.tgz" + resolved "https://registry.npmjs.org/ember-resolver/-/ember-resolver-8.1.0.tgz#8ada162746fde3e6ea6a703bbb9910fbe62ab1e5" integrity sha512-MGD7X2ztZVswGqs1mLgzhZJRhG7XiF6Mg4DgC7xJFWRYQQUHyGJpGdNWY9nXyrYnRIsCrQoL1do41zpxbrB/cg== dependencies: babel-plugin-debug-macros "^0.3.4" @@ -7328,7 +7515,7 @@ ember-resolver@^8.0.3: ember-resources@^5.0.1: version "5.6.4" - resolved "https://registry.npmjs.org/ember-resources/-/ember-resources-5.6.4.tgz" + resolved "https://registry.npmjs.org/ember-resources/-/ember-resources-5.6.4.tgz#1ae05bb5398ab0d8fab8c0925c5bf679ee86e327" integrity sha512-ShdosnruPm37jPpzPOgPVelymEDJT/27Jz/j5AGPVAfCaUhRIocTxNMtPx13ox890A2babuPF5M3Ur8UFidqtw== dependencies: "@babel/runtime" "^7.17.8" @@ -7337,12 +7524,12 @@ ember-resources@^5.0.1: ember-rfc176-data@^0.3.13, ember-rfc176-data@^0.3.15, ember-rfc176-data@^0.3.17: version "0.3.18" - resolved "https://registry.npmjs.org/ember-rfc176-data/-/ember-rfc176-data-0.3.18.tgz" + resolved "https://registry.npmjs.org/ember-rfc176-data/-/ember-rfc176-data-0.3.18.tgz#bb6fdcef49999981317ea81b6cc9210fb4108d65" integrity sha512-JtuLoYGSjay1W3MQAxt3eINWXNYYQliK90tLwtb8aeCuQK8zKGCRbBodVIrkcTqshULMnRuTOS6t1P7oQk3g6Q== ember-route-action-helper@^2.0.8: version "2.0.8" - resolved "https://registry.npmjs.org/ember-route-action-helper/-/ember-route-action-helper-2.0.8.tgz" + resolved "https://registry.npmjs.org/ember-route-action-helper/-/ember-route-action-helper-2.0.8.tgz#f227fcccb73e839b65e9b814e241b322fe8c02fc" integrity sha512-V+4uKwqaYveriVt2rl4e+9mzHJiQOr1B8dCPQQ2TS3iAcmi5RD2giRDFGtCK9d2XY9Arb/f9hJh0obP20iyt3A== dependencies: ember-cli-babel "^6.8.1" @@ -7350,7 +7537,7 @@ ember-route-action-helper@^2.0.8: ember-router-generator@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ember-router-generator/-/ember-router-generator-2.0.0.tgz" + resolved "https://registry.npmjs.org/ember-router-generator/-/ember-router-generator-2.0.0.tgz#d04abfed4ba8b42d166477bbce47fccc672dbde0" integrity sha512-89oVHVJwmLDvGvAUWgS87KpBoRhy3aZ6U0Ql6HOmU4TrPkyaa8pM0W81wj9cIwjYprcQtN9EwzZMHnq46+oUyw== dependencies: "@babel/parser" "^7.4.5" @@ -7359,21 +7546,21 @@ ember-router-generator@^2.0.0: ember-router-helpers@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/ember-router-helpers/-/ember-router-helpers-0.4.0.tgz" + resolved "https://registry.npmjs.org/ember-router-helpers/-/ember-router-helpers-0.4.0.tgz#6ef86cc75e38c3455ab916c78d5a38293e94c12f" integrity sha512-DiPyncEAACKV/XcmYqUwh0iHBPvGW75Fw1uerDudblofXTtAH/+QzeE/0wK2G6MUBWKyn0HyIuLXE3pJm0zKFg== dependencies: ember-cli-babel "^7.20.0" ember-set-helper@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/ember-set-helper/-/ember-set-helper-2.0.1.tgz" + resolved "https://registry.npmjs.org/ember-set-helper/-/ember-set-helper-2.0.1.tgz#e39417531e25089b45ccb905b8c00eda7b3fbbde" integrity sha512-6IIimVGOdehZcncH1ilCY4p7hWBtZqWYMc1Xodr1ATOCuIk6ZO1yztKcUQhlmwl7fE82gL4wHD01T6XP5W59Ng== dependencies: ember-cli-babel "^7.18.0" ember-sinon-qunit@5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/ember-sinon-qunit/-/ember-sinon-qunit-5.0.0.tgz" + resolved "https://registry.npmjs.org/ember-sinon-qunit/-/ember-sinon-qunit-5.0.0.tgz#d6585ee691f73c5733783a0583f87840d1323cb1" integrity sha512-7Q938adhhHcUHFg41fwj6g5Q6Iyt8eyo7c0D1r7uOeKSFlobcm1FiD/dCmjNZx224KiI6KYh/0EwqoaIyWAawA== dependencies: broccoli-funnel "^3.0.2" @@ -7382,7 +7569,7 @@ ember-sinon-qunit@5.0.0: ember-sinon@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/ember-sinon/-/ember-sinon-5.0.0.tgz" + resolved "https://registry.npmjs.org/ember-sinon/-/ember-sinon-5.0.0.tgz#990bcafa65403d2b2e3e7f14bb547862197e97d5" integrity sha512-dTP2vhao1xWm3OlfpOALooso/OLM71SFg7PIBmZ6JdwKCC+CzcPb4BYRAXuoAFYzmhH8z28p8HdemjZBb0B3Bw== dependencies: broccoli-funnel "^2.0.0" @@ -7392,14 +7579,14 @@ ember-sinon@^5.0.0: ember-source-channel-url@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/ember-source-channel-url/-/ember-source-channel-url-3.0.0.tgz" + resolved "https://registry.npmjs.org/ember-source-channel-url/-/ember-source-channel-url-3.0.0.tgz#bcd5be72c63fa0b8c390b3121783b462063e2a1b" integrity sha512-vF/8BraOc66ZxIDo3VuNP7iiDrnXEINclJgSJmqwAAEpg84Zb1DHPI22XTXSDA+E8fW5btPUxu65c3ZXi8AQFA== dependencies: node-fetch "^2.6.0" ember-source@3.28.8: version "3.28.8" - resolved "https://registry.npmjs.org/ember-source/-/ember-source-3.28.8.tgz" + resolved "https://registry.npmjs.org/ember-source/-/ember-source-3.28.8.tgz#c58fd4a1538d6c4b9aebe76c764cabf5396c64d9" integrity sha512-hA15oYzbRdi9983HIemeVzzX2iLcMmSPp6akUiMQhFZYWPrKksbPyLrO6YpZ4hNM8yBjQSDXEkZ1V3yxBRKjUA== dependencies: "@babel/helper-module-imports" "^7.8.3" @@ -7431,7 +7618,7 @@ ember-source@3.28.8: ember-stargate@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/ember-stargate/-/ember-stargate-0.2.0.tgz" + resolved "https://registry.npmjs.org/ember-stargate/-/ember-stargate-0.2.0.tgz#3b4594e1745dcd49372e3a8d6d06dada1dc6bf9a" integrity sha512-AJxj4GVfW1pADk2Re6eKq5qhsWNEPWOy9jj0as3wnJFjUe0OeMvnOIqmyhwT2zpX6eLL+hIJ9cazP+j9/DvMQg== dependencies: "@ember/render-modifiers" "^1.0.2" @@ -7443,7 +7630,7 @@ ember-stargate@^0.2.0: ember-stargate@^0.4.3: version "0.4.3" - resolved "https://registry.npmjs.org/ember-stargate/-/ember-stargate-0.4.3.tgz" + resolved "https://registry.npmjs.org/ember-stargate/-/ember-stargate-0.4.3.tgz#93e92e4928d489557401d70e52b242b38f36f9ab" integrity sha512-GeT5n+TT3Lfl335f16fx9ms0Jap+v5LTs8otIaQEGtFbSP5Jj/hlT3JPB9Uo8IDLXdjejxJsKRpCEzRD43g5dg== dependencies: "@ember/render-modifiers" "^2.0.0" @@ -7454,23 +7641,23 @@ ember-stargate@^0.4.3: ember-string-fns@^1.4.0: version "1.4.1" - resolved "https://registry.npmjs.org/ember-string-fns/-/ember-string-fns-1.4.1.tgz" + resolved "https://registry.npmjs.org/ember-string-fns/-/ember-string-fns-1.4.1.tgz#3890c80e4d73db78a5d3027c0ec9a3e677b3813a" integrity sha512-PtMjvFq34+ygsIaug0QYW+0e/CsHHRfffFEMIR+R2MIgNYLz/FED4gRMwtPZsUXsrYVr0JMvvbwwAeFxpyxFFw== dependencies: ember-cli-babel "^7.7.3" ember-style-modifier@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/ember-style-modifier/-/ember-style-modifier-0.6.0.tgz" + resolved "https://registry.npmjs.org/ember-style-modifier/-/ember-style-modifier-0.6.0.tgz#cc5e58db7f6d6662028a7b4e3cf63cf25ba59a8f" integrity sha512-KqW4vyR80l/GMJsuFV+WLqTmGjXKLpoQ/HAmno+oMDrMt13p/5ImrvarQ6lFgXttFnLCxl6YpMY4YX27p1G54g== dependencies: ember-cli-babel "^7.21.0" ember-modifier "^2.1.0" ember-style-modifier@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/ember-style-modifier/-/ember-style-modifier-3.0.1.tgz" - integrity sha512-WHRVIiqY/dpwDtVWlnHW0P4Z+Jha8QEwfaQdIF2ckJL77ZKdjbV2j1XZymS0Nzj61EGx5BM+YEsGL16r3hLv2A== + version "3.1.1" + resolved "https://registry.npmjs.org/ember-style-modifier/-/ember-style-modifier-3.1.1.tgz#313269708552c42255806586160411840adc98c5" + integrity sha512-J91YLKVp3/m7LrcLEWNSG2sJlSFhE5Ny75empU048qYJtdJMe788Ks/EpKEi953o1mJujVRg792YGrwbrpTzNA== dependencies: ember-auto-import "^2.5.0" ember-cli-babel "^7.26.11" @@ -7478,7 +7665,7 @@ ember-style-modifier@^3.0.1: ember-template-lint@^2.0.1: version "2.21.0" - resolved "https://registry.npmjs.org/ember-template-lint/-/ember-template-lint-2.21.0.tgz" + resolved "https://registry.npmjs.org/ember-template-lint/-/ember-template-lint-2.21.0.tgz#7e120abf309a8810eeed26c52377943faf15a95b" integrity sha512-19QbEqJQdMfcRS7PsQsubflRowEtnkbD0tpYR4q/xq4lodmhU7hhOFvlTQgbxD/jwW5Ur+tkOwH4KFy9JwOyXA== dependencies: chalk "^4.0.0" @@ -7495,7 +7682,7 @@ ember-template-lint@^2.0.1: ember-template-recast@^5.0.1: version "5.0.3" - resolved "https://registry.npmjs.org/ember-template-recast/-/ember-template-recast-5.0.3.tgz" + resolved "https://registry.npmjs.org/ember-template-recast/-/ember-template-recast-5.0.3.tgz#79df27a70bdce7be17f14db13886afde1e9d02d6" integrity sha512-qsJYQhf29Dk6QMfviXhUPE+byMOs6iRQxUDHgkj8yqjeppvjHaFG96hZi/NAXJTm/M7o3PpfF5YlmeaKtI9UeQ== dependencies: "@glimmer/reference" "^0.65.0" @@ -7512,7 +7699,7 @@ ember-template-recast@^5.0.1: ember-test-selectors@^5.0.0: version "5.5.0" - resolved "https://registry.npmjs.org/ember-test-selectors/-/ember-test-selectors-5.5.0.tgz" + resolved "https://registry.npmjs.org/ember-test-selectors/-/ember-test-selectors-5.5.0.tgz#114bd29c4a33eee3a328c9ce32a57a018c27f5f6" integrity sha512-PiKhbPnidRYQ5ed/CTU3teJV3XmzkjYjsCGx1UTy7qEY/1dEqxezlZu1DtisoLJ9Y+BcjTVlE+596lo9cOXd3w== dependencies: calculate-cache-key-for-tree "^2.0.0" @@ -7521,7 +7708,7 @@ ember-test-selectors@^5.0.0: ember-text-measurer@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/ember-text-measurer/-/ember-text-measurer-0.6.0.tgz" + resolved "https://registry.npmjs.org/ember-text-measurer/-/ember-text-measurer-0.6.0.tgz#140eda044fd7d4d7f60f654dd30da79c06922b2e" integrity sha512-/aZs2x2i6kT4a5tAW+zenH2wg8AbRK9jKxLkbVsKl/1ublNl27idVRdov1gJ+zgWu3DNK7whcfVycXtlaybYQw== dependencies: ember-cli-babel "^7.19.0" @@ -7529,7 +7716,7 @@ ember-text-measurer@^0.6.0: ember-tracked-storage-polyfill@1.0.0, ember-tracked-storage-polyfill@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/ember-tracked-storage-polyfill/-/ember-tracked-storage-polyfill-1.0.0.tgz" + resolved "https://registry.npmjs.org/ember-tracked-storage-polyfill/-/ember-tracked-storage-polyfill-1.0.0.tgz#84d307a1e4badc5f84dca681db2cfea9bdee8a77" integrity sha512-eL7lZat68E6P/D7b9UoTB5bB5Oh/0aju0Z7PCMi3aTwhaydRaxloE7TGrTRYU+NdJuyNVZXeGyxFxn2frvd3TA== dependencies: ember-cli-babel "^7.26.3" @@ -7537,14 +7724,14 @@ ember-tracked-storage-polyfill@1.0.0, ember-tracked-storage-polyfill@^1.0.0: "ember-truth-helpers@^2.1.0 || ^3.0.0", ember-truth-helpers@^3.0.0, ember-truth-helpers@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/ember-truth-helpers/-/ember-truth-helpers-3.1.1.tgz" + resolved "https://registry.npmjs.org/ember-truth-helpers/-/ember-truth-helpers-3.1.1.tgz#434715926d72bcc63b8a115dec09745fda4474dc" integrity sha512-FHwJAx77aA5q27EhdaaiBFuy9No+8yaWNT5A7zs0sIFCmf14GbcLn69vJEp6mW7vkITezizGAWhw7gL0Wbk7DA== dependencies: ember-cli-babel "^7.22.1" ember-validators@~4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/ember-validators/-/ember-validators-4.0.1.tgz" + resolved "https://registry.npmjs.org/ember-validators/-/ember-validators-4.0.1.tgz#13beefdf185b00efd1b60e51b21380686d8994ba" integrity sha512-QVHzzYQn17Ikz8EZVxEtjKRyr6fmwSUbjYpxjcuoZKN5Ub1jjU2LzPOXT6FJQet691UlBs35e6EjPkBOb+xOuA== dependencies: "@embroider/macros" "^0.41.0" @@ -7553,40 +7740,40 @@ ember-validators@~4.0.0: emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== emoji-regex@~10.1.0: version "10.1.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.1.0.tgz#d50e383743c0f7a5945c47087295afc112e3cf66" integrity sha512-xAEnNCT3w2Tg6MA7ly6QqYJvEoY1tm9iIjJ3yMKK9JPlWuRHAMoe5iETwQnx3M9TVbFMfsrBgWKR+IsmswwNjg== emojis-list@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== encodeurl@~1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -engine.io-parser@~5.0.3: - version "5.0.6" - resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz" - integrity sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw== +engine.io-parser@~5.2.1: + version "5.2.2" + resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz#37b48e2d23116919a3453738c5720455e64e1c49" + integrity sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw== -engine.io@~6.4.1: - version "6.4.1" - resolved "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz" - integrity sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw== +engine.io@~6.5.2: + version "6.5.5" + resolved "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz#430b80d8840caab91a50e9e23cb551455195fc93" + integrity sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA== dependencies: "@types/cookie" "^0.4.1" "@types/cors" "^2.8.12" @@ -7596,126 +7783,152 @@ engine.io@~6.4.1: cookie "~0.4.1" cors "~2.8.5" debug "~4.3.1" - engine.io-parser "~5.0.3" - ws "~8.11.0" + engine.io-parser "~5.2.1" + ws "~8.17.1" enhanced-resolve@^4.0.0, enhanced-resolve@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" tapable "^1.0.0" -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== +enhanced-resolve@^5.17.0: + version "5.17.0" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz#d037603789dd9555b89aaec7eb78845c49089bc5" + integrity sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" enquirer@^2.3.5, enquirer@^2.3.6: - version "2.3.6" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + version "2.4.1" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" + strip-ansi "^6.0.1" ensure-posix-path@^1.0.0, ensure-posix-path@^1.0.1, ensure-posix-path@^1.0.2, ensure-posix-path@^1.1.0, ensure-posix-path@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz" + resolved "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz#3c62bdb19fa4681544289edb2b382adc029179ce" integrity sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw== entities@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== entities@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz" + resolved "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== entities@~1.1.1: version "1.1.2" - resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz" + resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== entities@~2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz" + resolved "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== errlop@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/errlop/-/errlop-2.2.0.tgz" + resolved "https://registry.npmjs.org/errlop/-/errlop-2.2.0.tgz#1ff383f8f917ae328bebb802d6ca69666a42d21b" integrity sha512-e64Qj9+4aZzjzzFpZC7p5kmm/ccCrbLhAJplhsDXQFs87XTsXwOpH4s1Io2s90Tau/8r2j9f4l/thhDevRjzxw== errno@^0.1.3, errno@~0.1.7: version "0.1.8" - resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" error@^7.0.0: version "7.2.1" - resolved "https://registry.npmjs.org/error/-/error-7.2.1.tgz" + resolved "https://registry.npmjs.org/error/-/error-7.2.1.tgz#eab21a4689b5f684fc83da84a0e390de82d94894" integrity sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA== dependencies: string-template "~0.2.1" -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.1" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz" - integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== +es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: + version "1.23.3" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" globalthis "^1.0.3" gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" has-symbols "^1.0.3" - internal-slot "^1.0.4" - is-array-buffer "^3.0.1" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" is-callable "^1.2.7" - is-negative-zero "^2.0.2" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" + is-shared-array-buffer "^1.0.3" is-string "^1.0.7" - is-typed-array "^1.1.10" + is-typed-array "^1.1.13" is-weakref "^1.0.2" - object-inspect "^1.12.2" + object-inspect "^1.13.1" object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.15" -es-get-iterator@^1.1.2: +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.2.1, es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-get-iterator@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" + resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== dependencies: call-bind "^1.0.2" @@ -7728,69 +7941,75 @@ es-get-iterator@^1.1.2: isarray "^2.0.5" stop-iteration-iterator "^1.0.0" -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.5.4" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" es-to-primitive@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" is-symbol "^1.0.2" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.1, escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== escape-html@~1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + version "2.1.0" + resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" estraverse "^5.2.0" esutils "^2.0.2" - optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" eslint-config-prettier@^8.3.0: - version "8.7.0" - resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.7.0.tgz" - integrity sha512-HHVXLSlVUhMSmyW4ZzEuvjpwqamgmlfkutD53cYXLikh4pt/modINRcCIApJ84czDxM4GZInwUrromsDdTImTA== + version "8.10.0" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== eslint-plugin-ember@^10.5.8: version "10.6.1" - resolved "https://registry.npmjs.org/eslint-plugin-ember/-/eslint-plugin-ember-10.6.1.tgz" + resolved "https://registry.npmjs.org/eslint-plugin-ember/-/eslint-plugin-ember-10.6.1.tgz#04ea84cc82307f64a2faa4f2855b30e5ebf9f722" integrity sha512-R+TN3jwhYQ2ytZCA1VkfJDZSGgHFOHjsHU1DrBlRXYRepThe56PpuGxywAyDvQ7inhoAz3e6G6M60PzpvjzmNg== dependencies: "@ember-data/rfc395-data" "^0.0.4" @@ -7804,7 +8023,7 @@ eslint-plugin-ember@^10.5.8: eslint-plugin-es@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz" + resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== dependencies: eslint-utils "^2.0.0" @@ -7812,7 +8031,7 @@ eslint-plugin-es@^3.0.0: eslint-plugin-node@^11.0.0: version "11.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz" + resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== dependencies: eslint-plugin-es "^3.0.0" @@ -7824,14 +8043,14 @@ eslint-plugin-node@^11.0.0: eslint-plugin-prettier@^3.4.1: version "3.4.1" - resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz" + resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== dependencies: prettier-linter-helpers "^1.0.0" eslint-plugin-qunit@^6.2.0: version "6.2.0" - resolved "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-6.2.0.tgz" + resolved "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-6.2.0.tgz#f4efda29da99523e560848d9592c39c0590c308d" integrity sha512-KvPmkIC2MHpfRxs/r8WUeeGkG6y+3qwSi2AZIBtjcM/YG6Z3k0GxW5Hbu3l7X0TDhljVCeBb9Q5puUkHzl83Mw== dependencies: eslint-utils "^3.0.0" @@ -7839,7 +8058,7 @@ eslint-plugin-qunit@^6.2.0: eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -7847,7 +8066,7 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: eslint-scope@^4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== dependencies: esrecurse "^4.1.0" @@ -7855,31 +8074,31 @@ eslint-scope@^4.0.3: eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" eslint-utils@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== dependencies: eslint-visitor-keys "^2.0.0" eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint@^7.32.0: version "7.32.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz" + resolved "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== dependencies: "@babel/code-frame" "7.12.11" @@ -7925,12 +8144,12 @@ eslint@^7.32.0: esm@^3.2.25, esm@^3.2.4: version "3.2.25" - resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz" + resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== espree@^7.3.0, espree@^7.3.1: version "7.3.1" - resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" + resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== dependencies: acorn "^7.4.0" @@ -7939,71 +8158,71 @@ espree@^7.3.0, espree@^7.3.1: esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esprima@~3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz" + resolved "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9" integrity sha512-xoBq/MIShSydNZOkjkoCEjqod963yHNXTLC40ypBhop6yPqflPz/vTinmCfSrGcywVLnSftRf6a0kJLdFdzemw== esquery@^1.4.0: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + version "1.6.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" esrecurse@^4.1.0, esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== estree-walker@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== etag@~1.8.1: version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== eventemitter3@^4.0.0: version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== events-to-array@^1.0.1: version "1.1.2" - resolved "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz" + resolved "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz#2d41f563e1fe400ed4962fe1a4d5c6a7539df7f6" integrity sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA== events@^3.0.0, events@^3.2.0: version "3.3.0" - resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz" + resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: md5.js "^1.3.4" @@ -8011,12 +8230,12 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: exec-sh@^0.3.2: version "0.3.6" - resolved "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz" + resolved "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== execa@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz" + resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: cross-spawn "^6.0.0" @@ -8029,7 +8248,7 @@ execa@^1.0.0: execa@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz" + resolved "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz#e5d3ecd837d2a60ec50f3da78fd39767747bbe99" integrity sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw== dependencies: cross-spawn "^7.0.0" @@ -8044,7 +8263,7 @@ execa@^2.0.0: execa@^3.0.0: version "3.4.0" - resolved "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz" + resolved "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== dependencies: cross-spawn "^7.0.0" @@ -8060,7 +8279,7 @@ execa@^3.0.0: execa@^4.0.0, execa@^4.0.3, execa@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" @@ -8075,7 +8294,7 @@ execa@^4.0.0, execa@^4.0.3, execa@^4.1.0: execa@^5.0.0: version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -8090,17 +8309,17 @@ execa@^5.0.0: exists-sync@0.0.4: version "0.0.4" - resolved "https://registry.npmjs.org/exists-sync/-/exists-sync-0.0.4.tgz" + resolved "https://registry.npmjs.org/exists-sync/-/exists-sync-0.0.4.tgz#9744c2c428cc03b01060db454d4b12f0ef3c8879" integrity sha512-cy5z7K+05RFxHAWY37dSDkPWmuTi+VzrA/xLwPDHmwQPMnO/kVhu6jheGaItlnNRoOE6f5MAjxy3VEupfrHigQ== exit@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== expand-brackets@^2.1.4: version "2.1.4" - resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== dependencies: debug "^2.3.3" @@ -8113,22 +8332,22 @@ expand-brackets@^2.1.4: expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz" + resolved "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" integrity sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw== dependencies: homedir-polyfill "^1.0.1" express@^4.10.7, express@^4.17.1: - version "4.18.2" - resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + version "4.19.2" + resolved "https://registry.npmjs.org/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" @@ -8157,14 +8376,14 @@ express@^4.10.7, express@^4.17.1: extend-shallow@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== dependencies: assign-symbols "^1.0.0" @@ -8172,12 +8391,12 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: extend@^3.0.0, extend@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== external-editor@^3.0.3: version "3.1.0" - resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz" + resolved "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== dependencies: chardet "^0.7.0" @@ -8186,7 +8405,7 @@ external-editor@^3.0.3: extglob@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" @@ -8200,37 +8419,37 @@ extglob@^2.0.4: extract-stack@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/extract-stack/-/extract-stack-2.0.0.tgz" + resolved "https://registry.npmjs.org/extract-stack/-/extract-stack-2.0.0.tgz#11367bc865bfcd9bc0db3123e5edb57786f11f9b" integrity sha512-AEo4zm+TenK7zQorGK1f9mJ8L14hnTDi2ZQPR+Mub1NX8zimka1mXpV5LpH8x9HoUmFSHZCfLHqWvp0Y4FxxzQ== fake-xml-http-request@^2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/fake-xml-http-request/-/fake-xml-http-request-2.1.2.tgz" + resolved "https://registry.npmjs.org/fake-xml-http-request/-/fake-xml-http-request-2.1.2.tgz#f1786720cae50bbb46273035a0173414f3e85e74" integrity sha512-HaFMBi7r+oEC9iJNpc3bvcW7Z7iLmM26hPDmlb0mFwyANSsOQAtJxbdWsXITKOzZUyMYK0zYCv3h5yDj9TsiXg== faker@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz" + resolved "https://registry.npmjs.org/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" integrity sha512-ILKg69P6y/D8/wSmDXw35Ly0re8QzQ8pMfBCflsGiZG2ZjMUNLYNexA6lz5pkmJlepVdsiDFUxYAzPQ9/+iGLA== faker@^5.5.3: version "5.5.3" - resolved "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz" + resolved "https://registry.npmjs.org/faker/-/faker-5.5.3.tgz#c57974ee484431b25205c2c8dc09fda861e51e0e" integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + version "1.3.0" + resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@^2.2.6: version "2.2.7" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== dependencies: "@mrmlnc/readdir-enhanced" "^2.2.1" @@ -8240,10 +8459,10 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.0.3, fast-glob@^3.2.12, fast-glob@^3.2.5, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.0.3, fast-glob@^3.2.5, fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.2" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -8253,29 +8472,29 @@ fast-glob@^3.0.3, fast-glob@^3.2.12, fast-glob@^3.2.5, fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-memoize@^2.5.2: version "2.5.2" - resolved "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz" + resolved "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz#79e3bb6a4ec867ea40ba0e7146816f6cdce9b57e" integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw== fast-ordered-set@^1.0.0, fast-ordered-set@^1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/fast-ordered-set/-/fast-ordered-set-1.0.3.tgz" + resolved "https://registry.npmjs.org/fast-ordered-set/-/fast-ordered-set-1.0.3.tgz#3fbb36634f7be79e4f7edbdb4a357dee25d184eb" integrity sha512-MxBW4URybFszOx1YlACEoK52P6lE3xiFcPaGCUZ7QQOZ6uJXKo++Se8wa31SjcZ+NC/fdAWX7UtKEfaGgHS2Vg== dependencies: blank-object "^1.0.1" fast-sourcemap-concat@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/fast-sourcemap-concat/-/fast-sourcemap-concat-1.4.0.tgz" + resolved "https://registry.npmjs.org/fast-sourcemap-concat/-/fast-sourcemap-concat-1.4.0.tgz#122c330d4a2afaff16ad143bc9674b87cd76c8ad" integrity sha512-x90Wlx/2C83lfyg7h4oguTZN4MyaVfaiUSJQNpU+YEA0Odf9u659Opo44b0LfoVg9G/bOE++GdID/dkyja+XcA== dependencies: chalk "^2.0.0" @@ -8288,9 +8507,9 @@ fast-sourcemap-concat@^1.4.0: sourcemap-validator "^1.1.0" fast-sourcemap-concat@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-sourcemap-concat/-/fast-sourcemap-concat-2.1.0.tgz" - integrity sha512-L9uADEnnHOeF4U5Kc3gzEs3oFpNCFkiTJXvT+nKmR0zcFqHZJJbszWT7dv4t9558FJRGpCj8UxUpTgz2zwiIZA== + version "2.1.1" + resolved "https://registry.npmjs.org/fast-sourcemap-concat/-/fast-sourcemap-concat-2.1.1.tgz#3647fd5876deace53d9a1c418061199417911801" + integrity sha512-7h9/x25c6AQwdU3mA8MZDUMR3UCy50f237egBrBkuwjnUZSmfu4ptCf91PZSKzON2Uh5VvIHozYKWcPPgcjxIw== dependencies: chalk "^2.0.0" fs-extra "^5.0.0" @@ -8299,80 +8518,79 @@ fast-sourcemap-concat@^2.1.0: mkdirp "^0.5.0" source-map "^0.4.2" source-map-url "^0.3.0" - sourcemap-validator "^1.1.0" fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" fault@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz" + resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== dependencies: format "^0.2.0" faye-websocket@^0.11.3: version "0.11.4" - resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== dependencies: websocket-driver ">=0.5.1" fb-watchman@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" figgy-pudding@^3.5.1: version "3.5.2" - resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz" + resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== figures@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz" + resolved "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" integrity sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA== dependencies: escape-string-regexp "^1.0.5" figures@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== dependencies: escape-string-regexp "^1.0.5" file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" file-uri-to-path@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== filesize@^4.1.2: version "4.2.1" - resolved "https://registry.npmjs.org/filesize/-/filesize-4.2.1.tgz" + resolved "https://registry.npmjs.org/filesize/-/filesize-4.2.1.tgz#ab1cb2069db5d415911c1a13e144c0e743bc89bc" integrity sha512-bP82Hi8VRZX/TUBKfE24iiUGsB/sfm2WUrwTQyAzQrhO3V9IhcBBNBXMyzLY5orACxRyYJ3d2HeRVX+eFv4lmA== filesize@^6.1.0: version "6.4.0" - resolved "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz" + resolved "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz#914f50471dd66fdca3cefe628bd0cde4ef769bcd" integrity sha512-mjFIpOHC4jbfcTfoh4rkWpI31mF7viw9ikj/JyLoKzqlwG/YsefKfvYlYhdYdg/9mtK2z1AzgN/0LvVQ3zdlSQ== fill-range@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== dependencies: extend-shallow "^2.0.1" @@ -8380,16 +8598,16 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" finalhandler@1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== dependencies: debug "2.6.9" @@ -8402,7 +8620,7 @@ finalhandler@1.1.2: finalhandler@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" @@ -8414,16 +8632,24 @@ finalhandler@1.2.0: unpipe "~1.0.0" find-babel-config@^1.1.0, find-babel-config@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz" - integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA== + version "1.2.2" + resolved "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.2.tgz#41199b5cb9154dcb2fdc351cbe70eaf9198d5111" + integrity sha512-oK59njMyw2y3yxto1BCfVK7MQp/OYf4FleHu0RgosH3riFJ1aOuo/7naLDLAObfrgn3ueFhw5sAT/cp0QuJI3Q== dependencies: - json5 "^0.5.1" + json5 "^1.0.2" path-exists "^3.0.0" +find-babel-config@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.1.tgz#93703fc8e068db5e4c57592900c5715dd04b7e5b" + integrity sha512-5Ji+EAysHGe1OipH7GN4qDjok5Z1uw5KAwDCbicU/4wyTZY7CqOCzcWbG7J5ad9mazq67k89fXlbc1MuIfl9uA== + dependencies: + json5 "^2.2.3" + path-exists "^4.0.0" + find-cache-dir@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== dependencies: commondir "^1.0.1" @@ -8432,7 +8658,7 @@ find-cache-dir@^2.1.0: find-cache-dir@^3.3.1: version "3.3.2" - resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== dependencies: commondir "^1.0.1" @@ -8441,26 +8667,26 @@ find-cache-dir@^3.3.1: find-index@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/find-index/-/find-index-1.1.1.tgz" + resolved "https://registry.npmjs.org/find-index/-/find-index-1.1.1.tgz#4b221f8d46b7f8bea33d8faed953f3ca7a081cbc" integrity sha512-XYKutXMrIK99YMUPf91KX5QVJoG31/OsgftD6YoTPAObfQIxM4ziA9f0J1AsqKhJmo+IeaIPP0CFopTD4bdUBw== find-up@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" + resolved "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== dependencies: locate-path "^2.0.0" find-up@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: locate-path "^3.0.0" find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -8468,7 +8694,7 @@ find-up@^4.0.0, find-up@^4.1.0: find-up@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -8476,14 +8702,14 @@ find-up@^5.0.0: find-versions@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz" + resolved "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== dependencies: semver-regex "^3.1.2" -find-yarn-workspace-root@^1.1.0: +find-yarn-workspace-root@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz" + resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== dependencies: fs-extra "^4.0.3" @@ -8491,14 +8717,14 @@ find-yarn-workspace-root@^1.1.0: find-yarn-workspace-root@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz" + resolved "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== dependencies: micromatch "^4.0.2" findup-sync@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz" + resolved "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== dependencies: detect-file "^1.0.0" @@ -8506,9 +8732,9 @@ findup-sync@^4.0.0: micromatch "^4.0.2" resolve-dir "^1.0.1" -fireworm@^0.7.0: +fireworm@^0.7.2: version "0.7.2" - resolved "https://registry.npmjs.org/fireworm/-/fireworm-0.7.2.tgz" + resolved "https://registry.npmjs.org/fireworm/-/fireworm-0.7.2.tgz#bc5736515b48bd30bf3293a2062e0b0e0361537a" integrity sha512-GjebTzq+NKKhfmDxjKq3RXwQcN9xRmZWhnnuC9L+/x5wBQtR0aaQM50HsjrzJ2wc28v1vSdfOpELok0TKR4ddg== dependencies: async "~0.2.9" @@ -8519,7 +8745,7 @@ fireworm@^0.7.0: fixturify-project@^1.10.0: version "1.10.0" - resolved "https://registry.npmjs.org/fixturify-project/-/fixturify-project-1.10.0.tgz" + resolved "https://registry.npmjs.org/fixturify-project/-/fixturify-project-1.10.0.tgz#091c452a9bb15f09b6b9cc7cf5c0ad559f1d9aad" integrity sha512-L1k9uiBQuN0Yr8tA9Noy2VSQ0dfg0B8qMdvT7Wb5WQKc7f3dn3bzCbSrqlb+etLW+KDV4cBC7R1OvcMg3kcxmA== dependencies: fixturify "^1.2.0" @@ -8527,7 +8753,7 @@ fixturify-project@^1.10.0: fixturify-project@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/fixturify-project/-/fixturify-project-2.1.1.tgz" + resolved "https://registry.npmjs.org/fixturify-project/-/fixturify-project-2.1.1.tgz#a511dd26700c6b64ac271ef4393e7124f153c81f" integrity sha512-sP0gGMTr4iQ8Kdq5Ez0CVJOZOGWqzP5dv/veOTdFNywioKjkNWCHBi1q65DMpcNGUGeoOUWehyji274Q2wRgxA== dependencies: fixturify "^2.1.0" @@ -8536,7 +8762,7 @@ fixturify-project@^2.1.1: fixturify@^1.2.0: version "1.3.0" - resolved "https://registry.npmjs.org/fixturify/-/fixturify-1.3.0.tgz" + resolved "https://registry.npmjs.org/fixturify/-/fixturify-1.3.0.tgz#163c468093c7c4d90b70cde39fd6325f6528b25d" integrity sha512-tL0svlOy56pIMMUQ4bU1xRe6NZbFSa/ABTWMxW2mH38lFGc9TrNAKWcMBQ7eIjo3wqSS8f2ICabFaatFyFmrVQ== dependencies: "@types/fs-extra" "^5.0.5" @@ -8547,7 +8773,7 @@ fixturify@^1.2.0: fixturify@^2.1.0: version "2.1.1" - resolved "https://registry.npmjs.org/fixturify/-/fixturify-2.1.1.tgz" + resolved "https://registry.npmjs.org/fixturify/-/fixturify-2.1.1.tgz#e962d72f062600cb81a9651086f60d822c72d998" integrity sha512-SRgwIMXlxkb6AUgaVjIX+jCEqdhyXu9hah7mcK+lWynjKtX73Ux1TDv71B7XyaQ+LJxkYRHl5yCL8IycAvQRUw== dependencies: "@types/fs-extra" "^8.1.0" @@ -8558,26 +8784,27 @@ fixturify@^2.1.0: walk-sync "^2.0.2" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.2.0" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" flat@^5.0.0: version "5.0.2" - resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" + resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== flush-write-stream@^1.0.0: version "1.1.1" - resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz" + resolved "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== dependencies: inherits "^2.0.3" @@ -8585,36 +8812,36 @@ flush-write-stream@^1.0.0: focus-trap@^6.7.1: version "6.9.4" - resolved "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.4.tgz" + resolved "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.4.tgz#436da1a1d935c48b97da63cd8f361c6f3aa16444" integrity sha512-v2NTsZe2FF59Y+sDykKY+XjqZ0cPfhq/hikWVL88BqLivnNiEffAsac6rP6H45ff9wG9LL5ToiDqrLEP9GX9mw== dependencies: tabbable "^5.3.3" focusable-selectors@^0.3.0: version "0.3.1" - resolved "https://registry.npmjs.org/focusable-selectors/-/focusable-selectors-0.3.1.tgz" + resolved "https://registry.npmjs.org/focusable-selectors/-/focusable-selectors-0.3.1.tgz#7eacbca8dc6cc8d7f7563e5f5cc3699b91e20aaa" integrity sha512-5JLtr0e1YJIfmnVlpLiG+av07dd0Xkf/KfswsXcei5KmLfdwOysTQsjF058ynXniujb1fvev7nql1x+CkC5ikw== follow-redirects@^1.0.0: - version "1.15.2" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + version "1.15.6" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== dependencies: is-callable "^1.1.3" for-in@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== form-data@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" + resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" @@ -8623,34 +8850,34 @@ form-data@^3.0.0: format@^0.2.0: version "0.2.2" - resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" + resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== forwarded@0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== +fraction.js@^4.3.7: + version "4.3.7" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" + integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== fragment-cache@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== dependencies: map-cache "^0.2.2" fresh@0.5.2: version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== from2@^2.1.0: version "2.3.0" - resolved "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz" + resolved "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== dependencies: inherits "^2.0.1" @@ -8658,7 +8885,7 @@ from2@^2.1.0: fs-extra@^0.24.0: version "0.24.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-0.24.0.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952" integrity sha512-w1RvhdLZdU9V3vQdL+RooGlo6b9R9WVoBanOfoJvosWlqSKvrjFlci2oVhwvLwZXBtM7khyPvZ8r3fwsim3o0A== dependencies: graceful-fs "^4.1.2" @@ -8668,7 +8895,7 @@ fs-extra@^0.24.0: fs-extra@^10.0.0: version "10.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" @@ -8677,7 +8904,7 @@ fs-extra@^10.0.0: fs-extra@^4.0.2, fs-extra@^4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== dependencies: graceful-fs "^4.1.2" @@ -8686,7 +8913,7 @@ fs-extra@^4.0.2, fs-extra@^4.0.3: fs-extra@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== dependencies: graceful-fs "^4.1.2" @@ -8695,7 +8922,7 @@ fs-extra@^5.0.0: fs-extra@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" integrity sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA== dependencies: graceful-fs "^4.1.2" @@ -8704,7 +8931,7 @@ fs-extra@^6.0.1: fs-extra@^7.0.0, fs-extra@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== dependencies: graceful-fs "^4.1.2" @@ -8713,7 +8940,7 @@ fs-extra@^7.0.0, fs-extra@^7.0.1: fs-extra@^8.0.0, fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: graceful-fs "^4.2.0" @@ -8722,7 +8949,7 @@ fs-extra@^8.0.0, fs-extra@^8.0.1, fs-extra@^8.1.0: fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" @@ -8732,7 +8959,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0: fs-merger@^3.0.1, fs-merger@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz" + resolved "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz#a225b11ae530426138294b8fbb19e82e3d4e0b3b" integrity sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug== dependencies: broccoli-node-api "^1.7.0" @@ -8743,7 +8970,7 @@ fs-merger@^3.0.1, fs-merger@^3.2.1: fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5.6: version "0.5.9" - resolved "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-0.5.9.tgz" + resolved "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-0.5.9.tgz#a4ec6182c2f5bd80b9b83c8e23e4522e6f5fd946" integrity sha512-872G8ax0kHh01m9n/2KDzgYwouKza0Ad9iFltBpNykvROvf2AGtoOzPJgGx125aolGPER3JuC7uZFrQ7bG1AZw== dependencies: heimdalljs-logger "^0.1.7" @@ -8753,7 +8980,7 @@ fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5 fs-tree-diff@^2.0.0, fs-tree-diff@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz" + resolved "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz#343e4745ab435ec39ebac5f9059ad919cd034afa" integrity sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A== dependencies: "@types/symlink-or-copy" "^1.2.0" @@ -8764,7 +8991,7 @@ fs-tree-diff@^2.0.0, fs-tree-diff@^2.0.1: fs-updater@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/fs-updater/-/fs-updater-1.0.4.tgz" + resolved "https://registry.npmjs.org/fs-updater/-/fs-updater-1.0.4.tgz#2329980f99ae9176e9a0e84f7637538a182ce63b" integrity sha512-0pJX4mJF/qLsNEwTct8CdnnRdagfb+LmjRPJ8sO+nCnAZLW0cTmz4rTgU25n+RvTuWSITiLKrGVJceJPBIPlKg== dependencies: can-symlink "^1.0.0" @@ -8775,7 +9002,7 @@ fs-updater@^1.0.4: fs-write-stream-atomic@^1.0.8: version "1.0.10" - resolved "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz" + resolved "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== dependencies: graceful-fs "^4.1.2" @@ -8785,55 +9012,55 @@ fs-write-stream-atomic@^1.0.8: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^1.2.7: version "1.2.13" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== dependencies: bindings "^1.5.0" nan "^2.12.1" fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" functional-red-black-tree@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz" + resolved "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -functions-have-names@^1.2.2: +functions-have-names@^1.2.3: version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== fuse.js@^6.4.6: version "6.6.2" - resolved "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz" + resolved "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz#fe463fed4b98c0226ac3da2856a415576dc9a111" integrity sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA== gauge@^4.0.3: version "4.0.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" + resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== dependencies: aproba "^1.0.3 || ^2.0.0" @@ -8847,7 +9074,7 @@ gauge@^4.0.3: gauge@~2.7.3: version "2.7.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" + resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== dependencies: aproba "^1.0.3" @@ -8861,93 +9088,96 @@ gauge@~2.7.3: gensync@^1.0.0-beta.2: version "1.0.0-beta.2" - resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-package-type@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== get-stdin@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== get-stdin@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== get-stream@^4.0.0: version "4.1.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" get-stream@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== git-hooks-list@1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz" + resolved "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156" integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ== git-repo-info@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/git-repo-info/-/git-repo-info-2.1.1.tgz" + resolved "https://registry.npmjs.org/git-repo-info/-/git-repo-info-2.1.1.tgz#220ffed8cbae74ef8a80e3052f2ccb5179aed058" integrity sha512-8aCohiDo4jwjOwma4FmYFd3i97urZulL8XL24nIPxuE+GZnfsAyy/g2Shqx6OjUiFKUXZM+Yy+KHnOmmA3FVcg== github-slugger@^1.0.0, github-slugger@^1.2.1, github-slugger@^1.3.0: version "1.5.0" - resolved "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz" + resolved "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== glob-parent@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== dependencies: is-glob "^3.1.0" @@ -8955,42 +9185,31 @@ glob-parent@^3.1.0: glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" glob-to-regexp@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== glob-to-regexp@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^5.0.10: - version "5.0.15" - resolved "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz" - integrity sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA== - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.4, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.3: +glob@7.2.3, glob@^10.3.10, glob@^5.0.10, glob@^7.0.4, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7, glob@^7.2.3, glob@^9.3.3: version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -9002,7 +9221,7 @@ glob@^7.0.4, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, gl global-modules@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz" + resolved "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== dependencies: global-prefix "^1.0.1" @@ -9011,7 +9230,7 @@ global-modules@^1.0.0: global-prefix@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz" + resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" integrity sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg== dependencies: expand-tilde "^2.0.2" @@ -9022,36 +9241,37 @@ global-prefix@^1.0.1: globals@^11.1.0: version "11.12.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + version "13.24.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" globals@^9.18.0: version "9.18.0" - resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz" + resolved "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + version "1.0.4" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== dependencies: - define-properties "^1.1.3" + define-properties "^1.2.1" + gopd "^1.0.1" globalyzer@0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz" + resolved "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== globby@10.0.0: version "10.0.0" - resolved "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz" + resolved "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz#abfcd0630037ae174a88590132c2f6804e291072" integrity sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw== dependencies: "@types/glob" "^7.1.1" @@ -9065,7 +9285,7 @@ globby@10.0.0: globby@^11.0.2, globby@^11.0.3: version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -9077,45 +9297,45 @@ globby@^11.0.2, globby@^11.0.3: globrex@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz" + resolved "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== good-listener@^1.2.2: version "1.2.2" - resolved "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz" + resolved "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" integrity sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw== dependencies: delegate "^3.1.2" gopd@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== "graceful-readlink@>= 1.0.0": version "1.0.1" - resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w== growly@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz" + resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw== handlebars@^4.0.13, handlebars@^4.0.4, handlebars@^4.3.1, handlebars@^4.4.2, handlebars@^4.7.3: - version "4.7.7" - resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: @@ -9123,78 +9343,78 @@ handlebars@^4.0.13, handlebars@^4.0.4, handlebars@^4.3.1, handlebars@^4.4.2, han has-ansi@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== dependencies: ansi-regex "^2.0.0" has-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-3.0.0.tgz" + resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-3.0.0.tgz#36077ef1d15f333484aa7fa77a28606f1c655b37" integrity sha512-5JRDTvNq6mVkaMHQVXrGnaCXHD6JfqxwCy8LA/DQSqLLqePR9uaJVm2u3Ek/UziJFQz+d1ul99RtfIhE2aorkQ== dependencies: ansi-regex "^3.0.0" has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-color@~0.1.0: version "0.1.7" - resolved "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz" + resolved "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" integrity sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw== -has-dynamic-import@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.1.tgz" - integrity sha512-X3fbtsZmwb6W7fJGR9o7x65fZoodygCrZ3TVycvghP62yYQfS0t4RS0Qcz+j5tQYUKeSWS09tHkWW6WhFV3XhQ== +has-dynamic-import@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.1.0.tgz#06359ad7672b9e764aea93a54bb9d6e17542d34c" + integrity sha512-su0anMkNEnJKZ/rB99jn3y6lV/J8Ro96hBJ28YAeVzj5rWxH+YL/AdCyiYYA1HDLV9YhmvqpWSJJj2KLo1MX6g== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.5" + get-intrinsic "^1.2.2" has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: - get-intrinsic "^1.1.1" + es-define-property "^1.0.0" -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: - has-symbols "^1.0.2" + has-symbols "^1.0.3" has-unicode@^2.0.0, has-unicode@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== has-value@^0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== dependencies: get-value "^2.0.3" @@ -9203,7 +9423,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz" + resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== dependencies: get-value "^2.0.6" @@ -9212,36 +9432,37 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz" + resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== has-values@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== dependencies: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hash-base@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== dependencies: inherits "^2.0.4" readable-stream "^3.6.0" safe-buffer "^5.2.0" +hash-base@~3.0: + version "3.0.4" + resolved "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + hash-for-dep@^1.0.2, hash-for-dep@^1.2.3, hash-for-dep@^1.4.7, hash-for-dep@^1.5.0, hash-for-dep@^1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/hash-for-dep/-/hash-for-dep-1.5.1.tgz" + resolved "https://registry.npmjs.org/hash-for-dep/-/hash-for-dep-1.5.1.tgz#497754b39bee2f1c4ade4521bfd2af0a7c1196e3" integrity sha512-/dQ/A2cl7FBPI2pO0CANkvuuVi/IFS5oTyJ0PsOb6jW6WbVW1js5qJXMJTNbWHXBIPdFTWFbabjB+mE0d+gelw== dependencies: broccoli-kitchen-sink-helpers "^0.3.1" @@ -9253,25 +9474,32 @@ hash-for-dep@^1.0.2, hash-for-dep@^1.2.3, hash-for-dep@^1.4.7, hash-for-dep@^1.5 hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" - resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" + resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + hast-util-is-element@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz" + resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz#3b3ed5159a2707c6137b48637fbfe068e175a425" integrity sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ== hast-util-parse-selector@^2.0.0: version "2.2.5" - resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz" + resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== hast-util-to-html@^7.1.1: version "7.1.3" - resolved "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz" + resolved "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz#9f339ca9bea71246e565fc79ff7dbfe98bb50f5e" integrity sha512-yk2+1p3EJTEE9ZEUkgHsUSVhIpCsL/bvT8E5GzmWc+N1Po5gBw+0F8bo7dpxXR0nu0bQVxVZGX2lBGF21CmeDw== dependencies: ccount "^1.0.0" @@ -9287,17 +9515,17 @@ hast-util-to-html@^7.1.1: hast-util-to-string@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz" + resolved "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz#9b24c114866bdb9478927d7e9c36a485ac728378" integrity sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w== hast-util-whitespace@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz" + resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz#e4fe77c4a9ae1cb2e6c25e02df0043d0164f6e41" integrity sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A== hastscript@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz" + resolved "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== dependencies: "@types/hast" "^2.0.0" @@ -9308,7 +9536,7 @@ hastscript@^6.0.0: heimdalljs-fs-monitor@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/heimdalljs-fs-monitor/-/heimdalljs-fs-monitor-1.1.1.tgz" + resolved "https://registry.npmjs.org/heimdalljs-fs-monitor/-/heimdalljs-fs-monitor-1.1.1.tgz#bb4021007e88484202402cdf594e3962d70dc4f4" integrity sha512-BHB8oOXLRlrIaON0MqJSEjGVPDyqt2Y6gu+w2PaEZjrCxeVtZG7etEZp7M4ZQ80HNvnr66KIQ2lot2qdeG8HgQ== dependencies: callsites "^3.1.0" @@ -9319,12 +9547,12 @@ heimdalljs-fs-monitor@^1.1.0: heimdalljs-graph@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/heimdalljs-graph/-/heimdalljs-graph-1.0.0.tgz" + resolved "https://registry.npmjs.org/heimdalljs-graph/-/heimdalljs-graph-1.0.0.tgz#0059857952988e54f3a74bb23edaf669f8eaf6af" integrity sha512-v2AsTERBss0ukm/Qv4BmXrkwsT5x6M1V5Om6E8NcDQ/ruGkERsfsuLi5T8jx8qWzKMGYlwzAd7c/idymxRaPzA== heimdalljs-logger@^0.1.10, heimdalljs-logger@^0.1.7, heimdalljs-logger@^0.1.9: version "0.1.10" - resolved "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz" + resolved "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz#90cad58aabb1590a3c7e640ddc6a4cd3a43faaf7" integrity sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g== dependencies: debug "^2.2.0" @@ -9332,14 +9560,14 @@ heimdalljs-logger@^0.1.10, heimdalljs-logger@^0.1.7, heimdalljs-logger@^0.1.9: heimdalljs@^0.2.0, heimdalljs@^0.2.1, heimdalljs@^0.2.3, heimdalljs@^0.2.5, heimdalljs@^0.2.6: version "0.2.6" - resolved "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz" + resolved "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz#b0eebabc412813aeb9542f9cc622cb58dbdcd9fe" integrity sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA== dependencies: rsvp "~3.2.1" hmac-drbg@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" + resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== dependencies: hash.js "^1.0.3" @@ -9348,7 +9576,7 @@ hmac-drbg@^1.0.1: home-or-tmp@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz" + resolved "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" integrity sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg== dependencies: os-homedir "^1.0.0" @@ -9356,50 +9584,50 @@ home-or-tmp@^2.0.0: homedir-polyfill@^1.0.1: version "1.0.3" - resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz" + resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== dependencies: parse-passwd "^1.0.0" hosted-git-info@^2.1.4: version "2.8.9" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hosted-git-info@^3.0.8: version "3.0.8" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== dependencies: lru-cache "^6.0.0" hosted-git-info@^4.0.1: version "4.1.0" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" html-encoding-sniffer@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz" + resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== dependencies: whatwg-encoding "^1.0.5" html-escaper@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== html-void-elements@^1.0.0: version "1.0.5" - resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz" + resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== htmlparser2@^7.2.0: version "7.2.0" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5" integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== dependencies: domelementtype "^2.0.1" @@ -9409,7 +9637,7 @@ htmlparser2@^7.2.0: http-errors@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: depd "2.0.0" @@ -9420,7 +9648,7 @@ http-errors@2.0.0: http-errors@~1.6.2: version "1.6.3" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== dependencies: depd "~1.1.2" @@ -9430,12 +9658,12 @@ http-errors@~1.6.2: http-parser-js@>=0.5.1: version "0.5.8" - resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== http-proxy-agent@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: "@tootallnate/once" "1" @@ -9444,7 +9672,7 @@ http-proxy-agent@^4.0.1: http-proxy@^1.13.1, http-proxy@^1.18.1: version "1.18.1" - resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" + resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== dependencies: eventemitter3 "^4.0.0" @@ -9453,12 +9681,12 @@ http-proxy@^1.13.1, http-proxy@^1.18.1: https-browserify@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz" + resolved "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== https-proxy-agent@^5.0.0: version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" @@ -9466,22 +9694,22 @@ https-proxy-agent@^5.0.0: https@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/https/-/https-1.0.0.tgz" + resolved "https://registry.npmjs.org/https/-/https-1.0.0.tgz#3c37c7ae1a8eeb966904a2ad1e975a194b7ed3a4" integrity sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg== human-signals@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== husky@^4.2.5: version "4.3.8" - resolved "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz" + resolved "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== dependencies: chalk "^4.0.0" @@ -9497,44 +9725,44 @@ husky@^4.2.5: iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" - resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" + resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== ieee754@^1.1.13, ieee754@^1.1.4: version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" - resolved "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz" + resolved "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== ignore@^4.0.6: version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" + resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.1.1, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.1" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== immutable@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz" - integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + version "4.3.6" + resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.6.tgz#6a05f7858213238e587fb83586ffa3b4b27f0447" + integrity sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ== import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -9542,32 +9770,32 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== include-path-searcher@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/include-path-searcher/-/include-path-searcher-0.1.0.tgz" + resolved "https://registry.npmjs.org/include-path-searcher/-/include-path-searcher-0.1.0.tgz#c0cf2ddfa164fb2eae07bc7ca43a7f191cb4d7bd" integrity sha512-KlpXnsZOrBGo4PPKqPFi3Ft6dcRyh8fTaqgzqDRi8jKAsngJEWWOxeFIWC8EfZtXKaZqlsNf9XRwcQ49DVgl/g== indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== infer-owner@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" + resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== inflection@^1.12.0, inflection@~1.13.1: version "1.13.4" - resolved "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz" + resolved "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32" integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -9575,27 +9803,22 @@ inflight@^1.0.4: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - integrity sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA== - inherits@2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== ini@^1.3.4: version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== inline-source-map-comment@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz" + resolved "https://registry.npmjs.org/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz#50a8a44c2a790dfac441b5c94eccd5462635faf6" integrity sha512-a3/m6XgooVCXkZCduOb7pkuvUtNKt4DaqaggKKJrMQHQsqt6JcJXEreExeZiiK4vWL/cM/uF6+chH05pz2/TdQ== dependencies: chalk "^1.0.0" @@ -9606,7 +9829,7 @@ inline-source-map-comment@^1.0.5: inquirer@^6: version "6.5.2" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: ansi-escapes "^3.2.0" @@ -9625,7 +9848,7 @@ inquirer@^6: inquirer@^7.3.3: version "7.3.3" - resolved "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== dependencies: ansi-escapes "^4.2.1" @@ -9642,23 +9865,23 @@ inquirer@^7.3.3: strip-ansi "^6.0.0" through "^2.3.6" -internal-slot@^1.0.3, internal-slot@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== +internal-slot@^1.0.4, internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" + es-errors "^1.3.0" + hasown "^2.0.0" side-channel "^1.0.4" internmap@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== intl-messageformat-parser@^6.0.5: version "6.4.4" - resolved "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.4.4.tgz" + resolved "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.4.4.tgz#abbd94e96dc4ff41607376bfab024553450cc1e0" integrity sha512-7AaFKNZEfzLQR6+jivOuz9e7yA8ka5KrmLebgY4QHTRLf8r64dp3LjnW98LkBWjdk8GK0sawD2dHDqW++A/pXA== dependencies: "@formatjs/ecma402-abstract" "1.6.4" @@ -9666,7 +9889,7 @@ intl-messageformat-parser@^6.0.5: intl-messageformat@^9.3.6: version "9.13.0" - resolved "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz" + resolved "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz#97360b73bd82212e4f6005c712a4a16053165468" integrity sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw== dependencies: "@formatjs/ecma402-abstract" "1.11.4" @@ -9676,38 +9899,31 @@ intl-messageformat@^9.3.6: invariant@^2.2.2: version "2.2.4" - resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" + resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" ipaddr.js@1.9.1: version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== +is-accessor-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" + integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" is-alphabetical@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== is-alphanumerical@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== dependencies: is-alphabetical "^1.0.0" @@ -9715,50 +9931,49 @@ is-alphanumerical@^1.0.0: is-arguments@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" + resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== dependencies: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-array-buffer@^3.0.1: - version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== +is-array-buffer@^3.0.2, is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== dependencies: call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" + get-intrinsic "^1.2.1" is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== dependencies: has-bigints "^1.0.1" is-binary-path@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== dependencies: binary-extensions "^1.0.0" is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== dependencies: call-bind "^1.0.2" @@ -9766,212 +9981,210 @@ is-boolean-object@^1.1.0: is-buffer@^1.1.5: version "1.1.6" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-buffer@^2.0.0: version "2.0.5" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.13.0, is-core-module@^2.9.0: - version "2.13.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== +is-core-module@^2.13.0: + version "2.14.0" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz#43b8ef9f46a6a08888db67b1ffd4ec9e3dfd59d1" + integrity sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A== dependencies: - has "^1.0.3" + hasown "^2.0.2" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== +is-data-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" + integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== dependencies: - kind-of "^3.0.2" + hasown "^2.0.0" -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== dependencies: - kind-of "^6.0.0" + is-typed-array "^1.1.13" is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== dependencies: has-tostringtag "^1.0.0" is-decimal@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + version "0.1.7" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" + integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + version "1.0.3" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" + integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" is-docker@^2.0.0: version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== is-extendable@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-finite@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz" + resolved "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== is-fullwidth-code-point@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-git-url@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-git-url/-/is-git-url-1.0.0.tgz" + resolved "https://registry.npmjs.org/is-git-url/-/is-git-url-1.0.0.tgz#53f684cd143285b52c3244b4e6f28253527af66b" integrity sha512-UCFta9F9rWFSavp9H3zHEHrARUfZbdJvmHKeEpds4BK3v7W2LdXoNypMtXXi5w5YBDEBCTYmbI+vsSwI8LYJaQ== is-glob@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== dependencies: is-extglob "^2.1.0" is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-hexadecimal@^1.0.0: version "1.0.4" - resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== is-interactive@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" + resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== is-language-code@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-language-code/-/is-language-code-2.0.0.tgz" + resolved "https://registry.npmjs.org/is-language-code/-/is-language-code-2.0.0.tgz#6f4d59c551d73b98c45cf9f1d3ce65cee060e65b" integrity sha512-6xKmRRcP2YdmMBZMVS3uiJRPQgcMYolkD6hFw2Y4KjqyIyaJlCGxUt56tuu0iIV8q9r8kMEo0Gjd/GFwKrgjbw== -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== +is-map@^2.0.2, is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== is-number-object@^1.0.4: version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" is-number@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== dependencies: kind-of "^3.0.2" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== is-obj@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-plain-obj@2.1.0, is-plain-obj@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== is-plain-obj@^1.1: version "1.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-potential-custom-element-name@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz" + resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-regex@^1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== dependencies: call-bind "^1.0.2" @@ -9979,155 +10192,151 @@ is-regex@^1.1.4: is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== +is-set@^2.0.2, is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" is-stream@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== dependencies: has-tostringtag "^1.0.0" is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: has-symbols "^1.0.2" is-type@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/is-type/-/is-type-0.0.1.tgz" + resolved "https://registry.npmjs.org/is-type/-/is-type-0.0.1.tgz#f651d85c365d44955d14a51d8d7061f3f6b4779c" integrity sha512-YwJh/zBVrcJ90aAnPBM0CbHvm7lG9ao7lIFeqTZ1UQj4iFLpM5CikdaU+dGGesrMJwxLqPGmjjrUrQ6Kn3Zh+w== dependencies: core-util-is "~1.0.0" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.14" is-typedarray@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== is-weakref@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: call-bind "^1.0.2" -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz#e801519df8c0c43e12ff2834eead84ec9e624007" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.7" + get-intrinsic "^1.2.4" is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== is-wsl@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== is-wsl@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" isarray@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isarray@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== isbinaryfile@^4.0.6: version "4.0.10" - resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + version "3.2.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4: version "5.2.1" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" @@ -10137,25 +10346,25 @@ istanbul-lib-instrument@^5.0.4: semver "^6.3.0" istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-reports@^3.0.2: - version "3.1.5" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + version "3.1.7" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" istextorbinary@2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.1.0.tgz" + resolved "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.1.0.tgz#dbed2a6f51be2f7475b68f89465811141b758874" integrity sha512-kT1g2zxZ5Tdabtpp9VSdOzW9lb6LXImyWbzbQeTxoRtHhurC9Ej9Wckngr2+uepPL09ky/mJHmN9jeJPML5t6A== dependencies: binaryextensions "1 || 2" @@ -10164,7 +10373,7 @@ istextorbinary@2.1.0: istextorbinary@^2.5.1: version "2.6.0" - resolved "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.6.0.tgz" + resolved "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.6.0.tgz#60776315fb0fa3999add276c02c69557b9ca28ab" integrity sha512-+XRlFseT8B3L9KyjxxLjfXSLMuErKDsd8DBNrsaxoViABMEZlOSCstwmw0qpoFX3+U6yWU1yhLudAe6/lETGGA== dependencies: binaryextensions "^2.1.2" @@ -10173,7 +10382,7 @@ istextorbinary@^2.5.1: ivy-codemirror@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/ivy-codemirror/-/ivy-codemirror-2.1.0.tgz" + resolved "https://registry.npmjs.org/ivy-codemirror/-/ivy-codemirror-2.1.0.tgz#c06f1606c375610bf62b007a21a9e63f5854175e" integrity sha512-+Ha6Yf39fiK3dfQD5vlanrQ8GMIf/KVRbxzEzG+AsvAgUNSO8VECCfIRzdHQZcBfi9jNCaT+9q6VQd7mSqNalQ== dependencies: codemirror "~5.15.0" @@ -10182,36 +10391,41 @@ ivy-codemirror@^2.1.0: jest-worker@^27.4.5: version "27.5.1" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" +jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + jquery@^3.4.1, jquery@^3.5.1: - version "3.6.4" - resolved "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz" - integrity sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ== + version "3.7.1" + resolved "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" + integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== js-string-escape@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz" + resolved "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-tokens@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg== js-yaml@^3.13.1, js-yaml@^3.14.0, js-yaml@^3.2.5, js-yaml@^3.2.7: version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -10219,14 +10433,14 @@ js-yaml@^3.13.1, js-yaml@^3.14.0, js-yaml@^3.2.5, js-yaml@^3.2.7: js-yaml@^4.0.0: version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" jsdom@^16.4.0: version "16.7.0" - resolved "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: abab "^2.0.5" @@ -10259,90 +10473,98 @@ jsdom@^16.4.0: jsesc@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" integrity sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA== jsesc@^2.5.0, jsesc@^2.5.1: version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== jsesc@~0.3.x: version "0.3.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.3.0.tgz" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.3.0.tgz#1bf5ee63b4539fe2e26d0c1e99c240b97a457972" integrity sha512-UHQmAeTXV+iwEk0aHheJRqo6Or90eDxI6KIYpHSjKLXKuKlPt1CQ7tGBerFcFA8uKU5mYxiPMlckmFptd5XZzA== jsesc@~0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" + resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz" - integrity sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g== + version "1.1.1" + resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz#52d4361b47d49168bcc4e564189a42e5a7439454" + integrity sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg== dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" jsonify "^0.0.1" + object-keys "^1.1.1" json5@^0.5.1: version "0.5.1" - resolved "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz" + resolved "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw== -json5@^1.0.1: +json5@^1.0.1, json5@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.2: +json5@^2.1.2, json5@^2.2.3: version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^2.1.0: version "2.4.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== optionalDependencies: graceful-fs "^4.1.6" jsonfile@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== optionalDependencies: graceful-fs "^4.1.6" jsonfile@^6.0.1: version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: universalify "^2.0.0" @@ -10351,12 +10573,12 @@ jsonfile@^6.0.1: jsonify@^0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz" + resolved "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== jsonlint@^1.6.3: version "1.6.3" - resolved "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.3.tgz" + resolved "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.3.tgz#cb5e31efc0b78291d0d862fbef05900adf212988" integrity sha512-jMVTMzP+7gU/IyC6hvKyWpUU8tmTkK5b3BPNuMI9U8Sit+YAWLlZwB6Y6YrdCxfg2kNz05p3XY3Bmm4m26Nv3A== dependencies: JSV "^4.0.x" @@ -10364,43 +10586,45 @@ jsonlint@^1.6.3: just-extend@^4.0.2: version "4.2.1" - resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz" + resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: +kind-of@^6.0.2: version "6.0.3" - resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== layout-bin-packer@^1.4.0: version "1.5.0" - resolved "https://registry.npmjs.org/layout-bin-packer/-/layout-bin-packer-1.5.0.tgz" + resolved "https://registry.npmjs.org/layout-bin-packer/-/layout-bin-packer-1.5.0.tgz#2e950456083621fe01f82007d896294f5e31e89c" integrity sha512-i0jmMwhB9SfPNoiMgZrjUiZoGY8TJzVrRAWuGnspEv4JJmULLEbAZ8VUwF9H9ITk2kzYR+tX5i1v/CMtxgpm4A== dependencies: ember-cli-babel "^6.8.2" leek@0.0.24: version "0.0.24" - resolved "https://registry.npmjs.org/leek/-/leek-0.0.24.tgz" + resolved "https://registry.npmjs.org/leek/-/leek-0.0.24.tgz#e400e57f0e60d8ef2bd4d068dc428a54345dbcda" integrity sha512-6PVFIYXxlYF0o6hrAsHtGpTmi06otkwNrMcmQ0K96SeSRHPREPa9J3nJZ1frliVH7XT0XFswoJFQoXsDukzGNQ== dependencies: debug "^2.1.0" @@ -10409,23 +10633,15 @@ leek@0.0.24: levn@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - license-checker@^25.0.1: version "25.0.1" - resolved "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz" + resolved "https://registry.npmjs.org/license-checker/-/license-checker-25.0.1.tgz#4d14504478a5240a857bb3c21cd0491a00d761fa" integrity sha512-mET5AIwl7MR2IAKYYoVBBpV0OnkKQ1xGj2IMMeEFIs42QAkEVjRtFZGWmQ28WeU7MP779iAgOaOy93Mn44mn6g== dependencies: chalk "^2.4.1" @@ -10439,14 +10655,19 @@ license-checker@^25.0.1: spdx-satisfies "^4.0.0" treeify "^1.1.0" -lilconfig@^2.0.5, lilconfig@^2.0.6: +lilconfig@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== +lilconfig@^3.0.0: + version "3.1.2" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb" + integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow== + line-column@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz" + resolved "https://registry.npmjs.org/line-column/-/line-column-1.0.2.tgz#d25af2936b6f4849172b312e4792d1d987bc34a2" integrity sha512-Ktrjk5noGYlHsVnYWh62FLVs4hTb8A3e+vucNZMgPeAOITdshMSgv4cCZQeRDjm7+goqmo6+liZwTXo+U3sVww== dependencies: isarray "^1.0.0" @@ -10454,26 +10675,26 @@ line-column@^1.0.2: lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== linkify-it@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz" + resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== dependencies: uc.micro "^1.0.1" linkify-it@^3.0.1: version "3.0.3" - resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz" + resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== dependencies: uc.micro "^1.0.1" lint-staged@^10.2.11: version "10.5.4" - resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665" integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== dependencies: chalk "^4.1.0" @@ -10494,7 +10715,7 @@ lint-staged@^10.2.11: listr2@^3.2.2: version "3.14.0" - resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz" + resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== dependencies: cli-truncate "^2.1.0" @@ -10508,12 +10729,12 @@ listr2@^3.2.2: livereload-js@^3.3.1: version "3.4.1" - resolved "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz" + resolved "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz#ba90fbc708ed1b9a024bb89c4ee12c96ea03d66f" integrity sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g== load-json-file@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz" + resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== dependencies: graceful-fs "^4.1.2" @@ -10523,17 +10744,17 @@ load-json-file@^4.0.0: loader-runner@^2.4.0: version "2.4.0" - resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== loader-runner@^4.2.0: version "4.3.0" - resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^1.2.3: version "1.4.2" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== dependencies: big.js "^5.2.2" @@ -10542,7 +10763,7 @@ loader-utils@^1.2.3: loader-utils@^2.0.0: version "2.0.4" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" @@ -10551,17 +10772,17 @@ loader-utils@^2.0.0: loader.js@^4.7.0: version "4.7.0" - resolved "https://registry.npmjs.org/loader.js/-/loader.js-4.7.0.tgz" + resolved "https://registry.npmjs.org/loader.js/-/loader.js-4.7.0.tgz#a1a52902001c83631efde9688b8ab3799325ef1f" integrity sha512-9M2KvGT6duzGMgkOcTkWb+PR/Q2Oe54df/tLgHGVmFpAmtqJ553xJh6N63iFYI2yjo2PeJXbS5skHi/QpJq4vA== locale-emoji@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/locale-emoji/-/locale-emoji-0.3.0.tgz" + resolved "https://registry.npmjs.org/locale-emoji/-/locale-emoji-0.3.0.tgz#7f38262f7c877bd27659725570335b263f88742a" integrity sha512-JGm8+naU49CBDnH1jksS3LecPdfWQLxFgkLN6ZhYONKa850pJ0Xt8DPGJnYK0ZuJI8jTuiDDPCDtSL3nyacXwg== locate-path@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== dependencies: p-locate "^2.0.0" @@ -10569,7 +10790,7 @@ locate-path@^2.0.0: locate-path@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: p-locate "^3.0.0" @@ -10577,21 +10798,21 @@ locate-path@^3.0.0: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash._baseassign@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz" + resolved "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" integrity sha512-t3N26QR2IdSN+gqSy9Ds9pBu/J1EAFEshKlUHpJG3rvyJOYgcELIxcIeKKfZk7sjOz11cFfzJRsyFry/JyabJQ== dependencies: lodash._basecopy "^3.0.0" @@ -10599,12 +10820,12 @@ lodash._baseassign@^3.0.0: lodash._basecopy@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz" + resolved "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" integrity sha512-rFR6Vpm4HeCK1WPGvjZSJ+7yik8d8PVUdCJx5rT2pogG4Ve/2ZS7kfmO5l5T2o5V2mqlNIfSF5MZlr1+xOoYQQ== lodash._baseflatten@^3.0.0: version "3.1.4" - resolved "https://registry.npmjs.org/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz" + resolved "https://registry.npmjs.org/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz#0770ff80131af6e34f3b511796a7ba5214e65ff7" integrity sha512-fESngZd+X4k+GbTxdMutf8ohQa0s3sJEHIcwtu4/LsIQ2JTDzdRxDCMQjW+ezzwRitLmHnacVVmosCbxifefbw== dependencies: lodash.isarguments "^3.0.0" @@ -10612,12 +10833,12 @@ lodash._baseflatten@^3.0.0: lodash._bindcallback@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz" + resolved "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== lodash._createassigner@^3.0.0: version "3.1.1" - resolved "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz" + resolved "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" integrity sha512-LziVL7IDnJjQeeV95Wvhw6G28Z8Q6da87LWKOPWmzBLv4u6FAT/x5v00pyGW0u38UoogNF2JnD3bGgZZDaNEBw== dependencies: lodash._bindcallback "^3.0.0" @@ -10626,22 +10847,22 @@ lodash._createassigner@^3.0.0: lodash._getnative@^3.0.0: version "3.9.1" - resolved "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" + resolved "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== lodash._isiterateecall@^3.0.0: version "3.0.9" - resolved "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" + resolved "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" integrity sha512-De+ZbrMu6eThFti/CSzhRvTKMgQToLxbij58LMfM8JnYDNSOjkjTCIaa8ixglOeGh2nyPlakbt5bJWJ7gvpYlQ== lodash._reinterpolate@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" + resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== lodash.assign@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz" + resolved "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" integrity sha512-/VVxzgGBmbphasTg51FrztxQJ/VgAUpol6zmJuSVSGcNg4g7FA4z7rQV8Ovr9V3vFBNWZhvKWHfpAytjTVUfFA== dependencies: lodash._baseassign "^3.0.0" @@ -10650,49 +10871,49 @@ lodash.assign@^3.2.0: lodash.assignin@^4.1.0: version "4.2.0" - resolved "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz" + resolved "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" integrity sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg== lodash.castarray@^4.4.0: version "4.4.0" - resolved "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz" + resolved "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== lodash.clonedeep@^4.4.1: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" + resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== lodash.debounce@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz#812211c378a94cc29d5aa4e3346cf0bfce3a7df5" integrity sha512-lcmJwMpdPAtChA4hfiwxTtgFeNAaow701wWUgVUqeD0XJF7vMXIN+bu/2FJSGxT0NUbZy9g9VFrlOFfPjl+0Ew== dependencies: lodash._getnative "^3.0.0" lodash.debounce@^4.0.8: version "4.0.8" - resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz" + resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== lodash.defaults@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz" + resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== lodash.defaultsdeep@^4.6.1: version "4.6.1" - resolved "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz" + resolved "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== lodash.find@^4.5.1: version "4.6.0" - resolved "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz" + resolved "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" integrity sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg== lodash.flatten@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-3.0.2.tgz" + resolved "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-3.0.2.tgz#de1cf57758f8f4479319d35c3e9cc60c4501938c" integrity sha512-jCXLoNcqQRbnT/KWZq2fIREHWeczrzpTR0vsycm96l/pu5hGeAntVBG0t7GuM/2wFqmnZs3d1eGptnAH2E8+xQ== dependencies: lodash._baseflatten "^3.0.0" @@ -10700,37 +10921,37 @@ lodash.flatten@^3.0.2: lodash.foreach@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz" + resolved "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" integrity sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ== lodash.get@^4.4.2: version "4.4.2" - resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" + resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== lodash.isarguments@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz" + resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== lodash.isarray@^3.0.0: version "3.0.4" - resolved "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" + resolved "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" integrity sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ== -lodash.iteratee@^4.5.0: +lodash.iteratee@^4.7.0: version "4.7.0" - resolved "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz" + resolved "https://registry.npmjs.org/lodash.iteratee/-/lodash.iteratee-4.7.0.tgz#be4177db289a8ccc3c0990f1db26b5b22fc1554c" integrity sha512-yv3cSQZmfpbIKo4Yo45B1taEvxjNvcpF1CEOc0Y6dEyvhPIfEJE3twDwPgWTPQubcSgXyBwBKG6wpQvWMDOf6Q== lodash.kebabcase@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz" + resolved "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== lodash.keys@^3.0.0: version "3.1.2" - resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" + resolved "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" integrity sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ== dependencies: lodash._getnative "^3.0.0" @@ -10739,27 +10960,27 @@ lodash.keys@^3.0.0: lodash.last@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz" + resolved "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz#242f663112dd4c6e63728c60a3c909d1bdadbd4c" integrity sha512-14mq7rSkCxG4XMy9lF2FbIOqqgF0aH0NfPuQ3LPR3vIh0kHnUvIYP70dqa1Hf47zyXfQ8FzAg0MYOQeSuE1R7A== lodash.merge@^4.6.0, lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.omit@^4.1.0, lodash.omit@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz" + resolved "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg== lodash.restparam@^3.0.0: version "3.6.1" - resolved "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz" + resolved "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== lodash.template@^4.5.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz" + resolved "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== dependencies: lodash._reinterpolate "^3.0.0" @@ -10767,41 +10988,41 @@ lodash.template@^4.5.0: lodash.templatesettings@^4.0.0: version "4.2.0" - resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz" + resolved "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== dependencies: lodash._reinterpolate "^3.0.0" lodash.truncate@^4.4.2: version "4.4.2" - resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz" + resolved "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== lodash.uniq@^4.2.0: version "4.5.0" - resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" + resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== lodash.uniqby@^4.7.0: version "4.7.0" - resolved "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz" + resolved "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== lodash@^4.17.10, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.5.1, lodash@^4.7.0: version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== log-symbols@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== dependencies: chalk "^2.0.1" log-symbols@^4.0.0, log-symbols@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -10809,7 +11030,7 @@ log-symbols@^4.0.0, log-symbols@^4.1.0: log-update@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: ansi-escapes "^4.3.0" @@ -10819,47 +11040,47 @@ log-update@^4.0.0: longest-streak@^2.0.0: version "2.0.4" - resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz" + resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== loose-envify@^1.0.0: version "1.4.0" - resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lower-case@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" + resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== dependencies: tslib "^2.0.3" lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" magic-string@^0.25.7: version "0.25.9" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== dependencies: sourcemap-codec "^1.4.8" make-dir@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== dependencies: pify "^4.0.1" @@ -10867,33 +11088,40 @@ make-dir@^2.0.0: make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + makeerror@1.0.12: version "1.0.12" - resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: tmpl "1.0.5" map-cache@^0.2.2: version "0.2.2" - resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== map-visit@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== dependencies: object-visit "^1.0.0" markdown-it-terminal@0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/markdown-it-terminal/-/markdown-it-terminal-0.2.1.tgz" + resolved "https://registry.npmjs.org/markdown-it-terminal/-/markdown-it-terminal-0.2.1.tgz#670fd5ea824a7dcaa1591dcbeef28bf70aff1705" integrity sha512-e8hbK9L+IyFac2qY05R7paP+Fqw1T4pSQW3miK3VeG9QmpqBjg5Qzjv/v6C7YNxSNRS2Kp8hUFtm5lWU9eK4lw== dependencies: ansi-styles "^3.0.0" @@ -10904,7 +11132,7 @@ markdown-it-terminal@0.2.1: markdown-it@^12.0.4: version "12.3.2" - resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz" + resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== dependencies: argparse "^2.0.1" @@ -10915,7 +11143,7 @@ markdown-it@^12.0.4: markdown-it@^8.3.1: version "8.4.2" - resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz" + resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== dependencies: argparse "^1.0.7" @@ -10926,21 +11154,21 @@ markdown-it@^8.3.1: markdown-table@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz" + resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b" integrity sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A== dependencies: repeat-string "^1.0.0" matcher-collection@^1.0.0, matcher-collection@^1.1.1: version "1.1.2" - resolved "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.1.2.tgz" + resolved "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.1.2.tgz#1076f506f10ca85897b53d14ef54f90a5c426838" integrity sha512-YQ/teqaOIIfUHedRam08PB3NK7Mjct6BvzRnJmpGDm8uFXpNr1sbY4yuflI5JcEs6COpYA0FpRQhSDBf1tT95g== dependencies: minimatch "^3.0.2" matcher-collection@^2.0.0, matcher-collection@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz" + resolved "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz#90be1a4cf58d6f2949864f65bb3b0f3e41303b29" integrity sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ== dependencies: "@types/minimatch" "^3.0.3" @@ -10948,14 +11176,14 @@ matcher-collection@^2.0.0, matcher-collection@^2.0.1: md5-hex@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz" + resolved "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz#be3741b510591434b2784d79e556eefc2c9a8e5c" integrity sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw== dependencies: blueimp-md5 "^2.10.0" md5.js@^1.3.4: version "1.3.5" - resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz" + resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== dependencies: hash-base "^3.0.0" @@ -10964,21 +11192,21 @@ md5.js@^1.3.4: mdast-normalize-headings@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/mdast-normalize-headings/-/mdast-normalize-headings-2.0.0.tgz" + resolved "https://registry.npmjs.org/mdast-normalize-headings/-/mdast-normalize-headings-2.0.0.tgz#378c8161a9f57fcf52a6fd5628507af370c7f8c5" integrity sha512-PVuunQSsJNYiuZ56QypccTVPy8DowOkj61HtD78PSq1M8I49GwxzhdE2QmOp+j/TwaT1yq/K4b201388/ucV2g== dependencies: unist-util-visit "^2.0.0" mdast-util-definitions@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz" + resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== dependencies: unist-util-visit "^2.0.0" mdast-util-find-and-replace@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz" + resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz#b7db1e873f96f66588c321f1363069abf607d1b5" integrity sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA== dependencies: escape-string-regexp "^4.0.0" @@ -10987,7 +11215,7 @@ mdast-util-find-and-replace@^1.1.0: mdast-util-footnote@^0.1.0: version "0.1.7" - resolved "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz" + resolved "https://registry.npmjs.org/mdast-util-footnote/-/mdast-util-footnote-0.1.7.tgz#4b226caeab4613a3362c144c94af0fdd6f7e0ef0" integrity sha512-QxNdO8qSxqbO2e3m09KwDKfWiLgqyCurdWTQ198NpbZ2hxntdc+VKS4fDJCmNWbAroUdYnSthu+XbZ8ovh8C3w== dependencies: mdast-util-to-markdown "^0.6.0" @@ -10995,7 +11223,7 @@ mdast-util-footnote@^0.1.0: mdast-util-from-markdown@^0.8.0: version "0.8.5" - resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz" + resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== dependencies: "@types/mdast" "^3.0.0" @@ -11006,14 +11234,14 @@ mdast-util-from-markdown@^0.8.0: mdast-util-frontmatter@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz" + resolved "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-0.2.0.tgz#8bd5cd55e236c03e204a036f7372ebe9e6748240" integrity sha512-FHKL4w4S5fdt1KjJCwB0178WJ0evnyyQr5kXTM3wrOVpytD0hrkvd+AOOjU9Td8onOejCkmZ+HQRT3CZ3coHHQ== dependencies: micromark-extension-frontmatter "^0.2.0" mdast-util-gfm-autolink-literal@^0.1.0, mdast-util-gfm-autolink-literal@^0.1.3: version "0.1.3" - resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz" + resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz#9c4ff399c5ddd2ece40bd3b13e5447d84e385fb7" integrity sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A== dependencies: ccount "^1.0.0" @@ -11022,14 +11250,14 @@ mdast-util-gfm-autolink-literal@^0.1.0, mdast-util-gfm-autolink-literal@^0.1.3: mdast-util-gfm-strikethrough@^0.2.0: version "0.2.3" - resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz" + resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz#45eea337b7fff0755a291844fbea79996c322890" integrity sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA== dependencies: mdast-util-to-markdown "^0.6.0" mdast-util-gfm-table@^0.1.0: version "0.1.6" - resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz" + resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz#af05aeadc8e5ee004eeddfb324b2ad8c029b6ecf" integrity sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ== dependencies: markdown-table "^2.0.0" @@ -11037,14 +11265,14 @@ mdast-util-gfm-table@^0.1.0: mdast-util-gfm-task-list-item@^0.1.0: version "0.1.6" - resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz" + resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz#70c885e6b9f543ddd7e6b41f9703ee55b084af10" integrity sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A== dependencies: mdast-util-to-markdown "~0.6.0" mdast-util-gfm@^0.1.0: version "0.1.2" - resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz" + resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz#8ecddafe57d266540f6881f5c57ff19725bd351c" integrity sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ== dependencies: mdast-util-gfm-autolink-literal "^0.1.0" @@ -11055,7 +11283,7 @@ mdast-util-gfm@^0.1.0: mdast-util-to-hast@^10.2.0: version "10.2.0" - resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz" + resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz#61875526a017d8857b71abc9333942700b2d3604" integrity sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ== dependencies: "@types/mdast" "^3.0.0" @@ -11069,7 +11297,7 @@ mdast-util-to-hast@^10.2.0: mdast-util-to-markdown@^0.6.0, mdast-util-to-markdown@^0.6.1, mdast-util-to-markdown@~0.6.0: version "0.6.5" - resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz" + resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz#b33f67ca820d69e6cc527a93d4039249b504bebe" integrity sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ== dependencies: "@types/unist" "^2.0.0" @@ -11081,17 +11309,17 @@ mdast-util-to-markdown@^0.6.0, mdast-util-to-markdown@^0.6.1, mdast-util-to-mark mdast-util-to-string@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz" + resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== mdast-util-to-string@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz" + resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== mdast-util-toc@^5.1.0: version "5.1.0" - resolved "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-5.1.0.tgz" + resolved "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-5.1.0.tgz#3af0f9c9a764b993538af03f1f79f4e3cec22736" integrity sha512-csimbRIVkiqc+PpFeKDGQ/Ck2N4f9FYH3zzBMMJzcxoKL8m+cM0n94xXm0I9eaxHnKdY9n145SGTdyJC7i273g== dependencies: "@types/mdast" "^3.0.3" @@ -11104,22 +11332,22 @@ mdast-util-toc@^5.1.0: mdn-data@2.0.30: version "2.0.30" - resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz" + resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== mdurl@^1.0.0, mdurl@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" + resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== media-typer@0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== memory-fs@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz" + resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== dependencies: errno "^0.1.3" @@ -11127,7 +11355,7 @@ memory-fs@^0.4.1: memory-fs@^0.5.0: version "0.5.0" - resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz" + resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== dependencies: errno "^0.1.3" @@ -11135,36 +11363,36 @@ memory-fs@^0.5.0: memory-streams@^0.1.3: version "0.1.3" - resolved "https://registry.npmjs.org/memory-streams/-/memory-streams-0.1.3.tgz" + resolved "https://registry.npmjs.org/memory-streams/-/memory-streams-0.1.3.tgz#d9b0017b4b87f1d92f55f2745c9caacb1dc93ceb" integrity sha512-qVQ/CjkMyMInPaaRMrwWNDvf6boRZXaT/DbQeMYcCWuXPEBf1v8qChOc9OlEVQp2uOvRXa1Qu30fLmKhY6NipA== dependencies: readable-stream "~1.0.2" memorystream@^0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz" + resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== merge-descriptors@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== merge-options@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz" + resolved "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz#2a64b24457becd4e4dc608283247e94ce589aa32" integrity sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg== dependencies: is-plain-obj "^1.1" merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge-trees@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/merge-trees/-/merge-trees-1.0.1.tgz" + resolved "https://registry.npmjs.org/merge-trees/-/merge-trees-1.0.1.tgz#ccbe674569787f9def17fd46e6525f5700bbd23e" integrity sha512-O7TWwipLHhc9tErjq3WBvNP7I1g7Wgudl1ZkLqpT7F2MZy1yEdgnI9cpZZxBaqk+wJZu+2b9FE7D3ubUmGFHFA== dependencies: can-symlink "^1.0.0" @@ -11176,7 +11404,7 @@ merge-trees@^1.0.1: merge-trees@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/merge-trees/-/merge-trees-2.0.0.tgz" + resolved "https://registry.npmjs.org/merge-trees/-/merge-trees-2.0.0.tgz#a560d796e566c5d9b2c40472a2967cca48d85161" integrity sha512-5xBbmqYBalWqmhYm51XlohhkmVOua3VAUrrWh8t9iOkaLpS6ifqm/UVuUjQCeDVJ9Vx3g2l6ihfkbLSTeKsHbw== dependencies: fs-updater "^1.0.4" @@ -11184,69 +11412,69 @@ merge-trees@^2.0.0: merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== merge@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz" + resolved "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz#59ef4bf7e0b3e879186436e8481c06a6c162ca98" integrity sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w== methods@~1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== micromark-extension-footnote@^0.3.0: version "0.3.2" - resolved "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz" + resolved "https://registry.npmjs.org/micromark-extension-footnote/-/micromark-extension-footnote-0.3.2.tgz#129b74ef4920ce96719b2c06102ee7abb2b88a20" integrity sha512-gr/BeIxbIWQoUm02cIfK7mdMZ/fbroRpLsck4kvFtjbzP4yi+OPVbnukTc/zy0i7spC2xYE/dbX1Sur8BEDJsQ== dependencies: micromark "~2.11.0" micromark-extension-frontmatter@^0.2.0: version "0.2.2" - resolved "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz" + resolved "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-0.2.2.tgz#61b8e92e9213e1d3c13f5a59e7862f5ca98dfa53" integrity sha512-q6nPLFCMTLtfsctAuS0Xh4vaolxSFUWUWR6PZSrXXiRy+SANGllpcqdXFv2z07l0Xz/6Hl40hK0ffNCJPH2n1A== dependencies: fault "^1.0.0" micromark-extension-gfm-autolink-literal@~0.5.0: version "0.5.7" - resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz" + resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz#53866c1f0c7ef940ae7ca1f72c6faef8fed9f204" integrity sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw== dependencies: micromark "~2.11.3" micromark-extension-gfm-strikethrough@~0.6.5: version "0.6.5" - resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz" + resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz#96cb83356ff87bf31670eefb7ad7bba73e6514d1" integrity sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw== dependencies: micromark "~2.11.0" micromark-extension-gfm-table@~0.4.0: version "0.4.3" - resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz" + resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz#4d49f1ce0ca84996c853880b9446698947f1802b" integrity sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA== dependencies: micromark "~2.11.0" micromark-extension-gfm-tagfilter@~0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz" + resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz#d9f26a65adee984c9ccdd7e182220493562841ad" integrity sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q== micromark-extension-gfm-task-list-item@~0.3.0: version "0.3.3" - resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz" + resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz#d90c755f2533ed55a718129cee11257f136283b8" integrity sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ== dependencies: micromark "~2.11.0" micromark-extension-gfm@^0.3.0: version "0.3.3" - resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz" + resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz#36d1a4c089ca8bdfd978c9bd2bf1a0cb24e2acfe" integrity sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A== dependencies: micromark "~2.11.0" @@ -11258,7 +11486,7 @@ micromark-extension-gfm@^0.3.0: micromark@^2.11.3, micromark@~2.11.0, micromark@~2.11.3: version "2.11.4" - resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz" + resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== dependencies: debug "^4.0.0" @@ -11266,7 +11494,7 @@ micromark@^2.11.3, micromark@~2.11.0, micromark@~2.11.3: micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" @@ -11284,16 +11512,16 @@ micromatch@^3.1.10, micromatch@^3.1.4: to-regex "^3.0.2" micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.7" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5" + integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" miller-rabin@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz" + resolved "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== dependencies: bn.js "^4.0.0" @@ -11301,68 +11529,69 @@ miller-rabin@^4.0.0: mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.26, mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mime@1.6.0: version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^1.0.0: version "1.2.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mini-css-extract-plugin@^2.5.2: - version "2.7.3" - resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.3.tgz" - integrity sha512-CD9cXeKeXLcnMw8FZdtfrRrLaM7gwCl4nKuKn2YkY2Bw5wdlB8zU2cCzw+w2zS9RFvbrufTBkMCJACNPwqQA0w== + version "2.9.0" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz#c73a1327ccf466f69026ac22a8e8fd707b78a235" + integrity sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA== dependencies: schema-utils "^4.0.0" + tapable "^2.2.1" minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== minimalistic-crypto-utils@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" + resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimist@>=1.2.5, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.7: +minimist@>=1.2.5, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minimist@^0.2.1: version "0.2.4" - resolved "https://registry.npmjs.org/minimist/-/minimist-0.2.4.tgz" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.2.4.tgz#0085d5501e29033748a2f2a4da0180142697a475" integrity sha512-Pkrrm8NjyQ8yVt8Am9M+yUt74zE3iokhzbG1bFVNjLB92vwM71hf40RkEsryg98BujhVOncKm/C1xROxZ030LQ== minipass@^2.2.0: version "2.9.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz" + resolved "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" @@ -11370,7 +11599,7 @@ minipass@^2.2.0: mississippi@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz" + resolved "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== dependencies: concat-stream "^1.5.0" @@ -11386,7 +11615,7 @@ mississippi@^3.0.0: mixin-deep@^1.2.0: version "1.3.2" - resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" @@ -11394,31 +11623,48 @@ mixin-deep@^1.2.0: mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@^0.5.6: version "0.5.6" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" + integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== + mktemp@~0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz" + resolved "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz#6d0515611c8a8c84e484aa2000129b98e981ff0b" integrity sha512-IXnMcJ6ZyTuhRmJSjzvHSRhlVPiN9Jwc6e59V0bEJ0ba6OBeX2L0E+mRN1QseeOF4mM+F1Rit6Nh7o+rl2Yn/A== mnemonist@^0.38.0: version "0.38.5" - resolved "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz" + resolved "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== dependencies: obliterator "^2.0.0" +mock-property@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/mock-property/-/mock-property-1.0.3.tgz#3e37c50a56609d548cabd56559fde3dd8767b10c" + integrity sha512-2emPTb1reeLLYwHxyVx993iYyCHEiRRO+y8NFXFPL5kl5q14sgTK76cXyEKkeKCHeRw35SfdkUJ10Q1KfHuiIQ== + dependencies: + define-data-property "^1.1.1" + functions-have-names "^1.2.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + hasown "^2.0.0" + isarray "^2.0.5" + morgan@^1.10.0: version "1.10.0" - resolved "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz" + resolved "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== dependencies: basic-auth "~2.0.1" @@ -11429,12 +11675,12 @@ morgan@^1.10.0: mout@^1.0.0: version "1.2.4" - resolved "https://registry.npmjs.org/mout/-/mout-1.2.4.tgz" + resolved "https://registry.npmjs.org/mout/-/mout-1.2.4.tgz#9ffd261c4d6509e7ebcbf6b641a89b36ecdf8155" integrity sha512-mZb9uOruMWgn/fw28DG4/yE3Kehfk1zKCLhuDU2O3vlKdnBBr4XaOCqVTflJ5aODavGUPqFHZgrFX3NJVuxGhQ== move-concurrently@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz" + resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== dependencies: aproba "^1.1.1" @@ -11446,52 +11692,61 @@ move-concurrently@^1.0.1: ms@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.2, ms@^2.1.1: +ms@2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.1.1: version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== mustache@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz" + resolved "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== mute-stream@0.0.7: version "0.0.7" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ== mute-stream@0.0.8: version "0.0.8" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" + resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nan@^2.12.1: - version "2.17.0" - resolved "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== + version "2.20.0" + resolved "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3" + integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw== nanoassert@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz" + resolved "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz#4f3152e09540fde28c76f44b19bbcd1d5a42478d" integrity sha512-C40jQ3NzfkP53NsO8kEOFd79p4b9kDXQMwgiY1z8ZwrDZgUyom0AHwGegF4Dm99L+YoYhuaB0ceerUcXmqr1rQ== -nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== nanomatch@^1.2.9: version "1.2.13" - resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: arr-diff "^4.0.0" @@ -11508,39 +11763,39 @@ nanomatch@^1.2.9: natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@0.6.3: version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: +neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" - resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== ngraph.events@^1.2.1: version "1.2.2" - resolved "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz" + resolved "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz#3ceb92d676a04a4e7ce60a09fa8e17a4f0346d7f" integrity sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ== ngraph.graph@^19.1.0: version "19.1.0" - resolved "https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-19.1.0.tgz" + resolved "https://registry.npmjs.org/ngraph.graph/-/ngraph.graph-19.1.0.tgz#88910ed53f6b4bc374f1b67296f4f81aab814e24" integrity sha512-9cws84qfPkrYa7BaBtT+KgZfLXrd6pNL9Gl5Do+MBO/0Hm6rOM7qK78MZaO1uEoIK6p2pgUs6lu29zn/6tP59w== dependencies: ngraph.events "^1.2.1" nice-try@^1.0.4: version "1.0.5" - resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz" + resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== nise@^4.0.4: version "4.1.0" - resolved "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz" + resolved "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6" integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA== dependencies: "@sinonjs/commons" "^1.7.0" @@ -11551,7 +11806,7 @@ nise@^4.0.4: no-case@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz" + resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== dependencies: lower-case "^2.0.2" @@ -11559,26 +11814,26 @@ no-case@^3.0.4: node-dir@^0.1.17: version "0.1.17" - resolved "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz" + resolved "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== dependencies: minimatch "^3.0.2" node-fetch@^2.6.0: - version "2.6.9" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + version "2.7.0" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" node-int64@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== node-libs-browser@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz" + resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== dependencies: assert "^1.1.1" @@ -11607,12 +11862,12 @@ node-libs-browser@^2.2.1: node-modules-path@^1.0.0, node-modules-path@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/node-modules-path/-/node-modules-path-1.0.2.tgz" + resolved "https://registry.npmjs.org/node-modules-path/-/node-modules-path-1.0.2.tgz#e3acede9b7baf4bc336e3496b58e5b40d517056e" integrity sha512-6Gbjq+d7uhkO7epaKi5DNgUJn7H0gEyA4Jg0Mo1uQOi3Rk50G83LtmhhFyw0LxnAFhtlspkiiw52ISP13qzcBg== node-notifier@^10.0.0: version "10.0.1" - resolved "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz" + resolved "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.1.tgz#0e82014a15a8456c4cfcdb25858750399ae5f1c7" integrity sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ== dependencies: growly "^1.3.0" @@ -11622,19 +11877,19 @@ node-notifier@^10.0.0: uuid "^8.3.2" which "^2.0.2" -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== node-watch@0.7.3: version "0.7.3" - resolved "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz" + resolved "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz#6d4db88e39c8d09d3ea61d6568d80e5975abc7ab" integrity sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ== nomnom@^1.5.x: version "1.8.1" - resolved "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz" + resolved "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" integrity sha512-5s0JxqhDx9/rksG2BTMVN1enjWSvPidpoSgViZU4ZXULyTe+7jxcCRLB6f42Z0l1xYJpleCBtSyY6Lwg3uu5CQ== dependencies: chalk "~0.4.0" @@ -11642,14 +11897,14 @@ nomnom@^1.5.x: nopt@^3.0.6: version "3.0.6" - resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg== dependencies: abbrev "1" nopt@^4.0.1: version "4.0.3" - resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz" + resolved "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== dependencies: abbrev "1" @@ -11657,7 +11912,7 @@ nopt@^4.0.1: normalize-package-data@^2.0.0, normalize-package-data@^2.3.2: version "2.5.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== dependencies: hosted-git-info "^2.1.4" @@ -11667,34 +11922,34 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.3.2: normalize-path@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== dependencies: remove-trailing-separator "^1.0.1" normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-range@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== npm-git-info@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/npm-git-info/-/npm-git-info-1.0.3.tgz" + resolved "https://registry.npmjs.org/npm-git-info/-/npm-git-info-1.0.3.tgz#a933c42ec321e80d3646e0d6e844afe94630e1d5" integrity sha512-i5WBdj4F/ULl16z9ZhsJDMl1EQCMQhHZzBwNnKL2LOA+T8IHNeRkLCVz9uVV9SzUdGTbDq+1oXhIYMe+8148vw== npm-normalize-package-bin@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz" + resolved "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== npm-package-arg@^8.1.1: version "8.1.5" - resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz" + resolved "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== dependencies: hosted-git-info "^4.0.1" @@ -11703,7 +11958,7 @@ npm-package-arg@^8.1.1: npm-run-all@^4.1.5: version "4.1.5" - resolved "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz" + resolved "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== dependencies: ansi-styles "^3.2.1" @@ -11718,28 +11973,28 @@ npm-run-all@^4.1.5: npm-run-path@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== dependencies: path-key "^2.0.0" npm-run-path@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== dependencies: path-key "^3.0.0" npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" npmlog@^4.1.2: version "4.1.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" @@ -11749,7 +12004,7 @@ npmlog@^4.1.2: npmlog@^6.0.0: version "6.0.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== dependencies: are-we-there-yet "^3.0.0" @@ -11759,22 +12014,22 @@ npmlog@^6.0.0: number-is-nan@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== nwsapi@^2.2.0: - version "2.2.2" - resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== + version "2.2.10" + resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz#0b77a68e21a0b483db70b11fad055906e867cda8" + integrity sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ== -object-assign@4.1.1, object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@4.1.1, object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== object-copy@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== dependencies: copy-descriptor "^0.1.0" @@ -11783,133 +12038,121 @@ object-copy@^0.1.0: object-hash@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz" + resolved "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== object-hash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" + resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.12.2, object-inspect@^1.12.3, object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== -object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== +object-is@^1.1.5, object-is@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" + integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" + call-bind "^1.0.7" + define-properties "^1.2.1" object-keys@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== object-visit@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== dependencies: isobject "^3.0.0" -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== +object.assign@^4.1.4, object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" + call-bind "^1.0.5" + define-properties "^1.2.1" has-symbols "^1.0.3" object-keys "^1.1.1" object.pick@^1.3.0: version "1.3.0" - resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== dependencies: isobject "^3.0.1" obliterator@^2.0.0: version "2.0.4" - resolved "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz" + resolved "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== on-finished@2.4.1: version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" on-finished@~2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== dependencies: ee-first "1.1.1" on-headers@~1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz" + resolved "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ== dependencies: mimic-fn "^1.0.0" onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" opencollective-postinstall@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz" + resolved "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + version "0.9.4" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" + word-wrap "^1.2.5" ora@^3.4.0: version "3.4.0" - resolved "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz" + resolved "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== dependencies: chalk "^2.4.2" @@ -11921,7 +12164,7 @@ ora@^3.4.0: ora@^5.4.0: version "5.4.1" - resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" + resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== dependencies: bl "^4.1.0" @@ -11936,22 +12179,22 @@ ora@^5.4.0: os-browserify@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz" + resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== os-homedir@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" + resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" + resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== osenv@^0.1.3, osenv@^0.1.4: version "0.1.5" - resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz" + resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" @@ -11959,107 +12202,107 @@ osenv@^0.1.3, osenv@^0.1.4: p-defer@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz" + resolved "https://registry.npmjs.org/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83" integrity sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw== p-event@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz" + resolved "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== dependencies: p-timeout "^2.0.1" p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-finally@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== p-limit@^1.1.0: version "1.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== dependencies: p-limit "^1.1.0" p-locate@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: p-limit "^2.0.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-map@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-timeout@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz" + resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== dependencies: p-finally "^1.0.0" p-try@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz" + resolved "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== p-try@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: version "1.0.11" - resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz" + resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parallel-transform@^1.1.0: version "1.2.0" - resolved "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz" + resolved "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== dependencies: cyclist "^1.0.1" @@ -12068,30 +12311,31 @@ parallel-transform@^1.1.0: parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0, parse-asn1@^5.1.5: - version "5.1.6" - resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz" - integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== +parse-asn1@^5.0.0, parse-asn1@^5.1.7: + version "5.1.7" + resolved "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz#73cdaaa822125f9647165625eb45f8a051d2df06" + integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg== dependencies: - asn1.js "^5.2.0" - browserify-aes "^1.0.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" + asn1.js "^4.10.1" + browserify-aes "^1.2.0" + evp_bytestokey "^1.0.3" + hash-base "~3.0" + pbkdf2 "^3.1.2" + safe-buffer "^5.2.1" parse-duration@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/parse-duration/-/parse-duration-1.0.3.tgz" - integrity sha512-o6NAh12na5VvR6nFejkU0gpQ8jmOY9Y9sTU2ke3L3G/d/3z8jqmbBbeyBGHU73P4JLXfc7tJARygIK3WGIkloA== + version "1.1.0" + resolved "https://registry.npmjs.org/parse-duration/-/parse-duration-1.1.0.tgz#5192084c5d8f2a3fd676d04a451dbd2e05a1819c" + integrity sha512-z6t9dvSJYaPoQq7quMzdEagSFtpGu+utzHqqxmpVWNNZRIXnvqyCvn9XsTdh7c/w0Bqmdz3RB3YnRaKtpRtEXQ== parse-entities@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== dependencies: character-entities "^1.0.0" @@ -12103,7 +12347,7 @@ parse-entities@^2.0.0: parse-json@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== dependencies: error-ex "^1.3.1" @@ -12111,7 +12355,7 @@ parse-json@^4.0.0: parse-json@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -12121,118 +12365,118 @@ parse-json@^5.0.0: parse-ms@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz" + resolved "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== parse-passwd@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz" + resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== parse-static-imports@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/parse-static-imports/-/parse-static-imports-1.1.0.tgz" + resolved "https://registry.npmjs.org/parse-static-imports/-/parse-static-imports-1.1.0.tgz#ae2f18f18da1a993080ae406a5219455c0bbad5d" integrity sha512-HlxrZcISCblEV0lzXmAHheH/8qEkKgmqkdxyHTPbSqsTUV8GzqmN1L+SSti+VbNPfbBO3bYLPHDiUs2avbAdbA== parse5@6.0.1, parse5@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" + resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parseurl@~1.3.3: version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== pascalcase@^0.1.1: version "0.1.1" - resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== path-browserify@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== path-dirname@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz" + resolved "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== path-exists@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@1.0.1, path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-posix@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz" + resolved "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz#06b26113f56beab042545a23bfa88003ccac260f" integrity sha512-1gJ0WpNIiYcQydgg3Ed8KzvIqTsDpNwq+cjBCssvBtuTWjEqY1AW+i+OepiEMqDCzyro9B2sLAe4RBPajMYFiA== path-root-regex@^0.1.0: version "0.1.2" - resolved "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz" + resolved "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" integrity sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ== path-root@^0.1.1: version "0.1.1" - resolved "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz" + resolved "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" integrity sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg== dependencies: path-root-regex "^0.1.0" path-to-regexp@0.1.7: version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== path-to-regexp@^1.7.0: version "1.8.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== dependencies: isarray "0.0.1" path-type@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz" + resolved "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: pify "^3.0.0" path-type@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pbkdf2@^3.0.3: +pbkdf2@^3.0.3, pbkdf2@^3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz" + resolved "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" @@ -12241,93 +12485,98 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.0, picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pidtree@^0.3.0: version "0.3.1" - resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz" + resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== pify@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== pify@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== pify@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== pinkie-promise@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" + resolved "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" - resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" + resolved "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + pkg-dir@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== dependencies: find-up "^3.0.0" pkg-dir@^4.1.0: version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" pkg-dir@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== dependencies: find-up "^5.0.0" pkg-up@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" integrity sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg== dependencies: find-up "^2.1.0" pkg-up@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz" + resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== dependencies: find-up "^3.0.0" please-upgrade-node@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz" + resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" portfinder@^1.0.28: version "1.0.32" - resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz" + resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81" integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== dependencies: async "^2.6.4" @@ -12336,103 +12585,103 @@ portfinder@^1.0.28: posix-character-classes@^0.1.0: version "0.1.1" - resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== -postcss-import@^14.1.0: - version "14.1.0" - resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz" - integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== dependencies: postcss-value-parser "^4.0.0" read-cache "^1.0.0" resolve "^1.1.7" -postcss-js@^4.0.0: +postcss-js@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" + resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== dependencies: camelcase-css "^2.0.1" -postcss-load-config@^3.1.4: - version "3.1.4" - resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz" - integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== +postcss-load-config@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3" + integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== dependencies: - lilconfig "^2.0.5" - yaml "^1.10.2" + lilconfig "^3.0.0" + yaml "^2.3.4" postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + version "3.1.0" + resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + version "4.0.5" + resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" + integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + version "3.2.0" + resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" + integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== dependencies: postcss-selector-parser "^6.0.4" postcss-modules-values@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz" + resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== dependencies: icss-utils "^5.0.0" -postcss-nested@6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz" - integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== dependencies: - postcss-selector-parser "^6.0.10" + postcss-selector-parser "^6.0.11" -postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.11" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz" - integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.1.0" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz#49694cb4e7c649299fea510a29fa6577104bcf53" + integrity sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.9, postcss@^8.1.4, postcss@^8.2.15: - version "8.4.31" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== +postcss@^8.1.4, postcss@^8.2.15, postcss@^8.4.23: + version "8.4.39" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz#aa3c94998b61d3a9c259efa51db4b392e1bde0e3" + integrity sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw== dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" + nanoid "^3.3.7" + picocolors "^1.0.1" + source-map-js "^1.2.0" prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - pretender@^3.2.0: version "3.4.7" - resolved "https://registry.npmjs.org/pretender/-/pretender-3.4.7.tgz" + resolved "https://registry.npmjs.org/pretender/-/pretender-3.4.7.tgz#34a2ae2d1fc9db440a990d50e6c0f5481d8755fc" integrity sha512-jkPAvt1BfRi0RKamweJdEcnjkeu7Es8yix3bJ+KgBC5VpG/Ln4JE3hYN6vJym4qprm8Xo5adhWpm3HCoft1dOw== dependencies: fake-xml-http-request "^2.1.2" @@ -12440,92 +12689,97 @@ pretender@^3.2.0: prettier-linter-helpers@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" + resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== dependencies: fast-diff "^1.1.2" prettier@^2.5.1: - version "2.8.4" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz" - integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== + version "2.8.8" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== pretty-ms@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz" + resolved "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8" integrity sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q== dependencies: parse-ms "^2.1.0" printf@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/printf/-/printf-0.6.1.tgz" + resolved "https://registry.npmjs.org/printf/-/printf-0.6.1.tgz#b9afa3d3b55b7f2e8b1715272479fc756ed88650" integrity sha512-is0ctgGdPJ5951KulgfzvHGwJtZ5ck8l042vRkV6jrkpBzTmb/lueTqguWHy2JfVA+RY6gFVlaZgUS0j7S/dsw== +prismjs@^1.29.0: + version "1.29.0" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + prismjs@~1.27.0: version "1.27.0" - resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== private@^0.1.6, private@^0.1.8: version "0.1.8" - resolved "https://registry.npmjs.org/private/-/private-0.1.8.tgz" + resolved "https://registry.npmjs.org/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process-relative-require@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/process-relative-require/-/process-relative-require-1.0.0.tgz" + resolved "https://registry.npmjs.org/process-relative-require/-/process-relative-require-1.0.0.tgz#1590dfcf5b8f2983ba53e398446b68240b4cc68a" integrity sha512-r8G5WJPozMJAiv8sDdVWKgJ4In/zBXqwJdMCGAXQt2Kd3HdbAuJVzWYM4JW150hWoaI9DjhtbjcsCCHIMxm8RA== dependencies: node-modules-path "^1.0.0" process@^0.11.10: version "0.11.10" - resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== progress@^2.0.0: version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== promise-inflight@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" + resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== promise-map-series@^0.2.1: version "0.2.3" - resolved "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.2.3.tgz" + resolved "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.2.3.tgz#c2d377afc93253f6bd03dbb77755eb88ab20a847" integrity sha512-wx9Chrutvqu1N/NHzTayZjE1BgIwt6SJykQoCOic4IZ9yUDjKyVYrpLa/4YCNsV61eRENfs29hrEquVuB13Zlw== dependencies: rsvp "^3.0.14" promise-map-series@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz" + resolved "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz#41873ca3652bb7a042b387d538552da9b576f8a1" integrity sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA== promise.hash.helper@^1.0.7: version "1.0.8" - resolved "https://registry.npmjs.org/promise.hash.helper/-/promise.hash.helper-1.0.8.tgz" + resolved "https://registry.npmjs.org/promise.hash.helper/-/promise.hash.helper-1.0.8.tgz#8c5fa0570f6f96821f52364fd72292b2c5a114f7" integrity sha512-KYcnXctWUWyVD3W3Ye0ZDuA1N8Szrh85cVCxpG6xYrOk/0CttRtYCmU30nWsUch0NuExQQ63QXvzRE6FLimZmg== property-information@^5.0.0: version "5.6.0" - resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz" + resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== dependencies: xtend "^4.0.0" proxy-addr@~2.0.7: version "2.0.7" - resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: forwarded "0.2.0" @@ -12533,17 +12787,17 @@ proxy-addr@~2.0.7: prr@~1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== psl@^1.1.33: version "1.9.0" - resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" + resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== public-encrypt@^4.0.0: version "4.0.3" - resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz" + resolved "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: bn.js "^4.1.0" @@ -12555,7 +12809,7 @@ public-encrypt@^4.0.0: pump@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz" + resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== dependencies: end-of-stream "^1.1.0" @@ -12563,7 +12817,7 @@ pump@^2.0.0: pump@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -12571,63 +12825,55 @@ pump@^3.0.0: pumpify@^1.3.3: version "1.5.1" - resolved "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz" + resolved "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== dependencies: duplexify "^3.6.0" inherits "^2.0.3" pump "^2.0.0" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== - -punycode@^1.2.4: +punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" + resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== punycode@^2.1.0, punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -qs@6.11.0, qs@^6.4.0: +qs@6.11.0: version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" +qs@^6.11.2, qs@^6.4.0: + version "6.12.2" + resolved "https://registry.npmjs.org/qs/-/qs-6.12.2.tgz#5443b587f3bf73ac68968de491e5b25bafe04478" + integrity sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg== + dependencies: + side-channel "^1.0.6" + querystring-es3@^0.2.0: version "0.2.1" - resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz" + resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - querystringify@^2.1.1: version "2.2.0" - resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - quick-temp@^0.1.2, quick-temp@^0.1.3, quick-temp@^0.1.5, quick-temp@^0.1.8: version "0.1.8" - resolved "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz" + resolved "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz#bab02a242ab8fb0dd758a3c9776b32f9a5d94408" integrity sha512-YsmIFfD9j2zaFwJkzI6eMG7y0lQP7YeWzgtFgNl38pGWZBSXJooZbOWwkcRot7Vt0Fg9L23pX0tqWU3VvLDsiA== dependencies: mktemp "~0.4.0" @@ -12636,7 +12882,7 @@ quick-temp@^0.1.2, quick-temp@^0.1.3, quick-temp@^0.1.5, quick-temp@^0.1.8: qunit-dom@^1.6.0: version "1.6.0" - resolved "https://registry.npmjs.org/qunit-dom/-/qunit-dom-1.6.0.tgz" + resolved "https://registry.npmjs.org/qunit-dom/-/qunit-dom-1.6.0.tgz#a4bea6a46329d221e4a317d712cb40709107b977" integrity sha512-YwSqcLjQcRI0fUFpaSWwU10KIJPFW5Qh+d3cT5DOgx81dypRuUSiPkKFmBY/CDs/R1KdHRadthkcXg2rqAon8Q== dependencies: broccoli-funnel "^3.0.3" @@ -12645,9 +12891,9 @@ qunit-dom@^1.6.0: ember-cli-version-checker "^5.1.1" qunit@^2.16.0, qunit@^2.17.2: - version "2.19.4" - resolved "https://registry.npmjs.org/qunit/-/qunit-2.19.4.tgz" - integrity sha512-aqUzzUeCqlleWYKlpgfdHHw9C6KxkB9H3wNfiBg5yHqQMzy0xw/pbCRHYFkjl8MsP/t8qkTQE+JTYL71azgiew== + version "2.21.0" + resolved "https://registry.npmjs.org/qunit/-/qunit-2.21.0.tgz#c3d35adb1c9df8176459665f2daf33170c0f8662" + integrity sha512-kJJ+uzx5xDWk0oRrbOZ3zsm+imPULE58ZMIrNl+3POZl4a1k6VXj2E4OiqTmZ9j6hh9egE3kNgnAti9Q+BG6Yw== dependencies: commander "7.2.0" node-watch "0.7.3" @@ -12655,14 +12901,14 @@ qunit@^2.16.0, qunit@^2.17.2: randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" randomfill@^1.0.3: version "1.0.4" - resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz" + resolved "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== dependencies: randombytes "^2.0.5" @@ -12670,22 +12916,12 @@ randomfill@^1.0.3: range-parser@~1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - raw-body@2.5.2: version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" @@ -12695,7 +12931,7 @@ raw-body@2.5.2: raw-body@~1.1.0: version "1.1.7" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425" integrity sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg== dependencies: bytes "1" @@ -12703,19 +12939,19 @@ raw-body@~1.1.0: react-is@^17.0.1: version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== read-cache@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" + resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== dependencies: pify "^2.3.0" read-installed@~4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz" + resolved "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" integrity sha512-O03wg/IYuV/VtnK2h/KXEt9VIbMUFbk3ERG0Iu4FhLZw0EP0T9znqrYDGn6ncbEsXUFaUjiVAWXHzxwt3lhRPQ== dependencies: debuglog "^1.0.1" @@ -12729,7 +12965,7 @@ read-installed@~4.0.3: read-package-json@^2.0.0: version "2.1.2" - resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz" + resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== dependencies: glob "^7.1.1" @@ -12739,35 +12975,16 @@ read-package-json@^2.0.0: read-pkg@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== dependencies: load-json-file "^4.0.0" normalize-package-data "^2.3.2" path-type "^3.0.0" -"readable-stream@1 || 2", readable-stream@~1.0.2: - version "1.0.34" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" - integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -"readable-stream@2 || 3", readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@^2.3.8, readable-stream@~2.3.6: version "2.3.8" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" @@ -12778,9 +12995,28 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +"readable-stream@2 || 3", readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.0.2: + version "1.0.34" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdir-scoped-modules@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz" + resolved "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== dependencies: debuglog "^1.0.1" @@ -12790,7 +13026,7 @@ readdir-scoped-modules@^1.0.0: readdirp@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: graceful-fs "^4.1.11" @@ -12799,14 +13035,14 @@ readdirp@^2.2.1: readdirp@~3.6.0: version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" recast@^0.18.1: version "0.18.10" - resolved "https://registry.npmjs.org/recast/-/recast-0.18.10.tgz" + resolved "https://registry.npmjs.org/recast/-/recast-0.18.10.tgz#605ebbe621511eb89b6356a7e224bff66ed91478" integrity sha512-XNvYvkfdAN9QewbrxeTOjgINkdY/odTgTS56ZNEWL9Ml0weT4T3sFtvnTuF+Gxyu46ANcRm1ntrF6F5LAJPAaQ== dependencies: ast-types "0.13.3" @@ -12816,19 +13052,19 @@ recast@^0.18.1: recursive-readdir-sync@^1.0.6: version "1.0.6" - resolved "https://registry.npmjs.org/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz" + resolved "https://registry.npmjs.org/recursive-readdir-sync/-/recursive-readdir-sync-1.0.6.tgz#1dbf6d32f3c5bb8d3cde97a6c588d547a9e13d56" integrity sha512-QhkBh/V7T3L2m8FrwZEZ/VnSZU35bv7DSy/VlKVfcq10zvwwuxeuDLH7DZYFGHFyXefHchZmsHFLELR7poGjog== redeyed@~1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz" + resolved "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz#e96c193b40c0816b00aec842698e61185e55498a" integrity sha512-8eEWsNCkV2rvwKLS1Cvp5agNjMhwRe2um+y32B2+3LqOzg4C9BBPs6vzAfV16Ivb8B9HPNKIqd8OrdBws8kNlQ== dependencies: esprima "~3.0.0" refractor@^3.5.0: version "3.6.0" - resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz" + resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== dependencies: hastscript "^6.0.0" @@ -12836,83 +13072,84 @@ refractor@^3.5.0: prismjs "~1.27.0" regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz" - integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + version "10.1.1" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== dependencies: regenerate "^1.4.2" regenerate@^1.2.1, regenerate@^1.4.2: version "1.4.2" - resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.10.5: version "0.10.5" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" integrity sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w== regenerator-runtime@^0.11.0: version "0.11.1" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== regenerator-runtime@^0.13.4: version "0.13.11" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + version "0.14.1" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== regenerator-runtime@^0.9.5: version "0.9.6" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" integrity sha512-D0Y/JJ4VhusyMOd/o25a3jdUqN/bC85EFsaoL9Oqmy/O4efCh+xhp7yj2EEOsj974qvMkcW8AwUzJ1jB/MbxCw== regenerator-transform@^0.10.0: version "0.10.1" - resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== dependencies: babel-runtime "^6.18.0" babel-types "^6.19.0" private "^0.1.6" -regenerator-transform@^0.15.1: - version "0.15.1" - resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz" - integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== dependencies: "@babel/runtime" "^7.8.4" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" regexpp@^3.0.0, regexpp@^3.1.0: version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== regexpu-core@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" integrity sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ== dependencies: regenerate "^1.2.1" @@ -12921,7 +13158,7 @@ regexpu-core@^2.0.0: regexpu-core@^5.3.1: version "5.3.2" - resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== dependencies: "@babel/regjsgen" "^0.8.0" @@ -12933,33 +13170,33 @@ regexpu-core@^5.3.1: regjsgen@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" integrity sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g== regjsparser@^0.1.4: version "0.1.5" - resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" integrity sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw== dependencies: jsesc "~0.5.0" regjsparser@^0.9.1: version "0.9.1" - resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== dependencies: jsesc "~0.5.0" rehype-stringify@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-8.0.0.tgz" + resolved "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-8.0.0.tgz#9b6afb599bcf3165f10f93fc8548f9a03d2ec2ba" integrity sha512-VkIs18G0pj2xklyllrPSvdShAV36Ff3yE5PUO9u36f6+2qJFnn22Z5gKwBOwgXviux4UC7K+/j13AnZfPICi/g== dependencies: hast-util-to-html "^7.1.1" remark-autolink-headings@^6.0.1: version "6.1.0" - resolved "https://registry.npmjs.org/remark-autolink-headings/-/remark-autolink-headings-6.1.0.tgz" + resolved "https://registry.npmjs.org/remark-autolink-headings/-/remark-autolink-headings-6.1.0.tgz#45fa1f8860e0fc6b78bcbc4b0f5d5dd696170e04" integrity sha512-oeMSIfjaNboWPDVKahQAjF8iJ8hsz5aI8KFzAmmBdznir7zBvkgUjYE/BrpWvd02DCf/mSQ1IklznLkl3dVvZQ== dependencies: "@types/hast" "^2.0.0" @@ -12969,12 +13206,12 @@ remark-autolink-headings@^6.0.1: remark-extract-frontmatter@^3.1.0: version "3.2.0" - resolved "https://registry.npmjs.org/remark-extract-frontmatter/-/remark-extract-frontmatter-3.2.0.tgz" + resolved "https://registry.npmjs.org/remark-extract-frontmatter/-/remark-extract-frontmatter-3.2.0.tgz#bab57f599114f233702dea819431eec28e708656" integrity sha512-PmYwNCo0cMAUV3oAGg5Hn6YSZgiSDwVdxLJmPIZ804aYuvE5mAzozo5AkO0C8ELroWrtN/f9zzb0jqFPBkMnwg== remark-footnotes@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz" + resolved "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-3.0.0.tgz#5756b56f8464fa7ed80dbba0c966136305d8cb8d" integrity sha512-ZssAvH9FjGYlJ/PBVKdSmfyPc3Cz4rTWgZLI4iE/SX8Nt5l3o3oEjv3wwG5VD7xOjktzdwp5coac+kJV9l4jgg== dependencies: mdast-util-footnote "^0.1.0" @@ -12982,7 +13219,7 @@ remark-footnotes@^3.0.0: remark-frontmatter@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz" + resolved "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-3.0.0.tgz#ca5d996361765c859bd944505f377d6b186a6ec6" integrity sha512-mSuDd3svCHs+2PyO29h7iijIZx4plX0fheacJcAoYAASfgzgVIcXGYSq9GFyYocFLftQs8IOmmkgtOovs6d4oA== dependencies: mdast-util-frontmatter "^0.2.0" @@ -12990,7 +13227,7 @@ remark-frontmatter@^3.0.0: remark-gfm@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz" + resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz#9213643001be3f277da6256464d56fd28c3b3c0d" integrity sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA== dependencies: mdast-util-gfm "^0.1.0" @@ -12998,7 +13235,7 @@ remark-gfm@^1.0.0: remark-hbs@^0.4.0: version "0.4.1" - resolved "https://registry.npmjs.org/remark-hbs/-/remark-hbs-0.4.1.tgz" + resolved "https://registry.npmjs.org/remark-hbs/-/remark-hbs-0.4.1.tgz#07f5ce6cc85d64c673fd4ef7cd5a51189a2abe20" integrity sha512-q1qnjA473z409IGqj3iu0Rex9YVN3cfwf6siPP+SQN9Yx66OxyL2cU4VHWK6IxWHSa/cughU2CBUbDPPsWxlfg== dependencies: unist-builder "^2.0.3" @@ -13006,28 +13243,28 @@ remark-hbs@^0.4.0: remark-normalize-headings@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/remark-normalize-headings/-/remark-normalize-headings-2.0.0.tgz" + resolved "https://registry.npmjs.org/remark-normalize-headings/-/remark-normalize-headings-2.0.0.tgz#2e7492f4935346dc5eca96ffdb5f588196233169" integrity sha512-nXeBQ7luKRWDcuUTnc0ffUYZ7+cO01FomSjnzpGTGCi7rcD9Wbis+z3adbNyqbYtsC+/+o1S+GLHTwh9crnZxA== dependencies: mdast-normalize-headings "^2.0.0" remark-parse@^9.0.0: version "9.0.0" - resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz" + resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== dependencies: mdast-util-from-markdown "^0.8.0" remark-rehype@^8.0.0: version "8.1.0" - resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz" + resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-8.1.0.tgz#610509a043484c1e697437fa5eb3fd992617c945" integrity sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA== dependencies: mdast-util-to-hast "^10.2.0" remark-slug@^6.0.0: version "6.1.0" - resolved "https://registry.npmjs.org/remark-slug/-/remark-slug-6.1.0.tgz" + resolved "https://registry.npmjs.org/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== dependencies: github-slugger "^1.0.0" @@ -13036,59 +13273,59 @@ remark-slug@^6.0.0: remove-trailing-separator@^1.0.1: version "1.1.0" - resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" + resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== repeat-element@^1.1.2: version "1.1.4" - resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz" + resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.0.0, repeat-string@^1.6.1: version "1.6.1" - resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== repeating@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz" + resolved "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== dependencies: is-finite "^1.0.0" require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== require-from-string@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== requireindex@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz" + resolved "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== requires-port@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== reselect@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz" + resolved "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" integrity sha512-b/6tFZCmRhtBMa4xGqiiRp9jh9Aqi2A687Lo265cN0/QohJQEBPiQ52f4QB6i0eF3yp3hmLL21LSGBcML2dlxA== -reselect@^4.0.0: - version "4.1.7" - resolved "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz" - integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A== +reselect@^4.0.0, reselect@^4.1.7: + version "4.1.8" + resolved "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz" + resolved "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" integrity sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg== dependencies: expand-tilde "^2.0.0" @@ -13096,17 +13333,17 @@ resolve-dir@^1.0.0, resolve-dir@^1.0.1: resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-package-path@^1.0.11, resolve-package-path@^1.2.2, resolve-package-path@^1.2.6: version "1.2.7" - resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-1.2.7.tgz" + resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-1.2.7.tgz#2a7bc37ad96865e239330e3102c31322847e652e" integrity sha512-fVEKHGeK85bGbVFuwO9o1aU0n3vqQGrezPc51JGu9UTXpFQfWq5qCeKxyaRUSvephs+06c5j5rPq/dzHGEo8+Q== dependencies: path-root "^0.1.1" @@ -13114,7 +13351,7 @@ resolve-package-path@^1.0.11, resolve-package-path@^1.2.2, resolve-package-path@ resolve-package-path@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-2.0.0.tgz" + resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-2.0.0.tgz#7f258ab86ff074fff4ff8027a28f94d17d6fb1df" integrity sha512-/CLuzodHO2wyyHTzls5Qr+EFeG6RcW4u6//gjYvUfcfyuplIX1SSccU+A5A9A78Gmezkl3NBkFAMxLbzTY9TJA== dependencies: path-root "^0.1.1" @@ -13122,7 +13359,7 @@ resolve-package-path@^2.0.0: resolve-package-path@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-3.1.0.tgz" + resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-3.1.0.tgz#35faaa5d54a9c7dd481eb7c4b2a44410c9c763d8" integrity sha512-2oC2EjWbMJwvSN6Z7DbDfJMnD8MYEouaLn5eIX0j8XwPsYCVIyY9bbnX88YHVkbr8XHqvZrYbxaLPibfTYKZMA== dependencies: path-root "^0.1.1" @@ -13130,14 +13367,14 @@ resolve-package-path@^3.1.0: resolve-package-path@^4.0.1, resolve-package-path@^4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-4.0.3.tgz" + resolved "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-4.0.3.tgz#31dab6897236ea6613c72b83658d88898a9040aa" integrity sha512-SRpNAPW4kewOaNUt8VPqhJ0UMxawMwzJD8V7m1cJfdSTK9ieZwS6K7Dabsm4bmLFM96Z5Y/UznrpG5kt1im8yA== dependencies: path-root "^0.1.1" resolve-path@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz" + resolved "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" integrity sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w== dependencies: http-errors "~1.6.2" @@ -13145,30 +13382,30 @@ resolve-path@^1.4.0: resolve-url@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== -resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1: +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.2, resolve@^1.22.8, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1: version "1.22.8" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.4: - version "2.0.0-next.4" - resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" - integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== +resolve@^2.0.0-next.5: + version "2.0.0-next.5" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" restore-cursor@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q== dependencies: onetime "^2.0.0" @@ -13176,58 +13413,51 @@ restore-cursor@^2.0.0: restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" signal-exit "^3.0.2" -resumer@^0.0.0: - version "0.0.0" - resolved "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz" - integrity sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w== - dependencies: - through "~2.3.4" - ret@~0.1.10: version "0.1.15" - resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== reusify@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + version "1.4.1" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" rimraf@^3.0.0, rimraf@^3.0.1, rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" rimraf@~2.6.2: version "2.6.3" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" + resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== dependencies: hash-base "^3.0.0" @@ -13235,110 +13465,120 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: rollup-pluginutils@^2.8.1: version "2.8.2" - resolved "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz" + resolved "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== dependencies: estree-walker "^0.6.1" rollup@^2.50.0: version "2.79.1" - resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== optionalDependencies: fsevents "~2.3.2" route-recognizer@^0.3.3: version "0.3.4" - resolved "https://registry.npmjs.org/route-recognizer/-/route-recognizer-0.3.4.tgz" + resolved "https://registry.npmjs.org/route-recognizer/-/route-recognizer-0.3.4.tgz#39ab1ffbce1c59e6d2bdca416f0932611e4f3ca3" integrity sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g== rsvp@^3.0.14, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0: version "3.6.2" - resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz" + resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== rsvp@^4.7.0, rsvp@^4.8.1, rsvp@^4.8.2, rsvp@^4.8.4, rsvp@^4.8.5: version "4.8.5" - resolved "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz" + resolved "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== rsvp@~3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz" + resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz#07cb4a5df25add9e826ebc67dcc9fd89db27d84a" integrity sha512-Rf4YVNYpKjZ6ASAmibcwTNciQ5Co5Ztq6iZPEykHpkoflnD/K5ryE/rHehFsTm4NJj8nKDhbi3eKBWGogmNnkg== run-async@^2.2.0, run-async@^2.4.0: version "2.4.1" - resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz" + resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz" + resolved "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== dependencies: aproba "^1.1.1" rxjs@^6.4.0, rxjs@^6.6.0: version "6.6.7" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" rxjs@^7.5.1: - version "7.8.0" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" -safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-json-parse@~1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz" + resolved "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57" integrity sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A== -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" + call-bind "^1.0.6" + es-errors "^1.3.0" is-regex "^1.1.4" safe-regex@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sane@^4.0.0, sane@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz" + resolved "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== dependencies: "@cnakazawa/watch" "^1.0.3" @@ -13351,10 +13591,10 @@ sane@^4.0.0, sane@^4.1.0: minimist "^1.1.1" walker "~1.0.5" -sass@^1.28.0, sass@^1.49.7, sass@^1.62.1: - version "1.69.3" - resolved "https://registry.npmjs.org/sass/-/sass-1.69.3.tgz" - integrity sha512-X99+a2iGdXkdWn1akFPs0ZmelUzyAQfvqYc2P/MPTrJRuIRoTffGzT9W9nFqG00S+c8hXzVmgxhUuHFdrwxkhQ== +sass@^1.28.0, sass@^1.69.5: + version "1.77.6" + resolved "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz#898845c1348078c2e6d1b64f9ee06b3f8bd489e4" + integrity sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -13362,14 +13602,14 @@ sass@^1.28.0, sass@^1.49.7, sass@^1.62.1: saxes@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz" + resolved "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: xmlchars "^2.2.0" schema-utils@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== dependencies: ajv "^6.1.0" @@ -13378,67 +13618,65 @@ schema-utils@^1.0.0: schema-utils@^2.6.5: version "2.7.1" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== dependencies: "@types/json-schema" "^7.0.5" ajv "^6.12.4" ajv-keywords "^3.5.2" -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + version "4.2.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== dependencies: "@types/json-schema" "^7.0.9" - ajv "^8.8.0" + ajv "^8.9.0" ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" + ajv-keywords "^5.1.0" select@^1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/select/-/select-1.1.2.tgz" + resolved "https://registry.npmjs.org/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA== semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== semver-regex@^3.1.2: version "3.1.4" - resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz" + resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz#13053c0d4aa11d070a2f2872b6b1e3ae1e1971b4" integrity sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA== -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.0.0, semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" +semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3: + version "7.6.2" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== send@0.18.0: version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" @@ -13457,21 +13695,21 @@ send@0.18.0: serialize-javascript@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== dependencies: randombytes "^2.1.0" serialize-javascript@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + version "6.0.2" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" serve-static@1.15.0: version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" @@ -13481,12 +13719,34 @@ serve-static@1.15.0: set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +set-function-name@^2.0.1, set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz" + resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== dependencies: extend-shallow "^2.0.1" @@ -13496,22 +13756,22 @@ set-value@^2.0.0, set-value@^2.0.1: setimmediate@^1.0.4: version "1.0.5" - resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" + resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== setprototypeof@1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== setprototypeof@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" - resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz" + resolved "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: inherits "^2.0.1" @@ -13519,67 +13779,68 @@ sha.js@^2.4.0, sha.js@^2.4.8: shebang-command@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== dependencies: shebang-regex "^1.0.0" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.6.1: - version "1.8.0" - resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz" - integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== + version "1.8.1" + resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== shellwords@^0.1.1: version "0.1.1" - resolved "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz" + resolved "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== silent-error@^1.0.0, silent-error@^1.0.1, silent-error@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/silent-error/-/silent-error-1.1.1.tgz" + resolved "https://registry.npmjs.org/silent-error/-/silent-error-1.1.1.tgz#f72af5b0d73682a2ba1778b7e32cd8aa7c2d8662" integrity sha512-n4iEKyNcg4v6/jpb3c0/iyH2G1nzUNl7Gpqtn/mHIJK9S/q/7MCfoO4rwVOoO59qPFIc0hVHvMbiOJ0NdtxKKw== dependencies: debug "^2.2.0" simple-html-tokenizer@^0.5.10, simple-html-tokenizer@^0.5.11, simple-html-tokenizer@^0.5.8: version "0.5.11" - resolved "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz" + resolved "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz#4c5186083c164ba22a7b477b7687ac056ad6b1d9" integrity sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og== sinon@^9.0.0: version "9.2.4" - resolved "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz" + resolved "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz#e55af4d3b174a4443a8762fa8421c2976683752b" integrity sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg== dependencies: "@sinonjs/commons" "^1.8.1" @@ -13591,17 +13852,17 @@ sinon@^9.0.0: slash@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz" + resolved "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== slash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: ansi-styles "^4.0.0" @@ -13610,7 +13871,7 @@ slice-ansi@^3.0.0: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -13619,12 +13880,12 @@ slice-ansi@^4.0.0: slide@~1.1.3: version "1.1.6" - resolved "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" + resolved "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" integrity sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw== snake-case@^3.0.3: version "3.0.4" - resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz" + resolved "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== dependencies: dot-case "^3.0.4" @@ -13632,7 +13893,7 @@ snake-case@^3.0.3: snapdragon-node@^2.0.1: version "2.1.1" - resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" @@ -13641,14 +13902,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz" + resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" - resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" @@ -13661,40 +13922,42 @@ snapdragon@^0.8.1: use "^3.1.0" socket.io-adapter@~2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz" - integrity sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA== + version "2.5.5" + resolved "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz#c7a1f9c703d7756844751b6ff9abfc1780664082" + integrity sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg== dependencies: - ws "~8.11.0" + debug "~4.3.4" + ws "~8.17.1" -socket.io-parser@~4.2.1: - version "4.2.2" - resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz" - integrity sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw== +socket.io-parser@~4.2.4: + version "4.2.4" + resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83" + integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew== dependencies: "@socket.io/component-emitter" "~3.1.0" debug "~4.3.1" -socket.io@^4.1.2: - version "4.6.1" - resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz" - integrity sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA== +socket.io@^4.5.4: + version "4.7.5" + resolved "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz#56eb2d976aef9d1445f373a62d781a41c7add8f8" + integrity sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA== dependencies: accepts "~1.3.4" base64id "~2.0.0" + cors "~2.8.5" debug "~4.3.2" - engine.io "~6.4.1" + engine.io "~6.5.2" socket.io-adapter "~2.5.2" - socket.io-parser "~4.2.1" + socket.io-parser "~4.2.4" sort-object-keys@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz" + resolved "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== sort-package-json@^1.49.0: version "1.57.0" - resolved "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.57.0.tgz" + resolved "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.57.0.tgz#e95fb44af8ede0bb6147e3f39258102d4bb23fc4" integrity sha512-FYsjYn2dHTRb41wqnv+uEqCUvBpK3jZcTp9rbz2qDTmel7Pmdtf+i2rLaaPMRZeSVM60V3Se31GyWFpmKs4Q5Q== dependencies: detect-indent "^6.0.0" @@ -13706,17 +13969,17 @@ sort-package-json@^1.49.0: source-list-map@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== source-map-resolve@^0.5.0: version "0.5.3" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== dependencies: atob "^2.1.2" @@ -13727,7 +13990,7 @@ source-map-resolve@^0.5.0: source-map-resolve@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== dependencies: atob "^2.1.2" @@ -13735,14 +13998,14 @@ source-map-resolve@^0.6.0: source-map-support@^0.4.15: version "0.4.18" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== dependencies: source-map "^0.5.6" source-map-support@~0.5.12, source-map-support@~0.5.20: version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -13750,51 +14013,51 @@ source-map-support@~0.5.12, source-map-support@~0.5.20: source-map-url@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" integrity sha512-QU4fa0D6aSOmrT+7OHpUXw+jS84T0MLaQNtFs8xzLNe6Arj44Magd7WEbyVW5LNYoAPVV35aKs4azxIfVJrToQ== source-map-url@^0.4.0: version "0.4.1" - resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@0.4.x, source-map@^0.4.2: version "0.4.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" integrity sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A== dependencies: amdefine ">=0.0.4" source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@~0.1.x: version "0.1.43" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" integrity sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ== dependencies: amdefine ">=0.0.4" -source-map@~0.7.3: +source-map@~0.7.4: version "0.7.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== sourcemap-codec@^1.4.8: version "1.4.8" - resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" + resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== sourcemap-validator@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/sourcemap-validator/-/sourcemap-validator-1.1.1.tgz" + resolved "https://registry.npmjs.org/sourcemap-validator/-/sourcemap-validator-1.1.1.tgz#3d7d8a399ccab09c1fedc510d65436e25b1c386b" integrity sha512-pq6y03Vs6HUaKo9bE0aLoksAcpeOo9HZd7I8pI6O480W/zxNZ9U32GfzgtPP0Pgc/K1JHna569nAbOk3X8/Qtw== dependencies: jsesc "~0.3.x" @@ -13804,17 +14067,17 @@ sourcemap-validator@^1.1.0: space-separated-tokens@^1.0.0: version "1.1.5" - resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== spawn-args@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/spawn-args/-/spawn-args-0.2.0.tgz" + resolved "https://registry.npmjs.org/spawn-args/-/spawn-args-0.2.0.tgz#fb7d0bd1d70fd4316bd9e3dec389e65f9d6361bb" integrity sha512-73BoniQDcRWgnLAf/suKH6V5H54gd1KLzwYN9FB6J/evqTV33htH9xwV/4BHek+++jzxpVlZQKKZkqstPQPmQg== spdx-compare@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz" + resolved "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz#2c55f117362078d7409e6d7b08ce70a857cd3ed7" integrity sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A== dependencies: array-find-index "^1.0.2" @@ -13823,38 +14086,38 @@ spdx-compare@^1.0.0: spdx-correct@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + version "2.5.0" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== spdx-expression-parse@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + version "3.0.18" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz#22aa922dcf2f2885a6494a261f2d8b75345d0326" + integrity sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ== spdx-ranges@^2.0.0: version "2.1.1" - resolved "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz" + resolved "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz#87573927ba51e92b3f4550ab60bfc83dd07bac20" integrity sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA== spdx-satisfies@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz" + resolved "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-4.0.1.tgz#9a09a68d80f5f1a31cfaebb384b0c6009e4969fe" integrity sha512-WVzZ/cXAzoNmjCWiEluEA3BjHp5tiUmmhn9MK+X0tBbR9sOqtC6UQwmgCNrAIZvNlMuBUYAaHYfb2oqlF9SwKA== dependencies: spdx-compare "^1.0.0" @@ -13863,43 +14126,43 @@ spdx-satisfies@^4.0.0: split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" - resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@^1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + version "1.1.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== sri-toolbox@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/sri-toolbox/-/sri-toolbox-0.2.0.tgz" + resolved "https://registry.npmjs.org/sri-toolbox/-/sri-toolbox-0.2.0.tgz#a7fea5c3fde55e675cf1c8c06f3ebb5c2935835e" integrity sha512-DQIMWCAr/M7phwo+d3bEfXwSBEwuaJL+SJx9cuqt1Ty7K96ZFoHpYnSbhrQZEr0+0/GtmpKECP8X/R4RyeTAfw== ssri@^6.0.1: version "6.0.2" - resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz" + resolved "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== dependencies: figgy-pudding "^3.5.1" stagehand@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/stagehand/-/stagehand-1.0.1.tgz" + resolved "https://registry.npmjs.org/stagehand/-/stagehand-1.0.1.tgz#0cbca6f906e4a7be36c5830dc31d9cc7091a827e" integrity sha512-GqXBq2SPWv9hTXDFKS8WrKK1aISB0aKGHZzH+uD4ShAgs+Fz20ZfoerLOm8U+f62iRWLrw6nimOY/uYuTcVhvg== dependencies: debug "^4.1.0" static-extend@^0.1.1: version "0.1.2" - resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== dependencies: define-property "^0.2.5" @@ -13907,24 +14170,24 @@ static-extend@^0.1.1: statuses@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== "statuses@>= 1.4.0 < 2", statuses@~1.5.0: version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== stop-iteration-iterator@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" + resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== dependencies: internal-slot "^1.0.4" stream-browserify@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz" + resolved "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== dependencies: inherits "~2.0.1" @@ -13932,7 +14195,7 @@ stream-browserify@^2.0.1: stream-each@^1.1.0: version "1.2.3" - resolved "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz" + resolved "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== dependencies: end-of-stream "^1.1.0" @@ -13940,7 +14203,7 @@ stream-each@^1.1.0: stream-http@^2.7.2: version "2.8.3" - resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz" + resolved "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== dependencies: builtin-status-codes "^3.0.0" @@ -13950,23 +14213,23 @@ stream-http@^2.7.2: xtend "^4.0.0" stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + version "1.0.3" + resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== string-argv@0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== string-template@~0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz" + resolved "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== string-width@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== dependencies: code-point-at "^1.0.0" @@ -13975,7 +14238,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -13984,84 +14247,90 @@ string-width@^1.0.1: string-width@^2.1.0: version "2.1.1" - resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" string.prototype.matchall@^4.0.5: - version "4.0.8" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz" - integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== + version "4.0.11" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz#1092a72c59268d2abaad76582dccc687c0297e0a" + integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + gopd "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.3" - side-channel "^1.0.4" + internal-slot "^1.0.7" + regexp.prototype.flags "^1.5.2" + set-function-name "^2.0.2" + side-channel "^1.0.6" string.prototype.padend@^3.0.0: - version "3.1.4" - resolved "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz" - integrity sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw== + version "3.1.6" + resolved "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz#ba79cf8992609a91c872daa47c6bb144ee7f62a5" + integrity sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" -string.prototype.trim@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" string_decoder@0.10, string_decoder@~0.10.x: version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" stringify-entities@^3.0.1: version "3.1.0" - resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.1.0.tgz#b8d3feac256d9ffcc9fa1fefdcf3ca70576ee903" integrity sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg== dependencies: character-entities-html4 "^1.0.0" @@ -14070,7 +14339,7 @@ stringify-entities@^3.0.1: stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" @@ -14079,65 +14348,65 @@ stringify-object@^3.3.0: strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== dependencies: ansi-regex "^3.0.0" strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-ansi@~0.1.0: version "0.1.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" integrity sha512-behete+3uqxecWlDAm5lmskaSaISA+ThQ4oNNBDTBJt0x2ppR6IPqfZNuj6BLaLJ/Sji4TPZlcRyOis8wXQTLg== strip-bom@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-eof@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" + resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== style-loader@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz" + resolved "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== dependencies: loader-utils "^2.0.0" @@ -14145,60 +14414,73 @@ style-loader@^2.0.0: styled_string@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/styled_string/-/styled_string-0.0.1.tgz" + resolved "https://registry.npmjs.org/styled_string/-/styled_string-0.0.1.tgz#d22782bd81295459bc4f1df18c4bad8e94dd124a" integrity sha512-DU2KZiB6VbPkO2tGSqQ9n96ZstUPjW7X4sGO6V2m1myIQluX0p1Ol8BrA/l6/EesqhMqXOIXs3cJNOy1UuU2BA== +sucrase@^3.32.0: + version "3.35.0" + resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + sum-up@^1.0.1: version "1.0.3" - resolved "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz" + resolved "https://registry.npmjs.org/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" integrity sha512-zw5P8gnhiqokJUWRdR6F4kIIIke0+ubQSGyYUY506GCbJWtV7F6Xuy0j6S125eSX2oF+a8KdivsZ8PlVEH0Mcw== dependencies: chalk "^1.0.0" supports-color@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== symbol-tree@^3.2.4: version "3.2.4" - resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" + resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1, symlink-or-copy@^1.1.8, symlink-or-copy@^1.2.0, symlink-or-copy@^1.3.1: version "1.3.1" - resolved "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz" + resolved "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz#9506dd64d8e98fa21dcbf4018d1eab23e77f71fe" integrity sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA== sync-disk-cache@^1.3.3: version "1.3.4" - resolved "https://registry.npmjs.org/sync-disk-cache/-/sync-disk-cache-1.3.4.tgz" + resolved "https://registry.npmjs.org/sync-disk-cache/-/sync-disk-cache-1.3.4.tgz#53a2c5a09d8f4bb53160bce182a456ad71574024" integrity sha512-GlkGeM81GPPEKz/lH7QUTbvqLq7K/IUTuaKDSMulP9XQ42glqNJIN/RKgSOw4y8vxL1gOVvj+W7ruEO4s36eCw== dependencies: debug "^2.1.3" @@ -14209,7 +14491,7 @@ sync-disk-cache@^1.3.3: sync-disk-cache@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/sync-disk-cache/-/sync-disk-cache-2.1.0.tgz" + resolved "https://registry.npmjs.org/sync-disk-cache/-/sync-disk-cache-2.1.0.tgz#01e879edc41c34a01fcdda5b39d47dd496e154a6" integrity sha512-vngT2JmkSapgq0z7uIoYtB9kWOOzMihAAYq/D3Pjm/ODOGMgS4r++B+OZ09U4hWR6EaOdy9eqQ7/8ygbH3wehA== dependencies: debug "^4.1.1" @@ -14220,13 +14502,13 @@ sync-disk-cache@^2.0.0: tabbable@^5.3.3: version "5.3.3" - resolved "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz" + resolved "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz#aac0ff88c73b22d6c3c5a50b1586310006b47fbf" integrity sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA== table@^6.0.9: - version "6.8.1" - resolved "https://registry.npmjs.org/table/-/table-6.8.1.tgz" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + version "6.8.2" + resolved "https://registry.npmjs.org/table/-/table-6.8.2.tgz#c5504ccf201213fa227248bdc8c5569716ac6c58" + integrity sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA== dependencies: ajv "^8.0.1" lodash.truncate "^4.4.2" @@ -14235,37 +14517,36 @@ table@^6.0.9: strip-ansi "^6.0.1" tailwindcss@^3.1.8: - version "3.2.7" - resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.7.tgz" - integrity sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ== + version "3.4.4" + resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz#351d932273e6abfa75ce7d226b5bf3a6cb257c05" + integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== dependencies: + "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" chokidar "^3.5.3" - color-name "^1.1.4" - detective "^5.2.1" didyoumean "^1.2.2" dlv "^1.1.3" - fast-glob "^3.2.12" + fast-glob "^3.3.0" glob-parent "^6.0.2" is-glob "^4.0.3" - lilconfig "^2.0.6" + jiti "^1.21.0" + lilconfig "^2.1.0" micromatch "^4.0.5" normalize-path "^3.0.0" object-hash "^3.0.0" picocolors "^1.0.0" - postcss "^8.0.9" - postcss-import "^14.1.0" - postcss-js "^4.0.0" - postcss-load-config "^3.1.4" - postcss-nested "6.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" postcss-selector-parser "^6.0.11" - postcss-value-parser "^4.2.0" - quick-lru "^5.1.1" - resolve "^1.22.1" + resolve "^1.22.2" + sucrase "^3.32.0" tap-parser@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz" + resolved "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz#54db35302fda2c2ccc21954ad3be22b2cba42721" integrity sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA== dependencies: events-to-array "^1.0.1" @@ -14274,44 +14555,45 @@ tap-parser@^7.0.0: tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" + resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== tape@^5.0.1: - version "5.6.3" - resolved "https://registry.npmjs.org/tape/-/tape-5.6.3.tgz" - integrity sha512-cUDDGSbyoSIpdUAqbqLI/r7i/S4BHuCB9M5j7E/LrLs/x/i4zeAJ798aqo+FGo+kr9seBZwr8AkZW6rjceyAMQ== + version "5.8.1" + resolved "https://registry.npmjs.org/tape/-/tape-5.8.1.tgz#76fc0ddad652e9714355932fb56eb7c463d5232f" + integrity sha512-pUzADXBVYm5Jkneh9hfXnirADrzQrDA3vddKbPOc/ZLORj4dFQ6GR1KdGWX0/NvOLDcYkVgeMdw78Uf6BzO3KA== dependencies: - array.prototype.every "^1.1.4" - call-bind "^1.0.2" - deep-equal "^2.2.0" + "@ljharb/resumer" "^0.1.3" + "@ljharb/through" "^2.3.13" + array.prototype.every "^1.1.6" + call-bind "^1.0.7" + deep-equal "^2.2.3" defined "^1.0.1" dotignore "^0.1.2" for-each "^0.3.3" get-package-type "^0.1.0" glob "^7.2.3" - has "^1.0.3" - has-dynamic-import "^2.0.1" + has-dynamic-import "^2.1.0" + hasown "^2.0.2" inherits "^2.0.4" is-regex "^1.1.4" - minimist "^1.2.7" - object-inspect "^1.12.3" - object-is "^1.1.5" + minimist "^1.2.8" + mock-property "^1.0.3" + object-inspect "^1.13.1" + object-is "^1.1.6" object-keys "^1.1.1" - object.assign "^4.1.4" - resolve "^2.0.0-next.4" - resumer "^0.0.0" - string.prototype.trim "^1.2.7" - through "^2.3.8" + object.assign "^4.1.5" + resolve "^2.0.0-next.5" + string.prototype.trim "^1.2.9" temp@0.9.4: version "0.9.4" - resolved "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz" + resolved "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz#cd20a8580cb63635d0e4e9d4bd989d44286e7620" integrity sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA== dependencies: mkdirp "^0.5.1" @@ -14319,7 +14601,7 @@ temp@0.9.4: terser-webpack-plugin@^1.4.3: version "1.4.5" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== dependencies: cacache "^12.0.2" @@ -14332,39 +14614,39 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^5.1.3: - version "5.3.7" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz" - integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: - "@jridgewell/trace-mapping" "^0.3.17" + "@jridgewell/trace-mapping" "^0.3.20" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.1" - terser "^5.16.5" + terser "^5.26.0" terser@^4.1.2: version "4.8.1" - resolved "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz" + resolved "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== dependencies: commander "^2.20.0" source-map "~0.6.1" source-map-support "~0.5.12" -terser@^5.16.5, terser@^5.3.0: - version "5.16.6" - resolved "https://registry.npmjs.org/terser/-/terser-5.16.6.tgz" - integrity sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg== +terser@^5.26.0, terser@^5.7.0: + version "5.31.1" + resolved "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz#735de3c987dd671e95190e6b98cfe2f07f3cf0d4" + integrity sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" test-exclude@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: "@istanbuljs/schema" "^0.1.2" @@ -14372,9 +14654,9 @@ test-exclude@^6.0.0: minimatch "^3.0.4" testem@^3.2.0: - version "3.10.1" - resolved "https://registry.npmjs.org/testem/-/testem-3.10.1.tgz" - integrity sha512-42c4e7qlAelwMd8O3ogtVGRbgbr6fJnX6H51ACOIG1V1IjsKPlcQtxPyOwaL4iikH22Dfh+EyIuJnMG4yxieBQ== + version "3.15.0" + resolved "https://registry.npmjs.org/testem/-/testem-3.15.0.tgz#c1f66ff2f6d0e9606c77c4de6b62bca088632d1a" + integrity sha512-vI1oQsjJW4QdVaH6ZmfNErzH7nzs0KzHJluocnfvbz1XRYGJKkIMGKWfsbD8MGGJOg+uzXcEek0/2W7BmGR4ug== dependencies: "@xmldom/xmldom" "^0.8.0" backbone "^1.1.2" @@ -14385,7 +14667,7 @@ testem@^3.2.0: consolidate "^0.16.0" execa "^1.0.0" express "^4.10.7" - fireworm "^0.7.0" + fireworm "^0.7.2" glob "^7.0.4" http-proxy "^1.13.1" js-yaml "^3.2.5" @@ -14394,13 +14676,13 @@ testem@^3.2.0: lodash.clonedeep "^4.4.1" lodash.find "^4.5.1" lodash.uniqby "^4.7.0" - mkdirp "^1.0.4" + mkdirp "^3.0.1" mustache "^4.2.0" node-notifier "^10.0.0" npmlog "^6.0.0" printf "^0.6.1" rimraf "^3.0.2" - socket.io "^4.1.2" + socket.io "^4.5.4" spawn-args "^0.2.0" styled_string "0.0.1" tap-parser "^7.0.0" @@ -14408,22 +14690,36 @@ testem@^3.2.0: text-encoding@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz" + resolved "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz#f895e836e45990624086601798ea98e8f36ee643" integrity sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA== text-table@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== "textextensions@1 || 2", textextensions@^2.5.0: version "2.6.0" - resolved "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz" + resolved "https://registry.npmjs.org/textextensions/-/textextensions-2.6.0.tgz#d7e4ab13fe54e32e08873be40d51b74229b00fc4" integrity sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + through2@^2.0.0: version "2.0.5" - resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" + resolved "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== dependencies: readable-stream "~2.3.6" @@ -14431,32 +14727,32 @@ through2@^2.0.0: through2@^3.0.1: version "3.0.2" - resolved "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz" + resolved "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== dependencies: inherits "^2.0.4" readable-stream "2 || 3" -through@^2.3.6, through@^2.3.8, through@~2.3.4: +through@^2.3.6, through@^2.3.8: version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== timers-browserify@^2.0.4: version "2.0.12" - resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz" + resolved "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" tiny-emitter@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz" + resolved "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== tiny-glob@0.2.9: version "0.2.9" - resolved "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz" + resolved "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== dependencies: globalyzer "0.1.0" @@ -14464,7 +14760,7 @@ tiny-glob@0.2.9: tiny-lr@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/tiny-lr/-/tiny-lr-2.0.0.tgz" + resolved "https://registry.npmjs.org/tiny-lr/-/tiny-lr-2.0.0.tgz#863659d7ce1ed201a117d8197d7f8b9a27bdc085" integrity sha512-f6nh0VMRvhGx4KCeK1lQ/jaL0Zdb5WdR+Jk8q9OSUQnaSDxAEGH1fgqLZ+cMl5EW3F2MGnCsalBO1IsnnogW1Q== dependencies: body "^5.1.0" @@ -14476,69 +14772,67 @@ tiny-lr@^2.0.0: tippy.js@^6.2.7, tippy.js@^6.3.7: version "6.3.7" - resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz" + resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c" integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ== dependencies: "@popperjs/core" "^2.9.0" tmp@0.0.28: version "0.0.28" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" integrity sha512-c2mmfiBmND6SOVxzogm1oda0OJ1HZVIk/5n26N59dDTh80MUeavpiCls4PGAdkX1PFkKokLpcf7prSjCeXLsJg== dependencies: os-tmpdir "~1.0.1" tmp@0.0.33, tmp@^0.0.33: version "0.0.33" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: os-tmpdir "~1.0.2" tmp@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== dependencies: rimraf "^2.6.3" tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" + version "0.2.3" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== tmpl@1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-arraybuffer@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz" + resolved "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== to-fast-properties@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og== to-fast-properties@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-object-path@^0.3.0: version "0.3.0" - resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== dependencies: is-number "^3.0.0" @@ -14546,14 +14840,14 @@ to-regex-range@^2.1.0: to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" @@ -14563,7 +14857,7 @@ to-regex@^3.0.1, to-regex@^3.0.2: to-vfile@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz" + resolved "https://registry.npmjs.org/to-vfile/-/to-vfile-6.1.0.tgz#5f7a3f65813c2c4e34ee1f7643a5646344627699" integrity sha512-BxX8EkCxOAZe+D/ToHdDsJcVI4HqQfmw0tCkp31zf3dNP/XWIAjU4CmeuSwsSoOzOTqHPOL0KUzyZqJplkD0Qw== dependencies: is-buffer "^2.0.0" @@ -14571,21 +14865,21 @@ to-vfile@^6.1.0: toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== torii@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.npmjs.org/torii/-/torii-1.0.0-beta.1.tgz" - integrity sha512-MtR0QB5YbcADa2eM2eQaWKAUTQuHgr9Biu9yJV0sQOXRMW9X0cdTPWhxYM3PSnSBRg28BAeMKjbsr2uPdayS+g== + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/torii/-/torii-1.0.0-beta.2.tgz#d6b58aeee1418ad3c1815533886bbbd9982234a8" + integrity sha512-LGKf1Ntr4Nb8ApqQ2gbvsLwaCIPTSz+V9pkrb5ul2BCH0DJCjT8rUJNRNu7SlCBU77ZlxZtDjxbX9ydhMqoCfA== dependencies: ember-cli-babel "^7.26.10" ember-cli-htmlbars "^5.7.2" tough-cookie@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.4" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -14594,28 +14888,27 @@ tough-cookie@^4.0.0: tr46@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz" + resolved "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" tr46@~0.0.3: version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== tracked-built-ins@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/tracked-built-ins/-/tracked-built-ins-3.1.1.tgz" - integrity sha512-W8qLBxZzeC2zhEDdbPKi2GTffsiFn8PRbgal/2Fl6E/84CMvnpS6cPMmkvUmSLgKbqcAxl/RhyjWnhIZ9iPQjQ== + version "3.3.0" + resolved "https://registry.npmjs.org/tracked-built-ins/-/tracked-built-ins-3.3.0.tgz#3c8d780550658fe180d0ec32754f1eef1966f2d9" + integrity sha512-ewKFrW/AQs05oLPM5isOUb/1aOwBRfHfmF408CCzTk21FLAhKrKVOP5Q5ebX+zCT4kvg81PGBGwrBiEGND1nWA== dependencies: - ember-cli-babel "^7.26.10" - ember-cli-typescript "^5.1.0" + "@embroider/addon-shim" "^1.8.3" ember-tracked-storage-polyfill "^1.0.0" tracked-maps-and-sets@^2.1.0: version "2.2.1" - resolved "https://registry.npmjs.org/tracked-maps-and-sets/-/tracked-maps-and-sets-2.2.1.tgz" + resolved "https://registry.npmjs.org/tracked-maps-and-sets/-/tracked-maps-and-sets-2.2.1.tgz#323dd40540c561e8b0ffdec8bf129c68ec5025f9" integrity sha512-XYrXh6L/GpGmVmG3KcN/qoDyi4FxHh8eZY/BA/RuoxynskV+GZSfwrX3R+5DR2CIkzkCx4zi4kkDRg1AMDfDhg== dependencies: "@glimmer/tracking" "^1.0.0" @@ -14623,7 +14916,7 @@ tracked-maps-and-sets@^2.1.0: tracked-maps-and-sets@^3.0.1: version "3.0.2" - resolved "https://registry.npmjs.org/tracked-maps-and-sets/-/tracked-maps-and-sets-3.0.2.tgz" + resolved "https://registry.npmjs.org/tracked-maps-and-sets/-/tracked-maps-and-sets-3.0.2.tgz#6ea1b9f2a367d24f2e9905b74b24437fbce76ea6" integrity sha512-UIRcWsX1kDOcC/Q2R58weYWlw01EnmWWBwUv3okWS+zMBvsgIfYoO6veHhuNE3hgzWCEImNp46QS5CyKnw5QUA== dependencies: "@glimmer/tracking" "^1.0.0" @@ -14632,13 +14925,17 @@ tracked-maps-and-sets@^3.0.1: ember-tracked-storage-polyfill "1.0.0" traverse@^0.6.7: - version "0.6.7" - resolved "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz" - integrity sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg== + version "0.6.9" + resolved "https://registry.npmjs.org/traverse/-/traverse-0.6.9.tgz#76cfdbacf06382d460b76f8b735a44a6209d8b81" + integrity sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg== + dependencies: + gopd "^1.0.1" + typedarray.prototype.slice "^1.0.3" + which-typed-array "^1.1.15" tree-sync@^1.2.2: version "1.4.0" - resolved "https://registry.npmjs.org/tree-sync/-/tree-sync-1.4.0.tgz" + resolved "https://registry.npmjs.org/tree-sync/-/tree-sync-1.4.0.tgz#314598d13abaf752547d9335b8f95d9a137100d6" integrity sha512-YvYllqh3qrR5TAYZZTXdspnIhlKAYezPYw11ntmweoceu4VK+keN356phHRIIo1d+RDmLpHZrUlmxga2gc9kSQ== dependencies: debug "^2.2.0" @@ -14649,7 +14946,7 @@ tree-sync@^1.2.2: tree-sync@^2.0.0, tree-sync@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/tree-sync/-/tree-sync-2.1.0.tgz" + resolved "https://registry.npmjs.org/tree-sync/-/tree-sync-2.1.0.tgz#31cbbd41f2936f5390b61e8c9d7cb27e75a212fe" integrity sha512-OLWW+Nd99NOM53aZ8ilT/YpEiOo6mXD3F4/wLbARqybSZ3Jb8IxHK5UGVbZaae0wtXAyQshVV+SeqVBik+Fbmw== dependencies: debug "^4.1.1" @@ -14660,115 +14957,160 @@ tree-sync@^2.0.0, tree-sync@^2.1.0: treeify@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz" + resolved "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz#4e31c6a463accd0943879f30667c4fdaff411bb8" integrity sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A== trim-right@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz" + resolved "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw== trough@^1.0.0, trough@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz" + resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + tslib@^1.9.0: version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.3, tslib@^2.1.0: - version "2.5.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + version "2.6.3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== tty-browserify@0.0.0: version "0.0.0" - resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz" + resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - type-detect@4.0.8, type-detect@^4.0.8: version "4.0.8" - resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.11.0: version "0.11.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-is@~1.6.18: version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== dependencies: media-typer "0.3.0" mime-types "~2.1.24" -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" for-each "^0.3.3" - is-typed-array "^1.1.9" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" typedarray-to-buffer@^3.1.5: version "3.1.5" - resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" + resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== dependencies: is-typedarray "^1.0.0" +typedarray.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/typedarray.prototype.slice/-/typedarray.prototype.slice-1.0.3.tgz#bce2f685d3279f543239e4d595e0d021731d2d1a" + integrity sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-errors "^1.3.0" + typed-array-buffer "^1.0.2" + typed-array-byte-offset "^1.0.2" + typedarray@^0.0.6: version "0.0.6" - resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== typescript-memoize@^1.0.0-alpha.3, typescript-memoize@^1.0.1: version "1.1.1" - resolved "https://registry.npmjs.org/typescript-memoize/-/typescript-memoize-1.1.1.tgz" + resolved "https://registry.npmjs.org/typescript-memoize/-/typescript-memoize-1.1.1.tgz#02737495d5df6ebf72c07ba0d002e8f4cf5ccfa0" integrity sha512-GQ90TcKpIH4XxYTI2F98yEQYZgjNMOGPpOgdjIBhaLaWji5HPWlRnZ4AeA1hfBxtY7bCGDJsqDDHk/KaHOl5bA== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" - resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" + resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + version "3.18.0" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz#73b576a7e8fda63d2831e293aeead73e0a270deb" + integrity sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A== unbox-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: call-bind "^1.0.2" @@ -14778,7 +15120,7 @@ unbox-primitive@^1.0.2: underscore.string@^3.2.2, underscore.string@~3.3.4: version "3.3.6" - resolved "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz" + resolved "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz#ad8cf23d7423cb3b53b898476117588f4e2f9159" integrity sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ== dependencies: sprintf-js "^1.1.1" @@ -14786,22 +15128,27 @@ underscore.string@^3.2.2, underscore.string@~3.3.4: underscore@>=1.8.3, underscore@^1.13.2: version "1.13.6" - resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== underscore@~1.6.0: version "1.6.0" - resolved "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" + resolved "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" integrity sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== unicode-match-property-ecmascript@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== dependencies: unicode-canonical-property-names-ecmascript "^2.0.0" @@ -14809,17 +15156,17 @@ unicode-match-property-ecmascript@^2.0.0: unicode-match-property-value-ecmascript@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== unified@^9.0.0, unified@^9.2.2: version "9.2.2" - resolved "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz" + resolved "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== dependencies: bail "^1.0.0" @@ -14831,7 +15178,7 @@ unified@^9.0.0, unified@^9.2.2: union-value@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== dependencies: arr-union "^3.1.0" @@ -14841,90 +15188,71 @@ union-value@^1.0.0: unique-filename@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz" + resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== dependencies: unique-slug "^2.0.0" unique-slug@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz" + resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== dependencies: imurmurhash "^0.1.4" unique-string@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz" + resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== dependencies: crypto-random-string "^2.0.0" unist-builder@^2.0.0, unist-builder@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz" + resolved "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== unist-util-find@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/unist-util-find/-/unist-util-find-1.0.2.tgz" - integrity sha512-ft06UDYzqi9o9RmGP0sZWI/zvLLQiBW2/MD+rW6mDqbOWDcmknGX9orQPspfuGRYWr8eSJAmfsBcvOpfGRJseA== + version "1.0.4" + resolved "https://registry.npmjs.org/unist-util-find/-/unist-util-find-1.0.4.tgz#752e2c6fabf9d57e2c08e03d2f54aaee8c227ef3" + integrity sha512-T5vI7IkhroDj7KxAIy057VbIeGnCXfso4d4GoUsjbAmDLQUkzAeszlBtzx1+KHgdsYYBygaqUBvrbYCfePedZw== dependencies: - lodash.iteratee "^4.5.0" - unist-util-visit "^1.1.0" + lodash.iteratee "^4.7.0" + unist-util-visit "^2.0.0" unist-util-generated@^1.0.0: version "1.1.6" - resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz" + resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== -unist-util-is@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz" - integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== - unist-util-is@^4.0.0: version "4.1.0" - resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== unist-util-position@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz" + resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== unist-util-stringify-position@^2.0.0: version "2.0.3" - resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== dependencies: "@types/unist" "^2.0.2" -unist-util-visit-parents@^2.0.0: - version "2.1.2" - resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz" - integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g== - dependencies: - unist-util-is "^3.0.0" - unist-util-visit-parents@^3.0.0: version "3.1.1" - resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== dependencies: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" -unist-util-visit@^1.1.0: - version "1.4.1" - resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz" - integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw== - dependencies: - unist-util-visit-parents "^2.0.0" - unist-util-visit@^2.0.0, unist-util-visit@^2.0.2, unist-util-visit@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== dependencies: "@types/unist" "^2.0.0" @@ -14933,27 +15261,27 @@ unist-util-visit@^2.0.0, unist-util-visit@^2.0.2, unist-util-visit@^2.0.3: universalify@^0.1.0: version "0.1.2" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unset-value@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== dependencies: has-value "^0.3.1" @@ -14961,109 +15289,109 @@ unset-value@^1.0.0: untildify@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz" + resolved "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" integrity sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig== dependencies: os-homedir "^1.0.0" upath@^1.1.1: version "1.2.0" - resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz" + resolved "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.16: + version "1.1.0" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.1.2" + picocolors "^1.0.1" update-section@^0.3.3: version "0.3.3" - resolved "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz" + resolved "https://registry.npmjs.org/update-section/-/update-section-0.3.3.tgz#458f17820d37820dc60e20b86d94391b00123158" integrity sha512-BpRZMZpgXLuTiKeiu7kK0nIPwGdyrqrs6EDSaXtjD/aQ2T+qVo9a5hRC3HN3iJjCMxNT/VxoLGQ7E/OzE5ucnw== -uri-js@^4.2.2: +uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" urix@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== url-parse@^1.5.3: version "1.5.10" - resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== dependencies: querystringify "^2.1.1" requires-port "^1.0.0" url@^0.11.0: - version "0.11.0" - resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz" - integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + version "0.11.3" + resolved "https://registry.npmjs.org/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" + integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== dependencies: - punycode "1.3.2" - querystring "0.2.0" + punycode "^1.4.1" + qs "^6.11.2" use@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" + resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== username-sync@^1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/username-sync/-/username-sync-1.0.3.tgz" + resolved "https://registry.npmjs.org/username-sync/-/username-sync-1.0.3.tgz#ae41c5c8a4c8c2ecc1443a7d0742742bd7e36732" integrity sha512-m/7/FSqjJNAzF2La448c/aEom0gJy7HY7Y509h6l0ePvEkFictAGptwWaj1msWJ38JbfEDOUoE8kqFee9EHKdA== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util-extend@^1.0.1: version "1.0.3" - resolved "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz" + resolved "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" integrity sha512-mLs5zAK+ctllYBj+iAQvlDCwoxU/WDOUaJkcFudeiAX6OajC6BKXJUa9a+tbtkC11dz2Ufb7h0lyvIOVn4LADA== -util@0.10.3: - version "0.10.3" - resolved "https://registry.npmjs.org/util/-/util-0.10.3.tgz" - integrity sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ== +util@^0.10.4: + version "0.10.4" + resolved "https://registry.npmjs.org/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== dependencies: - inherits "2.0.1" + inherits "2.0.3" util@^0.11.0: version "0.11.1" - resolved "https://registry.npmjs.org/util/-/util-0.11.1.tgz" + resolved "https://registry.npmjs.org/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== dependencies: inherits "2.0.3" utils-merge@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== uuid@^8.3.2: version "8.3.2" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + version "2.4.0" + resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz#cdada8bec61e15865f05d097c5f4fd30e94dc128" + integrity sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw== validate-npm-package-license@^3.0.1: version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: spdx-correct "^3.0.0" @@ -15071,14 +15399,14 @@ validate-npm-package-license@^3.0.1: validate-npm-package-name@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz" + resolved "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== dependencies: builtins "^1.0.3" validate-peer-dependencies@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/validate-peer-dependencies/-/validate-peer-dependencies-1.2.0.tgz" + resolved "https://registry.npmjs.org/validate-peer-dependencies/-/validate-peer-dependencies-1.2.0.tgz#22aab93c514f4fda457d36c80685e8b1160d2036" integrity sha512-nd2HUpKc6RWblPZQ2GDuI65sxJ2n/UqZwSBVtj64xlWjMx0m7ZB2m9b2JS3v1f+n9VWH/dd1CMhkHfP6pIdckA== dependencies: resolve-package-path "^3.1.0" @@ -15086,17 +15414,17 @@ validate-peer-dependencies@^1.2.0: validated-changeset@1.0.0, validated-changeset@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/validated-changeset/-/validated-changeset-1.0.0.tgz" + resolved "https://registry.npmjs.org/validated-changeset/-/validated-changeset-1.0.0.tgz#a961b4a87953b6b12858b0477436360332493f4d" integrity sha512-HeHGkC2BlmWTwtq5DTUMmFX18PAunuLbIs8A4CWoLc58QGKRF4jtR+F5XzP/19xysQXkMApazT2OphqJ+lKVwQ== vary@^1, vary@~1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== vfile-message@^2.0.0: version "2.0.4" - resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== dependencies: "@types/unist" "^2.0.0" @@ -15104,7 +15432,7 @@ vfile-message@^2.0.0: vfile@^4.0.0: version "4.2.1" - resolved "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz" + resolved "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== dependencies: "@types/unist" "^2.0.0" @@ -15114,26 +15442,26 @@ vfile@^4.0.0: vm-browserify@^1.0.1: version "1.1.2" - resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz" + resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== w3c-hr-time@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz" + resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: browser-process-hrtime "^1.0.0" w3c-xmlserializer@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz" + resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== dependencies: xml-name-validator "^3.0.0" walk-sync@^0.2.5: version "0.2.7" - resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-0.2.7.tgz" + resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-0.2.7.tgz#b49be4ee6867657aeb736978b56a29d10fa39969" integrity sha512-OH8GdRMowEFr0XSHQeX5fGweO6zSVHo7bG/0yJQx6LAj9Oukz0C8heI3/FYectT66gY0IPGe89kOvU410/UNpg== dependencies: ensure-posix-path "^1.0.0" @@ -15141,7 +15469,7 @@ walk-sync@^0.2.5: walk-sync@^0.3.0, walk-sync@^0.3.1, walk-sync@^0.3.3: version "0.3.4" - resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.4.tgz" + resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.4.tgz#cf78486cc567d3a96b5b2237c6108017a5ffb9a4" integrity sha512-ttGcuHA/OBnN2pcM6johpYlEms7XpO5/fyKIr48541xXedan4roO8cS1Q2S/zbbjGH/BarYDAMeS2Mi9HE5Tig== dependencies: ensure-posix-path "^1.0.0" @@ -15149,7 +15477,7 @@ walk-sync@^0.3.0, walk-sync@^0.3.1, walk-sync@^0.3.3: walk-sync@^1.0.0, walk-sync@^1.1.3: version "1.1.4" - resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-1.1.4.tgz" + resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-1.1.4.tgz#81049f3d8095479b49574cfa5f558d7a252b127d" integrity sha512-nowc9thB/Jg0KW4TgxoRjLLYRPvl3DB/98S89r4ZcJqq2B0alNcKDh6pzLkBSkPMzRSMsJghJHQi79qw0YWEkA== dependencies: "@types/minimatch" "^3.0.3" @@ -15158,7 +15486,7 @@ walk-sync@^1.0.0, walk-sync@^1.1.3: walk-sync@^2.0.0, walk-sync@^2.0.2, walk-sync@^2.1.0, walk-sync@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz" + resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz#80786b0657fcc8c0e1c0b1a042a09eae2966387a" integrity sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg== dependencies: "@types/minimatch" "^3.0.3" @@ -15168,7 +15496,7 @@ walk-sync@^2.0.0, walk-sync@^2.0.2, walk-sync@^2.1.0, walk-sync@^2.2.0: walk-sync@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-3.0.0.tgz" + resolved "https://registry.npmjs.org/walk-sync/-/walk-sync-3.0.0.tgz#67f882925021e20569a1edd560b8da31da8d171c" integrity sha512-41TvKmDGVpm2iuH7o+DAOt06yyu/cSHpX3uzAwetzASvlNtVddgIjXIb2DfB/Wa20B1Jo86+1Dv1CraSU7hWdw== dependencies: "@types/minimatch" "^3.0.4" @@ -15178,14 +15506,14 @@ walk-sync@^3.0.0: walker@~1.0.5: version "1.0.8" - resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: makeerror "1.0.12" watch-detector@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/watch-detector/-/watch-detector-1.0.2.tgz" + resolved "https://registry.npmjs.org/watch-detector/-/watch-detector-1.0.2.tgz#95deb9189f8c89c0a9f211739cef6d01cffcf452" integrity sha512-MrJK9z7kD5Gl3jHBnnBVHvr1saVGAfmkyyrvuNzV/oe0Gr1nwZTy5VSA0Gw2j2Or0Mu8HcjUa44qlBvC2Ofnpg== dependencies: heimdalljs-logger "^0.1.10" @@ -15194,14 +15522,14 @@ watch-detector@^1.0.0: watchpack-chokidar2@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz" + resolved "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" watchpack@^1.7.4: version "1.7.5" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" @@ -15210,46 +15538,46 @@ watchpack@^1.7.4: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.1" -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff" + integrity sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" wayfarer@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/wayfarer/-/wayfarer-7.0.1.tgz" + resolved "https://registry.npmjs.org/wayfarer/-/wayfarer-7.0.1.tgz#17a64d351d49f9d3d6c508155867df7658184ce3" integrity sha512-yf+kAlOYnJRjLxflLy+1+xEclb6222EAVvAjSY+Yz2qAIDrXeN5wLl/G302Mwv3E0KMg1HT/WDGsvSymX0U7Rw== dependencies: nanoassert "^1.1.0" wcwidth@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" + resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== dependencies: defaults "^1.0.3" webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webidl-conversions@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== webidl-conversions@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" - resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" @@ -15257,13 +15585,13 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1: webpack-sources@^3.2.3: version "3.2.3" - resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^4.43.0: - version "4.46.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz" - integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== + version "4.47.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz#8b8a02152d7076aeb03b61b47dad2eeed9810ebc" + integrity sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ== dependencies: "@webassemblyjs/ast" "1.9.0" "@webassemblyjs/helper-module-context" "1.9.0" @@ -15290,38 +15618,38 @@ webpack@^4.43.0: webpack-sources "^1.4.1" webpack@^5.74.0: - version "5.76.1" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz" - integrity sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ== + version "5.92.1" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz#eca5c1725b9e189cffbd86e8b6c3c7400efc5788" + integrity sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" websocket-driver@>=0.5.1: version "0.7.4" - resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== dependencies: http-parser-js ">=0.5.1" @@ -15330,24 +15658,24 @@ websocket-driver@>=0.5.1: websocket-extensions@>=0.1.1: version "0.1.4" - resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== whatwg-encoding@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz" + resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" whatwg-mimetype@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz" + resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" @@ -15355,7 +15683,7 @@ whatwg-url@^5.0.0: whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: lodash "^4.7.0" @@ -15364,7 +15692,7 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: which-boxed-primitive@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== dependencies: is-bigint "^1.0.1" @@ -15374,99 +15702,98 @@ which-boxed-primitive@^1.0.2: is-symbol "^1.0.3" which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + version "1.0.2" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" which-pm-runs@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz" + resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz#35ccf7b1a0fce87bd8b92a478c9d045785d3bf35" integrity sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA== -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.13, which-typed-array@^1.1.14, which-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" + has-tostringtag "^1.0.2" which@^1.2.14, which@^1.2.9: version "1.3.1" - resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" which@^2.0.1, which@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" wide-align@^1.1.0, wide-align@^1.1.5: version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: string-width "^1.0.2 || 2 || 3 || 4" -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== wordwrap@^0.0.3: version "0.0.3" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" integrity sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw== wordwrap@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" + resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== worker-farm@^1.7.0: version "1.7.0" - resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz" + resolved "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== dependencies: errno "~0.1.7" workerpool@^2.3.0: version "2.3.4" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-2.3.4.tgz" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-2.3.4.tgz#661335ded59a08c01ca009e30cc96929a7b4b0aa" integrity sha512-c2EWrgB9IKHi1jbf4LG9sxKgHYOY+Ej5li6siEGtFecCXWG7eQOqATPEJ0rg1KFETXROEkErc1t5XiNrLG666Q== dependencies: object-assign "4.1.1" workerpool@^3.1.1: version "3.1.2" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-3.1.2.tgz" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-3.1.2.tgz#b34e79243647decb174b7481ab5b351dc565c426" integrity sha512-WJFA0dGqIK7qj7xPTqciWBH5DlJQzoPjsANvc3Y4hNB0SScT+Emjvt0jPPkDBUjBNngX1q9hHgt1Gfwytu6pug== dependencies: "@babel/core" "^7.3.4" object-assign "4.1.1" rsvp "^4.8.4" -workerpool@^6.0.0, workerpool@^6.1.4: - version "6.4.0" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.4.0.tgz" - integrity sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A== +workerpool@^6.0.2, workerpool@^6.1.4, workerpool@^6.1.5: + version "6.5.1" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" @@ -15475,7 +15802,7 @@ wrap-ansi@^6.2.0: wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -15484,7 +15811,7 @@ wrap-ansi@^7.0.0: wrap-legacy-hbs-plugin-if-needed@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/wrap-legacy-hbs-plugin-if-needed/-/wrap-legacy-hbs-plugin-if-needed-1.0.1.tgz" + resolved "https://registry.npmjs.org/wrap-legacy-hbs-plugin-if-needed/-/wrap-legacy-hbs-plugin-if-needed-1.0.1.tgz#6683eb74747f33e7caea54bb2ed85106ef9006b4" integrity sha512-aJjXe5WwrY0u0dcUgKW3m2SGnxosJ66LLm/QaG0YMHqgA6+J2xwAFZfhSLsQ2BmO5x8PTH+OIxoAXuGz3qBA7A== dependencies: "@glimmer/reference" "^0.42.1" @@ -15494,12 +15821,12 @@ wrap-legacy-hbs-plugin-if-needed@^1.0.1: wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^3.0.0: version "3.0.3" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: imurmurhash "^0.1.4" @@ -15508,86 +15835,91 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.4.6: - version "7.5.9" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + version "7.5.10" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@~8.11.0: - version "8.11.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz" - integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== +ws@~8.17.1: + version "8.17.1" + resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== xdg-basedir@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz" + resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== xml-name-validator@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz" + resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== xmlchars@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz" + resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== xmlhttprequest-ssl@^1.6.3: version "1.6.3" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" + resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== -xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: version "4.0.3" - resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" + resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yadda@*: version "2.2.0" - resolved "https://registry.npmjs.org/yadda/-/yadda-2.2.0.tgz" + resolved "https://registry.npmjs.org/yadda/-/yadda-2.2.0.tgz#748a2ae921a968aa5f914324898ccecb1fa5ee32" integrity sha512-TO5YH2XzFZjtInULMZHKTStTOaxRG5hB/nN8qxHOJedsd0HLeqRoP/TW1qKqTeGhIUzq7CVR7iIEFIwerbXIkg== yallist@^3.0.0, yallist@^3.0.2: version "3.1.1" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yam@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/yam/-/yam-1.0.0.tgz" + resolved "https://registry.npmjs.org/yam/-/yam-1.0.0.tgz#7f6c91dc0f5de75a031e6da6b3907c3d25ab0de5" integrity sha512-Hv9xxHtsJ9228wNhk03xnlDReUuWVvHwM4rIbjdAXYvHLs17xjuyF50N6XXFMN6N0omBaqgOok/MCK3At9fTAg== dependencies: fs-extra "^4.0.2" lodash.merge "^4.6.0" -yaml@^1.10.0, yaml@^1.10.2, yaml@^1.9.2: +yaml@^1.10.0, yaml@^1.9.2: version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.3.4: + version "2.4.5" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz#60630b206dd6d84df97003d33fc1ddf6296cca5e" + integrity sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg== + yargs-parser@^20.2.2: version "20.2.9" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs@^16.2.0: version "16.2.0" - resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" + resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== dependencies: cliui "^7.0.2" @@ -15600,10 +15932,10 @@ yargs@^16.2.0: yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zwitch@^1.0.0: version "1.0.5" - resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== From 8d2370da76c067fb424c49a522b263e1b99ec056 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Mon, 8 Jul 2024 18:59:51 -0400 Subject: [PATCH 098/185] [NET-10290] Update ENVOY_VERSIONS (#21524) * [NET-10290] Update ENVOY_VERSIONS * Add changelog entry * Link to CVE for more info in changelog entry Co-authored-by: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> --------- Co-authored-by: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> --- .changelog/21524.txt | 3 +++ envoyextensions/xdscommon/ENVOY_VERSIONS | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .changelog/21524.txt diff --git a/.changelog/21524.txt b/.changelog/21524.txt new file mode 100644 index 0000000000..5f064e5c94 --- /dev/null +++ b/.changelog/21524.txt @@ -0,0 +1,3 @@ +```release-note:security +Upgrade envoy module dependencies to version 1.27.7, 1.28.5 and 1.29.7 or higher to resolve [CVE-2024-39305](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-39305) +``` diff --git a/envoyextensions/xdscommon/ENVOY_VERSIONS b/envoyextensions/xdscommon/ENVOY_VERSIONS index c604e79dc1..eef7f3100e 100644 --- a/envoyextensions/xdscommon/ENVOY_VERSIONS +++ b/envoyextensions/xdscommon/ENVOY_VERSIONS @@ -8,7 +8,7 @@ # # See https://www.consul.io/docs/connect/proxies/envoy#supported-versions for more information on Consul's Envoy # version support. -1.29.5 -1.28.4 -1.27.6 +1.29.7 +1.28.5 +1.27.7 1.26.8 \ No newline at end of file From ab3d5c74ab39df64ffd266ea8b741cf34efd3e23 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 9 Jul 2024 12:21:51 -0400 Subject: [PATCH 099/185] Use debian:12 instead of centos:7 for artifact verification (#21527) CentOS 7 has entered End of Life as of June 30, 2024. Debian 12 is available from Docker and offers linux/386 architecture support --- .github/scripts/verify_artifact.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/verify_artifact.sh b/.github/scripts/verify_artifact.sh index 3aa9e0848d..d3a51ba854 100755 --- a/.github/scripts/verify_artifact.sh +++ b/.github/scripts/verify_artifact.sh @@ -70,11 +70,11 @@ function verify_rpm { case "${artifact_path}" in *.i386.rpm) docker_platform="linux/386" - docker_image="i386/centos:7" + docker_image="debian:12" ;; *.x86_64.rpm) docker_platform="linux/amd64" - docker_image="amd64/centos:7" + docker_image="debian:12" ;; *.armv7hl.rpm) docker_platform="linux/arm/v7" From bc6e889eef4e693a76b18bc274cc9428a90376a2 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 9 Jul 2024 14:58:22 -0400 Subject: [PATCH 100/185] Use vault.centos.org instead of mirror.centos.org (#21530) The latter is no longer resolvable since CentOS 7 is EOL --- .github/scripts/verify_artifact.sh | 7 ++++--- .github/scripts/verify_rpm.sh | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/scripts/verify_artifact.sh b/.github/scripts/verify_artifact.sh index d3a51ba854..cb94726571 100755 --- a/.github/scripts/verify_artifact.sh +++ b/.github/scripts/verify_artifact.sh @@ -70,11 +70,11 @@ function verify_rpm { case "${artifact_path}" in *.i386.rpm) docker_platform="linux/386" - docker_image="debian:12" + docker_image="i386/centos:7" ;; *.x86_64.rpm) docker_platform="linux/amd64" - docker_image="debian:12" + docker_image="amd64/centos:7" ;; *.armv7hl.rpm) docker_platform="linux/arm/v7" @@ -102,7 +102,8 @@ function verify_rpm { ${docker_image} \ /scripts/verify_rpm.sh \ "/workdir/${artifact_path}" \ - "${expect_version}" + "${expect_version}" \ + "${docker_image}" } # Arguments: diff --git a/.github/scripts/verify_rpm.sh b/.github/scripts/verify_rpm.sh index 96cd658eef..844f6a86bd 100755 --- a/.github/scripts/verify_rpm.sh +++ b/.github/scripts/verify_rpm.sh @@ -10,6 +10,10 @@ set -euo pipefail # report why it failed. This is meant to be run as part of the build workflow to verify the built # .rpm meets some basic criteria for validity. +# Notably, CentOS 7 is EOL, so we need to point to the vault for updates. It's not clear what alternative +# we may use in the future that supports linux/386 as the platform was dropped in CentOS 8+9. The docker_image +# is passed in as the third argument so that the script can determine if it needs to point to the vault for updates. + # set this so we can locate and execute the verify_bin.sh script for verifying version output SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" @@ -20,6 +24,7 @@ function usage { function main { local rpm_path="${1:-}" local expect_version="${2:-}" + local docker_image="${3:-}" local got_version if [[ -z "${rpm_path}" ]]; then @@ -34,6 +39,12 @@ function main { exit 1 fi + if [[ -z "${docker_image}" ]]; then + echo "ERROR: docker image argument is required" + usage + exit 1 + fi + # expand globs for path names, if this fails, the script will exit rpm_path=$(echo ${rpm_path}) @@ -43,6 +54,12 @@ function main { exit 1 fi + # CentOS 7 is EOL, so we need to point to the vault for updates + if [[ "$docker_image" == *centos:7 ]]; then + sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* + sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* + fi + yum -y clean all yum -y update yum -y install which openssl From c0faddbe1fbd9669a91011ca23247d3955676a7d Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 10 Jul 2024 10:55:53 -0400 Subject: [PATCH 101/185] [NET-10246] use correct enterprise meta for service name for LinkedService (#21382) * use correct enterprise meta for service name for LinkedService * add changelog --- .changelog/21382.txt | 3 +++ agent/consul/state/catalog.go | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 .changelog/21382.txt diff --git a/.changelog/21382.txt b/.changelog/21382.txt new file mode 100644 index 0000000000..dc59445371 --- /dev/null +++ b/.changelog/21382.txt @@ -0,0 +1,3 @@ +```release-note:bug +terminating-gateway: **(Enterprise Only)** Fixed issue where enterprise metadata applied to linked services was the terminating-gateways enterprise metadata and not the linked services enterprise metadata. +``` diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index ce40fda3e0..dcfe4ec91f 100644 --- a/agent/consul/state/catalog.go +++ b/agent/consul/state/catalog.go @@ -942,7 +942,7 @@ func ensureServiceTxn(tx WriteTxn, idx uint64, node string, preserveIndexes bool } if conf != nil { termGatewayConf := conf.(*structs.TerminatingGatewayConfigEntry) - addrs, err := getTermGatewayVirtualIPs(tx, idx, termGatewayConf.Services, &svc.EnterpriseMeta) + addrs, err := getTermGatewayVirtualIPs(tx, idx, termGatewayConf.Services) if err != nil { return err } @@ -3585,11 +3585,10 @@ func getTermGatewayVirtualIPs( tx WriteTxn, idx uint64, services []structs.LinkedService, - entMeta *acl.EnterpriseMeta, ) (map[string]structs.ServiceAddress, error) { addrs := make(map[string]structs.ServiceAddress, len(services)) for _, s := range services { - sn := structs.ServiceName{Name: s.Name, EnterpriseMeta: *entMeta} + sn := structs.ServiceName{Name: s.Name, EnterpriseMeta: s.EnterpriseMeta} // Terminating Gateways cannot route to services in peered clusters psn := structs.PeeredServiceName{ServiceName: sn, Peer: structs.DefaultPeerKeyword} vip, err := assignServiceVirtualIP(tx, idx, psn) @@ -3606,7 +3605,7 @@ func getTermGatewayVirtualIPs( func updateTerminatingGatewayVirtualIPs(tx WriteTxn, idx uint64, conf *structs.TerminatingGatewayConfigEntry, entMeta *acl.EnterpriseMeta) error { // Build the current map of services with virtual IPs for this gateway services := conf.Services - addrs, err := getTermGatewayVirtualIPs(tx, idx, services, entMeta) + addrs, err := getTermGatewayVirtualIPs(tx, idx, services) if err != nil { return err } From a9d92d020daf4a8fc491beab67d96f7108bcb641 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Thu, 11 Jul 2024 11:15:22 -0400 Subject: [PATCH 102/185] Add changelog entries for 1.15.13, 1.17.6, 1.18.3 and 1.19.1 (#21539) --- CHANGELOG.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd5c2584c9..acc8bbe298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,105 @@ +## 1.19.1 (July 11, 2024) + +SECURITY: + +* Upgrade envoy module dependencies to version 1.27.7, 1.28.5 and 1.29.7 or higher to resolve [CVE-2024-39305](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-39305) [[GH-21524](https://github.com/hashicorp/consul/issues/21524)] +* Upgrade go version to 1.22.5 to address [CVE-2024-24791](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-24791) [[GH-21507](https://github.com/hashicorp/consul/issues/21507)] +* Upgrade go-retryablehttp to address [CVE-2024-6104](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-6104) [[GH-21384](https://github.com/hashicorp/consul/issues/21384)] +* agent: removed reflected cross-site scripting vulnerability [[GH-21342](https://github.com/hashicorp/consul/issues/21342)] +* ui: Pin and namespace sub-module dependencies related to the Consul UI [[GH-21378](https://github.com/hashicorp/consul/issues/21378)] + +IMPROVEMENTS: + +* mesh: update supported envoy version 1.29.5 in addition to 1.28.4, 1.27.6. [[GH-21277](https://github.com/hashicorp/consul/issues/21277)] + +BUG FIXES: + +* core: Fix multiple incorrect type conversion for potential overflows [[GH-21251](https://github.com/hashicorp/consul/issues/21251)] +* core: Fix panic runtime error on AliasCheck [[GH-21339](https://github.com/hashicorp/consul/issues/21339)] +* dns: Fix a regression where DNS SRV questions were returning duplicate hostnames instead of encoded IPs. + This affected Nomad integrations with Consul. [[GH-21361](https://github.com/hashicorp/consul/issues/21361)] +* dns: Fix a regression where DNS tags using the standard lookup syntax, `tag.name.service.consul`, were being disregarded. [[GH-21361](https://github.com/hashicorp/consul/issues/21361)] +* dns: Fixes a spam log message "Failed to parse TTL for prepared query..." + that was always being logged on each prepared query evaluation. [[GH-21381](https://github.com/hashicorp/consul/issues/21381)] +* terminating-gateway: **(Enterprise Only)** Fixed issue where enterprise metadata applied to linked services was the terminating-gateways enterprise metadata and not the linked services enterprise metadata. [[GH-21382](https://github.com/hashicorp/consul/issues/21382)] +* txn: Fix a bug where mismatched Consul server versions could result in undetected data loss for when using newer Transaction verbs. [[GH-21519](https://github.com/hashicorp/consul/issues/21519)] + +## 1.18.3 Enterprise (July 11, 2024) + +**Enterprise LTS**: Consul Enterprise 1.18 is a Long-Term Support (LTS) release. + +SECURITY: + +* Upgrade envoy module dependencies to version 1.27.7, 1.28.5 and 1.29.7 or higher to resolve [CVE-2024-39305](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-39305) [[GH-21524](https://github.com/hashicorp/consul/issues/21524)] +* Upgrade go version to 1.22.5 to address [CVE-2024-24791](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-24791) [[GH-21507](https://github.com/hashicorp/consul/issues/21507)] +* Upgrade go-retryablehttp to address [CVE-2024-6104](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-6104) [[GH-21384](https://github.com/hashicorp/consul/issues/21384)] +* agent: removed reflected cross-site scripting vulnerability [[GH-21342](https://github.com/hashicorp/consul/issues/21342)] +* ui: Pin and namespace sub-module dependencies related to the Consul UI [[GH-21378](https://github.com/hashicorp/consul/issues/21378)] + +IMPROVEMENTS: + +* mesh: update supported envoy version 1.29.4 +* mesh: update supported envoy version 1.29.5 in addition to 1.28.4, 1.27.6. [[GH-21277](https://github.com/hashicorp/consul/issues/21277)] +* upgrade go version to v1.22.3. [[GH-21113](https://github.com/hashicorp/consul/issues/21113)] +* upgrade go version to v1.22.4. [[GH-21265](https://github.com/hashicorp/consul/issues/21265)] + +BUG FIXES: + +* core: Fix multiple incorrect type conversion for potential overflows [[GH-21251](https://github.com/hashicorp/consul/issues/21251)] +* core: Fix panic runtime error on AliasCheck [[GH-21339](https://github.com/hashicorp/consul/issues/21339)] +* dns: Fixes a spam log message "Failed to parse TTL for prepared query..." + that was always being logged on each prepared query evaluation. [[GH-21381](https://github.com/hashicorp/consul/issues/21381)] +* terminating-gateway: **(Enterprise Only)** Fixed issue where enterprise metadata applied to linked services was the terminating-gateways enterprise metadata and not the linked services enterprise metadata. [[GH-21382](https://github.com/hashicorp/consul/issues/21382)] +* txn: Fix a bug where mismatched Consul server versions could result in undetected data loss for when using newer Transaction verbs. [[GH-21519](https://github.com/hashicorp/consul/issues/21519)] +* v2dns: Fix a regression where DNS SRV questions were returning duplicate hostnames instead of encoded IPs. + This affected Nomad integrations with Consul. [[GH-21361](https://github.com/hashicorp/consul/issues/21361)] +* v2dns: Fix a regression where DNS tags using the standard lookup syntax, `tag.name.service.consul`, were being disregarded. [[GH-21361](https://github.com/hashicorp/consul/issues/21361)] + +## 1.17.6 Enterprise (July 11, 2024) + +SECURITY: + +* Upgrade envoy module dependencies to version 1.27.7, 1.28.5 and 1.29.7 or higher to resolve [CVE-2024-39305](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-39305) [[GH-21524](https://github.com/hashicorp/consul/issues/21524)] +* Upgrade go version to 1.22.5 to address [CVE-2024-24791](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-24791) [[GH-21507](https://github.com/hashicorp/consul/issues/21507)] +* Upgrade go-retryablehttp to address [CVE-2024-6104](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-6104) [[GH-21384](https://github.com/hashicorp/consul/issues/21384)] +* agent: removed reflected cross-site scripting vulnerability [[GH-21342](https://github.com/hashicorp/consul/issues/21342)] +* ui: Pin and namespace sub-module dependencies related to the Consul UI [[GH-21378](https://github.com/hashicorp/consul/issues/21378)] + +IMPROVEMENTS: + +* upgrade go version to v1.22.3. [[GH-21113](https://github.com/hashicorp/consul/issues/21113)] +* upgrade go version to v1.22.4. [[GH-21265](https://github.com/hashicorp/consul/issues/21265)] + +BUG FIXES: + +* core: Fix panic runtime error on AliasCheck [[GH-21339](https://github.com/hashicorp/consul/issues/21339)] +* terminating-gateway: **(Enterprise Only)** Fixed issue where enterprise metadata applied to linked services was the terminating-gateways enterprise metadata and not the linked services enterprise metadata. [[GH-21382](https://github.com/hashicorp/consul/issues/21382)] +* txn: Fix a bug where mismatched Consul server versions could result in undetected data loss for when using newer Transaction verbs. [[GH-21519](https://github.com/hashicorp/consul/issues/21519)] + +## 1.15.13 Enterprise (July 11, 2024) + +**Enterprise LTS**: Consul Enterprise 1.15 is a Long-Term Support (LTS) release. + +SECURITY: + +* Upgrade envoy module dependencies to version 1.27.7, 1.28.5 and 1.29.7 or higher to resolve [CVE-2024-39305](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-39305) [[GH-21524](https://github.com/hashicorp/consul/issues/21524)] +* Upgrade go version to 1.22.5 to address [CVE-2024-24791](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-24791) [[GH-21507](https://github.com/hashicorp/consul/issues/21507)] +* Upgrade go-retryablehttp to address [CVE-2024-6104](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-6104) [[GH-21384](https://github.com/hashicorp/consul/issues/21384)] +* agent: removed reflected cross-site scripting vulnerability [[GH-21342](https://github.com/hashicorp/consul/issues/21342)] +* ui: Pin and namespace sub-module dependencies related to the Consul UI [[GH-21378](https://github.com/hashicorp/consul/issues/21378)] + +IMPROVEMENTS: + +* mesh: update supported envoy version 1.29.4 +* upgrade go version to v1.22.3. [[GH-21113](https://github.com/hashicorp/consul/issues/21113)] +* upgrade go version to v1.22.4. [[GH-21265](https://github.com/hashicorp/consul/issues/21265)] + +BUG FIXES: + +* core: Fix panic runtime error on AliasCheck [[GH-21339](https://github.com/hashicorp/consul/issues/21339)] +* terminating-gateway: **(Enterprise Only)** Fixed issue where enterprise metadata applied to linked services was the terminating-gateways enterprise metadata and not the linked services enterprise metadata. [[GH-21382](https://github.com/hashicorp/consul/issues/21382)] +* txn: Fix a bug where mismatched Consul server versions could result in undetected data loss for when using newer Transaction verbs. [[GH-21519](https://github.com/hashicorp/consul/issues/21519)] + ## 1.19.0 (June 12, 2024) BREAKING CHANGES: From 654528ca60ca1836d0bfe3f19a345ab840bbab62 Mon Sep 17 00:00:00 2001 From: Aimee Ukasick Date: Thu, 18 Jul 2024 12:02:45 -0500 Subject: [PATCH 103/185] DOCS: CE-556 Add partition parameter to API endpoint docs (#21374) * CD-556 rename partition partial that's only used in CLI Update CLI pages for partial rename API: Add partial for partition as body option API: Add partial for partition as query parameter Update API peering and members pages * acl/auth-methods.mdx Update partition partials to be generic * binding-rules.mdx, policies.mdx * roles.mdx, templated-policies.mdx * tokens.mdx, catalog.mdx, config.mdx, intentions.mdx * service.mdx, exported-services.mdx, kv.mdx, namespaces.mdx * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Add partial to acl/auth-methods.mdx Fix headings indent in a few files. * Update website/content/api-docs/acl/auth-methods.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- website/content/api-docs/acl/auth-methods.mdx | 17 +++++++++--- .../content/api-docs/acl/binding-rules.mdx | 14 ++++++++-- website/content/api-docs/acl/policies.mdx | 12 ++++++++- website/content/api-docs/acl/roles.mdx | 12 +++++++++ .../api-docs/acl/templated-policies.mdx | 2 ++ website/content/api-docs/acl/tokens.mdx | 12 +++++++++ website/content/api-docs/agent/index.mdx | 2 ++ website/content/api-docs/agent/service.mdx | 4 +++ website/content/api-docs/catalog.mdx | 4 +++ website/content/api-docs/config.mdx | 8 ++++++ .../content/api-docs/connect/intentions.mdx | 12 +++++++++ .../content/api-docs/exported-services.mdx | 3 +-- website/content/api-docs/kv.mdx | 6 +++++ website/content/api-docs/namespaces.mdx | 27 ++++++++++++++----- website/content/api-docs/peering.mdx | 16 ++++------- .../commands/acl/auth-method/create.mdx | 2 +- .../commands/acl/auth-method/delete.mdx | 2 +- .../content/commands/acl/auth-method/list.mdx | 2 +- .../content/commands/acl/auth-method/read.mdx | 2 +- .../commands/acl/auth-method/update.mdx | 2 +- .../commands/acl/binding-rule/create.mdx | 2 +- .../commands/acl/binding-rule/delete.mdx | 2 +- .../commands/acl/binding-rule/list.mdx | 2 +- .../commands/acl/binding-rule/read.mdx | 2 +- .../commands/acl/binding-rule/update.mdx | 2 +- .../content/commands/acl/policy/create.mdx | 2 +- .../content/commands/acl/policy/delete.mdx | 2 +- website/content/commands/acl/policy/list.mdx | 2 +- website/content/commands/acl/policy/read.mdx | 2 +- .../content/commands/acl/policy/update.mdx | 2 +- website/content/commands/acl/role/create.mdx | 2 +- website/content/commands/acl/role/delete.mdx | 2 +- website/content/commands/acl/role/list.mdx | 2 +- website/content/commands/acl/role/read.mdx | 2 +- website/content/commands/acl/role/update.mdx | 2 +- .../commands/acl/templated-policy/preview.mdx | 2 +- website/content/commands/acl/token/clone.mdx | 2 +- website/content/commands/acl/token/create.mdx | 2 +- website/content/commands/acl/token/delete.mdx | 2 +- website/content/commands/acl/token/list.mdx | 2 +- website/content/commands/acl/token/read.mdx | 2 +- website/content/commands/acl/token/update.mdx | 2 +- website/content/commands/catalog/nodes.mdx | 2 +- website/content/commands/catalog/services.mdx | 2 +- website/content/commands/config/delete.mdx | 2 +- website/content/commands/config/list.mdx | 2 +- website/content/commands/config/read.mdx | 2 +- website/content/commands/config/write.mdx | 2 +- website/content/commands/connect/envoy.mdx | 2 +- .../commands/connect/redirect-traffic.mdx | 2 +- website/content/commands/intention/check.mdx | 2 +- website/content/commands/intention/create.mdx | 2 +- website/content/commands/intention/delete.mdx | 2 +- website/content/commands/intention/get.mdx | 2 +- website/content/commands/intention/match.mdx | 2 +- website/content/commands/kv/delete.mdx | 2 +- website/content/commands/kv/export.mdx | 2 +- website/content/commands/kv/get.mdx | 2 +- website/content/commands/kv/import.mdx | 2 +- website/content/commands/kv/put.mdx | 2 +- website/content/commands/members.mdx | 2 +- website/content/commands/namespace/create.mdx | 2 +- website/content/commands/namespace/delete.mdx | 2 +- website/content/commands/namespace/list.mdx | 2 +- website/content/commands/namespace/read.mdx | 2 +- website/content/commands/namespace/update.mdx | 2 +- website/content/commands/namespace/write.mdx | 2 +- website/content/commands/peering/delete.mdx | 2 +- .../content/commands/peering/establish.mdx | 2 +- .../commands/peering/exported-services.mdx | 2 +- .../commands/peering/generate-token.mdx | 2 +- website/content/commands/peering/list.mdx | 2 +- website/content/commands/peering/read.mdx | 2 +- .../content/commands/services/deregister.mdx | 2 +- website/content/commands/services/export.mdx | 2 +- .../commands/services/exported-services.mdx | 2 +- .../content/commands/services/register.mdx | 2 +- .../cli-http-api-partition-options.mdx | 1 + .../http-api-body-options-partition.mdx | 2 ++ .../http-api-query-parms-partition.mdx | 1 + .../partials/http_api_partition_options.mdx | 1 - 81 files changed, 190 insertions(+), 90 deletions(-) create mode 100644 website/content/partials/cli-http-api-partition-options.mdx create mode 100644 website/content/partials/http-api-body-options-partition.mdx create mode 100644 website/content/partials/http-api-query-parms-partition.mdx delete mode 100644 website/content/partials/http_api_partition_options.mdx diff --git a/website/content/api-docs/acl/auth-methods.mdx b/website/content/api-docs/acl/auth-methods.mdx index 805a9ee93c..34f59cb866 100644 --- a/website/content/api-docs/acl/auth-methods.mdx +++ b/website/content/api-docs/acl/auth-methods.mdx @@ -107,6 +107,8 @@ The corresponding CLI command is [`consul acl auth-method create`](/consul/comma prefixed-${serviceaccount.name} ``` +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -175,9 +177,11 @@ The corresponding CLI command is [`consul acl auth-method read`](/consul/command ### Query Parameters -- `ns` `(string: "")` - Specifies the namespace of the auth method you lookup. +- `ns` `(string: "")` - Specifies the namespace of the auth method you look up. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -291,9 +295,11 @@ The corresponding CLI command is [`consul acl auth-method update`](/consul/comma same values that are usable by the `Selector` syntax. For example: ```text - prefixed-${serviceaccount.name} + prefixed-${serviceaccount.name} ``` +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -369,6 +375,8 @@ The corresponding CLI command is [`consul acl auth-method delete`](/consul/comma - `ns` `(string: "")` - Specifies the namespace of the auth method you delete. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -408,8 +416,9 @@ The corresponding CLI command is [`consul acl auth-method list`](/consul/command The namespace may be specified as '\*' to return results for all namespaces. You can also [specify the namespace through other methods](#methods-to-specify-namespace). -The namespace may be specified as '\*' and then - results will be returned for all namespaces. + The namespace may be specified as '\*' and then results are returned for all namespaces. + +@include 'http-api-query-parms-partition.mdx' ## Sample Request diff --git a/website/content/api-docs/acl/binding-rules.mdx b/website/content/api-docs/acl/binding-rules.mdx index 9894ce21c7..34edeadc4a 100644 --- a/website/content/api-docs/acl/binding-rules.mdx +++ b/website/content/api-docs/acl/binding-rules.mdx @@ -172,6 +172,8 @@ The corresponding CLI command is [`consul acl binding-rule create`](/consul/comm This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -238,6 +240,8 @@ The corresponding CLI command is [`consul acl binding-rule read`](/consul/comman - `ns` `(string: "")` - Specifies the namespace of the binding rule you lookup. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -423,6 +427,8 @@ The corresponding CLI command is [`consul acl binding-rule update`](/consul/comm This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -489,6 +495,8 @@ The corresponding CLI command is [`consul acl binding-rule delete`](/consul/comm - `ns` `(string: "")` - Specifies the namespace of the binding rule you delete. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -522,7 +530,7 @@ The table below shows this endpoint's support for The corresponding CLI command is [`consul acl binding-rule list`](/consul/commands/acl/binding-rule/list). -## Query Parameters +### Query Parameters - `authmethod` `(string: "")` - Filters the binding rule list to those binding rules that are linked with the specific named auth method. @@ -531,7 +539,9 @@ The corresponding CLI command is [`consul acl binding-rule list`](/consul/comman The namespace may be specified as '\*' to return results for all namespaces. You can also [specify the namespace through other methods](#methods-to-specify-namespace). -## Sample Request +@include 'http-api-query-parms-partition.mdx' + +### Sample Request ```shell-session $ curl --request GET http://127.0.0.1:8500/v1/acl/binding-rules diff --git a/website/content/api-docs/acl/policies.mdx b/website/content/api-docs/acl/policies.mdx index c41583626b..1d46fa1b51 100644 --- a/website/content/api-docs/acl/policies.mdx +++ b/website/content/api-docs/acl/policies.mdx @@ -57,6 +57,8 @@ The corresponding CLI command is [`consul acl policy create`](/consul/commands/a This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -170,6 +172,8 @@ The corresponding CLI command is [`consul acl policy read -name=`](/cons - `ns` `(string: "")` - Specifies the namespace of the policy you lookup. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -242,6 +246,8 @@ The corresponding CLI command is [`consul acl policy update`](/consul/commands/a This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -307,6 +313,8 @@ The corresponding CLI command is [`consul acl policy delete`](/consul/commands/a - `ns` `(string: "")` - Specifies the namespace of the policy you delete. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -346,7 +354,9 @@ The corresponding CLI command is [`consul acl policy list`](/consul/commands/acl The namespace may be specified as '\*' to return results for all namespaces. You can also [specify the namespace through other methods](#methods-to-specify-namespace). -## Sample Request +@include 'http-api-query-parms-partition.mdx' + +### Sample Request ```shell-session $ curl --request GET http://127.0.0.1:8500/v1/acl/policies diff --git a/website/content/api-docs/acl/roles.mdx b/website/content/api-docs/acl/roles.mdx index fbcb8d8b72..e54e9a54b0 100644 --- a/website/content/api-docs/acl/roles.mdx +++ b/website/content/api-docs/acl/roles.mdx @@ -95,6 +95,8 @@ The corresponding CLI command is [`consul acl role create`](/consul/commands/acl This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -223,6 +225,8 @@ The corresponding CLI command is [`consul acl role read`](/consul/commands/acl/r - `ns` `(string: "")` - Specifies the namespace of the role you lookup. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -306,6 +310,8 @@ The corresponding CLI command is [`consul acl role read -name=`](/consul - `ns` `(string: "")` - Specifies the namespace of the role you lookup. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -418,6 +424,8 @@ The corresponding CLI command is [`consul acl role update`](/consul/commands/acl This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -523,6 +531,8 @@ The corresponding CLI command is [`consul acl role delete`](/consul/commands/acl - `ns` `(string: "")` - Specifies the namespace of the role you delete. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -565,6 +575,8 @@ The corresponding CLI command is [`consul acl role list`](/consul/commands/acl/r The namespace may be specified as '\*' to return results for all namespaces. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ## Sample Request ```shell-session diff --git a/website/content/api-docs/acl/templated-policies.mdx b/website/content/api-docs/acl/templated-policies.mdx index 5805449dd5..de3a6b59ae 100644 --- a/website/content/api-docs/acl/templated-policies.mdx +++ b/website/content/api-docs/acl/templated-policies.mdx @@ -87,6 +87,8 @@ The corresponding CLI command is [`consul acl templated-policy preview`](/consul - `Name` `(string: )` - Specifies the value of the `name` variable in the templated policy variables. +@include 'http-api-body-options-partition.mdx' + ### Sample payload ```json diff --git a/website/content/api-docs/acl/tokens.mdx b/website/content/api-docs/acl/tokens.mdx index a741ec3a70..af629a3500 100644 --- a/website/content/api-docs/acl/tokens.mdx +++ b/website/content/api-docs/acl/tokens.mdx @@ -118,6 +118,8 @@ The corresponding CLI command is [`consul acl token create`](/consul/commands/ac This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -217,6 +219,8 @@ The corresponding CLI command is [`consul acl token read`](/consul/commands/acl/ - `expanded` `(bool: false)` - If this field is set, the contents of all policies and roles affecting the token will also be returned. +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -497,6 +501,8 @@ The corresponding CLI command is [`consul acl token update`](/consul/commands/ac This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -591,6 +597,8 @@ The corresponding CLI command is [`consul acl token clone`](/consul/commands/acl This field takes precedence over the `ns` query parameter, one of several [other methods to specify the namespace](#methods-to-specify-namespace). +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -668,6 +676,8 @@ The corresponding CLI command is [`consul acl token delete`](/consul/commands/ac - `ns` `(string: "")` - Specifies the namespace of the token you delete. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -723,6 +733,8 @@ The corresponding CLI command is [`consul acl token list`](/consul/commands/acl/ The namespace may be specified as '\*' to return results for all namespaces. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/agent/index.mdx b/website/content/api-docs/agent/index.mdx index d76cc19107..749ea80f29 100644 --- a/website/content/api-docs/agent/index.mdx +++ b/website/content/api-docs/agent/index.mdx @@ -261,6 +261,8 @@ The corresponding CLI command is [`consul members`](/consul/commands/members). network segment). When querying a server, setting this to the special string `_all` will show members in all segments. +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/agent/service.mdx b/website/content/api-docs/agent/service.mdx index eee3dd471e..3018274182 100644 --- a/website/content/api-docs/agent/service.mdx +++ b/website/content/api-docs/agent/service.mdx @@ -684,6 +684,8 @@ The `/agent/service/register` endpoint supports camel case and _snake case_ for `false`. See [anti-entropy syncs](/consul/docs/architecture/anti-entropy) for additional information. +@include 'http-api-body-options-partition.mdx' + #### Connect Structure For the `Connect` field, the parameters are: @@ -769,6 +771,8 @@ The corresponding CLI command is [`consul services deregister`](/consul/commands - `ns` `(string: "")` - Specifies the namespace of the service you deregister. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/catalog.mdx b/website/content/api-docs/catalog.mdx index 8af4a2f011..8c549b3043 100644 --- a/website/content/api-docs/catalog.mdx +++ b/website/content/api-docs/catalog.mdx @@ -327,6 +327,8 @@ The corresponding CLI command is [`consul catalog nodes`](/consul/commands/catal - `filter` `(string: "")` - Specifies the expression used to filter the queries results prior to returning the data. +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -422,6 +424,8 @@ The corresponding CLI command is [`consul catalog services`](/consul/commands/ca - `filter` `(string: "")` - Specifies the expression used to filter the queries results prior to returning the data. +@include 'http-api-query-parms-partition.mdx' + ### Filtering The filter will be executed against each Service mapping within the catalog. diff --git a/website/content/api-docs/config.mdx b/website/content/api-docs/config.mdx index 79407b325a..49243da094 100644 --- a/website/content/api-docs/config.mdx +++ b/website/content/api-docs/config.mdx @@ -71,6 +71,8 @@ The ACL required depends on the config entry being written: - `ns` `(string: "")` - Specifies the namespace of the config entry you apply. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Payload ```json @@ -150,6 +152,8 @@ The ACL required depends on the config entry kind being read: - `ns` `(string: "")` - Specifies the namespace of the config entry you lookup You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -228,6 +232,8 @@ The corresponding CLI command is [`consul config list`](/consul/commands/config/ - `ns` `(string: "")` - Specifies the namespace of the config entries you lookup. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -321,6 +327,8 @@ The corresponding CLI command is [`consul config delete`](/consul/commands/confi - `ns` `(string: "")` - Specifies the namespace of the config entry you delete. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/connect/intentions.mdx b/website/content/api-docs/connect/intentions.mdx index ebe835ac90..95a5cfca60 100644 --- a/website/content/api-docs/connect/intentions.mdx +++ b/website/content/api-docs/connect/intentions.mdx @@ -60,6 +60,8 @@ The corresponding CLI command is [`consul intention create -replace`](/consul/co as shown in the [source and destination naming conventions](/consul/commands/intention#source-and-destination-naming). You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### JSON Request Body Schema - `SourceType` `(string: "")` - The type for the `SourceName` value. @@ -151,6 +153,8 @@ The corresponding CLI command is [`consul intention create`](/consul/commands/in as shown in the [source and destination naming conventions](/consul/commands/intention#source-and-destination-naming). You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### JSON Request Body Schema - `SourceName` `(string: )` - The source of the intention. @@ -290,6 +294,8 @@ The corresponding CLI command is [`consul intention get`](/consul/commands/inten as shown in the [source and destination naming conventions](/consul/commands/intention#source-and-destination-naming). You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -404,6 +410,8 @@ The corresponding CLI command is [`consul intention list`](/consul/commands/inte The `*` wildcard may be used to list intentions from all namespaces. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -485,6 +493,8 @@ The corresponding CLI command is [`consul intention delete`](/consul/commands/in as shown in the [source and destination naming conventions](/consul/commands/intention#source-and-destination-naming). You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -628,6 +638,8 @@ The corresponding CLI command is [`consul intention match`](/consul/commands/int as shown in the [source and destination naming conventions](/consul/commands/intention#source-and-destination-naming). You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/exported-services.mdx b/website/content/api-docs/exported-services.mdx index aa6521f62f..f7c89d4999 100644 --- a/website/content/api-docs/exported-services.mdx +++ b/website/content/api-docs/exported-services.mdx @@ -36,8 +36,7 @@ The table below shows this endpoint's support for ### Query Parameters -- `partition` `(string: "")` - Specifies the admin partition the services are exported from. When not specified, assumes the default value `default`. - +@include 'http-api-query-parms-partition.mdx' ### Sample Request diff --git a/website/content/api-docs/kv.mdx b/website/content/api-docs/kv.mdx index 29aa32cbe6..912a8b6944 100644 --- a/website/content/api-docs/kv.mdx +++ b/website/content/api-docs/kv.mdx @@ -79,6 +79,8 @@ The corresponding CLI command is [`consul kv get`](/consul/commands/kv/get). For recursive lookups, the namespace may be specified as '\*' to return results for all namespaces. +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -220,6 +222,8 @@ The corresponding CLI command is [`consul kv put`](/consul/commands/kv/put). - `ns` `(string: "")` - Specifies the namespace to query. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Payload The payload is arbitrary, and is loaded directly into Consul as supplied. @@ -289,6 +293,8 @@ The corresponding CLI command is [`consul kv delete`](/consul/commands/kv/delete - `ns` `(string: "")` - Specifies the namespace to query. You can also [specify the namespace through other methods](#methods-to-specify-namespace). +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/namespaces.mdx b/website/content/api-docs/namespaces.mdx index 2dd41a7e9b..8c963d80a9 100644 --- a/website/content/api-docs/namespaces.mdx +++ b/website/content/api-docs/namespaces.mdx @@ -67,6 +67,8 @@ The corresponding CLI command is [`consul namespace create`](/consul/commands/na - `Meta` `(map: )` - Specifies arbitrary KV metadata to associate with the namespace. +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -169,6 +171,10 @@ The corresponding CLI command is [`consul namespace read`](/consul/commands/name - `name` `(string: )` - Specifies the namespace to read. +### Query Parameters + +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -272,6 +278,8 @@ The corresponding CLI command is [`consul namespace update`](/consul/commands/na - `Meta` `(map: )` - Specifies arbitrary KV metadata to associate with the namespace. +@include 'http-api-body-options-partition.mdx' + ### Sample Payload ```json @@ -348,18 +356,15 @@ $ curl --request PUT \ ## Delete a Namespace -This endpoint marks a Namespace for deletion. Once marked Consul will -deleted all the associated Namespaced data in the background. Only once -all associated data has been deleted will the Namespace actually disappear. -Until then, further reads can be performed on the namespace and a `DeletedAt` -field will now be populated with the timestamp of when the Namespace was -marked for deletion. +This endpoint marks a Namespace for deletion. Once marked, Consul deletes all the associated Namespaced data in the background. Only after all associated data has been deleted, Consul deletes the Namespace. +Until then, you can perform further reads on the namespace, and a `DeletedAt` +field is populated with the timestamp of when the Namespace was marked for deletion. | Method | Path | Produces | | -------- | ------------------ | -------- | | `DELETE` | `/namespace/:name` | N/A | -This endpoint will return no data. Success or failure is indicated by the status +This endpoint returns no data. Success or failure is indicated by the status code returned. The table below shows this endpoint's support for @@ -378,6 +383,10 @@ The corresponding CLI command is [`consul namespace delete`](/consul/commands/na - `name` `(string: )` - Specifies the namespace to delete. +### Query Parameters + +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session @@ -449,6 +458,10 @@ the request has been granted any access in the namespace (read, list or write). The corresponding CLI command is [`consul namespace list`](/consul/commands/namespace/list). +### Query Parameters + +@include 'http-api-query-parms-partition.mdx' + ### Sample Request ```shell-session diff --git a/website/content/api-docs/peering.mdx b/website/content/api-docs/peering.mdx index 7604cb6a19..f0e4d77677 100644 --- a/website/content/api-docs/peering.mdx +++ b/website/content/api-docs/peering.mdx @@ -34,8 +34,7 @@ The table below shows this endpoint's support for and configuration entries such as `service-intentions`. This field must be a valid DNS hostname label. -- `Partition` `(string: "")` - The admin partition that the - peering token is generated from. Uses `default` when not specified. +@include 'http-api-body-options-partition.mdx' - `ServerExternalAddresses` `([]string: )` - The addresses for the cluster that generates the peering token. Addresses take the form `{host or IP}:port`. You can specify one or more load balancers or external IPs that route external traffic to this cluster's Consul servers. @@ -100,9 +99,7 @@ The table below shows this endpoint's support for and configuration entries such as `service-intentions`. This field must be a valid DNS hostname label. -- `Partition` `(string: "")` - The admin partition - that peers to the cluster that generated the peering token. Uses `default` - when not specified. +@include 'http-api-body-options-partition.mdx' - `PeeringToken` `(string: )` - The peering token fetched from the peer cluster. @@ -162,8 +159,7 @@ The table below shows this endpoint's support for ### Query Parameters -- `partition` `(string: "")` - Specifies the partition of the peering - to read. If not specified will default to `default`. +@include 'http-api-query-parms-partition.mdx' ### Sample Request @@ -235,8 +231,7 @@ The table below shows this endpoint's support for ### Query Parameters -- `partition` `(string: "")` - Specifies the partition of the peerings - to delete. If not specified will default to `default`. +@include 'http-api-query-parms-partition.mdx' ### Sample Request @@ -286,8 +281,7 @@ The table below shows this endpoint's support for ### Query Parameters -- `partition` `(string: "")` - Specifies the partition of the peerings - to list. If not specified will default to `default`. +@include 'http-api-query-parms-partition.mdx' ### Sample Request diff --git a/website/content/commands/acl/auth-method/create.mdx b/website/content/commands/acl/auth-method/create.mdx index 7a7ef7ea70..4f1015cfb6 100644 --- a/website/content/commands/acl/auth-method/create.mdx +++ b/website/content/commands/acl/auth-method/create.mdx @@ -67,7 +67,7 @@ Usage: `consul acl auth-method create [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/auth-method/delete.mdx b/website/content/commands/acl/auth-method/delete.mdx index fc2e166d36..acb095c587 100644 --- a/website/content/commands/acl/auth-method/delete.mdx +++ b/website/content/commands/acl/auth-method/delete.mdx @@ -31,7 +31,7 @@ Usage: `consul acl auth-method delete [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/auth-method/list.mdx b/website/content/commands/acl/auth-method/list.mdx index c7d2c0b9c2..42d7285ca7 100644 --- a/website/content/commands/acl/auth-method/list.mdx +++ b/website/content/commands/acl/auth-method/list.mdx @@ -34,7 +34,7 @@ Usage: `consul acl auth-method list` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/auth-method/read.mdx b/website/content/commands/acl/auth-method/read.mdx index 928863846d..015852f968 100644 --- a/website/content/commands/acl/auth-method/read.mdx +++ b/website/content/commands/acl/auth-method/read.mdx @@ -36,7 +36,7 @@ Usage: `consul acl auth-method read [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/auth-method/update.mdx b/website/content/commands/acl/auth-method/update.mdx index aef12ff351..d328ea999c 100644 --- a/website/content/commands/acl/auth-method/update.mdx +++ b/website/content/commands/acl/auth-method/update.mdx @@ -72,7 +72,7 @@ Usage: `consul acl auth-method update [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/binding-rule/create.mdx b/website/content/commands/acl/binding-rule/create.mdx index 38b2ffb57d..b32b2ce934 100644 --- a/website/content/commands/acl/binding-rule/create.mdx +++ b/website/content/commands/acl/binding-rule/create.mdx @@ -47,7 +47,7 @@ Usage: `consul acl binding-rule create [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/binding-rule/delete.mdx b/website/content/commands/acl/binding-rule/delete.mdx index c78e360310..9164f62a7c 100644 --- a/website/content/commands/acl/binding-rule/delete.mdx +++ b/website/content/commands/acl/binding-rule/delete.mdx @@ -32,7 +32,7 @@ Usage: `consul acl binding-rule delete [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/binding-rule/list.mdx b/website/content/commands/acl/binding-rule/list.mdx index 9d01e9d2b1..cbb9c184c8 100644 --- a/website/content/commands/acl/binding-rule/list.mdx +++ b/website/content/commands/acl/binding-rule/list.mdx @@ -34,7 +34,7 @@ Usage: `consul acl binding-rule list` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/binding-rule/read.mdx b/website/content/commands/acl/binding-rule/read.mdx index 86b8b4169c..50f1e8112f 100644 --- a/website/content/commands/acl/binding-rule/read.mdx +++ b/website/content/commands/acl/binding-rule/read.mdx @@ -37,7 +37,7 @@ Usage: `consul acl binding-rule read [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/binding-rule/update.mdx b/website/content/commands/acl/binding-rule/update.mdx index e33b7e026d..22ad67e0cf 100644 --- a/website/content/commands/acl/binding-rule/update.mdx +++ b/website/content/commands/acl/binding-rule/update.mdx @@ -54,7 +54,7 @@ Usage: `consul acl binding-rule update [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/policy/create.mdx b/website/content/commands/acl/policy/create.mdx index cbd4b8d875..e178536515 100644 --- a/website/content/commands/acl/policy/create.mdx +++ b/website/content/commands/acl/policy/create.mdx @@ -49,7 +49,7 @@ Usage: `consul acl policy create [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/policy/delete.mdx b/website/content/commands/acl/policy/delete.mdx index 074dfea607..2b611f5a78 100644 --- a/website/content/commands/acl/policy/delete.mdx +++ b/website/content/commands/acl/policy/delete.mdx @@ -34,7 +34,7 @@ Usage: `consul acl policy delete [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/policy/list.mdx b/website/content/commands/acl/policy/list.mdx index 7d56fd6f21..ad3b114b97 100644 --- a/website/content/commands/acl/policy/list.mdx +++ b/website/content/commands/acl/policy/list.mdx @@ -34,7 +34,7 @@ Usage: `consul acl policy list` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/policy/read.mdx b/website/content/commands/acl/policy/read.mdx index b84b5d3c34..28e2f51a79 100644 --- a/website/content/commands/acl/policy/read.mdx +++ b/website/content/commands/acl/policy/read.mdx @@ -39,7 +39,7 @@ Usage: `consul acl policy read [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/policy/update.mdx b/website/content/commands/acl/policy/update.mdx index f64a1f7906..edc529a5da 100644 --- a/website/content/commands/acl/policy/update.mdx +++ b/website/content/commands/acl/policy/update.mdx @@ -58,7 +58,7 @@ Usage: `consul acl policy update [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/role/create.mdx b/website/content/commands/acl/role/create.mdx index 44af92bd4e..82989a2697 100644 --- a/website/content/commands/acl/role/create.mdx +++ b/website/content/commands/acl/role/create.mdx @@ -52,7 +52,7 @@ Usage: `consul acl role create [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/role/delete.mdx b/website/content/commands/acl/role/delete.mdx index bb2a179d92..9a39e97ab8 100644 --- a/website/content/commands/acl/role/delete.mdx +++ b/website/content/commands/acl/role/delete.mdx @@ -34,7 +34,7 @@ Usage: `consul acl role delete [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/role/list.mdx b/website/content/commands/acl/role/list.mdx index ed3699ce3f..afd8c75a41 100644 --- a/website/content/commands/acl/role/list.mdx +++ b/website/content/commands/acl/role/list.mdx @@ -34,7 +34,7 @@ Usage: `consul acl role list` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/role/read.mdx b/website/content/commands/acl/role/read.mdx index 7de17d5dcb..aa5008f57d 100644 --- a/website/content/commands/acl/role/read.mdx +++ b/website/content/commands/acl/role/read.mdx @@ -39,7 +39,7 @@ Usage: `consul acl role read [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/role/update.mdx b/website/content/commands/acl/role/update.mdx index d6991a21e0..1308e445ba 100644 --- a/website/content/commands/acl/role/update.mdx +++ b/website/content/commands/acl/role/update.mdx @@ -63,7 +63,7 @@ Usage: `consul acl role update [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/templated-policy/preview.mdx b/website/content/commands/acl/templated-policy/preview.mdx index 7e0c38d165..cfffa6db7e 100644 --- a/website/content/commands/acl/templated-policy/preview.mdx +++ b/website/content/commands/acl/templated-policy/preview.mdx @@ -36,7 +36,7 @@ Usage: `consul acl templated-policy preview [options] [args]` ### Enterprise options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/token/clone.mdx b/website/content/commands/acl/token/clone.mdx index 7f2822d6c5..937097fb28 100644 --- a/website/content/commands/acl/token/clone.mdx +++ b/website/content/commands/acl/token/clone.mdx @@ -38,7 +38,7 @@ Usage: `consul acl token clone [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/token/create.mdx b/website/content/commands/acl/token/create.mdx index f0622ace7e..8cd5fb6b94 100644 --- a/website/content/commands/acl/token/create.mdx +++ b/website/content/commands/acl/token/create.mdx @@ -66,7 +66,7 @@ Usage: `consul acl token create [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/token/delete.mdx b/website/content/commands/acl/token/delete.mdx index 5ba6595758..13a3ca26e6 100644 --- a/website/content/commands/acl/token/delete.mdx +++ b/website/content/commands/acl/token/delete.mdx @@ -32,7 +32,7 @@ Usage: `consul acl token delete [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/token/list.mdx b/website/content/commands/acl/token/list.mdx index 531b4cc68e..fd3b6c2151 100644 --- a/website/content/commands/acl/token/list.mdx +++ b/website/content/commands/acl/token/list.mdx @@ -34,7 +34,7 @@ Usage: `consul acl token list` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/token/read.mdx b/website/content/commands/acl/token/read.mdx index e339292d96..dfcbea12d8 100644 --- a/website/content/commands/acl/token/read.mdx +++ b/website/content/commands/acl/token/read.mdx @@ -43,7 +43,7 @@ Usage: `consul acl token read [options] [args]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/acl/token/update.mdx b/website/content/commands/acl/token/update.mdx index 1a1703cb14..1f89d82864 100644 --- a/website/content/commands/acl/token/update.mdx +++ b/website/content/commands/acl/token/update.mdx @@ -93,7 +93,7 @@ instead. #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/catalog/nodes.mdx b/website/content/commands/catalog/nodes.mdx index f612627be2..6efa3ad071 100644 --- a/website/content/commands/catalog/nodes.mdx +++ b/website/content/commands/catalog/nodes.mdx @@ -85,7 +85,7 @@ Usage: `consul catalog nodes [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/catalog/services.mdx b/website/content/commands/catalog/services.mdx index 9d05ecbf47..a57adcb4a9 100644 --- a/website/content/commands/catalog/services.mdx +++ b/website/content/commands/catalog/services.mdx @@ -69,7 +69,7 @@ Usage: `consul catalog services [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/config/delete.mdx b/website/content/commands/config/delete.mdx index 134d6885e6..085b0e34c4 100644 --- a/website/content/commands/config/delete.mdx +++ b/website/content/commands/config/delete.mdx @@ -61,7 +61,7 @@ config entry. This is used in combination with the -cas flag. @include 'http_api_namespace_options.mdx' -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/config/list.mdx b/website/content/commands/config/list.mdx index e453b11943..5f55a7bcff 100644 --- a/website/content/commands/config/list.mdx +++ b/website/content/commands/config/list.mdx @@ -48,7 +48,7 @@ Usage: `consul config list [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/config/read.mdx b/website/content/commands/config/read.mdx index 7a49482c5b..c54a60dfec 100644 --- a/website/content/commands/config/read.mdx +++ b/website/content/commands/config/read.mdx @@ -52,7 +52,7 @@ Usage: `consul config read [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/config/write.mdx b/website/content/commands/config/write.mdx index bb98d8e498..f466654c61 100644 --- a/website/content/commands/config/write.mdx +++ b/website/content/commands/config/write.mdx @@ -53,7 +53,7 @@ Usage: `consul config write [options] FILE` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/connect/envoy.mdx b/website/content/commands/connect/envoy.mdx index 744873df56..913adb981d 100644 --- a/website/content/commands/connect/envoy.mdx +++ b/website/content/commands/connect/envoy.mdx @@ -199,7 +199,7 @@ compatibility with Envoy and prevent potential issues. Default is `false`. #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/connect/redirect-traffic.mdx b/website/content/commands/connect/redirect-traffic.mdx index af59baee56..d59fe7928c 100644 --- a/website/content/commands/connect/redirect-traffic.mdx +++ b/website/content/commands/connect/redirect-traffic.mdx @@ -60,7 +60,7 @@ Usage: `consul connect redirect-traffic [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/intention/check.mdx b/website/content/commands/intention/check.mdx index fadc8d224b..23ae56ceae 100644 --- a/website/content/commands/intention/check.mdx +++ b/website/content/commands/intention/check.mdx @@ -41,7 +41,7 @@ Usage: `consul intention check [options] SRC DST` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/intention/create.mdx b/website/content/commands/intention/create.mdx index 71c491b06a..bbaccc2be2 100644 --- a/website/content/commands/intention/create.mdx +++ b/website/content/commands/intention/create.mdx @@ -52,7 +52,7 @@ are not supported from commands, but may be from the corresponding HTTP endpoint #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/intention/delete.mdx b/website/content/commands/intention/delete.mdx index ad2fca1c97..2cfb97a966 100644 --- a/website/content/commands/intention/delete.mdx +++ b/website/content/commands/intention/delete.mdx @@ -37,7 +37,7 @@ Usage: #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/intention/get.mdx b/website/content/commands/intention/get.mdx index 84b3a86065..b3db133fd4 100644 --- a/website/content/commands/intention/get.mdx +++ b/website/content/commands/intention/get.mdx @@ -37,7 +37,7 @@ Usage: #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/intention/match.mdx b/website/content/commands/intention/match.mdx index 4c727b1fc2..3d94939b38 100644 --- a/website/content/commands/intention/match.mdx +++ b/website/content/commands/intention/match.mdx @@ -40,7 +40,7 @@ Usage: `consul intention match [options] SRC_OR_DST` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/kv/delete.mdx b/website/content/commands/kv/delete.mdx index 90e2e54624..17216b0ca7 100644 --- a/website/content/commands/kv/delete.mdx +++ b/website/content/commands/kv/delete.mdx @@ -40,7 +40,7 @@ Usage: `consul kv delete [options] KEY_OR_PREFIX` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/kv/export.mdx b/website/content/commands/kv/export.mdx index da063e9d82..c05b2f80f8 100644 --- a/website/content/commands/kv/export.mdx +++ b/website/content/commands/kv/export.mdx @@ -28,7 +28,7 @@ Usage: `consul kv export [options] [PREFIX]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/kv/get.mdx b/website/content/commands/kv/get.mdx index 0e83b2facb..6534fe3548 100644 --- a/website/content/commands/kv/get.mdx +++ b/website/content/commands/kv/get.mdx @@ -56,7 +56,7 @@ Usage: `consul kv get [options] [KEY_OR_PREFIX]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/kv/import.mdx b/website/content/commands/kv/import.mdx index 574fdfbd87..a960b1b738 100644 --- a/website/content/commands/kv/import.mdx +++ b/website/content/commands/kv/import.mdx @@ -31,7 +31,7 @@ Usage: `consul kv import [options] [DATA]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/kv/put.mdx b/website/content/commands/kv/put.mdx index efb045179f..dcde811fc0 100644 --- a/website/content/commands/kv/put.mdx +++ b/website/content/commands/kv/put.mdx @@ -59,7 +59,7 @@ Usage: `consul kv put [options] KEY [DATA]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/members.mdx b/website/content/commands/members.mdx index ff1df561a6..6299f21e4c 100644 --- a/website/content/commands/members.mdx +++ b/website/content/commands/members.mdx @@ -56,7 +56,7 @@ Usage: `consul members [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/namespace/create.mdx b/website/content/commands/namespace/create.mdx index f5d611a542..068666e5ca 100644 --- a/website/content/commands/namespace/create.mdx +++ b/website/content/commands/namespace/create.mdx @@ -61,7 +61,7 @@ from the CLI arguments. #### API Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_options_client.mdx' diff --git a/website/content/commands/namespace/delete.mdx b/website/content/commands/namespace/delete.mdx index 8742af6f4d..adc235be60 100644 --- a/website/content/commands/namespace/delete.mdx +++ b/website/content/commands/namespace/delete.mdx @@ -30,7 +30,7 @@ Usage: `consul namespace delete ` #### API Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_options_client.mdx' diff --git a/website/content/commands/namespace/list.mdx b/website/content/commands/namespace/list.mdx index 5d15c1f115..1b043ed657 100644 --- a/website/content/commands/namespace/list.mdx +++ b/website/content/commands/namespace/list.mdx @@ -42,7 +42,7 @@ Usage: `consul namespace list` #### API Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_options_client.mdx' diff --git a/website/content/commands/namespace/read.mdx b/website/content/commands/namespace/read.mdx index 4a4621ef06..778f672ff5 100644 --- a/website/content/commands/namespace/read.mdx +++ b/website/content/commands/namespace/read.mdx @@ -41,7 +41,7 @@ Usage: `consul namespace read ` #### API Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_options_client.mdx' diff --git a/website/content/commands/namespace/update.mdx b/website/content/commands/namespace/update.mdx index 6349d307f6..4cce122356 100644 --- a/website/content/commands/namespace/update.mdx +++ b/website/content/commands/namespace/update.mdx @@ -68,7 +68,7 @@ with the existing namespace definition. #### API Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_options_client.mdx' diff --git a/website/content/commands/namespace/write.mdx b/website/content/commands/namespace/write.mdx index 678c303a80..f1a16ec006 100644 --- a/website/content/commands/namespace/write.mdx +++ b/website/content/commands/namespace/write.mdx @@ -40,7 +40,7 @@ or HCL format. See [here](/consul/docs/enterprise/namespaces#namespace-definitio #### API Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_options_client.mdx' diff --git a/website/content/commands/peering/delete.mdx b/website/content/commands/peering/delete.mdx index 81ba3439db..1bd474dc30 100644 --- a/website/content/commands/peering/delete.mdx +++ b/website/content/commands/peering/delete.mdx @@ -34,7 +34,7 @@ Usage: `consul peering delete [options] -name ` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/peering/establish.mdx b/website/content/commands/peering/establish.mdx index a00dc33218..782fb9cda6 100644 --- a/website/content/commands/peering/establish.mdx +++ b/website/content/commands/peering/establish.mdx @@ -36,7 +36,7 @@ Usage: `consul peering establish [options] -name -peering-token ` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/peering/generate-token.mdx b/website/content/commands/peering/generate-token.mdx index 92d007125c..6ce3fb059c 100644 --- a/website/content/commands/peering/generate-token.mdx +++ b/website/content/commands/peering/generate-token.mdx @@ -43,7 +43,7 @@ You can specify one or more load balancers or external IPs that route external t #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/peering/list.mdx b/website/content/commands/peering/list.mdx index f0b1c83777..9838de3e7b 100644 --- a/website/content/commands/peering/list.mdx +++ b/website/content/commands/peering/list.mdx @@ -30,7 +30,7 @@ Usage: `consul peering list [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/peering/read.mdx b/website/content/commands/peering/read.mdx index 596c514520..95a41b2701 100644 --- a/website/content/commands/peering/read.mdx +++ b/website/content/commands/peering/read.mdx @@ -31,7 +31,7 @@ Usage: `consul peering read [options] -name ` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/services/deregister.mdx b/website/content/commands/services/deregister.mdx index edc493866e..138de2e763 100644 --- a/website/content/commands/services/deregister.mdx +++ b/website/content/commands/services/deregister.mdx @@ -43,7 +43,7 @@ This flexibility makes it easy to pair the command with the #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/services/export.mdx b/website/content/commands/services/export.mdx index 281d5f23e7..370f95dd64 100644 --- a/website/content/commands/services/export.mdx +++ b/website/content/commands/services/export.mdx @@ -40,7 +40,7 @@ Usage: consul services export [options] -name -consumer-peers ` - A comma-separated list of admin partitions within the same datacenter to export the service to. This flag is optional when `-consumer-peers` is specified. -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/commands/services/exported-services.mdx b/website/content/commands/services/exported-services.mdx index da1d3dd177..395ad2cb8b 100644 --- a/website/content/commands/services/exported-services.mdx +++ b/website/content/commands/services/exported-services.mdx @@ -32,7 +32,7 @@ Usage: `consul services exported-services [options]` #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' #### API Options diff --git a/website/content/commands/services/register.mdx b/website/content/commands/services/register.mdx index a1cbd8cf58..01a09d19bf 100644 --- a/website/content/commands/services/register.mdx +++ b/website/content/commands/services/register.mdx @@ -78,7 +78,7 @@ The following fields specify identical parameters in a standard service definiti #### Enterprise Options -@include 'http_api_partition_options.mdx' +@include 'cli-http-api-partition-options.mdx' @include 'http_api_namespace_options.mdx' diff --git a/website/content/partials/cli-http-api-partition-options.mdx b/website/content/partials/cli-http-api-partition-options.mdx new file mode 100644 index 0000000000..eb96310a37 --- /dev/null +++ b/website/content/partials/cli-http-api-partition-options.mdx @@ -0,0 +1 @@ +- `-partition=` - Specifies the admin partition to query. If not provided, the partition is inferred from the request's ACL token, or defaults to the `default` partition. diff --git a/website/content/partials/http-api-body-options-partition.mdx b/website/content/partials/http-api-body-options-partition.mdx new file mode 100644 index 0000000000..cf2acd813c --- /dev/null +++ b/website/content/partials/http-api-body-options-partition.mdx @@ -0,0 +1,2 @@ + +- `Partition` `(string: "")` - The admin partition to use. If not provided, the partition is inferred from the request's ACL token, or defaults to the `default` partition. \ No newline at end of file diff --git a/website/content/partials/http-api-query-parms-partition.mdx b/website/content/partials/http-api-query-parms-partition.mdx new file mode 100644 index 0000000000..8d954d86c5 --- /dev/null +++ b/website/content/partials/http-api-query-parms-partition.mdx @@ -0,0 +1 @@ +- `partition` `(string: "")` - The admin partition to use. If not provided, the partition is inferred from the request's ACL token, or defaults to the `default` partition. \ No newline at end of file diff --git a/website/content/partials/http_api_partition_options.mdx b/website/content/partials/http_api_partition_options.mdx deleted file mode 100644 index a290c38201..0000000000 --- a/website/content/partials/http_api_partition_options.mdx +++ /dev/null @@ -1 +0,0 @@ -- `-partition=` - Specifies the partition to query. If not provided, the partition will be inferred from the request's ACL token, or will default to the `default` partition. Partitions are a Consul Enterprise feature added in v1.11.0. From 5a74bb6d5a1e96ac3e94d55dd44660b2a29e4513 Mon Sep 17 00:00:00 2001 From: Krastin Krastev Date: Mon, 22 Jul 2024 16:43:36 +0300 Subject: [PATCH 104/185] docs/WAF: failure zones refresh (#21545) * failure zones initial commit * Apply suggestions from code review Co-authored-by: Aimee Ukasick Co-authored-by: danielehc <40759828+danielehc@users.noreply.github.com> * Update improving-consul-resilience.mdx Co-authored-by: Aimee Ukasick * typo * adding diagrams * fixing inline bulletpoint image * adding light and dark diagrams * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * fix links in article * fix inline alert render --------- Co-authored-by: Aimee Ukasick Co-authored-by: danielehc <40759828+danielehc@users.noreply.github.com> Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- .../improving-consul-resilience.mdx | 113 ++++++++++++------ .../cluster-peering-diagram-dark.png | Bin 0 -> 57893 bytes .../cluster-peering-diagram-light.png | Bin 0 -> 57916 bytes .../architecture/cluster-peering-diagram.png | Bin 0 -> 30403 bytes .../consul-redundancy-zones-dark.png | Bin 0 -> 58422 bytes .../consul-redundancy-zones-light.png | Bin 0 -> 57001 bytes .../consul-singleDC-redundancyzones.png | Bin 0 -> 54779 bytes 7 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 website/public/img/architecture/cluster-peering-diagram-dark.png create mode 100644 website/public/img/architecture/cluster-peering-diagram-light.png create mode 100644 website/public/img/architecture/cluster-peering-diagram.png create mode 100644 website/public/img/architecture/consul-redundancy-zones-dark.png create mode 100644 website/public/img/architecture/consul-redundancy-zones-light.png create mode 100644 website/public/img/architecture/consul-singleDC-redundancyzones.png diff --git a/website/content/docs/architecture/improving-consul-resilience.mdx b/website/content/docs/architecture/improving-consul-resilience.mdx index bfcc9a8be4..aea40f3558 100644 --- a/website/content/docs/architecture/improving-consul-resilience.mdx +++ b/website/content/docs/architecture/improving-consul-resilience.mdx @@ -5,21 +5,19 @@ description: >- Fault tolerance is a system's ability to operate without interruption despite component failure. Learn how a set of Consul servers provide fault tolerance through use of a quorum, and how to further improve control plane resilience through use of infrastructure zones and Enterprise redundancy zones. --- -# Fault Tolerance +# Fault tolerance + + +You must give careful consideration to reliability in the architecture frameworks that you build. When you build a resilient platform, it minimizes the remediation actions you need to take when a failure occurs. This document provides useful information on how to design and operate a resilient Consul cluster, including the methods and functionalities for this goal. + +Consul has many features that operate both locally and remotely that can help you offer a resilient service across multiple datacenters. + + +## Introduction Fault tolerance is the ability of a system to continue operating without interruption -despite the failure of one or more components. -The most basic production deployment of Consul has 3 server agents and can lose a single -server without interruption. +despite the failure of one or more components. In Consul, the number of server agents determines the fault tolerance. -As you continue to use Consul, your circumstances may change. -Perhaps a datacenter becomes more business critical or risk management policies change, -necessitating an increase in fault tolerance. -The sections below discuss options for how to improve Consul's fault tolerance. - -## Fault Tolerance in Consul - -Consul's fault tolerance is determined by the configuration of its voting server agents. Each Consul datacenter depends on a set of Consul voting server agents. The voting servers ensure Consul has a consistent, fault-tolerant state @@ -42,28 +40,25 @@ number of servers, quorum, and fault tolerance, refer to the [consensus protocol documentation](/consul/docs/architecture/consensus#deployment_table). Effectively mitigating your risk is more nuanced than just increasing the fault tolerance -metric described above. You must consider: +because the infrastructure costs can outweigh the improved resiliency. You must also consider correlated risks at the infrastructure-level. There are occasions when multiple servers fail at the same time. That means that a single failure could cause a Consul outage, even if your server-level fault tolerance is 2. -### Correlated Risks +Different options for your resilient datacenter present trade-offs between operational complexity, computing cost, and Consul request performance. Consider these factors when designing your resilient architecture. -Are you protected against correlated risks? Infrastructure-level failures can cause multiple servers to fail at the same time. This means that a single infrastructure-level failure could cause a Consul outage, even if your server-level fault tolerance is 2. +## Fault tolerance -### Mitigation Costs +The following sections explore several options for increasing Consul's fault tolerance. For enhanced reliability, we recommend taking a holistic approach by layering these multiple functionalities together. -What are the costs of the mitigation? Different mitigation options present different trade-offs for operational complexity, computing cost, and Consul request performance. +- Spread servers across infrastructure [availability zones](#availability-zones). +- Use a [minimum quorum size](#quorum-size) to avoid performance impacts. +- Use [redundancy zones](#redundancy-zones) to improve fault tolerance. +- Use [Autopilot](#autopilot) to automatically prune failed servers and maintain quorum size. +- Use [cluster peering](#cluster-peering) to provide service redundancy. -## Strategies to Increase Fault Tolerance +### Availability zones -The following sections explore several options for increasing Consul's fault tolerance. -HashiCorp recommends all production deployments consider: -- [Spreading Consul servers across availability zones](#spread-servers-across-infrastructure-availability-zones) -- Using backup voting servers to replace lost voters +The cloud or on-premise infrastructure underlying your [Consul datacenter](/consul/docs/install/glossary#datacenter) can run across multiple availability zones. -### Spread Servers Across Infrastructure Availability Zones - -The cloud or on-premise infrastructure underlying your [Consul datacenter](/consul/docs/install/glossary#datacenter) -may be split into several "availability zones". An availability zone is meant to share no points of failure with other zones by: - Having power, cooling, and networking systems independent from other zones - Being physically distant enough from other zones so that large-scale disruptions @@ -79,25 +74,25 @@ To distribute your Consul servers across availability zones, modify your infrast Additionally, you should leverage resources that can automatically restore your compute instance, such as autoscaling groups, virtual machine scale sets, or compute engine autoscaler. -The autoscaling resources can be customized to re-deploy servers into specific availability zones -and ensure the desired numbers of servers are available at all time. +Customize autoscaling resources to re-deploy servers into specific availability zones and ensure the desired numbers of servers are available at all times. -### Add More Voting Servers +### Quorum size -For most production use cases, we recommend using either 3 or 5 voting servers, +For most production use cases, we recommend using a minimum quorum of either 3 or 5 voting servers, yielding a server-level fault tolerance of 1 or 2 respectively. Even though it would improve fault tolerance, adding voting servers beyond 5 is **not recommended** because it decreases Consul's performance— it requires Consul to involve more servers in every state change or consistent read. -Consul Enterprise provides a way to improve fault tolerance without this performance penalty: -[using backup voting servers to replace lost voters](#use-backup-voting-servers-to-replace-lost-voters). +Consul Enterprise users can use redundancy zones to improve fault tolerance without this performance penalty. -### Use Backup Voting Servers to Replace Lost Voters +### Redundancy zones -Consul Enterprise [redundancy zones](/consul/docs/enterprise/redundancy) -can be used to improve fault tolerance without the performance penalty of increasing the number of voting servers. +Use Consul Enterprise [redundancy zones](/consul/docs/enterprise/redundancy) to improve fault tolerance without the performance penalty of increasing the number of voting servers. + +![Reference architecture diagram for Consul Redundancy zones](/img/architecture/consul-redundancy-zones-light.png#light-theme-only) +![Reference architecture diagram for Consul Redundancy zones](/img/architecture/consul-redundancy-zones-dark.png#dark-theme-only) Each redundancy zone should be assigned 2 or more Consul servers. If all servers are healthy, only one server per redundancy zone will be an active voter; @@ -132,3 +127,51 @@ For more information on redundancy zones, refer to: for a more detailed explanation - [Redundancy zone tutorial](/consul/tutorials/enterprise/redundancy-zones) to learn how to use them + +### Autopilot + +Autopilot is a set of functions that introduce servers to a cluster, cleans up dead servers, and monitors the state of the Raft protocol in the Consul cluster. + +When you enable Autopilot's dead server cleanup, Autopilot marks failed servers as `Left` and removes them from the Raft peer set to prevent them from interfering with the quorum size. Autopilot does that as soon as a replacement Consul server comes online. This behavior is beneficial when server nodes failed and have been redeployed but Consul considers them as new nodes because their IP address and hostnames have changed. Autopilot keeps the cluster peer set size correct and the quorum requirement simple. + +To illustrate the Autopilot advantage, consider a scenario where Consul has a cluster of five server nodes. The quorum is three, which means the cluster can lose two server nodes before the cluster fails. The following events happen: + +1. Two server nodes fail. +1. Two replacement nodes are deployed with new hostnames and IPs. +1. The two replacement nodes rejoin the Consul cluster. +1. Consul treats the replacement nodes as extra nodes, unrelated to the previously failed nodes. + +_With Autopilot not enabled_, the following happens: + +1. Consul does not immediately clean up the failed nodes when the replacement nodes join the cluster. +1. The cluster now has the three surviving nodes, the two failed nodes, and the two replacement nodes, for a total of seven nodes. + - The quorum is increased to four, which means the cluster can only afford to lose one node until after the two failed nodes are deleted in seventy-two hours. + - The redundancy level has decreased from its initial state. + +_With Autopilot enabled_, the following happens: + +1. Consul immediately cleans up the failed nodes when the replacement nodes join the cluster. +1. The cluster now has the three surviving nodes and the two replacement nodes, for a total of five nodes. + - The quorum stays at three, which means the cluster can afford to lose two nodes before it fails. + - The redundancy level remains the same. + +### Cluster peering + +Linking multiple Consul clusters together to provide service redundancy is the most effective method to prevent disruption from failure. This method is enhanced when you design individual Consul clusters with resilience in mind. Consul clusters interconnect in two ways: WAN federation and cluster peering. We recommend using cluster peering whenever possible. + +Cluster peering lets you connect two or more independent Consul clusters using mesh gateways, so that services can communicate between non-identical partitions in different datacenters. + +![Reference architecture diagram for Consul cluster peering](/img/architecture/cluster-peering-diagram-light.png#light-theme-only) +![Reference architecture diagram for Consul cluster peering](/img/architecture/cluster-peering-diagram-dark.png#dark-theme-only) + +Cluster peering is the preferred way to interconnect clusters because it is operationally easier to configure and manage than WAN federation. Cluster peering communication between two datacenters runs only on one port on the related Consul mesh gateway, which makes it operationally easy to expose for routing purposes. + +When you use cluster peering to connect admin partitions between datacenters, use Consul’s dynamic traffic management functionalities `service-splitter`, `service-router` and `service-failover` to configure your service mesh to automatically forward or failover service traffic between peer clusters. Consul can then manage the traffic intended for the service and do [failover](/consul/docs/connect/config-entries/service-resolver#spec-failover), [load-balancing](/consul/docs/connect/config-entries/service-resolver#spec-loadbalancer), or [redirection](/consul/docs/connect/config-entries/service-resolver#spec-redirect). + +Cluster peering also extends service discovery across different datacenters independent of service mesh functions. After you peer datacenters, you can refer to services between datacenters with `.virtual.peer.consul` in Consul DNS. For Consul Enterprise, your query string may need to include the namespace, partition, or both. Refer to the [Consul DNS documentation](/consul/docs/services/discovery/dns-static-lookups#service-virtual-ip-lookups) for details on building virtual service lookups. + +For more information on cluster peering, refer to: +- [Cluster peering documentation](/consul/docs/connect/cluster-peering) + for a more detailed explanation +- [Cluster peering tutorial](/consul/tutorials/implement-multi-tenancy/cluster-peering) + to learn how to implement cluster peering diff --git a/website/public/img/architecture/cluster-peering-diagram-dark.png b/website/public/img/architecture/cluster-peering-diagram-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..2c414a7e39441bde755e66024a58fb31b490727f GIT binary patch literal 57893 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

9>l>V!lFL?V-urIY0PCO-Oh@yRGpVuh=itG3}_v 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 literal 0 HcmV?d00001 diff --git a/website/public/img/architecture/cluster-peering-diagram-light.png b/website/public/img/architecture/cluster-peering-diagram-light.png new file mode 100644 index 0000000000000000000000000000000000000000..3d0a5959e8b08844ea0062eaeda1839e4e9ea470 GIT binary patch literal 57916 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

+j#M0|9GV z#?9@#V6SsVlYrrQ(HT7orI<_Y+xI~CYYOFQzx*3tV@ zt0%6OT;L8i4_jd>C1MaZMene;YFu4h6p0K1wL}d3cJ)kjkN^)L+JXL+HBc!tk%-`t zE>I_toAJ-Li;3D`)2&kXzEROkoeU}n?uG8;n#LiTD~TK(w@G;!OT7Cmq$I1Z&7Hhl zJ%XA?F8?^o4Z(<)+lwhWrRI4am92~#SQnV(UM5aFZ-4_zI*|Hdh}3DHb$66k5h&XK z9Fg_t@c1IVkn6}Cl;i}|JiQMkp%c*8JF3`O0_RBk^XIttsSXUYkN5IzT3XTpe3*CK zA6$O7QXO1ZC#M>O$)qImNCXbbErv29(1P|;8kJ@dQKHV?6R-<5=s35j4A0azxK5}BR14a>;3m#tKW{sPGK}!`BZDzBMK0I7&)!QUHIXmiv3LSLE z9i-`bM^!cNh`_b96y)O%RXX?KQ*HKrReB6!g~1<0*;84z zhj~{zu=T5*WQez#0<2rHr)wYvQ};Kez3Pz=Y?vz^( zJ0~w=Q7*a-mIUSTRN{m({z^!F=680R3k+XU$9j;R)5EYYvArqQz43S+P``s}2vy+@ zX;hqc%;^ve2kVO3Fy3b+vLe%Ou*(*pJ_%Gw#ievRQq!A7B{b-qrZmBb8)tMN9*Za$ z5+-e#I;gglKGETYU(QDMuKQE7q?Wtvt!Yrc*c4WT?;iR~Tiva9ZV7Ix&KoqMzieO7 z{2l*1yAD1)zx*mta|+nMfBk{z{Dt6S@mKrz$GGPY1|OPV704j_{8!`m|9-@Ouf>0# j3vheE{ro?2M-F|7@f&35P!{MYv_lolp7 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 literal 0 HcmV?d00001 diff --git a/website/public/img/architecture/consul-redundancy-zones-dark.png b/website/public/img/architecture/consul-redundancy-zones-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c7c5ba065b204b48f41b29f123c11989bf257742 GIT binary patch literal 58422 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⁢7L3m#5vfiI=KaO3qHWnn0Nb{E|$ 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

v>=BK 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 z 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 PCJyW7 Date: Wed, 24 Jul 2024 13:56:44 -0400 Subject: [PATCH 105/185] [NET-7787] Update JWT docs for APIGateway (#20800) * Update k8s docs * Update jwt docs with examples * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update docs to follow style guide, use CodeBlockConfig, remove section to apply the configuration for k8s docs * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --- .../secure-traffic/verify-jwts-k8s.mdx | 180 ++++++++++++++++-- .../secure-traffic/verify-jwts-vms.mdx | 151 ++++++++++++++- 2 files changed, 311 insertions(+), 20 deletions(-) diff --git a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx index 7aaded1fe2..87fd27dae8 100644 --- a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx +++ b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx @@ -14,16 +14,17 @@ This topic describes how to use JSON web tokens (JWT) to verify requests to API You can configure API gateways to use JWTs to verify incoming requests so that you can stop unverified traffic at the gateway. You can configure JWT verification at different levels: -- Listener defaults: Define basic defaults that apply to all routes attached to a listener. +- Listener defaults: Define basic defaults in a GatewayPolicy resource to apply them to all routes attached to a listener. - HTTP route-specific settings: You can define JWT authentication settings for specific HTTP routes. Route-specific JWT settings override default listener configurations. -- Listener overrides: Define override settings that take precedence over default and route-specific configurations. This enables you to set enforceable policies for listeners. +- Listener overrides: Define override settings in a GatewayPolicy resource that take precedence over default and route-specific configurations. Use override settings to set enforceable policies for listeners. Complete the following steps to use JWTs to verify requests: -1. Define a policy that specifies default and override settings for API gateway listeners and attach it to the gateway. -1. Define an HTTP route auth filter that specifies route-specific JWT verification settings. -1. Attach the auth filter to the HTTP route values file. +1. Define a JWTProvider that specifies the JWT provider and claims used to verify requests to the gateway. +1. Define a GatewayPolicy that specifies default and override settings for API gateway listeners and attach it to the gateway. +1. Define a RouteAuthFilter that specifies route-specific JWT verification settings. +1. Reference the RouteAuthFilter from the HTTPRoute. 1. Apply the configurations. @@ -33,9 +34,34 @@ Complete the following steps to use JWTs to verify requests: - Consul on Kubernetes CLI or Helm chart v1.3.0+ - JWT details, such as claims and provider -## Define override and default settings -Create a `GatewayPolicy` values file and configure the following fields to define default and override settings for JWT verification. Refer to [`GatewayPolicy` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/gatewaypolicy) for details. +## Define a JWTProvider + +Create a `JWTProvider` CRD that defines the JWT provider to verify claims against. + +In the following example, the JWTProvider CRD contains a local JWKS. In production environments, use a production-grade JWKs endpoint instead. + + + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: JWTProvider +metadata: + name: local +spec: + issuer: local + jsonWebKeySet: + local: + jwks: "" +``` + + + +For more information about the fields you can configure in this CRD, refer to [`JWTProvider` configuration reference](/consul/docs/connect/config-entries/jwtprovider). + +## Define a GatewayPolicy + +Create a `GatewayPolicy` CRD that defines default and override settings for JWT verification. - `kind`: Must be set to `GatewayPolicy` - `metadata.name`: Specifies a name for the policy. @@ -46,29 +72,155 @@ Create a `GatewayPolicy` values file and configure the following fields to defin - `spec.targetRef.override.jwt.providers`: Specifies a list of providers and claims used to verify requests to the gateway. The override settings take precedence over the default and route-specific JWT verification settings. - `spec.targetRef.default.jwt.providers`: Specifies a list of default providers and claims used to verify requests to the gateway. -## Define an HTTP route auth filter +The following examples configure a Gateway and the GatewayPolicy being attached to it so that every request coming through the listener must meet these conditions: -Create an `RouteAuthFilter` values file and configure the following fields. Refer to [`RouteAuthFilter` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/routeauthfilter) for details. +- The request must be signed by the `local` provider +- The request must have a claim of `role` with a value of `user` unless the HTTPRoute attached to the listener overrides it + + + + + + +```yaml +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: api-gateway +spec: + gatewayClassName: consul + listeners: + - protocol: HTTP + port: 30002 + name: listener-one +``` + + + + + + + + + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: GatewayPolicy +metadata: + name: gw-policy +spec: + targetRef: + name: api-gateway + sectionName: listener-one + group: gateway.networking.k8s.io/v1beta1 + kind: Gateway + override: + jwt: + providers: + - name: "local" + default: + jwt: + providers: + - name: "local" + verifyClaims: + - path: + - role + value: user +``` + + + + + + +For more information about the fields you can configure, refer to [`GatewayPolicy` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/gatewaypolicy). + +## Define a RouteAuthFilter + +Create an `RouteAuthFilter` CRD that defines overrides for the default JWT verification configured in the GatewayPolicy. - `kind`: Must be set to `RouteAuthFilter` - `metadata.name`: Specifies a name for the filter. - `metadata.namespace`: Specifies the Consul namespace the filter applies to. - `spec.jwt.providers`: Specifies a list of providers and claims used to verify requests to the gateway. The override settings take precedence over the default and route-specific JWT verification settings. +In the following example, the RouteAuthFilter overrides default settings set in the GatewayPolicy so that every request coming through the listener must meet these conditions: + +- The request must be signed by the `local` provider +- The request must have a `role` claim +- The value of the claim must be `admin` + + + +```yaml +apiVersion: consul.hashicorp.com/v1alpha1 +kind: RouteAuthFilter +metadata: + name: auth-filter +spec: + jwt: + providers: + - name: local + verifyClaims: + - path: + - role + value: admin +``` + + + +For more information about the fields you can configure, refer to [`RouteAuthFilter` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/routeauthfilter). + ## Attach the auth filter to your HTTP routes -In the `filters` field of your HTTP route configuration, add the following fields. Refer to the [`extensionRef` configuration reference](/consul/docs/connect/gateways/api-gateway/configuration/routes#rules-filters-extensionref) for details: +In the `filters` field of your HTTPRoute configuration, define the filter behavior that results from JWT verification. - `type: extensionRef`: Declare list of extension references. - `extensionRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kubernetes.io`. - `extensionRef.kind`: Specifies the type of extension reference to attach to the route. Must be `RouteAuthFilter` - `extensionRef.name`: Specifies the name of the auth filter. -## Apply the configurations +The following example configures an HTTPRoute so that every request to `api-gateway-fqdn:3002/admin` must meet these conditions: -Run the `kubectl apply` command and specify the values files to apply the configurations. The following example applies the values files stored in the `jwt-routes` directory: +- The request be signed by the `local` provider. +- The request must have a `role` claim. +- The value of the claim must be `admin`. -```shell-session -$ kubectl apply -f jwt-routes +Every other request must be signed by the `local` provider and have a claim of `role` with a value of `user`, as defined in the GatewayPolicy. + + + +```yaml +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-route +spec: + parentRefs: + - name: api-gateway + rules: + - matches: + - path: + type: PathPrefix + value: /admin + filters: + - type: ExtensionRef + extensionRef: + group: consul.hashicorp.com + kind: RouteAuthFilter + name: auth-filter + backendRefs: + - kind: Service + name: admin + port: 8080 + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - kind: Service + name: user-service + port: 8081 ``` + diff --git a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx index f58d92621a..fda579669f 100644 --- a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx +++ b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx @@ -20,6 +20,7 @@ You can configure API gateways to use JWTs to verify incoming requests so that y Complete the following steps to use JWTs to verify requests: +1. Define a JWTProvider that specifies the JWT provider and claims used to verify requests to the gateway. 1. Configure default and override settings for listeners in the API gateway configuration entry. 1. Define route-specific JWT verification settings as filters in the HTTP route configuration entries. 1. Write the configuration entries to Consul to begin verifying requests using JWTs. @@ -29,17 +30,155 @@ Complete the following steps to use JWTs to verify requests: - Consul 1.17 or later - JWT details, such as claims and provider +## Define a JWTProvider + +Create a JWTProvider config entry that defines the JWT provider to verify claims against. +In the following example, the JWTProvider CRD contains a local JWKS. In production environments, use a production-grade JWKs endpoint instead. + + + +```hcl +Kind = "jwt-provider" +Name = "local" + +Issuer = "local" + +JSONWebKeySet = { + Local = { + JWKS="" + } +} +``` + + + +For more information about the fields you can configure in this CRD, refer to [`JWTProvider` configuration reference](/consul/docs/connect/config-entries/jwtprovider). + ## Configure default and override settings -Define default and override settings for JWT verification in the [API gateway configuration entry](/consul/docs/connect/gateways/api-gateway/configuration/api-gateway). +Define default and override settings for JWT verification in the [API gateway configuration entry](/consul/docs/connect/gateways/api-gateway/configuration/api-gateway). -1. Add a `default.JWT` block to the listener that you want to apply JWT verification to. Consul applies these configurations to routes attached to the listener. Refer to the [`Listeners.default.JWT`](/consul/docs/connect/config-entries/api-gateway#listeners-default-jwt) configuration reference for details. -1. Add an `override.JWT` block to the listener that you want to apply JWT verification policies to. Consul applies these configurations to all routes attached to the listener, regardless of the `default` or route-specific settings. Refer to the [`Listeners.override.JWT`](/consul/docs/connect/config-entries/api-gateway#listeners-override-jwt) configuration reference for details. -1. Apply the settings in the API gateway configuration entry. You can use the [`/config` API endpoint](/consul/api-docs/config#apply-configuration) or the [`consul config write` command](/consul/commands/config/write). +1. Add a `default.JWT` block to the listener that you want to apply JWT verification to. Consul applies these configurations to routes attached to the listener. Refer to the [`Listeners.default.JWT`](/consul/docs/connect/config-entries/api-gateway#listeners-default-jwt) configuration reference for details. +1. Add an `override.JWT` block to the listener that you want to apply JWT verification policies to. Consul applies these configurations to all routes attached to the listener, regardless of the `default` or route-specific settings. Refer to the [`Listeners.override.JWT`](/consul/docs/connect/config-entries/api-gateway#listeners-override-jwt) configuration reference for details. +1. Apply the settings in the API gateway configuration entry. You can use the [`/config` API endpoint](/consul/api-docs/config#apply-configuration) or the [`consul config write` command](/consul/commands/config/write). + +The following examples configure a Gateway so that every request coming through the listener must meet these conditions: +- The request must be signed by the `local` provider +- The request must have a claim of `role` with a value of `user` unless the HTTPRoute attached to the listener overrides it + + + +```hcl +Kind = "api-gateway" +Name = "api-gateway" +Listeners = [ + { + Name = "listener-one" + Port = 9001 + Protocol = "http" + Override = { + JWT = { + Providers = [ + { + Name = "local" + } + ] + } + } + default = { + JWT = { + Providers = [ + { + Name = "local" + VerifyClaims = [ + { + Path = ["role"] + Value = "pet" + } + ] + } + ] + } + } + } +] +``` + + ## Configure verification for specific HTTP routes -Define filters to enable route-specific JWT verification settings in the [HTTP route configuration entry](/consul/docs/connect/config-entries/http-route). +Define filters to enable route-specific JWT verification settings in the [HTTP route configuration entry](/consul/docs/connect/config-entries/http-route). 1. Add a `JWT` configuration to the `rules.filter` block. Route-specific configurations that overlap the [default settings ](/consul/docs/connect/config-entries/api-gateway#listeners-default-jwt) in the API gateway configuration entry take precedence. Configurations defined in the [listener override settings](/consul/docs/connect/config-entries/api-gateway#listeners-override-jwt) take the highest precedence. -1. Apply the settings in the API gateway configuration entry. You can use the [`/config` API endpoint](/consul/api-docs/config#apply-configuration) or the [`consul config write` command](/consul/commands/config/write). +1. Apply the settings in the API gateway configuration entry. You can use the [`/config` API endpoint](/consul/api-docs/config#apply-configuration) or the [`consul config write` command](/consul/commands/config/write). + +The following example configures an HTTPRoute so that every request to `api-gateway-fqdn:3002/admin` must meet these conditions: +- The request be signed by the `local` provider. +- The request must have a `role` claim. +- The value of the claim must be `admin`. + +Every other request must be signed by the `local` provider and have a claim of `role` with a value of `user`, as defined in the Gateway listener. + + + +```hcl +Kind = "http-route" +Name = "api-gateway-route" +Parents = [ + { + SectionName = "listener-one" + Name = "api-gateway" + Kind = "api-gateway" + }, +] +Rules = [ + { + Matches = [ + { + Path = { + Match = "prefix" + Value = "/admin" + } + } + ] + Filters = { + JWT = { + Providers = [ + { + Name = "local" + VerifyClaims = [ + { + Path = ["role"] + Value = "admin" + } + ] + } + ] + } + } + Services = [ + { + Name = "admin-service" + } + ] + }, + { + Matches = [ + { + Path = { + Match = "prefix" + Value = "/" + } + } + ] + Services = [ + { + Name = "user-service" + } + ] + }, +] +``` + + From bbc5229362bc57cc74fbf79b8302c52d046d72c2 Mon Sep 17 00:00:00 2001 From: Krastin Krastev Date: Tue, 30 Jul 2024 16:24:25 +0300 Subject: [PATCH 106/185] docs: Clarify cluster peering vs WAN federation comparison (#21568) cluster peering: remove shared KV store bulletpoint --- website/content/docs/connect/cluster-peering/index.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/website/content/docs/connect/cluster-peering/index.mdx b/website/content/docs/connect/cluster-peering/index.mdx index 1714fc0fb0..2aa5147235 100644 --- a/website/content/docs/connect/cluster-peering/index.mdx +++ b/website/content/docs/connect/cluster-peering/index.mdx @@ -45,7 +45,6 @@ Regardless of whether you connect your clusters through WAN federation or cluste | Replicates exported services for service discovery | ❌ | ✅ | | Gossip protocol: Requires LAN gossip only | ❌ | ✅ | | Forwards service requests for service discovery | ✅ | ❌ | -| Shares key/value stores | ✅ | ❌ | | Can replicate ACL tokens, policies, and roles | ✅ | ❌ | ## Guidance From 01ae0d3d3862ced2b97563f89054ddc5f4bd3132 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 30 Jul 2024 16:20:41 -0400 Subject: [PATCH 107/185] ci: Update backport-assistant to 0.4.4 (#21572) Update backport-assistant to 0.4.4 --- .github/workflows/backport-assistant.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backport-assistant.yml b/.github/workflows/backport-assistant.yml index 27d83e94f5..ad5af27383 100644 --- a/.github/workflows/backport-assistant.yml +++ b/.github/workflows/backport-assistant.yml @@ -19,7 +19,7 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.4.1 + container: hashicorpdev/backport-assistant:0.4.4 steps: - name: Run Backport Assistant for release branches run: | From 588730c49f3f3a2870f6ea36b5a0819158786743 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Tue, 30 Jul 2024 16:34:40 -0400 Subject: [PATCH 108/185] ci: use workflow-scoped GH PAT for backports (#21570) This is necessary to allow backporting changes to GHA workflows, and mirrors the token use in the CE->Ent merge workflow. --- .github/workflows/backport-assistant.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backport-assistant.yml b/.github/workflows/backport-assistant.yml index ad5af27383..d004f220bf 100644 --- a/.github/workflows/backport-assistant.yml +++ b/.github/workflows/backport-assistant.yml @@ -27,7 +27,7 @@ jobs: env: BACKPORT_LABEL_REGEXP: "backport/(?P\\d+\\.\\d+)" BACKPORT_TARGET_TEMPLATE: "release/{{.target}}.x" - GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN_WORKFLOW }} ENABLE_VERSION_MANIFESTS: true backport-ent: if: github.event.pull_request.merged && contains(join(github.event.pull_request.labels.*.name), 'backport/ent') From c526659b7fb4d7f7646d38eeefd621ca26cceb79 Mon Sep 17 00:00:00 2001 From: John Murret Date: Thu, 1 Aug 2024 11:23:19 -0600 Subject: [PATCH 109/185] NET-10610 - stop logging no data as errors in DNS lookups (#21578) --- agent/dns/router.go | 1 - 1 file changed, 1 deletion(-) diff --git a/agent/dns/router.go b/agent/dns/router.go index 9c0175a776..34de8a7701 100644 --- a/agent/dns/router.go +++ b/agent/dns/router.go @@ -275,7 +275,6 @@ func (r *Router) handleRequestRecursively(req *dns.Msg, reqCtx Context, configCt } resp, err := messageSerializer{}.serialize(serializedOpts) if err != nil { - r.logger.Error("error serializing DNS results", "error", err) return respGenerator.generateResponseFromError(&generateResponseFromErrorOpts{ req: req, err: err, From 779d3c3eda1d4aa0d639f53a0e1d4437179a7224 Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:55:48 -0500 Subject: [PATCH 110/185] Suppress CVE-2024-7264 (#21590) supress curl error --- .release/security-scan.hcl | 1 + 1 file changed, 1 insertion(+) diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 88b2c88117..05f60ddc4a 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -41,6 +41,7 @@ container { "CVE-2023-46218", # curl@8.4.0-r0 "CVE-2023-46219", # curl@8.4.0-r0 "CVE-2023-5678", # openssl@3.1.4-r0 + "CVE-2024-7264", # curl@8.9.0 ] paths = [ "internal/tools/proto-gen-rpc-glue/e2e/consul/*", From 929d602dbb9299d150a52cc8bef435c5f722b3c3 Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Mon, 12 Aug 2024 08:52:16 -0500 Subject: [PATCH 111/185] ui: Upgrade d3 packages to update color dependency (#21588) * upgrade d3 packages to update color dependency * yarn package bump * deps moved into devdeps --------- Co-authored-by: Phil Renaud --- .changelog/21588.txt | 3 + ui/packages/consul-ui/package.json | 4 +- ui/yarn.lock | 90 +++++++++++++++++------------- 3 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 .changelog/21588.txt diff --git a/.changelog/21588.txt b/.changelog/21588.txt new file mode 100644 index 0000000000..073901f88b --- /dev/null +++ b/.changelog/21588.txt @@ -0,0 +1,3 @@ +```release-note:security +ui: Upgrade modules with d3-color as a dependency to address denial of service issue in d3-color < 3.1.0 +``` \ No newline at end of file diff --git a/ui/packages/consul-ui/package.json b/ui/packages/consul-ui/package.json index 76c2a55105..850cf5cb7b 100644 --- a/ui/packages/consul-ui/package.json +++ b/ui/packages/consul-ui/package.json @@ -98,8 +98,8 @@ "css": "^3.0.0", "css.escape": "^1.5.1", "d3-array": "^2.8.0", - "d3-scale": "^3.2.3", - "d3-scale-chromatic": "^2.0.0", + "d3-scale": "^4.0.2", + "d3-scale-chromatic": "^3.1.0", "d3-selection": "^2.0.0", "d3-shape": "^2.0.0", "dayjs": "^1.9.3", diff --git a/ui/yarn.lock b/ui/yarn.lock index 3f052af293..c993d4c3c1 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -5786,53 +5786,60 @@ cyclist@^1.0.1: resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== -d3-array@2, d3-array@^2.3.0, d3-array@^2.8.0: +"d3-array@2 - 3", "d3-array@2.10.0 - 3": + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +d3-array@^2.8.0: version "2.12.1" resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== dependencies: internmap "^1.0.0" -"d3-color@1 - 2": - version "2.0.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" - integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== +"d3-color@1 - 3": + version "3.1.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== -"d3-format@1 - 2": - version "2.0.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" - integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== +"d3-format@1 - 3": + version "3.1.0" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== -"d3-interpolate@1 - 2", "d3-interpolate@1.2.0 - 2": - version "2.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" - integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== +"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3": + version "3.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== dependencies: - d3-color "1 - 2" + d3-color "1 - 3" "d3-path@1 - 2": version "2.0.0" resolved "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8" integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA== -d3-scale-chromatic@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz#c13f3af86685ff91323dc2f0ebd2dabbd72d8bab" - integrity sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA== +d3-scale-chromatic@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#34c39da298b23c20e02f1a4b239bd0f22e7f1314" + integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== dependencies: - d3-color "1 - 2" - d3-interpolate "1 - 2" + d3-color "1 - 3" + d3-interpolate "1 - 3" -d3-scale@^3.2.3: - version "3.3.0" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" - integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== +d3-scale@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== dependencies: - d3-array "^2.3.0" - d3-format "1 - 2" - d3-interpolate "1.2.0 - 2" - d3-time "^2.1.1" - d3-time-format "2 - 3" + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" d3-selection@^2.0.0: version "2.0.0" @@ -5846,19 +5853,19 @@ d3-shape@^2.0.0: dependencies: d3-path "1 - 2" -"d3-time-format@2 - 3": - version "3.0.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" - integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== +"d3-time-format@2 - 4": + version "4.1.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== dependencies: - d3-time "1 - 2" + d3-time "1 - 3" -"d3-time@1 - 2", d3-time@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" - integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== +"d3-time@1 - 3", "d3-time@2.1.1 - 3": + version "3.1.0" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== dependencies: - d3-array "2" + d3-array "2 - 3" dag-map@^2.0.2: version "2.0.2" @@ -9874,6 +9881,11 @@ internal-slot@^1.0.4, internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + internmap@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" From 89618f9e377a4aadd88fb5f17dc1bc279299f7e3 Mon Sep 17 00:00:00 2001 From: danielehc <40759828+danielehc@users.noreply.github.com> Date: Tue, 13 Aug 2024 14:52:12 +0200 Subject: [PATCH 112/185] CE-655 - Moving DNS forwading tutorial to docs (#21348) * First commit * Add page to navigation * test new doc page * Update website/content/docs/services/discovery/dns-forwarding.mdx * Update website/content/docs/services/discovery/dns-forwarding.mdx * fix push build atttempt * Draft * Draft * empty line * Draft * empty lines * Draft * First draft * Create documentation for Argo Rollouts Plugin. (#20680) * Create documentation for Argo Rollouts Plugin. * Create documentation for Argo Rollouts Plugin. * Apply suggestions from code review Co-authored-by: David Yu * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update docs based on feedback * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx * Update website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx --------- Co-authored-by: David Yu Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> * Split content and add images * Fix navigation * Add links and context * Restructure changes * Fix enable documentation * Fix enable documentation * Fix index documentation * Add troubleshooting and fix codeblocks * Add troubleshooting and fix codeblocks * Typos and last checks * Apply suggestions from code review Co-authored-by: Aimee Ukasick * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/services/discovery/dns-forwarding/enable.mdx * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Add dark mode images * Add dark mode images * Apply suggestions from code review --------- Co-authored-by: boruszak Co-authored-by: Ashwin Venkatesh Co-authored-by: David Yu Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Co-authored-by: Aimee Ukasick --- .../discovery/dns-forwarding/enable.mdx | 420 ++++++++++++++++++ .../discovery/dns-forwarding/index.mdx | 186 ++++++++ .../docs/services/discovery/dns-overview.mdx | 6 + website/data/docs-nav-data.json | 13 + ...consul-dns-conditional-forwarding-dark.png | Bin 0 -> 111870 bytes .../img/consul-dns-conditional-forwarding.png | Bin 0 -> 111976 bytes .../public/img/consul-dns-forwarding-dark.png | Bin 0 -> 99418 bytes website/public/img/consul-dns-forwarding.png | Bin 0 -> 98393 bytes 8 files changed, 625 insertions(+) create mode 100644 website/content/docs/services/discovery/dns-forwarding/enable.mdx create mode 100644 website/content/docs/services/discovery/dns-forwarding/index.mdx create mode 100644 website/public/img/consul-dns-conditional-forwarding-dark.png create mode 100644 website/public/img/consul-dns-conditional-forwarding.png create mode 100644 website/public/img/consul-dns-forwarding-dark.png create mode 100644 website/public/img/consul-dns-forwarding.png diff --git a/website/content/docs/services/discovery/dns-forwarding/enable.mdx b/website/content/docs/services/discovery/dns-forwarding/enable.mdx new file mode 100644 index 0000000000..b165c2c8fa --- /dev/null +++ b/website/content/docs/services/discovery/dns-forwarding/enable.mdx @@ -0,0 +1,420 @@ +--- +layout: docs +page_title: Enable DNS forwarding +description: -> + Learn how to configure different DNS servers to perform DNS forwarding to Consul servers. +--- + +# Enable DNS forwarding + +This page describes the process to enable DNS forwarding to Consul servers. + +You can apply these operations on every node where a Consul agent is running. + +## Requirements + +To enable DNS forwarding, your deployment must have the following: + +- A running Consul server instance +- One or more Consul client nodes with registered services in the Consul catalog +- The `iptables` command available, or one of the following local DNS servers: + - [systemd-resolved](#systemd-resolved) + - [BIND](#bind) + - [Dnsmasq](#dnsmasq) + - [Unbound](#unbound) + - [macOS system resolver](#macos) + +### Network address configuration + +The example configurations on this page assumes Consul's DNS server is listening on the loopback interface on the same node of the local DNS server. + +If Consul is not listening on the loopback IP, replace the references to `localhost` and `120.0.0.1` in the configuration and commands with the appropriate IP address for your environment. + +## systemd-resolved + +[`systemd-resolved`](https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html) is a system service that provides network name resolution to local applications. It is the default local DNS server for many Linux distributions. + +To configure the `systemd-resolved` service so that it sends `.consul` domain queries to Consul, create a `consul.conf` file located in the `/etc/systemd/resolved.conf.d/` directory. + + + + +Add a `[Resolve]` section to your resolved configuration. + + + +```ini +[Resolve] +DNS=127.0.0.1 +DNSSEC=false +Domains=~consul +``` + + + +### Define port for Consul DNS server + +When using systemd 245 and older, you cannot specify port numbers in the `DNS` configuration field. systemd-resolved only uses port `53`, which is a privileged port. + +When you cannot specify ports for the system's configuration, there are two workarounds: + - [Configure Consul DNS service to listen on port `53`](/consul/docs/agent/config/config-files#dns_port) instead of `8600`. + - Map port `53` to `8600` using `iptables`. + +Binding to port `53` usually requires running Consul as a privileged user or running Linux with the `CAP_NET_BIND_SERVICE` capability. +When using the Consul Docker image, add the following to the environment to allow Consul to use the port: `CONSUL_ALLOW_PRIVILEGED_PORTS=yes`. + +To avoid running Consul as a privileged user, the following `iptables` commands are sufficient to map port `53` to `8600` and redirect DNS queries to Consul. + +```shell-session +# iptables --table nat --append OUTPUT --destination localhost --protocol udp --match udp --dport 53 --jump REDIRECT --to-ports 8600 \ + iptables --table nat --append OUTPUT --destination localhost --protocol tcp --match tcp --dport 53 --jump REDIRECT --to-ports 8600 +``` + + + + + +Systemd 246 and newer allow you to specify the DNS port directly in the `systemd-resolved` configuration file. +Previous versions of systemd required iptables rules to direct DNS traffic to Consul. + +Add a `[Resolve]` section to your resolved configuration. + + + +```ini +[Resolve] +DNS=127.0.0.1:8600 +DNSSEC=false +Domains=~consul +``` + + + + + + +PTR record queries are still sent to the other configured resolvers, in addition to Consul. + +After creating the resolved configuration, restart `systemd-resolved`. + +```shell-session +# systemctl restart systemd-resolved +``` + +The command produces no output. + +### Validate the systemd-resolved configuration + +Validate that `systemd-resolved` is active. + +```shell-session +# systemctl is-active systemd-resolved +active +``` + +Verify that `systemd-resolved` is configured to forward queries for the `consul` domain to Consul. + +```shell-session +# resolvectl domain +Global: ~consul +Link 2 (eth0): +``` + +Verify that `systemd-resolved` is able to resolve the Consul server address. + +```shell-session +# resolvectl query consul.service.consul +consul.service.consul: 127.0.0.1 + +-- Information acquired via protocol DNS in 6.6ms. +-- Data is authenticated: no +``` + +Confirm that `/etc/resolv.conf` points to the `stub-resolv.conf` file managed by `systemd-resolved`. + +```shell-session +$ ls -l /etc/resolv.conf +lrwxrwxrwx 1 root root 37 Jul 14 10:10 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf +``` + +Confirm that the IP address for `systemd-resolved`'s stub resolver is the configured `nameserver`. + + + +```shell-session +$ cat /etc/resolv.conf +## This file is managed by man:systemd-resolved(8). Do not edit. +## +## This is a dynamic resolv.conf file for connecting local clients to the +## internal DNS stub resolver of systemd-resolved. This file lists all +## configured search domains. +## +## Run "resolvectl status" to see details about the uplink DNS servers +## currently in use. +## +## Third party programs must not access this file directly, but only through the +## symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way, +## replace this symlink by a static file or a different symlink. +## +## See man:systemd-resolved.service(8) for details about the supported modes of +## operation for /etc/resolv.conf. + +nameserver 127.0.0.53 +options edns0 +``` + + + +Ensure that the operating system can resolve DNS queries to the `.consul` domain. + +```shell-session +$ host consul.service.consul +consul.service.consul has address 127.0.0.1 +``` + +### Using any local resolver with systemd + +By default, the local resolver stub in the `resolved.conf` file is configured to listen for UDP and TCP requests at `127.0.0.53:53`. However, you can set the `DNSStubListener` option to `false` so that your system can use any DNS configuration, as long as it loads earlier than `resolved`. + + + +```plaintext +DNSStubListener=false +``` + + + +## Dnsmasq + +Use [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) if you have a small network and need a lightweight DNS solution. + + + +If your distribution uses systemd, disable `systemd-resolved` before you follow these steps. + + + +Configure the `dnsmasq.conf` file or a series of files in the `/etc/dnsmasq.d` directory. Add server settings to your configuration file so that requests for the `consul` domain are forwarded to Consul DNS. + + + +```plaintext +# Enable forward lookup of the 'consul' domain: +server=/consul/127.0.0.1#8600 + +# Uncomment and modify as appropriate to enable reverse DNS lookups for +# common netblocks found in RFC 1918, 5735, and 6598: +#rev-server=0.0.0.0/8,127.0.0.1#8600 +#rev-server=10.0.0.0/8,127.0.0.1#8600 +#rev-server=100.64.0.0/10,127.0.0.1#8600 +#rev-server=127.0.0.1/8,127.0.0.1#8600 +#rev-server=169.254.0.0/16,127.0.0.1#8600 +#rev-server=172.16.0.0/12,127.0.0.1#8600 +#rev-server=192.168.0.0/16,127.0.0.1#8600 +#rev-server=224.0.0.0/4,127.0.0.1#8600 +#rev-server=240.0.0.0/4,127.0.0.1#8600 +# Accept DNS queries only from hosts whose address is on a local subnet. +#local-service +# Don't poll /etc/resolv.conf for changes. +#no-poll +# Don't read /etc/resolv.conf. Get upstream servers only from the command +# line or the dnsmasq configuration file (see the "server" directive below). +#no-resolv +# Specify IP address(es) of other DNS servers for queries not handled +# directly by consul. There is normally one 'server' entry set for every +# 'nameserver' parameter found in '/etc/resolv.conf'. See dnsmasq(8)'s +# 'server' configuration option for details. +#server=1.2.3.4 +#server=208.67.222.222 +#server=8.8.8.8 +# Set the size of dnsmasq's cache. The default is 150 names. Setting the +# cache size to zero disables caching. +#cache-size=65536 +``` + + + +Restart the `dnsmasq` service after creating the configuration. + +Refer to [`dnsmasq(8)`](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) for additional configuration settings such as specifying IP addresses for queries not handled directly by Consul. + + +## BIND + +[BIND](https://www.isc.org/bind/) is a robust DNS system. Its most prominent component, `named`, performs both of the main DNS server roles, acts as an authoritative name server for DNS zones, and is a recursive resolver in the network. + + + +If your distribution uses systemd, disable `systemd-resolved` before you follow these steps. + + + +To configure the BIND service to send `.consul` domain queries to Consul: + +1. Create a `named` configuration file with `DNSSEC` disabled. +1. Create a zone configuration file to manage the `.consul` domain. + +### Named configuration file + +Edit the `/etc/named.conf` to configure your BIND instance. Remember to disable `DNSSEC` so that Consul and BIND can communicate. Add an `include` section to include the zone file that you create in the next step. + +The following example shows a BIND configuration with `DNSSEC` disabled. + + + +```plaintext +options { + listen-on port 53 { 127.0.0.1; }; + listen-on-v6 port 53 { ::1; }; + directory "/var/named"; + dump-file "/var/named/data/cache_dump.db"; + statistics-file "/var/named/data/named_stats.txt"; + memstatistics-file "/var/named/data/named_mem_stats.txt"; + allow-query { localhost; }; + recursion yes; + + dnssec-enable no; + dnssec-validation no; + + /* Path to ISC DLV key */ + bindkeys-file "/etc/named.iscdlv.key"; + + managed-keys-directory "/var/named/dynamic"; +}; + +include "/etc/named/consul.conf"; +``` + + + +### Zone configuration file + +Set up a zone for your Consul-managed records in `consul.conf`. + + + +```dns-zone-file +zone "consul" IN { + type forward; + forward only; + forwarders { 127.0.0.1 port 8600; }; +}; +``` + + + +## Unbound + +Use [Unbound](https://www.unbound.net/) when you need a fast and lean DNS resolver for Linux and macOS. + + + +If your distribution uses systemd, disable `systemd-resolved` before you follow these steps. + + + + +The following example demonstrates a configuration for the `consul.conf` file in the `/etc/unbound/unbound.conf.d` directory. + +Add `server` and `stub-zone` settings to your Unbound configuration file. + + + +```plaintext +#Allow insecure queries to local resolvers +server: + do-not-query-localhost: no + domain-insecure: "consul" + +#Add consul as a stub-zone +stub-zone: + name: "consul" + stub-addr: 127.0.0.1@8600 +``` + + + +You may have to add the following line to the bottom of your `/etc/unbound/unbound.conf` file for the new configuration to be included. + + + +```plaintext +include: "/etc/unbound/unbound.conf.d/*.conf" +``` + + + +## iptables + +[iptables](https://www.netfilter.org/projects/iptables/index.html) is a generic firewalling software that allows you to define traffic rules for your system. + +If you do not have a local DNS server on the Consul agent node, use `iptables` to forward DNS requests on port `53` to the Consul agent running on the same machine without using a secondary service. + +This configuration realizes full DNS forwarding, which means that all DNS queries for the host are forwarded to Consul, not just the ones for the `.consul` top level domain. Consul's default configuration resolves only the `.consul` top level domain, so you must set the [`recursors`](/consul/docs/agent/config/config-files#recursors) flag if you want your node to be able to resolve other domains when using `iptables` configuration. + +If you use DNS relay hosts in your network, do not place them on the same host as Consul. The redirects may intercept the traffic. + +### Configure Consul recursors + +Add recursors to your Consul configuration. + + + +```hcl +# DNS recursors +recursors = [ "1.1.1.1" ] +``` + + + +Recursors should not include the `localhost` address because the `iptables` redirects would intercept the requests. + +You can replace the `1.1.1.1` address in the example with another DNS server address. This is suitable for situations where an external DNS +service is already running in your infrastructure and is used as the recursor. + +### Create iptables rules + +After you configure Consul to use a valid recursor, add rules to `iptables` to redirect traffic from port `53` to port `8600`. + +```shell-session +# iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600 \ + iptables -t nat -A PREROUTING -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600 \ + iptables -t nat -A OUTPUT -d localhost -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600 \ + iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600 +``` + +## macOS + +On macOS systems, use the macOS system resolver to point all `.consul` requests to Consul. +The `man 5 resolver` command describes this feature in more detail. + +The following instructions require `sudo` or root access. + +To configure the macOS system resolver to forward DNS queries to Consul, add a resolver entry in the `/etc/resolver/` directory that points at the Consul agent. + +If you do not have this folder, create it. + +```shell-session +# mkdir -p /etc/resolver +``` + +Create a new file `/etc/resolver/consul` with `nameserver` and `port` entries. + + + +```plaintext +nameserver 127.0.0.1 +port 8600 +``` + + + +The configuration informs the macOS resolver daemon to forward all `.consul` TLD requests to `127.0.0.1` on port `8600`. + +## Next steps + +This instructions on this page helped you configure your node to forward DNS requests to Consul. + +To learn more on how to query Consul DNS once forwarding is enabled, refer to [DNS forwarding workflow](/consul/docs/services/discovery/dns-forwarding#workflow). + +For more information on other DNS features and configurations available in Consul, refer to [DNS usage overview](/consul/docs/services/discovery/dns-overview). \ No newline at end of file diff --git a/website/content/docs/services/discovery/dns-forwarding/index.mdx b/website/content/docs/services/discovery/dns-forwarding/index.mdx new file mode 100644 index 0000000000..1ee2841739 --- /dev/null +++ b/website/content/docs/services/discovery/dns-forwarding/index.mdx @@ -0,0 +1,186 @@ +--- +layout: docs +page_title: DNS forwarding +description: -> + Learn how to configure your local DNS servers to perform DNS forwarding to Consul servers. +--- + +# DNS forwarding + +This topic describes the process to configure different DNS servers to enable DNS forwarding to Consul servers. + +You can apply these operations on every node where a Consul agent is running. + +## Introduction + +You deployed a Consul datacenter and want to use Consul DNS interface for name resolution. + +When configured with default values, Consul exposes the DNS interface on port `8600`. By default, DNS is served from port `53`. On most operating systems, this requires elevated privileges. It is also common, for most operating systems, to have a local DNS server already running on port `53`. + +Instead of running Consul with an administrative or root account, you can forward appropriate queries to Consul, running on an unprivileged port, from another DNS server or using port redirect. + +There are two configurations for a node's DNS forwarding behavior: + - **Conditional DNS forwarding**: the local DNS servers are configured to forward to Consul only queries relative to the `.consul` zone. All other queries are still served via the default DNS server in the node. + - **Full DNS forwarding**: Consul serves all DNS queries and forwards to a remote DNS server the ones outside `.consul` domain. + +### Conditional DNS forwarding + +We recommend the conditional DNS forwarding approach. This configuration lowers the Consul agent's resource consumption by limiting the number of DNS requests it handles. + +![Consul DNS conditional forwarding - Only .consul requests are routed to Consul](/img/consul-dns-conditional-forwarding.png#light-theme-only) +![Consul DNS conditional forwarding - Only .consul requests are routed to Consul](/img/consul-dns-conditional-forwarding-dark.png#dark-theme-only) + +In this configuration, Consul only serves queries relative to the `.consul` domain. There is no unnecessary load on Consul servers to serve queries from different domains. + +This behavior is not enabled by default. + +### Full DNS forwarding + +This approach can be useful in scenarios where the Consul agent's node is allocated limited resources and you want to avoid the overhead of running a local DNS server. In this configuration, Consul serves all DNS queries for all domains and forwards the ones outside the `.consul` domain to one or more configured forwarder servers. + +![Consul DNS forwarding - All requests are routed to Consul](/img/consul-dns-forwarding.png#light-theme-only) +![Consul DNS forwarding - All requests are routed to Consul](/img/consul-dns-forwarding-dark.png#dark-theme-only) + +This behavior is not enabled by default. Consul standard configuration only resolves DNS records inside the `.consul` zone. To enable DNS forwarding, you need to set the [recursors](/consul/docs/agent/config/config-files#recursors) option in your Consul configuration. + +In this scenario, if a Consul DNS reply includes a `CNAME` record pointing outside the `.consul` top level domain, then the DNS reply only includes `CNAME` records by default. + +When `recursors` is set and the upstream resolver is functioning correctly, Consul tries to resolve CNAMEs and include any records (for example, A, AAAA, PTR) for them in its DNS reply. In these scenarios, Consul is used for full DNS forwarding and is able to serve queries for all domains. + +## Workflow + +To use DNS forwarding in Consul deployments, complete the following steps: + +1. Configure the local DNS service to enable DNS forwarding to Consul. Follow the instructions for one of the following services: + + - [systemd-resolved](/consul/docs/services/discovery/dns-forwarding/enable#systemd-resolved) + - [BIND](/consul/docs/services/discovery/dns-forwarding/enable#bind) + - [Dnsmasq](/consul/docs/services/discovery/dns-forwarding/enable#dnsmasq) + - [Unbound](/consul/docs/services/discovery/dns-forwarding/enable#unbound) + - [iptables](/consul/docs/services/discovery/dns-forwarding/enable#iptables) + - [macOS system resolver](/consul/docs/services/discovery/dns-forwarding/enable#macOS) + +1. Query the Consul DNS to confirm that DNS forwarding functions correctly. + + ```shell-session + $ dig consul.service.consul A + + ; <<>> DiG 9.16.48-Debian <<>> consul.service.consul A + ;; global options: +cmd + ;; Got answer: + ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51736 + ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 + + ;; OPT PSEUDOSECTION: + ; EDNS: version: 0, flags:; udp: 65494 + ;; QUESTION SECTION: + ;consul.service.consul. IN A + + ;; ANSWER SECTION: + consul.service.consul. 0 IN A 10.0.4.140 + consul.service.consul. 0 IN A 10.0.4.121 + consul.service.consul. 0 IN A 10.0.4.9 + + ;; Query time: 4 msec + ;; SERVER: 127.0.0.53#53(127.0.0.53) + ;; WHEN: Wed Jun 26 20:47:05 UTC 2024 + ;; MSG SIZE rcvd: 98 + + ``` + +1. Optionally, verify reverse DNS. + + ```shell-session + $ dig 140.4.0.10.in-addr.arpa. PTR + + ; <<>> DiG 9.16.48-Debian <<>> 140.4.0.10.in-addr.arpa. PTR + ;; global options: +cmd + ;; Got answer: + ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35085 + ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 + + ;; OPT PSEUDOSECTION: + ; EDNS: version: 0, flags:; udp: 65494 + ;; QUESTION SECTION: + ;140.4.0.10.in-addr.arpa. IN PTR + + ;; ANSWER SECTION: + 140.4.0.10.in-addr.arpa. 0 IN PTR consul-server-0.node.dc1.consul. + + ;; Query time: 0 msec + ;; SERVER: 127.0.0.53#53(127.0.0.53) + ;; WHEN: Wed Jun 26 20:47:57 UTC 2024 + ;; MSG SIZE rcvd: 97 + + ``` + + You can use the `short` option for `dig` to only get the node name instead of the full output. + + ```shell-session + $ dig +short -x 10.0.4.140 + consul-server-0.node.dc1.consul. + ``` + +## Troubleshooting + +If your DNS server does not respond but you do get an answer from Consul, turn on your DNS server's query log to check for errors. + +### systemd-resolved + +Enable query logging for `systemd-resolved`: + +```shell-session +# resolvectl log-level debug +``` + +Check query log: + +```shell-session +# journalctl -r -u systemd-resolved +``` + +Disable query logging: + +```shell-session +# resolvectl log-level info +``` + +DNS forwarding may fail if you use the default `systemd-resolved` configuration and attempt to bind to `0.0.0.0`. The default configuration uses a DNS stub that listens for UDP and TCP requests at `127.0.0.53`. As a result, attempting to bind to `127.0.0.53` conflicts with the running stub. You can disable the stub as described in the [Using any local resolver with systemd](/consul/docs/services/discovery/dns-forwarding/enable#using-any-local-resolver-with-systemd) section to troubleshoot this problem. + +### Dnsmasq + +To enable query log refer to [Dnsmasq documentation](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html). + +In particular, look for the `log-queries` and `log-facility` configuration option. + +When query log is enabled, it is possible to force Dnsmasq to emit a full cache dump using the `SIGUSR1` signal. + +### BIND + +Enable query log: + +```shell-session +$ rndc querylog +``` + +Check logs: + +```shell-session +$ tail -f /var/log/messages +``` + +The log may show errors like this: + + + +```plaintext +error (no valid RRSIG) resolving +error (no valid DS) resolving +``` + + + +This error indicates that `DNSSEC` is not disabled properly. + +If you receive errors about network connections, verify that there are no firewall +or routing problems between the servers running BIND and Consul. diff --git a/website/content/docs/services/discovery/dns-overview.mdx b/website/content/docs/services/discovery/dns-overview.mdx index 34e92e5fe8..dd2b22bcf1 100644 --- a/website/content/docs/services/discovery/dns-overview.mdx +++ b/website/content/docs/services/discovery/dns-overview.mdx @@ -30,6 +30,12 @@ If you are using Consul for service mesh on VMs, you can use upstreams or DNS. W If you are using Consul on Kubernetes, refer to [the upstreams annotation documentation](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-connect-service-upstreams) for additional information. +## DNS forwarding + +You can configure your local DNS servers to use Consul. + +Refer to [DNS Forwarding](/consul/docs/services/discovery/dns-forwarding) for additional information. + ## Static queries Node lookups and service lookups are the fundamental types of static queries. Depending on your use case, you may need to use different query methods and syntaxes to query the DNS for services and nodes. diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 38126b547e..c883f29a5b 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -389,6 +389,19 @@ "title": "Configure DNS behavior", "path": "services/discovery/dns-configuration" }, + { + "title": "DNS forwarding", + "routes": [ + { + "title": "Overview", + "path": "services/discovery/dns-forwarding" + }, + { + "title": "Enable DNS forwarding", + "path": "services/discovery/dns-forwarding/enable" + } + ] + }, { "title": "Perform static DNS lookups", "path": "services/discovery/dns-static-lookups" diff --git a/website/public/img/consul-dns-conditional-forwarding-dark.png b/website/public/img/consul-dns-conditional-forwarding-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..b54ed817eb6c4289cc4fa6ab79f511c1d95ca9a2 GIT binary patch literal 111870 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¬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
&ut*&nu6 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�?uLc}B`UmdIu$wS%nRx1(|;yHs2 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 kez@Kq(fzq; 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 z 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 nk1BNO!)I@Yp>4Nm`ARxUH2werF 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 D8CG)y literal 0 HcmV?d00001 diff --git a/website/public/img/consul-dns-forwarding.png b/website/public/img/consul-dns-forwarding.png new file mode 100644 index 0000000000000000000000000000000000000000..bffce6e333a97411647c3ba9c41d517d65d9e478 GIT binary patch literal 98393 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 b7@l3G1Lcq)`zc@-fG;_j7mra=FTMW@o9W_L literal 0 HcmV?d00001 From dcad90639f7c788a31a4c842dabb91da97cbc7ae Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 13 Aug 2024 16:53:48 -0600 Subject: [PATCH 113/185] NET-10685 - Remove dns v2 code (#21598) * NET-10685 - Remove dns v2 code * adding missing erro * add missing license info. --- agent/agent.go | 110 +- agent/config/builder_test.go | 6 - agent/consul/options.go | 9 - agent/consul/server.go | 1 - agent/discovery/discovery.go | 250 - agent/discovery/discovery_test.go | 221 - agent/discovery/mock_CatalogDataFetcher.go | 209 - agent/discovery/query_fetcher_v1.go | 649 -- agent/discovery/query_fetcher_v1_ce.go | 30 - agent/discovery/query_fetcher_v1_ce_test.go | 64 - agent/discovery/query_fetcher_v1_test.go | 207 - agent/discovery/query_fetcher_v2.go | 365 - agent/discovery/query_fetcher_v2_test.go | 859 --- agent/dns.go | 143 +- agent/dns/buffer_response_writer.go | 78 + agent/dns/discovery_results_fetcher.go | 383 - agent/dns/discovery_results_fetcher_test.go | 336 - agent/dns/dns_address.go | 87 - agent/dns/dns_address_test.go | 168 - agent/dns/dns_record_maker.go | 151 - agent/dns/dns_record_maker_test.go | 228 - agent/dns/message_serializer.go | 651 -- agent/dns/mock_DNSRouter.go | 82 - agent/dns/mock_dnsRecursor.go | 55 - agent/dns/parser.go | 89 - agent/dns/parser_test.go | 141 - agent/dns/recursor.go | 123 - agent/dns/recursor_test.go | 39 - agent/dns/response_generator.go | 425 -- agent/dns/response_generator_test.go | 739 -- agent/dns/router.go | 557 -- agent/dns/router_addr_test.go | 405 -- agent/dns/router_ns_test.go | 244 - agent/dns/router_prepared_query_test.go | 187 - agent/dns/router_ptr_test.go | 563 -- agent/dns/router_recursor_test.go | 296 - agent/dns/router_service_test.go | 241 - agent/dns/router_soa_test.go | 277 - agent/dns/router_test.go | 842 --- agent/dns/router_v2_services_test.go | 628 -- agent/dns/router_virtual_test.go | 122 - agent/dns/router_workload_test.go | 515 -- agent/dns/server.go | 106 - agent/dns/server_test.go | 78 - agent/dns_catalogv2_test.go | 516 -- agent/dns_ce.go | 22 +- agent/dns_ce_test.go | 212 +- agent/dns_node_lookup_test.go | 1008 ++- agent/dns_reverse_lookup_test.go | 637 +- agent/dns_service_lookup_test.go | 6130 ++++++++--------- agent/dns_test.go | 4437 ++++++------ agent/grpc-external/services/dns/server.go | 76 +- agent/grpc-external/services/dns/server_v2.go | 90 - .../services/dns/server_v2_test.go | 164 - agent/setup.go | 2 - agent/structs/errors.go | 6 + website/content/docs/k8s/helm.mdx | 7 +- .../docs/release-notes/consul/v1_19_x.mdx | 12 +- 58 files changed, 6087 insertions(+), 19191 deletions(-) delete mode 100644 agent/discovery/discovery.go delete mode 100644 agent/discovery/discovery_test.go delete mode 100644 agent/discovery/mock_CatalogDataFetcher.go delete mode 100644 agent/discovery/query_fetcher_v1.go delete mode 100644 agent/discovery/query_fetcher_v1_ce.go delete mode 100644 agent/discovery/query_fetcher_v1_ce_test.go delete mode 100644 agent/discovery/query_fetcher_v1_test.go delete mode 100644 agent/discovery/query_fetcher_v2.go delete mode 100644 agent/discovery/query_fetcher_v2_test.go create mode 100644 agent/dns/buffer_response_writer.go delete mode 100644 agent/dns/discovery_results_fetcher.go delete mode 100644 agent/dns/discovery_results_fetcher_test.go delete mode 100644 agent/dns/dns_address.go delete mode 100644 agent/dns/dns_address_test.go delete mode 100644 agent/dns/dns_record_maker.go delete mode 100644 agent/dns/dns_record_maker_test.go delete mode 100644 agent/dns/message_serializer.go delete mode 100644 agent/dns/mock_DNSRouter.go delete mode 100644 agent/dns/mock_dnsRecursor.go delete mode 100644 agent/dns/parser.go delete mode 100644 agent/dns/parser_test.go delete mode 100644 agent/dns/recursor.go delete mode 100644 agent/dns/recursor_test.go delete mode 100644 agent/dns/response_generator.go delete mode 100644 agent/dns/response_generator_test.go delete mode 100644 agent/dns/router.go delete mode 100644 agent/dns/router_addr_test.go delete mode 100644 agent/dns/router_ns_test.go delete mode 100644 agent/dns/router_prepared_query_test.go delete mode 100644 agent/dns/router_ptr_test.go delete mode 100644 agent/dns/router_recursor_test.go delete mode 100644 agent/dns/router_service_test.go delete mode 100644 agent/dns/router_soa_test.go delete mode 100644 agent/dns/router_test.go delete mode 100644 agent/dns/router_v2_services_test.go delete mode 100644 agent/dns/router_virtual_test.go delete mode 100644 agent/dns/router_workload_test.go delete mode 100644 agent/dns/server.go delete mode 100644 agent/dns/server_test.go delete mode 100644 agent/dns_catalogv2_test.go delete mode 100644 agent/grpc-external/services/dns/server_v2.go delete mode 100644 agent/grpc-external/services/dns/server_v2_test.go diff --git a/agent/agent.go b/agent/agent.go index 88859a7b8b..a3916922df 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -48,8 +48,6 @@ import ( "github.com/hashicorp/consul/agent/consul" rpcRate "github.com/hashicorp/consul/agent/consul/rate" "github.com/hashicorp/consul/agent/consul/servercert" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/dns" external "github.com/hashicorp/consul/agent/grpc-external" grpcDNS "github.com/hashicorp/consul/agent/grpc-external/services/dns" middleware "github.com/hashicorp/consul/agent/grpc-middleware" @@ -222,7 +220,7 @@ type notifier interface { Notify(string) error } -// dnsServer abstracts the V1 and V2 implementations of the DNS server. +// dnsServer abstracts the implementations of the DNS server. type dnsServer interface { GetAddr() string ListenAndServe(string, string, func()) error @@ -354,10 +352,6 @@ type Agent struct { // dnsServer provides the DNS API dnsServers []dnsServer - // catalogDataFetcher is used as an interface to the catalog for service discovery - // (aka DNS). Only applicable to the V2 DNS server (agent/dns). - catalogDataFetcher discovery.CatalogDataFetcher - // apiServers listening for connections. If any of these server goroutines // fail, the agent will be shutdown. apiServers *apiServers @@ -879,14 +873,8 @@ func (a *Agent) Start(ctx context.Context) error { } // start DNS servers - if a.baseDeps.UseV1DNS() { - if err := a.listenAndServeV1DNS(); err != nil { - return err - } - } else { - if err := a.listenAndServeV2DNS(); err != nil { - return err - } + if err := a.listenAndServeDNS(); err != nil { + return err } // Configure the http connection limiter. @@ -1065,7 +1053,7 @@ func (a *Agent) listenAndServeGRPC(proxyTracker *proxytracker.ProxyTracker, serv return nil } -func (a *Agent) listenAndServeV1DNS() error { +func (a *Agent) listenAndServeDNS() error { notif := make(chan net.Addr, len(a.config.DNSAddrs)) errCh := make(chan error, len(a.config.DNSAddrs)) for _, addr := range a.config.DNSAddrs { @@ -1117,92 +1105,6 @@ func (a *Agent) listenAndServeV1DNS() error { return merr.ErrorOrNil() } -func (a *Agent) listenAndServeV2DNS() error { - - // Check the catalog version and decide which implementation of the data fetcher to implement - if a.baseDeps.UseV2Resources() { - a.catalogDataFetcher = discovery.NewV2DataFetcher(a.config, a.delegate.ResourceServiceClient(), a.logger.Named("catalog-data-fetcher")) - } else { - a.catalogDataFetcher = discovery.NewV1DataFetcher(a.config, - a.AgentEnterpriseMeta(), - a.cache.Get, - a.RPC, - a.rpcClientHealth.ServiceNodes, - a.rpcClientConfigEntry.GetSamenessGroup, - a.TranslateServicePort, - a.logger.Named("catalog-data-fetcher")) - } - - // Generate a Query Processor with the appropriate data fetcher - processor := discovery.NewQueryProcessor(a.catalogDataFetcher) - - notif := make(chan net.Addr, len(a.config.DNSAddrs)) - errCh := make(chan error, len(a.config.DNSAddrs)) - - // create server - cfg := dns.Config{ - AgentConfig: a.config, - EntMeta: *a.AgentEnterpriseMeta(), - Logger: a.logger, - Processor: processor, - TokenFunc: a.getTokenFunc(), - TranslateAddressFunc: a.TranslateAddress, - TranslateServiceAddressFunc: a.TranslateServiceAddress, - } - - for _, addr := range a.config.DNSAddrs { - s, err := dns.NewServer(cfg) - if err != nil { - return err - } - a.dnsServers = append(a.dnsServers, s) - - // start server - a.wgServers.Add(1) - go func(addr net.Addr) { - defer a.wgServers.Done() - err := s.ListenAndServe(addr.Network(), addr.String(), func() { notif <- addr }) - if err != nil && !strings.Contains(err.Error(), "accept") { - errCh <- err - } - }(addr) - } - - s, err := dns.NewServer(cfg) - if err != nil { - return fmt.Errorf("failed to create grpc dns server: %w", err) - } - - // Create a v2 compatible grpc dns server - grpcDNS.NewServerV2(grpcDNS.ConfigV2{ - Logger: a.logger.Named("grpc-api.dns"), - DNSRouter: s.Router, - TokenFunc: a.getTokenFunc(), - }).Register(a.externalGRPCServer) - - a.dnsServers = append(a.dnsServers, s) - - // wait for servers to be up - timeout := time.After(time.Second) - var merr *multierror.Error - for range a.config.DNSAddrs { - select { - case addr := <-notif: - a.logger.Info("Started DNS server", - "address", addr.String(), - "network", addr.Network(), - ) - - case err := <-errCh: - merr = multierror.Append(merr, err) - case <-timeout: - merr = multierror.Append(merr, fmt.Errorf("agent: timeout starting DNS servers")) - return merr.ErrorOrNil() - } - } - return merr.ErrorOrNil() -} - // startListeners will return a net.Listener for every address unless an // error is encountered, in which case it will close all previously opened // listeners and return the error. @@ -4414,10 +4316,6 @@ func (a *Agent) reloadConfigInternal(newCfg *config.RuntimeConfig) error { return fmt.Errorf("Failed reloading dns config : %v", err) } } - // This field is only populated for the V2 DNS server - if a.catalogDataFetcher != nil { - a.catalogDataFetcher.LoadConfig(newCfg) - } err := a.reloadEnterprise(newCfg) if err != nil { diff --git a/agent/config/builder_test.go b/agent/config/builder_test.go index 488fa9c7e0..a587dec132 100644 --- a/agent/config/builder_test.go +++ b/agent/config/builder_test.go @@ -618,9 +618,6 @@ func TestBuilder_CheckExperimentsInSecondaryDatacenters(t *testing.T) { "primary server v2catalog": { hcl: primary + `experiments = ["resource-apis"]`, }, - "primary server v1dns": { - hcl: primary + `experiments = ["v1dns"]`, - }, "primary server v2tenancy": { hcl: primary + `experiments = ["v2tenancy"]`, }, @@ -631,9 +628,6 @@ func TestBuilder_CheckExperimentsInSecondaryDatacenters(t *testing.T) { hcl: secondary + `experiments = ["resource-apis"]`, expectErr: true, }, - "secondary server v1dns": { - hcl: secondary + `experiments = ["v1dns"]`, - }, "secondary server v2tenancy": { hcl: secondary + `experiments = ["v2tenancy"]`, expectErr: true, diff --git a/agent/consul/options.go b/agent/consul/options.go index 0909bed70a..ced36bcad5 100644 --- a/agent/consul/options.go +++ b/agent/consul/options.go @@ -50,15 +50,6 @@ type Deps struct { EnterpriseDeps } -// UseV1DNS returns true if "v1dns" is present in the Experiments -// array of the agent config. It is ignored if the v2 resource APIs are enabled. -func (d Deps) UseV1DNS() bool { - if stringslice.Contains(d.Experiments, V1DNSExperimentName) && !d.UseV2Resources() { - return true - } - return false -} - // UseV2Resources returns true if "resource-apis" is present in the Experiments // array of the agent config. func (d Deps) UseV2Resources() bool { diff --git a/agent/consul/server.go b/agent/consul/server.go index b687c6c65d..12386cc9df 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -133,7 +133,6 @@ const ( LeaderTransferMinVersion = "1.6.0" CatalogResourceExperimentName = "resource-apis" - V1DNSExperimentName = "v1dns" V2TenancyExperimentName = "v2tenancy" HCPAllowV2ResourceAPIs = "hcp-v2-resource-apis" ) diff --git a/agent/discovery/discovery.go b/agent/discovery/discovery.go deleted file mode 100644 index ee2d742fe7..0000000000 --- a/agent/discovery/discovery.go +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package discovery - -import ( - "fmt" - "net" - - "github.com/hashicorp/consul/agent/config" -) - -var ( - ErrECSNotGlobal = fmt.Errorf("ECS response is not global") - ErrNoData = fmt.Errorf("no data") - ErrNotFound = fmt.Errorf("not found") - ErrNotSupported = fmt.Errorf("not supported") - ErrNoPathToDatacenter = fmt.Errorf("no path to datacenter") -) - -// ECSNotGlobalError may be used to wrap an error or nil, to indicate that the -// EDNS client subnet source scope is not global. -type ECSNotGlobalError struct { - error -} - -func (e ECSNotGlobalError) Error() string { - if e.error == nil { - return "" - } - return e.error.Error() -} - -func (e ECSNotGlobalError) Is(other error) bool { - return other == ErrECSNotGlobal -} - -func (e ECSNotGlobalError) Unwrap() error { - return e.error -} - -// Query is used to request a name-based Service Discovery lookup. -type Query struct { - QueryType QueryType - QueryPayload QueryPayload -} - -// QueryType is used to filter service endpoints. -// This is needed by the V1 catalog because of the -// overlapping lookups through the service endpoint. -type QueryType string - -const ( - QueryTypeConnect QueryType = "CONNECT" // deprecated: use for V1 only - QueryTypeIngress QueryType = "INGRESS" // deprecated: use for V1 only - QueryTypeInvalid QueryType = "INVALID" - QueryTypeNode QueryType = "NODE" - QueryTypePreparedQuery QueryType = "PREPARED_QUERY" // deprecated: use for V1 only - QueryTypeService QueryType = "SERVICE" - QueryTypeVirtual QueryType = "VIRTUAL" - QueryTypeWorkload QueryType = "WORKLOAD" // V2-only -) - -// Context is used to pass information about the request. -type Context struct { - Token string -} - -// QueryTenancy is used to filter catalog data based on tenancy. -type QueryTenancy struct { - Namespace string - Partition string - SamenessGroup string - Peer string - Datacenter string -} - -// QueryPayload represents all information needed by the data backend -// to decide which records to include. -type QueryPayload struct { - Name string - PortName string // v1 - this could optionally be "connect" or "ingress"; v2 - this is the service port name - Tag string // deprecated: use for V1 only - SourceIP net.IP // deprecated: used for prepared queries - Tenancy QueryTenancy // tenancy includes any additional labels specified before the domain - Limit int // The maximum number of records to return - - // v2 fields only - EnableFailover bool -} - -// ResultType indicates the Consul resource that a discovery record represents. -// This is useful for things like adding TTLs for different objects in the DNS. -type ResultType string - -const ( - ResultTypeService ResultType = "SERVICE" - ResultTypeNode ResultType = "NODE" - ResultTypeVirtual ResultType = "VIRTUAL" - ResultTypeWorkload ResultType = "WORKLOAD" -) - -// Result is a generic format of targets that could be returned in a query. -// It is the responsibility of the DNS encoder to know what to do with -// each Result, based on the query type. -type Result struct { - Service *Location // The name and address of the service. - Node *Location // The name and address of the node. - Metadata map[string]string // Used to collect metadata into TXT Records - Type ResultType // Used to reconstruct the fqdn name of the resource - DNS DNSConfig // Used for DNS-specific configuration for this result - - // Ports include anything the node/service/workload implements. These are filtered if requested by the client. - // They are used in to generate the FQDN and SRV port numbers in V2 Catalog responses. - Ports []Port - - Tenancy ResultTenancy -} - -// TaggedAddress is used to represent a tagged address. -type TaggedAddress struct { - Name string - Address string - Port Port -} - -// Location is used to represent a service, node, or workload. -type Location struct { - Name string - Address string - TaggedAddresses map[string]*TaggedAddress // Used to collect tagged addresses into A/AAAA Records -} - -type DNSConfig struct { - TTL *uint32 // deprecated: use for V1 prepared queries only - Weight uint32 // SRV queries -} - -type Port struct { - Name string - Number uint32 -} - -// ResultTenancy is used to reconstruct the fqdn name of the resource. -type ResultTenancy struct { - Namespace string - Partition string - PeerName string - Datacenter string -} - -// LookupType is used by the CatalogDataFetcher to properly filter endpoints. -type LookupType string - -const ( - LookupTypeService LookupType = "SERVICE" - LookupTypeConnect LookupType = "CONNECT" - LookupTypeIngress LookupType = "INGRESS" -) - -// CatalogDataFetcher is an interface that abstracts data collection -// for Discovery queries. It is assumed that the instantiation also -// includes any agent configuration that influences catalog queries. -// -//go:generate mockery --name CatalogDataFetcher --inpackage -type CatalogDataFetcher interface { - // LoadConfig is used to hot-reload the data fetcher with new agent config. - LoadConfig(config *config.RuntimeConfig) - - // FetchNodes fetches A/AAAA/CNAME - FetchNodes(ctx Context, req *QueryPayload) ([]*Result, error) - - // FetchEndpoints fetches records for A/AAAA/CNAME or SRV requests for services - FetchEndpoints(ctx Context, req *QueryPayload, lookupType LookupType) ([]*Result, error) - - // FetchVirtualIP fetches A/AAAA records for virtual IPs - FetchVirtualIP(ctx Context, req *QueryPayload) (*Result, error) - - // FetchRecordsByIp is used for PTR requests - // to look up a service/node from an IP. - FetchRecordsByIp(ctx Context, ip net.IP) ([]*Result, error) - - // FetchWorkload fetches a single Result associated with - // V2 Workload. V2-only. - FetchWorkload(ctx Context, req *QueryPayload) (*Result, error) - - // FetchPreparedQuery evaluates the results of a prepared query. - // deprecated in V2 - FetchPreparedQuery(ctx Context, req *QueryPayload) ([]*Result, error) - - // NormalizeRequest mutates the original request based on data fetcher configuration, like - // defaulting tenancy to the agent's partition. - NormalizeRequest(req *QueryPayload) - - // ValidateRequest throws an error is any of the input fields are invalid for this data fetcher. - ValidateRequest(ctx Context, req *QueryPayload) error -} - -// QueryProcessor is used to process a Discovery Query and return the results. -type QueryProcessor struct { - dataFetcher CatalogDataFetcher -} - -// NewQueryProcessor creates a new QueryProcessor. -func NewQueryProcessor(dataFetcher CatalogDataFetcher) *QueryProcessor { - return &QueryProcessor{ - dataFetcher: dataFetcher, - } -} - -// QueryByName is used to look up a service, node, workload, or prepared query. -func (p *QueryProcessor) QueryByName(query *Query, ctx Context) ([]*Result, error) { - if err := p.dataFetcher.ValidateRequest(ctx, &query.QueryPayload); err != nil { - return nil, err - } - - p.dataFetcher.NormalizeRequest(&query.QueryPayload) - - switch query.QueryType { - case QueryTypeNode: - return p.dataFetcher.FetchNodes(ctx, &query.QueryPayload) - case QueryTypeService: - return p.dataFetcher.FetchEndpoints(ctx, &query.QueryPayload, LookupTypeService) - case QueryTypeConnect: - return p.dataFetcher.FetchEndpoints(ctx, &query.QueryPayload, LookupTypeConnect) - case QueryTypeIngress: - return p.dataFetcher.FetchEndpoints(ctx, &query.QueryPayload, LookupTypeIngress) - case QueryTypeVirtual: - result, err := p.dataFetcher.FetchVirtualIP(ctx, &query.QueryPayload) - if err != nil { - return nil, err - } - return []*Result{result}, nil - case QueryTypeWorkload: - result, err := p.dataFetcher.FetchWorkload(ctx, &query.QueryPayload) - if err != nil { - return nil, err - } - return []*Result{result}, nil - case QueryTypePreparedQuery: - return p.dataFetcher.FetchPreparedQuery(ctx, &query.QueryPayload) - default: - return nil, fmt.Errorf("unknown query type: %s", query.QueryType) - } -} - -// QueryByIP is used to look up a service or node from an IP address. -func (p *QueryProcessor) QueryByIP(ip net.IP, reqCtx Context) ([]*Result, error) { - return p.dataFetcher.FetchRecordsByIp(reqCtx, ip) -} diff --git a/agent/discovery/discovery_test.go b/agent/discovery/discovery_test.go deleted file mode 100644 index a53ec7b866..0000000000 --- a/agent/discovery/discovery_test.go +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package discovery - -import ( - "errors" - "net" - "testing" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -var ( - testContext = Context{ - Token: "bar", - } - - testErr = errors.New("test error") - - testIP = net.ParseIP("1.2.3.4") - - testPayload = QueryPayload{ - Name: "foo", - } - - testResult = &Result{ - Node: &Location{Address: "1.2.3.4"}, - Type: ResultTypeNode, // This isn't correct for some test cases, but we are only asserting the right data fetcher functions are called - Service: &Location{Name: "foo"}, - } -) - -func TestQueryByName(t *testing.T) { - - type testCase struct { - name string - reqType QueryType - configureDataFetcher func(*testing.T, *MockCatalogDataFetcher) - expectedResults []*Result - expectedError error - } - - run := func(t *testing.T, tc testCase) { - - fetcher := NewMockCatalogDataFetcher(t) - tc.configureDataFetcher(t, fetcher) - - qp := NewQueryProcessor(fetcher) - - q := Query{ - QueryType: tc.reqType, - QueryPayload: testPayload, - } - - results, err := qp.QueryByName(&q, testContext) - if tc.expectedError != nil { - require.Error(t, err) - require.True(t, errors.Is(err, tc.expectedError)) - require.Nil(t, results) - return - } - require.NoError(t, err) - require.Equal(t, tc.expectedResults, results) - } - - testCases := []testCase{ - { - name: "query node", - reqType: QueryTypeNode, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchNodes", mock.Anything, mock.Anything).Return([]*Result{testResult}, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "query service", - reqType: QueryTypeService, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything).Return([]*Result{testResult}, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "query connect", - reqType: QueryTypeConnect, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything).Return([]*Result{testResult}, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "query ingress", - reqType: QueryTypeIngress, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything).Return([]*Result{testResult}, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "query virtual ip", - reqType: QueryTypeVirtual, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchVirtualIP", mock.Anything, mock.Anything).Return(testResult, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "query workload", - reqType: QueryTypeWorkload, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchWorkload", mock.Anything, mock.Anything).Return(testResult, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "query prepared query", - reqType: QueryTypePreparedQuery, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchPreparedQuery", mock.Anything, mock.Anything).Return([]*Result{testResult}, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "returns error from validation", - reqType: QueryTypePreparedQuery, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(testErr) - }, - expectedError: testErr, - }, - { - name: "returns error from fetcher", - reqType: QueryTypePreparedQuery, - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - fetcher.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - fetcher.On("NormalizeRequest", mock.Anything) - fetcher.On("FetchPreparedQuery", mock.Anything, mock.Anything).Return(nil, testErr) - }, - expectedError: testErr, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestQueryByIP(t *testing.T) { - type testCase struct { - name string - configureDataFetcher func(*testing.T, *MockCatalogDataFetcher) - expectedResults []*Result - expectedError error - } - - run := func(t *testing.T, tc testCase) { - - fetcher := NewMockCatalogDataFetcher(t) - tc.configureDataFetcher(t, fetcher) - - qp := NewQueryProcessor(fetcher) - - results, err := qp.QueryByIP(testIP, testContext) - if tc.expectedError != nil { - require.Error(t, err) - require.True(t, errors.Is(err, tc.expectedError)) - require.Nil(t, results) - return - } - require.NoError(t, err) - require.Equal(t, tc.expectedResults, results) - } - - testCases := []testCase{ - { - name: "query by IP", - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - fetcher.On("FetchRecordsByIp", mock.Anything, mock.Anything).Return([]*Result{testResult}, nil) - }, - expectedResults: []*Result{testResult}, - }, - { - name: "returns error from fetcher", - configureDataFetcher: func(t *testing.T, fetcher *MockCatalogDataFetcher) { - fetcher.On("FetchRecordsByIp", mock.Anything, mock.Anything).Return(nil, testErr) - }, - expectedError: testErr, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/agent/discovery/mock_CatalogDataFetcher.go b/agent/discovery/mock_CatalogDataFetcher.go deleted file mode 100644 index f80a6010d2..0000000000 --- a/agent/discovery/mock_CatalogDataFetcher.go +++ /dev/null @@ -1,209 +0,0 @@ -// Code generated by mockery v2.37.1. DO NOT EDIT. - -package discovery - -import ( - config "github.com/hashicorp/consul/agent/config" - mock "github.com/stretchr/testify/mock" - - net "net" -) - -// MockCatalogDataFetcher is an autogenerated mock type for the CatalogDataFetcher type -type MockCatalogDataFetcher struct { - mock.Mock -} - -// FetchEndpoints provides a mock function with given fields: ctx, req, lookupType -func (_m *MockCatalogDataFetcher) FetchEndpoints(ctx Context, req *QueryPayload, lookupType LookupType) ([]*Result, error) { - ret := _m.Called(ctx, req, lookupType) - - var r0 []*Result - var r1 error - if rf, ok := ret.Get(0).(func(Context, *QueryPayload, LookupType) ([]*Result, error)); ok { - return rf(ctx, req, lookupType) - } - if rf, ok := ret.Get(0).(func(Context, *QueryPayload, LookupType) []*Result); ok { - r0 = rf(ctx, req, lookupType) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*Result) - } - } - - if rf, ok := ret.Get(1).(func(Context, *QueryPayload, LookupType) error); ok { - r1 = rf(ctx, req, lookupType) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FetchNodes provides a mock function with given fields: ctx, req -func (_m *MockCatalogDataFetcher) FetchNodes(ctx Context, req *QueryPayload) ([]*Result, error) { - ret := _m.Called(ctx, req) - - var r0 []*Result - var r1 error - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) ([]*Result, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) []*Result); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*Result) - } - } - - if rf, ok := ret.Get(1).(func(Context, *QueryPayload) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FetchPreparedQuery provides a mock function with given fields: ctx, req -func (_m *MockCatalogDataFetcher) FetchPreparedQuery(ctx Context, req *QueryPayload) ([]*Result, error) { - ret := _m.Called(ctx, req) - - var r0 []*Result - var r1 error - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) ([]*Result, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) []*Result); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*Result) - } - } - - if rf, ok := ret.Get(1).(func(Context, *QueryPayload) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FetchRecordsByIp provides a mock function with given fields: ctx, ip -func (_m *MockCatalogDataFetcher) FetchRecordsByIp(ctx Context, ip net.IP) ([]*Result, error) { - ret := _m.Called(ctx, ip) - - var r0 []*Result - var r1 error - if rf, ok := ret.Get(0).(func(Context, net.IP) ([]*Result, error)); ok { - return rf(ctx, ip) - } - if rf, ok := ret.Get(0).(func(Context, net.IP) []*Result); ok { - r0 = rf(ctx, ip) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*Result) - } - } - - if rf, ok := ret.Get(1).(func(Context, net.IP) error); ok { - r1 = rf(ctx, ip) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FetchVirtualIP provides a mock function with given fields: ctx, req -func (_m *MockCatalogDataFetcher) FetchVirtualIP(ctx Context, req *QueryPayload) (*Result, error) { - ret := _m.Called(ctx, req) - - var r0 *Result - var r1 error - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) (*Result, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) *Result); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*Result) - } - } - - if rf, ok := ret.Get(1).(func(Context, *QueryPayload) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FetchWorkload provides a mock function with given fields: ctx, req -func (_m *MockCatalogDataFetcher) FetchWorkload(ctx Context, req *QueryPayload) (*Result, error) { - ret := _m.Called(ctx, req) - - var r0 *Result - var r1 error - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) (*Result, error)); ok { - return rf(ctx, req) - } - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) *Result); ok { - r0 = rf(ctx, req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*Result) - } - } - - if rf, ok := ret.Get(1).(func(Context, *QueryPayload) error); ok { - r1 = rf(ctx, req) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LoadConfig provides a mock function with given fields: _a0 -func (_m *MockCatalogDataFetcher) LoadConfig(_a0 *config.RuntimeConfig) { - _m.Called(_a0) -} - -// NormalizeRequest provides a mock function with given fields: req -func (_m *MockCatalogDataFetcher) NormalizeRequest(req *QueryPayload) { - _m.Called(req) -} - -// ValidateRequest provides a mock function with given fields: ctx, req -func (_m *MockCatalogDataFetcher) ValidateRequest(ctx Context, req *QueryPayload) error { - ret := _m.Called(ctx, req) - - var r0 error - if rf, ok := ret.Get(0).(func(Context, *QueryPayload) error); ok { - r0 = rf(ctx, req) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// NewMockCatalogDataFetcher creates a new instance of MockCatalogDataFetcher. 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 NewMockCatalogDataFetcher(t interface { - mock.TestingT - Cleanup(func()) -}) *MockCatalogDataFetcher { - mock := &MockCatalogDataFetcher{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/agent/discovery/query_fetcher_v1.go b/agent/discovery/query_fetcher_v1.go deleted file mode 100644 index 31f74c0119..0000000000 --- a/agent/discovery/query_fetcher_v1.go +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package discovery - -import ( - "context" - "fmt" - "net" - "strings" - "sync/atomic" - "time" - - "github.com/armon/go-metrics" - "github.com/armon/go-metrics/prometheus" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/cache" - cachetype "github.com/hashicorp/consul/agent/cache-types" - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" -) - -const ( - // Increment a counter when requests staler than this are served - staleCounterThreshold = 5 * time.Second -) - -// DNSCounters pre-registers the staleness metric. -// This value is used by both the V1 and V2 DNS (V1 Catalog-only) servers. -var DNSCounters = []prometheus.CounterDefinition{ - { - Name: []string{"dns", "stale_queries"}, - Help: "Increments when an agent serves a query within the allowed stale threshold.", - }, -} - -// V1DataFetcherDynamicConfig is used to store the dynamic configuration of the V1 data fetcher. -type V1DataFetcherDynamicConfig struct { - // Default request tenancy - Datacenter string - - SegmentName string - NodeName string - NodePartition string - - // Catalog configuration - AllowStale bool - MaxStale time.Duration - UseCache bool - CacheMaxAge time.Duration - OnlyPassing bool -} - -// V1DataFetcher is used to fetch data from the V1 catalog. -type V1DataFetcher struct { - defaultEnterpriseMeta acl.EnterpriseMeta - dynamicConfig atomic.Value - logger hclog.Logger - - getFromCacheFunc func(ctx context.Context, t string, r cache.Request) (interface{}, cache.ResultMeta, error) - rpcFunc func(ctx context.Context, method string, args interface{}, reply interface{}) error - rpcFuncForServiceNodes func(ctx context.Context, req structs.ServiceSpecificRequest) (structs.IndexedCheckServiceNodes, cache.ResultMeta, error) - rpcFuncForSamenessGroup func(ctx context.Context, req *structs.ConfigEntryQuery) (structs.SamenessGroupConfigEntry, cache.ResultMeta, error) - translateServicePortFunc func(dc string, port int, taggedAddresses map[string]structs.ServiceAddress) int -} - -// NewV1DataFetcher creates a new V1 data fetcher. -func NewV1DataFetcher(config *config.RuntimeConfig, - entMeta *acl.EnterpriseMeta, - getFromCacheFunc func(ctx context.Context, t string, r cache.Request) (interface{}, cache.ResultMeta, error), - rpcFunc func(ctx context.Context, method string, args interface{}, reply interface{}) error, - rpcFuncForServiceNodes func(ctx context.Context, req structs.ServiceSpecificRequest) (structs.IndexedCheckServiceNodes, cache.ResultMeta, error), - rpcFuncForSamenessGroup func(ctx context.Context, req *structs.ConfigEntryQuery) (structs.SamenessGroupConfigEntry, cache.ResultMeta, error), - translateServicePortFunc func(dc string, port int, taggedAddresses map[string]structs.ServiceAddress) int, - logger hclog.Logger) *V1DataFetcher { - f := &V1DataFetcher{ - defaultEnterpriseMeta: *entMeta, - getFromCacheFunc: getFromCacheFunc, - rpcFunc: rpcFunc, - rpcFuncForServiceNodes: rpcFuncForServiceNodes, - rpcFuncForSamenessGroup: rpcFuncForSamenessGroup, - translateServicePortFunc: translateServicePortFunc, - logger: logger, - } - f.LoadConfig(config) - return f -} - -// LoadConfig loads the configuration for the V1 data fetcher. -func (f *V1DataFetcher) LoadConfig(config *config.RuntimeConfig) { - dynamicConfig := &V1DataFetcherDynamicConfig{ - AllowStale: config.DNSAllowStale, - MaxStale: config.DNSMaxStale, - UseCache: config.DNSUseCache, - CacheMaxAge: config.DNSCacheMaxAge, - OnlyPassing: config.DNSOnlyPassing, - Datacenter: config.Datacenter, - SegmentName: config.SegmentName, - NodeName: config.NodeName, - } - f.dynamicConfig.Store(dynamicConfig) -} - -func (f *V1DataFetcher) GetConfig() *V1DataFetcherDynamicConfig { - return f.dynamicConfig.Load().(*V1DataFetcherDynamicConfig) -} - -// FetchNodes fetches A/AAAA/CNAME -func (f *V1DataFetcher) FetchNodes(ctx Context, req *QueryPayload) ([]*Result, error) { - if req.Tenancy.Namespace != "" && req.Tenancy.Namespace != acl.DefaultNamespaceName { - // Nodes are not namespaced, so this is a name error - return nil, ErrNotFound - } - cfg := f.dynamicConfig.Load().(*V1DataFetcherDynamicConfig) - - // If no datacenter is passed, default to our own - datacenter := cfg.Datacenter - if req.Tenancy.Datacenter != "" { - datacenter = req.Tenancy.Datacenter - } - - // Make an RPC request - args := &structs.NodeSpecificRequest{ - Datacenter: datacenter, - PeerName: req.Tenancy.Peer, - Node: req.Name, - QueryOptions: structs.QueryOptions{ - Token: ctx.Token, - AllowStale: cfg.AllowStale, - }, - EnterpriseMeta: queryTenancyToEntMeta(req.Tenancy), - } - out, err := f.fetchNode(cfg, args) - if err != nil { - return nil, fmt.Errorf("failed rpc request: %w", err) - } - - // If we have no out.NodeServices.Nodeaddress, return not found! - if out.NodeServices == nil { - return nil, ErrNotFound - } - - results := make([]*Result, 0, 1) - n := out.NodeServices.Node - - results = append(results, &Result{ - Node: &Location{ - Name: n.Node, - Address: n.Address, - TaggedAddresses: makeTaggedAddressesFromStrings(n.TaggedAddresses), - }, - Type: ResultTypeNode, - Metadata: n.Meta, - - Tenancy: ResultTenancy{ - // Namespace is not required because nodes are not namespaced - Partition: n.GetEnterpriseMeta().PartitionOrDefault(), - Datacenter: n.Datacenter, - }, - }) - - return results, nil -} - -// FetchEndpoints fetches records for A/AAAA/CNAME or SRV requests for services -func (f *V1DataFetcher) FetchEndpoints(ctx Context, req *QueryPayload, lookupType LookupType) ([]*Result, error) { - f.logger.Trace(fmt.Sprintf("FetchEndpoints - req: %+v / lookupType: %+v", req, lookupType)) - cfg := f.dynamicConfig.Load().(*V1DataFetcherDynamicConfig) - return f.fetchService(ctx, req, cfg, lookupType) -} - -// FetchVirtualIP fetches A/AAAA records for virtual IPs -func (f *V1DataFetcher) FetchVirtualIP(ctx Context, req *QueryPayload) (*Result, error) { - args := structs.ServiceSpecificRequest{ - // The Datacenter of the request is not specified because cross-Datacenter virtual IP - // queries are not supported. This guard rail is in place because virtual IPs are allocated - // within a DC, therefore their uniqueness is not guaranteed globally. - PeerName: req.Tenancy.Peer, - ServiceName: req.Name, - EnterpriseMeta: queryTenancyToEntMeta(req.Tenancy), - QueryOptions: structs.QueryOptions{ - Token: ctx.Token, - }, - } - - var out string - if err := f.rpcFunc(context.Background(), "Catalog.VirtualIPForService", &args, &out); err != nil { - return nil, err - } - - result := &Result{ - Service: &Location{ - Name: req.Name, - Address: out, - }, - Type: ResultTypeVirtual, - } - return result, nil -} - -// FetchRecordsByIp is used for PTR requests to look up a service/node from an IP. -// The search is performed in the agent's partition and over all namespaces (or those allowed by the ACL token). -func (f *V1DataFetcher) FetchRecordsByIp(reqCtx Context, ip net.IP) ([]*Result, error) { - if ip == nil { - return nil, ErrNotSupported - } - - configCtx := f.dynamicConfig.Load().(*V1DataFetcherDynamicConfig) - targetIP := ip.String() - - var results []*Result - - args := structs.DCSpecificRequest{ - Datacenter: configCtx.Datacenter, - QueryOptions: structs.QueryOptions{ - Token: reqCtx.Token, - AllowStale: configCtx.AllowStale, - }, - } - var out structs.IndexedNodes - - // TODO: Replace ListNodes with an internal RPC that can do the filter - // server side to avoid transferring the entire node list. - if err := f.rpcFunc(context.Background(), "Catalog.ListNodes", &args, &out); err == nil { - for _, n := range out.Nodes { - if targetIP == n.Address { - results = append(results, &Result{ - Node: &Location{ - Name: n.Node, - Address: n.Address, - TaggedAddresses: makeTaggedAddressesFromStrings(n.TaggedAddresses), - }, - Type: ResultTypeNode, - Tenancy: ResultTenancy{ - Namespace: f.defaultEnterpriseMeta.NamespaceOrDefault(), - Partition: f.defaultEnterpriseMeta.PartitionOrDefault(), - Datacenter: configCtx.Datacenter, - }, - }) - return results, nil - } - } - } - - // only look into the services if we didn't find a node - sargs := structs.ServiceSpecificRequest{ - Datacenter: configCtx.Datacenter, - QueryOptions: structs.QueryOptions{ - Token: reqCtx.Token, - AllowStale: configCtx.AllowStale, - }, - ServiceAddress: targetIP, - EnterpriseMeta: *f.defaultEnterpriseMeta.WithWildcardNamespace(), - } - - var sout structs.IndexedServiceNodes - if err := f.rpcFunc(context.Background(), "Catalog.ServiceNodes", &sargs, &sout); err == nil { - if len(sout.ServiceNodes) == 0 { - return nil, ErrNotFound - } - - for _, n := range sout.ServiceNodes { - if n.ServiceAddress == targetIP { - results = append(results, &Result{ - Service: &Location{ - Name: n.ServiceName, - Address: n.ServiceAddress, - }, - Type: ResultTypeService, - Node: &Location{ - Name: n.Node, - Address: n.Address, - }, - Tenancy: ResultTenancy{ - Namespace: n.NamespaceOrEmpty(), - Partition: n.PartitionOrEmpty(), - Datacenter: n.Datacenter, - }, - }) - return results, nil - } - } - } - - // nothing found locally, recurse - // TODO: (v2-dns) implement recursion (NET-7883) - //d.handleRecurse(resp, req) - - return nil, fmt.Errorf("unhandled error in FetchRecordsByIp") -} - -// FetchWorkload fetches a single Result associated with -// V2 Workload. V2-only. -func (f *V1DataFetcher) FetchWorkload(ctx Context, req *QueryPayload) (*Result, error) { - return nil, ErrNotSupported -} - -// FetchPreparedQuery evaluates the results of a prepared query. -// deprecated in V2 -func (f *V1DataFetcher) FetchPreparedQuery(ctx Context, req *QueryPayload) ([]*Result, error) { - cfg := f.dynamicConfig.Load().(*V1DataFetcherDynamicConfig) - - // If no datacenter is passed, default to our own - datacenter := cfg.Datacenter - if req.Tenancy.Datacenter != "" { - datacenter = req.Tenancy.Datacenter - } - - // Execute the prepared query. - args := structs.PreparedQueryExecuteRequest{ - Datacenter: datacenter, - QueryIDOrName: req.Name, - QueryOptions: structs.QueryOptions{ - Token: ctx.Token, - AllowStale: cfg.AllowStale, - MaxAge: cfg.CacheMaxAge, - }, - - // Always pass the local agent through. In the DNS interface, there - // is no provision for passing additional query parameters, so we - // send the local agent's data through to allow distance sorting - // relative to ourself on the server side. - Agent: structs.QuerySource{ - Datacenter: cfg.Datacenter, - Segment: cfg.SegmentName, - Node: cfg.NodeName, - NodePartition: cfg.NodePartition, - }, - Source: structs.QuerySource{ - Ip: req.SourceIP.String(), - }, - } - - out, err := f.executePreparedQuery(cfg, args) - if err != nil { - // errors.Is() doesn't work with errors.New() so we need to check the error message. - if err.Error() == structs.ErrQueryNotFound.Error() { - err = ErrNotFound - } - return nil, ECSNotGlobalError{err} - } - - // TODO (slackpad) - What's a safe limit we can set here? It seems like - // with dup filtering done at this level we need to get everything to - // match the previous behavior. We can optimize by pushing more filtering - // into the query execution, but for now I think we need to get the full - // response. We could also choose a large arbitrary number that will - // likely work in practice, like 10*maxUDPAnswerLimit which should help - // reduce bandwidth if there are thousands of nodes available. - // Determine the TTL. The parse should never fail since we vet it when - // the query is created, but we check anyway. If the query didn't - // specify a TTL then we will try to use the agent's service-specific - // TTL configs. - - // Check is there is a TTL provided as part of the prepared query - var ttlOverride *uint32 - if out.DNS.TTL != "" { - ttl, err := time.ParseDuration(out.DNS.TTL) - if err == nil { - ttlSec := uint32(ttl / time.Second) - ttlOverride = &ttlSec - } else { - f.logger.Warn("Failed to parse TTL for prepared query , ignoring", - "ttl", out.DNS.TTL, - "prepared_query", req.Name, - ) - } - } - - // If we have no nodes, return not found! - if len(out.Nodes) == 0 { - return nil, ECSNotGlobalError{ErrNotFound} - } - - // Perform a random shuffle - out.Nodes.Shuffle() - return f.buildResultsFromServiceNodes(out.Nodes, req, ttlOverride), ECSNotGlobalError{} -} - -// executePreparedQuery is used to execute a PreparedQuery against the Consul catalog. -// If the config is set to UseCache, it will use agent cache. -func (f *V1DataFetcher) executePreparedQuery(cfg *V1DataFetcherDynamicConfig, args structs.PreparedQueryExecuteRequest) (*structs.PreparedQueryExecuteResponse, error) { - var out structs.PreparedQueryExecuteResponse - -RPC: - if cfg.UseCache { - raw, m, err := f.getFromCacheFunc(context.TODO(), cachetype.PreparedQueryName, &args) - if err != nil { - return nil, err - } - reply, ok := raw.(*structs.PreparedQueryExecuteResponse) - if !ok { - // This should never happen, but we want to protect against panics - return nil, err - } - - f.logger.Trace("cache results for prepared query", - "cache_hit", m.Hit, - "prepared_query", args.QueryIDOrName, - ) - - out = *reply - } else { - if err := f.rpcFunc(context.Background(), "PreparedQuery.Execute", &args, &out); err != nil { - return nil, err - } - } - - // Verify that request is not too stale, redo the request. - if args.AllowStale { - if out.LastContact > cfg.MaxStale { - args.AllowStale = false - f.logger.Warn("Query results too stale, re-requesting") - goto RPC - } else if out.LastContact > staleCounterThreshold { - metrics.IncrCounter([]string{"dns", "stale_queries"}, 1) - } - } - - return &out, nil -} - -func (f *V1DataFetcher) ValidateRequest(_ Context, req *QueryPayload) error { - if req.EnableFailover { - return ErrNotSupported - } - if req.PortName != "" { - return ErrNotSupported - } - return validateEnterpriseTenancy(req.Tenancy) -} - -// buildResultsFromServiceNodes builds a list of results from a list of nodes. -func (f *V1DataFetcher) buildResultsFromServiceNodes(nodes []structs.CheckServiceNode, req *QueryPayload, ttlOverride *uint32) []*Result { - // Convert the service endpoints to results up to the limit - limit := req.Limit - if len(nodes) < limit || limit == 0 { - limit = len(nodes) - } - - results := make([]*Result, 0, limit) - for idx := 0; idx < limit; idx++ { - n := nodes[idx] - results = append(results, &Result{ - Service: &Location{ - Name: n.Service.Service, - Address: n.Service.Address, - TaggedAddresses: makeTaggedAddressesFromServiceAddresses(n.Service.TaggedAddresses), - }, - Node: &Location{ - Name: n.Node.Node, - Address: n.Node.Address, - TaggedAddresses: makeTaggedAddressesFromStrings(n.Node.TaggedAddresses), - }, - Type: ResultTypeService, - DNS: DNSConfig{ - TTL: ttlOverride, - Weight: uint32(findWeight(n)), - }, - Ports: []Port{ - {Number: uint32(f.translateServicePortFunc(n.Node.Datacenter, n.Service.Port, n.Service.TaggedAddresses))}, - }, - Metadata: n.Node.Meta, - Tenancy: ResultTenancy{ - Namespace: n.Service.NamespaceOrEmpty(), - Partition: n.Service.PartitionOrEmpty(), - Datacenter: n.Node.Datacenter, - PeerName: n.Service.PeerName, - }, - }) - } - return results -} - -// makeTaggedAddressesFromServiceAddresses is used to convert a map of service addresses to a map of Locations. -func makeTaggedAddressesFromServiceAddresses(tagged map[string]structs.ServiceAddress) map[string]*TaggedAddress { - taggedAddresses := make(map[string]*TaggedAddress) - for k, v := range tagged { - taggedAddresses[k] = &TaggedAddress{ - Name: k, - Address: v.Address, - Port: Port{ - Number: uint32(v.Port), - }, - } - } - return taggedAddresses -} - -// makeTaggedAddressesFromStrings is used to convert a map of strings to a map of Locations. -func makeTaggedAddressesFromStrings(tagged map[string]string) map[string]*TaggedAddress { - taggedAddresses := make(map[string]*TaggedAddress) - for k, v := range tagged { - taggedAddresses[k] = &TaggedAddress{ - Name: k, - Address: v, - } - } - return taggedAddresses -} - -// fetchNode is used to look up a node in the Consul catalog within NodeServices. -// If the config is set to UseCache, it will get the record from the agent cache. -func (f *V1DataFetcher) fetchNode(cfg *V1DataFetcherDynamicConfig, args *structs.NodeSpecificRequest) (*structs.IndexedNodeServices, error) { - var out structs.IndexedNodeServices - - useCache := cfg.UseCache -RPC: - if useCache { - raw, _, err := f.getFromCacheFunc(context.TODO(), cachetype.NodeServicesName, args) - if err != nil { - return nil, err - } - reply, ok := raw.(*structs.IndexedNodeServices) - if !ok { - // This should never happen, but we want to protect against panics - return nil, fmt.Errorf("internal error: response type not correct") - } - out = *reply - } else { - if err := f.rpcFunc(context.Background(), "Catalog.NodeServices", &args, &out); err != nil { - return nil, err - } - } - - // Verify that request is not too stale, redo the request - if args.AllowStale { - if out.LastContact > cfg.MaxStale { - args.AllowStale = false - useCache = false - f.logger.Warn("Query results too stale, re-requesting") - goto RPC - } else if out.LastContact > staleCounterThreshold { - metrics.IncrCounter([]string{"dns", "stale_queries"}, 1) - } - } - - return &out, nil -} - -// fetchService is used to look up a service in the Consul catalog. -func (f *V1DataFetcher) fetchService(ctx Context, req *QueryPayload, - cfg *V1DataFetcherDynamicConfig, lookupType LookupType) ([]*Result, error) { - f.logger.Trace(fmt.Sprintf("fetchService - req: %+v", req)) - - // If no datacenter is passed, default to our own - datacenter := cfg.Datacenter - if req.Tenancy.Datacenter != "" { - datacenter = req.Tenancy.Datacenter - } - if req.Tenancy.Peer != "" { - datacenter = "" - } - - serviceTags := []string{} - if req.Tag != "" { - serviceTags = []string{req.Tag} - } - healthFilterType := structs.HealthFilterExcludeCritical - if cfg.OnlyPassing { - healthFilterType = structs.HealthFilterIncludeOnlyPassing - } - args := structs.ServiceSpecificRequest{ - PeerName: req.Tenancy.Peer, - SamenessGroup: req.Tenancy.SamenessGroup, - Connect: lookupType == LookupTypeConnect, - Ingress: lookupType == LookupTypeIngress, - Datacenter: datacenter, - ServiceName: req.Name, - ServiceTags: serviceTags, - TagFilter: req.Tag != "", - HealthFilterType: healthFilterType, - QueryOptions: structs.QueryOptions{ - Token: ctx.Token, - AllowStale: cfg.AllowStale, - MaxAge: cfg.CacheMaxAge, - UseCache: cfg.UseCache, - MaxStaleDuration: cfg.MaxStale, - }, - EnterpriseMeta: queryTenancyToEntMeta(req.Tenancy), - } - - out, _, err := f.rpcFuncForServiceNodes(context.TODO(), args) - if err != nil { - if strings.Contains(err.Error(), structs.ErrNoDCPath.Error()) { - return nil, ErrNoPathToDatacenter - } - return nil, fmt.Errorf("rpc request failed: %w", err) - } - - // If we have no nodes, return not found! - if len(out.Nodes) == 0 { - return nil, ErrNotFound - } - - // Perform a random shuffle - out.Nodes.Shuffle() - return f.buildResultsFromServiceNodes(out.Nodes, req, nil), nil -} - -// findWeight returns the weight of a service node. -func findWeight(node structs.CheckServiceNode) int { - // By default, when only_passing is false, warning and passing nodes are returned - // Those values will be used if using a client with support while server has no - // support for weights - weightPassing := 1 - weightWarning := 1 - if node.Service.Weights != nil { - weightPassing = node.Service.Weights.Passing - weightWarning = node.Service.Weights.Warning - } - serviceChecks := make(api.HealthChecks, 0, len(node.Checks)) - for _, c := range node.Checks { - if c.ServiceName == node.Service.Service || c.ServiceName == "" { - healthCheck := &api.HealthCheck{ - Node: c.Node, - CheckID: string(c.CheckID), - Name: c.Name, - Status: c.Status, - Notes: c.Notes, - Output: c.Output, - ServiceID: c.ServiceID, - ServiceName: c.ServiceName, - ServiceTags: c.ServiceTags, - } - serviceChecks = append(serviceChecks, healthCheck) - } - } - status := serviceChecks.AggregatedStatus() - switch status { - case api.HealthWarning: - return weightWarning - case api.HealthPassing: - return weightPassing - case api.HealthMaint: - // Not used in theory - return 0 - case api.HealthCritical: - // Should not happen since already filtered - return 0 - default: - // When non-standard status, return 1 - return 1 - } -} diff --git a/agent/discovery/query_fetcher_v1_ce.go b/agent/discovery/query_fetcher_v1_ce.go deleted file mode 100644 index 06299704bd..0000000000 --- a/agent/discovery/query_fetcher_v1_ce.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package discovery - -import ( - "github.com/hashicorp/consul/acl" -) - -func (f *V1DataFetcher) NormalizeRequest(req *QueryPayload) { - // Nothing to do for CE - return -} - -// validateEnterpriseTenancy validates the tenancy fields for an enterprise request to -// make sure that they are either set to an empty string or "default" to align with the behavior -// in CE. -func validateEnterpriseTenancy(req QueryTenancy) error { - if !(req.Namespace == acl.EmptyNamespaceName || req.Namespace == acl.DefaultNamespaceName) || - !(req.Partition == acl.DefaultPartitionName || req.Partition == acl.NonEmptyDefaultPartitionName) { - return ErrNotSupported - } - return nil -} - -func queryTenancyToEntMeta(_ QueryTenancy) acl.EnterpriseMeta { - return acl.EnterpriseMeta{} -} diff --git a/agent/discovery/query_fetcher_v1_ce_test.go b/agent/discovery/query_fetcher_v1_ce_test.go deleted file mode 100644 index 69cd2dea98..0000000000 --- a/agent/discovery/query_fetcher_v1_ce_test.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package discovery - -import ( - "github.com/stretchr/testify/require" - "testing" -) - -const ( - defaultTestNamespace = "" - defaultTestPartition = "" -) - -func Test_validateEnterpriseTenancy(t *testing.T) { - testCases := []struct { - name string - req QueryTenancy - expected error - }{ - { - name: "empty namespace and partition returns no error", - req: QueryTenancy{ - Namespace: defaultTestNamespace, - Partition: defaultTestPartition, - }, - expected: nil, - }, - { - name: "namespace and partition set to 'default' returns no error", - req: QueryTenancy{ - Namespace: "default", - Partition: "default", - }, - expected: nil, - }, - { - name: "namespace set to something other than empty string or `default` returns not supported error", - req: QueryTenancy{ - Namespace: "namespace-1", - Partition: "default", - }, - expected: ErrNotSupported, - }, - { - name: "partition set to something other than empty string or `default` returns not supported error", - req: QueryTenancy{ - Namespace: "default", - Partition: "partition-1", - }, - expected: ErrNotSupported, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := validateEnterpriseTenancy(tc.req) - require.Equal(t, tc.expected, err) - }) - } -} diff --git a/agent/discovery/query_fetcher_v1_test.go b/agent/discovery/query_fetcher_v1_test.go deleted file mode 100644 index f56e1f61b8..0000000000 --- a/agent/discovery/query_fetcher_v1_test.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package discovery - -import ( - "context" - "errors" - "testing" - "time" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/cache" - cachetype "github.com/hashicorp/consul/agent/cache-types" - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/sdk/testutil" -) - -// Test_FetchVirtualIP tests the FetchVirtualIP method in scenarios where the RPC -// call succeeds and fails. -func Test_FetchVirtualIP(t *testing.T) { - // set these to confirm that RPC call does not use them for this particular RPC - rc := &config.RuntimeConfig{ - DNSAllowStale: true, - DNSMaxStale: 100, - DNSUseCache: true, - DNSCacheMaxAge: 100, - } - tests := []struct { - name string - queryPayload *QueryPayload - context Context - expectedResult *Result - expectedErr error - }{ - { - name: "FetchVirtualIP returns result", - queryPayload: &QueryPayload{ - Name: "db", - Tenancy: QueryTenancy{ - Peer: "test-peer", - Namespace: defaultTestNamespace, - Partition: defaultTestPartition, - }, - }, - context: Context{ - Token: "test-token", - }, - expectedResult: &Result{ - Service: &Location{ - Name: "db", - Address: "192.168.10.10", - }, - Type: ResultTypeVirtual, - }, - expectedErr: nil, - }, - { - name: "FetchVirtualIP returns error", - queryPayload: &QueryPayload{ - Name: "db", - Tenancy: QueryTenancy{ - Peer: "test-peer", - Namespace: defaultTestNamespace, - Partition: defaultTestPartition}, - }, - context: Context{ - Token: "test-token", - }, - expectedResult: nil, - expectedErr: errors.New("test-error"), - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - logger := testutil.Logger(t) - mockRPC := cachetype.NewMockRPC(t) - mockRPC.On("RPC", mock.Anything, "Catalog.VirtualIPForService", mock.Anything, mock.Anything). - Return(tc.expectedErr). - Run(func(args mock.Arguments) { - req := args.Get(2).(*structs.ServiceSpecificRequest) - - // validate RPC options are not set from config for the VirtuaLIPForService RPC - require.False(t, req.AllowStale) - require.Equal(t, time.Duration(0), req.MaxStaleDuration) - require.False(t, req.UseCache) - require.Equal(t, time.Duration(0), req.MaxAge) - - // validate RPC options are set correctly from the queryPayload and context - require.Equal(t, tc.queryPayload.Tenancy.Peer, req.PeerName) - require.Equal(t, tc.queryPayload.Tenancy.Namespace, req.EnterpriseMeta.NamespaceOrEmpty()) - require.Equal(t, tc.queryPayload.Tenancy.Partition, req.EnterpriseMeta.PartitionOrEmpty()) - require.Equal(t, tc.context.Token, req.QueryOptions.Token) - - if tc.expectedErr == nil { - // set the out parameter to ensure that it is used to formulate the result.Address - reply := args.Get(3).(*string) - *reply = tc.expectedResult.Service.Address - } - }) - translateServicePortFunc := func(dc string, port int, taggedAddresses map[string]structs.ServiceAddress) int { return 0 } - rpcFuncForServiceNodes := func(ctx context.Context, req structs.ServiceSpecificRequest) (structs.IndexedCheckServiceNodes, cache.ResultMeta, error) { - return structs.IndexedCheckServiceNodes{}, cache.ResultMeta{}, nil - } - rpcFuncForSamenessGroup := func(ctx context.Context, req *structs.ConfigEntryQuery) (structs.SamenessGroupConfigEntry, cache.ResultMeta, error) { - return structs.SamenessGroupConfigEntry{}, cache.ResultMeta{}, nil - } - getFromCacheFunc := func(ctx context.Context, t string, r cache.Request) (interface{}, cache.ResultMeta, error) { - return nil, cache.ResultMeta{}, nil - } - - df := NewV1DataFetcher(rc, acl.DefaultEnterpriseMeta(), getFromCacheFunc, mockRPC.RPC, rpcFuncForServiceNodes, rpcFuncForSamenessGroup, translateServicePortFunc, logger) - - result, err := df.FetchVirtualIP(tc.context, tc.queryPayload) - require.Equal(t, tc.expectedErr, err) - require.Equal(t, tc.expectedResult, result) - }) - } -} - -// Test_FetchEndpoints tests the FetchEndpoints method in scenarios where the RPC -// call succeeds and fails. -func Test_FetchEndpoints(t *testing.T) { - // set these to confirm that RPC call does not use them for this particular RPC - rc := &config.RuntimeConfig{ - Datacenter: "dc2", - DNSAllowStale: true, - DNSMaxStale: 100, - DNSUseCache: true, - DNSCacheMaxAge: 100, - } - ctx := Context{ - Token: "test-token", - } - expectedResults := []*Result{ - { - Node: &Location{ - Name: "node-name", - Address: "node-address", - TaggedAddresses: map[string]*TaggedAddress{}, - }, - Service: &Location{ - Name: "service-name", - Address: "service-address", - TaggedAddresses: map[string]*TaggedAddress{}, - }, - Type: ResultTypeService, - DNS: DNSConfig{ - Weight: 1, - }, - Ports: []Port{ - { - Number: 0, - }, - }, - Tenancy: ResultTenancy{ - PeerName: "test-peer", - }, - }, - } - - logger := testutil.Logger(t) - mockRPC := cachetype.NewMockRPC(t) - translateServicePortFunc := func(dc string, port int, taggedAddresses map[string]structs.ServiceAddress) int { return 0 } - rpcFuncForSamenessGroup := func(ctx context.Context, req *structs.ConfigEntryQuery) (structs.SamenessGroupConfigEntry, cache.ResultMeta, error) { - return structs.SamenessGroupConfigEntry{}, cache.ResultMeta{}, nil - } - getFromCacheFunc := func(ctx context.Context, t string, r cache.Request) (interface{}, cache.ResultMeta, error) { - return nil, cache.ResultMeta{}, nil - } - rpcFuncForServiceNodes := func(ctx context.Context, req structs.ServiceSpecificRequest) (structs.IndexedCheckServiceNodes, cache.ResultMeta, error) { - return structs.IndexedCheckServiceNodes{ - Nodes: []structs.CheckServiceNode{ - { - Node: &structs.Node{ - Address: "node-address", - Node: "node-name", - }, - Service: &structs.NodeService{ - Address: "service-address", - Service: "service-name", - PeerName: "test-peer", - }, - }, - }, - }, cache.ResultMeta{}, nil - } - queryPayload := &QueryPayload{ - Name: "service-name", - Tenancy: QueryTenancy{ - Peer: "test-peer", - Namespace: defaultTestNamespace, - Partition: defaultTestPartition, - }, - } - - df := NewV1DataFetcher(rc, acl.DefaultEnterpriseMeta(), getFromCacheFunc, mockRPC.RPC, rpcFuncForServiceNodes, rpcFuncForSamenessGroup, translateServicePortFunc, logger) - - results, err := df.FetchEndpoints(ctx, queryPayload, LookupTypeService) - require.NoError(t, err) - require.Equal(t, expectedResults, results) -} diff --git a/agent/discovery/query_fetcher_v2.go b/agent/discovery/query_fetcher_v2.go deleted file mode 100644 index dc870e76ad..0000000000 --- a/agent/discovery/query_fetcher_v2.go +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package discovery - -import ( - "context" - "fmt" - "math/rand" - "net" - "strings" - "sync/atomic" - - "golang.org/x/exp/slices" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// V2DataFetcherDynamicConfig is used to store the dynamic configuration of the V2 data fetcher. -type V2DataFetcherDynamicConfig struct { - OnlyPassing bool -} - -// V2DataFetcher is used to fetch data from the V2 catalog. -type V2DataFetcher struct { - client pbresource.ResourceServiceClient - logger hclog.Logger - - // Requests inherit the partition of the agent unless otherwise specified. - defaultPartition string - - dynamicConfig atomic.Value -} - -// NewV2DataFetcher creates a new V2 data fetcher. -func NewV2DataFetcher(config *config.RuntimeConfig, client pbresource.ResourceServiceClient, logger hclog.Logger) *V2DataFetcher { - f := &V2DataFetcher{ - client: client, - logger: logger, - defaultPartition: config.PartitionOrDefault(), - } - f.LoadConfig(config) - return f -} - -// LoadConfig loads the configuration for the V2 data fetcher. -func (f *V2DataFetcher) LoadConfig(config *config.RuntimeConfig) { - dynamicConfig := &V2DataFetcherDynamicConfig{ - OnlyPassing: config.DNSOnlyPassing, - } - f.dynamicConfig.Store(dynamicConfig) -} - -// GetConfig loads the configuration for the V2 data fetcher. -func (f *V2DataFetcher) GetConfig() *V2DataFetcherDynamicConfig { - return f.dynamicConfig.Load().(*V2DataFetcherDynamicConfig) -} - -// FetchNodes fetches A/AAAA/CNAME -func (f *V2DataFetcher) FetchNodes(ctx Context, req *QueryPayload) ([]*Result, error) { - // TODO (v2-dns): NET-6623 - Implement FetchNodes - // Make sure that we validate that namespace is not provided here - return nil, fmt.Errorf("not implemented") -} - -// FetchEndpoints fetches records for A/AAAA/CNAME or SRV requests for services -func (f *V2DataFetcher) FetchEndpoints(reqContext Context, req *QueryPayload, lookupType LookupType) ([]*Result, error) { - if lookupType != LookupTypeService { - return nil, ErrNotSupported - } - - configCtx := f.dynamicConfig.Load().(*V2DataFetcherDynamicConfig) - - serviceEndpoints := pbcatalog.ServiceEndpoints{} - serviceEndpointsResource, err := f.fetchResource(reqContext, *req, pbcatalog.ServiceEndpointsType, &serviceEndpoints) - if err != nil { - return nil, err - } - - f.logger.Trace("shuffling endpoints", "name", req.Name, "endpoints", len(serviceEndpoints.Endpoints)) - - // Shuffle the endpoints slice - shuffleFunc := func(i, j int) { - serviceEndpoints.Endpoints[i], serviceEndpoints.Endpoints[j] = serviceEndpoints.Endpoints[j], serviceEndpoints.Endpoints[i] - } - rand.Shuffle(len(serviceEndpoints.Endpoints), shuffleFunc) - - // Convert the service endpoints to results up to the limit - limit := req.Limit - if len(serviceEndpoints.Endpoints) < limit || limit == 0 { - limit = len(serviceEndpoints.Endpoints) - } - - results := make([]*Result, 0, limit) - for _, endpoint := range serviceEndpoints.Endpoints[:limit] { - - // First we check the endpoint first to make sure that the requested port is matched from the service. - // We error here because we expect all endpoints to have the same ports as the service. - ports := getResultPorts(req, endpoint.Ports) //assuming the logic changed in getResultPorts - if len(ports) == 0 { - f.logger.Debug("could not find matching port in endpoint", "name", req.Name, "port", req.PortName) - return nil, ErrNotFound - } - - address, err := f.addressFromWorkloadAddresses(endpoint.Addresses, req.Name) - if err != nil { - return nil, err - } - - weight, ok := getEndpointWeight(endpoint, configCtx) - if !ok { - f.logger.Debug("endpoint filtered out because of health status", "name", req.Name, "endpoint", endpoint.GetTargetRef().GetName()) - continue - } - - result := &Result{ - Node: &Location{ - Address: address, - Name: endpoint.GetTargetRef().GetName(), - }, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: serviceEndpointsResource.GetId().GetTenancy().GetNamespace(), - Partition: serviceEndpointsResource.GetId().GetTenancy().GetPartition(), - }, - DNS: DNSConfig{ - Weight: weight, - }, - Ports: ports, - } - results = append(results, result) - } - return results, nil -} - -// FetchVirtualIP fetches A/AAAA records for virtual IPs -func (f *V2DataFetcher) FetchVirtualIP(ctx Context, req *QueryPayload) (*Result, error) { - // TODO (v2-dns): NET-6624 - Implement FetchVirtualIP - return nil, fmt.Errorf("not implemented") -} - -// FetchRecordsByIp is used for PTR requests to look up a service/node from an IP. -func (f *V2DataFetcher) FetchRecordsByIp(ctx Context, ip net.IP) ([]*Result, error) { - // TODO (v2-dns): NET-6795 - Implement FetchRecordsByIp - // Validate non-nil IP - return nil, fmt.Errorf("not implemented") -} - -// FetchWorkload is used to fetch a single workload from the V2 catalog. -// V2-only. -func (f *V2DataFetcher) FetchWorkload(reqContext Context, req *QueryPayload) (*Result, error) { - workload := pbcatalog.Workload{} - resourceObj, err := f.fetchResource(reqContext, *req, pbcatalog.WorkloadType, &workload) - if err != nil { - return nil, err - } - - // First we check the endpoint first to make sure that the requested port is matched from the service. - // We error here because we expect all endpoints to have the same ports as the service. - ports := getResultPorts(req, workload.Ports) //assuming the logic changed in getResultPorts - if ports == nil || len(ports) == 0 { - f.logger.Debug("could not find matching port in endpoint", "name", req.Name, "port", req.PortName) - return nil, ErrNotFound - } - - address, err := f.addressFromWorkloadAddresses(workload.Addresses, req.Name) - if err != nil { - return nil, err - } - - tenancy := resourceObj.GetId().GetTenancy() - result := &Result{ - Node: &Location{ - Address: address, - Name: resourceObj.GetId().GetName(), - }, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: tenancy.GetNamespace(), - Partition: tenancy.GetPartition(), - }, - Ports: ports, - } - - return result, nil -} - -// FetchPreparedQuery is used to fetch a prepared query from the V2 catalog. -// Deprecated in V2. -func (f *V2DataFetcher) FetchPreparedQuery(ctx Context, req *QueryPayload) ([]*Result, error) { - return nil, ErrNotSupported -} - -func (f *V2DataFetcher) NormalizeRequest(req *QueryPayload) { - // If we do not have an explicit partition in the request, we use the agent's - if req.Tenancy.Partition == "" { - req.Tenancy.Partition = f.defaultPartition - } -} - -// ValidateRequest throws an error is any of the deprecated V1 input fields are used in a QueryByName for this data fetcher. -func (f *V2DataFetcher) ValidateRequest(_ Context, req *QueryPayload) error { - if req.Tag != "" { - return ErrNotSupported - } - if req.SourceIP != nil { - return ErrNotSupported - } - return nil -} - -// fetchResource is used to read a single resource from the V2 catalog and cast into a concrete type. -func (f *V2DataFetcher) fetchResource(reqContext Context, req QueryPayload, kind *pbresource.Type, payload proto.Message) (*pbresource.Resource, error) { - // Query the resource service for the ServiceEndpoints by name and tenancy - resourceReq := pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: req.Name, - Type: kind, - Tenancy: queryTenancyToResourceTenancy(req.Tenancy), - }, - } - - f.logger.Trace("fetching "+kind.String(), "name", req.Name) - resourceCtx := metadata.AppendToOutgoingContext(context.Background(), "x-consul-token", reqContext.Token) - - // If the service is not found, return nil and an error equivalent to NXDOMAIN - response, err := f.client.Read(resourceCtx, &resourceReq) - switch { - case grpcNotFoundErr(err): - f.logger.Debug(kind.String()+" not found", "name", req.Name) - return nil, ErrNotFound - case err != nil: - f.logger.Error("error fetching "+kind.String(), "name", req.Name) - return nil, fmt.Errorf("error fetching %s: %w", kind.String(), err) - // default: fallthrough - } - - data := response.GetResource().GetData() - if err := data.UnmarshalTo(payload); err != nil { - f.logger.Error("error unmarshalling "+kind.String(), "name", req.Name) - return nil, fmt.Errorf("error unmarshalling %s: %w", kind.String(), err) - } - return response.GetResource(), nil -} - -// addressFromWorkloadAddresses returns one address from the workload addresses. -func (f *V2DataFetcher) addressFromWorkloadAddresses(addresses []*pbcatalog.WorkloadAddress, name string) (string, error) { - // TODO: (v2-dns): we will need to intelligently return the right workload address based on either the translate - // address setting or the locality of the requester. Workloads must have at least one. - // We also need to make sure that we filter out unix sockets here. - address := addresses[0].GetHost() - if strings.HasPrefix(address, "unix://") { - f.logger.Error("unix sockets are currently unsupported in workload results", "name", name) - return "", ErrNotFound - } - return address, nil -} - -// getEndpointWeight returns the weight of the endpoint and a boolean indicating if the endpoint should be included -// based on it's health status. -func getEndpointWeight(endpoint *pbcatalog.Endpoint, configCtx *V2DataFetcherDynamicConfig) (uint32, bool) { - health := endpoint.GetHealthStatus().Enum() - if health == nil { - return 0, false - } - - // Filter based on health status and agent config - // This is also a good opportunity to see if SRV weights are set - var weight uint32 - switch *health { - case pbcatalog.Health_HEALTH_PASSING: - weight = endpoint.GetDns().GetWeights().GetPassing() - case pbcatalog.Health_HEALTH_CRITICAL: - return 0, false // always filtered out - case pbcatalog.Health_HEALTH_WARNING: - if configCtx.OnlyPassing { - return 0, false // filtered out - } - weight = endpoint.GetDns().GetWeights().GetWarning() - default: - // Everything else can be filtered out - return 0, false - } - - // Important! double-check the weight in the case DNS weights are not set - if weight == 0 { - weight = 1 - } - return weight, true -} - -// getResultPorts conditionally returns ports from a map based on a query. The results are sorted by name. -func getResultPorts(req *QueryPayload, workloadPorts map[string]*pbcatalog.WorkloadPort) []Port { - if len(workloadPorts) == 0 { - return nil - } - - var ports []Port - if req.PortName != "" { - // Make sure the workload implements that port name. - if _, ok := workloadPorts[req.PortName]; !ok { - return nil - } - // In the case that the query asked for a specific port, we only return that port. - ports = []Port{ - { - Name: req.PortName, - Number: workloadPorts[req.PortName].Port, - }, - } - } else { - // If the client didn't specify a particular port, return all the workload ports. - for name, port := range workloadPorts { - ports = append(ports, Port{ - Name: name, - Number: port.Port, - }) - } - // Stable Sort - slices.SortStableFunc(ports, func(i, j Port) int { - if i.Name < j.Name { - return -1 - } else if i.Name > j.Name { - return 1 - } - return 0 - }) - } - return ports -} - -// queryTenancyToResourceTenancy converts a QueryTenancy to a pbresource.Tenancy. -func queryTenancyToResourceTenancy(qTenancy QueryTenancy) *pbresource.Tenancy { - rTenancy := resource.DefaultNamespacedTenancy() - - // If the request has any tenancy specified, it overrides the defaults. - if qTenancy.Namespace != "" { - rTenancy.Namespace = qTenancy.Namespace - } - // In the case of partition, we have the agent's partition as the fallback. - // That is handled in NormalizeRequest. - if qTenancy.Partition != "" { - rTenancy.Partition = qTenancy.Partition - } - - return rTenancy -} - -// grpcNotFoundErr returns true if the error is a gRPC status error with a code of NotFound. -func grpcNotFoundErr(err error) bool { - if err == nil { - return false - } - s, ok := status.FromError(err) - return ok && s.Code() == codes.NotFound -} diff --git a/agent/discovery/query_fetcher_v2_test.go b/agent/discovery/query_fetcher_v2_test.go deleted file mode 100644 index 5519ad13c7..0000000000 --- a/agent/discovery/query_fetcher_v2_test.go +++ /dev/null @@ -1,859 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package discovery - -import ( - "errors" - "fmt" - "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/types/known/anypb" - - "github.com/hashicorp/consul/agent/config" - mockpbresource "github.com/hashicorp/consul/grpcmocks/proto-public/pbresource" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" -) - -var ( - unknownErr = errors.New("I don't feel so good") -) - -// Test_FetchService tests the FetchService method in scenarios where the RPC -// call succeeds and fails. -func Test_FetchWorkload(t *testing.T) { - - rc := &config.RuntimeConfig{ - DNSOnlyPassing: false, - } - - tests := []struct { - name string - queryPayload *QueryPayload - context Context - configureMockClient func(mockClient *mockpbresource.ResourceServiceClient_Expecter) - expectedResult *Result - expectedErr error - }{ - { - name: "FetchWorkload returns result", - queryPayload: &QueryPayload{ - Name: "foo-1234", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - result := getTestWorkloadResponse(t, "foo-1234", "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: &Result{ - Node: &Location{Name: "foo-1234", Address: "1.2.3.4"}, - Type: ResultTypeWorkload, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - expectedErr: nil, - }, - { - name: "FetchWorkload for non-existent workload", - queryPayload: &QueryPayload{ - Name: "foo-1234", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - input := getTestWorkloadResponse(t, "foo-1234", "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(nil, status.Error(codes.NotFound, "not found")). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, input.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: nil, - expectedErr: ErrNotFound, - }, - { - name: "FetchWorkload encounters a resource client error", - queryPayload: &QueryPayload{ - Name: "foo-1234", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - input := getTestWorkloadResponse(t, "foo-1234", "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(nil, unknownErr). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, input.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: nil, - expectedErr: unknownErr, - }, - { - name: "FetchWorkload with a matching port", - queryPayload: &QueryPayload{ - Name: "foo-1234", - PortName: "api", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - result := getTestWorkloadResponse(t, "foo-1234", "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: &Result{ - Node: &Location{Name: "foo-1234", Address: "1.2.3.4"}, - Type: ResultTypeWorkload, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - }, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - expectedErr: nil, - }, - { - name: "FetchWorkload with a matching port", - queryPayload: &QueryPayload{ - Name: "foo-1234", - PortName: "not-api", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - result := getTestWorkloadResponse(t, "foo-1234", "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: nil, - expectedErr: ErrNotFound, - }, - { - name: "FetchWorkload returns result for non-default tenancy", - queryPayload: &QueryPayload{ - Name: "foo-1234", - Tenancy: QueryTenancy{ - Namespace: "test-namespace", - Partition: "test-partition", - }, - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - result := getTestWorkloadResponse(t, "foo-1234", "test-namespace", "test-partition") - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - require.Equal(t, result.GetResource().GetId().GetTenancy().GetNamespace(), req.Id.Tenancy.Namespace) - require.Equal(t, result.GetResource().GetId().GetTenancy().GetPartition(), req.Id.Tenancy.Partition) - }) - }, - expectedResult: &Result{ - Node: &Location{Name: "foo-1234", Address: "1.2.3.4"}, - Type: ResultTypeWorkload, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - Tenancy: ResultTenancy{ - Namespace: "test-namespace", - Partition: "test-partition", - }, - }, - expectedErr: nil, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - logger := testutil.Logger(t) - - client := mockpbresource.NewResourceServiceClient(t) - mockClient := client.EXPECT() - tc.configureMockClient(mockClient) - - df := NewV2DataFetcher(rc, client, logger) - - result, err := df.FetchWorkload(tc.context, tc.queryPayload) - require.True(t, errors.Is(err, tc.expectedErr)) - require.Equal(t, tc.expectedResult, result) - }) - } -} - -// Test_V2FetchEndpoints the FetchService method in scenarios where the RPC -// call succeeds and fails. -func Test_V2FetchEndpoints(t *testing.T) { - - tests := []struct { - name string - queryPayload *QueryPayload - context Context - configureMockClient func(mockClient *mockpbresource.ResourceServiceClient_Expecter) - rc *config.RuntimeConfig - expectedResult []*Result - expectedErr error - verifyShuffle bool - }{ - { - name: "FetchEndpoints returns result", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - endpoints := []*pbcatalog.Endpoint{ - makeEndpoint("consul-1", "1.2.3.4", pbcatalog.Health_HEALTH_PASSING, 0, 0), - } - - serviceEndpoints := getTestEndpointsResponse(t, "", "", endpoints...) - mockClient.Read(mock.Anything, mock.Anything). - Return(serviceEndpoints, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, serviceEndpoints.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: []*Result{ - { - Node: &Location{Name: "consul-1", Address: "1.2.3.4"}, - Type: ResultTypeWorkload, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - DNS: DNSConfig{ - Weight: 1, - }, - }, - }, - }, - { - name: "FetchEndpoints returns empty result with no endpoints", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - - result := getTestEndpointsResponse(t, "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: []*Result{}, - }, - { - name: "FetchEndpoints returns a name error when the ServiceEndpoint does not exist", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - - result := getTestEndpointsResponse(t, "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(nil, status.Error(codes.NotFound, "not found")). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedErr: ErrNotFound, - }, - { - name: "FetchEndpoints encounters a resource client error", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - - result := getTestEndpointsResponse(t, "", "") - mockClient.Read(mock.Anything, mock.Anything). - Return(nil, unknownErr). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedErr: unknownErr, - }, - { - name: "FetchEndpoints always filters out critical endpoints; DNS weights applied correctly", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - results := []*pbcatalog.Endpoint{ - makeEndpoint("consul-1", "1.2.3.4", pbcatalog.Health_HEALTH_PASSING, 2, 3), - makeEndpoint("consul-2", "2.3.4.5", pbcatalog.Health_HEALTH_WARNING, 2, 3), - makeEndpoint("consul-3", "3.4.5.6", pbcatalog.Health_HEALTH_CRITICAL, 2, 3), - } - - result := getTestEndpointsResponse(t, "", "", results...) - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: []*Result{ - { - Node: &Location{Name: "consul-1", Address: "1.2.3.4"}, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - DNS: DNSConfig{ - Weight: 2, - }, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - }, - { - Node: &Location{Name: "consul-2", Address: "2.3.4.5"}, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - DNS: DNSConfig{ - Weight: 3, - }, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - }, - }, - }, - { - name: "FetchEndpoints filters out warning endpoints when DNSOnlyPassing is true", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - results := []*pbcatalog.Endpoint{ - makeEndpoint("consul-1", "1.2.3.4", pbcatalog.Health_HEALTH_PASSING, 2, 3), - makeEndpoint("consul-2", "2.3.4.5", pbcatalog.Health_HEALTH_WARNING, 2, 3), - makeEndpoint("consul-3", "3.4.5.6", pbcatalog.Health_HEALTH_CRITICAL, 2, 3), - } - - result := getTestEndpointsResponse(t, "", "", results...) - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - rc: &config.RuntimeConfig{ - DNSOnlyPassing: true, - }, - expectedResult: []*Result{ - { - Node: &Location{Name: "consul-1", Address: "1.2.3.4"}, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - DNS: DNSConfig{ - Weight: 2, - }, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - }, - }, - }, - { - name: "FetchEndpoints shuffles the results", - queryPayload: &QueryPayload{ - Name: "consul", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - results := []*pbcatalog.Endpoint{ - // use a set of 10 elements, the odds of getting the same result are 1 in 3628800 - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-2", "10.0.0.2", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-3", "10.0.0.3", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-4", "10.0.0.4", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-5", "10.0.0.5", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-6", "10.0.0.6", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-7", "10.0.0.7", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-8", "10.0.0.8", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-9", "10.0.0.9", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-10", "10.0.0.10", pbcatalog.Health_HEALTH_PASSING, 0, 0), - } - - result := getTestEndpointsResponse(t, "", "", results...) - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: func() []*Result { - results := make([]*Result, 0, 10) - - for i := 0; i < 10; i++ { - name := fmt.Sprintf("consul-%d", i+1) - address := fmt.Sprintf("10.0.0.%d", i+1) - result := &Result{ - Node: &Location{Name: name, Address: address}, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - DNS: DNSConfig{ - Weight: 1, - }, - } - results = append(results, result) - } - return results - }(), - verifyShuffle: true, - }, - { - name: "FetchEndpoints returns only the specified limit", - queryPayload: &QueryPayload{ - Name: "consul", - Limit: 1, - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - results := []*pbcatalog.Endpoint{ - // intentionally all the same to make this easier to verify - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - } - - result := getTestEndpointsResponse(t, "", "", results...) - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: []*Result{ - { - Node: &Location{Name: "consul-1", Address: "10.0.0.1"}, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - DNS: DNSConfig{ - Weight: 1, - }, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - }, - }, - }, - { - name: "FetchEndpoints returns results with non-default tenancy", - queryPayload: &QueryPayload{ - Name: "consul", - Tenancy: QueryTenancy{ - Namespace: "test-namespace", - Partition: "test-partition", - }, - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - results := []*pbcatalog.Endpoint{ - // intentionally all the same to make this easier to verify - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - } - - result := getTestEndpointsResponse(t, "test-namespace", "test-partition", results...) - mockClient.Read(mock.Anything, mock.Anything). - Return(result, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, result.GetResource().GetId().GetName(), req.Id.Name) - require.Equal(t, result.GetResource().GetId().GetTenancy().GetNamespace(), req.Id.Tenancy.Namespace) - require.Equal(t, result.GetResource().GetId().GetTenancy().GetPartition(), req.Id.Tenancy.Partition) - }) - }, - expectedResult: []*Result{ - { - Node: &Location{Name: "consul-1", Address: "10.0.0.1"}, - Type: ResultTypeWorkload, - Tenancy: ResultTenancy{ - Namespace: "test-namespace", - Partition: "test-partition", - }, - DNS: DNSConfig{ - Weight: 1, - }, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - }, - }, - }, - { - name: "FetchEndpoints returns only a specific port if is one requested", - queryPayload: &QueryPayload{ - Name: "consul", - PortName: "api", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - endpoints := []*pbcatalog.Endpoint{ - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - } - - serviceEndpoints := getTestEndpointsResponse(t, "", "", endpoints...) - mockClient.Read(mock.Anything, mock.Anything). - Return(serviceEndpoints, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, serviceEndpoints.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedResult: []*Result{ - { - Node: &Location{Name: "consul-1", Address: "10.0.0.1"}, - Type: ResultTypeWorkload, - Ports: []Port{ - { - Name: "api", - Number: 5678, - }, - // No mesh port this time - }, - Tenancy: ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - DNS: DNSConfig{ - Weight: 1, - }, - }, - }, - }, - { - name: "FetchEndpoints returns a name error when a service doesn't implement the requested port", - queryPayload: &QueryPayload{ - Name: "consul", - PortName: "banana", - }, - context: Context{ - Token: "test-token", - }, - configureMockClient: func(mockClient *mockpbresource.ResourceServiceClient_Expecter) { - endpoints := []*pbcatalog.Endpoint{ - makeEndpoint("consul-1", "10.0.0.1", pbcatalog.Health_HEALTH_PASSING, 0, 0), - } - - serviceEndpoints := getTestEndpointsResponse(t, "", "", endpoints...) - mockClient.Read(mock.Anything, mock.Anything). - Return(serviceEndpoints, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.Equal(t, serviceEndpoints.GetResource().GetId().GetName(), req.Id.Name) - }) - }, - expectedErr: ErrNotFound, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - logger := testutil.Logger(t) - - client := mockpbresource.NewResourceServiceClient(t) - mockClient := client.EXPECT() - tc.configureMockClient(mockClient) - - if tc.rc == nil { - tc.rc = &config.RuntimeConfig{ - DNSOnlyPassing: false, - } - } - - df := NewV2DataFetcher(tc.rc, client, logger) - - result, err := df.FetchEndpoints(tc.context, tc.queryPayload, LookupTypeService) - require.True(t, errors.Is(err, tc.expectedErr)) - - if tc.verifyShuffle { - require.NotEqualf(t, tc.expectedResult, result, "expected result to be shuffled. There is a small probability that it shuffled back to the original order. In that case, you may want to play the lottery.") - } - - require.ElementsMatchf(t, tc.expectedResult, result, "elements of results should match") - }) - } -} - -func getTestWorkloadResponse(t *testing.T, name string, nsOverride string, partitionOverride string) *pbresource.ReadResponse { - workload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "1.2.3.4", - Ports: []string{"api", "mesh"}, - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "api": { - Port: 5678, - }, - "mesh": { - Port: 21000, - }, - }, - Identity: "test-identity", - } - - data, err := anypb.New(workload) - require.NoError(t, err) - - resp := &pbresource.ReadResponse{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Name: name, - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - }, - Data: data, - }, - } - - if nsOverride != "" { - resp.Resource.Id.Tenancy.Namespace = nsOverride - } - if partitionOverride != "" { - resp.Resource.Id.Tenancy.Partition = partitionOverride - } - - return resp -} - -func makeEndpoint(name string, address string, health pbcatalog.Health, weightPassing, weightWarning uint32) *pbcatalog.Endpoint { - endpoint := &pbcatalog.Endpoint{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: address, - Ports: []string{"api"}, - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "api": { - Port: 5678, - }, - "mesh": { - Port: 21000, - }, - }, - HealthStatus: health, - TargetRef: &pbresource.ID{ - Name: name, - }, - } - - if weightPassing > 0 || weightWarning > 0 { - endpoint.Dns = &pbcatalog.DNSPolicy{ - Weights: &pbcatalog.Weights{ - Passing: weightPassing, - Warning: weightWarning, - }, - } - } - - return endpoint -} - -func getTestEndpointsResponse(t *testing.T, nsOverride string, partitionOverride string, endpoints ...*pbcatalog.Endpoint) *pbresource.ReadResponse { - serviceEndpoints := &pbcatalog.ServiceEndpoints{ - Endpoints: endpoints, - } - - data, err := anypb.New(serviceEndpoints) - require.NoError(t, err) - - resp := &pbresource.ReadResponse{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Name: "consul", - Type: pbcatalog.ServiceType, - Tenancy: resource.DefaultNamespacedTenancy(), - }, - Data: data, - }, - } - - if nsOverride != "" { - resp.Resource.Id.Tenancy.Namespace = nsOverride - } - if partitionOverride != "" { - resp.Resource.Id.Tenancy.Partition = partitionOverride - } - - return resp -} diff --git a/agent/dns.go b/agent/dns.go index 5e0f54a1b7..dd34b3b8bd 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "errors" "fmt" + agentdns "github.com/hashicorp/consul/agent/dns" "math" "net" "regexp" @@ -61,7 +62,17 @@ type dnsSOAConfig struct { Minttl uint32 // 0 } -type dnsConfig struct { +// dnsRequestConfig returns the DNS request configuration that encapsulates: +// - the DNS server configuration. +// - the token from the request, if available. +// - the enterprise meta from the request, if available. +type dnsRequestConfig struct { + *dnsServerConfig + token string + defaultEnterpriseMeta acl.EnterpriseMeta +} + +type dnsServerConfig struct { AllowStale bool Datacenter string EnableTruncate bool @@ -119,7 +130,7 @@ type DNSServer struct { altDomain string logger hclog.Logger - // config stores the config as an atomic value (for hot-reloading). It is always of type *dnsConfig + // config stores the config as an atomic value (for hot-reloading). It is always of type *dnsServerConfig config atomic.Value // recursorEnabled stores whever the recursor handler is enabled as an atomic flag. @@ -141,7 +152,7 @@ func NewDNSServer(a *Agent) (*DNSServer, error) { defaultEnterpriseMeta: *a.AgentEnterpriseMeta(), mux: dns.NewServeMux(), } - cfg, err := GetDNSConfig(a.config) + cfg, err := getDNSServerConfig(a.config) if err != nil { return nil, err } @@ -163,9 +174,9 @@ func NewDNSServer(a *Agent) (*DNSServer, error) { return srv, nil } -// GetDNSConfig takes global config and creates the config used by DNS server -func GetDNSConfig(conf *config.RuntimeConfig) (*dnsConfig, error) { - cfg := &dnsConfig{ +// getDNSServerConfig takes global config and creates the config used by DNS server +func getDNSServerConfig(conf *config.RuntimeConfig) (*dnsServerConfig, error) { + cfg := &dnsServerConfig{ AllowStale: conf.DNSAllowStale, ARecordLimit: conf.DNSARecordLimit, Datacenter: conf.Datacenter, @@ -217,7 +228,7 @@ func GetDNSConfig(conf *config.RuntimeConfig) (*dnsConfig, error) { // GetTTLForService Find the TTL for a given service. // return ttl, true if found, 0, false otherwise -func (cfg *dnsConfig) GetTTLForService(service string) (time.Duration, bool) { +func (cfg *dnsServerConfig) GetTTLForService(service string) (time.Duration, bool) { if cfg.TTLStrict != nil { ttl, ok := cfg.TTLStrict[service] if ok { @@ -269,7 +280,7 @@ func (d *DNSServer) GetAddr() string { } // toggleRecursorHandlerFromConfig enables or disables the recursor handler based on config idempotently -func (d *DNSServer) toggleRecursorHandlerFromConfig(cfg *dnsConfig) { +func (d *DNSServer) toggleRecursorHandlerFromConfig(cfg *dnsServerConfig) { shouldEnable := len(cfg.Recursors) > 0 if shouldEnable && atomic.CompareAndSwapUint32(&d.recursorEnabled, 0, 1) { @@ -287,7 +298,7 @@ func (d *DNSServer) toggleRecursorHandlerFromConfig(cfg *dnsConfig) { // ReloadConfig hot-reloads the server config with new parameters under config.RuntimeConfig.DNS* func (d *DNSServer) ReloadConfig(newCfg *config.RuntimeConfig) error { - cfg, err := GetDNSConfig(newCfg) + cfg, err := getDNSServerConfig(newCfg) if err != nil { return err } @@ -407,7 +418,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) { ) }(time.Now()) - cfg := d.config.Load().(*dnsConfig) + cfg := d.getRequestConfig(resp) // Setup the message response m := new(dns.Msg) @@ -430,7 +441,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) { args := structs.DCSpecificRequest{ Datacenter: datacenter, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.coalesceDNSToken(cfg.token), AllowStale: cfg.AllowStale, }, } @@ -463,11 +474,11 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) { sargs := structs.ServiceSpecificRequest{ Datacenter: datacenter, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.coalesceDNSToken(cfg.token), AllowStale: cfg.AllowStale, }, ServiceAddress: serviceAddress, - EnterpriseMeta: *d.defaultEnterpriseMeta.WithWildcardNamespace(), + EnterpriseMeta: *cfg.defaultEnterpriseMeta.WithWildcardNamespace(), } var sout structs.IndexedServiceNodes @@ -536,7 +547,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) { network = "tcp" } - cfg := d.config.Load().(*dnsConfig) + cfg := d.getRequestConfig(resp) // Set up the message response m := new(dns.Msg) @@ -565,7 +576,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) { m.SetRcode(req, dns.RcodeNotImplemented) default: - err = d.dispatch(resp.RemoteAddr(), req, m, maxRecursionLevelDefault) + err = d.dispatch(resp.RemoteAddr(), req, m, cfg, maxRecursionLevelDefault) rCode := rCodeFromError(err) if rCode == dns.RcodeNameError || errors.Is(err, errNoData) { d.addSOAToMessage(cfg, m, q.Name) @@ -583,7 +594,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) { } // Craft dns records for an SOA -func (d *DNSServer) makeSOARecord(cfg *dnsConfig, questionName string) *dns.SOA { +func (d *DNSServer) makeSOARecord(cfg *dnsRequestConfig, questionName string) *dns.SOA { domain := d.domain if d.altDomain != "" && strings.HasSuffix(questionName, "."+d.altDomain) { domain = d.altDomain @@ -608,19 +619,19 @@ func (d *DNSServer) makeSOARecord(cfg *dnsConfig, questionName string) *dns.SOA } // addSOA is used to add an SOA record to a message for the given domain -func (d *DNSServer) addSOAToMessage(cfg *dnsConfig, msg *dns.Msg, questionName string) { +func (d *DNSServer) addSOAToMessage(cfg *dnsRequestConfig, msg *dns.Msg, questionName string) { msg.Ns = append(msg.Ns, d.makeSOARecord(cfg, questionName)) } // getNameserversAndNodeRecord returns the names and ip addresses of up to three random servers // in the current cluster which serve as authoritative name servers for zone. -func (d *DNSServer) getNameserversAndNodeRecord(questionName string, cfg *dnsConfig, maxRecursionLevel int) (ns []dns.RR, extra []dns.RR) { +func (d *DNSServer) getNameserversAndNodeRecord(questionName string, cfg *dnsRequestConfig, maxRecursionLevel int) (ns []dns.RR, extra []dns.RR) { out, err := d.lookupServiceNodes(cfg, serviceLookup{ Datacenter: d.agent.config.Datacenter, Service: structs.ConsulServiceName, Connect: false, Ingress: false, - EnterpriseMeta: d.defaultEnterpriseMeta, + EnterpriseMeta: cfg.defaultEnterpriseMeta, }) if err != nil { d.logger.Warn("Unable to get list of servers", "error", err) @@ -658,7 +669,7 @@ func (d *DNSServer) getNameserversAndNodeRecord(questionName string, cfg *dnsCon } ns = append(ns, nsrr) - extra = append(extra, d.makeRecordFromNode(o.Node, dns.TypeANY, fqdn, cfg.NodeTTL, maxRecursionLevel)...) + extra = append(extra, d.makeRecordFromNode(o.Node, dns.TypeANY, fqdn, cfg, maxRecursionLevel)...) // don't provide more than 3 servers if len(ns) >= 3 { @@ -754,7 +765,7 @@ func (l queryLocality) effectiveDatacenter(defaultDC string) string { // dispatch is used to parse a request and invoke the correct handler. // parameter maxRecursionLevel will handle whether recursive call can be performed -func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursionLevel int) error { +func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, cfg *dnsRequestConfig, maxRecursionLevel int) error { // Choose correct response domain respDomain := d.getResponseDomain(req.Question[0].Name) @@ -765,8 +776,6 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi // Split into the label parts labels := dns.SplitDomainName(qName) - cfg := d.config.Load().(*dnsConfig) - var queryKind string var queryParts []string var querySuffixes []string @@ -899,7 +908,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.coalesceDNSToken(cfg.token), }, } if args.PeerName == "" { @@ -1099,7 +1108,8 @@ func rCodeFromError(err error) int { case errors.Is(err, errNameNotFound), structs.IsErrNoDCPath(err), structs.IsErrQueryNotFound(err), - structs.IsErrSamenessGroupMustBeDefaultForFailover(err): + structs.IsErrSamenessGroupMustBeDefaultForFailover(err), + structs.IsErrSamenessGroupNotFound(err): return dns.RcodeNameError default: return dns.RcodeServerFailure @@ -1107,7 +1117,7 @@ func rCodeFromError(err error) int { } // handleNodeQuery is used to handle a node query -func (d *DNSServer) handleNodeQuery(cfg *dnsConfig, lookup nodeLookup, req, resp *dns.Msg) error { +func (d *DNSServer) handleNodeQuery(cfg *dnsRequestConfig, lookup nodeLookup, req, resp *dns.Msg) error { // Only handle ANY, A, AAAA, and TXT type requests qType := req.Question[0].Qtype if qType != dns.TypeANY && qType != dns.TypeA && qType != dns.TypeAAAA && qType != dns.TypeTXT { @@ -1120,7 +1130,7 @@ func (d *DNSServer) handleNodeQuery(cfg *dnsConfig, lookup nodeLookup, req, resp PeerName: lookup.PeerName, Node: lookup.Node, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.coalesceDNSToken(cfg.token), AllowStale: cfg.AllowStale, }, EnterpriseMeta: lookup.EnterpriseMeta, @@ -1146,7 +1156,7 @@ func (d *DNSServer) handleNodeQuery(cfg *dnsConfig, lookup nodeLookup, req, resp q := req.Question[0] // Only compute A and CNAME record if query is not TXT type if qType != dns.TypeTXT { - records := d.makeRecordFromNode(n, q.Qtype, q.Name, cfg.NodeTTL, lookup.MaxRecursionLevel) + records := d.makeRecordFromNode(n, q.Qtype, q.Name, cfg, lookup.MaxRecursionLevel) resp.Answer = append(resp.Answer, records...) } @@ -1159,7 +1169,7 @@ func (d *DNSServer) handleNodeQuery(cfg *dnsConfig, lookup nodeLookup, req, resp // lookupNode is used to look up a node in the Consul catalog within NodeServices. // If the config is set to UseCache, it will get the record from the agent cache. -func (d *DNSServer) lookupNode(cfg *dnsConfig, args *structs.NodeSpecificRequest) (*structs.IndexedNodeServices, error) { +func (d *DNSServer) lookupNode(cfg *dnsRequestConfig, args *structs.NodeSpecificRequest) (*structs.IndexedNodeServices, error) { var out structs.IndexedNodeServices useCache := cfg.UseCache @@ -1416,7 +1426,7 @@ func trimUDPResponse(req, resp *dns.Msg, udpAnswerLimit int) (trimmed bool) { } // trimDNSResponse will trim the response for UDP and TCP -func (d *DNSServer) trimDNSResponse(cfg *dnsConfig, network string, req, resp *dns.Msg) { +func (d *DNSServer) trimDNSResponse(cfg *dnsRequestConfig, network string, req, resp *dns.Msg) { var trimmed bool originalSize := resp.Len() originalNumRecords := len(resp.Answer) @@ -1441,7 +1451,7 @@ func (d *DNSServer) trimDNSResponse(cfg *dnsConfig, network string, req, resp *d // lookupServiceNodes is used to look up a node in the Consul health catalog within ServiceNodes. // If the config is set to UseCache, it will get the record from the agent cache. -func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (structs.IndexedCheckServiceNodes, error) { +func (d *DNSServer) lookupServiceNodes(cfg *dnsRequestConfig, lookup serviceLookup) (structs.IndexedCheckServiceNodes, error) { serviceTags := []string{} if lookup.Tag != "" { serviceTags = []string{lookup.Tag} @@ -1461,7 +1471,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st TagFilter: lookup.Tag != "", HealthFilterType: healthFilterType, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.coalesceDNSToken(cfg.token), AllowStale: cfg.AllowStale, MaxAge: cfg.CacheMaxAge, UseCache: cfg.UseCache, @@ -1479,7 +1489,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st } // handleServiceQuery is used to handle a service query -func (d *DNSServer) handleServiceQuery(cfg *dnsConfig, lookup serviceLookup, req, resp *dns.Msg) error { +func (d *DNSServer) handleServiceQuery(cfg *dnsRequestConfig, lookup serviceLookup, req, resp *dns.Msg) error { out, err := d.lookupServiceNodes(cfg, lookup) if err != nil { return fmt.Errorf("rpc request failed: %w", err) @@ -1528,13 +1538,13 @@ func ednsSubnetForRequest(req *dns.Msg) *dns.EDNS0_SUBNET { } // handlePreparedQuery is used to handle a prepared query. -func (d *DNSServer) handlePreparedQuery(cfg *dnsConfig, datacenter, query string, remoteAddr net.Addr, req, resp *dns.Msg, maxRecursionLevel int) error { +func (d *DNSServer) handlePreparedQuery(cfg *dnsRequestConfig, datacenter, query string, remoteAddr net.Addr, req, resp *dns.Msg, maxRecursionLevel int) error { // Execute the prepared query. args := structs.PreparedQueryExecuteRequest{ Datacenter: datacenter, QueryIDOrName: query, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.coalesceDNSToken(cfg.token), AllowStale: cfg.AllowStale, MaxAge: cfg.CacheMaxAge, }, @@ -1622,7 +1632,7 @@ func (d *DNSServer) handlePreparedQuery(cfg *dnsConfig, datacenter, query string // lookupPreparedQuery is used to execute a PreparedQuery against the Consul catalog. // If the config is set to UseCache, it will use agent cache. -func (d *DNSServer) lookupPreparedQuery(cfg *dnsConfig, args structs.PreparedQueryExecuteRequest) (*structs.PreparedQueryExecuteResponse, error) { +func (d *DNSServer) lookupPreparedQuery(cfg *dnsRequestConfig, args structs.PreparedQueryExecuteRequest) (*structs.PreparedQueryExecuteResponse, error) { var out structs.PreparedQueryExecuteResponse RPC: @@ -1664,7 +1674,7 @@ RPC: } // addServiceNodeRecordsToMessage is used to add the node records for a service lookup -func (d *DNSServer) addServiceNodeRecordsToMessage(cfg *dnsConfig, lookup serviceLookup, nodes structs.CheckServiceNodes, req, resp *dns.Msg, ttl time.Duration, maxRecursionLevel int) { +func (d *DNSServer) addServiceNodeRecordsToMessage(cfg *dnsRequestConfig, lookup serviceLookup, nodes structs.CheckServiceNodes, req, resp *dns.Msg, ttl time.Duration, maxRecursionLevel int) { handled := make(map[string]struct{}) var answerCNAME []dns.RR = nil @@ -1803,7 +1813,8 @@ func makeARecord(qType uint16, ip net.IP, ttl time.Duration) dns.RR { // Craft dns records for a node // In case of an SRV query the answer will be a IN SRV and additional data will store an IN A to the node IP // Otherwise it will return a IN A record -func (d *DNSServer) makeRecordFromNode(node *structs.Node, qType uint16, qName string, ttl time.Duration, maxRecursionLevel int) []dns.RR { +func (d *DNSServer) makeRecordFromNode(node *structs.Node, qType uint16, qName string, cfg *dnsRequestConfig, maxRecursionLevel int) []dns.RR { + ttl := cfg.NodeTTL addrTranslate := dnsutil.TranslateAddressAcceptDomain if qType == dns.TypeA { addrTranslate |= dnsutil.TranslateAddressAcceptIPv4 @@ -1830,7 +1841,7 @@ func (d *DNSServer) makeRecordFromNode(node *structs.Node, qType uint16, qName s }) res = append(res, - d.resolveCNAME(d.config.Load().(*dnsConfig), dns.Fqdn(node.Address), maxRecursionLevel)..., + d.resolveCNAME(cfg, dns.Fqdn(node.Address), maxRecursionLevel)..., ) return res @@ -1919,7 +1930,7 @@ func (d *DNSServer) makeRecordFromIP(lookup serviceLookup, addr net.IP, serviceN // Craft dns records for an FQDN // In case of an SRV query the answer will be a IN SRV and additional data will store an IN A to the IP // Otherwise it will return a CNAME and a IN A record -func (d *DNSServer) makeRecordFromFQDN(lookup serviceLookup, fqdn string, serviceNode structs.CheckServiceNode, req *dns.Msg, ttl time.Duration, cfg *dnsConfig, maxRecursionLevel int) ([]dns.RR, []dns.RR) { +func (d *DNSServer) makeRecordFromFQDN(lookup serviceLookup, fqdn string, serviceNode structs.CheckServiceNode, req *dns.Msg, ttl time.Duration, cfg *dnsRequestConfig, maxRecursionLevel int) ([]dns.RR, []dns.RR) { edns := req.IsEdns0() != nil q := req.Question[0] @@ -1975,7 +1986,7 @@ MORE_REC: } // Craft dns records from a CheckServiceNode struct -func (d *DNSServer) makeNodeServiceRecords(lookup serviceLookup, node structs.CheckServiceNode, req *dns.Msg, ttl time.Duration, cfg *dnsConfig, maxRecursionLevel int) ([]dns.RR, []dns.RR) { +func (d *DNSServer) makeNodeServiceRecords(lookup serviceLookup, node structs.CheckServiceNode, req *dns.Msg, ttl time.Duration, cfg *dnsRequestConfig, maxRecursionLevel int) ([]dns.RR, []dns.RR) { addrTranslate := dnsutil.TranslateAddressAcceptDomain if req.Question[0].Qtype == dns.TypeA { addrTranslate |= dnsutil.TranslateAddressAcceptIPv4 @@ -2049,7 +2060,7 @@ func (d *DNSServer) makeTXTRecordFromNodeMeta(qName string, node *structs.Node, } // addServiceSRVRecordsToMessage is used to add the SRV records for a service lookup -func (d *DNSServer) addServiceSRVRecordsToMessage(cfg *dnsConfig, lookup serviceLookup, nodes structs.CheckServiceNodes, req, resp *dns.Msg, ttl time.Duration, maxRecursionLevel int) { +func (d *DNSServer) addServiceSRVRecordsToMessage(cfg *dnsRequestConfig, lookup serviceLookup, nodes structs.CheckServiceNodes, req, resp *dns.Msg, ttl time.Duration, maxRecursionLevel int) { handled := make(map[string]struct{}) for _, node := range nodes { @@ -2080,7 +2091,7 @@ func (d *DNSServer) addServiceSRVRecordsToMessage(cfg *dnsConfig, lookup service // handleRecurse is used to handle recursive DNS queries func (d *DNSServer) handleRecurse(resp dns.ResponseWriter, req *dns.Msg) { - cfg := d.config.Load().(*dnsConfig) + cfg := d.getRequestConfig(resp) q := req.Question[0] network := "udp" @@ -2156,7 +2167,7 @@ func (d *DNSServer) handleRecurse(resp dns.ResponseWriter, req *dns.Msg) { } // resolveCNAME is used to recursively resolve CNAME records -func (d *DNSServer) resolveCNAME(cfg *dnsConfig, name string, maxRecursionLevel int) []dns.RR { +func (d *DNSServer) resolveCNAME(cfg *dnsRequestConfig, name string, maxRecursionLevel int) []dns.RR { // If the CNAME record points to a Consul address, resolve it internally // Convert query to lowercase because DNS is case insensitive; d.domain and // d.altDomain are already converted @@ -2171,7 +2182,7 @@ func (d *DNSServer) resolveCNAME(cfg *dnsConfig, name string, maxRecursionLevel req.SetQuestion(name, dns.TypeANY) // TODO: handle error response - d.dispatch(nil, req, resp, maxRecursionLevel-1) + d.dispatch(nil, req, resp, cfg, maxRecursionLevel-1) return resp.Answer } @@ -2209,10 +2220,46 @@ func (d *DNSServer) resolveCNAME(cfg *dnsConfig, name string, maxRecursionLevel return nil } -func (d *DNSServer) coalesceDNSToken() string { +// coalesceDNSToken returns the ACL token to use for DNS queries. +// It returns the first token found in the following order: +// 1. The token from the request, if available. +// 2. The DNSToken from the agent. +// 3. The UserToken from the agent. +func (d *DNSServer) coalesceDNSToken(requestToken string) string { + // if the request token is set, which occurs when consul-dataplane forwards requests over gRPC, use it + if requestToken != "" { + return requestToken + } if d.agent.tokens.DNSToken() != "" { return d.agent.tokens.DNSToken() - } else { - return d.agent.tokens.UserToken() } + return d.agent.tokens.UserToken() +} + +// getRequestConfig returns the DNS request configuration that encapsulates: +// - the DNS server configuration. +// - the token from the request, if available. +// - the enterprise meta from the request, if available. +func (d *DNSServer) getRequestConfig(resp dns.ResponseWriter) *dnsRequestConfig { + dnsServerConfig := d.config.Load().(*dnsServerConfig) + requestDnsConfig := &dnsRequestConfig{ + dnsServerConfig: dnsServerConfig, + defaultEnterpriseMeta: d.defaultEnterpriseMeta, + } + + // DNS uses *dns.ServeMux, which takes a ResponseWriter interface and a DNS message both + // from the github.com/miekg/dns module, so we are limited in what we can pass as arguments. + // We can't pass a context.Context, so we have to add the RequestContext field to our + // implementation of dns.ResponseWriter to pass the context from the request. + if rw, ok := resp.(*agentdns.BufferResponseWriter); ok { + // use the ACL token from the request if available. Regular DNS hitting the + // agent will not carry a token, but gRPC requests from consul-dataplane will. + if rw.RequestContext.Token != "" { + requestDnsConfig.token = rw.RequestContext.Token + } + + d.setEnterpriseMetaFromRequestContext(rw.RequestContext, requestDnsConfig) + } + + return requestDnsConfig } diff --git a/agent/dns/buffer_response_writer.go b/agent/dns/buffer_response_writer.go new file mode 100644 index 0000000000..ed240758be --- /dev/null +++ b/agent/dns/buffer_response_writer.go @@ -0,0 +1,78 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package dns + +import ( + "github.com/hashicorp/go-hclog" + "github.com/miekg/dns" + "net" +) + +// BufferResponseWriter writes a DNS response to a byte buffer. +type BufferResponseWriter struct { + // responseBuffer is the buffer that the response is written to. + responseBuffer []byte + // RequestContext is the context of the request that carries the ACL token and tenancy of the request. + RequestContext Context + // LocalAddress is the address of the server. + LocalAddress net.Addr + // RemoteAddress is the address of the client that sent the request. + RemoteAddress net.Addr + // Logger is the logger for the response writer. + Logger hclog.Logger +} + +var _ dns.ResponseWriter = (*BufferResponseWriter)(nil) + +// ResponseBuffer returns the buffer containing the response. +func (b *BufferResponseWriter) ResponseBuffer() []byte { + return b.responseBuffer +} + +// LocalAddr returns the net.Addr of the server +func (b *BufferResponseWriter) LocalAddr() net.Addr { + return b.LocalAddress +} + +// RemoteAddr returns the net.Addr of the client that sent the current request. +func (b *BufferResponseWriter) RemoteAddr() net.Addr { + return b.RemoteAddress +} + +// WriteMsg writes a reply back to the client. +func (b *BufferResponseWriter) WriteMsg(m *dns.Msg) error { + // Pack message to bytes first. + msgBytes, err := m.Pack() + if err != nil { + b.Logger.Error("error packing message", "err", err) + return err + } + b.responseBuffer = msgBytes + return nil +} + +// Write writes a raw buffer back to the client. +func (b *BufferResponseWriter) Write(m []byte) (int, error) { + b.Logger.Trace("Write was called") + return copy(b.responseBuffer, m), nil +} + +// Close closes the connection. +func (b *BufferResponseWriter) Close() error { + // There's nothing for us to do here as we don't handle the connection. + return nil +} + +// TsigStatus returns the status of the Tsig. +func (b *BufferResponseWriter) TsigStatus() error { + // TSIG doesn't apply to this response writer. + return nil +} + +// TsigTimersOnly sets the tsig timers only boolean. +func (b *BufferResponseWriter) TsigTimersOnly(bool) {} + +// Hijack lets the caller take over the connection. +// After a call to Hijack(), the DNS package will not do anything with the connection. { +func (b *BufferResponseWriter) Hijack() {} diff --git a/agent/dns/discovery_results_fetcher.go b/agent/dns/discovery_results_fetcher.go deleted file mode 100644 index 97b91c12aa..0000000000 --- a/agent/dns/discovery_results_fetcher.go +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "encoding/hex" - "net" - "strings" - - "github.com/miekg/dns" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/dnsutil" -) - -// discoveryResultsFetcher is a facade for the DNS router to formulate -// and execute discovery queries. -type discoveryResultsFetcher struct{} - -// getQueryOptions is a struct to hold the options for getQueryResults method. -type getQueryOptions struct { - req *dns.Msg - reqCtx Context - qName string - remoteAddress net.Addr - processor DiscoveryQueryProcessor - logger hclog.Logger - domain string - altDomain string -} - -// getQueryResults returns a discovery.Result from a DNS message. -func (d discoveryResultsFetcher) getQueryResults(opts *getQueryOptions) ([]*discovery.Result, *discovery.Query, error) { - reqType := parseRequestType(opts.req) - - switch reqType { - case requestTypeConsul: - // This is a special case of discovery.QueryByName where we know that we need to query the consul service - // regardless of the question name. - query := &discovery.Query{ - QueryType: discovery.QueryTypeService, - QueryPayload: discovery.QueryPayload{ - Name: structs.ConsulServiceName, - Tenancy: discovery.QueryTenancy{ - // We specify the partition here so that in the case we are a client agent in a non-default partition. - // We don't want the query processors default partition to be used. - // This is a small hack because for V1 CE, this is not the correct default partition name, but we - // need to add something to disambiguate the empty field. - Partition: acl.DefaultPartitionName, //NOTE: note this won't work if we ever have V2 client agents - }, - Limit: 3, - }, - } - - results, err := opts.processor.QueryByName(query, discovery.Context{Token: opts.reqCtx.Token}) - return results, query, err - case requestTypeName: - query, err := buildQueryFromDNSMessage(opts.req, opts.reqCtx, opts.domain, opts.altDomain, opts.remoteAddress) - if err != nil { - opts.logger.Error("error building discovery query from DNS request", "error", err) - return nil, query, err - } - results, err := opts.processor.QueryByName(query, discovery.Context{Token: opts.reqCtx.Token}) - - if getErrorFromECSNotGlobalError(err) != nil { - opts.logger.Error("error processing discovery query", "error", err) - if structs.IsErrSamenessGroupMustBeDefaultForFailover(err) { - return nil, query, errNameNotFound - } - return nil, query, err - } - return results, query, err - case requestTypeIP: - ip := dnsutil.IPFromARPA(opts.qName) - if ip == nil { - opts.logger.Error("error building IP from DNS request", "name", opts.qName) - return nil, nil, errNameNotFound - } - results, err := opts.processor.QueryByIP(ip, discovery.Context{Token: opts.reqCtx.Token}) - return results, nil, err - case requestTypeAddress: - results, err := buildAddressResults(opts.req) - if err != nil { - opts.logger.Error("error processing discovery query", "error", err) - return nil, nil, err - } - return results, nil, nil - } - - opts.logger.Error("error parsing discovery query type", "requestType", reqType) - return nil, nil, errInvalidQuestion -} - -// buildQueryFromDNSMessage returns a discovery.Query from a DNS message. -func buildQueryFromDNSMessage(req *dns.Msg, reqCtx Context, domain, altDomain string, - remoteAddress net.Addr) (*discovery.Query, error) { - queryType, queryParts, querySuffixes := getQueryTypePartsAndSuffixesFromDNSMessage(req, domain, altDomain) - - queryTenancy, err := getQueryTenancy(reqCtx, queryType, querySuffixes) - if err != nil { - return nil, err - } - - name, tag, err := getQueryNameAndTagFromParts(queryType, queryParts) - if err != nil { - return nil, err - } - - portName := parsePort(queryParts) - - switch { - case queryType == discovery.QueryTypeWorkload && req.Question[0].Qtype == dns.TypeSRV: - // Currently we do not support SRV records for workloads - return nil, errNotImplemented - case queryType == discovery.QueryTypeInvalid, name == "": - return nil, errInvalidQuestion - } - - return &discovery.Query{ - QueryType: queryType, - QueryPayload: discovery.QueryPayload{ - Name: name, - Tenancy: queryTenancy, - Tag: tag, - PortName: portName, - SourceIP: getSourceIP(req, queryType, remoteAddress), - }, - }, nil -} - -// buildAddressResults returns a discovery.Result from a DNS request for addr. records. -func buildAddressResults(req *dns.Msg) ([]*discovery.Result, error) { - domain := dns.CanonicalName(req.Question[0].Name) - labels := dns.SplitDomainName(domain) - hexadecimal := labels[0] - - if len(hexadecimal)/2 != 4 && len(hexadecimal)/2 != 16 { - return nil, errNameNotFound - } - - var ip net.IP - ip, err := hex.DecodeString(hexadecimal) - if err != nil { - return nil, errNameNotFound - } - - return []*discovery.Result{ - { - Node: &discovery.Location{ - Address: ip.String(), - }, - Type: discovery.ResultTypeNode, // We choose node by convention since we do not know the origin of the IP - }, - }, nil -} - -// getQueryNameAndTagFromParts returns the query name and tag from the query parts that are taken from the original dns question. -// -// Valid Query Parts: -// [.] -// [.port.] -// _._ // RFC 2782 style -func getQueryNameAndTagFromParts(queryType discovery.QueryType, queryParts []string) (string, string, error) { - n := len(queryParts) - if n == 0 { - return "", "", errInvalidQuestion - } - - switch queryType { - case discovery.QueryTypeService: - if n > 3 { - // Having this many fields is never valid. - return "", "", errInvalidQuestion - } - if n == 3 && queryParts[n-2] != "port" { - // This probably means that someone was trying to use a tag name with a period. - // This was deprecated in Consul 0.3. - return "", "", errInvalidQuestion - } - // Support RFC 2782 style syntax - if n == 2 && strings.HasPrefix(queryParts[1], "_") && strings.HasPrefix(queryParts[0], "_") { - // Grab the tag since we make nuke it if it's tcp - tag := queryParts[1][1:] - - // Treat _name._tcp.service.consul as a default, no need to filter on that tag - if tag == "tcp" { - tag = "" - } - - name := queryParts[0][1:] - // _name._tag.service.consul - return name, tag, nil - } - // Standard-style lookup w/ tag - if n == 2 { - return queryParts[1], queryParts[0], nil - } - // This works for the v1 and v2 catalog queries, even if a port name was specified. - return queryParts[n-1], "", nil - case discovery.QueryTypePreparedQuery: - name := "" - - // If the first and last DNS query parts begin with _, this is an RFC 2782 style SRV lookup. - // This allows for prepared query names to include "." (for backwards compatibility). - // Otherwise, this is a standard prepared query lookup. - if n >= 2 && strings.HasPrefix(queryParts[0], "_") && strings.HasPrefix(queryParts[n-1], "_") { - // The last DNS query part is the protocol field (ignored). - // All prior parts are the prepared query name or ID. - name = strings.Join(queryParts[:n-1], ".") - - // Strip leading underscore - name = name[1:] - } else { - // Allow a "." in the query name, just join all the parts. - name = strings.Join(queryParts, ".") - } - - if name == "" { - return "", "", errInvalidQuestion - } - return name, "", nil - } - name := queryParts[n-1] - if name == "" { - return "", "", errInvalidQuestion - } - return queryParts[n-1], "", nil -} - -// getQueryTenancy returns a discovery.QueryTenancy from a DNS message. -func getQueryTenancy(reqCtx Context, queryType discovery.QueryType, querySuffixes []string) (discovery.QueryTenancy, error) { - labels, ok := parseLabels(querySuffixes) - if !ok { - return discovery.QueryTenancy{}, errNameNotFound - } - - // If we don't have an explicit partition/ns in the request, try the first fallback - // which was supplied in the request context. The agent's partition will be used as the last fallback - // later in the query processor. - if labels.Partition == "" { - labels.Partition = reqCtx.DefaultPartition - } - - if labels.Namespace == "" { - labels.Namespace = reqCtx.DefaultNamespace - } - - // If we have a sameness group, we can return early without further data massage. - if labels.SamenessGroup != "" { - return discovery.QueryTenancy{ - Namespace: labels.Namespace, - Partition: labels.Partition, - SamenessGroup: labels.SamenessGroup, - // Datacenter is not supported - }, nil - } - - if queryType == discovery.QueryTypeVirtual { - if labels.Peer == "" { - // If the peer name was not explicitly defined, fall back to the ambiguously-parsed version. - labels.Peer = labels.PeerOrDatacenter - } - } - - return discovery.QueryTenancy{ - Namespace: labels.Namespace, - Partition: labels.Partition, - Peer: labels.Peer, - Datacenter: getEffectiveDatacenter(labels), - }, nil -} - -// getEffectiveDatacenter returns the effective datacenter from the parsed labels. -func getEffectiveDatacenter(labels *parsedLabels) string { - switch { - case labels.Datacenter != "": - return labels.Datacenter - case labels.PeerOrDatacenter != "" && labels.Peer != labels.PeerOrDatacenter: - return labels.PeerOrDatacenter - } - return "" -} - -// getQueryTypePartsAndSuffixesFromDNSMessage returns the query type, the parts, and suffixes of the query name. -func getQueryTypePartsAndSuffixesFromDNSMessage(req *dns.Msg, domain, altDomain string) (queryType discovery.QueryType, parts []string, suffixes []string) { - // Get the QName without the domain suffix - // TODO (v2-dns): we will also need to handle the "failover" and "no-failover" suffixes here. - // They come AFTER the domain. See `stripAnyFailoverSuffix` in router.go - qName := trimDomainFromQuestionName(req.Question[0].Name, domain, altDomain) - - // Split into the label parts - labels := dns.SplitDomainName(qName) - - done := false - for i := len(labels) - 1; i >= 0 && !done; i-- { - queryType = getQueryTypeFromLabels(labels[i]) - switch queryType { - case discovery.QueryTypeService, discovery.QueryTypeWorkload, - discovery.QueryTypeConnect, discovery.QueryTypeVirtual, discovery.QueryTypeIngress, - discovery.QueryTypeNode, discovery.QueryTypePreparedQuery: - parts = labels[:i] - suffixes = labels[i+1:] - done = true - case discovery.QueryTypeInvalid: - fallthrough - default: - // If this is a SRV query the "service" label is optional, we add it back to use the - // existing code-path. - if req.Question[0].Qtype == dns.TypeSRV && strings.HasPrefix(labels[i], "_") { - queryType = discovery.QueryTypeService - parts = labels[:i+1] - suffixes = labels[i+1:] - done = true - } - } - } - - return queryType, parts, suffixes -} - -// trimDomainFromQuestionName returns the question name without the domain suffix. -func trimDomainFromQuestionName(questionName, domain, altDomain string) string { - qName := dns.CanonicalName(questionName) - longer := domain - shorter := altDomain - - if len(shorter) > len(longer) { - longer, shorter = shorter, longer - } - - if strings.HasSuffix(qName, "."+strings.TrimLeft(longer, ".")) { - return strings.TrimSuffix(qName, longer) - } - return strings.TrimSuffix(qName, shorter) -} - -// getQueryTypeFromLabels returns the query type from the labels. -func getQueryTypeFromLabels(label string) discovery.QueryType { - switch label { - case "service": - return discovery.QueryTypeService - case "connect": - return discovery.QueryTypeConnect - case "virtual": - return discovery.QueryTypeVirtual - case "ingress": - return discovery.QueryTypeIngress - case "node": - return discovery.QueryTypeNode - case "query": - return discovery.QueryTypePreparedQuery - case "workload": - return discovery.QueryTypeWorkload - default: - return discovery.QueryTypeInvalid - } -} - -// getSourceIP returns the source IP from the dns request. -func getSourceIP(req *dns.Msg, queryType discovery.QueryType, remoteAddr net.Addr) (sourceIP net.IP) { - if queryType == discovery.QueryTypePreparedQuery { - subnet := ednsSubnetForRequest(req) - - if subnet != nil { - sourceIP = subnet.Address - } else { - switch v := remoteAddr.(type) { - case *net.UDPAddr: - sourceIP = v.IP - case *net.TCPAddr: - sourceIP = v.IP - case *net.IPAddr: - sourceIP = v.IP - } - } - } - return sourceIP -} diff --git a/agent/dns/discovery_results_fetcher_test.go b/agent/dns/discovery_results_fetcher_test.go deleted file mode 100644 index 4c219b5a62..0000000000 --- a/agent/dns/discovery_results_fetcher_test.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "testing" - - "github.com/miekg/dns" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/discovery" -) - -// testCaseBuildQueryFromDNSMessage is a test case for the buildQueryFromDNSMessage function. -type testCaseBuildQueryFromDNSMessage struct { - name string - request *dns.Msg - requestContext *Context - expectedQuery *discovery.Query - expectedError string -} - -// Test_buildQueryFromDNSMessage tests the buildQueryFromDNSMessage function. -func Test_buildQueryFromDNSMessage(t *testing.T) { - - testCases := []testCaseBuildQueryFromDNSMessage{ - // virtual ip queries - { - name: "test A 'virtual.' query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "db.virtual.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeVirtual, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tenancy: discovery.QueryTenancy{}, - }, - }, - }, - { - name: "test A 'virtual.' with kitchen sink labels", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "db.virtual.banana.ns.orange.ap.foo.peer.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeVirtual, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tenancy: discovery.QueryTenancy{ - Peer: "foo", - Namespace: "banana", - Partition: "orange", - }, - }, - }, - }, - { - name: "test A 'virtual.' with implicit peer", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "db.virtual.foo.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeVirtual, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tenancy: discovery.QueryTenancy{ - Peer: "foo", - }, - }, - }, - }, - { - name: "test A 'virtual.' with implicit peer and namespace query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "db.virtual.frontend.foo.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeVirtual, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tenancy: discovery.QueryTenancy{ - Namespace: "frontend", - Peer: "foo", - }, - }, - }, - }, - // V1 Service Queries - { - name: "test A 'service.' standard query with tag", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "primary.db.service.dc1.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeService, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tag: "primary", - Tenancy: discovery.QueryTenancy{ - Datacenter: "dc1", - }, - }, - }, - }, - { - name: "test A 'service.' RFC 2782 query with tag", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "_db._primary.service.dc1.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeService, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tag: "primary", - Tenancy: discovery.QueryTenancy{ - Datacenter: "dc1", - }, - }, - }, - }, - { - name: "test A 'service.' RFC 2782 query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "_db._tcp.service.dc1.consul", // the `tcp` tag should be ignored - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeService, - QueryPayload: discovery.QueryPayload{ - Name: "db", - Tenancy: discovery.QueryTenancy{ - Datacenter: "dc1", - }, - }, - }, - }, - { - name: "test A 'service.' with too many query parts (RFC 2782 style)", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "nope._db._tcp.service.dc1.consul", // the `tcp` tag should be ignored - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedError: "invalid question", - }, - { - name: "test A 'service.' with too many query parts (standard style)", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "too.many.parts.service.dc1.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedError: "invalid question", - }, - // V2 Catalog Queries - { - name: "test A 'workload.'", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.workload.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeWorkload, - QueryPayload: discovery.QueryPayload{ - Name: "foo", - Tenancy: discovery.QueryTenancy{}, - }, - }, - }, - { - name: "test A 'workload.' with all possible labels", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.banana.ns.orange.ap.apple.peer.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - requestContext: &Context{ - DefaultPartition: "default-partition", - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeWorkload, - QueryPayload: discovery.QueryPayload{ - Name: "foo", - PortName: "api", - Tenancy: discovery.QueryTenancy{ - Namespace: "banana", - Partition: "orange", - Peer: "apple", - }, - }, - }, - }, - { - name: "test sameness group with all possible labels", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.apple.sg.banana.ns.orange.ap.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - requestContext: &Context{ - DefaultPartition: "default-partition", - }, - expectedQuery: &discovery.Query{ - QueryType: discovery.QueryTypeService, - QueryPayload: discovery.QueryPayload{ - Name: "foo", - Tenancy: discovery.QueryTenancy{ - Namespace: "banana", - Partition: "orange", - SamenessGroup: "apple", - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - context := tc.requestContext - if context == nil { - context = &Context{} - } - query, err := buildQueryFromDNSMessage(tc.request, *context, "consul.", ".", nil) - - if tc.expectedError != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tc.expectedError) - return - } - - require.NoError(t, err) - assert.Equal(t, tc.expectedQuery, query) - }) - } -} diff --git a/agent/dns/dns_address.go b/agent/dns/dns_address.go deleted file mode 100644 index e1e61f689f..0000000000 --- a/agent/dns/dns_address.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 -package dns - -import ( - "github.com/miekg/dns" - "net" - "strings" -) - -func newDNSAddress(addr string) *dnsAddress { - a := &dnsAddress{} - a.SetAddress(addr) - return a -} - -// dnsAddress is a wrapper around a string that represents a DNS address and -// provides helper methods for determining whether it is an IP or FQDN and -// whether it is internal or external to the domain. -type dnsAddress struct { - addr string - - // store an IP so helpers don't have to parse it multiple times - ip net.IP -} - -// SetAddress sets the address field and the ip field if the string is an IP. -func (a *dnsAddress) SetAddress(addr string) { - a.addr = addr - a.ip = net.ParseIP(addr) -} - -// IP returns the IP address if the address is an IP. -func (a *dnsAddress) IP() net.IP { - return a.ip -} - -// IsIP returns true if the address is an IP. -func (a *dnsAddress) IsIP() bool { - return a.IP() != nil -} - -// IsIPV4 returns true if the address is an IPv4 address. -func (a *dnsAddress) IsIPV4() bool { - if a.IP() == nil { - return false - } - return a.IP().To4() != nil -} - -// FQDN returns the FQDN if the address is not an IP. -func (a *dnsAddress) FQDN() string { - if !a.IsEmptyString() && !a.IsIP() { - return dns.Fqdn(a.addr) - } - return "" -} - -// IsFQDN returns true if the address is a FQDN and not an IP. -func (a *dnsAddress) IsFQDN() bool { - return !a.IsEmptyString() && !a.IsIP() && dns.IsFqdn(a.FQDN()) -} - -// String returns the address as a string. -func (a *dnsAddress) String() string { - return a.addr -} - -// IsEmptyString returns true if the address is an empty string. -func (a *dnsAddress) IsEmptyString() bool { - return a.addr == "" -} - -// IsInternalFQDN returns true if the address is a FQDN and is internal to the domain. -func (a *dnsAddress) IsInternalFQDN(domain string) bool { - return !a.IsIP() && a.IsFQDN() && strings.HasSuffix(a.FQDN(), domain) -} - -// IsInternalFQDNOrIP returns true if the address is an IP or a FQDN and is internal to the domain. -func (a *dnsAddress) IsInternalFQDNOrIP(domain string) bool { - return a.IsIP() || a.IsInternalFQDN(domain) -} - -// IsExternalFQDN returns true if the address is a FQDN and is external to the domain. -func (a *dnsAddress) IsExternalFQDN(domain string) bool { - return !a.IsIP() && a.IsFQDN() && strings.Count(a.FQDN(), ".") > 1 && !strings.HasSuffix(a.FQDN(), domain) -} diff --git a/agent/dns/dns_address_test.go b/agent/dns/dns_address_test.go deleted file mode 100644 index 93460437f2..0000000000 --- a/agent/dns/dns_address_test.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 -package dns - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func Test_dnsAddress(t *testing.T) { - const domain = "consul." - type expectedResults struct { - isIp bool - stringResult string - fqdn string - isFQDN bool - isEmptyString bool - isExternalFQDN bool - isInternalFQDN bool - isInternalFQDNOrIP bool - } - type testCase struct { - name string - input string - expectedResults expectedResults - } - testCases := []testCase{ - { - name: "empty string", - input: "", - expectedResults: expectedResults{ - isIp: false, - stringResult: "", - fqdn: "", - isFQDN: false, - isEmptyString: true, - isExternalFQDN: false, - isInternalFQDN: false, - isInternalFQDNOrIP: false, - }, - }, - { - name: "ipv4 address", - input: "127.0.0.1", - expectedResults: expectedResults{ - isIp: true, - stringResult: "127.0.0.1", - fqdn: "", - isFQDN: false, - isEmptyString: false, - isExternalFQDN: false, - isInternalFQDN: false, - isInternalFQDNOrIP: true, - }, - }, - { - name: "ipv6 address", - input: "2001:db8:1:2:cafe::1337", - expectedResults: expectedResults{ - isIp: true, - stringResult: "2001:db8:1:2:cafe::1337", - fqdn: "", - isFQDN: false, - isEmptyString: false, - isExternalFQDN: false, - isInternalFQDN: false, - isInternalFQDNOrIP: true, - }, - }, - { - name: "internal FQDN without trailing period", - input: "web.service.consul", - expectedResults: expectedResults{ - isIp: false, - stringResult: "web.service.consul", - fqdn: "web.service.consul.", - isFQDN: true, - isEmptyString: false, - isExternalFQDN: false, - isInternalFQDN: true, - isInternalFQDNOrIP: true, - }, - }, - { - name: "internal FQDN with period", - input: "web.service.consul.", - expectedResults: expectedResults{ - isIp: false, - stringResult: "web.service.consul.", - fqdn: "web.service.consul.", - isFQDN: true, - isEmptyString: false, - isExternalFQDN: false, - isInternalFQDN: true, - isInternalFQDNOrIP: true, - }, - }, - { - name: "server name", - input: "web.", - expectedResults: expectedResults{ - isIp: false, - stringResult: "web.", - fqdn: "web.", - isFQDN: true, - isEmptyString: false, - isExternalFQDN: false, - isInternalFQDN: false, - isInternalFQDNOrIP: false, - }, - }, - { - name: "external FQDN without trailing period", - input: "web.service.vault", - expectedResults: expectedResults{ - isIp: false, - stringResult: "web.service.vault", - fqdn: "web.service.vault.", - isFQDN: true, - isEmptyString: false, - isExternalFQDN: true, - isInternalFQDN: false, - isInternalFQDNOrIP: false, - }, - }, - { - name: "external FQDN with trailing period", - input: "web.service.vault.", - expectedResults: expectedResults{ - isIp: false, - stringResult: "web.service.vault.", - fqdn: "web.service.vault.", - isFQDN: true, - isEmptyString: false, - isExternalFQDN: true, - isInternalFQDN: false, - isInternalFQDNOrIP: false, - }, - }, - { - name: "another external FQDN", - input: "www.google.com", - expectedResults: expectedResults{ - isIp: false, - stringResult: "www.google.com", - fqdn: "www.google.com.", - isFQDN: true, - isEmptyString: false, - isExternalFQDN: true, - isInternalFQDN: false, - isInternalFQDNOrIP: false, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - dnsAddress := newDNSAddress(tc.input) - assert.Equal(t, tc.expectedResults.isIp, dnsAddress.IsIP()) - assert.Equal(t, tc.expectedResults.stringResult, dnsAddress.String()) - assert.Equal(t, tc.expectedResults.isFQDN, dnsAddress.IsFQDN()) - assert.Equal(t, tc.expectedResults.isEmptyString, dnsAddress.IsEmptyString()) - assert.Equal(t, tc.expectedResults.isExternalFQDN, dnsAddress.IsExternalFQDN(domain)) - assert.Equal(t, tc.expectedResults.isInternalFQDN, dnsAddress.IsInternalFQDN(domain)) - assert.Equal(t, tc.expectedResults.isInternalFQDNOrIP, dnsAddress.IsInternalFQDNOrIP(domain)) - }) - } -} diff --git a/agent/dns/dns_record_maker.go b/agent/dns/dns_record_maker.go deleted file mode 100644 index c63d9d500b..0000000000 --- a/agent/dns/dns_record_maker.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "regexp" - "strings" - "time" - - "github.com/miekg/dns" - - "github.com/hashicorp/consul/agent/discovery" -) - -// dnsRecordMaker creates DNS records to be used when generating -// responses to dns requests. -type dnsRecordMaker struct{} - -// makeSOA returns an SOA record for the given domain and config. -func (dnsRecordMaker) makeSOA(domain string, cfg *RouterDynamicConfig) dns.RR { - return &dns.SOA{ - Hdr: dns.RR_Header{ - Name: domain, - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - // Has to be consistent with MinTTL to avoid invalidation - Ttl: cfg.SOAConfig.Minttl, - }, - Ns: "ns." + domain, - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster." + domain, - Refresh: cfg.SOAConfig.Refresh, - Retry: cfg.SOAConfig.Retry, - Expire: cfg.SOAConfig.Expire, - Minttl: cfg.SOAConfig.Minttl, - } -} - -// makeNS returns an NS record for the given domain and fqdn. -func (dnsRecordMaker) makeNS(domain, fqdn string, ttl uint32) dns.RR { - return &dns.NS{ - Hdr: dns.RR_Header{ - Name: domain, - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: ttl, - }, - Ns: fqdn, - } -} - -// makeIPBasedRecord returns an A or AAAA record for the given name and IP. -// Note: we might want to pass in the Query Name here, which is used in addr. and virtual. queries -// since there is only ever one result. Right now choosing to leave it off for simplification. -func (dnsRecordMaker) makeIPBasedRecord(name string, addr *dnsAddress, ttl uint32) dns.RR { - - if addr.IsIPV4() { - // check if the query type is A for IPv4 or ANY - return &dns.A{ - Hdr: dns.RR_Header{ - Name: name, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: ttl, - }, - A: addr.IP(), - } - } - - return &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: name, - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: ttl, - }, - AAAA: addr.IP(), - } -} - -// makeCNAME returns a CNAME record for the given name and target. -func (dnsRecordMaker) makeCNAME(name string, target string, ttl uint32) *dns.CNAME { - return &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: name, - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - Ttl: ttl, - }, - Target: dns.Fqdn(target), - } -} - -// makeSRV returns an SRV record for the given name and target. -func (dnsRecordMaker) makeSRV(name, target string, weight uint16, ttl uint32, port *discovery.Port) *dns.SRV { - return &dns.SRV{ - Hdr: dns.RR_Header{ - Name: name, - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: ttl, - }, - Priority: 1, - Weight: weight, - Port: uint16(port.Number), - Target: target, - } -} - -// makeTXT returns a TXT record for the given name and result metadata. -func (dnsRecordMaker) makeTXT(name string, metadata map[string]string, ttl uint32) []dns.RR { - extra := make([]dns.RR, 0, len(metadata)) - for key, value := range metadata { - txt := value - if !strings.HasPrefix(strings.ToLower(key), "rfc1035-") { - txt = encodeKVasRFC1464(key, value) - } - - extra = append(extra, &dns.TXT{ - Hdr: dns.RR_Header{ - Name: name, - Rrtype: dns.TypeTXT, - Class: dns.ClassINET, - Ttl: ttl, - }, - Txt: []string{txt}, - }) - } - return extra -} - -// encodeKVasRFC1464 encodes a key-value pair according to RFC1464 -func encodeKVasRFC1464(key, value string) (txt string) { - // For details on these replacements c.f. https://www.ietf.org/rfc/rfc1464.txt - key = strings.Replace(key, "`", "``", -1) - key = strings.Replace(key, "=", "`=", -1) - - // Backquote the leading spaces - leadingSpacesRE := regexp.MustCompile("^ +") - numLeadingSpaces := len(leadingSpacesRE.FindString(key)) - key = leadingSpacesRE.ReplaceAllString(key, strings.Repeat("` ", numLeadingSpaces)) - - // Backquote the trailing spaces - numTrailingSpaces := len(trailingSpacesRE.FindString(key)) - key = trailingSpacesRE.ReplaceAllString(key, strings.Repeat("` ", numTrailingSpaces)) - - value = strings.Replace(value, "`", "``", -1) - - return key + "=" + value -} diff --git a/agent/dns/dns_record_maker_test.go b/agent/dns/dns_record_maker_test.go deleted file mode 100644 index 3235ab3ef0..0000000000 --- a/agent/dns/dns_record_maker_test.go +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/discovery" -) - -func TestDNSRecordMaker_makeSOA(t *testing.T) { - cfg := &RouterDynamicConfig{ - SOAConfig: SOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - } - domain := "testdomain." - expected := &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.testdomain.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.testdomain.", - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - } - actual := dnsRecordMaker{}.makeSOA(domain, cfg) - require.Equal(t, expected, actual) -} - -func TestDNSRecordMaker_makeNS(t *testing.T) { - domain := "testdomain." - fqdn := "ns.testdomain." - ttl := uint32(123) - expected := &dns.NS{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "ns.testdomain.", - } - actual := dnsRecordMaker{}.makeNS(domain, fqdn, ttl) - require.Equal(t, expected, actual) -} - -func TestDNSRecordMaker_makeIPBasedRecord(t *testing.T) { - ipv4Addr := newDNSAddress("1.2.3.4") - ipv6Addr := newDNSAddress("2001:db8:1:2:cafe::1337") - testCases := []struct { - name string - recordHeaderName string - addr *dnsAddress - ttl uint32 - expected dns.RR - }{ - { - name: "IPv4", - recordHeaderName: "my.service.dc1.consul.", - addr: ipv4Addr, - ttl: 123, - expected: &dns.A{ - Hdr: dns.RR_Header{ - Name: "my.service.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: ipv4Addr.IP(), - }, - }, - { - name: "IPv6", - recordHeaderName: "my.service.dc1.consul.", - addr: ipv6Addr, - ttl: 123, - expected: &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: "my.service.dc1.consul.", - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: 123, - }, - AAAA: ipv6Addr.IP(), - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := dnsRecordMaker{}.makeIPBasedRecord(tc.recordHeaderName, tc.addr, tc.ttl) - require.Equal(t, tc.expected, actual) - }) - } -} - -func TestDNSRecordMaker_makeCNAME(t *testing.T) { - name := "my.service.consul." - target := "foo" - ttl := uint32(123) - expected := &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "my.service.consul.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - Ttl: 123, - }, - Target: "foo.", - } - actual := dnsRecordMaker{}.makeCNAME(name, target, ttl) - require.Equal(t, expected, actual) -} - -func TestDNSRecordMaker_makeSRV(t *testing.T) { - name := "my.service.consul." - target := "foo" - ttl := uint32(123) - expected := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "my.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: 123, - }, - Priority: 1, - Weight: uint16(345), - Port: uint16(234), - Target: "foo", - } - actual := dnsRecordMaker{}.makeSRV(name, target, uint16(345), ttl, &discovery.Port{Number: 234}) - require.Equal(t, expected, actual) -} - -func TestDNSRecordMaker_makeTXT(t *testing.T) { - testCases := []struct { - name string - metadata map[string]string - ttl uint32 - expected []dns.RR - }{ - { - name: "single metadata", - metadata: map[string]string{ - "key": "value", - }, - ttl: 123, - expected: []dns.RR{ - &dns.TXT{ - Hdr: dns.RR_Header{ - Name: "my.service.consul.", - Rrtype: dns.TypeTXT, - Class: dns.ClassINET, - Ttl: 123, - }, - Txt: []string{"key=value"}, - }, - }, - }, - { - name: "multiple metadata entries", - metadata: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - ttl: 123, - expected: []dns.RR{ - &dns.TXT{ - Hdr: dns.RR_Header{ - Name: "my.service.consul.", - Rrtype: dns.TypeTXT, - Class: dns.ClassINET, - Ttl: 123, - }, - Txt: []string{"key1=value1"}, - }, - &dns.TXT{ - Hdr: dns.RR_Header{ - Name: "my.service.consul.", - Rrtype: dns.TypeTXT, - Class: dns.ClassINET, - Ttl: 123, - }, - Txt: []string{"key2=value2"}, - }, - }, - }, - { - name: "'rfc1035-' prefixed- metadata entry", - metadata: map[string]string{ - "rfc1035-key": "value", - }, - ttl: 123, - expected: []dns.RR{ - &dns.TXT{ - Hdr: dns.RR_Header{ - Name: "my.service.consul.", - Rrtype: dns.TypeTXT, - Class: dns.ClassINET, - Ttl: 123, - }, - Txt: []string{"value"}, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := dnsRecordMaker{}.makeTXT("my.service.consul.", tc.metadata, tc.ttl) - require.ElementsMatchf(t, tc.expected, actual, "expected: %v, actual: %v", tc.expected, actual) - }) - } -} diff --git a/agent/dns/message_serializer.go b/agent/dns/message_serializer.go deleted file mode 100644 index 15e301fc8b..0000000000 --- a/agent/dns/message_serializer.go +++ /dev/null @@ -1,651 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "encoding/hex" - "fmt" - "net" - "strings" - "time" - - "github.com/miekg/dns" - - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/dnsutil" -) - -// messageSerializer is the high level orchestrator for generating the Answer, -// Extra, and Ns records for a DNS response. -type messageSerializer struct{} - -// serializeOptions are the options for serializing a discovery.Result into a DNS message. -type serializeOptions struct { - req *dns.Msg - reqCtx Context - query *discovery.Query - results []*discovery.Result - resp *dns.Msg - cfg *RouterDynamicConfig - responseDomain string - remoteAddress net.Addr - maxRecursionLevel int - dnsRecordMaker dnsRecordMaker - translateAddressFunc func(dc string, addr string, taggedAddresses map[string]string, accept dnsutil.TranslateAddressAccept) string - translateServiceAddressFunc func(dc string, address string, taggedAddresses map[string]structs.ServiceAddress, accept dnsutil.TranslateAddressAccept) string - resolveCnameFunc func(cfgContext *RouterDynamicConfig, name string, reqCtx Context, remoteAddress net.Addr, maxRecursionLevel int) []dns.RR -} - -// serializeQueryResults converts a discovery.Result into a DNS message. -func (d messageSerializer) serialize(opts *serializeOptions) (*dns.Msg, error) { - resp := new(dns.Msg) - resp.SetReply(opts.req) - resp.Compress = !opts.cfg.DisableCompression - resp.Authoritative = true - resp.RecursionAvailable = canRecurse(opts.cfg) - opts.resp = resp - - qType := opts.req.Question[0].Qtype - reqType := parseRequestType(opts.req) - - // Always add the SOA record if requested. - if qType == dns.TypeSOA { - resp.Answer = append(resp.Answer, opts.dnsRecordMaker.makeSOA(opts.responseDomain, opts.cfg)) - } - - switch { - case qType == dns.TypeSOA, reqType == requestTypeAddress: - for _, result := range opts.results { - for _, port := range getPortsFromResult(result) { - ans, ex, ns := d.getAnswerExtraAndNs(serializeToGetAnswerExtraAndNsOptions(opts, result, port)) - resp.Answer = append(resp.Answer, ans...) - resp.Extra = append(resp.Extra, ex...) - resp.Ns = append(resp.Ns, ns...) - } - } - case qType == dns.TypeSRV: - handled := make(map[string]struct{}) - for _, result := range opts.results { - for _, port := range getPortsFromResult(result) { - - // Avoid duplicate entries, possible if a node has - // the same service the same port, etc. - - // The datacenter should be empty during translation if it is a peering lookup. - // This should be fine because we should always prefer the WAN address. - - address := "" - if result.Service != nil { - address = result.Service.Address - } else { - address = result.Node.Address - } - tuple := fmt.Sprintf("%s:%s:%d", result.Node.Name, address, port.Number) - if _, ok := handled[tuple]; ok { - continue - } - handled[tuple] = struct{}{} - - ans, ex, ns := d.getAnswerExtraAndNs(serializeToGetAnswerExtraAndNsOptions(opts, result, port)) - resp.Answer = append(resp.Answer, ans...) - resp.Extra = append(resp.Extra, ex...) - resp.Ns = append(resp.Ns, ns...) - } - } - default: - // default will send it to where it does some de-duping while it calls getAnswerExtraAndNs and recurses. - d.appendResultsToDNSResponse(opts) - } - - if opts.query != nil && opts.query.QueryType != discovery.QueryTypeVirtual && - len(resp.Answer) == 0 && len(resp.Extra) == 0 { - return nil, discovery.ErrNoData - } - - return resp, nil -} - -// appendResultsToDNSResponse builds dns message from the discovery results and -// appends them to the dns response. -func (d messageSerializer) appendResultsToDNSResponse(opts *serializeOptions) { - - // Always add the SOA record if requested. - if opts.req.Question[0].Qtype == dns.TypeSOA { - opts.resp.Answer = append(opts.resp.Answer, opts.dnsRecordMaker.makeSOA(opts.responseDomain, opts.cfg)) - } - - handled := make(map[string]struct{}) - var answerCNAME []dns.RR = nil - - count := 0 - for _, result := range opts.results { - for _, port := range getPortsFromResult(result) { - - // Add the node record - had_answer := false - ans, extra, _ := d.getAnswerExtraAndNs(serializeToGetAnswerExtraAndNsOptions(opts, result, port)) - opts.resp.Extra = append(opts.resp.Extra, extra...) - - if len(ans) == 0 { - continue - } - - // Avoid duplicate entries, possible if a node has - // the same service on multiple ports, etc. - if _, ok := handled[ans[0].String()]; ok { - continue - } - handled[ans[0].String()] = struct{}{} - - switch ans[0].(type) { - case *dns.CNAME: - // keep track of the first CNAME + associated RRs but don't add to the resp.Answer yet - // this will only be added if no non-CNAME RRs are found - if len(answerCNAME) == 0 { - answerCNAME = ans - } - default: - opts.resp.Answer = append(opts.resp.Answer, ans...) - had_answer = true - } - - if had_answer { - count++ - if count == opts.cfg.ARecordLimit { - // We stop only if greater than 0 or we reached the limit - return - } - } - } - } - if len(opts.resp.Answer) == 0 && len(answerCNAME) > 0 { - opts.resp.Answer = answerCNAME - } -} - -// getAnswerExtraAndNsOptions are the options for getting the Answer, Extra, and Ns records for a DNS response. -type getAnswerExtraAndNsOptions struct { - port discovery.Port - result *discovery.Result - req *dns.Msg - reqCtx Context - query *discovery.Query - results []*discovery.Result - resp *dns.Msg - cfg *RouterDynamicConfig - responseDomain string - remoteAddress net.Addr - maxRecursionLevel int - ttl uint32 - dnsRecordMaker dnsRecordMaker - translateAddressFunc func(dc string, addr string, taggedAddresses map[string]string, accept dnsutil.TranslateAddressAccept) string - translateServiceAddressFunc func(dc string, address string, taggedAddresses map[string]structs.ServiceAddress, accept dnsutil.TranslateAddressAccept) string - resolveCnameFunc func(cfgContext *RouterDynamicConfig, name string, reqCtx Context, remoteAddress net.Addr, maxRecursionLevel int) []dns.RR -} - -// getAnswerAndExtra creates the dns answer and extra from discovery results. -func (d messageSerializer) getAnswerExtraAndNs(opts *getAnswerExtraAndNsOptions) (answer []dns.RR, extra []dns.RR, ns []dns.RR) { - serviceAddress, nodeAddress := d.getServiceAndNodeAddresses(opts) - qName := opts.req.Question[0].Name - ttlLookupName := qName - if opts.query != nil { - ttlLookupName = opts.query.QueryPayload.Name - } - - opts.ttl = getTTLForResult(ttlLookupName, opts.result.DNS.TTL, opts.query, opts.cfg) - - qType := opts.req.Question[0].Qtype - - // TODO (v2-dns): skip records that refer to a workload/node that don't have a valid DNS name. - - // Special case responses - switch { - // PTR requests are first since they are a special case of domain overriding question type - case parseRequestType(opts.req) == requestTypeIP: - ptrTarget := "" - if opts.result.Type == discovery.ResultTypeNode { - ptrTarget = opts.result.Node.Name - } else if opts.result.Type == discovery.ResultTypeService { - ptrTarget = opts.result.Service.Name - } - - ptr := &dns.PTR{ - Hdr: dns.RR_Header{Name: qName, Rrtype: dns.TypePTR, Class: dns.ClassINET, Ttl: 0}, - Ptr: canonicalNameForResult(opts.result.Type, ptrTarget, opts.responseDomain, opts.result.Tenancy, opts.port.Name), - } - answer = append(answer, ptr) - case qType == dns.TypeNS: - resultType := opts.result.Type - target := opts.result.Node.Name - if parseRequestType(opts.req) == requestTypeConsul && resultType == discovery.ResultTypeService { - resultType = discovery.ResultTypeNode - } - fqdn := canonicalNameForResult(resultType, target, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - extraRecord := opts.dnsRecordMaker.makeIPBasedRecord(fqdn, nodeAddress, opts.ttl) - - answer = append(answer, opts.dnsRecordMaker.makeNS(opts.responseDomain, fqdn, opts.ttl)) - extra = append(extra, extraRecord) - case qType == dns.TypeSOA: - // to be returned in the result. - fqdn := canonicalNameForResult(opts.result.Type, opts.result.Node.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - extraRecord := opts.dnsRecordMaker.makeIPBasedRecord(fqdn, nodeAddress, opts.ttl) - - ns = append(ns, opts.dnsRecordMaker.makeNS(opts.responseDomain, fqdn, opts.ttl)) - extra = append(extra, extraRecord) - case qType == dns.TypeSRV: - fallthrough - default: - a, e := d.getAnswerExtrasForAddressAndTarget(nodeAddress, serviceAddress, opts) - answer = append(answer, a...) - extra = append(extra, e...) - } - - a, e := getAnswerAndExtraTXT(opts.req, opts.cfg, qName, opts.result, opts.ttl, - opts.responseDomain, opts.query, &opts.port, opts.dnsRecordMaker) - answer = append(answer, a...) - extra = append(extra, e...) - return -} - -// getServiceAndNodeAddresses returns the service and node addresses from a discovery result. -func (d messageSerializer) getServiceAndNodeAddresses(opts *getAnswerExtraAndNsOptions) (*dnsAddress, *dnsAddress) { - addrTranslate := dnsutil.TranslateAddressAcceptDomain - if opts.req.Question[0].Qtype == dns.TypeA { - addrTranslate |= dnsutil.TranslateAddressAcceptIPv4 - } else if opts.req.Question[0].Qtype == dns.TypeAAAA { - addrTranslate |= dnsutil.TranslateAddressAcceptIPv6 - } else { - addrTranslate |= dnsutil.TranslateAddressAcceptAny - } - - // The datacenter should be empty during translation if it is a peering lookup. - // This should be fine because we should always prefer the WAN address. - serviceAddress := newDNSAddress("") - if opts.result.Service != nil { - sa := opts.translateServiceAddressFunc(opts.result.Tenancy.Datacenter, - opts.result.Service.Address, getServiceAddressMapFromLocationMap(opts.result.Service.TaggedAddresses), - addrTranslate) - serviceAddress = newDNSAddress(sa) - } - nodeAddress := newDNSAddress("") - if opts.result.Node != nil { - na := opts.translateAddressFunc(opts.result.Tenancy.Datacenter, opts.result.Node.Address, - getStringAddressMapFromTaggedAddressMap(opts.result.Node.TaggedAddresses), addrTranslate) - nodeAddress = newDNSAddress(na) - } - return serviceAddress, nodeAddress -} - -// getAnswerExtrasForAddressAndTarget creates the dns answer and extra from nodeAddress and serviceAddress dnsAddress pairs. -func (d messageSerializer) getAnswerExtrasForAddressAndTarget(nodeAddress *dnsAddress, - serviceAddress *dnsAddress, opts *getAnswerExtraAndNsOptions) (answer []dns.RR, extra []dns.RR) { - qName := opts.req.Question[0].Name - reqType := parseRequestType(opts.req) - - switch { - case (reqType == requestTypeAddress || opts.result.Type == discovery.ResultTypeVirtual) && - serviceAddress.IsEmptyString() && nodeAddress.IsIP(): - a, e := getAnswerExtrasForIP(qName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) - answer = append(answer, a...) - extra = append(extra, e...) - - case opts.result.Type == discovery.ResultTypeNode && nodeAddress.IsIP(): - canonicalNodeName := canonicalNameForResult(opts.result.Type, - opts.result.Node.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) - answer = append(answer, a...) - extra = append(extra, e...) - - case opts.result.Type == discovery.ResultTypeNode && !nodeAddress.IsIP(): - a, e := d.makeRecordFromFQDN(serviceAddress.FQDN(), opts) - answer = append(answer, a...) - extra = append(extra, e...) - - case serviceAddress.IsEmptyString() && nodeAddress.IsEmptyString(): - return nil, nil - - // There is no service address and the node address is an IP - case serviceAddress.IsEmptyString() && nodeAddress.IsIP(): - resultType := discovery.ResultTypeNode - if opts.result.Type == discovery.ResultTypeWorkload { - resultType = discovery.ResultTypeWorkload - } - canonicalNodeName := canonicalNameForResult(resultType, opts.result.Node.Name, - opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, nodeAddress.String() == opts.result.Node.Address) // We compare the node address to the result to detect changes from the WAN translation - answer = append(answer, a...) - extra = append(extra, e...) - - // There is no service address and the node address is a FQDN (external service) - case serviceAddress.IsEmptyString(): - a, e := d.makeRecordFromFQDN(nodeAddress.FQDN(), opts) - answer = append(answer, a...) - extra = append(extra, e...) - - case serviceAddress.IsIP() && opts.req.Question[0].Qtype == dns.TypeSRV: - a, e := getAnswerExtrasForIP(qName, serviceAddress, opts.req.Question[0], requestTypeName, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) - answer = append(answer, a...) - extra = append(extra, e...) - - // The service address is an IP - case serviceAddress.IsIP(): - canonicalServiceName := canonicalNameForResult(discovery.ResultTypeService, - opts.result.Service.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalServiceName, serviceAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, false) - answer = append(answer, a...) - extra = append(extra, e...) - - // If the service address is a CNAME for the service we are looking - // for then use the node address. - case serviceAddress.FQDN() == opts.req.Question[0].Name && nodeAddress.IsIP(): - canonicalNodeName := canonicalNameForResult(discovery.ResultTypeNode, - opts.result.Node.Name, opts.responseDomain, opts.result.Tenancy, opts.port.Name) - a, e := getAnswerExtrasForIP(canonicalNodeName, nodeAddress, opts.req.Question[0], reqType, opts.result, opts.ttl, opts.responseDomain, &opts.port, opts.dnsRecordMaker, nodeAddress.String() == opts.result.Node.Address) // We compare the node address to the result to detect changes from the WAN translation - answer = append(answer, a...) - extra = append(extra, e...) - - // The service address is a FQDN (internal or external service name) - default: - a, e := d.makeRecordFromFQDN(serviceAddress.FQDN(), opts) - answer = append(answer, a...) - extra = append(extra, e...) - } - - return -} - -// makeRecordFromFQDN creates a DNS record from a FQDN. -func (d messageSerializer) makeRecordFromFQDN(fqdn string, opts *getAnswerExtraAndNsOptions) ([]dns.RR, []dns.RR) { - edns := opts.req.IsEdns0() != nil - q := opts.req.Question[0] - - more := opts.resolveCnameFunc(opts.cfg, dns.Fqdn(fqdn), opts.reqCtx, opts.remoteAddress, opts.maxRecursionLevel) - var additional []dns.RR - extra := 0 -MORE_REC: - for _, rr := range more { - switch rr.Header().Rrtype { - case dns.TypeCNAME, dns.TypeA, dns.TypeAAAA, dns.TypeTXT: - // set the TTL manually - rr.Header().Ttl = opts.ttl - additional = append(additional, rr) - - extra++ - if extra == maxRecurseRecords && !edns { - break MORE_REC - } - } - } - - if q.Qtype == dns.TypeSRV { - answer := opts.dnsRecordMaker.makeSRV(q.Name, fqdn, uint16(opts.result.DNS.Weight), opts.ttl, &opts.port) - return []dns.RR{answer}, additional - } - - address := "" - if opts.result.Service != nil && opts.result.Service.Address != "" { - address = opts.result.Service.Address - } else if opts.result.Node != nil { - address = opts.result.Node.Address - } - - answers := []dns.RR{ - opts.dnsRecordMaker.makeCNAME(q.Name, address, opts.ttl), - } - answers = append(answers, additional...) - - return answers, nil -} - -// getAnswerAndExtraTXT determines whether a TXT needs to be create and then -// returns the TXT record in the answer or extra depending on the question type. -func getAnswerAndExtraTXT(req *dns.Msg, cfg *RouterDynamicConfig, qName string, - result *discovery.Result, ttl uint32, domain string, query *discovery.Query, - port *discovery.Port, maker dnsRecordMaker) (answer []dns.RR, extra []dns.RR) { - if !shouldAppendTXTRecord(query, cfg, req) { - return - } - recordHeaderName := qName - serviceAddress := newDNSAddress("") - if result.Service != nil { - serviceAddress = newDNSAddress(result.Service.Address) - } - if result.Type != discovery.ResultTypeNode && - result.Type != discovery.ResultTypeVirtual && - !serviceAddress.IsInternalFQDN(domain) && - !serviceAddress.IsExternalFQDN(domain) { - recordHeaderName = canonicalNameForResult(discovery.ResultTypeNode, result.Node.Name, - domain, result.Tenancy, port.Name) - } - qType := req.Question[0].Qtype - generateMeta := false - metaInAnswer := false - if qType == dns.TypeANY || qType == dns.TypeTXT { - generateMeta = true - metaInAnswer = true - } else if cfg.NodeMetaTXT { - generateMeta = true - } - - // Do not generate txt records if we don't have to: https://github.com/hashicorp/consul/pull/5272 - if generateMeta { - meta := maker.makeTXT(recordHeaderName, result.Metadata, ttl) - if metaInAnswer { - answer = append(answer, meta...) - } else { - extra = append(extra, meta...) - } - } - return answer, extra -} - -// shouldAppendTXTRecord determines whether a TXT record should be appended to the response. -func shouldAppendTXTRecord(query *discovery.Query, cfg *RouterDynamicConfig, req *dns.Msg) bool { - qType := req.Question[0].Qtype - switch { - // Node records - case query != nil && query.QueryType == discovery.QueryTypeNode && (cfg.NodeMetaTXT || qType == dns.TypeANY || qType == dns.TypeTXT): - return true - // Service records - case query != nil && query.QueryType == discovery.QueryTypeService && cfg.NodeMetaTXT && qType == dns.TypeSRV: - return true - // Prepared query records - case query != nil && query.QueryType == discovery.QueryTypePreparedQuery && cfg.NodeMetaTXT && qType == dns.TypeSRV: - return true - } - return false -} - -// getAnswerExtrasForIP creates the dns answer and extra from IP dnsAddress pairs. -func getAnswerExtrasForIP(name string, addr *dnsAddress, question dns.Question, reqType requestType, result *discovery.Result, ttl uint32, domain string, port *discovery.Port, maker dnsRecordMaker, addressOverridden bool) (answer []dns.RR, extra []dns.RR) { - qType := question.Qtype - canReturnARecord := qType == dns.TypeSRV || qType == dns.TypeA || qType == dns.TypeANY || qType == dns.TypeNS || qType == dns.TypeTXT - canReturnAAAARecord := qType == dns.TypeSRV || qType == dns.TypeAAAA || qType == dns.TypeANY || qType == dns.TypeNS || qType == dns.TypeTXT - if reqType != requestTypeAddress && result.Type != discovery.ResultTypeVirtual { - switch { - // check IPV4 - case addr.IsIP() && addr.IsIPV4() && !canReturnARecord, - // check IPV6 - addr.IsIP() && !addr.IsIPV4() && !canReturnAAAARecord: - return - } - } - - // Have to pass original question name here even if the system has recursed - // and stripped off the domain suffix. - recHdrName := question.Name - if qType == dns.TypeSRV { - nameSplit := strings.Split(name, ".") - if len(nameSplit) > 1 && nameSplit[1] == addrLabel { - recHdrName = name - } else { - recHdrName = name - } - name = question.Name - } - - if reqType != requestTypeAddress && qType == dns.TypeSRV { - - if addr.IsIP() && question.Name == name && !addressOverridden { - // encode the ip to be used in the header of the A/AAAA record - // as well as the target of the SRV record. - recHdrName = encodeIPAsFqdn(result, addr.IP(), domain) - } - if result.Type == discovery.ResultTypeWorkload { - recHdrName = canonicalNameForResult(result.Type, result.Node.Name, domain, result.Tenancy, port.Name) - } - srv := maker.makeSRV(name, recHdrName, uint16(result.DNS.Weight), ttl, port) - answer = append(answer, srv) - } - - record := maker.makeIPBasedRecord(recHdrName, addr, ttl) - - isARecordWhenNotExplicitlyQueried := record.Header().Rrtype == dns.TypeA && qType != dns.TypeA && qType != dns.TypeANY - isAAAARecordWhenNotExplicitlyQueried := record.Header().Rrtype == dns.TypeAAAA && qType != dns.TypeAAAA && qType != dns.TypeANY - - // For explicit A/AAAA queries, we must only return those records in the answer section. - if isARecordWhenNotExplicitlyQueried || - isAAAARecordWhenNotExplicitlyQueried { - extra = append(extra, record) - } else { - answer = append(answer, record) - } - - return -} - -// getPortsFromResult returns the ports from a discovery result. -func getPortsFromResult(result *discovery.Result) []discovery.Port { - if len(result.Ports) > 0 { - return result.Ports - } - // return one record. - return []discovery.Port{{}} -} - -// encodeIPAsFqdn encodes an IP address as a FQDN. -func encodeIPAsFqdn(result *discovery.Result, ip net.IP, responseDomain string) string { - ipv4 := ip.To4() - ipStr := hex.EncodeToString(ip) - if ipv4 != nil { - ipStr = ipStr[len(ipStr)-(net.IPv4len*2):] - } - if result.Tenancy.PeerName != "" { - // Exclude the datacenter from the FQDN on the addr for peers. - // This technically makes no difference, since the addr endpoint ignores the DC - // component of the request, but do it anyway for a less confusing experience. - return fmt.Sprintf("%s.addr.%s", ipStr, responseDomain) - } - return fmt.Sprintf("%s.addr.%s.%s", ipStr, result.Tenancy.Datacenter, responseDomain) -} - -// canonicalNameForResult returns the canonical name for a discovery result. -func canonicalNameForResult(resultType discovery.ResultType, target, domain string, - tenancy discovery.ResultTenancy, portName string) string { - switch resultType { - case discovery.ResultTypeService: - if tenancy.Namespace != "" { - return fmt.Sprintf("%s.%s.%s.%s.%s", target, "service", tenancy.Namespace, tenancy.Datacenter, domain) - } - return fmt.Sprintf("%s.%s.%s.%s", target, "service", tenancy.Datacenter, domain) - case discovery.ResultTypeNode: - if tenancy.PeerName != "" && tenancy.Partition != "" { - // We must return a more-specific DNS name for peering so - // that there is no ambiguity with lookups. - // Nodes are always registered in the default namespace, so - // the `.ns` qualifier is not required. - return fmt.Sprintf("%s.node.%s.peer.%s.ap.%s", - target, - tenancy.PeerName, - tenancy.Partition, - domain) - } - if tenancy.PeerName != "" { - // We must return a more-specific DNS name for peering so - // that there is no ambiguity with lookups. - return fmt.Sprintf("%s.node.%s.peer.%s", - target, - tenancy.PeerName, - domain) - } - // Return a simpler format for non-peering nodes. - return fmt.Sprintf("%s.node.%s.%s", target, tenancy.Datacenter, domain) - case discovery.ResultTypeWorkload: - // TODO (v2-dns): it doesn't appear this is being used to return a result. Need to investigate and refactor - if portName != "" { - return fmt.Sprintf("%s.port.%s.workload.%s.ns.%s.ap.%s", portName, target, tenancy.Namespace, tenancy.Partition, domain) - } - return fmt.Sprintf("%s.workload.%s.ns.%s.ap.%s", target, tenancy.Namespace, tenancy.Partition, domain) - } - return "" -} - -// getServiceAddressMapFromLocationMap converts a map of Location to a map of ServiceAddress. -func getServiceAddressMapFromLocationMap(taggedAddresses map[string]*discovery.TaggedAddress) map[string]structs.ServiceAddress { - taggedServiceAddresses := make(map[string]structs.ServiceAddress, len(taggedAddresses)) - for k, v := range taggedAddresses { - taggedServiceAddresses[k] = structs.ServiceAddress{ - Address: v.Address, - Port: int(v.Port.Number), - } - } - return taggedServiceAddresses -} - -// getStringAddressMapFromTaggedAddressMap converts a map of Location to a map of string. -func getStringAddressMapFromTaggedAddressMap(taggedAddresses map[string]*discovery.TaggedAddress) map[string]string { - taggedServiceAddresses := make(map[string]string, len(taggedAddresses)) - for k, v := range taggedAddresses { - taggedServiceAddresses[k] = v.Address - } - return taggedServiceAddresses -} - -// getTTLForResult returns the TTL for a given result. -func getTTLForResult(name string, overrideTTL *uint32, query *discovery.Query, cfg *RouterDynamicConfig) uint32 { - // In the case we are not making a discovery query, such as addr. or arpa. lookups, - // use the node TTL by convention - if query == nil { - return uint32(cfg.NodeTTL / time.Second) - } - - if overrideTTL != nil { - // If a result was provided with an override, use that. This is the case for some prepared queries. - return *overrideTTL - } - - switch query.QueryType { - case discovery.QueryTypeService, discovery.QueryTypePreparedQuery: - ttl, ok := cfg.GetTTLForService(name) - if ok { - return uint32(ttl / time.Second) - } - fallthrough - default: - return uint32(cfg.NodeTTL / time.Second) - } -} - -// serializeToGetAnswerExtraAndNsOptions converts serializeOptions to getAnswerExtraAndNsOptions. -func serializeToGetAnswerExtraAndNsOptions(opts *serializeOptions, - result *discovery.Result, port discovery.Port) *getAnswerExtraAndNsOptions { - return &getAnswerExtraAndNsOptions{ - port: port, - result: result, - req: opts.req, - reqCtx: opts.reqCtx, - query: opts.query, - results: opts.results, - resp: opts.resp, - cfg: opts.cfg, - responseDomain: opts.responseDomain, - remoteAddress: opts.remoteAddress, - maxRecursionLevel: opts.maxRecursionLevel, - translateAddressFunc: opts.translateAddressFunc, - translateServiceAddressFunc: opts.translateServiceAddressFunc, - resolveCnameFunc: opts.resolveCnameFunc, - dnsRecordMaker: opts.dnsRecordMaker, - } -} diff --git a/agent/dns/mock_DNSRouter.go b/agent/dns/mock_DNSRouter.go deleted file mode 100644 index 9e90de771e..0000000000 --- a/agent/dns/mock_DNSRouter.go +++ /dev/null @@ -1,82 +0,0 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. - -package dns - -import ( - config "github.com/hashicorp/consul/agent/config" - miekgdns "github.com/miekg/dns" - - mock "github.com/stretchr/testify/mock" - - net "net" -) - -// MockDNSRouter is an autogenerated mock type for the DNSRouter type -type MockDNSRouter struct { - mock.Mock -} - -// GetConfig provides a mock function with given fields: -func (_m *MockDNSRouter) GetConfig() *RouterDynamicConfig { - ret := _m.Called() - - var r0 *RouterDynamicConfig - if rf, ok := ret.Get(0).(func() *RouterDynamicConfig); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*RouterDynamicConfig) - } - } - - return r0 -} - -// HandleRequest provides a mock function with given fields: req, reqCtx, remoteAddress -func (_m *MockDNSRouter) HandleRequest(req *miekgdns.Msg, reqCtx Context, remoteAddress net.Addr) *miekgdns.Msg { - ret := _m.Called(req, reqCtx, remoteAddress) - - var r0 *miekgdns.Msg - if rf, ok := ret.Get(0).(func(*miekgdns.Msg, Context, net.Addr) *miekgdns.Msg); ok { - r0 = rf(req, reqCtx, remoteAddress) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*miekgdns.Msg) - } - } - - return r0 -} - -// ReloadConfig provides a mock function with given fields: newCfg -func (_m *MockDNSRouter) ReloadConfig(newCfg *config.RuntimeConfig) error { - ret := _m.Called(newCfg) - - var r0 error - if rf, ok := ret.Get(0).(func(*config.RuntimeConfig) error); ok { - r0 = rf(newCfg) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ServeDNS provides a mock function with given fields: w, req -func (_m *MockDNSRouter) ServeDNS(w miekgdns.ResponseWriter, req *miekgdns.Msg) { - _m.Called(w, req) -} - -// NewMockDNSRouter creates a new instance of MockDNSRouter. 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 NewMockDNSRouter(t interface { - mock.TestingT - Cleanup(func()) -}) *MockDNSRouter { - mock := &MockDNSRouter{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/agent/dns/mock_dnsRecursor.go b/agent/dns/mock_dnsRecursor.go deleted file mode 100644 index b590661da1..0000000000 --- a/agent/dns/mock_dnsRecursor.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. - -package dns - -import ( - miekgdns "github.com/miekg/dns" - mock "github.com/stretchr/testify/mock" - - net "net" -) - -// mockDnsRecursor is an autogenerated mock type for the dnsRecursor type -type mockDnsRecursor struct { - mock.Mock -} - -// handle provides a mock function with given fields: req, cfgCtx, remoteAddr -func (_m *mockDnsRecursor) handle(req *miekgdns.Msg, cfgCtx *RouterDynamicConfig, remoteAddr net.Addr) (*miekgdns.Msg, error) { - ret := _m.Called(req, cfgCtx, remoteAddr) - - var r0 *miekgdns.Msg - var r1 error - if rf, ok := ret.Get(0).(func(*miekgdns.Msg, *RouterDynamicConfig, net.Addr) (*miekgdns.Msg, error)); ok { - return rf(req, cfgCtx, remoteAddr) - } - if rf, ok := ret.Get(0).(func(*miekgdns.Msg, *RouterDynamicConfig, net.Addr) *miekgdns.Msg); ok { - r0 = rf(req, cfgCtx, remoteAddr) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*miekgdns.Msg) - } - } - - if rf, ok := ret.Get(1).(func(*miekgdns.Msg, *RouterDynamicConfig, net.Addr) error); ok { - r1 = rf(req, cfgCtx, remoteAddr) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// newMockDnsRecursor creates a new instance of mockDnsRecursor. 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 newMockDnsRecursor(t interface { - mock.TestingT - Cleanup(func()) -}) *mockDnsRecursor { - mock := &mockDnsRecursor{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/agent/dns/parser.go b/agent/dns/parser.go deleted file mode 100644 index e39f91e0f9..0000000000 --- a/agent/dns/parser.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -// parsedLabels defines valid DNS labels that are possible for ALL DNS query in Consul. (v1 and v2, CE and ENT) -// It is the job of the parser to populate the struct, the routers to call the query processor, -// and the query processor to validate is the labels. -type parsedLabels struct { - Datacenter string - Namespace string - Partition string - Peer string - PeerOrDatacenter string // deprecated: use Datacenter or Peer - SamenessGroup string -} - -// ParseLabels can parse a DNS query's labels and returns a parsedLabels. -// It also does light validation according to invariants across all possible DNS queries for all Consul versions -func parseLabels(labels []string) (*parsedLabels, bool) { - var result parsedLabels - - switch len(labels) { - case 2, 4, 6: - // Supports the following formats: - // - [..ns][..ap][..dc] - // - . - // - [..ns][..ap][..peer] - // - [..sg][..ap][..ns] - for i := 0; i < len(labels); i += 2 { - switch labels[i+1] { - case "ns": - result.Namespace = labels[i] - case "ap": - result.Partition = labels[i] - case "dc", "cluster": - result.Datacenter = labels[i] - case "sg": - result.SamenessGroup = labels[i] - case "peer": - result.Peer = labels[i] - default: - // The only case in which labels[i+1] is allowed to be a value - // other than ns, ap, or dc is if n == 2 to support the format: - // .. - if len(labels) == 2 { - result.PeerOrDatacenter = labels[1] - result.Namespace = labels[0] - return &result, true - } - return nil, false - } - } - - // VALIDATIONS - // Return nil result and false boolean when both datacenter and peer are specified. - if result.Datacenter != "" && result.Peer != "" { - return nil, false - } - - // Validate that this a valid DNS including sg - if result.SamenessGroup != "" && (result.Datacenter != "" || result.Peer != "") { - return nil, false - } - - return &result, true - - case 1: - result.PeerOrDatacenter = labels[0] - return &result, true - - case 0: - return &result, true - } - - return &result, false -} - -// parsePort looks through the query parts for a named port label. -// It assumes the only valid input format is["", "port", ""]. -// The other expected formats are [""] and ["", ""]. -// It is expected that the queryProcessor validates if the label is allowed for the query type. -func parsePort(parts []string) string { - // The minimum number of parts would be - if len(parts) != 3 || parts[1] != "port" { - return "" - } - return parts[0] -} diff --git a/agent/dns/parser_test.go b/agent/dns/parser_test.go deleted file mode 100644 index cd5beb117a..0000000000 --- a/agent/dns/parser_test.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "github.com/stretchr/testify/require" - "testing" -) - -func Test_parseLabels(t *testing.T) { - type testCase struct { - name string - labels []string - expectedOK bool - expectedResult *parsedLabels - } - testCases := []testCase{ - { - name: "6 labels - with datacenter", - labels: []string{"test-ns", "ns", "test-ap", "ap", "test-dc", "dc"}, - expectedResult: &parsedLabels{ - Namespace: "test-ns", - Partition: "test-ap", - Datacenter: "test-dc", - }, - expectedOK: true, - }, - { - name: "6 labels - with cluster", - labels: []string{"test-ns", "ns", "test-ap", "ap", "test-cluster", "cluster"}, - expectedResult: &parsedLabels{ - Namespace: "test-ns", - Partition: "test-ap", - Datacenter: "test-cluster", - }, - expectedOK: true, - }, - { - name: "6 labels - with peer", - labels: []string{"test-ns", "ns", "test-ap", "ap", "test-peer", "peer"}, - expectedResult: &parsedLabels{ - Namespace: "test-ns", - Partition: "test-ap", - Peer: "test-peer", - }, - expectedOK: true, - }, - { - name: "6 labels - with sameness group", - labels: []string{"test-sg", "sg", "test-ap", "ap", "test-ns", "ns"}, - expectedResult: &parsedLabels{ - Namespace: "test-ns", - Partition: "test-ap", - SamenessGroup: "test-sg", - }, - expectedOK: true, - }, - { - name: "6 labels - invalid", - labels: []string{"test-ns", "not-ns", "test-ap", "ap", "test-dc", "dc"}, - expectedResult: nil, - expectedOK: false, - }, - { - name: "4 labels - namespace and datacenter", - labels: []string{"test-ns", "ns", "test-ap", "ap"}, - expectedResult: &parsedLabels{ - Namespace: "test-ns", - Partition: "test-ap", - }, - expectedOK: true, - }, - { - name: "4 labels - invalid", - labels: []string{"test-ns", "not-ns", "test-ap", "ap", "test-dc", "dc"}, - expectedResult: nil, - expectedOK: false, - }, - { - name: "2 labels - namespace and peer or datacenter", - labels: []string{"test-ns", "test-peer-or-dc"}, - expectedResult: &parsedLabels{ - Namespace: "test-ns", - PeerOrDatacenter: "test-peer-or-dc", - }, - expectedOK: true, - }, - { - name: "1 label - peer or datacenter", - labels: []string{"test-peer-or-dc"}, - expectedResult: &parsedLabels{ - PeerOrDatacenter: "test-peer-or-dc", - }, - expectedOK: true, - }, - { - name: "0 labels - returns empty result and true", - labels: []string{}, - expectedResult: &parsedLabels{}, - expectedOK: true, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - result, ok := parseLabels(tc.labels) - require.Equal(t, tc.expectedOK, ok) - require.Equal(t, tc.expectedResult, result) - }) - } -} - -func Test_parsePort(t *testing.T) { - type testCase struct { - name string - labels []string - expectedResult string - } - testCases := []testCase{ - { - name: "given 3 labels where the second label is port, the first label is returned", - labels: []string{"port-name", "port", "target-name"}, - expectedResult: "port-name", - }, - { - name: "given 3 labels where the second label is not port, an empty string is returned", - labels: []string{"port-name", "not-port", "target-name"}, - expectedResult: "", - }, - { - name: "given anything but 3 labels, an empty string is returned", - labels: []string{"port-name", "something-else"}, - expectedResult: "", - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - require.Equal(t, tc.expectedResult, parsePort(tc.labels)) - }) - } -} diff --git a/agent/dns/recursor.go b/agent/dns/recursor.go deleted file mode 100644 index 21ea94a6c8..0000000000 --- a/agent/dns/recursor.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "errors" - "net" - "time" - - "github.com/hashicorp/go-hclog" - "github.com/miekg/dns" - - "github.com/hashicorp/consul/ipaddr" - "github.com/hashicorp/consul/logging" -) - -type recursor struct { - logger hclog.Logger -} - -func newRecursor(logger hclog.Logger) *recursor { - return &recursor{ - logger: logger.Named(logging.DNS), - } -} - -// handle is used to process DNS queries for externally configured servers -func (r *recursor) handle(req *dns.Msg, cfgCtx *RouterDynamicConfig, remoteAddr net.Addr) (*dns.Msg, error) { - q := req.Question[0] - - network := "udp" - defer func(s time.Time) { - r.logger.Trace("request served from client", - "question", q, - "network", network, - "latency", time.Since(s).String(), - "client", remoteAddr.String(), - "client_network", remoteAddr.Network(), - ) - }(time.Now()) - - // Switch to TCP if the client is - if _, ok := remoteAddr.(*net.TCPAddr); ok { - network = "tcp" - } - - // Recursively resolve - c := &dns.Client{Net: network, Timeout: cfgCtx.RecursorTimeout} - var resp *dns.Msg - var rtt time.Duration - var err error - for _, idx := range cfgCtx.RecursorStrategy.Indexes(len(cfgCtx.Recursors)) { - recurseAddr := cfgCtx.Recursors[idx] - resp, rtt, err = c.Exchange(req, recurseAddr) - // Check if the response is valid and has the desired Response code - if resp != nil && (resp.Rcode != dns.RcodeSuccess && resp.Rcode != dns.RcodeNameError) { - r.logger.Trace("recurse failed for question", - "question", q, - "rtt", rtt, - "recursor", recurseAddr, - "rcode", dns.RcodeToString[resp.Rcode], - ) - // If we still have recursors to forward the query to, - // we move forward onto the next one else the loop ends - continue - } else if err == nil || (resp != nil && resp.Truncated) { - // Compress the response; we don't know if the incoming - // response was compressed or not, so by not compressing - // we might generate an invalid packet on the way out. - resp.Compress = !cfgCtx.DisableCompression - - // Forward the response - r.logger.Trace("recurse succeeded for question", - "question", q, - "rtt", rtt, - "recursor", recurseAddr, - ) - return resp, nil - } - r.logger.Error("recurse failed", "error", err) - } - - // If all resolvers fail, return a SERVFAIL message - r.logger.Error("all resolvers failed for question from client", - "question", q, - "client", remoteAddr.String(), - "client_network", remoteAddr.Network(), - ) - - return nil, errRecursionFailed -} - -// formatRecursorAddress is used to add a port to the recursor if omitted. -func formatRecursorAddress(recursor string) (string, error) { - _, _, err := net.SplitHostPort(recursor) - var ae *net.AddrError - if errors.As(err, &ae) { - switch ae.Err { - case "missing port in address": - recursor = ipaddr.FormatAddressPort(recursor, 53) - case "too many colons in address": - if ip := net.ParseIP(recursor); ip != nil && ip.To4() == nil { - recursor = ipaddr.FormatAddressPort(recursor, 53) - break - } - fallthrough - default: - return "", err - } - } else if err != nil { - return "", err - } - - // Get the address - addr, err := net.ResolveTCPAddr("tcp", recursor) - if err != nil { - return "", err - } - - // Return string - return addr.String(), nil -} diff --git a/agent/dns/recursor_test.go b/agent/dns/recursor_test.go deleted file mode 100644 index 69514e508e..0000000000 --- a/agent/dns/recursor_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "strings" - "testing" -) - -// Test_handle cases are covered by the integration tests in agent/dns_test.go. -// They should be moved here when the V1 DNS server is deprecated. -//func Test_handle(t *testing.T) { - -func Test_formatRecursorAddress(t *testing.T) { - t.Parallel() - addr, err := formatRecursorAddress("8.8.8.8") - if err != nil { - t.Fatalf("err: %v", err) - } - if addr != "8.8.8.8:53" { - t.Fatalf("bad: %v", addr) - } - addr, err = formatRecursorAddress("2001:4860:4860::8888") - if err != nil { - t.Fatalf("err: %v", err) - } - if addr != "[2001:4860:4860::8888]:53" { - t.Fatalf("bad: %v", addr) - } - _, err = formatRecursorAddress("1.2.3.4::53") - if err == nil || !strings.Contains(err.Error(), "too many colons in address") { - t.Fatalf("err: %v", err) - } - _, err = formatRecursorAddress("2001:4860:4860::8888:::53") - if err == nil || !strings.Contains(err.Error(), "too many colons in address") { - t.Fatalf("err: %v", err) - } -} diff --git a/agent/dns/response_generator.go b/agent/dns/response_generator.go deleted file mode 100644 index ad7b14270d..0000000000 --- a/agent/dns/response_generator.go +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "errors" - "fmt" - "math" - "net" - "strings" - - "github.com/miekg/dns" - - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/lib" - "github.com/hashicorp/go-hclog" -) - -const ( - // UDP can fit ~25 A records in a 512B response, and ~14 AAAA - // records. Limit further to prevent unintentional configuration - // abuse that would have a negative effect on application response - // times. - maxUDPAnswerLimit = 8 - - defaultMaxUDPSize = 512 - - // If a consumer sets a buffer size greater than this amount we will default it down - // to this amount to ensure that consul does respond. Previously if consumer had a larger buffer - // size than 65535 - 60 bytes (maximim 60 bytes for IP header. UDP header will be offset in the - // trimUDP call) consul would fail to respond and the consumer timesout - // the request. - maxUDPDatagramSize = math.MaxUint16 - 68 -) - -// dnsResponseGenerator is used to: -// - generate DNS responses for errors -// - trim and truncate DNS responses -// - EDNS to the response -type dnsResponseGenerator struct{} - -// createRefusedResponse returns a REFUSED message. This is the default behavior for unmatched queries in -// upstream miekg/dns. -func (d dnsResponseGenerator) createRefusedResponse(req *dns.Msg) *dns.Msg { - // Return a REFUSED message - m := &dns.Msg{} - m.SetRcode(req, dns.RcodeRefused) - return m -} - -// createServerFailureResponse returns a SERVFAIL message. -func (d dnsResponseGenerator) createServerFailureResponse(req *dns.Msg, cfg *RouterDynamicConfig, recursionAvailable bool) *dns.Msg { - // Return a SERVFAIL message - m := &dns.Msg{} - m.SetReply(req) - m.Compress = !cfg.DisableCompression - m.SetRcode(req, dns.RcodeServerFailure) - m.RecursionAvailable = recursionAvailable - if edns := req.IsEdns0(); edns != nil { - d.setEDNS(req, m, true) - } - - return m -} - -// createAuthoritativeResponse returns an authoritative message that contains the SOA in the event that data is -// not return for a query. There can be multiple reasons for not returning data, hence the rcode argument. -func (d dnsResponseGenerator) createAuthoritativeResponse(req *dns.Msg, cfg *RouterDynamicConfig, domain string, rcode int, ecsGlobal bool) *dns.Msg { - m := &dns.Msg{} - m.SetRcode(req, rcode) - m.Compress = !cfg.DisableCompression - m.Authoritative = true - m.RecursionAvailable = canRecurse(cfg) - if edns := req.IsEdns0(); edns != nil { - d.setEDNS(req, m, ecsGlobal) - } - - // We add the SOA on NameErrors - maker := &dnsRecordMaker{} - soa := maker.makeSOA(domain, cfg) - m.Ns = append(m.Ns, soa) - - return m -} - -// generateResponseFromErrorOpts is used to pass options to generateResponseFromError. -type generateResponseFromErrorOpts struct { - req *dns.Msg - err error - qName string - configCtx *RouterDynamicConfig - responseDomain string - isECSGlobal bool - query *discovery.Query - canRecurse bool - logger hclog.Logger -} - -// generateResponseFromError generates a response from an error. -func (d dnsResponseGenerator) generateResponseFromError(opts *generateResponseFromErrorOpts) *dns.Msg { - switch { - case errors.Is(opts.err, errInvalidQuestion): - opts.logger.Error("invalid question", "name", opts.qName) - - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeNameError, opts.isECSGlobal) - case errors.Is(opts.err, errNameNotFound): - opts.logger.Error("name not found", "name", opts.qName) - - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeNameError, opts.isECSGlobal) - case errors.Is(opts.err, errNotImplemented): - opts.logger.Error("query not implemented", "name", opts.qName, "type", dns.Type(opts.req.Question[0].Qtype).String()) - - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeNotImplemented, opts.isECSGlobal) - case errors.Is(opts.err, discovery.ErrNotSupported): - opts.logger.Debug("query name syntax not supported", "name", opts.req.Question[0].Name) - - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeNameError, opts.isECSGlobal) - case errors.Is(opts.err, discovery.ErrNotFound): - opts.logger.Debug("query name not found", "name", opts.req.Question[0].Name) - - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeNameError, opts.isECSGlobal) - case errors.Is(opts.err, discovery.ErrNoData): - opts.logger.Debug("no data available", "name", opts.qName) - - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeSuccess, opts.isECSGlobal) - case errors.Is(opts.err, discovery.ErrNoPathToDatacenter): - dc := "" - if opts.query != nil { - dc = opts.query.QueryPayload.Tenancy.Datacenter - } - opts.logger.Debug("no path to datacenter", "datacenter", dc) - return d.createAuthoritativeResponse(opts.req, opts.configCtx, opts.responseDomain, dns.RcodeNameError, opts.isECSGlobal) - } - opts.logger.Error("error processing discovery query", "error", opts.err) - return d.createServerFailureResponse(opts.req, opts.configCtx, opts.canRecurse) -} - -// trimDNSResponse will trim the response for UDP and TCP -func (d dnsResponseGenerator) trimDNSResponse(cfg *RouterDynamicConfig, remoteAddress net.Addr, req, resp *dns.Msg, logger hclog.Logger) { - // Switch to TCP if the client is - network := "udp" - if _, ok := remoteAddress.(*net.TCPAddr); ok { - network = "tcp" - } - - var trimmed bool - originalSize := resp.Len() - originalNumRecords := len(resp.Answer) - if network != "tcp" { - trimmed = trimUDPResponse(req, resp, cfg.UDPAnswerLimit) - } else { - trimmed = trimTCPResponse(req, resp) - } - // Flag that there are more records to return in the UDP response - if trimmed { - if cfg.EnableTruncate { - resp.Truncated = true - } - logger.Debug("DNS response too large, truncated", - "protocol", network, - "question", req.Question, - "records", fmt.Sprintf("%d/%d", len(resp.Answer), originalNumRecords), - "size", fmt.Sprintf("%d/%d", resp.Len(), originalSize), - ) - } -} - -// setEDNS is used to set the responses EDNS size headers and -// possibly the ECS headers as well if they were present in the -// original request -func (d dnsResponseGenerator) setEDNS(request *dns.Msg, response *dns.Msg, ecsGlobal bool) { - edns := request.IsEdns0() - if edns == nil { - return - } - - // cannot just use the SetEdns0 function as we need to embed - // the ECS option as well - ednsResp := new(dns.OPT) - ednsResp.Hdr.Name = "." - ednsResp.Hdr.Rrtype = dns.TypeOPT - ednsResp.SetUDPSize(edns.UDPSize()) - - // Set up the ECS option if present - if subnet := ednsSubnetForRequest(request); subnet != nil { - subOp := new(dns.EDNS0_SUBNET) - subOp.Code = dns.EDNS0SUBNET - subOp.Family = subnet.Family - subOp.Address = subnet.Address - subOp.SourceNetmask = subnet.SourceNetmask - if c := response.Rcode; ecsGlobal || c == dns.RcodeNameError || c == dns.RcodeServerFailure || c == dns.RcodeRefused || c == dns.RcodeNotImplemented { - // reply is globally valid and should be cached accordingly - subOp.SourceScope = 0 - } else { - // reply is only valid for the subnet it was queried with - subOp.SourceScope = subnet.SourceNetmask - } - ednsResp.Option = append(ednsResp.Option, subOp) - } - - response.Extra = append(response.Extra, ednsResp) -} - -// ednsSubnetForRequest looks through the request to find any EDS subnet options -func ednsSubnetForRequest(req *dns.Msg) *dns.EDNS0_SUBNET { - // IsEdns0 returns the EDNS RR if present or nil otherwise - edns := req.IsEdns0() - if edns == nil { - return nil - } - - for _, o := range edns.Option { - if subnet, ok := o.(*dns.EDNS0_SUBNET); ok { - return subnet - } - } - return nil -} - -// trimTCPResponse limit the MaximumSize of messages to 64k as it is the limit -// of DNS responses -func trimTCPResponse(req, resp *dns.Msg) (trimmed bool) { - hasExtra := len(resp.Extra) > 0 - // There is some overhead, 65535 does not work - maxSize := 65523 // 64k - 12 bytes DNS raw overhead - - // We avoid some function calls and allocations by only handling the - // extra data when necessary. - var index map[string]dns.RR - - // It is not possible to return more than 4k records even with compression - // Since we are performing binary search it is not a big deal, but it - // improves a bit performance, even with binary search - truncateAt := 4096 - if req.Question[0].Qtype == dns.TypeSRV { - // More than 1024 SRV records do not fit in 64k - truncateAt = 1024 - } - if len(resp.Answer) > truncateAt { - resp.Answer = resp.Answer[:truncateAt] - } - if hasExtra { - index = make(map[string]dns.RR, len(resp.Extra)) - indexRRs(resp.Extra, index) - } - truncated := false - - // This enforces the given limit on 64k, the max limit for DNS messages - for len(resp.Answer) > 1 && resp.Len() > maxSize { - truncated = true - // first try to remove the NS section may be it will truncate enough - if len(resp.Ns) != 0 { - resp.Ns = []dns.RR{} - } - // More than 100 bytes, find with a binary search - if resp.Len()-maxSize > 100 { - bestIndex := dnsBinaryTruncate(resp, maxSize, index, hasExtra) - resp.Answer = resp.Answer[:bestIndex] - } else { - resp.Answer = resp.Answer[:len(resp.Answer)-1] - } - if hasExtra { - syncExtra(index, resp) - } - } - - return truncated -} - -// trimUDPResponse makes sure a UDP response is not longer than allowed by RFC -// 1035. Enforce an arbitrary limit that can be further ratcheted down by -// config, and then make sure the response doesn't exceed 512 bytes. Any extra -// records will be trimmed along with answers. -func trimUDPResponse(req, resp *dns.Msg, udpAnswerLimit int) (trimmed bool) { - numAnswers := len(resp.Answer) - hasExtra := len(resp.Extra) > 0 - maxSize := defaultMaxUDPSize - - // Update to the maximum edns size - if edns := req.IsEdns0(); edns != nil { - if size := edns.UDPSize(); size > uint16(maxSize) { - maxSize = int(size) - } - } - // Overriding maxSize as the maxSize cannot be larger than the - // maxUDPDatagram size. Reliability guarantees disappear > than this amount. - if maxSize > maxUDPDatagramSize { - maxSize = maxUDPDatagramSize - } - - // We avoid some function calls and allocations by only handling the - // extra data when necessary. - var index map[string]dns.RR - if hasExtra { - index = make(map[string]dns.RR, len(resp.Extra)) - indexRRs(resp.Extra, index) - } - - // This cuts UDP responses to a useful but limited number of responses. - maxAnswers := lib.MinInt(maxUDPAnswerLimit, udpAnswerLimit) - compress := resp.Compress - if maxSize == defaultMaxUDPSize && numAnswers > maxAnswers { - // We disable computation of Len ONLY for non-eDNS request (512 bytes) - resp.Compress = false - resp.Answer = resp.Answer[:maxAnswers] - if hasExtra { - syncExtra(index, resp) - } - } - if maxSize == defaultMaxUDPSize && numAnswers > maxAnswers { - // We disable computation of Len ONLY for non-eDNS request (512 bytes) - resp.Compress = false - resp.Answer = resp.Answer[:maxAnswers] - if hasExtra { - syncExtra(index, resp) - } - } - - // This enforces the given limit on the number bytes. The default is 512 as - // per the RFC, but EDNS0 allows for the user to specify larger sizes. Note - // that we temporarily switch to uncompressed so that we limit to a response - // that will not exceed 512 bytes uncompressed, which is more conservative and - // will allow our responses to be compliant even if some downstream server - // uncompresses them. - // Even when size is too big for one single record, try to send it anyway - // (useful for 512 bytes messages). 8 is removed from maxSize to ensure that we account - // for the udp header (8 bytes). - for len(resp.Answer) > 1 && resp.Len() > maxSize-8 { - // first try to remove the NS section may be it will truncate enough - if len(resp.Ns) != 0 { - resp.Ns = []dns.RR{} - } - // More than 100 bytes, find with a binary search - if resp.Len()-maxSize > 100 { - bestIndex := dnsBinaryTruncate(resp, maxSize, index, hasExtra) - resp.Answer = resp.Answer[:bestIndex] - } else { - resp.Answer = resp.Answer[:len(resp.Answer)-1] - } - if hasExtra { - syncExtra(index, resp) - } - } - // For 512 non-eDNS responses, while we compute size non-compressed, - // we send result compressed - resp.Compress = compress - return len(resp.Answer) < numAnswers -} - -// syncExtra takes a DNS response message and sets the extra data to the most -// minimal set needed to cover the answer data. A pre-made index of RRs is given -// so that can be re-used between calls. This assumes that the extra data is -// only used to provide info for SRV records. If that's not the case, then this -// will wipe out any additional data. -func syncExtra(index map[string]dns.RR, resp *dns.Msg) { - extra := make([]dns.RR, 0, len(resp.Answer)) - resolved := make(map[string]struct{}, len(resp.Answer)) - for _, ansRR := range resp.Answer { - srv, ok := ansRR.(*dns.SRV) - if !ok { - continue - } - - // Note that we always use lower case when using the index so - // that compares are not case-sensitive. We don't alter the actual - // RRs we add into the extra section, however. - target := strings.ToLower(srv.Target) - - RESOLVE: - if _, ok := resolved[target]; ok { - continue - } - resolved[target] = struct{}{} - - extraRR, ok := index[target] - if ok { - extra = append(extra, extraRR) - if cname, ok := extraRR.(*dns.CNAME); ok { - target = strings.ToLower(cname.Target) - goto RESOLVE - } - } - } - resp.Extra = extra -} - -// dnsBinaryTruncate find the optimal number of records using a fast binary search and return -// it in order to return a DNS answer lower than maxSize parameter. -func dnsBinaryTruncate(resp *dns.Msg, maxSize int, index map[string]dns.RR, hasExtra bool) int { - originalAnswser := resp.Answer - startIndex := 0 - endIndex := len(resp.Answer) + 1 - for endIndex-startIndex > 1 { - median := startIndex + (endIndex-startIndex)/2 - - resp.Answer = originalAnswser[:median] - if hasExtra { - syncExtra(index, resp) - } - aLen := resp.Len() - if aLen <= maxSize { - if maxSize-aLen < 10 { - // We are good, increasing will go out of bounds - return median - } - startIndex = median - } else { - endIndex = median - } - } - return startIndex -} - -// indexRRs populates a map which indexes a given list of RRs by name. NOTE that -// the names are all squashed to lower case so we can perform case-insensitive -// lookups; the RRs are not modified. -func indexRRs(rrs []dns.RR, index map[string]dns.RR) { - for _, rr := range rrs { - name := strings.ToLower(rr.Header().Name) - if _, ok := index[name]; !ok { - index[name] = rr - } - } -} diff --git a/agent/dns/response_generator_test.go b/agent/dns/response_generator_test.go deleted file mode 100644 index ec9849307e..0000000000 --- a/agent/dns/response_generator_test.go +++ /dev/null @@ -1,739 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "errors" - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestDNSResponseGenerator_generateResponseFromError(t *testing.T) { - testCases := []struct { - name string - opts *generateResponseFromErrorOpts - expectedResponse *dns.Msg - }{ - { - name: "error is nil returns server failure", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{}, - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: nil, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: false, - Rcode: dns.RcodeServerFailure, - }, - }, - }, - { - name: "error is invalid question returns name error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "invalid-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "invalid-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: errInvalidQuestion, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Question: []dns.Question{ - { - Name: "invalid-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is name not found returns name error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "invalid-name", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "invalid-name", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: errNameNotFound, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Question: []dns.Question{ - { - Name: "invalid-name", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is not implemented returns not implemented error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "some-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: errNotImplemented, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNotImplemented, - }, - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is not supported returns name error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "some-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: discovery.ErrNotSupported, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is not found returns name error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "some-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: discovery.ErrNotFound, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is no data returns success with soa", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "some-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: discovery.ErrNoData, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is no path to datacenter returns name error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "some-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: discovery.ErrNoPathToDatacenter, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 0, - }, - Ns: "ns.testdomain.", - Mbox: "hostmaster.testdomain.", - Serial: uint32(time.Now().Unix()), - }, - }, - }, - }, - { - name: "error is something else returns server failure error", - opts: &generateResponseFromErrorOpts{ - req: &dns.Msg{ - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - }, - qName: "some-question", - responseDomain: "testdomain.", - logger: testutil.Logger(t), - configCtx: &RouterDynamicConfig{ - DisableCompression: true, - }, - err: errors.New("KABOOM"), - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: false, - Rcode: dns.RcodeServerFailure, - }, - Question: []dns.Question{ - { - Name: "some-question", - Qtype: dns.TypeSRV, - Qclass: dns.ClassANY, - }, - }, - Ns: nil, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - tc.opts.req.IsEdns0() - actualResponse := dnsResponseGenerator{}.generateResponseFromError(tc.opts) - require.Equal(t, tc.expectedResponse, actualResponse) - }) - } -} - -func TestDNSResponseGenerator_setEDNS(t *testing.T) { - testCases := []struct { - name string - req *dns.Msg - response *dns.Msg - ecsGlobal bool - expectedResponse *dns.Msg - }{ - { - name: "request is not edns0, response is not edns0", - req: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Extra: []dns.RR{ - &dns.OPT{ - Hdr: dns.RR_Header{ - Name: ".", - Rrtype: dns.TypeOPT, - Class: 4096, - Ttl: 0, - }, - Option: []dns.EDNS0{ - &dns.EDNS0_SUBNET{ - Code: 1, - Family: 2, - SourceNetmask: 3, - SourceScope: 4, - Address: net.ParseIP("255.255.255.255"), - }, - }, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Extra: []dns.RR{ - &dns.OPT{ - Hdr: dns.RR_Header{ - Name: ".", - Rrtype: dns.TypeOPT, - Class: 4096, - Ttl: 0, - }, - Option: []dns.EDNS0{ - &dns.EDNS0_SUBNET{ - Code: 8, - Family: 2, - SourceNetmask: 3, - SourceScope: 3, - Address: net.ParseIP("255.255.255.255"), - }, - }, - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - dnsResponseGenerator{}.setEDNS(tc.req, tc.response, tc.ecsGlobal) - require.Equal(t, tc.expectedResponse, tc.response) - }) - } -} - -func TestDNSResponseGenerator_trimDNSResponse(t *testing.T) { - testCases := []struct { - name string - req *dns.Msg - response *dns.Msg - cfg *RouterDynamicConfig - remoteAddress net.Addr - expectedResponse *dns.Msg - }{ - { - name: "network is udp, enable truncate is true, answer count of 1 is less/equal than configured max f 1, response is not trimmed", - req: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - cfg: &RouterDynamicConfig{ - UDPAnswerLimit: 1, - }, - remoteAddress: &net.UDPAddr{ - IP: net.ParseIP("127.0.0.1"), - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "network is udp, enable truncate is true, answer count of 2 is greater than configure UDP max f 2, response is trimmed", - req: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - cfg: &RouterDynamicConfig{ - UDPAnswerLimit: 1, - }, - remoteAddress: &net.UDPAddr{ - IP: net.ParseIP("127.0.0.1"), - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo1.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo2.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("2.2.3.4"), - }, - }, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo1.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "network is tcp, enable truncate is true, answer is less than 64k limit, response is not trimmed", - req: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - cfg: &RouterDynamicConfig{}, - remoteAddress: &net.TCPAddr{ - IP: net.ParseIP("127.0.0.1"), - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - expectedResponse: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - logger := testutil.Logger(t) - dnsResponseGenerator{}.trimDNSResponse(tc.cfg, tc.remoteAddress, tc.req, tc.response, logger) - require.Equal(t, tc.expectedResponse, tc.response) - }) - - } -} diff --git a/agent/dns/router.go b/agent/dns/router.go deleted file mode 100644 index 34de8a7701..0000000000 --- a/agent/dns/router.go +++ /dev/null @@ -1,557 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "errors" - "fmt" - "net" - "regexp" - "strings" - "sync/atomic" - "time" - - "github.com/armon/go-metrics" - "github.com/armon/go-radix" - "github.com/hashicorp/go-hclog" - "github.com/miekg/dns" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/dnsutil" - "github.com/hashicorp/consul/logging" -) - -const ( - addrLabel = "addr" - - arpaDomain = "arpa." - arpaLabel = "arpa" - - suffixFailover = "failover." - suffixNoFailover = "no-failover." - maxRecursionLevelDefault = 3 // This field comes from the V1 DNS server and affects V1 catalog lookups - maxRecurseRecords = 5 -) - -var ( - errInvalidQuestion = fmt.Errorf("invalid question") - errNameNotFound = fmt.Errorf("name not found") - errNotImplemented = fmt.Errorf("not implemented") - errRecursionFailed = fmt.Errorf("recursion failed") - - trailingSpacesRE = regexp.MustCompile(" +$") -) - -// RouterDynamicConfig is the dynamic configuration that can be hot-reloaded -type RouterDynamicConfig struct { - ARecordLimit int - DisableCompression bool - EnableTruncate bool - NodeMetaTXT bool - NodeTTL time.Duration - Recursors []string - RecursorTimeout time.Duration - RecursorStrategy structs.RecursorStrategy - SOAConfig SOAConfig - // TTLRadix sets service TTLs by prefix, eg: "database-*" - TTLRadix *radix.Tree - // TTLStrict sets TTLs to service by full name match. It Has higher priority than TTLRadix - TTLStrict map[string]time.Duration - UDPAnswerLimit int -} - -// GetTTLForService Find the TTL for a given service. -// return ttl, true if found, 0, false otherwise -func (cfg *RouterDynamicConfig) GetTTLForService(service string) (time.Duration, bool) { - if cfg.TTLStrict != nil { - ttl, ok := cfg.TTLStrict[service] - if ok { - return ttl, true - } - } - if cfg.TTLRadix != nil { - _, ttlRaw, ok := cfg.TTLRadix.LongestPrefix(service) - if ok { - return ttlRaw.(time.Duration), true - } - } - return 0, false -} - -type SOAConfig struct { - Refresh uint32 // 3600 by default - Retry uint32 // 600 - Expire uint32 // 86400 - Minttl uint32 // 0 -} - -// DiscoveryQueryProcessor is an interface that can be used by any consumer requesting Service Discovery results. -// This could be attached to a gRPC endpoint in the future in addition to DNS. -// Making this an interface means testing the router with a mock is trivial. -type DiscoveryQueryProcessor interface { - QueryByName(*discovery.Query, discovery.Context) ([]*discovery.Result, error) - QueryByIP(net.IP, discovery.Context) ([]*discovery.Result, error) -} - -// dnsRecursor is an interface that can be used to mock calls to external DNS servers for unit testing. -// -//go:generate mockery --name dnsRecursor --inpackage -type dnsRecursor interface { - handle(req *dns.Msg, cfgCtx *RouterDynamicConfig, remoteAddress net.Addr) (*dns.Msg, error) -} - -// Router replaces miekg/dns.ServeMux with a simpler router that only checks for the 2-3 valid domains -// that Consul supports and forwards to a single DiscoveryQueryProcessor handler. If there is no match, it will recurse. -type Router struct { - processor DiscoveryQueryProcessor - recursor dnsRecursor - domain string - altDomain string - nodeName string - logger hclog.Logger - - tokenFunc func() string - translateAddressFunc func(dc string, addr string, taggedAddresses map[string]string, accept dnsutil.TranslateAddressAccept) string - translateServiceAddressFunc func(dc string, address string, taggedAddresses map[string]structs.ServiceAddress, accept dnsutil.TranslateAddressAccept) string - - // dynamicConfig stores the config as an atomic value (for hot-reloading). - // It is always of type *RouterDynamicConfig - dynamicConfig atomic.Value -} - -var _ = dns.Handler(&Router{}) -var _ = DNSRouter(&Router{}) - -func NewRouter(cfg Config) (*Router, error) { - // Make sure domains are FQDN, make them case-insensitive for DNSRequestRouter - domain := dns.CanonicalName(cfg.AgentConfig.DNSDomain) - altDomain := dns.CanonicalName(cfg.AgentConfig.DNSAltDomain) - - logger := cfg.Logger.Named(logging.DNS) - - router := &Router{ - processor: cfg.Processor, - recursor: newRecursor(logger), - domain: domain, - altDomain: altDomain, - logger: logger, - nodeName: cfg.AgentConfig.NodeName, - tokenFunc: cfg.TokenFunc, - translateAddressFunc: cfg.TranslateAddressFunc, - translateServiceAddressFunc: cfg.TranslateServiceAddressFunc, - } - - if err := router.ReloadConfig(cfg.AgentConfig); err != nil { - return nil, err - } - return router, nil -} - -// HandleRequest is used to process an individual DNS request. It returns a message in success or fail cases. -func (r *Router) HandleRequest(req *dns.Msg, reqCtx Context, remoteAddress net.Addr) *dns.Msg { - configCtx := r.dynamicConfig.Load().(*RouterDynamicConfig) - - respGenerator := dnsResponseGenerator{} - - err := validateAndNormalizeRequest(req) - if err != nil { - r.logger.Error("error parsing DNS query", "error", err) - if errors.Is(err, errInvalidQuestion) { - return respGenerator.createRefusedResponse(req) - } - return respGenerator.createServerFailureResponse(req, configCtx, false) - } - - r.logger.Trace("received request", "question", req.Question[0].Name, "type", dns.Type(req.Question[0].Qtype).String()) - r.normalizeContext(&reqCtx) - - defer func(s time.Time, q dns.Question) { - metrics.MeasureSinceWithLabels([]string{"dns", "query"}, s, - []metrics.Label{ - {Name: "node", Value: r.nodeName}, - {Name: "type", Value: dns.Type(q.Qtype).String()}, - }) - - r.logger.Trace("request served from client", - "name", q.Name, - "type", dns.Type(q.Qtype).String(), - "class", dns.Class(q.Qclass).String(), - "latency", time.Since(s).String(), - "client", remoteAddress.String(), - "client_network", remoteAddress.Network(), - ) - }(time.Now(), req.Question[0]) - - return r.handleRequestRecursively(req, reqCtx, configCtx, remoteAddress, maxRecursionLevelDefault) -} - -// handleRequestRecursively is used to process an individual DNS request. It will recurse as needed -// a maximum number of times and returns a message in success or fail cases. -func (r *Router) handleRequestRecursively(req *dns.Msg, reqCtx Context, configCtx *RouterDynamicConfig, - remoteAddress net.Addr, maxRecursionLevel int) *dns.Msg { - respGenerator := dnsResponseGenerator{} - - r.logger.Trace( - "received request", - "question", req.Question[0].Name, - "type", dns.Type(req.Question[0].Qtype).String(), - "recursion_remaining", maxRecursionLevel) - - responseDomain, needRecurse := r.parseDomain(req.Question[0].Name) - if needRecurse && !canRecurse(configCtx) { - // This is the same error as an unmatched domain - return respGenerator.createRefusedResponse(req) - } - - if needRecurse { - r.logger.Trace("checking recursors to handle request", "question", req.Question[0].Name, "type", dns.Type(req.Question[0].Qtype).String()) - - // This assumes `canRecurse(configCtx)` is true above - resp, err := r.recursor.handle(req, configCtx, remoteAddress) - if err != nil && !errors.Is(err, errRecursionFailed) { - r.logger.Error("unhandled error recursing DNS query", "error", err) - } - if err != nil { - return respGenerator.createServerFailureResponse(req, configCtx, true) - } - return resp - } - - // Need to pass the question name to properly support recursion and the - // trimming of the domain suffixes. - qName := dns.CanonicalName(req.Question[0].Name) - if maxRecursionLevel < maxRecursionLevelDefault { - // Get the QName without the domain suffix - qName = r.trimDomain(qName) - } - - results, query, err := discoveryResultsFetcher{}.getQueryResults(&getQueryOptions{ - req: req, - reqCtx: reqCtx, - qName: qName, - remoteAddress: remoteAddress, - processor: r.processor, - logger: r.logger, - domain: r.domain, - altDomain: r.altDomain, - }) - - // in case of the wrapped ECSNotGlobalError, extract the error from it. - isECSGlobal := !errors.Is(err, discovery.ErrECSNotGlobal) - err = getErrorFromECSNotGlobalError(err) - if err != nil { - return respGenerator.generateResponseFromError(&generateResponseFromErrorOpts{ - req: req, - err: err, - qName: qName, - configCtx: configCtx, - responseDomain: responseDomain, - isECSGlobal: isECSGlobal, - query: query, - canRecurse: canRecurse(configCtx), - logger: r.logger, - }) - } - - r.logger.Trace("serializing results", "question", req.Question[0].Name, "results-found", len(results)) - - // This needs the question information because it affects the serialization format. - // e.g., the Consul service has the same "results" for both NS and A/AAAA queries, but the serialization differs. - serializedOpts := &serializeOptions{ - req: req, - reqCtx: reqCtx, - query: query, - results: results, - cfg: configCtx, - responseDomain: responseDomain, - remoteAddress: remoteAddress, - maxRecursionLevel: maxRecursionLevel, - translateAddressFunc: r.translateAddressFunc, - translateServiceAddressFunc: r.translateServiceAddressFunc, - resolveCnameFunc: r.resolveCNAME, - } - resp, err := messageSerializer{}.serialize(serializedOpts) - if err != nil { - return respGenerator.generateResponseFromError(&generateResponseFromErrorOpts{ - req: req, - err: err, - qName: qName, - configCtx: configCtx, - responseDomain: responseDomain, - isECSGlobal: isECSGlobal, - query: query, - canRecurse: false, - logger: r.logger, - }) - } - - respGenerator.trimDNSResponse(configCtx, remoteAddress, req, resp, r.logger) - respGenerator.setEDNS(req, resp, isECSGlobal) - return resp -} - -// trimDomain trims the domain from the question name. -func (r *Router) trimDomain(questionName string) string { - longer := r.domain - shorter := r.altDomain - - if len(shorter) > len(longer) { - longer, shorter = shorter, longer - } - - if strings.HasSuffix(questionName, "."+strings.TrimLeft(longer, ".")) { - return strings.TrimSuffix(questionName, longer) - } - return strings.TrimSuffix(questionName, shorter) -} - -// ServeDNS implements the miekg/dns.Handler interface. -// This is a standard DNS listener. -func (r *Router) ServeDNS(w dns.ResponseWriter, req *dns.Msg) { - out := r.HandleRequest(req, Context{}, w.RemoteAddr()) - w.WriteMsg(out) -} - -// ReloadConfig hot-reloads the router config with new parameters -func (r *Router) ReloadConfig(newCfg *config.RuntimeConfig) error { - cfg, err := getDynamicRouterConfig(newCfg) - if err != nil { - return fmt.Errorf("error loading DNS config: %w", err) - } - r.dynamicConfig.Store(cfg) - return nil -} - -// resolveCNAME is used to recursively resolve CNAME records -func (r *Router) resolveCNAME(cfgContext *RouterDynamicConfig, name string, reqCtx Context, - remoteAddress net.Addr, maxRecursionLevel int) []dns.RR { - // If the CNAME record points to a Consul address, resolve it internally - // Convert query to lowercase because DNS is case-insensitive; r.domain and - // r.altDomain are already converted - - if ln := strings.ToLower(name); strings.HasSuffix(ln, "."+r.domain) || strings.HasSuffix(ln, "."+r.altDomain) { - if maxRecursionLevel < 1 { - r.logger.Error("Infinite recursion detected for name, won't perform any CNAME resolution.", "name", name) - return nil - } - req := &dns.Msg{} - - req.SetQuestion(name, dns.TypeANY) - // TODO: handle error response (this is a comment from the V1 DNS Server) - resp := r.handleRequestRecursively(req, reqCtx, cfgContext, nil, maxRecursionLevel-1) - - return resp.Answer - } - - // Do nothing if we don't have a recursor - if !canRecurse(cfgContext) { - return nil - } - - // Ask for any A records - m := new(dns.Msg) - m.SetQuestion(name, dns.TypeA) - - // Make a DNS lookup request - recursorResponse, err := r.recursor.handle(m, cfgContext, remoteAddress) - if err == nil { - return recursorResponse.Answer - } - - r.logger.Error("all resolvers failed for name", "name", name) - return nil -} - -// Request type is similar to miekg/dns.Type, but correlates to the different query processors we might need to invoke. -type requestType string - -const ( - requestTypeName requestType = "NAME" // A/AAAA/CNAME/SRV - requestTypeIP requestType = "IP" // PTR - requestTypeAddress requestType = "ADDR" // Custom addr. A/AAAA lookups - requestTypeConsul requestType = "CONSUL" // SOA/NS -) - -// parseDomain converts a DNS message into a generic discovery request. -// If the request domain does not match "consul." or the alternative domain, -// it will return true for needRecurse. The logic is based on miekg/dns.ServeDNS matcher. -// The implementation assumes that the only valid domains are "consul." and the alternative domain, and -// that DS query types are not supported. -func (r *Router) parseDomain(questionName string) (string, bool) { - target := dns.CanonicalName(questionName) - target, _ = stripAnyFailoverSuffix(target) - - for offset, overflow := 0, false; !overflow; offset, overflow = dns.NextLabel(target, offset) { - subdomain := target[offset:] - switch subdomain { - case ".": - // We don't support consul having a domain or altdomain attached to the root. - return "", true - case r.domain: - return r.domain, false - case r.altDomain: - return r.altDomain, false - case arpaDomain: - // PTR queries always respond with the primary domain. - return r.domain, false - // Default: fallthrough - } - } - // No match found; recurse if possible - return "", true -} - -// GetConfig returns the current router config -func (r *Router) GetConfig() *RouterDynamicConfig { - return r.dynamicConfig.Load().(*RouterDynamicConfig) -} - -// getErrorFromECSNotGlobalError returns the underlying error from an ECSNotGlobalError, if it exists. -func getErrorFromECSNotGlobalError(err error) error { - if errors.Is(err, discovery.ErrECSNotGlobal) { - return err.(discovery.ECSNotGlobalError).Unwrap() - } - return err -} - -// parseRequestType inspects the DNS message type and question name to determine the requestType of request. -// We assume by the time this is called, we are responding to a question with a domain we serve. -// This is used internally to determine which query processor method (if any) to invoke. -func parseRequestType(req *dns.Msg) requestType { - switch { - case req.Question[0].Qtype == dns.TypeSOA || req.Question[0].Qtype == dns.TypeNS: - // SOA and NS type supersede the domain - // NOTE!: In V1 of the DNS server it was possible to serve a PTR lookup using the arpa domain but a SOA question type. - // This also included the SOA record. This seemed inconsistent and unnecessary - it was removed for simplicity. - return requestTypeConsul - case isPTRSubdomain(req.Question[0].Name): - return requestTypeIP - case isAddrSubdomain(req.Question[0].Name): - return requestTypeAddress - default: - return requestTypeName - } -} - -// validateAndNormalizeRequest validates the DNS request and normalizes the request name. -func validateAndNormalizeRequest(req *dns.Msg) error { - // like upstream miekg/dns, we require at least one question, - // but we will only answer the first. - if len(req.Question) == 0 { - return errInvalidQuestion - } - - // We mutate the request name to respond with the canonical name. - // This is Consul convention. - req.Question[0].Name = dns.CanonicalName(req.Question[0].Name) - return nil -} - -// normalizeContext makes sure context information is populated with agent defaults as needed. -// Right now this is just the ACL token. We do this in the router with the token because DNS doesn't -// allow a token to be passed in the request, and we expect ACL tokens upfront in APIs when they are enabled. -// Tenancy information is left out because it is safe/expected to assume agent defaults in the backend lookup. -func (r *Router) normalizeContext(ctx *Context) { - if ctx.Token == "" { - ctx.Token = r.tokenFunc() - } -} - -// stripAnyFailoverSuffix strips off the suffixes that may have been added to the request name. -func stripAnyFailoverSuffix(target string) (string, bool) { - enableFailover := false - - // Strip off any suffixes that may have been added. - offset, underflow := dns.PrevLabel(target, 1) - if !underflow { - maybeSuffix := target[offset:] - switch maybeSuffix { - case suffixFailover: - target = target[:offset] - enableFailover = true - case suffixNoFailover: - target = target[:offset] - } - } - return target, enableFailover -} - -// isAddrSubdomain returns true if the domain is a valid addr subdomain. -func isAddrSubdomain(domain string) bool { - labels := dns.SplitDomainName(domain) - - // Looking for .addr..consul. - if len(labels) > 2 { - return labels[1] == addrLabel - } - return false -} - -// isPTRSubdomain returns true if the domain ends in the PTR domain, "in-addr.arpa.". -func isPTRSubdomain(domain string) bool { - labels := dns.SplitDomainName(domain) - labelCount := len(labels) - - // We keep this check brief so we can have more specific error handling later. - if labelCount < 1 { - return false - } - - return labels[labelCount-1] == arpaLabel -} - -// getDynamicRouterConfig takes agent config and creates/resets the config used by DNS Router -func getDynamicRouterConfig(conf *config.RuntimeConfig) (*RouterDynamicConfig, error) { - cfg := &RouterDynamicConfig{ - ARecordLimit: conf.DNSARecordLimit, - EnableTruncate: conf.DNSEnableTruncate, - NodeTTL: conf.DNSNodeTTL, - RecursorStrategy: conf.DNSRecursorStrategy, - RecursorTimeout: conf.DNSRecursorTimeout, - UDPAnswerLimit: conf.DNSUDPAnswerLimit, - NodeMetaTXT: conf.DNSNodeMetaTXT, - DisableCompression: conf.DNSDisableCompression, - SOAConfig: SOAConfig{ - Expire: conf.DNSSOA.Expire, - Minttl: conf.DNSSOA.Minttl, - Refresh: conf.DNSSOA.Refresh, - Retry: conf.DNSSOA.Retry, - }, - } - - if conf.DNSServiceTTL != nil { - cfg.TTLRadix = radix.New() - cfg.TTLStrict = make(map[string]time.Duration) - - for key, ttl := range conf.DNSServiceTTL { - // All suffix with '*' are put in radix - // This include '*' that will match anything - if strings.HasSuffix(key, "*") { - cfg.TTLRadix.Insert(key[:len(key)-1], ttl) - } else { - cfg.TTLStrict[key] = ttl - } - } - } else { - cfg.TTLRadix = nil - cfg.TTLStrict = nil - } - - for _, r := range conf.DNSRecursors { - ra, err := formatRecursorAddress(r) - if err != nil { - return nil, fmt.Errorf("invalid recursor address: %w", err) - } - cfg.Recursors = append(cfg.Recursors, ra) - } - - return cfg, nil -} - -// canRecurse returns true if the router can recurse on the request. -func canRecurse(cfg *RouterDynamicConfig) bool { - return len(cfg.Recursors) > 0 -} diff --git a/agent/dns/router_addr_test.go b/agent/dns/router_addr_test.go deleted file mode 100644 index 2c493bd13e..0000000000 --- a/agent/dns/router_addr_test.go +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" -) - -func Test_HandleRequest_ADDR(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "test A 'addr.' query, ipv4 response", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "c000020a.addr.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("192.0.2.10"), - }, - }, - }, - }, - { - name: "test AAAA 'addr.' query, ipv4 response", - // Since we asked for an AAAA record, the A record that resolves from the address is attached as an extra - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul", - Qtype: dns.TypeAAAA, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul.", - Qtype: dns.TypeAAAA, - Qclass: dns.ClassINET, - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "c000020a.addr.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("192.0.2.10"), - }, - }, - }, - }, - { - name: "test SRV 'addr.' query, ipv4 response", - // Since we asked for a SRV record, the A record that resolves from the address is attached as an extra - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "c000020a.addr.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("192.0.2.10"), - }, - }, - }, - }, - { - name: "test ANY 'addr.' query, ipv4 response", - // The response to ANY should look the same as the A response - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "c000020a.addr.dc1.consul.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "c000020a.addr.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("192.0.2.10"), - }, - }, - }, - }, - { - name: "test AAAA 'addr.' query, ipv6 response", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul", - Qtype: dns.TypeAAAA, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Qtype: dns.TypeAAAA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: 123, - }, - AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), - }, - }, - }, - }, - { - name: "test A 'addr.' query, ipv6 response", - // Since we asked for an A record, the AAAA record that resolves from the address is attached as an extra - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Extra: []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: 123, - }, - AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), - }, - }, - }, - }, - { - name: "test SRV 'addr.' query, ipv6 response", - // Since we asked for an SRV record, the AAAA record that resolves from the address is attached as an extra - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - Extra: []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: 123, - }, - AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), - }, - }, - }, - }, - { - name: "test ANY 'addr.' query, ipv6 response", - // The response to ANY should look the same as the AAAA response - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: "20010db800010002cafe000000001337.addr.dc1.consul.", - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: 123, - }, - AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), - }, - }, - }, - }, - { - name: "test malformed 'addr.' query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "c000.addr.dc1.consul", // too short - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Rcode: dns.RcodeNameError, // NXDOMAIN - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "c000.addr.dc1.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.consul.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.consul.", - Refresh: 1, - Expire: 3, - Retry: 2, - Minttl: 4, - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_ns_test.go b/agent/dns/router_ns_test.go deleted file mode 100644 index 0011ac8626..0000000000 --- a/agent/dns/router_ns_test.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" -) - -func Test_HandleRequest_NS(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "vanilla NS query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "consul.", - Qtype: dns.TypeNS, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return([]*discovery.Result{ - { - Node: &discovery.Location{Name: "server-one", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - { - Node: &discovery.Location{Name: "server-two", Address: "4.5.6.7"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - }, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, discovery.LookupTypeService, reqType) - require.Equal(t, structs.ConsulServiceName, req.Name) - require.Equal(t, 3, req.Limit) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "consul.", - Qtype: dns.TypeNS, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-one.workload.default.ns.default.ap.consul.", - }, - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-two.workload.default.ns.default.ap.consul.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-one.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-two.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("4.5.6.7"), - }, - }, - }, - }, - { - name: "NS query against alternate domain", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "testdomain.", - Qtype: dns.TypeNS, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSDomain: "consul", - DNSAltDomain: "testdomain", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return([]*discovery.Result{ - { - Node: &discovery.Location{Name: "server-one", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - { - Node: &discovery.Location{Name: "server-two", Address: "4.5.6.7"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - }, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, discovery.LookupTypeService, reqType) - require.Equal(t, structs.ConsulServiceName, req.Name) - require.Equal(t, 3, req.Limit) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "testdomain.", - Qtype: dns.TypeNS, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-one.workload.default.ns.default.ap.testdomain.", - }, - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-two.workload.default.ns.default.ap.testdomain.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-one.workload.default.ns.default.ap.testdomain.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-two.workload.default.ns.default.ap.testdomain.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("4.5.6.7"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_prepared_query_test.go b/agent/dns/router_prepared_query_test.go deleted file mode 100644 index ff33395a5e..0000000000 --- a/agent/dns/router_prepared_query_test.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" -) - -func Test_HandleRequest_PreparedQuery(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "v1 prepared query w/ TTL override, ANY query, returns A record", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSDomain: "consul", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - // We shouldn't use this if we have the override defined - DNSServiceTTL: map[string]time.Duration{ - "foo": 1 * time.Second, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchPreparedQuery", mock.Anything, mock.Anything). - Return([]*discovery.Result{ - { - Service: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Node: &discovery.Location{Name: "bar", Address: "1.2.3.4"}, - Type: discovery.ResultTypeService, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc1", - }, - DNS: discovery.DNSConfig{ - TTL: getUint32Ptr(3), - Weight: 1, - }, - }, - }, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - require.Equal(t, "foo", req.Name) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.query.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.query.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 3, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "v1 prepared query w/ matching service TTL, ANY query, returns A record", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.query.dc1.cluster.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSDomain: "consul", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - // Results should use this as the TTL - DNSServiceTTL: map[string]time.Duration{ - "foo": 1 * time.Second, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchPreparedQuery", mock.Anything, mock.Anything). - Return([]*discovery.Result{ - { - Service: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Node: &discovery.Location{Name: "bar", Address: "1.2.3.4"}, - Type: discovery.ResultTypeService, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc1", - }, - DNS: discovery.DNSConfig{ - // Intentionally no TTL here. - Weight: 1, - }, - }, - }, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - require.Equal(t, "foo", req.Name) - require.Equal(t, "dc1", req.Tenancy.Datacenter) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.query.dc1.cluster.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.query.dc1.cluster.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 1, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_ptr_test.go b/agent/dns/router_ptr_test.go deleted file mode 100644 index 7704e350d1..0000000000 --- a/agent/dns/router_ptr_test.go +++ /dev/null @@ -1,563 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/discovery" -) - -func Test_HandleRequest_PTR(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "PTR lookup for node, query type is ANY", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Service: &discovery.Location{Name: "bar", Address: "foo"}, - Type: discovery.ResultTypeNode, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "1.2.3.4", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "4.3.2.1.in-addr.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.node.dc2.consul.", - }, - }, - }, - }, - { - name: "PTR lookup for IPV6 node", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo", Address: "2001:db8::567:89ab"}, - Service: &discovery.Location{Name: "web", Address: "foo"}, - Type: discovery.ResultTypeNode, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "2001:db8::567:89ab", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.node.dc2.consul.", - }, - }, - }, - }, - { - name: "PTR lookup for invalid IP address", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "257.3.2.1.in-addr.arpa", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "257.3.2.1.in-addr.arpa.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.consul.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.consul.", - Refresh: 1, - Expire: 3, - Retry: 2, - Minttl: 4, - }, - }, - }, - }, - { - name: "PTR lookup for invalid subdomain", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.blah.arpa", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeNameError, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.blah.arpa.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.consul.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.consul.", - Refresh: 1, - Expire: 3, - Retry: 2, - Minttl: 4, - }, - }, - }, - }, - { - name: "[ENT] PTR Lookup for node w/ peer name in default partition, query type is ANY", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Type: discovery.ResultTypeNode, - Service: &discovery.Location{Name: "foo-web", Address: "foo"}, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - PeerName: "peer1", - Partition: "default", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "1.2.3.4", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "4.3.2.1.in-addr.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.node.peer1.peer.default.ap.consul.", - }, - }, - }, - }, - { - name: "[ENT] PTR Lookup for service in default namespace, query type is PTR", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Type: discovery.ResultTypeService, - Service: &discovery.Location{Name: "foo", Address: "foo"}, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - Namespace: "default", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "1.2.3.4", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa.", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "4.3.2.1.in-addr.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.service.default.dc2.consul.", - }, - }, - }, - }, - { - name: "[ENT] PTR Lookup for service in a non-default namespace, query type is PTR", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo-node", Address: "1.2.3.4"}, - Type: discovery.ResultTypeService, - Service: &discovery.Location{Name: "foo", Address: "foo"}, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - Namespace: "bar", - Partition: "baz", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "1.2.3.4", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa.", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "4.3.2.1.in-addr.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.service.bar.dc2.consul.", - }, - }, - }, - }, - { - name: "[CE] PTR Lookup for node w/ peer name, query type is ANY", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Type: discovery.ResultTypeNode, - Service: &discovery.Location{Name: "foo", Address: "foo"}, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - PeerName: "peer1", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "1.2.3.4", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "4.3.2.1.in-addr.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.node.peer1.peer.consul.", - }, - }, - }, - }, - { - name: "[CE] PTR Lookup for service, query type is PTR", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Service: &discovery.Location{Name: "foo", Address: "foo"}, - Type: discovery.ResultTypeService, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc2", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchRecordsByIp", mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(net.IP) - - require.NotNil(t, req) - require.Equal(t, "1.2.3.4", req.String()) - }) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "4.3.2.1.in-addr.arpa.", - Qtype: dns.TypePTR, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.PTR{ - Hdr: dns.RR_Header{ - Name: "4.3.2.1.in-addr.arpa.", - Rrtype: dns.TypePTR, - Class: dns.ClassINET, - }, - Ptr: "foo.service.dc2.consul.", - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_recursor_test.go b/agent/dns/router_recursor_test.go deleted file mode 100644 index b5e4c029c0..0000000000 --- a/agent/dns/router_recursor_test.go +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "errors" - "github.com/hashicorp/consul/agent/config" - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "net" - "testing" -) - -func Test_HandleRequest_recursor(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "recursors not configured, non-matching domain", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "google.com", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - // configureRecursor: call not expected. - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Rcode: dns.RcodeRefused, - }, - Question: []dns.Question{ - { - Name: "google.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - }, - { - name: "recursors configured, matching domain", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "google.com", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - resp := &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "google.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "google.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - } - recursor.(*mockDnsRecursor).On("handle", - mock.Anything, mock.Anything, mock.Anything).Return(resp, nil) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "google.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "google.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "recursors configured, no matching domain", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "google.com", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - recursor.(*mockDnsRecursor).On("handle", mock.Anything, mock.Anything, mock.Anything). - Return(nil, errRecursionFailed) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: false, - Rcode: dns.RcodeServerFailure, - RecursionAvailable: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "google.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - }, - { - name: "recursors configured, unhandled error calling recursors", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "google.com", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - err := errors.New("ahhhhh!!!!") - recursor.(*mockDnsRecursor).On("handle", mock.Anything, mock.Anything, mock.Anything). - Return(nil, err) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: false, - Rcode: dns.RcodeServerFailure, - RecursionAvailable: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "google.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - }, - { - name: "recursors configured, the root domain is handled by the recursor", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: ".", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - // this response is modeled after `dig .` - resp := &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: ".", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: ".", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 86391, - }, - Ns: "a.root-servers.net.", - Serial: 2024012200, - Mbox: "nstld.verisign-grs.com.", - Refresh: 1800, - Retry: 900, - Expire: 604800, - Minttl: 86400, - }, - }, - } - recursor.(*mockDnsRecursor).On("handle", - mock.Anything, mock.Anything, mock.Anything).Return(resp, nil) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: ".", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: ".", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 86391, - }, - Ns: "a.root-servers.net.", - Serial: 2024012200, - Mbox: "nstld.verisign-grs.com.", - Refresh: 1800, - Retry: 900, - Expire: 604800, - Minttl: 86400, - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_service_test.go b/agent/dns/router_service_test.go deleted file mode 100644 index 0738d376e1..0000000000 --- a/agent/dns/router_service_test.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/discovery" -) - -func Test_HandleRequest_ServiceQuestions(t *testing.T) { - testCases := []HandleTestCase{ - // Service Lookup - { - name: "When no data is return from a query, send SOA", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(nil, discovery.ErrNoData). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, discovery.LookupTypeService, reqType) - require.Equal(t, "foo", req.Name) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Ns: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.consul.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.consul.", - Refresh: 1, - Expire: 3, - Retry: 2, - Minttl: 4, - }, - }, - }, - }, - { - // TestDNS_ExternalServiceToConsulCNAMELookup - name: "req type: service / question type: SRV / CNAME required: no", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "alias.service.consul.", - Qtype: dns.TypeSRV, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, - &discovery.QueryPayload{ - Name: "alias", - Tenancy: discovery.QueryTenancy{}, - }, discovery.LookupTypeService). - Return([]*discovery.Result{ - { - Type: discovery.ResultTypeVirtual, - Service: &discovery.Location{Name: "alias", Address: "web.service.consul"}, - Node: &discovery.Location{Name: "web", Address: "web.service.consul"}, - }, - }, - nil).On("FetchEndpoints", mock.Anything, - &discovery.QueryPayload{ - Name: "web", - Tenancy: discovery.QueryTenancy{}, - }, discovery.LookupTypeService). - Return([]*discovery.Result{ - { - Type: discovery.ResultTypeNode, - Service: &discovery.Location{Name: "web", Address: "webnode"}, - Node: &discovery.Location{Name: "webnode", Address: "127.0.0.2"}, - }, - }, nil).On("ValidateRequest", mock.Anything, - mock.Anything).Return(nil).On("NormalizeRequest", mock.Anything) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "alias.service.consul.", - Qtype: dns.TypeSRV, - }, - }, - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "alias.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: 123, - }, - Target: "web.service.consul.", - Priority: 1, - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "web.service.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("127.0.0.2"), - }, - }, - }, - }, - { - name: "req type: service / question type: SRV / CNAME required: no - multiple results without Node address + tags", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "tag.foo.service.consul.", - Qtype: dns.TypeSRV, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, - &discovery.QueryPayload{ - Name: "foo", - Tenancy: discovery.QueryTenancy{}, - Tag: "tag", - }, discovery.LookupTypeService). - Return([]*discovery.Result{ - { - // This result emulates an allocation registration with Nomad. - // The node name is generated by Consul and shares the service IP - Type: discovery.ResultTypeService, - Service: &discovery.Location{Name: "foo", Address: "127.0.0.1"}, - Node: &discovery.Location{Name: "Node-9e46a487-f5be-2f40-ad60-5a10e32237ed", Address: "127.0.0.1"}, - Tenancy: discovery.ResultTenancy{ - Datacenter: "dc1", - }, - }, - }, - nil).On("ValidateRequest", mock.Anything, - mock.Anything).Return(nil).On("NormalizeRequest", mock.Anything) - }, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "tag.foo.service.consul.", - Qtype: dns.TypeSRV, - }, - }, - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "tag.foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: 123, - }, - Target: "7f000001.addr.dc1.consul.", - Priority: 1, - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "7f000001.addr.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("127.0.0.1"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_soa_test.go b/agent/dns/router_soa_test.go deleted file mode 100644 index f578a4abe3..0000000000 --- a/agent/dns/router_soa_test.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" -) - -func Test_HandleRequest_SOA(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "vanilla SOA query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "consul.", - Qtype: dns.TypeSOA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return([]*discovery.Result{ - { - Node: &discovery.Location{Name: "server-one", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - { - Node: &discovery.Location{Name: "server-two", Address: "4.5.6.7"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - }, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, discovery.LookupTypeService, reqType) - require.Equal(t, structs.ConsulServiceName, req.Name) - require.Equal(t, 3, req.Limit) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "consul.", - Qtype: dns.TypeSOA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.consul.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.consul.", - Refresh: 1, - Expire: 3, - Retry: 2, - Minttl: 4, - }, - }, - Ns: []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-one.workload.default.ns.default.ap.consul.", - }, - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "consul.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-two.workload.default.ns.default.ap.consul.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-one.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-two.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("4.5.6.7"), - }, - }, - }, - }, - { - name: "SOA query against alternate domain", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "testdomain.", - Qtype: dns.TypeSOA, - Qclass: dns.ClassINET, - }, - }, - }, - agentConfig: &config.RuntimeConfig{ - DNSDomain: "consul", - DNSAltDomain: "testdomain", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return([]*discovery.Result{ - { - Node: &discovery.Location{Name: "server-one", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - }, - { - Node: &discovery.Location{Name: "server-two", Address: "4.5.6.7"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }}, - }, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, discovery.LookupTypeService, reqType) - require.Equal(t, structs.ConsulServiceName, req.Name) - require.Equal(t, 3, req.Limit) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "testdomain.", - Qtype: dns.TypeSOA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SOA{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - Ttl: 4, - }, - Ns: "ns.testdomain.", - Serial: uint32(time.Now().Unix()), - Mbox: "hostmaster.testdomain.", - Refresh: 1, - Expire: 3, - Retry: 2, - Minttl: 4, - }, - }, - Ns: []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-one.workload.default.ns.default.ap.testdomain.", - }, - &dns.NS{ - Hdr: dns.RR_Header{ - Name: "testdomain.", - Rrtype: dns.TypeNS, - Class: dns.ClassINET, - Ttl: 123, - }, - Ns: "server-two.workload.default.ns.default.ap.testdomain.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-one.workload.default.ns.default.ap.testdomain.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "server-two.workload.default.ns.default.ap.testdomain.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("4.5.6.7"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_test.go b/agent/dns/router_test.go deleted file mode 100644 index 717ee9e16b..0000000000 --- a/agent/dns/router_test.go +++ /dev/null @@ -1,842 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "fmt" - "net" - "reflect" - "testing" - "time" - - "github.com/armon/go-radix" - - "github.com/hashicorp/consul/internal/dnsutil" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/agent/structs" -) - -// HandleTestCase is a test case for the HandleRequest function. -// Tests for HandleRequest are split into multiple files to make it easier to -// manage and understand the tests. Other test files are: -// - router_addr_test.go -// - router_ns_test.go -// - router_prepared_query_test.go -// - router_ptr_test.go -// - router_recursor_test.go -// - router_service_test.go -// - router_soa_test.go -// - router_virtual_test.go -// - router_v2_services_test.go -// - router_workload_test.go -type HandleTestCase struct { - name string - agentConfig *config.RuntimeConfig // This will override the default test Router Config - configureDataFetcher func(fetcher discovery.CatalogDataFetcher) - validateAndNormalizeExpected bool - configureRecursor func(recursor dnsRecursor) - mockProcessorError error - request *dns.Msg - requestContext *Context - remoteAddress net.Addr - response *dns.Msg -} - -func Test_HandleRequest_Validation(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "request with empty message", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{}, - }, - validateAndNormalizeExpected: false, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: false, - Rcode: dns.RcodeRefused, - }, - Compress: false, - Question: nil, - Answer: nil, - Ns: nil, - Extra: nil, - }, - }, - // Context Tests - { - name: "When a request context is provided, use those field in the query", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - requestContext: &Context{ - Token: "test-token", - DefaultNamespace: "test-namespace", - DefaultPartition: "test-partition", - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := []*discovery.Result{ - { - Type: discovery.ResultTypeNode, - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Tenancy: discovery.ResultTenancy{ - Namespace: "test-namespace", - Partition: "test-partition", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(result, nil). - Run(func(args mock.Arguments) { - ctx := args.Get(0).(discovery.Context) - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "test-token", ctx.Token) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "test-namespace", req.Tenancy.Namespace) - require.Equal(t, "test-partition", req.Tenancy.Partition) - - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "When a request context is provided, values do not override explicit tenancy", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.bar.ns.baz.ap.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - requestContext: &Context{ - Token: "test-token", - DefaultNamespace: "test-namespace", - DefaultPartition: "test-partition", - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := []*discovery.Result{ - { - Type: discovery.ResultTypeNode, - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Tenancy: discovery.ResultTenancy{ - Namespace: "bar", - Partition: "baz", - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(result, nil). - Run(func(args mock.Arguments) { - ctx := args.Get(0).(discovery.Context) - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "test-token", ctx.Token) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "bar", req.Tenancy.Namespace) - require.Equal(t, "baz", req.Tenancy.Partition) - - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.bar.ns.baz.ap.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.service.bar.ns.baz.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} - -// runHandleTestCases runs the test cases for the HandleRequest function. -func runHandleTestCases(t *testing.T, tc HandleTestCase) { - cdf := discovery.NewMockCatalogDataFetcher(t) - if tc.validateAndNormalizeExpected { - cdf.On("ValidateRequest", mock.Anything, mock.Anything).Return(nil) - cdf.On("NormalizeRequest", mock.Anything).Return() - } - - if tc.configureDataFetcher != nil { - tc.configureDataFetcher(cdf) - } - cfg := buildDNSConfig(tc.agentConfig, cdf, tc.mockProcessorError) - - router, err := NewRouter(cfg) - require.NoError(t, err) - - // Replace the recursor with a mock and configure - router.recursor = newMockDnsRecursor(t) - if tc.configureRecursor != nil { - tc.configureRecursor(router.recursor) - } - - ctx := tc.requestContext - if ctx == nil { - ctx = &Context{} - } - - var remoteAddress net.Addr - if tc.remoteAddress != nil { - remoteAddress = tc.remoteAddress - } else { - remoteAddress = &net.UDPAddr{} - } - - actual := router.HandleRequest(tc.request, *ctx, remoteAddress) - require.Equal(t, tc.response, actual) -} - -func TestRouterDynamicConfig_GetTTLForService(t *testing.T) { - type testCase struct { - name string - inputKey string - shouldMatch bool - expectedDuration time.Duration - } - - testCases := []testCase{ - { - name: "strict match", - inputKey: "foo", - shouldMatch: true, - expectedDuration: 1 * time.Second, - }, - { - name: "wildcard match", - inputKey: "bar", - shouldMatch: true, - expectedDuration: 2 * time.Second, - }, - { - name: "wildcard match 2", - inputKey: "bart", - shouldMatch: true, - expectedDuration: 2 * time.Second, - }, - { - name: "no match", - inputKey: "homer", - shouldMatch: false, - expectedDuration: 0 * time.Second, - }, - } - - rtCfg := &config.RuntimeConfig{ - DNSServiceTTL: map[string]time.Duration{ - "foo": 1 * time.Second, - "bar*": 2 * time.Second, - }, - } - cfg, err := getDynamicRouterConfig(rtCfg) - require.NoError(t, err) - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual, ok := cfg.GetTTLForService(tc.inputKey) - require.Equal(t, tc.shouldMatch, ok) - require.Equal(t, tc.expectedDuration, actual) - }) - } -} -func buildDNSConfig(agentConfig *config.RuntimeConfig, cdf discovery.CatalogDataFetcher, _ error) Config { - cfg := Config{ - AgentConfig: &config.RuntimeConfig{ - DNSDomain: "consul", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - EntMeta: acl.EnterpriseMeta{}, - Logger: hclog.NewNullLogger(), - Processor: discovery.NewQueryProcessor(cdf), - TokenFunc: func() string { return "" }, - TranslateServiceAddressFunc: func(dc string, address string, taggedAddresses map[string]structs.ServiceAddress, accept dnsutil.TranslateAddressAccept) string { - return address - }, - TranslateAddressFunc: func(dc string, addr string, taggedAddresses map[string]string, accept dnsutil.TranslateAddressAccept) string { - return addr - }, - } - - if agentConfig != nil { - cfg.AgentConfig = agentConfig - } - - return cfg -} - -// TestDNS_BinaryTruncate tests the dnsBinaryTruncate function. -func TestDNS_BinaryTruncate(t *testing.T) { - msgSrc := new(dns.Msg) - msgSrc.Compress = true - msgSrc.SetQuestion("redis.service.consul.", dns.TypeSRV) - - for i := 0; i < 5000; i++ { - target := fmt.Sprintf("host-redis-%d-%d.test.acme.com.node.dc1.consul.", i/256, i%256) - msgSrc.Answer = append(msgSrc.Answer, &dns.SRV{Hdr: dns.RR_Header{Name: "redis.service.consul.", Class: 1, Rrtype: dns.TypeSRV, Ttl: 0x3c}, Port: 0x4c57, Target: target}) - msgSrc.Extra = append(msgSrc.Extra, &dns.CNAME{Hdr: dns.RR_Header{Name: target, Class: 1, Rrtype: dns.TypeCNAME, Ttl: 0x3c}, Target: fmt.Sprintf("fx.168.%d.%d.", i/256, i%256)}) - } - for _, compress := range []bool{true, false} { - for idx, maxSize := range []int{12, 256, 512, 8192, 65535} { - t.Run(fmt.Sprintf("binarySearch %d", maxSize), func(t *testing.T) { - msg := new(dns.Msg) - msgSrc.Compress = compress - msgSrc.SetQuestion("redis.service.consul.", dns.TypeSRV) - msg.Answer = msgSrc.Answer - msg.Extra = msgSrc.Extra - msg.Ns = msgSrc.Ns - index := make(map[string]dns.RR, len(msg.Extra)) - indexRRs(msg.Extra, index) - blen := dnsBinaryTruncate(msg, maxSize, index, true) - msg.Answer = msg.Answer[:blen] - syncExtra(index, msg) - predicted := msg.Len() - buf, err := msg.Pack() - if err != nil { - t.Error(err) - } - if predicted < len(buf) { - t.Fatalf("Bug in DNS library: %d != %d", predicted, len(buf)) - } - if len(buf) > maxSize || (idx != 0 && len(buf) < 16) { - t.Fatalf("bad[%d]: %d > %d", idx, len(buf), maxSize) - } - }) - } - } -} - -// TestDNS_syncExtra tests the syncExtra function. -func TestDNS_syncExtra(t *testing.T) { - resp := &dns.Msg{ - Answer: []dns.RR{ - // These two are on the same host so the redundant extra - // records should get deduplicated. - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Port: 1001, - Target: "ip-10-0-1-185.node.dc1.consul.", - }, - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Port: 1002, - Target: "ip-10-0-1-185.node.dc1.consul.", - }, - // This one isn't in the Consul domain so it will get a - // CNAME and then an A record from the recursor. - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Port: 1003, - Target: "demo.consul.io.", - }, - // This one isn't in the Consul domain and it will get - // a CNAME and A record from a recursor that alters the - // case of the name. This proves we look up in the index - // in a case-insensitive way. - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Port: 1001, - Target: "insensitive.consul.io.", - }, - // This is also a CNAME, but it'll be set up to loop to - // make sure we don't crash. - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Port: 1001, - Target: "deadly.consul.io.", - }, - // This is also a CNAME, but it won't have another record. - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Port: 1001, - Target: "nope.consul.io.", - }, - }, - Extra: []dns.RR{ - // These should get deduplicated. - &dns.A{ - Hdr: dns.RR_Header{ - Name: "ip-10-0-1-185.node.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("10.0.1.185"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "ip-10-0-1-185.node.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("10.0.1.185"), - }, - // This is a normal CNAME followed by an A record but we - // have flipped the order. The algorithm should emit them - // in the opposite order. - &dns.A{ - Hdr: dns.RR_Header{ - Name: "fakeserver.consul.io.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("127.0.0.1"), - }, - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "demo.consul.io.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "fakeserver.consul.io.", - }, - // These differ in case to test case insensitivity. - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "INSENSITIVE.CONSUL.IO.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "Another.Server.Com.", - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "another.server.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("127.0.0.1"), - }, - // This doesn't appear in the answer, so should get - // dropped. - &dns.A{ - Hdr: dns.RR_Header{ - Name: "ip-10-0-1-186.node.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("10.0.1.186"), - }, - // These two test edge cases with CNAME handling. - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "deadly.consul.io.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "deadly.consul.io.", - }, - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "nope.consul.io.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "notthere.consul.io.", - }, - }, - } - - index := make(map[string]dns.RR) - indexRRs(resp.Extra, index) - syncExtra(index, resp) - - expected := &dns.Msg{ - Answer: resp.Answer, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "ip-10-0-1-185.node.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("10.0.1.185"), - }, - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "demo.consul.io.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "fakeserver.consul.io.", - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "fakeserver.consul.io.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("127.0.0.1"), - }, - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "INSENSITIVE.CONSUL.IO.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "Another.Server.Com.", - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "another.server.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("127.0.0.1"), - }, - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "deadly.consul.io.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "deadly.consul.io.", - }, - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "nope.consul.io.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - Target: "notthere.consul.io.", - }, - }, - } - if !reflect.DeepEqual(resp, expected) { - t.Fatalf("Bad %#v vs. %#v", *resp, *expected) - } -} - -// getUint32Ptr return the pointer of an uint32 literal -func getUint32Ptr(i uint32) *uint32 { - return &i -} - -func TestRouter_ReloadConfig(t *testing.T) { - cdf := discovery.NewMockCatalogDataFetcher(t) - cfg := buildDNSConfig(nil, cdf, nil) - router, err := NewRouter(cfg) - require.NoError(t, err) - - router.recursor = newMockDnsRecursor(t) - - // Reload the config - newAgentConfig := &config.RuntimeConfig{ - DNSARecordLimit: 123, - DNSEnableTruncate: true, - DNSNodeTTL: 234, - DNSRecursorStrategy: "strategy-123", - DNSRecursorTimeout: 345, - DNSUDPAnswerLimit: 456, - DNSNodeMetaTXT: true, - DNSDisableCompression: true, - DNSSOA: config.RuntimeSOAConfig{ - Expire: 123, - Minttl: 234, - Refresh: 345, - Retry: 456, - }, - DNSServiceTTL: map[string]time.Duration{ - "wildcard-config-*": 123, - "strict-config": 234, - }, - DNSRecursors: []string{ - "8.8.8.8", - "2001:4860:4860::8888", - }, - } - - expectTTLRadix := radix.New() - expectTTLRadix.Insert("wildcard-config-", time.Duration(123)) - - expectedCfg := &RouterDynamicConfig{ - ARecordLimit: 123, - EnableTruncate: true, - NodeTTL: 234, - RecursorStrategy: "strategy-123", - RecursorTimeout: 345, - UDPAnswerLimit: 456, - NodeMetaTXT: true, - DisableCompression: true, - SOAConfig: SOAConfig{ - Expire: 123, - Minttl: 234, - Refresh: 345, - Retry: 456, - }, - TTLRadix: expectTTLRadix, - TTLStrict: map[string]time.Duration{ - "strict-config": 234, - }, - Recursors: []string{ - "8.8.8.8:53", - "[2001:4860:4860::8888]:53", - }, - } - err = router.ReloadConfig(newAgentConfig) - require.NoError(t, err) - savedCfg := router.dynamicConfig.Load().(*RouterDynamicConfig) - - // Ensure the new config is used - require.Equal(t, expectedCfg, savedCfg) -} - -func Test_isPTRSubdomain(t *testing.T) { - testCases := []struct { - name string - domain string - expected bool - }{ - { - name: "empty domain returns false", - domain: "", - expected: false, - }, - { - name: "last label is 'arpa' returns true", - domain: "my-addr.arpa.", - expected: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := isPTRSubdomain(tc.domain) - require.Equal(t, tc.expected, actual) - }) - } -} - -func Test_isAddrSubdomain(t *testing.T) { - testCases := []struct { - name string - domain string - expected bool - }{ - { - name: "empty domain returns false", - domain: "", - expected: false, - }, - { - name: "'c000020a.addr.dc1.consul.' returns true", - domain: "c000020a.addr.dc1.consul.", - expected: true, - }, - { - name: "'c000020a.addr.consul.' returns true", - domain: "c000020a.addr.consul.", - expected: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := isAddrSubdomain(tc.domain) - require.Equal(t, tc.expected, actual) - }) - } -} - -func Test_stripAnyFailoverSuffix(t *testing.T) { - testCases := []struct { - name string - target string - expectedEnableFailover bool - expectedResult string - }{ - { - name: "my-addr.service.dc1.consul.failover. returns 'my-addr.service.dc1.consul' and true", - target: "my-addr.service.dc1.consul.failover.", - expectedEnableFailover: true, - expectedResult: "my-addr.service.dc1.consul.", - }, - { - name: "my-addr.service.dc1.consul.no-failover. returns 'my-addr.service.dc1.consul' and false", - target: "my-addr.service.dc1.consul.no-failover.", - expectedEnableFailover: false, - expectedResult: "my-addr.service.dc1.consul.", - }, - { - name: "my-addr.service.dc1.consul. returns 'my-addr.service.dc1.consul' and false", - target: "my-addr.service.dc1.consul.", - expectedEnableFailover: false, - expectedResult: "my-addr.service.dc1.consul.", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual, actualEnableFailover := stripAnyFailoverSuffix(tc.target) - require.Equal(t, tc.expectedEnableFailover, actualEnableFailover) - require.Equal(t, tc.expectedResult, actual) - }) - } -} - -func Test_trimDomain(t *testing.T) { - testCases := []struct { - name string - domain string - altDomain string - questionName string - expectedResult string - }{ - { - name: "given domain is 'consul.' and altDomain is 'my.consul.', when calling trimDomain with 'my-service.my.consul.', it returns 'my-service.'", - questionName: "my-service.my.consul.", - domain: "consul.", - altDomain: "my.consul.", - expectedResult: "my-service.", - }, - { - name: "given domain is 'consul.' and altDomain is 'my.consul.', when calling trimDomain with 'my-service.consul.', it returns 'my-service.'", - questionName: "my-service.consul.", - domain: "consul.", - altDomain: "my.consul.", - expectedResult: "my-service.", - }, - { - name: "given domain is 'consul.' and altDomain is 'my-consul.', when calling trimDomain with 'my-service.consul.', it returns 'my-service.'", - questionName: "my-service.consul.", - domain: "consul.", - altDomain: "my-consul.", - expectedResult: "my-service.", - }, - { - name: "given domain is 'consul.' and altDomain is 'my-consul.', when calling trimDomain with 'my-service.my-consul.', it returns 'my-service.'", - questionName: "my-service.my-consul.", - domain: "consul.", - altDomain: "my-consul.", - expectedResult: "my-service.", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - router := Router{ - domain: tc.domain, - altDomain: tc.altDomain, - } - actual := router.trimDomain(tc.questionName) - require.Equal(t, tc.expectedResult, actual) - }) - } -} diff --git a/agent/dns/router_v2_services_test.go b/agent/dns/router_v2_services_test.go deleted file mode 100644 index 7b7b84f32a..0000000000 --- a/agent/dns/router_v2_services_test.go +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" - "github.com/hashicorp/consul/internal/resource" -) - -func Test_HandleRequest_V2Services(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "A/AAAA Query a service and return multiple A records", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo-1", Address: "10.0.0.1"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - // Intentionally not in the mesh - }, - DNS: discovery.DNSConfig{ - Weight: 2, - }, - }, - { - Node: &discovery.Location{Name: "foo-2", Address: "10.0.0.2"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - DNS: discovery.DNSConfig{ - Weight: 3, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "foo", req.Name) - require.Empty(t, req.PortName) - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("10.0.0.1"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("10.0.0.2"), - }, - }, - }, - }, - { - name: "SRV Query with a multi-port service return multiple SRV records", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo-1", Address: "10.0.0.1"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - // Intentionally not in the mesh - }, - DNS: discovery.DNSConfig{ - Weight: 2, - }, - }, - { - Node: &discovery.Location{Name: "foo-2", Address: "10.0.0.2"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "mesh", - Number: 21000, - }, - }, - DNS: discovery.DNSConfig{ - Weight: 3, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "foo", req.Name) - require.Empty(t, req.PortName) - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 2, - Priority: 1, - Port: 5678, - Target: "api.port.foo-1.workload.default.ns.default.ap.consul.", - }, - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 3, - Priority: 1, - Port: 5678, - Target: "api.port.foo-2.workload.default.ns.default.ap.consul.", - }, - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 3, - Priority: 1, - Port: 21000, - Target: "mesh.port.foo-2.workload.default.ns.default.ap.consul.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "api.port.foo-1.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("10.0.0.1"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "api.port.foo-2.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("10.0.0.2"), - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "mesh.port.foo-2.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("10.0.0.2"), - }, - }, - }, - }, - { - name: "SRV Query with a multi-port service where the client requests a specific port, returns SRV and A records", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "mesh.port.foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo-2", Address: "10.0.0.2"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "mesh", - Number: 21000, - }, - }, - DNS: discovery.DNSConfig{ - Weight: 3, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "mesh", req.PortName) - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "mesh.port.foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "mesh.port.foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 3, - Priority: 1, - Port: 21000, - Target: "mesh.port.foo-2.workload.default.ns.default.ap.consul.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "mesh.port.foo-2.workload.default.ns.default.ap.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("10.0.0.2"), - }, - }, - }, - }, - { - name: "SRV Query with a multi-port service that has workloads w/ hostnames (no recursors)", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo-1", Address: "foo-1.example.com"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "web", - Number: 8080, - }, - }, - DNS: discovery.DNSConfig{ - Weight: 2, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "foo", req.Name) - require.Empty(t, req.PortName) - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 2, - Priority: 1, - Port: 5678, - Target: "foo-1.example.com.", - }, - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 2, - Priority: 1, - Port: 8080, - Target: "foo-1.example.com.", - }, - }, - }, - }, - { - name: "SRV Query with a multi-port service that has workloads w/ hostnames (with recursor)", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - results := []*discovery.Result{ - { - Node: &discovery.Location{Name: "foo-1", Address: "foo-1.example.com"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: resource.DefaultNamespaceName, - Partition: resource.DefaultPartitionName, - }, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - { - Name: "web", - Number: 8080, - }, - }, - DNS: discovery.DNSConfig{ - Weight: 2, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchEndpoints", mock.Anything, mock.Anything, mock.Anything). - Return(results, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - reqType := args.Get(2).(discovery.LookupType) - - require.Equal(t, "foo", req.Name) - require.Empty(t, req.PortName) - require.Equal(t, discovery.LookupTypeService, reqType) - }) - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSDomain: "consul", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - resp := &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo-1.example.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo-1.example.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - } - recursor.(*mockDnsRecursor).On("handle", - mock.Anything, mock.Anything, mock.Anything).Return(resp, nil) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - RecursionAvailable: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.service.consul.", - Qtype: dns.TypeSRV, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 2, - Priority: 1, - Port: 5678, - Target: "foo-1.example.com.", - }, - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "foo.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - Weight: 2, - Priority: 1, - Port: 8080, - Target: "foo-1.example.com.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo-1.example.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("1.2.3.4"), - }, - // TODO (v2-dns): This needs to be de-duplicated (NET-8064) - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo-1.example.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: uint32(123), - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_virtual_test.go b/agent/dns/router_virtual_test.go deleted file mode 100644 index 5d70425e0e..0000000000 --- a/agent/dns/router_virtual_test.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "github.com/hashicorp/consul/agent/discovery" - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "net" - "testing" -) - -func Test_HandleRequest_Virtual(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "test A 'virtual.' query, ipv4 response", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "c000020a.virtual.dc1.consul", // "intentionally missing the trailing dot" - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher).On("FetchVirtualIP", - mock.Anything, mock.Anything).Return(&discovery.Result{ - Node: &discovery.Location{Address: "240.0.0.2"}, - Type: discovery.ResultTypeVirtual, - }, nil) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "c000020a.virtual.dc1.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "c000020a.virtual.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("240.0.0.2"), - }, - }, - }, - }, - { - name: "test A 'virtual.' query, ipv6 response", - // Since we asked for an A record, the AAAA record that resolves from the address is attached as an extra - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.virtual.dc1.consul", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - fetcher.(*discovery.MockCatalogDataFetcher).On("FetchVirtualIP", - mock.Anything, mock.Anything).Return(&discovery.Result{ - Node: &discovery.Location{Address: "2001:db8:1:2:cafe::1337"}, - Type: discovery.ResultTypeVirtual, - }, nil) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "20010db800010002cafe000000001337.virtual.dc1.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Extra: []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{ - Name: "20010db800010002cafe000000001337.virtual.dc1.consul.", - Rrtype: dns.TypeAAAA, - Class: dns.ClassINET, - Ttl: 123, - }, - AAAA: net.ParseIP("2001:db8:1:2:cafe::1337"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/router_workload_test.go b/agent/dns/router_workload_test.go deleted file mode 100644 index 04170a495c..0000000000 --- a/agent/dns/router_workload_test.go +++ /dev/null @@ -1,515 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "net" - "testing" - "time" - - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/agent/discovery" -) - -func Test_HandleRequest_workloads(t *testing.T) { - testCases := []HandleTestCase{ - { - name: "workload A query w/ port, returns A record", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := &discovery.Result{ - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{}, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchWorkload", mock.Anything, mock.Anything). - Return(result, nil). //TODO - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "api", req.PortName) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "api.port.foo.workload.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "workload ANY query w/o port, returns A record", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.workload.consul.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := &discovery.Result{ - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{}, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchWorkload", mock.Anything, mock.Anything). - Return(result, nil). //TODO - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - - require.Equal(t, "foo", req.Name) - require.Empty(t, req.PortName) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.workload.consul.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.workload.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "workload A query with namespace, partition, and cluster id; IPV4 address; returns A record", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "foo.workload.bar.ns.baz.ap.dc3.dc.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := &discovery.Result{ - Node: &discovery.Location{Name: "foo", Address: "1.2.3.4"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{ - Namespace: "bar", - Partition: "baz", - // We currently don't set the datacenter in any of the V2 results. - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchWorkload", mock.Anything, mock.Anything). - Return(result, nil). - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - - require.Equal(t, "foo", req.Name) - require.Empty(t, req.PortName) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "foo.workload.bar.ns.baz.ap.dc3.dc.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.workload.bar.ns.baz.ap.dc3.dc.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "workload w/hostname address, ANY query (no recursor)", - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := &discovery.Result{ - Node: &discovery.Location{Name: "foo", Address: "foo.example.com"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{}, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchWorkload", mock.Anything, mock.Anything). - Return(result, nil). //TODO - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "api", req.PortName) - }) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "api.port.foo.workload.consul.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - Ttl: 123, - }, - Target: "foo.example.com.", - }, - }, - }, - }, - { - name: "workload w/hostname address, ANY query (w/ recursor)", - // https://datatracker.ietf.org/doc/html/rfc1034#section-3.6.2 both the CNAME and the A record should be in the answer - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := &discovery.Result{ - Node: &discovery.Location{Name: "foo", Address: "foo.example.com"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{}, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchWorkload", mock.Anything, mock.Anything). - Return(result, nil). //TODO - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "api", req.PortName) - }) - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSDomain: "consul", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - resp := &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.example.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.example.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - } - recursor.(*mockDnsRecursor).On("handle", - mock.Anything, mock.Anything, mock.Anything).Return(resp, nil) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - RecursionAvailable: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "api.port.foo.workload.consul.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - Ttl: 123, - }, - Target: "foo.example.com.", - }, - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.example.com.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - { - name: "workload w/hostname address, CNAME query (w/ recursor)", - // https://datatracker.ietf.org/doc/html/rfc1034#section-3.6.2 only the CNAME should be in the answer - request: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - }, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeCNAME, - Qclass: dns.ClassINET, - }, - }, - }, - configureDataFetcher: func(fetcher discovery.CatalogDataFetcher) { - result := &discovery.Result{ - Node: &discovery.Location{Name: "foo", Address: "foo.example.com"}, - Type: discovery.ResultTypeWorkload, - Tenancy: discovery.ResultTenancy{}, - Ports: []discovery.Port{ - { - Name: "api", - Number: 5678, - }, - }, - } - - fetcher.(*discovery.MockCatalogDataFetcher). - On("FetchWorkload", mock.Anything, mock.Anything). - Return(result, nil). //TODO - Run(func(args mock.Arguments) { - req := args.Get(1).(*discovery.QueryPayload) - - require.Equal(t, "foo", req.Name) - require.Equal(t, "api", req.PortName) - }) - }, - agentConfig: &config.RuntimeConfig{ - DNSRecursors: []string{"8.8.8.8"}, - DNSDomain: "consul", - DNSNodeTTL: 123 * time.Second, - DNSSOA: config.RuntimeSOAConfig{ - Refresh: 1, - Retry: 2, - Expire: 3, - Minttl: 4, - }, - DNSUDPAnswerLimit: maxUDPAnswerLimit, - }, - configureRecursor: func(recursor dnsRecursor) { - resp := &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - Rcode: dns.RcodeSuccess, - }, - Question: []dns.Question{ - { - Name: "foo.example.com.", - Qtype: dns.TypeA, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.example.com.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - } - recursor.(*mockDnsRecursor).On("handle", - mock.Anything, mock.Anything, mock.Anything).Return(resp, nil) - }, - validateAndNormalizeExpected: true, - response: &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - RecursionAvailable: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "api.port.foo.workload.consul.", - Qtype: dns.TypeCNAME, - Qclass: dns.ClassINET, - }, - }, - Answer: []dns.RR{ - &dns.CNAME{ - Hdr: dns.RR_Header{ - Name: "api.port.foo.workload.consul.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - Ttl: 123, - }, - Target: "foo.example.com.", - }, - // TODO (v2-dns): this next record is wrong per the RFC-1034 mentioned in the comment above (NET-8060) - &dns.A{ - Hdr: dns.RR_Header{ - Name: "foo.example.com.", - Rrtype: dns.TypeCNAME, - Class: dns.ClassINET, - Ttl: 123, - }, - A: net.ParseIP("1.2.3.4"), - }, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - runHandleTestCases(t, tc) - }) - } -} diff --git a/agent/dns/server.go b/agent/dns/server.go deleted file mode 100644 index 764fb15980..0000000000 --- a/agent/dns/server.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "fmt" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/dnsutil" - "net" - - "github.com/miekg/dns" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/logging" -) - -// DNSRouter is a mock for Router that can be used for testing. -// -//go:generate mockery --name DNSRouter --inpackage -type DNSRouter interface { - HandleRequest(req *dns.Msg, reqCtx Context, remoteAddress net.Addr) *dns.Msg - ServeDNS(w dns.ResponseWriter, req *dns.Msg) - GetConfig() *RouterDynamicConfig - ReloadConfig(newCfg *config.RuntimeConfig) error -} - -// Server is used to expose service discovery queries using a DNS interface. -// It implements the agent.dnsServer interface. -type Server struct { - *dns.Server // Used for setting up listeners - Router DNSRouter // Used to routes and parse DNS requests - - logger hclog.Logger -} - -// Config represent all the DNS configuration required to construct a DNS server. -type Config struct { - AgentConfig *config.RuntimeConfig - EntMeta acl.EnterpriseMeta - Logger hclog.Logger - Processor DiscoveryQueryProcessor - TokenFunc func() string - TranslateAddressFunc func(dc string, addr string, taggedAddresses map[string]string, accept dnsutil.TranslateAddressAccept) string - TranslateServiceAddressFunc func(dc string, address string, taggedAddresses map[string]structs.ServiceAddress, accept dnsutil.TranslateAddressAccept) string -} - -// NewServer creates a new DNS server. -func NewServer(config Config) (*Server, error) { - router, err := NewRouter(config) - if err != nil { - return nil, fmt.Errorf("error creating DNS router: %w", err) - } - - srv := &Server{ - Router: router, - logger: config.Logger.Named(logging.DNS), - } - return srv, nil -} - -// ListenAndServe starts the DNS server. -func (d *Server) ListenAndServe(network, addr string, notif func()) error { - d.Server = &dns.Server{ - Addr: addr, - Net: network, - Handler: d.Router, - NotifyStartedFunc: notif, - } - if network == "udp" { - d.UDPSize = 65535 - } - return d.Server.ListenAndServe() -} - -// ReloadConfig hot-reloads the server config with new parameters under config.RuntimeConfig.DNS* -func (d *Server) ReloadConfig(newCfg *config.RuntimeConfig) error { - return d.Router.ReloadConfig(newCfg) -} - -// Shutdown stops the DNS server. -func (d *Server) Shutdown() { - if d.Server != nil { - d.logger.Info("Stopping server", - "protocol", "DNS", - "address", d.Server.Addr, - "network", d.Server.Net, - ) - err := d.Server.Shutdown() - if err != nil { - d.logger.Error("Error stopping DNS server", "error", err) - } - } - d.Router = nil -} - -// GetAddr is a function to return the server address if is not nil. -func (d *Server) GetAddr() string { - if d.Server != nil { - return d.Server.Addr - } - return "" -} diff --git a/agent/dns/server_test.go b/agent/dns/server_test.go deleted file mode 100644 index 7ede22efda..0000000000 --- a/agent/dns/server_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/stretchr/testify/require" - "testing" -) - -// TestServer_ReloadConfig tests that the ReloadConfig method calls the router's ReloadConfig method. -func TestDNSServer_ReloadConfig(t *testing.T) { - srv, err := NewServer(Config{ - AgentConfig: &config.RuntimeConfig{ - DNSDomain: "test-domain", - DNSAltDomain: "test-alt-domain", - }, - Logger: testutil.Logger(t), - }) - srv.Router = NewMockDNSRouter(t) - require.NoError(t, err) - cfg := &config.RuntimeConfig{ - DNSARecordLimit: 123, - DNSEnableTruncate: true, - DNSNodeTTL: 123, - DNSRecursorStrategy: "test", - DNSRecursorTimeout: 123, - DNSUDPAnswerLimit: 123, - DNSNodeMetaTXT: true, - DNSDisableCompression: true, - DNSSOA: config.RuntimeSOAConfig{ - Expire: 123, - Refresh: 123, - Retry: 123, - Minttl: 123, - }, - } - srv.Router.(*MockDNSRouter).On("ReloadConfig", cfg).Return(nil) - err = srv.ReloadConfig(cfg) - require.NoError(t, err) - require.True(t, srv.Router.(*MockDNSRouter).AssertExpectations(t)) -} - -// TestDNSServer_Lifecycle tests that the server can be started and shutdown. -func TestDNSServer_Lifecycle(t *testing.T) { - // Arrange - srv, err := NewServer(Config{ - AgentConfig: &config.RuntimeConfig{ - DNSDomain: "test-domain", - DNSAltDomain: "test-alt-domain", - }, - Logger: testutil.Logger(t), - }) - defer srv.Shutdown() - require.NotNil(t, srv.Router) - require.NoError(t, err) - require.NotNil(t, srv) - - ch := make(chan bool) - go func() { - err = srv.ListenAndServe("udp", "127.0.0.1:8500", func() { - ch <- true - }) - require.NoError(t, err) - }() - started, ok := <-ch - require.True(t, ok) - require.True(t, started) - require.NotNil(t, srv.Handler) - require.NotNil(t, srv.Handler.(*Router)) - require.NotNil(t, srv.PacketConn) - - //Shutdown - srv.Shutdown() - require.Nil(t, srv.Router) -} diff --git a/agent/dns_catalogv2_test.go b/agent/dns_catalogv2_test.go deleted file mode 100644 index 7aef88751c..0000000000 --- a/agent/dns_catalogv2_test.go +++ /dev/null @@ -1,516 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package agent - -import ( - "context" - "fmt" - "net" - "testing" - - "github.com/miekg/dns" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/consul/testrpc" -) - -// Similar to TestDNS_ServiceLookup, but removes config for features unsupported in v2 and -// tests against DNS v2 and Catalog v2 explicitly using a resource API client. -func TestDNS_CatalogV2_Basic(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - var err error - a := NewTestAgent(t, `experiments=["resource-apis"]`) // v2dns is implicit w/ resource-apis - defer a.Shutdown() - - testrpc.WaitForRaftLeader(t, a.RPC, "dc1") - - client := a.delegate.ResourceServiceClient() - - // Smoke test for `consul-server` service. - readResource(t, client, &pbresource.ID{ - Name: structs.ConsulServiceName, - Type: pbcatalog.ServiceType, - Tenancy: resource.DefaultNamespacedTenancy(), - }, new(pbcatalog.Service)) - - // Register a new service. - dbServiceId := &pbresource.ID{ - Name: "db", - Type: pbcatalog.ServiceType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - emptyServiceId := &pbresource.ID{ - Name: "empty", - Type: pbcatalog.ServiceType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - dbService := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"db-"}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "admin", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - emptyService := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"empty-"}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "admin", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - dbServiceResource := &pbresource.Resource{ - Id: dbServiceId, - Data: toAny(t, dbService), - } - emptyServiceResource := &pbresource.Resource{ - Id: emptyServiceId, - Data: toAny(t, emptyService), - } - for _, r := range []*pbresource.Resource{dbServiceResource, emptyServiceResource} { - _, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: r}) - if err != nil { - t.Fatalf("failed to create the %s service: %v", r.Id.Name, err) - } - } - - // Validate services written. - readResource(t, client, dbServiceId, new(pbcatalog.Service)) - readResource(t, client, emptyServiceId, new(pbcatalog.Service)) - - // Register workloads. - dbWorkloadId1 := &pbresource.ID{ - Name: "db-1", - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - dbWorkloadId2 := &pbresource.ID{ - Name: "db-2", - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - dbWorkloadId3 := &pbresource.ID{ - Name: "db-3", - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - dbWorkloadPorts := map[string]*pbcatalog.WorkloadPort{ - "tcp": { - Port: 12345, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "admin": { - Port: 23456, - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - } - dbWorkloadFn := func(ip string) *pbcatalog.Workload { - return &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: ip, - }, - }, - Identity: "test-identity", - Ports: dbWorkloadPorts, - } - } - dbWorkload1 := dbWorkloadFn("172.16.1.1") - _, err = client.Write(context.Background(), &pbresource.WriteRequest{Resource: &pbresource.Resource{ - Id: dbWorkloadId1, - Data: toAny(t, dbWorkload1), - }}) - if err != nil { - t.Fatalf("failed to create the %s workload: %v", dbWorkloadId1.Name, err) - } - dbWorkload2 := dbWorkloadFn("172.16.1.2") - _, err = client.Write(context.Background(), &pbresource.WriteRequest{Resource: &pbresource.Resource{ - Id: dbWorkloadId2, - Data: toAny(t, dbWorkload2), - }}) - if err != nil { - t.Fatalf("failed to create the %s workload: %v", dbWorkloadId2.Name, err) - } - dbWorkload3 := dbWorkloadFn("2001:db8:85a3::8a2e:370:7334") // test IPv6 - _, err = client.Write(context.Background(), &pbresource.WriteRequest{Resource: &pbresource.Resource{ - Id: dbWorkloadId3, - Data: toAny(t, dbWorkload3), - }}) - if err != nil { - t.Fatalf("failed to create the %s workload: %v", dbWorkloadId2.Name, err) - } - - // Validate workloads written. - dbWorkloads := make(map[string]*pbcatalog.Workload) - dbWorkloads["db-1"] = readResource(t, client, dbWorkloadId1, new(pbcatalog.Workload)).(*pbcatalog.Workload) - dbWorkloads["db-2"] = readResource(t, client, dbWorkloadId2, new(pbcatalog.Workload)).(*pbcatalog.Workload) - dbWorkloads["db-3"] = readResource(t, client, dbWorkloadId3, new(pbcatalog.Workload)).(*pbcatalog.Workload) - - // Ensure endpoints exist and have health status, which is required for inclusion in DNS results. - retry.Run(t, func(r *retry.R) { - endpoints := readResource(r, client, resource.ReplaceType(pbcatalog.ServiceEndpointsType, dbServiceId), new(pbcatalog.ServiceEndpoints)).(*pbcatalog.ServiceEndpoints) - require.Equal(r, 3, len(endpoints.GetEndpoints())) - for _, e := range endpoints.GetEndpoints() { - require.True(r, - // We only return results for passing and warning health checks. - e.HealthStatus == pbcatalog.Health_HEALTH_PASSING || e.HealthStatus == pbcatalog.Health_HEALTH_WARNING, - fmt.Sprintf("unexpected health status: %v", e.HealthStatus)) - } - }) - - // Test UDP and TCP clients. - for _, client := range []*dns.Client{ - newDNSClient(false), - newDNSClient(true), - } { - // Lookup a service without matching workloads, we should receive an SOA and no answers. - questions := []string{ - "empty.service.consul.", - "_empty._tcp.service.consul.", - } - for _, question := range questions { - for _, dnsType := range []uint16{dns.TypeSRV, dns.TypeA, dns.TypeAAAA} { - m := new(dns.Msg) - m.SetQuestion(question, dnsType) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - require.Equal(t, 0, len(in.Answer), "Bad: %s", in.String()) - require.Equal(t, 0, len(in.Extra), "Bad: %s", in.String()) - require.Equal(t, 1, len(in.Ns), "Bad: %s", in.String()) - - soaRec, ok := in.Ns[0].(*dns.SOA) - require.True(t, ok, "Bad: %s", in.Ns[0].String()) - require.EqualValues(t, 0, soaRec.Hdr.Ttl, "Bad: %s", in.Ns[0].String()) - } - } - - // Look up the service directly including all ports. - questions = []string{ - "db.service.consul.", - "_db._tcp.service.consul.", // RFC 2782 query. All ports are TCP, so this should return the same result. - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - // This check only runs for a TCP client because a UDP client will truncate the response. - if client.Net == "tcp" { - for portName, port := range dbWorkloadPorts { - for workloadName, workload := range dbWorkloads { - workloadTarget := fmt.Sprintf("%s.port.%s.workload.default.ns.default.ap.consul.", portName, workloadName) - workloadHost := workload.Addresses[0].Host - - srvRec := findSrvAnswerForTarget(t, in, workloadTarget) - require.EqualValues(t, port.Port, srvRec.Port, "Bad: %s", srvRec.String()) - require.EqualValues(t, 0, srvRec.Hdr.Ttl, "Bad: %s", srvRec.String()) - - a := findAorAAAAForName(t, in, in.Extra, workloadTarget) - require.Equal(t, workloadHost, a.AorAAAA.String(), "Bad: %s", a.Original.String()) - require.EqualValues(t, 0, a.Hdr.Ttl, "Bad: %s", a.Original.String()) - } - } - - // Expect 1 result per port, per workload. - require.Equal(t, 9, len(in.Answer), "answer count did not match expected\n\n%s", in.String()) - require.Equal(t, 9, len(in.Extra), "extra answer count did not match expected\n\n%s", in.String()) - } else { - // Expect 1 result per port, per workload, up to the default limit of 3. In practice the results are truncated - // at 2 because of the record byte size. - require.Equal(t, 2, len(in.Answer), "answer count did not match expected\n\n%s", in.String()) - require.Equal(t, 2, len(in.Extra), "extra answer count did not match expected\n\n%s", in.String()) - } - } - - // Look up the service directly by each port. - for portName, port := range dbWorkloadPorts { - question := fmt.Sprintf("%s.port.db.service.consul.", portName) - - for workloadName, workload := range dbWorkloads { - workloadTarget := fmt.Sprintf("%s.port.%s.workload.default.ns.default.ap.consul.", portName, workloadName) - workloadHost := workload.Addresses[0].Host - - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - srvRec := findSrvAnswerForTarget(t, in, workloadTarget) - require.EqualValues(t, port.Port, srvRec.Port, "Bad: %s", srvRec.String()) - require.EqualValues(t, 0, srvRec.Hdr.Ttl, "Bad: %s", srvRec.String()) - - a := findAorAAAAForName(t, in, in.Extra, workloadTarget) - require.Equal(t, workloadHost, a.AorAAAA.String(), "Bad: %s", a.Original.String()) - require.EqualValues(t, 0, a.Hdr.Ttl, "Bad: %s", a.Original.String()) - - // Expect 1 result per port. - require.Equal(t, 3, len(in.Answer), "answer count did not match expected\n\n%s", in.String()) - require.Equal(t, 3, len(in.Extra), "extra answer count did not match expected\n\n%s", in.String()) - } - } - - // Look up A/AAAA by service. - questions = []string{ - "db.service.consul.", - } - for _, question := range questions { - for workloadName, dnsType := range map[string]uint16{ - "db-1": dns.TypeA, - "db-2": dns.TypeA, - "db-3": dns.TypeAAAA, - } { - workload := dbWorkloads[workloadName] - - m := new(dns.Msg) - m.SetQuestion(question, dnsType) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - workloadHost := workload.Addresses[0].Host - - a := findAorAAAAForAddress(t, in, in.Answer, workloadHost) - require.Equal(t, question, a.Hdr.Name, "Bad: %s", a.Original.String()) - require.EqualValues(t, 0, a.Hdr.Ttl, "Bad: %s", a.Original.String()) - - // Expect 1 answer per workload. For A records, expect 2 answers because there's 2 IPv4 workloads. - if dnsType == dns.TypeA { - require.Equal(t, 2, len(in.Answer), "answer count did not match expected\n\n%s", in.String()) - } else { - require.Equal(t, 1, len(in.Answer), "answer count did not match expected\n\n%s", in.String()) - } - require.Equal(t, 0, len(in.Extra), "extra answer count did not match expected\n\n%s", in.String()) - } - } - - // Lookup a non-existing service, we should receive an SOA. - questions = []string{ - "nodb.service.consul.", - "nope.query.consul.", // prepared query is not supported in v2 - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - require.Equal(t, 1, len(in.Ns), "Bad: %s", in.String()) - - soaRec, ok := in.Ns[0].(*dns.SOA) - require.True(t, ok, "Bad: %s", in.Ns[0].String()) - require.EqualValues(t, 0, soaRec.Hdr.Ttl, "Bad: %s", in.Ns[0].String()) - } - - // Lookup workloads directly with a port. - for workloadName, dnsType := range map[string]uint16{ - "db-1": dns.TypeA, - "db-2": dns.TypeA, - "db-3": dns.TypeAAAA, - } { - for _, question := range []string{ - fmt.Sprintf("%s.workload.default.ns.default.ap.consul.", workloadName), - fmt.Sprintf("tcp.port.%s.workload.default.ns.default.ap.consul.", workloadName), - fmt.Sprintf("admin.port.%s.workload.default.ns.default.ap.consul.", workloadName), - fmt.Sprintf("mesh.port.%s.workload.default.ns.default.ap.consul.", workloadName), - } { - workload := dbWorkloads[workloadName] - workloadHost := workload.Addresses[0].Host - - m := new(dns.Msg) - m.SetQuestion(question, dnsType) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - require.Equal(t, 1, len(in.Answer), "Bad: %s", in.String()) - - a := findAorAAAAForName(t, in, in.Answer, question) - require.Equal(t, workloadHost, a.AorAAAA.String(), "Bad: %s", a.Original.String()) - require.EqualValues(t, 0, a.Hdr.Ttl, "Bad: %s", a.Original.String()) - } - } - - // Lookup a non-existing workload, we should receive an NXDOMAIN response. - for _, aType := range []uint16{dns.TypeA, dns.TypeAAAA} { - question := "unknown.workload.consul." - - m := new(dns.Msg) - m.SetQuestion(question, aType) - - in, _, err := client.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - require.Equal(t, 0, len(in.Answer), "Bad: %s", in.String()) - require.Equal(t, dns.RcodeNameError, in.Rcode, "Bad: %s", in.String()) - } - } -} - -func findSrvAnswerForTarget(t *testing.T, in *dns.Msg, target string) *dns.SRV { - t.Helper() - - for _, a := range in.Answer { - srvRec, ok := a.(*dns.SRV) - if ok && srvRec.Target == target { - return srvRec - } - } - t.Fatalf("could not find SRV record for target: %s\n\n%s", target, in.String()) - return nil -} - -func findAorAAAAForName(t *testing.T, in *dns.Msg, rrs []dns.RR, name string) *dnsAOrAAAA { - t.Helper() - - for _, rr := range rrs { - a := newAOrAAAA(t, rr) - if a.Hdr.Name == name { - return a - } - } - t.Fatalf("could not find A/AAAA record for name: %s\n\n%+v", name, in.String()) - return nil -} - -func findAorAAAAForAddress(t *testing.T, in *dns.Msg, rrs []dns.RR, address string) *dnsAOrAAAA { - t.Helper() - - for _, rr := range rrs { - a := newAOrAAAA(t, rr) - if a.AorAAAA.String() == address { - return a - } - } - t.Fatalf("could not find A/AAAA record for address: %s\n\n%+v", address, in.String()) - return nil -} - -func readResource(t retry.TestingTB, client pbresource.ResourceServiceClient, id *pbresource.ID, m proto.Message) proto.Message { - t.Helper() - - retry.Run(t, func(r *retry.R) { - res, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: id}) - if err != nil { - r.Fatalf("err: %v", err) - } - data := res.GetResource() - require.NotEmpty(r, data) - - err = data.Data.UnmarshalTo(m) - require.NoError(r, err) - }) - - return m -} - -func toAny(t retry.TestingTB, m proto.Message) *anypb.Any { - t.Helper() - a, err := anypb.New(m) - if err != nil { - t.Fatalf("could not convert proto to `any` message: %v", err) - } - return a -} - -// dnsAOrAAAA unifies A and AAAA records for simpler testing when the IP type doesn't matter. -type dnsAOrAAAA struct { - Original dns.RR - Hdr dns.RR_Header - AorAAAA net.IP - isAAAA bool -} - -func newAOrAAAA(t *testing.T, rr dns.RR) *dnsAOrAAAA { - t.Helper() - - if aRec, ok := rr.(*dns.A); ok { - return &dnsAOrAAAA{ - Original: rr, - Hdr: aRec.Hdr, - AorAAAA: aRec.A, - isAAAA: false, - } - } - if aRec, ok := rr.(*dns.AAAA); ok { - return &dnsAOrAAAA{ - Original: rr, - Hdr: aRec.Hdr, - AorAAAA: aRec.AAAA, - isAAAA: true, - } - } - - t.Fatalf("Bad A or AAAA record: %#v", rr) - return nil -} - -func newDNSClient(tcp bool) *dns.Client { - c := new(dns.Client) - - // Use TCP to avoid truncation of larger responses and - // sidestep the default UDP size limit of 3 answers - // set by config.DefaultSource() in agent/config/default.go. - if tcp { - c.Net = "tcp" - } - - return c -} diff --git a/agent/dns_ce.go b/agent/dns_ce.go index 171a789945..03595cb5bd 100644 --- a/agent/dns_ce.go +++ b/agent/dns_ce.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" + agentdns "github.com/hashicorp/consul/agent/dns" "github.com/hashicorp/consul/agent/structs" ) @@ -26,9 +27,9 @@ func getEnterpriseDNSConfig(conf *config.RuntimeConfig) enterpriseDNSConfig { // parseLocality can parse peer name or datacenter from a DNS query's labels. // Peer name is parsed from the same query part that datacenter is, so given this ambiguity // we parse a "peerOrDatacenter". The caller or RPC handler are responsible for disambiguating. -func (d *DNSServer) parseLocality(labels []string, cfg *dnsConfig) (queryLocality, bool) { +func (d *DNSServer) parseLocality(labels []string, cfg *dnsRequestConfig) (queryLocality, bool) { locality := queryLocality{ - EnterpriseMeta: d.defaultEnterpriseMeta, + EnterpriseMeta: cfg.defaultEnterpriseMeta, } switch len(labels) { @@ -52,7 +53,10 @@ func (d *DNSServer) parseLocality(labels []string, cfg *dnsConfig) (queryLocalit } return locality, true case 1: - return queryLocality{peerOrDatacenter: labels[0]}, true + return queryLocality{ + peerOrDatacenter: labels[0], + EnterpriseMeta: cfg.defaultEnterpriseMeta, + }, true case 0: return queryLocality{}, true @@ -64,10 +68,12 @@ func (d *DNSServer) parseLocality(labels []string, cfg *dnsConfig) (queryLocalit type querySameness struct{} // parseSamenessGroupLocality wraps parseLocality in CE -func (d *DNSServer) parseSamenessGroupLocality(cfg *dnsConfig, labels []string, errfnc func() error) (queryLocality, error) { +func (d *DNSServer) parseSamenessGroupLocality(cfg *dnsRequestConfig, labels []string, errfnc func() error) (queryLocality, error) { locality, ok := d.parseLocality(labels, cfg) if !ok { - return queryLocality{}, errfnc() + return queryLocality{ + EnterpriseMeta: cfg.defaultEnterpriseMeta, + }, errfnc() } return locality, nil } @@ -88,3 +94,9 @@ func nodeCanonicalDNSName(node *structs.Node, respDomain string) string { // Return a simpler format for non-peering nodes. return fmt.Sprintf("%s.node.%s.%s", node.Node, node.Datacenter, respDomain) } + +// setEnterpriseMetaFromRequestContext sets the DefaultNamespace and DefaultPartition on the requestDnsConfig +// based on the requestContext's DefaultNamespace and DefaultPartition. +func (d *DNSServer) setEnterpriseMetaFromRequestContext(requestContext agentdns.Context, requestDnsConfig *dnsRequestConfig) { + // do nothing +} diff --git a/agent/dns_ce_test.go b/agent/dns_ce_test.go index 44e3028562..6787c42577 100644 --- a/agent/dns_ce_test.go +++ b/agent/dns_ce_test.go @@ -22,116 +22,112 @@ func TestDNS_CE_PeeredServices(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := StartTestAgent(t, TestAgent{HCL: ``, Overrides: `peering = { test_allow_peer_registrations = true } ` + experimentsHCL}) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + a := StartTestAgent(t, TestAgent{HCL: ``, Overrides: `peering = { test_allow_peer_registrations = true } `}) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - makeReq := func() *structs.RegisterRequest { - return &structs.RegisterRequest{ - PeerName: "peer1", - Datacenter: "dc1", - Node: "peernode1", - Address: "198.18.1.1", - Service: &structs.NodeService{ - PeerName: "peer1", - Kind: structs.ServiceKindConnectProxy, - Service: "web-proxy", - Address: "199.0.0.1", - Port: 12345, - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "peer-web", - }, - EnterpriseMeta: *acl.DefaultEnterpriseMeta(), - }, - EnterpriseMeta: *acl.DefaultEnterpriseMeta(), - } - } - - dnsQuery := func(t *testing.T, question string, typ uint16) *dns.Msg { - m := new(dns.Msg) - m.SetQuestion(question, typ) - - c := new(dns.Client) - reply, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, reply.Answer, 1, "zero valid records found for %q", question) - return reply - } - - assertARec := func(t *testing.T, rec dns.RR, expectName, expectIP string) { - aRec, ok := rec.(*dns.A) - require.True(t, ok, "Extra is not an A record: %T", rec) - require.Equal(t, expectName, aRec.Hdr.Name) - require.Equal(t, expectIP, aRec.A.String()) - } - - assertSRVRec := func(t *testing.T, rec dns.RR, expectName string, expectPort uint16) { - srvRec, ok := rec.(*dns.SRV) - require.True(t, ok, "Answer is not a SRV record: %T", rec) - require.Equal(t, expectName, srvRec.Target) - require.Equal(t, expectPort, srvRec.Port) - } - - t.Run("srv-with-addr-reply", func(t *testing.T) { - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 1) - - addr := "c7000001.addr.consul." - assertSRVRec(t, q.Answer[0], addr, 12345) - assertARec(t, q.Extra[0], addr, "199.0.0.1") - - // Query the addr to make sure it's also valid. - q = dnsQuery(t, addr, dns.TypeA) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertARec(t, q.Answer[0], addr, "199.0.0.1") - }) - - t.Run("srv-with-node-reply", func(t *testing.T) { - req := makeReq() - // Clear service address to trigger node response - req.Service.Address = "" - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 1) - - nodeName := "peernode1.node.peer1.peer.consul." - assertSRVRec(t, q.Answer[0], nodeName, 12345) - assertARec(t, q.Extra[0], nodeName, "198.18.1.1") - - // Query the node to make sure it's also valid. - q = dnsQuery(t, nodeName, dns.TypeA) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertARec(t, q.Answer[0], nodeName, "198.18.1.1") - }) - - t.Run("srv-with-fqdn-reply", func(t *testing.T) { - req := makeReq() - // Set non-ip address to trigger external response - req.Address = "localhost" - req.Service.Address = "" - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertSRVRec(t, q.Answer[0], "localhost.", 12345) - }) - - t.Run("a-reply", func(t *testing.T) { - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) - q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeA) - require.Len(t, q.Answer, 1) - require.Len(t, q.Extra, 0) - assertARec(t, q.Answer[0], "web-proxy.service.peer1.peer.consul.", "199.0.0.1") - }) - }) + makeReq := func() *structs.RegisterRequest { + return &structs.RegisterRequest{ + PeerName: "peer1", + Datacenter: "dc1", + Node: "peernode1", + Address: "198.18.1.1", + Service: &structs.NodeService{ + PeerName: "peer1", + Kind: structs.ServiceKindConnectProxy, + Service: "web-proxy", + Address: "199.0.0.1", + Port: 12345, + Proxy: structs.ConnectProxyConfig{ + DestinationServiceName: "peer-web", + }, + EnterpriseMeta: *acl.DefaultEnterpriseMeta(), + }, + EnterpriseMeta: *acl.DefaultEnterpriseMeta(), + } } + + dnsQuery := func(t *testing.T, question string, typ uint16) *dns.Msg { + m := new(dns.Msg) + m.SetQuestion(question, typ) + + c := new(dns.Client) + reply, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, reply.Answer, 1, "zero valid records found for %q", question) + return reply + } + + assertARec := func(t *testing.T, rec dns.RR, expectName, expectIP string) { + aRec, ok := rec.(*dns.A) + require.True(t, ok, "Extra is not an A record: %T", rec) + require.Equal(t, expectName, aRec.Hdr.Name) + require.Equal(t, expectIP, aRec.A.String()) + } + + assertSRVRec := func(t *testing.T, rec dns.RR, expectName string, expectPort uint16) { + srvRec, ok := rec.(*dns.SRV) + require.True(t, ok, "Answer is not a SRV record: %T", rec) + require.Equal(t, expectName, srvRec.Target) + require.Equal(t, expectPort, srvRec.Port) + } + + t.Run("srv-with-addr-reply", func(t *testing.T) { + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 1) + + addr := "c7000001.addr.consul." + assertSRVRec(t, q.Answer[0], addr, 12345) + assertARec(t, q.Extra[0], addr, "199.0.0.1") + + // Query the addr to make sure it's also valid. + q = dnsQuery(t, addr, dns.TypeA) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertARec(t, q.Answer[0], addr, "199.0.0.1") + }) + + t.Run("srv-with-node-reply", func(t *testing.T) { + req := makeReq() + // Clear service address to trigger node response + req.Service.Address = "" + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 1) + + nodeName := "peernode1.node.peer1.peer.consul." + assertSRVRec(t, q.Answer[0], nodeName, 12345) + assertARec(t, q.Extra[0], nodeName, "198.18.1.1") + + // Query the node to make sure it's also valid. + q = dnsQuery(t, nodeName, dns.TypeA) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertARec(t, q.Answer[0], nodeName, "198.18.1.1") + }) + + t.Run("srv-with-fqdn-reply", func(t *testing.T) { + req := makeReq() + // Set non-ip address to trigger external response + req.Address = "localhost" + req.Service.Address = "" + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", req, &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeSRV) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertSRVRec(t, q.Answer[0], "localhost.", 12345) + }) + + t.Run("a-reply", func(t *testing.T) { + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", makeReq(), &struct{}{})) + q := dnsQuery(t, "web-proxy.service.peer1.peer.consul.", dns.TypeA) + require.Len(t, q.Answer, 1) + require.Len(t, q.Extra, 0) + assertARec(t, q.Answer[0], "web-proxy.service.peer1.peer.consul.", "199.0.0.1") + }) } func getTestCasesParseLocality() []testCaseParseLocality { diff --git a/agent/dns_node_lookup_test.go b/agent/dns_node_lookup_test.go index 8dbb3d407e..e66fca99ab 100644 --- a/agent/dns_node_lookup_test.go +++ b/agent/dns_node_lookup_test.go @@ -19,101 +19,97 @@ func TestDNS_NodeLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - TaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - NodeMeta: map[string]string{ - "key": "value", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m := new(dns.Msg) - m.SetQuestion("foo.node.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 2) - require.Len(t, in.Extra, 0) - - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok, "First answer is not an A record") - require.Equal(t, "127.0.0.1", aRec.A.String()) - require.Equal(t, uint32(0), aRec.Hdr.Ttl) - - txt, ok := in.Answer[1].(*dns.TXT) - require.True(t, ok, "Second answer is not a TXT record") - require.Len(t, txt.Txt, 1) - require.Equal(t, "key=value", txt.Txt[0]) - - // Re-do the query, but only for an A RR - - m = new(dns.Msg) - m.SetQuestion("foo.node.consul.", dns.TypeA) - - c = new(dns.Client) - in, _, err = c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 1) - require.Len(t, in.Extra, 1) - - aRec, ok = in.Answer[0].(*dns.A) - require.True(t, ok, "Answer is not an A record") - require.Equal(t, "127.0.0.1", aRec.A.String()) - require.Equal(t, uint32(0), aRec.Hdr.Ttl) - - txt, ok = in.Extra[0].(*dns.TXT) - require.True(t, ok, "Extra record is not a TXT record") - require.Len(t, txt.Txt, 1) - require.Equal(t, "key=value", txt.Txt[0]) - - // Re-do the query, but specify the DC - m = new(dns.Msg) - m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY) - - c = new(dns.Client) - in, _, err = c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 2) - require.Len(t, in.Extra, 0) - - aRec, ok = in.Answer[0].(*dns.A) - require.True(t, ok, "First answer is not an A record") - require.Equal(t, "127.0.0.1", aRec.A.String()) - require.Equal(t, uint32(0), aRec.Hdr.Ttl) - - _, ok = in.Answer[1].(*dns.TXT) - require.True(t, ok, "Second answer is not a TXT record") - - // lookup a non-existing node, we should receive a SOA - m = new(dns.Msg) - m.SetQuestion("nofoo.node.dc1.consul.", dns.TypeANY) - - c = new(dns.Client) - in, _, err = c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Ns, 1) - soaRec, ok := in.Ns[0].(*dns.SOA) - require.True(t, ok, "NS RR is not a SOA record") - require.Equal(t, uint32(0), soaRec.Hdr.Ttl) - }) + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + TaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + NodeMeta: map[string]string{ + "key": "value", + }, } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m := new(dns.Msg) + m.SetQuestion("foo.node.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 2) + require.Len(t, in.Extra, 0) + + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok, "First answer is not an A record") + require.Equal(t, "127.0.0.1", aRec.A.String()) + require.Equal(t, uint32(0), aRec.Hdr.Ttl) + + txt, ok := in.Answer[1].(*dns.TXT) + require.True(t, ok, "Second answer is not a TXT record") + require.Len(t, txt.Txt, 1) + require.Equal(t, "key=value", txt.Txt[0]) + + // Re-do the query, but only for an A RR + + m = new(dns.Msg) + m.SetQuestion("foo.node.consul.", dns.TypeA) + + c = new(dns.Client) + in, _, err = c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 1) + require.Len(t, in.Extra, 1) + + aRec, ok = in.Answer[0].(*dns.A) + require.True(t, ok, "Answer is not an A record") + require.Equal(t, "127.0.0.1", aRec.A.String()) + require.Equal(t, uint32(0), aRec.Hdr.Ttl) + + txt, ok = in.Extra[0].(*dns.TXT) + require.True(t, ok, "Extra record is not a TXT record") + require.Len(t, txt.Txt, 1) + require.Equal(t, "key=value", txt.Txt[0]) + + // Re-do the query, but specify the DC + m = new(dns.Msg) + m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY) + + c = new(dns.Client) + in, _, err = c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 2) + require.Len(t, in.Extra, 0) + + aRec, ok = in.Answer[0].(*dns.A) + require.True(t, ok, "First answer is not an A record") + require.Equal(t, "127.0.0.1", aRec.A.String()) + require.Equal(t, uint32(0), aRec.Hdr.Ttl) + + _, ok = in.Answer[1].(*dns.TXT) + require.True(t, ok, "Second answer is not a TXT record") + + // lookup a non-existing node, we should receive a SOA + m = new(dns.Msg) + m.SetQuestion("nofoo.node.dc1.consul.", dns.TypeANY) + + c = new(dns.Client) + in, _, err = c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Ns, 1) + soaRec, ok := in.Ns[0].(*dns.SOA) + require.True(t, ok, "NS RR is not a SOA record") + require.Equal(t, uint32(0), soaRec.Hdr.Ttl) } func TestDNS_NodeLookup_CaseInsensitive(t *testing.T) { @@ -121,37 +117,33 @@ func TestDNS_NodeLookup_CaseInsensitive(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "Foo", - Address: "127.0.0.1", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "Foo", + Address: "127.0.0.1", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("fOO.node.dc1.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("fOO.node.dc1.consul.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("empty lookup: %#v", in) - } - }) + if len(in.Answer) != 1 { + t.Fatalf("empty lookup: %#v", in) } } @@ -161,45 +153,41 @@ func TestDNS_NodeLookup_PeriodName(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(false) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node with period in name - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo.bar", - Address: "127.0.0.1", - } + // Register node with period in name + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo.bar", + Address: "127.0.0.1", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("foo.bar.node.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("foo.bar.node.consul.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - aRec, ok := in.Answer[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - }) + aRec, ok := in.Answer[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Answer[0]) } } @@ -208,48 +196,44 @@ func TestDNS_NodeLookup_AAAA(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "::4242:4242", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "::4242:4242", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("bar.node.consul.", dns.TypeAAAA) + m := new(dns.Msg) + m.SetQuestion("bar.node.consul.", dns.TypeAAAA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - aRec, ok := in.Answer[0].(*dns.AAAA) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.AAAA.String() != "::4242:4242" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - }) + aRec, ok := in.Answer[0].(*dns.AAAA) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.AAAA.String() != "::4242:4242" { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) } } @@ -267,57 +251,53 @@ func TestDNS_NodeLookup_CNAME(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "google", - Address: "www.google.com", - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m := new(dns.Msg) - m.SetQuestion("google.node.consul.", dns.TypeANY) - m.SetEdns0(8192, true) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAnswer := []dns.RR{ - &dns.CNAME{ - Hdr: dns.RR_Header{Name: "google.node.consul.", Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x10}, - Target: "www.google.com.", - }, - &dns.CNAME{ - Hdr: dns.RR_Header{Name: "www.google.com.", Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Rdlength: 0x2}, - Target: "google.com.", - }, - &dns.A{ - Hdr: dns.RR_Header{Name: "google.com.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0x1, 0x2, 0x3, 0x4}, // 1.2.3.4 - }, - &dns.TXT{ - Hdr: dns.RR_Header{Name: "google.com.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xd}, - Txt: []string{"my_txt_value"}, - }, - } - require.Equal(t, wantAnswer, in.Answer) - }) + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "google", + Address: "www.google.com", } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m := new(dns.Msg) + m.SetQuestion("google.node.consul.", dns.TypeANY) + m.SetEdns0(8192, true) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + wantAnswer := []dns.RR{ + &dns.CNAME{ + Hdr: dns.RR_Header{Name: "google.node.consul.", Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x10}, + Target: "www.google.com.", + }, + &dns.CNAME{ + Hdr: dns.RR_Header{Name: "www.google.com.", Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Rdlength: 0x2}, + Target: "google.com.", + }, + &dns.A{ + Hdr: dns.RR_Header{Name: "google.com.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0x1, 0x2, 0x3, 0x4}, // 1.2.3.4 + }, + &dns.TXT{ + Hdr: dns.RR_Header{Name: "google.com.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xd}, + Txt: []string{"my_txt_value"}, + }, + } + require.Equal(t, wantAnswer, in.Answer) } func TestDNS_NodeLookup_TXT(t *testing.T) { @@ -325,52 +305,48 @@ func TestDNS_NodeLookup_TXT(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "google", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "rfc1035-00": "value0", - "key0": "value1", - }, - } + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "google", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "rfc1035-00": "value0", + "key0": "value1", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("google.node.consul.", dns.TypeTXT) + m := new(dns.Msg) + m.SetQuestion("google.node.consul.", dns.TypeTXT) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Should have the 1 TXT record reply - if len(in.Answer) != 2 { - t.Fatalf("Bad: %#v", in) - } + // Should have the 1 TXT record reply + if len(in.Answer) != 2 { + t.Fatalf("Bad: %#v", in) + } - txtRec, ok := in.Answer[0].(*dns.TXT) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if len(txtRec.Txt) != 1 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if txtRec.Txt[0] != "value0" && txtRec.Txt[0] != "key0=value1" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - }) + txtRec, ok := in.Answer[0].(*dns.TXT) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if len(txtRec.Txt) != 1 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if txtRec.Txt[0] != "value0" && txtRec.Txt[0] != "key0=value1" { + t.Fatalf("Bad: %#v", in.Answer[0]) } } @@ -379,52 +355,48 @@ func TestDNS_NodeLookup_TXT_DontSuppress(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "google", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "rfc1035-00": "value0", - "key0": "value1", - }, - } + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "google", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "rfc1035-00": "value0", + "key0": "value1", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("google.node.consul.", dns.TypeTXT) + m := new(dns.Msg) + m.SetQuestion("google.node.consul.", dns.TypeTXT) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Should have the 1 TXT record reply - if len(in.Answer) != 2 { - t.Fatalf("Bad: %#v", in) - } + // Should have the 1 TXT record reply + if len(in.Answer) != 2 { + t.Fatalf("Bad: %#v", in) + } - txtRec, ok := in.Answer[0].(*dns.TXT) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if len(txtRec.Txt) != 1 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if txtRec.Txt[0] != "value0" && txtRec.Txt[0] != "key0=value1" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - }) + txtRec, ok := in.Answer[0].(*dns.TXT) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if len(txtRec.Txt) != 1 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if txtRec.Txt[0] != "value0" && txtRec.Txt[0] != "key0=value1" { + t.Fatalf("Bad: %#v", in.Answer[0]) } } @@ -433,48 +405,44 @@ func TestDNS_NodeLookup_ANY(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "key": "value", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m := new(dns.Msg) - m.SetQuestion("bar.node.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAnswer := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 - }, - &dns.TXT{ - Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xa}, - Txt: []string{"key=value"}, - }, - } - require.Equal(t, wantAnswer, in.Answer) - }) + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "key": "value", + }, } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m := new(dns.Msg) + m.SetQuestion("bar.node.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + wantAnswer := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 + }, + &dns.TXT{ + Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xa}, + Txt: []string{"key=value"}, + }, + } + require.Equal(t, wantAnswer, in.Answer) } func TestDNS_NodeLookup_ANY_DontSuppressTXT(t *testing.T) { @@ -482,48 +450,44 @@ func TestDNS_NodeLookup_ANY_DontSuppressTXT(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "key": "value", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m := new(dns.Msg) - m.SetQuestion("bar.node.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAnswer := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 - }, - &dns.TXT{ - Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xa}, - Txt: []string{"key=value"}, - }, - } - require.Equal(t, wantAnswer, in.Answer) - }) + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "key": "value", + }, } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m := new(dns.Msg) + m.SetQuestion("bar.node.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + wantAnswer := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 + }, + &dns.TXT{ + Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xa}, + Txt: []string{"key=value"}, + }, + } + require.Equal(t, wantAnswer, in.Answer) } func TestDNS_NodeLookup_A_SuppressTXT(t *testing.T) { @@ -531,43 +495,39 @@ func TestDNS_NodeLookup_A_SuppressTXT(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "key": "value", - }, - } - - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - - m := new(dns.Msg) - m.SetQuestion("bar.node.consul.", dns.TypeA) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - - wantAnswer := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 - }, - } - require.Equal(t, wantAnswer, in.Answer) - - // ensure TXT RR suppression - require.Len(t, in.Extra, 0) - }) + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "key": "value", + }, } + + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + + m := new(dns.Msg) + m.SetQuestion("bar.node.consul.", dns.TypeA) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + + wantAnswer := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "bar.node.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 + }, + } + require.Equal(t, wantAnswer, in.Answer) + + // ensure TXT RR suppression + require.Len(t, in.Extra, 0) } func TestDNS_NodeLookup_TTL(t *testing.T) { @@ -583,122 +543,118 @@ func TestDNS_NodeLookup_TTL(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] dns_config { node_ttl = "10s" allow_stale = true max_stale = "1s" } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("foo.node.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("foo.node.consul.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - aRec, ok := in.Answer[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.Hdr.Ttl != 10 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + aRec, ok := in.Answer[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.Hdr.Ttl != 10 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - // Register node with IPv6 - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "::4242:4242", - } - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + // Register node with IPv6 + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "::4242:4242", + } + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - // Check an IPv6 record - m = new(dns.Msg) - m.SetQuestion("bar.node.consul.", dns.TypeANY) + // Check an IPv6 record + m = new(dns.Msg) + m.SetQuestion("bar.node.consul.", dns.TypeANY) - in, _, err = c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + in, _, err = c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - aaaaRec, ok := in.Answer[0].(*dns.AAAA) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aaaaRec.AAAA.String() != "::4242:4242" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aaaaRec.Hdr.Ttl != 10 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + aaaaRec, ok := in.Answer[0].(*dns.AAAA) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aaaaRec.AAAA.String() != "::4242:4242" { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aaaaRec.Hdr.Ttl != 10 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - // Register node with CNAME - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "google", - Address: "www.google.com", - } - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + // Register node with CNAME + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "google", + Address: "www.google.com", + } + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m = new(dns.Msg) - m.SetQuestion("google.node.consul.", dns.TypeANY) + m = new(dns.Msg) + m.SetQuestion("google.node.consul.", dns.TypeANY) - in, _, err = c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + in, _, err = c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Should have the CNAME record + a few A records - if len(in.Answer) < 2 { - t.Fatalf("Bad: %#v", in) - } + // Should have the CNAME record + a few A records + if len(in.Answer) < 2 { + t.Fatalf("Bad: %#v", in) + } - cnRec, ok := in.Answer[0].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if cnRec.Target != "www.google.com." { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if cnRec.Hdr.Ttl != 10 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - }) + cnRec, ok := in.Answer[0].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if cnRec.Target != "www.google.com." { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if cnRec.Hdr.Ttl != 10 { + t.Fatalf("Bad: %#v", in.Answer[0]) } } diff --git a/agent/dns_reverse_lookup_test.go b/agent/dns_reverse_lookup_test.go index 6a7cc49456..755921833b 100644 --- a/agent/dns_reverse_lookup_test.go +++ b/agent/dns_reverse_lookup_test.go @@ -17,45 +17,41 @@ func TestDNS_ReverseLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo2", - Address: "127.0.0.2", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo2", + Address: "127.0.0.2", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != "foo2.node.dc1.consul." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != "foo2.node.dc1.consul." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -64,47 +60,43 @@ func TestDNS_ReverseLookup_CustomDomain(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "custom" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo2", - Address: "127.0.0.2", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo2", + Address: "127.0.0.2", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != "foo2.node.dc1.custom." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != "foo2.node.dc1.custom." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -113,45 +105,41 @@ func TestDNS_ReverseLookup_IPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "::4242:4242", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "::4242:4242", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("2.4.2.4.2.4.2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("2.4.2.4.2.4.2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != "bar.node.dc1.consul." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != "bar.node.dc1.consul." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -160,58 +148,53 @@ func TestDNS_Compression_ReverseLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + // Register node. + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo2", + Address: "127.0.0.2", + } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - // Register node. - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo2", - Address: "127.0.0.2", - } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + m := new(dns.Msg) + m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) - m := new(dns.Msg) - m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) + conn, err := dns.Dial("udp", a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - conn, err := dns.Dial("udp", a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + // Do a manual exchange with compression on (the default). + if err := conn.WriteMsg(m); err != nil { + t.Fatalf("err: %v", err) + } + p := make([]byte, dns.MaxMsgSize) + compressed, err := conn.Read(p) + if err != nil { + t.Fatalf("err: %v", err) + } - // Do a manual exchange with compression on (the default). - if err := conn.WriteMsg(m); err != nil { - t.Fatalf("err: %v", err) - } - p := make([]byte, dns.MaxMsgSize) - compressed, err := conn.Read(p) - if err != nil { - t.Fatalf("err: %v", err) - } + // Disable compression and try again. + a.DNSDisableCompression(true) + if err := conn.WriteMsg(m); err != nil { + t.Fatalf("err: %v", err) + } + unc, err := conn.Read(p) + if err != nil { + t.Fatalf("err: %v", err) + } - // Disable compression and try again. - a.DNSDisableCompression(true) - if err := conn.WriteMsg(m); err != nil { - t.Fatalf("err: %v", err) - } - unc, err := conn.Read(p) - if err != nil { - t.Fatalf("err: %v", err) - } - - // We can't see the compressed status given the DNS API, so we just make - // sure the message is smaller to see if it's respecting the flag. - if compressed == 0 || unc == 0 || compressed >= unc { - t.Fatalf("doesn't look compressed: %d vs. %d", compressed, unc) - } - }) + // We can't see the compressed status given the DNS API, so we just make + // sure the message is smaller to see if it's respecting the flag. + if compressed == 0 || unc == 0 || compressed >= unc { + t.Fatalf("doesn't look compressed: %d vs. %d", compressed, unc) } } @@ -220,53 +203,49 @@ func TestDNS_ServiceReverseLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - Address: "127.0.0.2", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + Address: "127.0.0.2", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - m := new(dns.Msg) - m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != serviceCanonicalDNSName("db", "service", "dc1", "consul", nil)+"." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != serviceCanonicalDNSName("db", "service", "dc1", "consul", nil)+"." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -275,53 +254,49 @@ func TestDNS_ServiceReverseLookup_IPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "2001:db8::1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - Address: "2001:db8::ff00:42:8329", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "2001:db8::1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + Address: "2001:db8::ff00:42:8329", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - m := new(dns.Msg) - m.SetQuestion("9.2.3.8.2.4.0.0.0.0.f.f.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("9.2.3.8.2.4.0.0.0.0.f.f.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != serviceCanonicalDNSName("db", "service", "dc1", "consul", nil)+"." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != serviceCanonicalDNSName("db", "service", "dc1", "consul", nil)+"." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -330,55 +305,51 @@ func TestDNS_ServiceReverseLookup_CustomDomain(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "custom" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - Address: "127.0.0.2", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + Address: "127.0.0.2", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - m := new(dns.Msg) - m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("2.0.0.127.in-addr.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != serviceCanonicalDNSName("db", "service", "dc1", "custom", nil)+"." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != serviceCanonicalDNSName("db", "service", "dc1", "custom", nil)+"." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -387,53 +358,49 @@ func TestDNS_ServiceReverseLookupNodeAddress(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - Address: "127.0.0.1", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + Address: "127.0.0.1", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - m := new(dns.Msg) - m.SetQuestion("1.0.0.127.in-addr.arpa.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("1.0.0.127.in-addr.arpa.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - ptrRec, ok := in.Answer[0].(*dns.PTR) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if ptrRec.Ptr != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", ptrRec) - } - }) + ptrRec, ok := in.Answer[0].(*dns.PTR) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if ptrRec.Ptr != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", ptrRec) } } @@ -442,35 +409,31 @@ func TestDNS_ReverseLookup_NotFound(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - // do not configure recursors - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + // do not configure recursors + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Do not register any nodes - m := new(dns.Msg) - qName := "2.0.0.127.in-addr.arpa." - m.SetQuestion(qName, dns.TypeANY) + // Do not register any nodes + m := new(dns.Msg) + qName := "2.0.0.127.in-addr.arpa." + m.SetQuestion(qName, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Nil(t, in.Answer) - require.Nil(t, in.Extra) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Nil(t, in.Answer) + require.Nil(t, in.Extra) - require.Equal(t, dns.RcodeNameError, in.Rcode) + require.Equal(t, dns.RcodeNameError, in.Rcode) - question := in.Question[0] - require.Equal(t, qName, question.Name) - require.Equal(t, dns.TypeANY, question.Qtype) - require.Equal(t, uint16(dns.ClassINET), question.Qclass) + question := in.Question[0] + require.Equal(t, qName, question.Name) + require.Equal(t, dns.TypeANY, question.Qtype) + require.Equal(t, uint16(dns.ClassINET), question.Qclass) - soa, ok := in.Ns[0].(*dns.SOA) - require.True(t, ok) - require.Equal(t, "ns.consul.", soa.Ns) - require.Equal(t, "hostmaster.consul.", soa.Mbox) - }) - } + soa, ok := in.Ns[0].(*dns.SOA) + require.True(t, ok) + require.Equal(t, "ns.consul.", soa.Ns) + require.Equal(t, "hostmaster.consul.", soa.Mbox) } diff --git a/agent/dns_service_lookup_test.go b/agent/dns_service_lookup_test.go index dcad04696d..ef2a9dbe6d 100644 --- a/agent/dns_service_lookup_test.go +++ b/agent/dns_service_lookup_test.go @@ -26,61 +26,57 @@ func TestDNS_ServiceLookupNoMultiCNAME(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "198.18.0.1", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "foo.node.consul", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "198.18.0.1", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "foo.node.consul", + }, + } - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } - - // Register a second node node with the same service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "198.18.0.2", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "bar.node.consul", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - - // expect a CNAME and an A RR - require.Len(t, in.Answer, 2) - require.IsType(t, &dns.CNAME{}, in.Answer[0]) - require.IsType(t, &dns.A{}, in.Answer[1]) - }) + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) } + + // Register a second node node with the same service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "198.18.0.2", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "bar.node.consul", + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + + // expect a CNAME and an A RR + require.Len(t, in.Answer, 2) + require.IsType(t, &dns.CNAME{}, in.Answer[0]) + require.IsType(t, &dns.A{}, in.Answer[1]) } func TestDNS_ServiceLookupPreferNoCNAME(t *testing.T) { @@ -88,64 +84,60 @@ func TestDNS_ServiceLookupPreferNoCNAME(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "198.18.0.1", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "198.18.0.1", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "198.18.0.1", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "198.18.0.1", + }, + } - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } - - // Register a second node node with the same service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "198.18.0.2", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "bar.node.consul", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - - // expect an A RR - require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.A) - require.Truef(t, ok, "Not an A RR") - - require.Equal(t, "db.service.consul.", aRec.Hdr.Name) - require.Equal(t, "198.18.0.1", aRec.A.String()) - }) + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) } + + // Register a second node node with the same service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "198.18.0.2", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "bar.node.consul", + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + + // expect an A RR + require.Len(t, in.Answer, 1) + aRec, ok := in.Answer[0].(*dns.A) + require.Truef(t, ok, "Not an A RR") + + require.Equal(t, "db.service.consul.", aRec.Hdr.Name) + require.Equal(t, "198.18.0.1", aRec.A.String()) } func TestDNS_ServiceLookupMultiAddrNoCNAME(t *testing.T) { @@ -153,90 +145,86 @@ func TestDNS_ServiceLookupMultiAddrNoCNAME(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "198.18.0.1", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "198.18.0.1", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "198.18.0.1", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "198.18.0.1", + }, + } - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } - - // Register a second node node with the same service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "198.18.0.2", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "bar.node.consul", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Register a second node node with the same service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "baz", - Address: "198.18.0.3", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - Address: "198.18.0.3", - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - - // expect two A RRs - require.Len(t, in.Answer, 2) - require.IsType(t, &dns.A{}, in.Answer[0]) - require.Equal(t, "db.service.consul.", in.Answer[0].Header().Name) - isOneOfTheseIPs := func(ip net.IP) bool { - if ip.Equal(net.ParseIP("198.18.0.1")) || ip.Equal(net.ParseIP("198.18.0.3")) { - return true - } - return false - } - require.True(t, isOneOfTheseIPs(in.Answer[0].(*dns.A).A)) - require.IsType(t, &dns.A{}, in.Answer[1]) - require.Equal(t, "db.service.consul.", in.Answer[1].Header().Name) - require.True(t, isOneOfTheseIPs(in.Answer[1].(*dns.A).A)) - }) + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) } + + // Register a second node node with the same service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "198.18.0.2", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "bar.node.consul", + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register a second node node with the same service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "baz", + Address: "198.18.0.3", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + Address: "198.18.0.3", + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + + // expect two A RRs + require.Len(t, in.Answer, 2) + require.IsType(t, &dns.A{}, in.Answer[0]) + require.Equal(t, "db.service.consul.", in.Answer[0].Header().Name) + isOneOfTheseIPs := func(ip net.IP) bool { + if ip.Equal(net.ParseIP("198.18.0.1")) || ip.Equal(net.ParseIP("198.18.0.3")) { + return true + } + return false + } + require.True(t, isOneOfTheseIPs(in.Answer[0].(*dns.A).A)) + require.IsType(t, &dns.A{}, in.Answer[1]) + require.Equal(t, "db.service.consul.", in.Answer[1].Header().Name) + require.True(t, isOneOfTheseIPs(in.Answer[1].(*dns.A).A)) } func TestDNS_ServiceLookup(t *testing.T) { @@ -244,140 +232,136 @@ func TestDNS_ServiceLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + DNS: structs.QueryDNSOptions{ + TTL: "3s", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + + if strings.Contains(question, "query") { + // The query should have the TTL associated with the query registration. + if srvRec.Hdr.Ttl != 3 { + t.Fatalf("Bad: %#v", in.Answer[0]) } - - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - DNS: structs.QueryDNSOptions{ - TTL: "3s", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } + if aRec.Hdr.Ttl != 3 { + t.Fatalf("Bad: %#v", in.Extra[0]) } - - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", + } else { + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } - - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - - if strings.Contains(question, "query") { - // The query should have the TTL associated with the query registration. - if srvRec.Hdr.Ttl != 3 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.Hdr.Ttl != 3 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } else { - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) } + } - // Lookup a non-existing service/query, we should receive an SOA. - questions = []string{ - "nodb.service.consul.", - "nope.query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + } - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + // Lookup a non-existing service/query, we should receive an SOA. + questions = []string{ + "nodb.service.consul.", + "nope.query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - if len(in.Ns) != 1 { - t.Fatalf("Bad: %#v", in) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - soaRec, ok := in.Ns[0].(*dns.SOA) - if !ok { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - if soaRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - } - }) + if len(in.Ns) != 1 { + t.Fatalf("Bad: %#v", in) + } + + soaRec, ok := in.Ns[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + if soaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Ns[0]) + } } } @@ -390,93 +374,88 @@ func TestDNS_ServiceAddressWithTagLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - { - // This emulates a Nomad service registration. - // Using an internal RPC for Catalog.Register will not trigger the same condition. - err := a.Client().Agent().ServiceRegister(&api.AgentServiceRegistration{ - Kind: api.ServiceKindTypical, - ID: "db-1", - Name: "db", - Tags: []string{"primary"}, - Address: "127.0.0.1", - Port: 12345, - Checks: make([]*api.AgentServiceCheck, 0), - }) - require.NoError(t, err) - } - - { - err := a.Client().Agent().ServiceRegister(&api.AgentServiceRegistration{ - Kind: api.ServiceKindTypical, - ID: "db-2", - Name: "db", - Tags: []string{"secondary"}, - Address: "127.0.0.2", // The address here has to be different, or the DNS server will dedupe it. - Port: 12345, - Checks: make([]*api.AgentServiceCheck, 0), - }) - require.NoError(t, err) - } - - // Query the service using a tag - this also checks that we're filtering correctly - questions := []string{ - "_db._primary.service.dc1.consul.", // w/ RFC 2782 style syntax - "primary.db.service.dc1.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 1, "Expected only one result in the Answer section") - - srvRec, ok := in.Answer[0].(*dns.SRV) - require.True(t, ok, "Expected an SRV record in the Answer section") - require.Equal(t, uint16(12345), srvRec.Port) - require.Equal(t, "7f000001.addr.dc1.consul.", srvRec.Target) - - aRec, ok := in.Extra[0].(*dns.A) - require.True(t, ok, "Expected an A record in the Extra section") - require.Equal(t, "7f000001.addr.dc1.consul.", aRec.Hdr.Name) - require.Equal(t, "127.0.0.1", aRec.A.String()) - - if strings.Contains(question, "query") { - // The query should have the TTL associated with the query registration. - require.Equal(t, uint32(3), srvRec.Hdr.Ttl) - require.Equal(t, uint32(3), aRec.Hdr.Ttl) - } else { - require.Equal(t, uint32(0), srvRec.Hdr.Ttl) - require.Equal(t, uint32(0), aRec.Hdr.Ttl) - } - } - - // Multiple tags are not supported in the legacy DNS server - questions = []string{ - "banana._db._primary.service.dc1.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 0, "Expected no results in the Answer section") - - // For v1dns, we combine the tags with a period, which results in NXDOMAIN - // For v2dns, we are also return NXDomain - // The reported issue says that v2dns this is returning valid results. - require.Equal(t, dns.RcodeNameError, in.Rcode) - } + { + // This emulates a Nomad service registration. + // Using an internal RPC for Catalog.Register will not trigger the same condition. + err := a.Client().Agent().ServiceRegister(&api.AgentServiceRegistration{ + Kind: api.ServiceKindTypical, + ID: "db-1", + Name: "db", + Tags: []string{"primary"}, + Address: "127.0.0.1", + Port: 12345, + Checks: make([]*api.AgentServiceCheck, 0), }) + require.NoError(t, err) + } + + { + err := a.Client().Agent().ServiceRegister(&api.AgentServiceRegistration{ + Kind: api.ServiceKindTypical, + ID: "db-2", + Name: "db", + Tags: []string{"secondary"}, + Address: "127.0.0.2", // The address here has to be different, or the DNS server will dedupe it. + Port: 12345, + Checks: make([]*api.AgentServiceCheck, 0), + }) + require.NoError(t, err) + } + + // Query the service using a tag - this also checks that we're filtering correctly + questions := []string{ + "_db._primary.service.dc1.consul.", // w/ RFC 2782 style syntax + "primary.db.service.dc1.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 1, "Expected only one result in the Answer section") + + srvRec, ok := in.Answer[0].(*dns.SRV) + require.True(t, ok, "Expected an SRV record in the Answer section") + require.Equal(t, uint16(12345), srvRec.Port) + require.Equal(t, "7f000001.addr.dc1.consul.", srvRec.Target) + + aRec, ok := in.Extra[0].(*dns.A) + require.True(t, ok, "Expected an A record in the Extra section") + require.Equal(t, "7f000001.addr.dc1.consul.", aRec.Hdr.Name) + require.Equal(t, "127.0.0.1", aRec.A.String()) + + if strings.Contains(question, "query") { + // The query should have the TTL associated with the query registration. + require.Equal(t, uint32(3), srvRec.Hdr.Ttl) + require.Equal(t, uint32(3), aRec.Hdr.Ttl) + } else { + require.Equal(t, uint32(0), srvRec.Hdr.Ttl) + require.Equal(t, uint32(0), aRec.Hdr.Ttl) + } + } + + // Multiple tags are not supported in the legacy DNS server + questions = []string{ + "banana._db._primary.service.dc1.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 0, "Expected no results in the Answer section") + + // We combine the tags with a period, which results in NXDOMAIN + // The reported issue says that v2dns this is returning valid results. + require.Equal(t, dns.RcodeNameError, in.Rcode) } } @@ -485,63 +464,59 @@ func TestDNS_ServiceLookupWithInternalServiceAddress(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` node_name = "my.test-node" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - // The service is using the consul DNS name as service address - // which triggers a lookup loop and a subsequent stack overflow - // crash. - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Address: "db.service.consul", - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - // Looking up the service should not trigger a loop - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAnswer := []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{Name: "db.service.consul.", Rrtype: 0x21, Class: 0x1, Rdlength: 0x1b}, - Priority: 0x1, - Weight: 0x1, - Port: 12345, - Target: "foo.node.dc1.consul.", - }, - } - require.Equal(t, wantAnswer, in.Answer, "answer") - wantExtra := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "foo.node.dc1.consul.", Rrtype: 0x1, Class: 0x1, Rdlength: 0x4}, - A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 - }, - } - require.Equal(t, wantExtra, in.Extra, "extra") - }) + // Register a node with a service. + // The service is using the consul DNS name as service address + // which triggers a lookup loop and a subsequent stack overflow + // crash. + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Address: "db.service.consul", + Port: 12345, + }, } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + // Looking up the service should not trigger a loop + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + wantAnswer := []dns.RR{ + &dns.SRV{ + Hdr: dns.RR_Header{Name: "db.service.consul.", Rrtype: 0x21, Class: 0x1, Rdlength: 0x1b}, + Priority: 0x1, + Weight: 0x1, + Port: 12345, + Target: "foo.node.dc1.consul.", + }, + } + require.Equal(t, wantAnswer, in.Answer, "answer") + wantExtra := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "foo.node.dc1.consul.", Rrtype: 0x1, Class: 0x1, Rdlength: 0x4}, + A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 + }, + } + require.Equal(t, wantExtra, in.Extra, "extra") } func TestDNS_ConnectServiceLookup(t *testing.T) { @@ -549,50 +524,47 @@ func TestDNS_ConnectServiceLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register - { - args := structs.TestRegisterRequestProxy(t) - args.Address = "127.0.0.55" - args.Service.Proxy.DestinationServiceName = "db" - args.Service.Address = "" - args.Service.Port = 12345 - var out struct{} - require.Nil(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } - - // Look up the service - questions := []string{ - "db.connect.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.Nil(t, err) - require.Len(t, in.Answer, 1) - - srvRec, ok := in.Answer[0].(*dns.SRV) - require.True(t, ok) - require.Equal(t, uint16(12345), srvRec.Port) - require.Equal(t, "foo.node.dc1.consul.", srvRec.Target) - require.Equal(t, uint32(0), srvRec.Hdr.Ttl) - - cnameRec, ok := in.Extra[0].(*dns.A) - require.True(t, ok) - require.Equal(t, "foo.node.dc1.consul.", cnameRec.Hdr.Name) - require.Equal(t, uint32(0), srvRec.Hdr.Ttl) - require.Equal(t, "127.0.0.55", cnameRec.A.String()) - } - }) + // Register + { + args := structs.TestRegisterRequestProxy(t) + args.Address = "127.0.0.55" + args.Service.Proxy.DestinationServiceName = "db" + args.Service.Address = "" + args.Service.Port = 12345 + var out struct{} + require.Nil(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) } + + // Look up the service + questions := []string{ + "db.connect.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.Nil(t, err) + require.Len(t, in.Answer, 1) + + srvRec, ok := in.Answer[0].(*dns.SRV) + require.True(t, ok) + require.Equal(t, uint16(12345), srvRec.Port) + require.Equal(t, "foo.node.dc1.consul.", srvRec.Target) + require.Equal(t, uint32(0), srvRec.Hdr.Ttl) + + cnameRec, ok := in.Extra[0].(*dns.A) + require.True(t, ok) + require.Equal(t, "foo.node.dc1.consul.", cnameRec.Hdr.Name) + require.Equal(t, uint32(0), srvRec.Hdr.Ttl) + require.Equal(t, "127.0.0.55", cnameRec.A.String()) + } + } func TestDNS_IngressServiceLookup(t *testing.T) { @@ -600,106 +572,102 @@ func TestDNS_IngressServiceLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register ingress-gateway service - { - args := structs.TestRegisterIngressGateway(t) - var out struct{} - require.Nil(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } + // Register ingress-gateway service + { + args := structs.TestRegisterIngressGateway(t) + var out struct{} + require.Nil(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + } - // Register db service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Address: "", - Port: 80, + // Register db service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Address: "", + Port: 80, + }, + } + + var out struct{} + require.Nil(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + } + + // Register proxy-defaults with 'http' protocol + { + req := structs.ConfigEntryRequest{ + Op: structs.ConfigEntryUpsert, + Datacenter: "dc1", + Entry: &structs.ProxyConfigEntry{ + Kind: structs.ProxyDefaults, + Name: structs.ProxyConfigGlobal, + Config: map[string]interface{}{ + "protocol": "http", + }, + }, + WriteRequest: structs.WriteRequest{Token: "root"}, + } + var out bool + require.Nil(t, a.RPC(context.Background(), "ConfigEntry.Apply", req, &out)) + require.True(t, out) + } + + // Register ingress-gateway config entry + { + args := &structs.IngressGatewayConfigEntry{ + Name: "ingress-gateway", + Kind: structs.IngressGateway, + Listeners: []structs.IngressListener{ + { + Port: 8888, + Protocol: "http", + Services: []structs.IngressService{ + {Name: "db"}, + {Name: "api"}, }, - } + }, + }, + } - var out struct{} - require.Nil(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } + req := structs.ConfigEntryRequest{ + Op: structs.ConfigEntryUpsert, + Datacenter: "dc1", + Entry: args, + } + var out bool + require.Nil(t, a.RPC(context.Background(), "ConfigEntry.Apply", req, &out)) + require.True(t, out) + } - // Register proxy-defaults with 'http' protocol - { - req := structs.ConfigEntryRequest{ - Op: structs.ConfigEntryUpsert, - Datacenter: "dc1", - Entry: &structs.ProxyConfigEntry{ - Kind: structs.ProxyDefaults, - Name: structs.ProxyConfigGlobal, - Config: map[string]interface{}{ - "protocol": "http", - }, - }, - WriteRequest: structs.WriteRequest{Token: "root"}, - } - var out bool - require.Nil(t, a.RPC(context.Background(), "ConfigEntry.Apply", req, &out)) - require.True(t, out) - } + // Look up the service + questions := []string{ + "api.ingress.consul.", + "api.ingress.dc1.consul.", + "db.ingress.consul.", + "db.ingress.dc1.consul.", + } + for _, question := range questions { + t.Run(question, func(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) - // Register ingress-gateway config entry - { - args := &structs.IngressGatewayConfigEntry{ - Name: "ingress-gateway", - Kind: structs.IngressGateway, - Listeners: []structs.IngressListener{ - { - Port: 8888, - Protocol: "http", - Services: []structs.IngressService{ - {Name: "db"}, - {Name: "api"}, - }, - }, - }, - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.Nil(t, err) + require.Len(t, in.Answer, 1) - req := structs.ConfigEntryRequest{ - Op: structs.ConfigEntryUpsert, - Datacenter: "dc1", - Entry: args, - } - var out bool - require.Nil(t, a.RPC(context.Background(), "ConfigEntry.Apply", req, &out)) - require.True(t, out) - } - - // Look up the service - questions := []string{ - "api.ingress.consul.", - "api.ingress.dc1.consul.", - "db.ingress.consul.", - "db.ingress.dc1.consul.", - } - for _, question := range questions { - t.Run(question, func(t *testing.T) { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.Nil(t, err) - require.Len(t, in.Answer, 1) - - cnameRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok) - require.Equal(t, question, cnameRec.Hdr.Name) - require.Equal(t, uint32(0), cnameRec.Hdr.Ttl) - require.Equal(t, "127.0.0.1", cnameRec.A.String()) - }) - } + cnameRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok) + require.Equal(t, question, cnameRec.Hdr.Name) + require.Equal(t, uint32(0), cnameRec.Hdr.Ttl) + require.Equal(t, "127.0.0.1", cnameRec.A.String()) }) } } @@ -709,63 +677,59 @@ func TestDNS_ExternalServiceLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with an external service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "www.google.com", - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - }, - } + // Register a node with an external service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "www.google.com", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service - questions := []string{ - "db.service.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the service + questions := []string{ + "db.service.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 || len(in.Extra) > 0 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 || len(in.Extra) > 0 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "www.google.com." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - } - }) + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "www.google.com." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } } } @@ -774,104 +738,101 @@ func TestDNS_ExternalServiceToConsulCNAMELookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "CONSUL." node_name = "test node" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register the initial node with a service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "web", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "web", - Port: 12345, - }, - } + // Register the initial node with a service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "web", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "web", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Register an external service pointing to the 'web' service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "alias", - Address: "web.service.consul", - Service: &structs.NodeService{ - Service: "alias", - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Look up the service directly - questions := []string{ - "alias.service.consul.", - "alias.service.CoNsUl.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } - - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "web.service.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - - if len(in.Extra) != 1 { - t.Fatalf("Bad: %#v", in) - } - - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "web.service.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } } + + // Register an external service pointing to the 'web' service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "alias", + Address: "web.service.consul", + Service: &structs.NodeService{ + Service: "alias", + Port: 12345, + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly + questions := []string{ + "alias.service.consul.", + "alias.service.CoNsUl.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "web.service.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + + if len(in.Extra) != 1 { + t.Fatalf("Bad: %#v", in) + } + + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "web.service.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + } + } func TestDNS_ExternalServiceToConsulCNAMENestedLookup(t *testing.T) { @@ -879,132 +840,128 @@ func TestDNS_ExternalServiceToConsulCNAMENestedLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` node_name = "test-node" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register the initial node with a service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "web", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "web", - Port: 12345, - }, - } + // Register the initial node with a service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "web", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "web", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an external service pointing to the 'web' service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "alias", - Address: "web.service.consul", - Service: &structs.NodeService{ - Service: "alias", - Port: 12345, - }, - } + // Register an external service pointing to the 'web' service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "alias", + Address: "web.service.consul", + Service: &structs.NodeService{ + Service: "alias", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an external service pointing to the 'alias' service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "alias2", - Address: "alias.service.consul", - Service: &structs.NodeService{ - Service: "alias2", - Port: 12345, - }, - } + // Register an external service pointing to the 'alias' service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "alias2", + Address: "alias.service.consul", + Service: &structs.NodeService{ + Service: "alias2", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly - questions := []string{ - "alias2.service.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the service directly + questions := []string{ + "alias2.service.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "alias.service.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if len(in.Extra) != 2 { - t.Fatalf("Bad: %#v", in) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "alias.service.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if len(in.Extra) != 2 { + t.Fatalf("Bad: %#v", in) + } - cnameRec, ok := in.Extra[0].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if cnameRec.Hdr.Name != "alias.service.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if cnameRec.Target != "web.service.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if cnameRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } + cnameRec, ok := in.Extra[0].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if cnameRec.Hdr.Name != "alias.service.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if cnameRec.Target != "web.service.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if cnameRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } - aRec, ok := in.Extra[1].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - if aRec.Hdr.Name != "web.service.consul." { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - } - }) + aRec, ok := in.Extra[1].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[1]) + } + if aRec.Hdr.Name != "web.service.consul." { + t.Fatalf("Bad: %#v", in.Extra[1]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[1]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[1]) + } } } @@ -1013,99 +970,96 @@ func TestDNS_ServiceLookup_ServiceAddress_A(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Address: "127.0.0.2", - Port: 12345, - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Address: "127.0.0.2", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } - - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "7f000002.addr.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "7f000002.addr.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.2" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } } + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "7f000002.addr.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "7f000002.addr.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.2" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + } + } func TestDNS_AltDomain_ServiceLookup_ServiceAddress_A(t *testing.T) { @@ -1113,105 +1067,101 @@ func TestDNS_AltDomain_ServiceLookup_ServiceAddress_A(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` alt_domain = "test-domain" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Address: "127.0.0.2", - Port: 12345, - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Address: "127.0.0.2", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []struct { - ask string - wantDomain string - }{ - {"db.service.consul.", "consul."}, - {id + ".query.consul.", "consul."}, - {"db.service.test-domain.", "test-domain."}, - {id + ".query.test-domain.", "test-domain."}, - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question.ask, dns.TypeSRV) + // Look up the service directly and via prepared query. + questions := []struct { + ask string + wantDomain string + }{ + {"db.service.consul.", "consul."}, + {id + ".query.consul.", "consul."}, + {"db.service.test-domain.", "test-domain."}, + {id + ".query.test-domain.", "test-domain."}, + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "7f000002.addr.dc1."+question.wantDomain { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "7f000002.addr.dc1."+question.wantDomain { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "7f000002.addr.dc1."+question.wantDomain { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.2" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "7f000002.addr.dc1."+question.wantDomain { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.2" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } } } @@ -1228,110 +1178,106 @@ func TestDNS_ServiceLookup_ServiceAddress_SRV(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service whose address isn't an IP. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Address: "www.google.com", - Port: 12345, - }, - } + // Register a node with a service whose address isn't an IP. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Address: "www.google.com", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - // Specify prepared query name containing "." to test - // since that is technically supported (though atypical). - var id string - preparedQueryName := "query.name.with.dots" - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: preparedQueryName, - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + // Specify prepared query name containing "." to test + // since that is technically supported (though atypical). + var id string + preparedQueryName := "query.name.with.dots" + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: preparedQueryName, + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - preparedQueryName + ".query.consul.", - fmt.Sprintf("_%s._tcp.query.consul.", id), - fmt.Sprintf("_%s._tcp.query.consul.", preparedQueryName), - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + preparedQueryName + ".query.consul.", + fmt.Sprintf("_%s._tcp.query.consul.", id), + fmt.Sprintf("_%s._tcp.query.consul.", preparedQueryName), + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "www.google.com." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "www.google.com." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - // Should have google CNAME - cnRec, ok := in.Extra[0].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if cnRec.Target != "google.com." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } + // Should have google CNAME + cnRec, ok := in.Extra[0].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if cnRec.Target != "google.com." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } - // Check we recursively resolve - aRec, ok := in.Extra[1].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - if aRec.A.String() != "1.2.3.4" { - t.Fatalf("Bad: %s", aRec.A.String()) - } - } - }) + // Check we recursively resolve + aRec, ok := in.Extra[1].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[1]) + } + if aRec.A.String() != "1.2.3.4" { + t.Fatalf("Bad: %s", aRec.A.String()) + } } } @@ -1340,98 +1286,94 @@ func TestDNS_ServiceLookup_ServiceAddressIPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Address: "2607:20:4005:808::200e", - Port: 12345, - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Address: "2607:20:4005:808::200e", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "2607002040050808000000000000200e.addr.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "2607002040050808000000000000200e.addr.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - aRec, ok := in.Extra[0].(*dns.AAAA) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "2607002040050808000000000000200e.addr.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.AAAA.String() != "2607:20:4005:808::200e" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + aRec, ok := in.Extra[0].(*dns.AAAA) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "2607002040050808000000000000200e.addr.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.AAAA.String() != "2607:20:4005:808::200e" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } } } @@ -1440,105 +1382,101 @@ func TestDNS_AltDomain_ServiceLookup_ServiceAddressIPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` alt_domain = "test-domain" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Address: "2607:20:4005:808::200e", - Port: 12345, - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Address: "2607:20:4005:808::200e", + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []struct { - ask string - want string - }{ - {"db.service.consul.", "2607002040050808000000000000200e.addr.dc1.consul."}, - {"db.service.test-domain.", "2607002040050808000000000000200e.addr.dc1.test-domain."}, - {id + ".query.consul.", "2607002040050808000000000000200e.addr.dc1.consul."}, - {id + ".query.test-domain.", "2607002040050808000000000000200e.addr.dc1.test-domain."}, - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question.ask, dns.TypeSRV) + // Look up the service directly and via prepared query. + questions := []struct { + ask string + want string + }{ + {"db.service.consul.", "2607002040050808000000000000200e.addr.dc1.consul."}, + {"db.service.test-domain.", "2607002040050808000000000000200e.addr.dc1.test-domain."}, + {id + ".query.consul.", "2607002040050808000000000000200e.addr.dc1.consul."}, + {id + ".query.test-domain.", "2607002040050808000000000000200e.addr.dc1.test-domain."}, + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != question.want { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != question.want { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - aRec, ok := in.Extra[0].(*dns.AAAA) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != question.want { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.AAAA.String() != "2607:20:4005:808::200e" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + aRec, ok := in.Extra[0].(*dns.AAAA) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != question.want { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.AAAA.String() != "2607:20:4005:808::200e" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } } } @@ -1547,211 +1485,207 @@ func TestDNS_ServiceLookup_WanTranslation(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a1 := NewTestAgent(t, ` + a1 := NewTestAgent(t, ` datacenter = "dc1" translate_wan_addrs = true acl_datacenter = "" - `+experimentsHCL) - defer a1.Shutdown() + `) + defer a1.Shutdown() - a2 := NewTestAgent(t, ` + a2 := NewTestAgent(t, ` datacenter = "dc2" translate_wan_addrs = true acl_datacenter = "" - `+experimentsHCL) - defer a2.Shutdown() + `) + defer a2.Shutdown() - // Join WAN cluster - addr := fmt.Sprintf("127.0.0.1:%d", a1.Config.SerfPortWAN) - _, err := a2.JoinWAN([]string{addr}) - require.NoError(t, err) + // Join WAN cluster + addr := fmt.Sprintf("127.0.0.1:%d", a1.Config.SerfPortWAN) + _, err := a2.JoinWAN([]string{addr}) + require.NoError(t, err) + retry.Run(t, func(r *retry.R) { + require.Len(r, a1.WANMembers(), 2) + require.Len(r, a2.WANMembers(), 2) + }) + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc2", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + require.NoError(t, a2.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) + } + + type testCase struct { + nodeTaggedAddresses map[string]string + serviceAddress string + serviceTaggedAddresses map[string]structs.ServiceAddress + + dnsAddr string + + expectedPort uint16 + expectedAddress string + expectedARRName string + } + + cases := map[string]testCase{ + "node-addr-from-dc1": { + dnsAddr: a1.config.DNSAddrs[0].String(), + expectedPort: 8080, + expectedAddress: "127.0.0.1", + expectedARRName: "foo.node.dc2.consul.", + }, + "node-wan-from-dc1": { + dnsAddr: a1.config.DNSAddrs[0].String(), + nodeTaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + expectedPort: 8080, + expectedAddress: "127.0.0.2", + expectedARRName: "7f000002.addr.dc2.consul.", + }, + "service-addr-from-dc1": { + dnsAddr: a1.config.DNSAddrs[0].String(), + nodeTaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + serviceAddress: "10.0.1.1", + expectedPort: 8080, + expectedAddress: "10.0.1.1", + expectedARRName: "0a000101.addr.dc2.consul.", + }, + "service-wan-from-dc1": { + dnsAddr: a1.config.DNSAddrs[0].String(), + nodeTaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + serviceAddress: "10.0.1.1", + serviceTaggedAddresses: map[string]structs.ServiceAddress{ + "wan": { + Address: "198.18.0.1", + Port: 80, + }, + }, + expectedPort: 80, + expectedAddress: "198.18.0.1", + expectedARRName: "c6120001.addr.dc2.consul.", + }, + "node-addr-from-dc2": { + dnsAddr: a2.config.DNSAddrs[0].String(), + expectedPort: 8080, + expectedAddress: "127.0.0.1", + expectedARRName: "foo.node.dc2.consul.", + }, + "node-wan-from-dc2": { + dnsAddr: a2.config.DNSAddrs[0].String(), + nodeTaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + expectedPort: 8080, + expectedAddress: "127.0.0.1", + expectedARRName: "foo.node.dc2.consul.", + }, + "service-addr-from-dc2": { + dnsAddr: a2.config.DNSAddrs[0].String(), + nodeTaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + serviceAddress: "10.0.1.1", + expectedPort: 8080, + expectedAddress: "10.0.1.1", + expectedARRName: "0a000101.addr.dc2.consul.", + }, + "service-wan-from-dc2": { + dnsAddr: a2.config.DNSAddrs[0].String(), + nodeTaggedAddresses: map[string]string{ + "wan": "127.0.0.2", + }, + serviceAddress: "10.0.1.1", + serviceTaggedAddresses: map[string]structs.ServiceAddress{ + "wan": { + Address: "198.18.0.1", + Port: 80, + }, + }, + expectedPort: 8080, + expectedAddress: "10.0.1.1", + expectedARRName: "0a000101.addr.dc2.consul.", + }, + } + + for name, tc := range cases { + name := name + tc := tc + t.Run(name, func(t *testing.T) { + // Register a remote node with a service. This is in a retry since we + // need the datacenter to have a route which takes a little more time + // beyond the join, and we don't have direct access to the router here. retry.Run(t, func(r *retry.R) { - require.Len(r, a1.WANMembers(), 2) - require.Len(r, a2.WANMembers(), 2) - }) - - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc2", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, + args := &structs.RegisterRequest{ + Datacenter: "dc2", + Node: "foo", + Address: "127.0.0.1", + TaggedAddresses: tc.nodeTaggedAddresses, + Service: &structs.NodeService{ + Service: "db", + Address: tc.serviceAddress, + Port: 8080, + TaggedAddresses: tc.serviceTaggedAddresses, }, } - require.NoError(t, a2.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) + + var out struct{} + require.NoError(r, a2.RPC(context.Background(), "Catalog.Register", args, &out)) + }) + + // Look up the SRV record via service and prepared query. + questions := []string{ + "db.service.dc2.consul.", + id + ".query.dc2.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + + addr := tc.dnsAddr + in, _, err := c.Exchange(m, addr) + require.NoError(t, err) + require.Len(t, in.Answer, 1) + srvRec, ok := in.Answer[0].(*dns.SRV) + require.True(t, ok, "Bad: %#v", in.Answer[0]) + require.Equal(t, tc.expectedPort, srvRec.Port) + + aRec, ok := in.Extra[0].(*dns.A) + require.True(t, ok, "Bad: %#v", in.Extra[0]) + require.Equal(t, tc.expectedARRName, aRec.Hdr.Name) + require.Equal(t, tc.expectedAddress, aRec.A.String()) } - type testCase struct { - nodeTaggedAddresses map[string]string - serviceAddress string - serviceTaggedAddresses map[string]structs.ServiceAddress + // Also check the A record directly + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) - dnsAddr string + c := new(dns.Client) + addr := tc.dnsAddr + in, _, err := c.Exchange(m, addr) + require.NoError(t, err) + require.Len(t, in.Answer, 1) - expectedPort uint16 - expectedAddress string - expectedARRName string - } - - cases := map[string]testCase{ - "node-addr-from-dc1": { - dnsAddr: a1.config.DNSAddrs[0].String(), - expectedPort: 8080, - expectedAddress: "127.0.0.1", - expectedARRName: "foo.node.dc2.consul.", - }, - "node-wan-from-dc1": { - dnsAddr: a1.config.DNSAddrs[0].String(), - nodeTaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - expectedPort: 8080, - expectedAddress: "127.0.0.2", - expectedARRName: "7f000002.addr.dc2.consul.", - }, - "service-addr-from-dc1": { - dnsAddr: a1.config.DNSAddrs[0].String(), - nodeTaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - serviceAddress: "10.0.1.1", - expectedPort: 8080, - expectedAddress: "10.0.1.1", - expectedARRName: "0a000101.addr.dc2.consul.", - }, - "service-wan-from-dc1": { - dnsAddr: a1.config.DNSAddrs[0].String(), - nodeTaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - serviceAddress: "10.0.1.1", - serviceTaggedAddresses: map[string]structs.ServiceAddress{ - "wan": { - Address: "198.18.0.1", - Port: 80, - }, - }, - expectedPort: 80, - expectedAddress: "198.18.0.1", - expectedARRName: "c6120001.addr.dc2.consul.", - }, - "node-addr-from-dc2": { - dnsAddr: a2.config.DNSAddrs[0].String(), - expectedPort: 8080, - expectedAddress: "127.0.0.1", - expectedARRName: "foo.node.dc2.consul.", - }, - "node-wan-from-dc2": { - dnsAddr: a2.config.DNSAddrs[0].String(), - nodeTaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - expectedPort: 8080, - expectedAddress: "127.0.0.1", - expectedARRName: "foo.node.dc2.consul.", - }, - "service-addr-from-dc2": { - dnsAddr: a2.config.DNSAddrs[0].String(), - nodeTaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - serviceAddress: "10.0.1.1", - expectedPort: 8080, - expectedAddress: "10.0.1.1", - expectedARRName: "0a000101.addr.dc2.consul.", - }, - "service-wan-from-dc2": { - dnsAddr: a2.config.DNSAddrs[0].String(), - nodeTaggedAddresses: map[string]string{ - "wan": "127.0.0.2", - }, - serviceAddress: "10.0.1.1", - serviceTaggedAddresses: map[string]structs.ServiceAddress{ - "wan": { - Address: "198.18.0.1", - Port: 80, - }, - }, - expectedPort: 8080, - expectedAddress: "10.0.1.1", - expectedARRName: "0a000101.addr.dc2.consul.", - }, - } - - for name, tc := range cases { - name := name - tc := tc - t.Run(name, func(t *testing.T) { - // Register a remote node with a service. This is in a retry since we - // need the datacenter to have a route which takes a little more time - // beyond the join, and we don't have direct access to the router here. - retry.Run(t, func(r *retry.R) { - args := &structs.RegisterRequest{ - Datacenter: "dc2", - Node: "foo", - Address: "127.0.0.1", - TaggedAddresses: tc.nodeTaggedAddresses, - Service: &structs.NodeService{ - Service: "db", - Address: tc.serviceAddress, - Port: 8080, - TaggedAddresses: tc.serviceTaggedAddresses, - }, - } - - var out struct{} - require.NoError(r, a2.RPC(context.Background(), "Catalog.Register", args, &out)) - }) - - // Look up the SRV record via service and prepared query. - questions := []string{ - "db.service.dc2.consul.", - id + ".query.dc2.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - - addr := tc.dnsAddr - in, _, err := c.Exchange(m, addr) - require.NoError(t, err) - require.Len(t, in.Answer, 1) - srvRec, ok := in.Answer[0].(*dns.SRV) - require.True(t, ok, "Bad: %#v", in.Answer[0]) - require.Equal(t, tc.expectedPort, srvRec.Port) - - aRec, ok := in.Extra[0].(*dns.A) - require.True(t, ok, "Bad: %#v", in.Extra[0]) - require.Equal(t, tc.expectedARRName, aRec.Hdr.Name) - require.Equal(t, tc.expectedAddress, aRec.A.String()) - } - - // Also check the A record directly - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) - - c := new(dns.Client) - addr := tc.dnsAddr - in, _, err := c.Exchange(m, addr) - require.NoError(t, err) - require.Len(t, in.Answer, 1) - - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok, "Bad: %#v", in.Answer[0]) - require.Equal(t, question, aRec.Hdr.Name) - require.Equal(t, tc.expectedAddress, aRec.A.String()) - } - }) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok, "Bad: %#v", in.Answer[0]) + require.Equal(t, question, aRec.Hdr.Name) + require.Equal(t, tc.expectedAddress, aRec.A.String()) } }) } @@ -1779,216 +1713,8 @@ func TestDNS_ServiceLookup_CaseInsensitive(t *testing.T) { } for _, tst := range tests { t.Run(fmt.Sprintf("A lookup %v", tst.name), func(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, fmt.Sprintf("%s %s", tst.config, experimentsHCL)) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "Db", - Tags: []string{"Primary"}, - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Register an equivalent prepared query, as well as a name. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "somequery", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Try some variations to make sure case doesn't matter. - questions := []string{ - "primary.Db.service.consul.", - "primary.db.service.consul.", - "pRIMARY.dB.service.consul.", - "PRIMARY.dB.service.consul.", - "db.service.consul.", - "DB.service.consul.", - "Db.service.consul.", - "somequery.query.consul.", - "SomeQuery.query.consul.", - "SOMEQUERY.query.consul.", - } - - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) - - c := new(dns.Client) - retry.Run(t, func(r *retry.R) { - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - r.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - r.Fatalf("question %v, empty lookup: %#v", question, in) - } - }) - } - }) - } - }) - } -} - -// V2 DNS: we have deprecated support for service tags w/ periods -func TestDNS_ServiceLookup_TagPeriod(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - for name, experimentsHCL := range getVersionHCL(false) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") - - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"v1.primary"}, - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m1 := new(dns.Msg) - m1.SetQuestion("v1.primary2.db.service.consul.", dns.TypeSRV) - - c1 := new(dns.Client) - in, _, err := c1.Exchange(m1, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 0 { - t.Fatalf("Bad: %#v", in) - } - - m := new(dns.Msg) - m.SetQuestion("v1.primary.db.service.consul.", dns.TypeSRV) - - c := new(dns.Client) - in, _, err = c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } - - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - }) - } -} - -// TestDNS_ServiceLookup_ExtraTags tests tag behavior. -// With v1dns, we still support period tags, but if a tag is not found it's an NXDOMAIN code. -// With v2dns, we do not support period tags, so it's an NXDOMAIN code because the name is not valid. -func TestDNS_ServiceLookup_ExtraTags(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") - - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m1 := new(dns.Msg) - m1.SetQuestion("dummy.primary.db.service.consul.", dns.TypeSRV) - - c1 := new(dns.Client) - in, _, err := c1.Exchange(m1, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 0, "Expected no answer") - require.Equal(t, dns.RcodeNameError, in.Rcode) - }) - } -} - -func TestDNS_ServiceLookup_PreparedQueryNamePeriod(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) + a := NewTestAgent(t, tst.config) defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") @@ -1999,7 +1725,8 @@ func TestDNS_ServiceLookup_PreparedQueryNamePeriod(t *testing.T) { Node: "foo", Address: "127.0.0.1", Service: &structs.NodeService{ - Service: "db", + Service: "Db", + Tags: []string{"Primary"}, Port: 12345, }, } @@ -2010,170 +1737,355 @@ func TestDNS_ServiceLookup_PreparedQueryNamePeriod(t *testing.T) { } } - // Register a prepared query with a period in the name. + // Register an equivalent prepared query, as well as a name. + var id string { args := &structs.PreparedQueryRequest{ Datacenter: "dc1", Op: structs.PreparedQueryCreate, Query: &structs.PreparedQuery{ - Name: "some.query.we.like", + Name: "somequery", Service: structs.ServiceQuery{ Service: "db", }, }, } - - var id string if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { t.Fatalf("err: %v", err) } } - m := new(dns.Msg) - m.SetQuestion("some.query.we.like.query.consul.", dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) + // Try some variations to make sure case doesn't matter. + questions := []string{ + "primary.Db.service.consul.", + "primary.db.service.consul.", + "pRIMARY.dB.service.consul.", + "PRIMARY.dB.service.consul.", + "db.service.consul.", + "DB.service.consul.", + "Db.service.consul.", + "somequery.query.consul.", + "SomeQuery.query.consul.", + "SOMEQUERY.query.consul.", } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } + c := new(dns.Client) + retry.Run(t, func(r *retry.R) { + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + r.Fatalf("err: %v", err) + } - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) + if len(in.Answer) != 1 { + r.Fatalf("question %v, empty lookup: %#v", question, in) + } + }) } }) } } +// We have deprecated support for service tags w/ periods +func TestDNS_ServiceLookup_TagPeriod(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"v1.primary"}, + Port: 12345, + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m1 := new(dns.Msg) + m1.SetQuestion("v1.primary2.db.service.consul.", dns.TypeSRV) + + c1 := new(dns.Client) + in, _, err := c1.Exchange(m1, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 0 { + t.Fatalf("Bad: %#v", in) + } + + m := new(dns.Msg) + m.SetQuestion("v1.primary.db.service.consul.", dns.TypeSRV) + + c := new(dns.Client) + in, _, err = c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } +} + +// TestDNS_ServiceLookup_ExtraTags tests tag behavior. +func TestDNS_ServiceLookup_ExtraTags(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m1 := new(dns.Msg) + m1.SetQuestion("dummy.primary.db.service.consul.", dns.TypeSRV) + + c1 := new(dns.Client) + in, _, err := c1.Exchange(m1, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 0, "Expected no answer") + require.Equal(t, dns.RcodeNameError, in.Rcode) +} + +func TestDNS_ServiceLookup_PreparedQueryNamePeriod(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register a prepared query with a period in the name. + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "some.query.we.like", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + + var id string + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + m := new(dns.Msg) + m.SetQuestion("some.query.we.like.query.consul.", dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } +} + func TestDNS_ServiceLookup_Dedup(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a single node with multiple instances of a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register a single node with multiple instances of a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - ID: "db2", - Service: "db", - Tags: []string{"replica"}, - Port: 12345, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + ID: "db2", + Service: "db", + Tags: []string{"replica"}, + Port: 12345, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - ID: "db3", - Service: "db", - Tags: []string{"replica"}, - Port: 12346, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + ID: "db3", + Service: "db", + Tags: []string{"replica"}, + Port: 12346, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query, make sure only - // one IP is returned. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the service directly and via prepared query, make sure only + // one IP is returned. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - aRec, ok := in.Answer[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - } - }) + aRec, ok := in.Answer[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Answer[0]) + } } } @@ -2182,136 +2094,132 @@ func TestDNS_ServiceLookup_Dedup_SRV(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a single node with multiple instances of a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register a single node with multiple instances of a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - ID: "db2", - Service: "db", - Tags: []string{"replica"}, - Port: 12345, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + ID: "db2", + Service: "db", + Tags: []string{"replica"}, + Port: 12345, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - ID: "db3", - Service: "db", - Tags: []string{"replica"}, - Port: 12346, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + ID: "db3", + Service: "db", + Tags: []string{"replica"}, + Port: 12346, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query, make sure only - // one IP is returned and two unique ports are returned. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the service directly and via prepared query, make sure only + // one IP is returned and two unique ports are returned. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 2 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 2 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 && srvRec.Port != 12346 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 && srvRec.Port != 12346 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } - srvRec, ok = in.Answer[1].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[1]) - } - if srvRec.Port != 12346 && srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Port == in.Answer[0].(*dns.SRV).Port { - t.Fatalf("should be a different port") - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } + srvRec, ok = in.Answer[1].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[1]) + } + if srvRec.Port != 12346 && srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Port == in.Answer[0].(*dns.SRV).Port { + t.Fatalf("should be a different port") + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } } } @@ -2320,161 +2228,157 @@ func TestDNS_ServiceLookup_FilterCritical(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register nodes with health checks in various states. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "serf", - Name: "serf", - Status: api.HealthCritical, - }, - } + // Register nodes with health checks in various states. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "serf", + Name: "serf", + Status: api.HealthCritical, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args2 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.2", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "serf", - Name: "serf", - Status: api.HealthCritical, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args2, &out); err != nil { - t.Fatalf("err: %v", err) - } + args2 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.2", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "serf", + Name: "serf", + Status: api.HealthCritical, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args2, &out); err != nil { + t.Fatalf("err: %v", err) + } - args3 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.2", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "db", - Name: "db", - ServiceID: "db", - Status: api.HealthCritical, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args3, &out); err != nil { - t.Fatalf("err: %v", err) - } + args3 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.2", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "db", + Name: "db", + ServiceID: "db", + Status: api.HealthCritical, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args3, &out); err != nil { + t.Fatalf("err: %v", err) + } - args4 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "baz", - Address: "127.0.0.3", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args4, &out); err != nil { - t.Fatalf("err: %v", err) - } + args4 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "baz", + Address: "127.0.0.3", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args4, &out); err != nil { + t.Fatalf("err: %v", err) + } - args5 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "quux", - Address: "127.0.0.4", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "db", - Name: "db", - ServiceID: "db", - Status: api.HealthWarning, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args5, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + args5 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "quux", + Address: "127.0.0.4", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "db", + Name: "db", + ServiceID: "db", + Status: api.HealthWarning, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args5, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Only 4 and 5 are not failing, so we should get 2 answers - if len(in.Answer) != 2 { - t.Fatalf("Bad: %#v", in) - } + // Only 4 and 5 are not failing, so we should get 2 answers + if len(in.Answer) != 2 { + t.Fatalf("Bad: %#v", in) + } - ips := make(map[string]bool) - for _, resp := range in.Answer { - aRec := resp.(*dns.A) - ips[aRec.A.String()] = true - } + ips := make(map[string]bool) + for _, resp := range in.Answer { + aRec := resp.(*dns.A) + ips[aRec.A.String()] = true + } - if !ips["127.0.0.3"] { - t.Fatalf("Bad: %#v should contain 127.0.0.3 (state healthy)", in) - } - if !ips["127.0.0.4"] { - t.Fatalf("Bad: %#v should contain 127.0.0.4 (state warning)", in) - } - } - }) + if !ips["127.0.0.3"] { + t.Fatalf("Bad: %#v should contain 127.0.0.3 (state healthy)", in) + } + if !ips["127.0.0.4"] { + t.Fatalf("Bad: %#v should contain 127.0.0.4 (state warning)", in) + } } } @@ -2483,118 +2387,114 @@ func TestDNS_ServiceLookup_OnlyFailing(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register nodes with all health checks in a critical state. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "serf", - Name: "serf", - Status: api.HealthCritical, - }, - } + // Register nodes with all health checks in a critical state. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "serf", + Name: "serf", + Status: api.HealthCritical, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args2 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.2", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "serf", - Name: "serf", - Status: api.HealthCritical, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args2, &out); err != nil { - t.Fatalf("err: %v", err) - } + args2 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.2", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "serf", + Name: "serf", + Status: api.HealthCritical, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args2, &out); err != nil { + t.Fatalf("err: %v", err) + } - args3 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.2", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "db", - Name: "db", - ServiceID: "db", - Status: api.HealthCritical, - }, - } - if err := a.RPC(context.Background(), "Catalog.Register", args3, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + args3 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.2", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "db", + Name: "db", + ServiceID: "db", + Status: api.HealthCritical, + }, + } + if err := a.RPC(context.Background(), "Catalog.Register", args3, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // All 3 are failing, so we should get 0 answers and an NXDOMAIN response - if len(in.Answer) != 0 { - t.Fatalf("Bad: %#v", in) - } + // All 3 are failing, so we should get 0 answers and an NXDOMAIN response + if len(in.Answer) != 0 { + t.Fatalf("Bad: %#v", in) + } - if in.Rcode != dns.RcodeNameError { - t.Fatalf("Bad: %#v", in) - } - } - }) + if in.Rcode != dns.RcodeNameError { + t.Fatalf("Bad: %#v", in) + } } } @@ -2603,149 +2503,145 @@ func TestDNS_ServiceLookup_OnlyPassing(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { only_passing = true } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register nodes with health checks in various states. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "db", - Name: "db", - ServiceID: "db", - Status: api.HealthPassing, - }, - } + // Register nodes with health checks in various states. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "db", + Name: "db", + ServiceID: "db", + Status: api.HealthPassing, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - args2 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.2", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "db", - Name: "db", - ServiceID: "db", - Status: api.HealthWarning, - }, - } + args2 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.2", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "db", + Name: "db", + ServiceID: "db", + Status: api.HealthWarning, + }, + } - if err := a.RPC(context.Background(), "Catalog.Register", args2, &out); err != nil { - t.Fatalf("err: %v", err) - } + if err := a.RPC(context.Background(), "Catalog.Register", args2, &out); err != nil { + t.Fatalf("err: %v", err) + } - args3 := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "baz", - Address: "127.0.0.3", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - Check: &structs.HealthCheck{ - CheckID: "db", - Name: "db", - ServiceID: "db", - Status: api.HealthCritical, - }, - } + args3 := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "baz", + Address: "127.0.0.3", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + Check: &structs.HealthCheck{ + CheckID: "db", + Name: "db", + ServiceID: "db", + Status: api.HealthCritical, + }, + } - if err := a.RPC(context.Background(), "Catalog.Register", args3, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - OnlyPassing: true, - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - // Only 1 is passing, so we should only get 1 answer - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } - - resp := in.Answer[0] - aRec := resp.(*dns.A) - - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - } - - newCfg := *a.Config - newCfg.DNSOnlyPassing = false - err := a.reloadConfigInternal(&newCfg) - require.NoError(t, err) - - // only_passing is now false. we should now get two nodes - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeANY) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - - require.Equal(t, 2, len(in.Answer)) - ips := []string{in.Answer[0].(*dns.A).A.String(), in.Answer[1].(*dns.A).A.String()} - sort.Strings(ips) - require.Equal(t, []string{"127.0.0.1", "127.0.0.2"}, ips) - }) + if err := a.RPC(context.Background(), "Catalog.Register", args3, &out); err != nil { + t.Fatalf("err: %v", err) + } } + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + OnlyPassing: true, + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Only 1 is passing, so we should only get 1 answer + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } + + resp := in.Answer[0] + aRec := resp.(*dns.A) + + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + } + + newCfg := *a.Config + newCfg.DNSOnlyPassing = false + err := a.reloadConfigInternal(&newCfg) + require.NoError(t, err) + + // only_passing is now false. we should now get two nodes + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + + require.Equal(t, 2, len(in.Answer)) + ips := []string{in.Answer[0].(*dns.A).A.String(), in.Answer[1].(*dns.A).A.String()} + sort.Strings(ips) + require.Equal(t, []string{"127.0.0.1", "127.0.0.2"}, ips) } func TestDNS_ServiceLookup_Randomize(t *testing.T) { @@ -2753,96 +2649,92 @@ func TestDNS_ServiceLookup_Randomize(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a large number of nodes. - for i := 0; i < generateNumNodes; i++ { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("foo%d", i), - Address: fmt.Sprintf("127.0.0.%d", i+1), - Service: &structs.NodeService{ - Service: "web", - Port: 8000, - }, - } + // Register a large number of nodes. + for i := 0; i < generateNumNodes; i++ { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: fmt.Sprintf("foo%d", i), + Address: fmt.Sprintf("127.0.0.%d", i+1), + Service: &structs.NodeService{ + Service: "web", + Port: 8000, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "web", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. Ensure the + // response is randomized each time. + questions := []string{ + "web.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + uniques := map[string]struct{}{} + for i := 0; i < 10; i++ { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) + + c := &dns.Client{Net: "udp"} + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "web", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } + // Response length should be truncated and we should get + // an A record for each response. + if len(in.Answer) != defaultNumUDPResponses { + t.Fatalf("Bad: %#v", len(in.Answer)) } - // Look up the service directly and via prepared query. Ensure the - // response is randomized each time. - questions := []string{ - "web.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - uniques := map[string]struct{}{} - for i := 0; i < 10; i++ { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) - - c := &dns.Client{Net: "udp"} - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - // Response length should be truncated and we should get - // an A record for each response. - if len(in.Answer) != defaultNumUDPResponses { - t.Fatalf("Bad: %#v", len(in.Answer)) - } - - // Collect all the names. - var names []string - for _, rec := range in.Answer { - switch v := rec.(type) { - case *dns.SRV: - names = append(names, v.Target) - case *dns.A: - names = append(names, v.A.String()) - } - } - nameS := strings.Join(names, "|") - - // Tally the results. - uniques[nameS] = struct{}{} - } - - // Give some wiggle room. Since the responses are randomized and - // there is a finite number of combinations, requiring 0 - // duplicates every test run eventually gives us failures. - if len(uniques) < 2 { - t.Fatalf("unique response ratio too low: %d/10\n%v", len(uniques), uniques) + // Collect all the names. + var names []string + for _, rec := range in.Answer { + switch v := rec.(type) { + case *dns.SRV: + names = append(names, v.Target) + case *dns.A: + names = append(names, v.A.String()) } } - }) + nameS := strings.Join(names, "|") + + // Tally the results. + uniques[nameS] = struct{}{} + } + + // Give some wiggle room. Since the responses are randomized and + // there is a finite number of combinations, requiring 0 + // duplicates every test run eventually gives us failures. + if len(uniques) < 2 { + t.Fatalf("unique response ratio too low: %d/10\n%v", len(uniques), uniques) + } } } @@ -2851,74 +2743,70 @@ func TestDNS_ServiceLookup_Truncate(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { enable_truncate = true } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a large number of nodes. - for i := 0; i < generateNumNodes; i++ { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("foo%d", i), - Address: fmt.Sprintf("127.0.0.%d", i+1), - Service: &structs.NodeService{ - Service: "web", - Port: 8000, - }, - } + // Register a large number of nodes. + for i := 0; i < generateNumNodes; i++ { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: fmt.Sprintf("foo%d", i), + Address: fmt.Sprintf("127.0.0.%d", i+1), + Service: &structs.NodeService{ + Service: "web", + Port: 8000, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "web", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "web", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. Ensure the - // response is truncated each time. - questions := []string{ - "web.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the service directly and via prepared query. Ensure the + // response is truncated each time. + questions := []string{ + "web.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Check for the truncate bit - if !in.Truncated { - t.Fatalf("should have truncate bit") - } - } - }) + // Check for the truncate bit + if !in.Truncated { + t.Fatalf("should have truncate bit") + } } } @@ -2927,111 +2815,107 @@ func TestDNS_ServiceLookup_LargeResponses(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { enable_truncate = true } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - longServiceName := "this-is-a-very-very-very-very-very-long-name-for-a-service" + longServiceName := "this-is-a-very-very-very-very-very-long-name-for-a-service" - // Register a lot of nodes. - for i := 0; i < 4; i++ { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("foo%d", i), - Address: fmt.Sprintf("127.0.0.%d", i+1), - Service: &structs.NodeService{ - Service: longServiceName, - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register a lot of nodes. + for i := 0; i < 4; i++ { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: fmt.Sprintf("foo%d", i), + Address: fmt.Sprintf("127.0.0.%d", i+1), + Service: &structs.NodeService{ + Service: longServiceName, + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register an equivalent prepared query. + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: longServiceName, + Service: structs.ServiceQuery{ + Service: longServiceName, + Tags: []string{"primary"}, + }, + }, + } + var id string + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. + questions := []string{ + "_" + longServiceName + "._primary.service.consul.", + longServiceName + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if !in.Truncated { + t.Fatalf("should have truncate bit") + } + + // Make sure the response size is RFC 1035-compliant for UDP messages + if in.Len() > 512 { + t.Fatalf("Bad: %d", in.Len()) + } + + // We should only have two answers now + if len(in.Answer) != 2 { + t.Fatalf("Bad: %d", len(in.Answer)) + } + + // Make sure the ADDITIONAL section matches the ANSWER section. + if len(in.Answer) != len(in.Extra) { + t.Fatalf("Bad: %d vs. %d", len(in.Answer), len(in.Extra)) + } + for i := 0; i < len(in.Answer); i++ { + srv, ok := in.Answer[i].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[i]) } - // Register an equivalent prepared query. - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: longServiceName, - Service: structs.ServiceQuery{ - Service: longServiceName, - Tags: []string{"primary"}, - }, - }, - } - var id string - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } + a, ok := in.Extra[i].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[i]) } - // Look up the service directly and via prepared query. - questions := []string{ - "_" + longServiceName + "._primary.service.consul.", - longServiceName + ".query.consul.", + if srv.Target != a.Hdr.Name { + t.Fatalf("Bad: %#v %#v", srv, a) } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + } - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if !in.Truncated { - t.Fatalf("should have truncate bit") - } - - // Make sure the response size is RFC 1035-compliant for UDP messages - if in.Len() > 512 { - t.Fatalf("Bad: %d", in.Len()) - } - - // We should only have two answers now - if len(in.Answer) != 2 { - t.Fatalf("Bad: %d", len(in.Answer)) - } - - // Make sure the ADDITIONAL section matches the ANSWER section. - if len(in.Answer) != len(in.Extra) { - t.Fatalf("Bad: %d vs. %d", len(in.Answer), len(in.Extra)) - } - for i := 0; i < len(in.Answer); i++ { - srv, ok := in.Answer[i].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[i]) - } - - a, ok := in.Extra[i].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[i]) - } - - if srv.Target != a.Hdr.Name { - t.Fatalf("Bad: %#v %#v", srv, a) - } - } - - // Check for the truncate bit - if !in.Truncated { - t.Fatalf("should have truncate bit") - } - } - }) + // Check for the truncate bit + if !in.Truncated { + t.Fatalf("should have truncate bit") + } } } @@ -3133,83 +3017,79 @@ func checkDNSService( expectedResultsCount int, udpSize uint16, ) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` node_name = "test-node" dns_config { a_record_limit = `+fmt.Sprintf("%d", aRecordLimit)+` udp_answer_limit = `+fmt.Sprintf("%d", aRecordLimit)+` } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6) - for i := 0; i < generateNumNodes; i++ { - nodeAddress := fmt.Sprintf("127.0.0.%d", i+1) - if choices[i] { - nodeAddress = fmt.Sprintf("fe80::%d", i+1) - } - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("foo%d", i), - Address: nodeAddress, - Service: &structs.NodeService{ - Service: "api-tier", - Port: 8080, - }, - } + choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6) + for i := 0; i < generateNumNodes; i++ { + nodeAddress := fmt.Sprintf("127.0.0.%d", i+1) + if choices[i] { + nodeAddress = fmt.Sprintf("fe80::%d", i+1) + } + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: fmt.Sprintf("foo%d", i), + Address: nodeAddress, + Service: &structs.NodeService{ + Service: "api-tier", + Port: 8080, + }, + } - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + } + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "api-tier", + Service: structs.ServiceQuery{ + Service: "api-tier", + }, + }, + } + + require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) + } + + // Look up the service directly and via prepared query. + questions := []string{ + "api-tier.service.consul.", + "api-tier.query.consul.", + id + ".query.consul.", + } + for _, question := range questions { + question := question + t.Run("question: "+question, func(t *testing.T) { + + m := new(dns.Msg) + + m.SetQuestion(question, qType) + protocol := "tcp" + if udpSize > 0 { + protocol = "udp" } - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "api-tier", - Service: structs.ServiceQuery{ - Service: "api-tier", - }, - }, - } - - require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) + if udpSize > 512 { + m.SetEdns0(udpSize, true) } + c := &dns.Client{Net: protocol, UDPSize: 8192} + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) - // Look up the service directly and via prepared query. - questions := []string{ - "api-tier.service.consul.", - "api-tier.query.consul.", - id + ".query.consul.", - } - for _, question := range questions { - question := question - t.Run("question: "+question, func(t *testing.T) { + t.Logf("DNS Response for %+v - %+v", m, in) - m := new(dns.Msg) - - m.SetQuestion(question, qType) - protocol := "tcp" - if udpSize > 0 { - protocol = "udp" - } - if udpSize > 512 { - m.SetEdns0(udpSize, true) - } - c := &dns.Client{Net: protocol, UDPSize: 8192} - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - - t.Logf("DNS Response for %+v - %+v", m, in) - - require.Equal(t, expectedResultsCount, len(in.Answer), - "%d/%d answers received for type %v for %s (%s)", len(in.Answer), expectedResultsCount, qType, question, protocol) - }) - } + require.Equal(t, expectedResultsCount, len(in.Answer), + "%d/%d answers received for type %v for %s (%s)", len(in.Answer), expectedResultsCount, qType, question, protocol) }) } } @@ -3299,67 +3179,62 @@ func TestDNS_ServiceLookup_AnswerLimits(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - - // Build a matrix of config parameters (udpAnswerLimit), and the - // length of the response per query type and question. Negative - // values imply the test must return at least the abs(value) number - // of records in the answer section. This is required because, for - // example, on OS-X and Linux, the number of answers returned in a - // 512B response is different even though both platforms are x86_64 - // and using the same version of Go. - // - // TODO(sean@): Why is it not identical everywhere when using the - // same compiler? - tests := []struct { - name string - udpAnswerLimit int - expectedAService int - expectedAQuery int - expectedAQueryID int - expectedAAAAService int - expectedAAAAQuery int - expectedAAAAQueryID int - expectedANYService int - expectedANYQuery int - expectedANYQueryID int - }{ - {"0", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {"1", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {"2", 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, - {"3", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, - {"4", 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, - {"5", 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, - {"6", 6, 6, 6, 6, 6, 6, 5, 6, 6, -5}, - {"7", 7, 7, 7, 6, 7, 7, 5, 7, 7, -5}, - {"8", 8, 8, 8, 6, 8, 8, 5, 8, 8, -5}, - {"9", 9, 8, 8, 6, 8, 8, 5, 8, 8, -5}, - {"20", 20, 8, 8, 6, 8, 8, 5, 8, -5, -5}, - {"30", 30, 8, 8, 6, 8, 8, 5, 8, -5, -5}, + // Build a matrix of config parameters (udpAnswerLimit), and the + // length of the response per query type and question. Negative + // values imply the test must return at least the abs(value) number + // of records in the answer section. This is required because, for + // example, on OS-X and Linux, the number of answers returned in a + // 512B response is different even though both platforms are x86_64 + // and using the same version of Go. + // + // TODO(sean@): Why is it not identical everywhere when using the + // same compiler? + tests := []struct { + name string + udpAnswerLimit int + expectedAService int + expectedAQuery int + expectedAQueryID int + expectedAAAAService int + expectedAAAAQuery int + expectedAAAAQueryID int + expectedANYService int + expectedANYQuery int + expectedANYQueryID int + }{ + {"0", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {"1", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {"2", 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + {"3", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + {"4", 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + {"5", 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, + {"6", 6, 6, 6, 6, 6, 6, 5, 6, 6, -5}, + {"7", 7, 7, 7, 6, 7, 7, 5, 7, 7, -5}, + {"8", 8, 8, 8, 6, 8, 8, 5, 8, 8, -5}, + {"9", 9, 8, 8, 6, 8, 8, 5, 8, 8, -5}, + {"20", 20, 8, 8, 6, 8, 8, 5, 8, -5, -5}, + {"30", 30, 8, 8, 6, 8, 8, 5, 8, -5, -5}, + } + for _, test := range tests { + test := test // capture loop var + t.Run(fmt.Sprintf("A lookup %v", test), func(t *testing.T) { + ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeA, test.expectedAService, test.expectedAQuery, test.expectedAQueryID, "") + if !ok { + t.Fatalf("Expected service A lookup %s to pass: %v", test.name, err) } - for _, test := range tests { - test := test // capture loop var - t.Run(fmt.Sprintf("A lookup %v", test), func(t *testing.T) { - ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeA, test.expectedAService, test.expectedAQuery, test.expectedAQueryID, experimentsHCL) - if !ok { - t.Fatalf("Expected service A lookup %s to pass: %v", test.name, err) - } - }) + }) - t.Run(fmt.Sprintf("AAAA lookup %v", test), func(t *testing.T) { - ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeAAAA, test.expectedAAAAService, test.expectedAAAAQuery, test.expectedAAAAQueryID, experimentsHCL) - if !ok { - t.Fatalf("Expected service AAAA lookup %s to pass: %v", test.name, err) - } - }) + t.Run(fmt.Sprintf("AAAA lookup %v", test), func(t *testing.T) { + ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeAAAA, test.expectedAAAAService, test.expectedAAAAQuery, test.expectedAAAAQueryID, "") + if !ok { + t.Fatalf("Expected service AAAA lookup %s to pass: %v", test.name, err) + } + }) - t.Run(fmt.Sprintf("ANY lookup %v", test), func(t *testing.T) { - ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeANY, test.expectedANYService, test.expectedANYQuery, test.expectedANYQueryID, experimentsHCL) - if !ok { - t.Fatalf("Expected service ANY lookup %s to pass: %v", test.name, err) - } - }) + t.Run(fmt.Sprintf("ANY lookup %v", test), func(t *testing.T) { + ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeANY, test.expectedANYService, test.expectedANYQuery, test.expectedANYQueryID, "") + if !ok { + t.Fatalf("Expected service ANY lookup %s to pass: %v", test.name, err) } }) } @@ -3378,94 +3253,90 @@ func TestDNS_ServiceLookup_CNAME(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a name for an address. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "google", - Address: "www.google.com", - Service: &structs.NodeService{ - Service: "search", - Port: 80, - }, - } + // Register a node with a name for an address. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "google", + Address: "www.google.com", + Service: &structs.NodeService{ + Service: "search", + Port: 80, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "search", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "search", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []string{ - "search.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the service directly and via prepared query. + questions := []string{ + "search.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Service CNAME, google CNAME, google A record - if len(in.Answer) != 3 { - t.Fatalf("Bad: %#v", in) - } + // Service CNAME, google CNAME, google A record + if len(in.Answer) != 3 { + t.Fatalf("Bad: %#v", in) + } - // Should have service CNAME - cnRec, ok := in.Answer[0].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if cnRec.Target != "www.google.com." { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + // Should have service CNAME + cnRec, ok := in.Answer[0].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if cnRec.Target != "www.google.com." { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - // Should have google CNAME - cnRec, ok = in.Answer[1].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[1]) - } - if cnRec.Target != "google.com." { - t.Fatalf("Bad: %#v", in.Answer[1]) - } + // Should have google CNAME + cnRec, ok = in.Answer[1].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[1]) + } + if cnRec.Target != "google.com." { + t.Fatalf("Bad: %#v", in.Answer[1]) + } - // Check we recursively resolve - if _, ok := in.Answer[2].(*dns.A); !ok { - t.Fatalf("Bad: %#v", in.Answer[2]) - } - } - }) + // Check we recursively resolve + if _, ok := in.Answer[2].(*dns.A); !ok { + t.Fatalf("Bad: %#v", in.Answer[2]) + } } } @@ -3482,95 +3353,91 @@ func TestDNS_ServiceLookup_ServiceAddress_CNAME(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a name for an address. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "google", - Address: "1.2.3.4", - Service: &structs.NodeService{ - Service: "search", - Port: 80, - Address: "www.google.com", - }, - } + // Register a node with a name for an address. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "google", + Address: "1.2.3.4", + Service: &structs.NodeService{ + Service: "search", + Port: 80, + Address: "www.google.com", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "search", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "search", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly and via prepared query. - questions := []string{ - "search.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the service directly and via prepared query. + questions := []string{ + "search.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Service CNAME, google CNAME, google A record - if len(in.Answer) != 3 { - t.Fatalf("Bad: %#v", in) - } + // Service CNAME, google CNAME, google A record + if len(in.Answer) != 3 { + t.Fatalf("Bad: %#v", in) + } - // Should have service CNAME - cnRec, ok := in.Answer[0].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if cnRec.Target != "www.google.com." { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + // Should have service CNAME + cnRec, ok := in.Answer[0].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if cnRec.Target != "www.google.com." { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - // Should have google CNAME - cnRec, ok = in.Answer[1].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[1]) - } - if cnRec.Target != "google.com." { - t.Fatalf("Bad: %#v", in.Answer[1]) - } + // Should have google CNAME + cnRec, ok = in.Answer[1].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[1]) + } + if cnRec.Target != "google.com." { + t.Fatalf("Bad: %#v", in.Answer[1]) + } - // Check we recursively resolve - if _, ok := in.Answer[2].(*dns.A); !ok { - t.Fatalf("Bad: %#v", in.Answer[2]) - } - } - }) + // Check we recursively resolve + if _, ok := in.Answer[2].(*dns.A); !ok { + t.Fatalf("Bad: %#v", in.Answer[2]) + } } } @@ -3579,9 +3446,7 @@ func TestDNS_ServiceLookup_TTL(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { service_ttl = { "d*" = "42s" @@ -3592,71 +3457,69 @@ func TestDNS_ServiceLookup_TTL(t *testing.T) { allow_stale = true max_stale = "1s" } - `+experimentsHCL) - defer a.Shutdown() + `) + defer a.Shutdown() - for idx, service := range []string{"db", "dblb", "dk", "api"} { - nodeName := fmt.Sprintf("foo%d", idx) - address := fmt.Sprintf("127.0.0.%d", idx) - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: nodeName, - Address: address, - Service: &structs.NodeService{ - Service: service, - Tags: []string{"primary"}, - Port: 12345 + idx, - }, - } + for idx, service := range []string{"db", "dblb", "dk", "api"} { + nodeName := fmt.Sprintf("foo%d", idx) + address := fmt.Sprintf("127.0.0.%d", idx) + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: nodeName, + Address: address, + Service: &structs.NodeService{ + Service: service, + Tags: []string{"primary"}, + Port: 12345 + idx, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + c := new(dns.Client) + expectResult := func(dnsQuery string, expectedTTL uint32) { + t.Run(dnsQuery, func(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion(dnsQuery, dns.TypeSRV) + + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) } - c := new(dns.Client) - expectResult := func(dnsQuery string, expectedTTL uint32) { - t.Run(dnsQuery, func(t *testing.T) { - m := new(dns.Msg) - m.SetQuestion(dnsQuery, dns.TypeSRV) - - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v, len is %d", in, len(in.Answer)) - } - - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Hdr.Ttl != expectedTTL { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != expectedTTL { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - }) + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v, len is %d", in, len(in.Answer)) + } + + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Hdr.Ttl != expectedTTL { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != expectedTTL { + t.Fatalf("Bad: %#v", in.Extra[0]) } - // Should have its exact TTL - expectResult("db.service.consul.", 10) - // Should match db* - expectResult("dblb.service.consul.", 66) - // Should match d* - expectResult("dk.service.consul.", 42) - // Should match * - expectResult("api.service.consul.", 5) }) } + // Should have its exact TTL + expectResult("db.service.consul.", 10) + // Should match db* + expectResult("dblb.service.consul.", 66) + // Should match d* + expectResult("dk.service.consul.", 42) + // Should match * + expectResult("api.service.consul.", 5) } func TestDNS_ServiceLookup_SRV_RFC(t *testing.T) { @@ -3664,79 +3527,75 @@ func TestDNS_ServiceLookup_SRV_RFC(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - questions := []string{ - "_db._primary.service.dc1.consul.", - "_db._primary.service.consul.", - "_db._primary.dc1.consul.", - "_db._primary.consul.", - } + questions := []string{ + "_db._primary.service.dc1.consul.", + "_db._primary.service.consul.", + "_db._primary.dc1.consul.", + "_db._primary.consul.", + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - } - }) + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) + } } } @@ -3745,83 +3604,78 @@ func TestDNS_ServiceLookup_SRV_RFC_TCP_Default(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + questions := []string{ + "_db._tcp.service.dc1.consul.", + "_db._tcp.service.consul.", + "_db._tcp.dc1.consul.", + "_db._tcp.consul.", + } + + for _, question := range questions { + t.Run(question, func(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { t.Fatalf("err: %v", err) } - questions := []string{ - "_db._tcp.service.dc1.consul.", - "_db._tcp.service.consul.", - "_db._tcp.dc1.consul.", - "_db._tcp.consul.", + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) } - for _, question := range questions { - t.Run(question, func(t *testing.T) { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Target != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", srvRec) + } + if srvRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } - - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Target != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", srvRec) - } - if srvRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Name != "foo.node.dc1.consul." { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - if aRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Extra[0]) - } - }) + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Name != "foo.node.dc1.consul." { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } + if aRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Extra[0]) } }) } - } func initDNSToken(t *testing.T, rpc RPC) { @@ -3885,45 +3739,41 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) { } ` - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, hcl+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, hcl) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - if tt.token == "dns" { - initDNSToken(t, a) - } + if tt.token == "dns" { + initDNSToken(t, a) + } - // Register a service - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "foo", - Port: 12345, - }, - WriteRequest: structs.WriteRequest{Token: "root"}, - } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + // Register a service + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "foo", + Port: 12345, + }, + WriteRequest: structs.WriteRequest{Token: "root"}, + } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - // Set up the DNS query - c := new(dns.Client) - m := new(dns.Msg) - m.SetQuestion("foo.service.consul.", dns.TypeA) + // Set up the DNS query + c := new(dns.Client) + m := new(dns.Msg) + m.SetQuestion("foo.service.consul.", dns.TypeA) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - if len(in.Answer) != tt.results { - t.Fatalf("Bad: %#v", in) - } - }) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + if len(in.Answer) != tt.results { + t.Fatalf("Bad: %#v", in) } }) } @@ -3934,53 +3784,49 @@ func TestDNS_ServiceLookup_MetaTXT(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = true } `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = true } `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "key": "value", - }, - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAdditional := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "bar.node.dc1.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 - }, - &dns.TXT{ - Hdr: dns.RR_Header{Name: "bar.node.dc1.consul.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xa}, - Txt: []string{"key=value"}, - }, - } - require.Equal(t, wantAdditional, in.Extra) - }) + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "key": "value", + }, + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + wantAdditional := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "bar.node.dc1.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 + }, + &dns.TXT{ + Hdr: dns.RR_Header{Name: "bar.node.dc1.consul.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Rdlength: 0xa}, + Txt: []string{"key=value"}, + }, + } + require.Equal(t, wantAdditional, in.Extra) } func TestDNS_ServiceLookup_SuppressTXT(t *testing.T) { @@ -3988,48 +3834,44 @@ func TestDNS_ServiceLookup_SuppressTXT(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, `dns_config = { enable_additional_node_meta_txt = false } `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "127.0.0.1", - NodeMeta: map[string]string{ - "key": "value", - }, - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - m := new(dns.Msg) - m.SetQuestion("db.service.consul.", dns.TypeSRV) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAdditional := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "bar.node.dc1.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 - }, - } - require.Equal(t, wantAdditional, in.Extra) - }) + // Register a node with a service. + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "127.0.0.1", + NodeMeta: map[string]string{ + "key": "value", + }, + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + m := new(dns.Msg) + m.SetQuestion("db.service.consul.", dns.TypeSRV) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + wantAdditional := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "bar.node.dc1.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0x7f, 0x0, 0x0, 0x1}, // 127.0.0.1 + }, + } + require.Equal(t, wantAdditional, in.Extra) } diff --git a/agent/dns_test.go b/agent/dns_test.go index c44fd2bbc2..c5a8c1db2c 100644 --- a/agent/dns_test.go +++ b/agent/dns_test.go @@ -33,8 +33,6 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/agent/consul" - "github.com/hashicorp/consul/agent/discovery" - dnsConsul "github.com/hashicorp/consul/agent/dns" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/gossip/librtt" "github.com/hashicorp/consul/sdk/testutil/retry" @@ -119,17 +117,6 @@ func dnsTXT(src string, txt []string) *dns.TXT { } } -func getVersionHCL(enableV2 bool) map[string]string { - versions := map[string]string{ - "DNS: v1 / Catalog: v1": "experiments=[\"v1dns\"]", - } - - if enableV2 { - versions["DNS: v2 / Catalog: v1"] = "" - } - return versions -} - // Copied to agent/dns/recursor_test.go func TestDNS_RecursorAddr(t *testing.T) { addr, err := recursorAddr("8.8.8.8") @@ -190,38 +177,34 @@ func TestDNS_Over_TCP(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "Foo", - Address: "127.0.0.1", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "Foo", + Address: "127.0.0.1", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY) - c := new(dns.Client) - c.Net = "tcp" - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + c.Net = "tcp" + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("empty lookup: %#v", in) - } - }) + if len(in.Answer) != 1 { + t.Fatalf("empty lookup: %#v", in) } } @@ -230,21 +213,17 @@ func TestDNS_EmptyAltDomain(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("consul.service.", dns.TypeA) + m := new(dns.Msg) + m.SetQuestion("consul.service.", dns.TypeA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Empty(t, in.Answer) - }) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Empty(t, in.Answer) } func TestDNS_CycleRecursorCheck(t *testing.T) { @@ -265,29 +244,25 @@ func TestDNS_CycleRecursorCheck(t *testing.T) { }, }) defer server2.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - // Mock the agent startup with the necessary configs - agent := NewTestAgent(t, - `recursors = ["`+server1.Addr+`", "`+server2.Addr+`"] - `+experimentsHCL) - defer agent.Shutdown() - // DNS Message init - m := new(dns.Msg) - m.SetQuestion("google.com.", dns.TypeA) - // Agent request - client := new(dns.Client) - in, _, _ := client.Exchange(m, agent.DNSAddr()) - wantAnswer := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "www.google.com.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, - A: []byte{0xAC, 0x15, 0x2D, 0x43}, // 172 , 21, 45, 67 - }, - } - require.NotNil(t, in) - require.Equal(t, wantAnswer, in.Answer) - }) + // Mock the agent startup with the necessary configs + agent := NewTestAgent(t, + `recursors = ["`+server1.Addr+`", "`+server2.Addr+`"] + `) + defer agent.Shutdown() + // DNS Message init + m := new(dns.Msg) + m.SetQuestion("google.com.", dns.TypeA) + // Agent request + client := new(dns.Client) + in, _, _ := client.Exchange(m, agent.DNSAddr()) + wantAnswer := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "www.google.com.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4}, + A: []byte{0xAC, 0x15, 0x2D, 0x43}, // 172 , 21, 45, 67 + }, } + require.NotNil(t, in) + require.Equal(t, wantAnswer, in.Answer) } func TestDNS_CycleRecursorCheckAllFail(t *testing.T) { if testing.Short() { @@ -307,25 +282,21 @@ func TestDNS_CycleRecursorCheckAllFail(t *testing.T) { MsgHdr: dns.MsgHdr{Rcode: dns.RcodeRefused}, }) defer server3.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - // Mock the agent startup with the necessary configs - agent := NewTestAgent(t, - `recursors = ["`+server1.Addr+`", "`+server2.Addr+`","`+server3.Addr+`"] - `+experimentsHCL) - defer agent.Shutdown() - // DNS dummy message initialization - m := new(dns.Msg) - m.SetQuestion("google.com.", dns.TypeA) - // Agent request - client := new(dns.Client) - in, _, err := client.Exchange(m, agent.DNSAddr()) - require.NoError(t, err) - // Verify if we hit SERVFAIL from Consul - require.NotNil(t, in) - require.Equal(t, dns.RcodeServerFailure, in.Rcode) - }) - } + // Mock the agent startup with the necessary configs + agent := NewTestAgent(t, + `recursors = ["`+server1.Addr+`", "`+server2.Addr+`","`+server3.Addr+`"] + `) + defer agent.Shutdown() + // DNS dummy message initialization + m := new(dns.Msg) + m.SetQuestion("google.com.", dns.TypeA) + // Agent request + client := new(dns.Client) + in, _, err := client.Exchange(m, agent.DNSAddr()) + require.NoError(t, err) + // Verify if we hit SERVFAIL from Consul + require.NotNil(t, in) + require.Equal(t, dns.RcodeServerFailure, in.Rcode) } func TestDNS_EDNS0(t *testing.T) { @@ -333,45 +304,41 @@ func TestDNS_EDNS0(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register node - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.2", - } + // Register node + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.2", + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } - m := new(dns.Msg) - m.SetEdns0(12345, true) - m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetEdns0(12345, true) + m.SetQuestion("foo.node.dc1.consul.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("empty lookup: %#v", in) - } - edns := in.IsEdns0() - if edns == nil { - t.Fatalf("empty edns: %#v", in) - } - if edns.UDPSize() != 12345 { - t.Fatalf("bad edns size: %d", edns.UDPSize()) - } - }) + if len(in.Answer) != 1 { + t.Fatalf("empty lookup: %#v", in) + } + edns := in.IsEdns0() + if edns == nil { + t.Fatalf("empty edns: %#v", in) + } + if edns.UDPSize() != 12345 { + t.Fatalf("bad edns size: %d", edns.UDPSize()) } } @@ -380,95 +347,91 @@ func TestDNS_EDNS0_ECS(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) + } - cases := []struct { - Name string - Question string - SubnetAddr string - SourceNetmask uint8 - ExpectedScope uint8 - }{ - {"global", "db.service.consul.", "198.18.0.1", 32, 0}, - {"query", "test.query.consul.", "198.18.0.1", 32, 32}, - {"query-subnet", "test.query.consul.", "198.18.0.0", 21, 21}, - } + cases := []struct { + Name string + Question string + SubnetAddr string + SourceNetmask uint8 + ExpectedScope uint8 + }{ + {"global", "db.service.consul.", "198.18.0.1", 32, 0}, + {"query", "test.query.consul.", "198.18.0.1", 32, 32}, + {"query-subnet", "test.query.consul.", "198.18.0.0", 21, 21}, + } - for _, tc := range cases { - t.Run(tc.Name, func(t *testing.T) { - c := new(dns.Client) - // Query the service directly - should have a globally valid scope (0) - m := new(dns.Msg) - edns := new(dns.OPT) - edns.Hdr.Name = "." - edns.Hdr.Rrtype = dns.TypeOPT - edns.SetUDPSize(12345) - edns.SetDo(true) - subnetOp := new(dns.EDNS0_SUBNET) - subnetOp.Code = dns.EDNS0SUBNET - subnetOp.Family = 1 - subnetOp.SourceNetmask = tc.SourceNetmask - subnetOp.Address = net.ParseIP(tc.SubnetAddr) - edns.Option = append(edns.Option, subnetOp) - m.Extra = append(m.Extra, edns) - m.SetQuestion(tc.Question, dns.TypeA) + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + c := new(dns.Client) + // Query the service directly - should have a globally valid scope (0) + m := new(dns.Msg) + edns := new(dns.OPT) + edns.Hdr.Name = "." + edns.Hdr.Rrtype = dns.TypeOPT + edns.SetUDPSize(12345) + edns.SetDo(true) + subnetOp := new(dns.EDNS0_SUBNET) + subnetOp.Code = dns.EDNS0SUBNET + subnetOp.Family = 1 + subnetOp.SourceNetmask = tc.SourceNetmask + subnetOp.Address = net.ParseIP(tc.SubnetAddr) + edns.Option = append(edns.Option, subnetOp) + m.Extra = append(m.Extra, edns) + m.SetQuestion(tc.Question, dns.TypeA) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok) - require.Equal(t, "127.0.0.1", aRec.A.String()) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Len(t, in.Answer, 1) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok) + require.Equal(t, "127.0.0.1", aRec.A.String()) - optRR := in.IsEdns0() - require.NotNil(t, optRR) - require.Len(t, optRR.Option, 1) + optRR := in.IsEdns0() + require.NotNil(t, optRR) + require.Len(t, optRR.Option, 1) - subnet, ok := optRR.Option[0].(*dns.EDNS0_SUBNET) - require.True(t, ok) - require.Equal(t, uint16(1), subnet.Family) - require.Equal(t, tc.SourceNetmask, subnet.SourceNetmask) - require.Equal(t, tc.ExpectedScope, subnet.SourceScope) - require.Equal(t, net.ParseIP(tc.SubnetAddr), subnet.Address) - }) - } + subnet, ok := optRR.Option[0].(*dns.EDNS0_SUBNET) + require.True(t, ok) + require.Equal(t, uint16(1), subnet.Family) + require.Equal(t, tc.SourceNetmask, subnet.SourceNetmask) + require.Equal(t, tc.ExpectedScope, subnet.SourceScope) + require.Equal(t, net.ParseIP(tc.SubnetAddr), subnet.Address) }) } } @@ -499,19 +462,15 @@ func TestDNS_SOA_Settings(t *testing.T) { require.Equal(t, uint32(retry), soaRec.Retry) require.Equal(t, uint32(ttl), soaRec.Hdr.Ttl) } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - // Default configuration - testSoaWithConfig(experimentsHCL, 0, 86400, 3600, 600) - // Override all settings - testSoaWithConfig("dns_config={soa={min_ttl=60,expire=43200,refresh=1800,retry=300}} "+experimentsHCL, 60, 43200, 1800, 300) - // Override partial settings - testSoaWithConfig("dns_config={soa={min_ttl=60,expire=43200}} "+experimentsHCL, 60, 43200, 3600, 600) - // Override partial settings, part II - testSoaWithConfig("dns_config={soa={refresh=1800,retry=300}} "+experimentsHCL, 0, 86400, 1800, 300) - }) - } + // Default configuration + testSoaWithConfig("", 0, 86400, 3600, 600) + // Override all settings + testSoaWithConfig("dns_config={soa={min_ttl=60,expire=43200,refresh=1800,retry=300}} ", 60, 43200, 1800, 300) + // Override partial settings + testSoaWithConfig("dns_config={soa={min_ttl=60,expire=43200}} ", 60, 43200, 3600, 600) + // Override partial settings, part II + testSoaWithConfig("dns_config={soa={refresh=1800,retry=300}} ", 0, 86400, 1800, 300) } func TestDNS_VirtualIPLookup(t *testing.T) { @@ -519,93 +478,89 @@ func TestDNS_VirtualIPLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := StartTestAgent(t, TestAgent{HCL: experimentsHCL, Overrides: `peering = { test_allow_peer_registrations = true } log_level = "debug"`}) - defer a.Shutdown() + a := StartTestAgent(t, TestAgent{HCL: "", Overrides: `peering = { test_allow_peer_registrations = true } log_level = "debug"`}) + defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + testrpc.WaitForLeader(t, a.RPC, "dc1") - server, ok := a.delegate.(*consul.Server) - require.True(t, ok) + server, ok := a.delegate.(*consul.Server) + require.True(t, ok) - // The proxy service will not receive a virtual IP if the server is not assigning virtual IPs yet. - retry.Run(t, func(r *retry.R) { - _, entry, err := server.FSM().State().SystemMetadataGet(nil, structs.SystemMetadataVirtualIPsEnabled) - require.NoError(r, err) - require.NotNil(r, entry) - }) + // The proxy service will not receive a virtual IP if the server is not assigning virtual IPs yet. + retry.Run(t, func(r *retry.R) { + _, entry, err := server.FSM().State().SystemMetadataGet(nil, structs.SystemMetadataVirtualIPsEnabled) + require.NoError(r, err) + require.NotNil(r, entry) + }) - type testCase struct { - name string - reg *structs.RegisterRequest - question string - expect string - } + type testCase struct { + name string + reg *structs.RegisterRequest + question string + expect string + } - run := func(t *testing.T, tc testCase) { - var out struct{} - require.Nil(t, a.RPC(context.Background(), "Catalog.Register", tc.reg, &out)) + run := func(t *testing.T, tc testCase) { + var out struct{} + require.Nil(t, a.RPC(context.Background(), "Catalog.Register", tc.reg, &out)) - m := new(dns.Msg) - m.SetQuestion(tc.question, dns.TypeA) + m := new(dns.Msg) + m.SetQuestion(tc.question, dns.TypeA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.Nil(t, err) - require.Len(t, in.Answer, 1) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.Nil(t, err) + require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok) - require.Equal(t, tc.expect, aRec.A.String()) - } + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok) + require.Equal(t, tc.expect, aRec.A.String()) + } - tt := []testCase{ - { - name: "local query", - reg: &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.55", - Service: &structs.NodeService{ - Kind: structs.ServiceKindConnectProxy, - Service: "web-proxy", - Port: 12345, - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "db", - }, - }, + tt := []testCase{ + { + name: "local query", + reg: &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.55", + Service: &structs.NodeService{ + Kind: structs.ServiceKindConnectProxy, + Service: "web-proxy", + Port: 12345, + Proxy: structs.ConnectProxyConfig{ + DestinationServiceName: "db", }, - question: "db.virtual.consul.", - expect: "240.0.0.1", }, - { - name: "query for imported service", - reg: &structs.RegisterRequest{ - PeerName: "frontend", - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.55", - Service: &structs.NodeService{ - PeerName: "frontend", - Kind: structs.ServiceKindConnectProxy, - Service: "web-proxy", - Port: 12345, - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "db", - }, - }, + }, + question: "db.virtual.consul.", + expect: "240.0.0.1", + }, + { + name: "query for imported service", + reg: &structs.RegisterRequest{ + PeerName: "frontend", + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.55", + Service: &structs.NodeService{ + PeerName: "frontend", + Kind: structs.ServiceKindConnectProxy, + Service: "web-proxy", + Port: 12345, + Proxy: structs.ConnectProxyConfig{ + DestinationServiceName: "db", }, - question: "db.virtual.frontend.consul.", - expect: "240.0.0.2", }, - } + }, + question: "db.virtual.frontend.consul.", + expect: "240.0.0.2", + }, + } - for _, tc := range tt { - t.Run(tc.name, func(t *testing.T) { - run(t, tc) - }) - } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + run(t, tc) }) } } @@ -616,59 +571,55 @@ func TestDNS_InifiniteRecursion(t *testing.T) { } // This test should not create an infinite recursion - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "CONSUL." node_name = "test node" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register the initial node with a service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "web", - Address: "web.service.consul.", - Service: &structs.NodeService{ - Service: "web", - Port: 12345, - Address: "web.service.consul.", - }, - } + // Register the initial node with a service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "web", + Address: "web.service.consul.", + Service: &structs.NodeService{ + Service: "web", + Port: 12345, + Address: "web.service.consul.", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - // Look up the service directly - questions := []string{ - "web.service.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + // Look up the service directly + questions := []string{ + "web.service.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) < 1 { - t.Fatalf("Bad: %#v", in) - } - aRec, ok := in.Answer[0].(*dns.CNAME) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aRec.Target != "web.service.consul." { - t.Fatalf("Bad: %#v, target:=%s", aRec, aRec.Target) - } - } - }) + if len(in.Answer) < 1 { + t.Fatalf("Bad: %#v", in) + } + aRec, ok := in.Answer[0].(*dns.CNAME) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aRec.Target != "web.service.consul." { + t.Fatalf("Bad: %#v, target:=%s", aRec, aRec.Target) + } } } @@ -677,41 +628,37 @@ func TestDNS_NSRecords(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "CONSUL." node_name = "server1" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("something.node.consul.", dns.TypeNS) + m := new(dns.Msg) + m.SetQuestion("something.node.consul.", dns.TypeNS) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAnswer := []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{Name: "consul.", Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x13}, - Ns: "server1.node.dc1.consul.", - }, - } - require.Equal(t, wantAnswer, in.Answer, "answer") - wantExtra := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: "server1.node.dc1.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4, Ttl: 0}, - A: net.ParseIP("127.0.0.1").To4(), - }, - } - - require.Equal(t, wantExtra, in.Extra, "extra") - }) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) } + + wantAnswer := []dns.RR{ + &dns.NS{ + Hdr: dns.RR_Header{Name: "consul.", Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x13}, + Ns: "server1.node.dc1.consul.", + }, + } + require.Equal(t, wantAnswer, in.Answer, "answer") + wantExtra := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: "server1.node.dc1.consul.", Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4, Ttl: 0}, + A: net.ParseIP("127.0.0.1").To4(), + }, + } + + require.Equal(t, wantExtra, in.Extra, "extra") } func TestDNS_AltDomain_NSRecords(t *testing.T) { @@ -719,53 +666,48 @@ func TestDNS_AltDomain_NSRecords(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "CONSUL." node_name = "server1" alt_domain = "test-domain." - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - questions := []struct { - ask string - domain string - wantDomain string - }{ - {"something.node.consul.", "consul.", "server1.node.dc1.consul."}, - {"something.node.test-domain.", "test-domain.", "server1.node.dc1.test-domain."}, - } + questions := []struct { + ask string + domain string + wantDomain string + }{ + {"something.node.consul.", "consul.", "server1.node.dc1.consul."}, + {"something.node.test-domain.", "test-domain.", "server1.node.dc1.test-domain."}, + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question.ask, dns.TypeNS) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeNS) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - wantAnswer := []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{Name: question.domain, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x13}, - Ns: question.wantDomain, - }, - } - require.Equal(t, wantAnswer, in.Answer, "answer") - wantExtra := []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{Name: question.wantDomain, Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4, Ttl: 0}, - A: net.ParseIP("127.0.0.1").To4(), - }, - } + wantAnswer := []dns.RR{ + &dns.NS{ + Hdr: dns.RR_Header{Name: question.domain, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x13}, + Ns: question.wantDomain, + }, + } + require.Equal(t, wantAnswer, in.Answer, "answer") + wantExtra := []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{Name: question.wantDomain, Rrtype: dns.TypeA, Class: dns.ClassINET, Rdlength: 0x4, Ttl: 0}, + A: net.ParseIP("127.0.0.1").To4(), + }, + } - require.Equal(t, wantExtra, in.Extra, "extra") - } - }) + require.Equal(t, wantExtra, in.Extra, "extra") } } @@ -774,42 +716,38 @@ func TestDNS_NSRecords_IPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "CONSUL." node_name = "server1" advertise_addr = "::1" - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("server1.node.dc1.consul.", dns.TypeNS) + m := new(dns.Msg) + m.SetQuestion("server1.node.dc1.consul.", dns.TypeNS) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - wantAnswer := []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{Name: "consul.", Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x2}, - Ns: "server1.node.dc1.consul.", - }, - } - require.Equal(t, wantAnswer, in.Answer, "answer") - wantExtra := []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{Name: "server1.node.dc1.consul.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Rdlength: 0x10, Ttl: 0}, - AAAA: net.ParseIP("::1"), - }, - } - - require.Equal(t, wantExtra, in.Extra, "extra") - }) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) } + + wantAnswer := []dns.RR{ + &dns.NS{ + Hdr: dns.RR_Header{Name: "consul.", Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x2}, + Ns: "server1.node.dc1.consul.", + }, + } + require.Equal(t, wantAnswer, in.Answer, "answer") + wantExtra := []dns.RR{ + &dns.AAAA{ + Hdr: dns.RR_Header{Name: "server1.node.dc1.consul.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Rdlength: 0x10, Ttl: 0}, + AAAA: net.ParseIP("::1"), + }, + } + + require.Equal(t, wantExtra, in.Extra, "extra") } func TestDNS_AltDomain_NSRecords_IPV6(t *testing.T) { @@ -817,53 +755,49 @@ func TestDNS_AltDomain_NSRecords_IPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` domain = "CONSUL." node_name = "server1" advertise_addr = "::1" alt_domain = "test-domain." - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - questions := []struct { - ask string - domain string - wantDomain string - }{ - {"server1.node.dc1.consul.", "consul.", "server1.node.dc1.consul."}, - {"server1.node.dc1.test-domain.", "test-domain.", "server1.node.dc1.test-domain."}, - } + questions := []struct { + ask string + domain string + wantDomain string + }{ + {"server1.node.dc1.consul.", "consul.", "server1.node.dc1.consul."}, + {"server1.node.dc1.test-domain.", "test-domain.", "server1.node.dc1.test-domain."}, + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question.ask, dns.TypeNS) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeNS) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - wantAnswer := []dns.RR{ - &dns.NS{ - Hdr: dns.RR_Header{Name: question.domain, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x2}, - Ns: question.wantDomain, - }, - } - require.Equal(t, wantAnswer, in.Answer, "answer") - wantExtra := []dns.RR{ - &dns.AAAA{ - Hdr: dns.RR_Header{Name: question.wantDomain, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Rdlength: 0x10, Ttl: 0}, - AAAA: net.ParseIP("::1"), - }, - } + wantAnswer := []dns.RR{ + &dns.NS{ + Hdr: dns.RR_Header{Name: question.domain, Rrtype: dns.TypeNS, Class: dns.ClassINET, Ttl: 0, Rdlength: 0x2}, + Ns: question.wantDomain, + }, + } + require.Equal(t, wantAnswer, in.Answer, "answer") + wantExtra := []dns.RR{ + &dns.AAAA{ + Hdr: dns.RR_Header{Name: question.wantDomain, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Rdlength: 0x10, Ttl: 0}, + AAAA: net.ParseIP("::1"), + }, + } - require.Equal(t, wantExtra, in.Extra, "extra") - } - }) + require.Equal(t, wantExtra, in.Extra, "extra") } } @@ -872,193 +806,189 @@ func TestDNS_Lookup_TaggedIPAddresses(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) + } + + type testCase struct { + nodeAddress string + nodeTaggedAddresses map[string]string + serviceAddress string + serviceTaggedAddresses map[string]structs.ServiceAddress + + expectedServiceIPv4Address string + expectedServiceIPv6Address string + expectedNodeIPv4Address string + expectedNodeIPv6Address string + } + + cases := map[string]testCase{ + "simple-ipv4": { + serviceAddress: "127.0.0.2", + nodeAddress: "127.0.0.1", + + expectedServiceIPv4Address: "127.0.0.2", + expectedServiceIPv6Address: "", + expectedNodeIPv4Address: "127.0.0.1", + expectedNodeIPv6Address: "", + }, + "simple-ipv6": { + serviceAddress: "::2", + nodeAddress: "::1", + + expectedServiceIPv6Address: "::2", + expectedServiceIPv4Address: "", + expectedNodeIPv6Address: "::1", + expectedNodeIPv4Address: "", + }, + "ipv4-with-tagged-ipv6": { + serviceAddress: "127.0.0.2", + nodeAddress: "127.0.0.1", + + serviceTaggedAddresses: map[string]structs.ServiceAddress{ + structs.TaggedAddressLANIPv6: {Address: "::2"}, + }, + nodeTaggedAddresses: map[string]string{ + structs.TaggedAddressLANIPv6: "::1", + }, + + expectedServiceIPv4Address: "127.0.0.2", + expectedServiceIPv6Address: "::2", + expectedNodeIPv4Address: "127.0.0.1", + expectedNodeIPv6Address: "::1", + }, + "ipv6-with-tagged-ipv4": { + serviceAddress: "::2", + nodeAddress: "::1", + + serviceTaggedAddresses: map[string]structs.ServiceAddress{ + structs.TaggedAddressLANIPv4: {Address: "127.0.0.2"}, + }, + nodeTaggedAddresses: map[string]string{ + structs.TaggedAddressLANIPv4: "127.0.0.1", + }, + + expectedServiceIPv4Address: "127.0.0.2", + expectedServiceIPv6Address: "::2", + expectedNodeIPv4Address: "127.0.0.1", + expectedNodeIPv6Address: "::1", + }, + } + + for name, tc := range cases { + name := name + tc := tc t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: tc.nodeAddress, + TaggedAddresses: tc.nodeTaggedAddresses, + Service: &structs.NodeService{ + Service: "db", + Address: tc.serviceAddress, + Port: 8080, + TaggedAddresses: tc.serviceTaggedAddresses, + }, + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + + // Look up the SRV record via service and prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) + + c := new(dns.Client) + addr := a.config.DNSAddrs[0].String() + in, _, err := c.Exchange(m, addr) + require.NoError(t, err) + + if tc.expectedServiceIPv4Address != "" { + require.Len(t, in.Answer, 1) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok, "Bad: %#v", in.Answer[0]) + require.Equal(t, question, aRec.Hdr.Name) + require.Equal(t, tc.expectedServiceIPv4Address, aRec.A.String()) + } else { + require.Len(t, in.Answer, 0) + } + + m = new(dns.Msg) + m.SetQuestion(question, dns.TypeAAAA) + + c = new(dns.Client) + addr = a.config.DNSAddrs[0].String() + in, _, err = c.Exchange(m, addr) + require.NoError(t, err) + + if tc.expectedServiceIPv6Address != "" { + require.Len(t, in.Answer, 1) + aRec, ok := in.Answer[0].(*dns.AAAA) + require.True(t, ok, "Bad: %#v", in.Answer[0]) + require.Equal(t, question, aRec.Hdr.Name) + require.Equal(t, tc.expectedServiceIPv6Address, aRec.AAAA.String()) + } else { + require.Len(t, in.Answer, 0) } - require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) } - type testCase struct { - nodeAddress string - nodeTaggedAddresses map[string]string - serviceAddress string - serviceTaggedAddresses map[string]structs.ServiceAddress + // Look up node + m := new(dns.Msg) + m.SetQuestion("foo.node.consul.", dns.TypeA) - expectedServiceIPv4Address string - expectedServiceIPv6Address string - expectedNodeIPv4Address string - expectedNodeIPv6Address string + c := new(dns.Client) + addr := a.config.DNSAddrs[0].String() + in, _, err := c.Exchange(m, addr) + require.NoError(t, err) + + if tc.expectedNodeIPv4Address != "" { + require.Len(t, in.Answer, 1) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok, "Bad: %#v", in.Answer[0]) + require.Equal(t, "foo.node.consul.", aRec.Hdr.Name) + require.Equal(t, tc.expectedNodeIPv4Address, aRec.A.String()) + } else { + require.Len(t, in.Answer, 0) } - cases := map[string]testCase{ - "simple-ipv4": { - serviceAddress: "127.0.0.2", - nodeAddress: "127.0.0.1", + m = new(dns.Msg) + m.SetQuestion("foo.node.consul.", dns.TypeAAAA) - expectedServiceIPv4Address: "127.0.0.2", - expectedServiceIPv6Address: "", - expectedNodeIPv4Address: "127.0.0.1", - expectedNodeIPv6Address: "", - }, - "simple-ipv6": { - serviceAddress: "::2", - nodeAddress: "::1", + c = new(dns.Client) + addr = a.config.DNSAddrs[0].String() + in, _, err = c.Exchange(m, addr) + require.NoError(t, err) - expectedServiceIPv6Address: "::2", - expectedServiceIPv4Address: "", - expectedNodeIPv6Address: "::1", - expectedNodeIPv4Address: "", - }, - "ipv4-with-tagged-ipv6": { - serviceAddress: "127.0.0.2", - nodeAddress: "127.0.0.1", - - serviceTaggedAddresses: map[string]structs.ServiceAddress{ - structs.TaggedAddressLANIPv6: {Address: "::2"}, - }, - nodeTaggedAddresses: map[string]string{ - structs.TaggedAddressLANIPv6: "::1", - }, - - expectedServiceIPv4Address: "127.0.0.2", - expectedServiceIPv6Address: "::2", - expectedNodeIPv4Address: "127.0.0.1", - expectedNodeIPv6Address: "::1", - }, - "ipv6-with-tagged-ipv4": { - serviceAddress: "::2", - nodeAddress: "::1", - - serviceTaggedAddresses: map[string]structs.ServiceAddress{ - structs.TaggedAddressLANIPv4: {Address: "127.0.0.2"}, - }, - nodeTaggedAddresses: map[string]string{ - structs.TaggedAddressLANIPv4: "127.0.0.1", - }, - - expectedServiceIPv4Address: "127.0.0.2", - expectedServiceIPv6Address: "::2", - expectedNodeIPv4Address: "127.0.0.1", - expectedNodeIPv6Address: "::1", - }, - } - - for name, tc := range cases { - name := name - tc := tc - t.Run(name, func(t *testing.T) { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: tc.nodeAddress, - TaggedAddresses: tc.nodeTaggedAddresses, - Service: &structs.NodeService{ - Service: "db", - Address: tc.serviceAddress, - Port: 8080, - TaggedAddresses: tc.serviceTaggedAddresses, - }, - } - - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - - // Look up the SRV record via service and prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) - - c := new(dns.Client) - addr := a.config.DNSAddrs[0].String() - in, _, err := c.Exchange(m, addr) - require.NoError(t, err) - - if tc.expectedServiceIPv4Address != "" { - require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok, "Bad: %#v", in.Answer[0]) - require.Equal(t, question, aRec.Hdr.Name) - require.Equal(t, tc.expectedServiceIPv4Address, aRec.A.String()) - } else { - require.Len(t, in.Answer, 0) - } - - m = new(dns.Msg) - m.SetQuestion(question, dns.TypeAAAA) - - c = new(dns.Client) - addr = a.config.DNSAddrs[0].String() - in, _, err = c.Exchange(m, addr) - require.NoError(t, err) - - if tc.expectedServiceIPv6Address != "" { - require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.AAAA) - require.True(t, ok, "Bad: %#v", in.Answer[0]) - require.Equal(t, question, aRec.Hdr.Name) - require.Equal(t, tc.expectedServiceIPv6Address, aRec.AAAA.String()) - } else { - require.Len(t, in.Answer, 0) - } - } - - // Look up node - m := new(dns.Msg) - m.SetQuestion("foo.node.consul.", dns.TypeA) - - c := new(dns.Client) - addr := a.config.DNSAddrs[0].String() - in, _, err := c.Exchange(m, addr) - require.NoError(t, err) - - if tc.expectedNodeIPv4Address != "" { - require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok, "Bad: %#v", in.Answer[0]) - require.Equal(t, "foo.node.consul.", aRec.Hdr.Name) - require.Equal(t, tc.expectedNodeIPv4Address, aRec.A.String()) - } else { - require.Len(t, in.Answer, 0) - } - - m = new(dns.Msg) - m.SetQuestion("foo.node.consul.", dns.TypeAAAA) - - c = new(dns.Client) - addr = a.config.DNSAddrs[0].String() - in, _, err = c.Exchange(m, addr) - require.NoError(t, err) - - if tc.expectedNodeIPv6Address != "" { - require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.AAAA) - require.True(t, ok, "Bad: %#v", in.Answer[0]) - require.Equal(t, "foo.node.consul.", aRec.Hdr.Name) - require.Equal(t, tc.expectedNodeIPv6Address, aRec.AAAA.String()) - } else { - require.Len(t, in.Answer, 0) - } - }) + if tc.expectedNodeIPv6Address != "" { + require.Len(t, in.Answer, 1) + aRec, ok := in.Answer[0].(*dns.AAAA) + require.True(t, ok, "Bad: %#v", in.Answer[0]) + require.Equal(t, "foo.node.consul.", aRec.Hdr.Name) + require.Equal(t, tc.expectedNodeIPv6Address, aRec.AAAA.String()) + } else { + require.Len(t, in.Answer, 0) } }) } @@ -1080,122 +1010,118 @@ func TestDNS_PreparedQueryNearIPEDNS(t *testing.T) { {"foo3", "198.18.0.3", librtt.GenerateCoordinate(30 * time.Millisecond)}, } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - added := 0 + added := 0 - // Register nodes with a service - for _, cfg := range serviceNodes { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: cfg.name, - Address: cfg.address, - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - }, - } + // Register nodes with a service + for _, cfg := range serviceNodes { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: cfg.name, + Address: cfg.address, + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + }, + } - var out struct{} - err := a.RPC(context.Background(), "Catalog.Register", args, &out) - require.NoError(t, err) + var out struct{} + err := a.RPC(context.Background(), "Catalog.Register", args, &out) + require.NoError(t, err) - // Send coordinate updates - coordArgs := structs.CoordinateUpdateRequest{ - Datacenter: "dc1", - Node: cfg.name, - Coord: cfg.coord, - } - err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) - require.NoError(t, err) + // Send coordinate updates + coordArgs := structs.CoordinateUpdateRequest{ + Datacenter: "dc1", + Node: cfg.name, + Coord: cfg.coord, + } + err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) + require.NoError(t, err) - added += 1 - } - - fmt.Printf("Added %d service nodes\n", added) - - // Register a node without a service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "198.18.0.9", - } - - var out struct{} - err := a.RPC(context.Background(), "Catalog.Register", args, &out) - require.NoError(t, err) - - // Send coordinate updates for a few nodes. - coordArgs := structs.CoordinateUpdateRequest{ - Datacenter: "dc1", - Node: "bar", - Coord: ipCoord, - } - err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) - require.NoError(t, err) - } - - // Register a prepared query Near = _ip - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "some.query.we.like", - Service: structs.ServiceQuery{ - Service: "db", - Near: "_ip", - }, - }, - } - - var id string - err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id) - require.NoError(t, err) - } - retry.Run(t, func(r *retry.R) { - m := new(dns.Msg) - m.SetQuestion("some.query.we.like.query.consul.", dns.TypeA) - m.SetEdns0(4096, false) - o := new(dns.OPT) - o.Hdr.Name = "." - o.Hdr.Rrtype = dns.TypeOPT - e := new(dns.EDNS0_SUBNET) - e.Code = dns.EDNS0SUBNET - e.Family = 1 - e.SourceNetmask = 32 - e.SourceScope = 0 - e.Address = net.ParseIP("198.18.0.9").To4() - o.Option = append(o.Option, e) - m.Extra = append(m.Extra, o) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - r.Fatalf("Error with call to dns.Client.Exchange: %s", err) - } - - if len(serviceNodes) != len(in.Answer) { - r.Fatalf("Expecting %d A RRs in response, Actual found was %d", len(serviceNodes), len(in.Answer)) - } - - for i, rr := range in.Answer { - if aRec, ok := rr.(*dns.A); ok { - if actual := aRec.A.String(); serviceNodes[i].address != actual { - r.Fatalf("Expecting A RR #%d = %s, Actual RR was %s", i, serviceNodes[i].address, actual) - } - } else { - r.Fatalf("DNS Answer contained a non-A RR") - } - } - }) - }) + added += 1 } + + fmt.Printf("Added %d service nodes\n", added) + + // Register a node without a service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "198.18.0.9", + } + + var out struct{} + err := a.RPC(context.Background(), "Catalog.Register", args, &out) + require.NoError(t, err) + + // Send coordinate updates for a few nodes. + coordArgs := structs.CoordinateUpdateRequest{ + Datacenter: "dc1", + Node: "bar", + Coord: ipCoord, + } + err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) + require.NoError(t, err) + } + + // Register a prepared query Near = _ip + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "some.query.we.like", + Service: structs.ServiceQuery{ + Service: "db", + Near: "_ip", + }, + }, + } + + var id string + err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id) + require.NoError(t, err) + } + retry.Run(t, func(r *retry.R) { + m := new(dns.Msg) + m.SetQuestion("some.query.we.like.query.consul.", dns.TypeA) + m.SetEdns0(4096, false) + o := new(dns.OPT) + o.Hdr.Name = "." + o.Hdr.Rrtype = dns.TypeOPT + e := new(dns.EDNS0_SUBNET) + e.Code = dns.EDNS0SUBNET + e.Family = 1 + e.SourceNetmask = 32 + e.SourceScope = 0 + e.Address = net.ParseIP("198.18.0.9").To4() + o.Option = append(o.Option, e) + m.Extra = append(m.Extra, o) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + r.Fatalf("Error with call to dns.Client.Exchange: %s", err) + } + + if len(serviceNodes) != len(in.Answer) { + r.Fatalf("Expecting %d A RRs in response, Actual found was %d", len(serviceNodes), len(in.Answer)) + } + + for i, rr := range in.Answer { + if aRec, ok := rr.(*dns.A); ok { + if actual := aRec.A.String(); serviceNodes[i].address != actual { + r.Fatalf("Expecting A RR #%d = %s, Actual RR was %s", i, serviceNodes[i].address, actual) + } + } else { + r.Fatalf("DNS Answer contained a non-A RR") + } + } + }) } func TestDNS_PreparedQueryNearIP(t *testing.T) { @@ -1214,111 +1140,107 @@ func TestDNS_PreparedQueryNearIP(t *testing.T) { {"foo3", "198.18.0.3", librtt.GenerateCoordinate(30 * time.Millisecond)}, } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - added := 0 + added := 0 - // Register nodes with a service - for _, cfg := range serviceNodes { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: cfg.name, - Address: cfg.address, - Service: &structs.NodeService{ - Service: "db", - Port: 12345, - }, - } + // Register nodes with a service + for _, cfg := range serviceNodes { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: cfg.name, + Address: cfg.address, + Service: &structs.NodeService{ + Service: "db", + Port: 12345, + }, + } - var out struct{} - err := a.RPC(context.Background(), "Catalog.Register", args, &out) - require.NoError(t, err) + var out struct{} + err := a.RPC(context.Background(), "Catalog.Register", args, &out) + require.NoError(t, err) - // Send coordinate updates - coordArgs := structs.CoordinateUpdateRequest{ - Datacenter: "dc1", - Node: cfg.name, - Coord: cfg.coord, - } - err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) - require.NoError(t, err) + // Send coordinate updates + coordArgs := structs.CoordinateUpdateRequest{ + Datacenter: "dc1", + Node: cfg.name, + Coord: cfg.coord, + } + err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) + require.NoError(t, err) - added += 1 - } - - fmt.Printf("Added %d service nodes\n", added) - - // Register a node without a service - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "bar", - Address: "198.18.0.9", - } - - var out struct{} - err := a.RPC(context.Background(), "Catalog.Register", args, &out) - require.NoError(t, err) - - // Send coordinate updates for a few nodes. - coordArgs := structs.CoordinateUpdateRequest{ - Datacenter: "dc1", - Node: "bar", - Coord: ipCoord, - } - err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) - require.NoError(t, err) - } - - // Register a prepared query Near = _ip - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "some.query.we.like", - Service: structs.ServiceQuery{ - Service: "db", - Near: "_ip", - }, - }, - } - - var id string - err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id) - require.NoError(t, err) - } - - retry.Run(t, func(r *retry.R) { - m := new(dns.Msg) - m.SetQuestion("some.query.we.like.query.consul.", dns.TypeA) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - r.Fatalf("Error with call to dns.Client.Exchange: %s", err) - } - - if len(serviceNodes) != len(in.Answer) { - r.Fatalf("Expecting %d A RRs in response, Actual found was %d", len(serviceNodes), len(in.Answer)) - } - - for i, rr := range in.Answer { - if aRec, ok := rr.(*dns.A); ok { - if actual := aRec.A.String(); serviceNodes[i].address != actual { - r.Fatalf("Expecting A RR #%d = %s, Actual RR was %s", i, serviceNodes[i].address, actual) - } - } else { - r.Fatalf("DNS Answer contained a non-A RR") - } - } - }) - }) + added += 1 } + + fmt.Printf("Added %d service nodes\n", added) + + // Register a node without a service + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "bar", + Address: "198.18.0.9", + } + + var out struct{} + err := a.RPC(context.Background(), "Catalog.Register", args, &out) + require.NoError(t, err) + + // Send coordinate updates for a few nodes. + coordArgs := structs.CoordinateUpdateRequest{ + Datacenter: "dc1", + Node: "bar", + Coord: ipCoord, + } + err = a.RPC(context.Background(), "Coordinate.Update", &coordArgs, &out) + require.NoError(t, err) + } + + // Register a prepared query Near = _ip + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "some.query.we.like", + Service: structs.ServiceQuery{ + Service: "db", + Near: "_ip", + }, + }, + } + + var id string + err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id) + require.NoError(t, err) + } + + retry.Run(t, func(r *retry.R) { + m := new(dns.Msg) + m.SetQuestion("some.query.we.like.query.consul.", dns.TypeA) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + r.Fatalf("Error with call to dns.Client.Exchange: %s", err) + } + + if len(serviceNodes) != len(in.Answer) { + r.Fatalf("Expecting %d A RRs in response, Actual found was %d", len(serviceNodes), len(in.Answer)) + } + + for i, rr := range in.Answer { + if aRec, ok := rr.(*dns.A); ok { + if actual := aRec.A.String(); serviceNodes[i].address != actual { + r.Fatalf("Expecting A RR #%d = %s, Actual RR was %s", i, serviceNodes[i].address, actual) + } + } else { + r.Fatalf("DNS Answer contained a non-A RR") + } + } + }) } func TestDNS_Recurse(t *testing.T) { @@ -1331,31 +1253,28 @@ func TestDNS_Recurse(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("apple.com.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("apple.com.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Answer) == 0 { - t.Fatalf("Bad: %#v", in) - } - if in.Rcode != dns.RcodeSuccess { - t.Fatalf("Bad: %#v", in) - } - }) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) } + + if len(in.Answer) == 0 { + t.Fatalf("Bad: %#v", in) + } + if in.Rcode != dns.RcodeSuccess { + t.Fatalf("Bad: %#v", in) + } + } func TestDNS_Recurse_Truncation(t *testing.T) { @@ -1369,32 +1288,28 @@ func TestDNS_Recurse_Truncation(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("apple.com.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("apple.com.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - if in.Truncated != true { - t.Fatalf("err: message should have been truncated %v", in) - } - if len(in.Answer) == 0 { - t.Fatalf("Bad: Truncated message ignored, expected some reply %#v", in) - } - if in.Rcode != dns.RcodeSuccess { - t.Fatalf("Bad: %#v", in) - } - }) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + if in.Truncated != true { + t.Fatalf("err: message should have been truncated %v", in) + } + if len(in.Answer) == 0 { + t.Fatalf("Bad: Truncated message ignored, expected some reply %#v", in) + } + if in.Rcode != dns.RcodeSuccess { + t.Fatalf("Bad: %#v", in) } } @@ -1417,43 +1332,39 @@ func TestDNS_RecursorTimeout(t *testing.T) { } defer resolver.Close() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+resolver.LocalAddr().String()+`"] // host must cause a connection|read|write timeout dns_config { recursor_timeout = "`+serverClientTimeout.String()+`" } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("apple.com.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("apple.com.", dns.TypeANY) - // This client calling the server under test must have a longer timeout than the one we set internally - c := &dns.Client{Timeout: testClientTimeout} + // This client calling the server under test must have a longer timeout than the one we set internally + c := &dns.Client{Timeout: testClientTimeout} - start := time.Now() - in, _, err := c.Exchange(m, a.DNSAddr()) + start := time.Now() + in, _, err := c.Exchange(m, a.DNSAddr()) - duration := time.Since(start) + duration := time.Since(start) - if err != nil { - t.Fatalf("err: %v", err) - } + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 0 { - t.Fatalf("Bad: %#v", in) - } - if in.Rcode != dns.RcodeServerFailure { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 0 { + t.Fatalf("Bad: %#v", in) + } + if in.Rcode != dns.RcodeServerFailure { + t.Fatalf("Bad: %#v", in) + } - if duration < serverClientTimeout { - t.Fatalf("Expected the call to return after at least %f seconds but lasted only %f", serverClientTimeout.Seconds(), duration.Seconds()) - } - }) + if duration < serverClientTimeout { + t.Fatalf("Expected the call to return after at least %f seconds but lasted only %f", serverClientTimeout.Seconds(), duration.Seconds()) } } @@ -1504,115 +1415,111 @@ func TestDNS_TCP_and_UDP_Truncate(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { enable_truncate = true } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - services := []string{"normal", "truncated"} - for index, service := range services { - numServices := (index * 5000) + 2 - var eg errgroup.Group - for i := 1; i < numServices; i++ { - j := i - eg.Go(func() error { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("%s-%d.acme.com", service, j), - Address: fmt.Sprintf("127.%d.%d.%d", 0, (j / 255), j%255), - Service: &structs.NodeService{ - Service: service, - Port: 8000, - }, - } - - var out struct{} - return a.RPC(context.Background(), "Catalog.Register", args, &out) - }) - } - if err := eg.Wait(); err != nil { - t.Fatalf("error registering: %v", err) + services := []string{"normal", "truncated"} + for index, service := range services { + numServices := (index * 5000) + 2 + var eg errgroup.Group + for i := 1; i < numServices; i++ { + j := i + eg.Go(func() error { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: fmt.Sprintf("%s-%d.acme.com", service, j), + Address: fmt.Sprintf("127.%d.%d.%d", 0, (j / 255), j%255), + Service: &structs.NodeService{ + Service: service, + Port: 8000, + }, } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: service, - Service: structs.ServiceQuery{ - Service: service, - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + return a.RPC(context.Background(), "Catalog.Register", args, &out) + }) + } + if err := eg.Wait(); err != nil { + t.Fatalf("error registering: %v", err) + } - // Look up the service directly and via prepared query. Ensure the - // response is truncated each time. - questions := []string{ - fmt.Sprintf("%s.service.consul.", service), - id + ".query.consul.", - } - protocols := []string{ - "tcp", - "udp", - } - for _, maxSize := range []uint16{8192, 65535} { - for _, qType := range []uint16{dns.TypeANY, dns.TypeA, dns.TypeSRV} { - for _, question := range questions { - for _, protocol := range protocols { - for _, compress := range []bool{true, false} { - t.Run(fmt.Sprintf("lookup %s %s (qType:=%d) compressed=%v", question, protocol, qType, compress), func(t *testing.T) { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) - maxSz := maxSize - if protocol == "udp" { - maxSz = 8192 - } - m.SetEdns0(maxSz, true) - c := new(dns.Client) - c.Net = protocol - m.Compress = compress - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - // actually check if we need to have the truncate bit - resbuf, err := in.Pack() - if err != nil { - t.Fatalf("Error while packing answer: %s", err) - } - if !in.Truncated && len(resbuf) > int(maxSz) { - t.Fatalf("should have truncate bit %#v %#v", in, len(in.Answer)) - } - // Check for the truncate bit - buf, err := m.Pack() - info := fmt.Sprintf("service %s question:=%s (%s) (%d total records) sz:= %d in %v", - service, question, protocol, numServices, len(in.Answer), in) - if err != nil { - t.Fatalf("Error while packing: %v ; info:=%s", err, info) - } - if len(buf) > int(maxSz) { - t.Fatalf("len(buf) := %d > maxSz=%d for %v", len(buf), maxSz, info) - } - }) + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: service, + Service: structs.ServiceQuery{ + Service: service, + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Look up the service directly and via prepared query. Ensure the + // response is truncated each time. + questions := []string{ + fmt.Sprintf("%s.service.consul.", service), + id + ".query.consul.", + } + protocols := []string{ + "tcp", + "udp", + } + for _, maxSize := range []uint16{8192, 65535} { + for _, qType := range []uint16{dns.TypeANY, dns.TypeA, dns.TypeSRV} { + for _, question := range questions { + for _, protocol := range protocols { + for _, compress := range []bool{true, false} { + t.Run(fmt.Sprintf("lookup %s %s (qType:=%d) compressed=%v", question, protocol, qType, compress), func(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) + maxSz := maxSize + if protocol == "udp" { + maxSz = 8192 } - } + m.SetEdns0(maxSz, true) + c := new(dns.Client) + c.Net = protocol + m.Compress = compress + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + // actually check if we need to have the truncate bit + resbuf, err := in.Pack() + if err != nil { + t.Fatalf("Error while packing answer: %s", err) + } + if !in.Truncated && len(resbuf) > int(maxSz) { + t.Fatalf("should have truncate bit %#v %#v", in, len(in.Answer)) + } + // Check for the truncate bit + buf, err := m.Pack() + info := fmt.Sprintf("service %s question:=%s (%s) (%d total records) sz:= %d in %v", + service, question, protocol, numServices, len(in.Answer), in) + if err != nil { + t.Fatalf("Error while packing: %v ; info:=%s", err, info) + } + if len(buf) > int(maxSz) { + t.Fatalf("len(buf) := %d > maxSz=%d for %v", len(buf), maxSz, info) + } + }) } } } } - }) + } } } @@ -1621,37 +1528,33 @@ func TestDNS_AddressLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Look up the addresses - cases := map[string]string{ - "7f000001.addr.dc1.consul.": "127.0.0.1", - } - for question, answer := range cases { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) + // Look up the addresses + cases := map[string]string{ + "7f000001.addr.dc1.consul.": "127.0.0.1", + } + for question, answer := range cases { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - require.Len(t, in.Answer, 1) + require.Len(t, in.Answer, 1) - require.Equal(t, dns.TypeA, in.Answer[0].Header().Rrtype) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok) - require.Equal(t, aRec.A.To4().String(), answer) - require.Zero(t, aRec.Hdr.Ttl) - require.Nil(t, in.Ns) - require.Nil(t, in.Extra) - } - }) + require.Equal(t, dns.TypeA, in.Answer[0].Header().Rrtype) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok) + require.Equal(t, aRec.A.To4().String(), answer) + require.Zero(t, aRec.Hdr.Ttl) + require.Nil(t, in.Ns) + require.Nil(t, in.Extra) } } @@ -1660,33 +1563,29 @@ func TestDNS_AddressLookupANY(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Look up the addresses - cases := map[string]string{ - "7f000001.addr.dc1.consul.": "127.0.0.1", - } - for question, answer := range cases { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeANY) + // Look up the addresses + cases := map[string]string{ + "7f000001.addr.dc1.consul.": "127.0.0.1", + } + for question, answer := range cases { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Len(t, in.Answer, 1) - require.Equal(t, in.Answer[0].Header().Rrtype, dns.TypeA) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok) - require.Equal(t, aRec.A.To4().String(), answer) - require.Zero(t, aRec.Hdr.Ttl) + require.NoError(t, err) + require.Len(t, in.Answer, 1) + require.Equal(t, in.Answer[0].Header().Rrtype, dns.TypeA) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok) + require.Equal(t, aRec.A.To4().String(), answer) + require.Zero(t, aRec.Hdr.Ttl) - } - }) } } @@ -1695,34 +1594,30 @@ func TestDNS_AddressLookupInvalidType(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Look up the addresses - cases := map[string]string{ - "7f000001.addr.dc1.consul.": "", - } - for question := range cases { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the addresses + cases := map[string]string{ + "7f000001.addr.dc1.consul.": "", + } + for question := range cases { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - require.NoError(t, err) - require.Zero(t, in.Rcode) - require.Nil(t, in.Answer) - require.NotNil(t, in.Extra) - require.Len(t, in.Extra, 1) - aRecord := in.Extra[0].(*dns.A) - require.Equal(t, "7f000001.addr.dc1.consul.", aRecord.Hdr.Name) - require.Equal(t, dns.TypeA, aRecord.Hdr.Rrtype) - require.Zero(t, aRecord.Hdr.Ttl) - require.Equal(t, "127.0.0.1", aRecord.A.String()) - } - }) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + require.NoError(t, err) + require.Zero(t, in.Rcode) + require.Nil(t, in.Answer) + require.NotNil(t, in.Extra) + require.Len(t, in.Extra, 1) + aRecord := in.Extra[0].(*dns.A) + require.Equal(t, "7f000001.addr.dc1.consul.", aRecord.Hdr.Name) + require.Equal(t, dns.TypeA, aRecord.Hdr.Rrtype) + require.Zero(t, aRecord.Hdr.Ttl) + require.Equal(t, "127.0.0.1", aRecord.A.String()) } } @@ -1731,46 +1626,42 @@ func TestDNS_AddressLookupIPV6(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Look up the addresses - cases := map[string]string{ - "2607002040050808000000000000200e.addr.consul.": "2607:20:4005:808::200e", - "2607112040051808ffffffffffff200e.addr.consul.": "2607:1120:4005:1808:ffff:ffff:ffff:200e", - } - for question, answer := range cases { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeAAAA) + // Look up the addresses + cases := map[string]string{ + "2607002040050808000000000000200e.addr.consul.": "2607:20:4005:808::200e", + "2607112040051808ffffffffffff200e.addr.consul.": "2607:1120:4005:1808:ffff:ffff:ffff:200e", + } + for question, answer := range cases { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeAAAA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - if in.Answer[0].Header().Rrtype != dns.TypeAAAA { - t.Fatalf("Invalid type: %#v", in.Answer[0]) - } - aaaaRec, ok := in.Answer[0].(*dns.AAAA) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if aaaaRec.AAAA.To16().String() != answer { - t.Fatalf("Bad: %#v", aaaaRec) - } - if aaaaRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - } - }) + if in.Answer[0].Header().Rrtype != dns.TypeAAAA { + t.Fatalf("Invalid type: %#v", in.Answer[0]) + } + aaaaRec, ok := in.Answer[0].(*dns.AAAA) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if aaaaRec.AAAA.To16().String() != answer { + t.Fatalf("Bad: %#v", aaaaRec) + } + if aaaaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Answer[0]) + } } } @@ -1779,32 +1670,28 @@ func TestDNS_AddressLookupIPV6InvalidType(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Look up the addresses - cases := map[string]string{ - "2607002040050808000000000000200e.addr.consul.": "2607:20:4005:808::200e", - "2607112040051808ffffffffffff200e.addr.consul.": "2607:1120:4005:1808:ffff:ffff:ffff:200e", - } - for question := range cases { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Look up the addresses + cases := map[string]string{ + "2607002040050808000000000000200e.addr.consul.": "2607:20:4005:808::200e", + "2607112040051808ffffffffffff200e.addr.consul.": "2607:1120:4005:1808:ffff:ffff:ffff:200e", + } + for question := range cases { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if in.Answer != nil { - t.Fatalf("Bad: %#v", in) - } - } - }) + if in.Answer != nil { + t.Fatalf("Bad: %#v", in) + } } } @@ -1816,31 +1703,27 @@ func TestDNS_NonExistentDC_Server(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("consul.service.dc2.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("consul.service.dc2.consul.", dns.TypeANY) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - require.Equal(t, dns.RcodeNameError, in.Rcode) - require.Equal(t, 0, len(in.Answer)) - require.Equal(t, 0, len(in.Extra)) - require.Equal(t, 1, len(in.Ns)) - soa := in.Ns[0].(*dns.SOA) - require.Equal(t, "consul.", soa.Hdr.Name) - require.Equal(t, "ns.consul.", soa.Ns) - require.Equal(t, "hostmaster.consul.", soa.Mbox) - }) + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) } + + require.Equal(t, dns.RcodeNameError, in.Rcode) + require.Equal(t, 0, len(in.Answer)) + require.Equal(t, 0, len(in.Extra)) + require.Equal(t, 1, len(in.Ns)) + soa := in.Ns[0].(*dns.SOA) + require.Equal(t, "consul.", soa.Hdr.Name) + require.Equal(t, "ns.consul.", soa.Ns) + require.Equal(t, "hostmaster.consul.", soa.Mbox) } // TestDNS_NonExistentDC_RPC verifies NXDOMAIN is returned when @@ -1851,39 +1734,35 @@ func TestDNS_NonExistentDC_RPC(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - s := NewTestAgent(t, ` + s := NewTestAgent(t, ` node_name = "test-server" - `+experimentsHCL) + `) - defer s.Shutdown() - c := NewTestAgent(t, ` + defer s.Shutdown() + c := NewTestAgent(t, ` node_name = "test-client" bootstrap = false server = false - `+experimentsHCL) - defer c.Shutdown() + `) + defer c.Shutdown() - // Join LAN cluster - addr := fmt.Sprintf("127.0.0.1:%d", s.Config.SerfPortLAN) - _, err := c.JoinLAN([]string{addr}, nil) - require.NoError(t, err) - testrpc.WaitForTestAgent(t, c.RPC, "dc1") + // Join LAN cluster + addr := fmt.Sprintf("127.0.0.1:%d", s.Config.SerfPortLAN) + _, err := c.JoinLAN([]string{addr}, nil) + require.NoError(t, err) + testrpc.WaitForTestAgent(t, c.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("consul.service.dc2.consul.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("consul.service.dc2.consul.", dns.TypeANY) - d := new(dns.Client) - in, _, err := d.Exchange(m, c.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + d := new(dns.Client) + in, _, err := d.Exchange(m, c.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if in.Rcode != dns.RcodeNameError { - t.Fatalf("Expected RCode: %#v, had: %#v", dns.RcodeNameError, in.Rcode) - } - }) + if in.Rcode != dns.RcodeNameError { + t.Fatalf("Expected RCode: %#v, had: %#v", dns.RcodeNameError, in.Rcode) } } @@ -1892,15 +1771,148 @@ func TestDNS_NonExistentLookup(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // lookup a non-existing node, we should receive a SOA + // lookup a non-existing node, we should receive a SOA + m := new(dns.Msg) + m.SetQuestion("nonexisting.consul.", dns.TypeANY) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + if len(in.Ns) != 1 { + t.Fatalf("Bad: %#v %#v", in, len(in.Answer)) + } + + soaRec, ok := in.Ns[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + if soaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Ns[0]) + } +} + +func TestDNS_NonExistentLookupEmptyAorAAAA(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") + + // Register a v6-only service and a v4-only service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foov6", + Address: "fe80::1", + Service: &structs.NodeService{ + Service: "webv6", + Port: 8000, + }, + } + + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + + args = &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foov4", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "webv4", + Port: 8000, + }, + } + + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Register equivalent prepared queries. + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "webv4", + Service: structs.ServiceQuery{ + Service: "webv4", + }, + }, + } + + var id string + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + + args = &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "webv6", + Service: structs.ServiceQuery{ + Service: "webv6", + }, + }, + } + + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Check for ipv6 records on ipv4-only service directly and via the + // prepared query. + questions := []string{ + "webv4.service.consul.", + "webv4.query.consul.", + } + for _, question := range questions { + t.Run(question, func(t *testing.T) { m := new(dns.Msg) - m.SetQuestion("nonexisting.consul.", dns.TypeANY) + m.SetQuestion(question, dns.TypeAAAA) + + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } + + require.Len(t, in.Ns, 1) + soaRec, ok := in.Ns[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + if soaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + + require.Equal(t, dns.RcodeSuccess, in.Rcode) + }) + } + + // Check for ipv4 records on ipv6-only service directly and via the + // prepared query. + questions = []string{ + "webv6.service.consul.", + "webv6.query.consul.", + } + for _, question := range questions { + t.Run(question, func(t *testing.T) { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) c := new(dns.Client) in, _, err := c.Exchange(m, a.DNSAddr()) @@ -1909,7 +1921,7 @@ func TestDNS_NonExistentLookup(t *testing.T) { } if len(in.Ns) != 1 { - t.Fatalf("Bad: %#v %#v", in, len(in.Answer)) + t.Fatalf("Bad: %#v", in) } soaRec, ok := in.Ns[0].(*dns.SOA) @@ -1919,150 +1931,9 @@ func TestDNS_NonExistentLookup(t *testing.T) { if soaRec.Hdr.Ttl != 0 { t.Fatalf("Bad: %#v", in.Ns[0]) } - }) - } -} -func TestDNS_NonExistentLookupEmptyAorAAAA(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") - - // Register a v6-only service and a v4-only service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foov6", - Address: "fe80::1", - Service: &structs.NodeService{ - Service: "webv6", - Port: 8000, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - - args = &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foov4", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "webv4", - Port: 8000, - }, - } - - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Register equivalent prepared queries. - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "webv4", - Service: structs.ServiceQuery{ - Service: "webv4", - }, - }, - } - - var id string - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - - args = &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "webv6", - Service: structs.ServiceQuery{ - Service: "webv6", - }, - }, - } - - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Check for ipv6 records on ipv4-only service directly and via the - // prepared query. - questions := []string{ - "webv4.service.consul.", - "webv4.query.consul.", - } - for _, question := range questions { - t.Run(question, func(t *testing.T) { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeAAAA) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - require.Len(t, in.Ns, 1) - soaRec, ok := in.Ns[0].(*dns.SOA) - if !ok { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - if soaRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - - require.Equal(t, dns.RcodeSuccess, in.Rcode) - }) - } - - // Check for ipv4 records on ipv6-only service directly and via the - // prepared query. - questions = []string{ - "webv6.service.consul.", - "webv6.query.consul.", - } - for _, question := range questions { - t.Run(question, func(t *testing.T) { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) - - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } - - if len(in.Ns) != 1 { - t.Fatalf("Bad: %#v", in) - } - - soaRec, ok := in.Ns[0].(*dns.SOA) - if !ok { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - if soaRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - - if in.Rcode != dns.RcodeSuccess { - t.Fatalf("Bad: %#v", in) - } - }) + if in.Rcode != dns.RcodeSuccess { + t.Fatalf("Bad: %#v", in) } }) } @@ -2073,96 +1944,92 @@ func TestDNS_AltDomains_Service(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` alt_domain = "test-domain." - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "test-node", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - NodeMeta: map[string]string{ - "key": "value", - }, - } + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "test-node", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + NodeMeta: map[string]string{ + "key": "value", + }, + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - questions := []struct { - ask string - wantDomain string - }{ - {"db.service.consul.", "test-node.node.dc1.consul."}, - {"db.service.test-domain.", "test-node.node.dc1.test-domain."}, - {"db.service.dc1.consul.", "test-node.node.dc1.consul."}, - {"db.service.dc1.test-domain.", "test-node.node.dc1.test-domain."}, - } + questions := []struct { + ask string + wantDomain string + }{ + {"db.service.consul.", "test-node.node.dc1.consul."}, + {"db.service.test-domain.", "test-node.node.dc1.test-domain."}, + {"db.service.dc1.consul.", "test-node.node.dc1.consul."}, + {"db.service.dc1.test-domain.", "test-node.node.dc1.test-domain."}, + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question.ask, dns.TypeSRV) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - srvRec, ok := in.Answer[0].(*dns.SRV) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } - if srvRec.Port != 12345 { - t.Fatalf("Bad: %#v", srvRec) - } - if got, want := srvRec.Target, question.wantDomain; got != want { - t.Fatalf("SRV target invalid, got %v want %v", got, want) - } + srvRec, ok := in.Answer[0].(*dns.SRV) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } + if srvRec.Port != 12345 { + t.Fatalf("Bad: %#v", srvRec) + } + if got, want := srvRec.Target, question.wantDomain; got != want { + t.Fatalf("SRV target invalid, got %v want %v", got, want) + } - aRec, ok := in.Extra[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[0]) - } + aRec, ok := in.Extra[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[0]) + } - if got, want := aRec.Hdr.Name, question.wantDomain; got != want { - t.Fatalf("A record header invalid, got %v want %v", got, want) - } + if got, want := aRec.Hdr.Name, question.wantDomain; got != want { + t.Fatalf("A record header invalid, got %v want %v", got, want) + } - if aRec.A.String() != "127.0.0.1" { - t.Fatalf("Bad: %#v", in.Extra[0]) - } + if aRec.A.String() != "127.0.0.1" { + t.Fatalf("Bad: %#v", in.Extra[0]) + } - txtRec, ok := in.Extra[1].(*dns.TXT) - if !ok { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - if got, want := txtRec.Hdr.Name, question.wantDomain; got != want { - t.Fatalf("TXT record header invalid, got %v want %v", got, want) - } - if txtRec.Txt[0] != "key=value" { - t.Fatalf("Bad: %#v", in.Extra[1]) - } - } - }) + txtRec, ok := in.Extra[1].(*dns.TXT) + if !ok { + t.Fatalf("Bad: %#v", in.Extra[1]) + } + if got, want := txtRec.Hdr.Name, question.wantDomain; got != want { + t.Fatalf("TXT record header invalid, got %v want %v", got, want) + } + if txtRec.Txt[0] != "key=value" { + t.Fatalf("Bad: %#v", in.Extra[1]) + } } } @@ -2171,50 +2038,46 @@ func TestDNS_AltDomains_SOA(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` node_name = "test-node" alt_domain = "test-domain." - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - questions := []struct { - ask string - want_domain string - }{ - {"test-node.node.consul.", "consul."}, - {"test-node.node.test-domain.", "test-domain."}, - } + questions := []struct { + ask string + want_domain string + }{ + {"test-node.node.consul.", "consul."}, + {"test-node.node.test-domain.", "test-domain."}, + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question.ask, dns.TypeSOA) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question.ask, dns.TypeSOA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Answer) != 1 { + t.Fatalf("Bad: %#v", in) + } - soaRec, ok := in.Answer[0].(*dns.SOA) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + soaRec, ok := in.Answer[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - if got, want := soaRec.Hdr.Name, question.want_domain; got != want { - t.Fatalf("SOA name invalid, got %q want %q", got, want) - } - if got, want := soaRec.Ns, ("ns." + question.want_domain); got != want { - t.Fatalf("SOA ns invalid, got %q want %q", got, want) - } - } - }) + if got, want := soaRec.Hdr.Name, question.want_domain; got != want { + t.Fatalf("SOA name invalid, got %q want %q", got, want) + } + if got, want := soaRec.Ns, ("ns." + question.want_domain); got != want { + t.Fatalf("SOA ns invalid, got %q want %q", got, want) + } } } @@ -2226,46 +2089,42 @@ func TestDNS_AltDomains_Overlap(t *testing.T) { // this tests the domain matching logic in DNSServer when encountering more // than one potential match (i.e. ambiguous match) // it should select the longer matching domain when dispatching - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` node_name = "test-node" alt_domain = "test.consul." - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - questions := []string{ - "test-node.node.consul.", - "test-node.node.test.consul.", - "test-node.node.dc1.consul.", - "test-node.node.dc1.test.consul.", - } + questions := []string{ + "test-node.node.consul.", + "test-node.node.test.consul.", + "test-node.node.dc1.consul.", + "test-node.node.dc1.test.consul.", + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Answer) != 1 { - t.Fatalf("failed to resolve ambiguous alt domain %q: %#v", question, in) - } + if len(in.Answer) != 1 { + t.Fatalf("failed to resolve ambiguous alt domain %q: %#v", question, in) + } - aRec, ok := in.Answer[0].(*dns.A) - if !ok { - t.Fatalf("Bad: %#v", in.Answer[0]) - } + aRec, ok := in.Answer[0].(*dns.A) + if !ok { + t.Fatalf("Bad: %#v", in.Answer[0]) + } - if got, want := aRec.A.To4().String(), "127.0.0.1"; got != want { - t.Fatalf("A ip invalid, got %v want %v", got, want) - } - } - }) + if got, want := aRec.A.To4().String(), "127.0.0.1"; got != want { + t.Fatalf("A ip invalid, got %v want %v", got, want) + } } } @@ -2276,38 +2135,34 @@ func TestDNS_AltDomain_DCName_Overlap(t *testing.T) { // this tests the DC name overlap with the consul domain/alt-domain // we should get response when DC suffix is a prefix of consul alt-domain - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` datacenter = "dc-test" node_name = "test-node" alt_domain = "test.consul." - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc-test") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc-test") - questions := []string{ - "test-node.node.dc-test.consul.", - "test-node.node.dc-test.test.consul.", - } + questions := []string{ + "test-node.node.dc-test.consul.", + "test-node.node.dc-test.test.consul.", + } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeA) + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeA) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - require.Len(t, in.Answer, 1) + require.Len(t, in.Answer, 1) - aRec, ok := in.Answer[0].(*dns.A) - require.True(t, ok) - require.Equal(t, aRec.A.To4().String(), "127.0.0.1") - } - }) + aRec, ok := in.Answer[0].(*dns.A) + require.True(t, ok) + require.Equal(t, aRec.A.To4().String(), "127.0.0.1") } } @@ -2316,54 +2171,50 @@ func TestDNS_PreparedQuery_AllowStale(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { allow_stale = true max_stale = "1s" } - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := MockPreparedQuery{ - executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { - // Return a response that's perpetually too stale. - reply.LastContact = 2 * time.Second - return nil - }, - } + m := MockPreparedQuery{ + executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { + // Return a response that's perpetually too stale. + reply.LastContact = 2 * time.Second + return nil + }, + } - if err := a.registerEndpoint("PreparedQuery", &m); err != nil { - t.Fatalf("err: %v", err) - } + if err := a.registerEndpoint("PreparedQuery", &m); err != nil { + t.Fatalf("err: %v", err) + } - // Make sure that the lookup terminates and results in an SOA since - // the query doesn't exist. - { - m := new(dns.Msg) - m.SetQuestion("nope.query.consul.", dns.TypeSRV) + // Make sure that the lookup terminates and results in an SOA since + // the query doesn't exist. + { + m := new(dns.Msg) + m.SetQuestion("nope.query.consul.", dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Ns) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Ns) != 1 { + t.Fatalf("Bad: %#v", in) + } - soaRec, ok := in.Ns[0].(*dns.SOA) - if !ok { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - if soaRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - } - }) + soaRec, ok := in.Ns[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + if soaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Ns[0]) + } } } @@ -2372,46 +2223,42 @@ func TestDNS_InvalidQueries(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - // Try invalid forms of queries that should hit the special invalid case - // of our query parser. - questions := []string{ - "consul.", - "node.consul.", - "service.consul.", - "query.consul.", - "foo.node.dc1.extra.more.consul.", - "foo.service.dc1.extra.more.consul.", - "foo.query.dc1.extra.more.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + // Try invalid forms of queries that should hit the special invalid case + // of our query parser. + questions := []string{ + "consul.", + "node.consul.", + "service.consul.", + "query.consul.", + "foo.node.dc1.extra.more.consul.", + "foo.service.dc1.extra.more.consul.", + "foo.query.dc1.extra.more.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - if len(in.Ns) != 1 { - t.Fatalf("Bad: %#v", in) - } + if len(in.Ns) != 1 { + t.Fatalf("Bad: %#v", in) + } - soaRec, ok := in.Ns[0].(*dns.SOA) - if !ok { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - if soaRec.Hdr.Ttl != 0 { - t.Fatalf("Bad: %#v", in.Ns[0]) - } - } - }) + soaRec, ok := in.Ns[0].(*dns.SOA) + if !ok { + t.Fatalf("Bad: %#v", in.Ns[0]) + } + if soaRec.Hdr.Ttl != 0 { + t.Fatalf("Bad: %#v", in.Ns[0]) + } } } @@ -2420,38 +2267,34 @@ func TestDNS_PreparedQuery_AgentSource(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := MockPreparedQuery{ - executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { - // Check that the agent inserted its self-name and datacenter to - // the RPC request body. - if args.Agent.Datacenter != a.Config.Datacenter || - args.Agent.Node != a.Config.NodeName { - t.Fatalf("bad: %#v", args.Agent) - } - return nil - }, + m := MockPreparedQuery{ + executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { + // Check that the agent inserted its self-name and datacenter to + // the RPC request body. + if args.Agent.Datacenter != a.Config.Datacenter || + args.Agent.Node != a.Config.NodeName { + t.Fatalf("bad: %#v", args.Agent) } + return nil + }, + } - if err := a.registerEndpoint("PreparedQuery", &m); err != nil { - t.Fatalf("err: %v", err) - } + if err := a.registerEndpoint("PreparedQuery", &m); err != nil { + t.Fatalf("err: %v", err) + } - { - m := new(dns.Msg) - m.SetQuestion("foo.query.consul.", dns.TypeSRV) + { + m := new(dns.Msg) + m.SetQuestion("foo.query.consul.", dns.TypeSRV) - c := new(dns.Client) - if _, _, err := c.Exchange(m, a.DNSAddr()); err != nil { - t.Fatalf("err: %v", err) - } - } - }) + c := new(dns.Client) + if _, _, err := c.Exchange(m, a.DNSAddr()); err != nil { + t.Fatalf("err: %v", err) + } } } @@ -2460,255 +2303,234 @@ func TestDNS_EDNS_Truncate_AgentSource(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` dns_config { enable_truncate = true } - `+experimentsHCL) - defer a.Shutdown() - a.DNSDisableCompression(true) - testrpc.WaitForLeader(t, a.RPC, "dc1") + `) + defer a.Shutdown() + a.DNSDisableCompression(true) + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := MockPreparedQuery{ - executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { - // Check that the agent inserted its self-name and datacenter to - // the RPC request body. - if args.Agent.Datacenter != a.Config.Datacenter || - args.Agent.Node != a.Config.NodeName { - t.Fatalf("bad: %#v", args.Agent) - } - for i := 0; i < 100; i++ { - reply.Nodes = append(reply.Nodes, structs.CheckServiceNode{Node: &structs.Node{Node: "apple", Address: fmt.Sprintf("node.address:%d", i)}, Service: &structs.NodeService{Service: "appleService", Address: fmt.Sprintf("service.address:%d", i)}}) - } - return nil - }, + m := MockPreparedQuery{ + executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { + // Check that the agent inserted its self-name and datacenter to + // the RPC request body. + if args.Agent.Datacenter != a.Config.Datacenter || + args.Agent.Node != a.Config.NodeName { + t.Fatalf("bad: %#v", args.Agent) } - - if err := a.registerEndpoint("PreparedQuery", &m); err != nil { - t.Fatalf("err: %v", err) + for i := 0; i < 100; i++ { + reply.Nodes = append(reply.Nodes, structs.CheckServiceNode{Node: &structs.Node{Node: "apple", Address: fmt.Sprintf("node.address:%d", i)}, Service: &structs.NodeService{Service: "appleService", Address: fmt.Sprintf("service.address:%d", i)}}) } - - req := new(dns.Msg) - req.SetQuestion("foo.query.consul.", dns.TypeSRV) - req.SetEdns0(2048, true) - req.Compress = false - - c := new(dns.Client) - resp, _, err := c.Exchange(req, a.DNSAddr()) - require.NoError(t, err) - require.True(t, resp.Len() < 2048) - }) + return nil + }, } + + if err := a.registerEndpoint("PreparedQuery", &m); err != nil { + t.Fatalf("err: %v", err) + } + + req := new(dns.Msg) + req.SetQuestion("foo.query.consul.", dns.TypeSRV) + req.SetEdns0(2048, true) + req.Compress = false + + c := new(dns.Client) + resp, _, err := c.Exchange(req, a.DNSAddr()) + require.NoError(t, err) + require.True(t, resp.Len() < 2048) } func TestDNS_trimUDPResponse_NoTrim(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { + req := &dns.Msg{} + resp := &dns.Msg{ + Answer: []dns.RR{ + &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: "ip-10-0-1-185.node.dc1.consul.", + }, + }, + Extra: []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{ + Name: "ip-10-0-1-185.node.dc1.consul.", + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP("10.0.1.185"), + }, + }, + } - req := &dns.Msg{} - resp := &dns.Msg{ - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: "ip-10-0-1-185.node.dc1.consul.", - }, - }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "ip-10-0-1-185.node.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("10.0.1.185"), - }, - }, - } + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) + if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); trimmed { + t.Fatalf("Bad %#v", *resp) + } - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) - if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); trimmed { - t.Fatalf("Bad %#v", *resp) - } - - expected := &dns.Msg{ - Answer: []dns.RR{ - &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: "ip-10-0-1-185.node.dc1.consul.", - }, + expected := &dns.Msg{ + Answer: []dns.RR{ + &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, }, - Extra: []dns.RR{ - &dns.A{ - Hdr: dns.RR_Header{ - Name: "ip-10-0-1-185.node.dc1.consul.", - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP("10.0.1.185"), - }, + Target: "ip-10-0-1-185.node.dc1.consul.", + }, + }, + Extra: []dns.RR{ + &dns.A{ + Hdr: dns.RR_Header{ + Name: "ip-10-0-1-185.node.dc1.consul.", + Rrtype: dns.TypeA, + Class: dns.ClassINET, }, - } - if !reflect.DeepEqual(resp, expected) { - t.Fatalf("Bad %#v vs. %#v", *resp, *expected) - } - }) + A: net.ParseIP("10.0.1.185"), + }, + }, + } + if !reflect.DeepEqual(resp, expected) { + t.Fatalf("Bad %#v vs. %#v", *resp, *expected) } } func TestDNS_trimUDPResponse_TrimLimit(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - req, resp, expected := &dns.Msg{}, &dns.Msg{}, &dns.Msg{} - for i := 0; i < cfg.DNSUDPAnswerLimit+1; i++ { - target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) - srv := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: target, - } - a := &dns.A{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), - } + req, resp, expected := &dns.Msg{}, &dns.Msg{}, &dns.Msg{} + for i := 0; i < cfg.DNSUDPAnswerLimit+1; i++ { + target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: target, + } + a := &dns.A{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), + } - resp.Answer = append(resp.Answer, srv) - resp.Extra = append(resp.Extra, a) - if i < cfg.DNSUDPAnswerLimit { - expected.Answer = append(expected.Answer, srv) - expected.Extra = append(expected.Extra, a) - } - } + resp.Answer = append(resp.Answer, srv) + resp.Extra = append(resp.Extra, a) + if i < cfg.DNSUDPAnswerLimit { + expected.Answer = append(expected.Answer, srv) + expected.Extra = append(expected.Extra, a) + } + } - if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { - t.Fatalf("Bad %#v", *resp) - } - if !reflect.DeepEqual(resp, expected) { - t.Fatalf("Bad %#v vs. %#v", *resp, *expected) - } - }) + if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { + t.Fatalf("Bad %#v", *resp) + } + if !reflect.DeepEqual(resp, expected) { + t.Fatalf("Bad %#v vs. %#v", *resp, *expected) } } func TestDNS_trimUDPResponse_TrimLimitWithNS(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - req, resp, expected := &dns.Msg{}, &dns.Msg{}, &dns.Msg{} - for i := 0; i < cfg.DNSUDPAnswerLimit+1; i++ { - target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) - srv := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: target, - } - a := &dns.A{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), - } - ns := &dns.SOA{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - }, - Ns: fmt.Sprintf("soa-%d", i), - } + req, resp, expected := &dns.Msg{}, &dns.Msg{}, &dns.Msg{} + for i := 0; i < cfg.DNSUDPAnswerLimit+1; i++ { + target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: target, + } + a := &dns.A{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), + } + ns := &dns.SOA{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeSOA, + Class: dns.ClassINET, + }, + Ns: fmt.Sprintf("soa-%d", i), + } - resp.Answer = append(resp.Answer, srv) - resp.Extra = append(resp.Extra, a) - resp.Ns = append(resp.Ns, ns) - if i < cfg.DNSUDPAnswerLimit { - expected.Answer = append(expected.Answer, srv) - expected.Extra = append(expected.Extra, a) - } - } - - if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { - t.Fatalf("Bad %#v", *resp) - } - require.LessOrEqual(t, resp.Len(), defaultMaxUDPSize) - require.Len(t, resp.Ns, 0) - }) + resp.Answer = append(resp.Answer, srv) + resp.Extra = append(resp.Extra, a) + resp.Ns = append(resp.Ns, ns) + if i < cfg.DNSUDPAnswerLimit { + expected.Answer = append(expected.Answer, srv) + expected.Extra = append(expected.Extra, a) + } } + + if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { + t.Fatalf("Bad %#v", *resp) + } + require.LessOrEqual(t, resp.Len(), defaultMaxUDPSize) + require.Len(t, resp.Ns, 0) } func TestDNS_trimTCPResponse_TrimLimitWithNS(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - req, resp, expected := &dns.Msg{}, &dns.Msg{}, &dns.Msg{} - for i := 0; i < 5000; i++ { - target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) - srv := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: target, - } - a := &dns.A{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), - } - ns := &dns.SOA{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeSOA, - Class: dns.ClassINET, - }, - Ns: fmt.Sprintf("soa-%d", i), - } + req, resp, expected := &dns.Msg{}, &dns.Msg{}, &dns.Msg{} + for i := 0; i < 5000; i++ { + target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: target, + } + a := &dns.A{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), + } + ns := &dns.SOA{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeSOA, + Class: dns.ClassINET, + }, + Ns: fmt.Sprintf("soa-%d", i), + } - resp.Answer = append(resp.Answer, srv) - resp.Extra = append(resp.Extra, a) - resp.Ns = append(resp.Ns, ns) - if i < cfg.DNSUDPAnswerLimit { - expected.Answer = append(expected.Answer, srv) - expected.Extra = append(expected.Extra, a) - } - } - req.Question = append(req.Question, dns.Question{Qtype: dns.TypeSRV}) - - if trimmed := trimTCPResponse(req, resp); !trimmed { - t.Fatalf("Bad %#v", *resp) - } - require.LessOrEqual(t, resp.Len(), 65523) - require.Len(t, resp.Ns, 0) - }) + resp.Answer = append(resp.Answer, srv) + resp.Extra = append(resp.Extra, a) + resp.Ns = append(resp.Ns, ns) + if i < cfg.DNSUDPAnswerLimit { + expected.Answer = append(expected.Answer, srv) + expected.Extra = append(expected.Extra, a) + } } + req.Question = append(req.Question, dns.Question{Qtype: dns.TypeSRV}) + + if trimmed := trimTCPResponse(req, resp); !trimmed { + t.Fatalf("Bad %#v", *resp) + } + require.LessOrEqual(t, resp.Len(), 65523) + require.Len(t, resp.Ns, 0) } func loadRuntimeConfig(t *testing.T, hcl string) *config.RuntimeConfig { @@ -2720,193 +2542,179 @@ func loadRuntimeConfig(t *testing.T, hcl string) *config.RuntimeConfig { } func TestDNS_trimUDPResponse_TrimSize(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - req, resp := &dns.Msg{}, &dns.Msg{} - for i := 0; i < 100; i++ { - target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) - srv := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: target, - } - a := &dns.A{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), - } + req, resp := &dns.Msg{}, &dns.Msg{} + for i := 0; i < 100; i++ { + target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 185+i) + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: target, + } + a := &dns.A{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 185+i)), + } - resp.Answer = append(resp.Answer, srv) - resp.Extra = append(resp.Extra, a) - } + resp.Answer = append(resp.Answer, srv) + resp.Extra = append(resp.Extra, a) + } - // We don't know the exact trim, but we know the resulting answer - // data should match its extra data. - if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { - t.Fatalf("Bad %#v", *resp) - } - if len(resp.Answer) == 0 || len(resp.Answer) != len(resp.Extra) { - t.Fatalf("Bad %#v", *resp) - } - for i := range resp.Answer { - srv, ok := resp.Answer[i].(*dns.SRV) - if !ok { - t.Fatalf("should be SRV") - } + // We don't know the exact trim, but we know the resulting answer + // data should match its extra data. + if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { + t.Fatalf("Bad %#v", *resp) + } + if len(resp.Answer) == 0 || len(resp.Answer) != len(resp.Extra) { + t.Fatalf("Bad %#v", *resp) + } + for i := range resp.Answer { + srv, ok := resp.Answer[i].(*dns.SRV) + if !ok { + t.Fatalf("should be SRV") + } - a, ok := resp.Extra[i].(*dns.A) - if !ok { - t.Fatalf("should be A") - } + a, ok := resp.Extra[i].(*dns.A) + if !ok { + t.Fatalf("should be A") + } - if srv.Target != a.Header().Name { - t.Fatalf("Bad %#v vs. %#v", *srv, *a) - } - } - }) + if srv.Target != a.Header().Name { + t.Fatalf("Bad %#v vs. %#v", *srv, *a) + } } } func TestDNS_trimUDPResponse_TrimSizeEDNS(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + req, resp := &dns.Msg{}, &dns.Msg{} - req, resp := &dns.Msg{}, &dns.Msg{} + for i := 0; i < 100; i++ { + target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 150+i) + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: target, + } + a := &dns.A{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 150+i)), + } - for i := 0; i < 100; i++ { - target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 150+i) - srv := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: target, - } - a := &dns.A{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 150+i)), - } + resp.Answer = append(resp.Answer, srv) + resp.Extra = append(resp.Extra, a) + } - resp.Answer = append(resp.Answer, srv) - resp.Extra = append(resp.Extra, a) - } + // Copy over to a new slice since we are trimming both. + reqEDNS, respEDNS := &dns.Msg{}, &dns.Msg{} + reqEDNS.SetEdns0(2048, true) + respEDNS.Answer = append(respEDNS.Answer, resp.Answer...) + respEDNS.Extra = append(respEDNS.Extra, resp.Extra...) - // Copy over to a new slice since we are trimming both. - reqEDNS, respEDNS := &dns.Msg{}, &dns.Msg{} - reqEDNS.SetEdns0(2048, true) - respEDNS.Answer = append(respEDNS.Answer, resp.Answer...) - respEDNS.Extra = append(respEDNS.Extra, resp.Extra...) + // Trim each response + if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { + t.Errorf("expected response to be trimmed: %#v", resp) + } + if trimmed := trimUDPResponse(reqEDNS, respEDNS, cfg.DNSUDPAnswerLimit); !trimmed { + t.Errorf("expected edns to be trimmed: %#v", resp) + } - // Trim each response - if trimmed := trimUDPResponse(req, resp, cfg.DNSUDPAnswerLimit); !trimmed { - t.Errorf("expected response to be trimmed: %#v", resp) - } - if trimmed := trimUDPResponse(reqEDNS, respEDNS, cfg.DNSUDPAnswerLimit); !trimmed { - t.Errorf("expected edns to be trimmed: %#v", resp) - } + // Check answer lengths + if len(resp.Answer) == 0 || len(resp.Answer) != len(resp.Extra) { + t.Errorf("bad response answer length: %#v", resp) + } + if len(respEDNS.Answer) == 0 || len(respEDNS.Answer) != len(respEDNS.Extra) { + t.Errorf("bad edns answer length: %#v", resp) + } - // Check answer lengths - if len(resp.Answer) == 0 || len(resp.Answer) != len(resp.Extra) { - t.Errorf("bad response answer length: %#v", resp) - } - if len(respEDNS.Answer) == 0 || len(respEDNS.Answer) != len(respEDNS.Extra) { - t.Errorf("bad edns answer length: %#v", resp) - } + // Due to the compression, we can't check exact equality of sizes, but we can + // make two requests and ensure that the edns one returns a larger payload + // than the non-edns0 one. + if len(resp.Answer) >= len(respEDNS.Answer) { + t.Errorf("expected edns have larger answer: %#v\n%#v", resp, respEDNS) + } + if len(resp.Extra) >= len(respEDNS.Extra) { + t.Errorf("expected edns have larger extra: %#v\n%#v", resp, respEDNS) + } - // Due to the compression, we can't check exact equality of sizes, but we can - // make two requests and ensure that the edns one returns a larger payload - // than the non-edns0 one. - if len(resp.Answer) >= len(respEDNS.Answer) { - t.Errorf("expected edns have larger answer: %#v\n%#v", resp, respEDNS) - } - if len(resp.Extra) >= len(respEDNS.Extra) { - t.Errorf("expected edns have larger extra: %#v\n%#v", resp, respEDNS) - } + // Verify that the things point where they should + for i := range resp.Answer { + srv, ok := resp.Answer[i].(*dns.SRV) + if !ok { + t.Errorf("%d should be an SRV", i) + } - // Verify that the things point where they should - for i := range resp.Answer { - srv, ok := resp.Answer[i].(*dns.SRV) - if !ok { - t.Errorf("%d should be an SRV", i) - } + a, ok := resp.Extra[i].(*dns.A) + if !ok { + t.Errorf("%d should be an A", i) + } - a, ok := resp.Extra[i].(*dns.A) - if !ok { - t.Errorf("%d should be an A", i) - } - - if srv.Target != a.Header().Name { - t.Errorf("%d: bad %#v vs. %#v", i, srv, a) - } - } - }) + if srv.Target != a.Header().Name { + t.Errorf("%d: bad %#v vs. %#v", i, srv, a) + } } } func TestDNS_trimUDPResponse_TrimSizeMaxSize(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { + cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - cfg := loadRuntimeConfig(t, `node_name = "test" data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + resp := &dns.Msg{} - resp := &dns.Msg{} + for i := 0; i < 600; i++ { + target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 150+i) + srv := &dns.SRV{ + Hdr: dns.RR_Header{ + Name: "redis-cache-redis.service.consul.", + Rrtype: dns.TypeSRV, + Class: dns.ClassINET, + }, + Target: target, + } + a := &dns.A{ + Hdr: dns.RR_Header{ + Name: target, + Rrtype: dns.TypeA, + Class: dns.ClassINET, + }, + A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 150+i)), + } - for i := 0; i < 600; i++ { - target := fmt.Sprintf("ip-10-0-1-%d.node.dc1.consul.", 150+i) - srv := &dns.SRV{ - Hdr: dns.RR_Header{ - Name: "redis-cache-redis.service.consul.", - Rrtype: dns.TypeSRV, - Class: dns.ClassINET, - }, - Target: target, - } - a := &dns.A{ - Hdr: dns.RR_Header{ - Name: target, - Rrtype: dns.TypeA, - Class: dns.ClassINET, - }, - A: net.ParseIP(fmt.Sprintf("10.0.1.%d", 150+i)), - } + resp.Answer = append(resp.Answer, srv) + resp.Extra = append(resp.Extra, a) + } - resp.Answer = append(resp.Answer, srv) - resp.Extra = append(resp.Extra, a) - } + reqEDNS, respEDNS := &dns.Msg{}, &dns.Msg{} + reqEDNS.SetEdns0(math.MaxUint16, true) + respEDNS.Answer = append(respEDNS.Answer, resp.Answer...) + respEDNS.Extra = append(respEDNS.Extra, resp.Extra...) + require.Greater(t, respEDNS.Len(), math.MaxUint16) + t.Logf("length is: %v", respEDNS.Len()) - reqEDNS, respEDNS := &dns.Msg{}, &dns.Msg{} - reqEDNS.SetEdns0(math.MaxUint16, true) - respEDNS.Answer = append(respEDNS.Answer, resp.Answer...) - respEDNS.Extra = append(respEDNS.Extra, resp.Extra...) - require.Greater(t, respEDNS.Len(), math.MaxUint16) - t.Logf("length is: %v", respEDNS.Len()) + if trimmed := trimUDPResponse(reqEDNS, respEDNS, cfg.DNSUDPAnswerLimit); !trimmed { + t.Errorf("expected edns to be trimmed: %#v", resp) + } + require.Greater(t, math.MaxUint16, respEDNS.Len()) - if trimmed := trimUDPResponse(reqEDNS, respEDNS, cfg.DNSUDPAnswerLimit); !trimmed { - t.Errorf("expected edns to be trimmed: %#v", resp) - } - require.Greater(t, math.MaxUint16, respEDNS.Len()) + t.Logf("length is: %v", respEDNS.Len()) - t.Logf("length is: %v", respEDNS.Len()) - - if len(respEDNS.Answer) == 0 || len(respEDNS.Answer) != len(respEDNS.Extra) { - t.Errorf("bad edns answer length: %#v", resp) - } - }) + if len(respEDNS.Answer) == 0 || len(respEDNS.Answer) != len(respEDNS.Extra) { + t.Errorf("bad edns answer length: %#v", resp) } } @@ -3134,25 +2942,20 @@ func TestDNS_syncExtra(t *testing.T) { } func TestDNS_Compression_trimUDPResponse(t *testing.T) { - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { + cfg := loadRuntimeConfig(t, `data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `) - cfg := loadRuntimeConfig(t, `data_dir = "a" bind_addr = "127.0.0.1" node_name = "dummy" `+experimentsHCL) + req, m := dns.Msg{}, dns.Msg{} + trimUDPResponse(&req, &m, cfg.DNSUDPAnswerLimit) + if m.Compress { + t.Fatalf("compression should be off") + } - req, m := dns.Msg{}, dns.Msg{} - trimUDPResponse(&req, &m, cfg.DNSUDPAnswerLimit) - if m.Compress { - t.Fatalf("compression should be off") - } - - // The trim function temporarily turns off compression, so we need to - // make sure the setting gets restored properly. - m.Compress = true - trimUDPResponse(&req, &m, cfg.DNSUDPAnswerLimit) - if !m.Compress { - t.Fatalf("compression should be on") - } - }) + // The trim function temporarily turns off compression, so we need to + // make sure the setting gets restored properly. + m.Compress = true + trimUDPResponse(&req, &m, cfg.DNSUDPAnswerLimit) + if !m.Compress { + t.Fatalf("compression should be on") } } @@ -3161,93 +2964,88 @@ func TestDNS_Compression_Query(t *testing.T) { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + // Register a node with a service. + { + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: "foo", + Address: "127.0.0.1", + Service: &structs.NodeService{ + Service: "db", + Tags: []string{"primary"}, + Port: 12345, + }, + } - // Register a node with a service. - { - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: "foo", - Address: "127.0.0.1", - Service: &structs.NodeService{ - Service: "db", - Tags: []string{"primary"}, - Port: 12345, - }, - } + var out struct{} + if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { + t.Fatalf("err: %v", err) + } + } - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - t.Fatalf("err: %v", err) - } - } + // Register an equivalent prepared query. + var id string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: "test", + Service: structs.ServiceQuery{ + Service: "db", + }, + }, + } + if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { + t.Fatalf("err: %v", err) + } + } - // Register an equivalent prepared query. - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "test", - Service: structs.ServiceQuery{ - Service: "db", - }, - }, - } - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - t.Fatalf("err: %v", err) - } - } + // Look up the service directly and via prepared query. + questions := []string{ + "db.service.consul.", + id + ".query.consul.", + } + for _, question := range questions { + m := new(dns.Msg) + m.SetQuestion(question, dns.TypeSRV) - // Look up the service directly and via prepared query. - questions := []string{ - "db.service.consul.", - id + ".query.consul.", - } - for _, question := range questions { - m := new(dns.Msg) - m.SetQuestion(question, dns.TypeSRV) + conn, err := dns.Dial("udp", a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - conn, err := dns.Dial("udp", a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + // Do a manual exchange with compression on (the default). + a.DNSDisableCompression(false) + if err := conn.WriteMsg(m); err != nil { + t.Fatalf("err: %v", err) + } + p := make([]byte, dns.MaxMsgSize) + compressed, err := conn.Read(p) + if err != nil { + t.Fatalf("err: %v", err) + } - // Do a manual exchange with compression on (the default). - a.DNSDisableCompression(false) - if err := conn.WriteMsg(m); err != nil { - t.Fatalf("err: %v", err) - } - p := make([]byte, dns.MaxMsgSize) - compressed, err := conn.Read(p) - if err != nil { - t.Fatalf("err: %v", err) - } + // Disable compression and try again. + a.DNSDisableCompression(true) + if err := conn.WriteMsg(m); err != nil { + t.Fatalf("err: %v", err) + } + unc, err := conn.Read(p) + if err != nil { + t.Fatalf("err: %v", err) + } - // Disable compression and try again. - a.DNSDisableCompression(true) - if err := conn.WriteMsg(m); err != nil { - t.Fatalf("err: %v", err) - } - unc, err := conn.Read(p) - if err != nil { - t.Fatalf("err: %v", err) - } - - // We can't see the compressed status given the DNS API, so we - // just make sure the message is smaller to see if it's - // respecting the flag. - if compressed == 0 || unc == 0 || compressed >= unc { - t.Fatalf("'%s' doesn't look compressed: %d vs. %d", question, compressed, unc) - } - } - }) + // We can't see the compressed status given the DNS API, so we + // just make sure the message is smaller to see if it's + // respecting the flag. + if compressed == 0 || unc == 0 || compressed >= unc { + t.Fatalf("'%s' doesn't look compressed: %d vs. %d", question, compressed, unc) + } } } @@ -3261,49 +3059,44 @@ func TestDNS_Compression_Recurse(t *testing.T) { }) defer recursor.Shutdown() - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - - a := NewTestAgent(t, ` + a := NewTestAgent(t, ` recursors = ["`+recursor.Addr+`"] - `+experimentsHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") + `) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - m := new(dns.Msg) - m.SetQuestion("apple.com.", dns.TypeANY) + m := new(dns.Msg) + m.SetQuestion("apple.com.", dns.TypeANY) - conn, err := dns.Dial("udp", a.DNSAddr()) - if err != nil { - t.Fatalf("err: %v", err) - } + conn, err := dns.Dial("udp", a.DNSAddr()) + if err != nil { + t.Fatalf("err: %v", err) + } - // Do a manual exchange with compression on (the default). - if err := conn.WriteMsg(m); err != nil { - t.Fatalf("err: %v", err) - } - p := make([]byte, dns.MaxMsgSize) - compressed, err := conn.Read(p) - if err != nil { - t.Fatalf("err: %v", err) - } + // Do a manual exchange with compression on (the default). + if err := conn.WriteMsg(m); err != nil { + t.Fatalf("err: %v", err) + } + p := make([]byte, dns.MaxMsgSize) + compressed, err := conn.Read(p) + if err != nil { + t.Fatalf("err: %v", err) + } - // Disable compression and try again. - a.DNSDisableCompression(true) - if err := conn.WriteMsg(m); err != nil { - t.Fatalf("err: %v", err) - } - unc, err := conn.Read(p) - if err != nil { - t.Fatalf("err: %v", err) - } + // Disable compression and try again. + a.DNSDisableCompression(true) + if err := conn.WriteMsg(m); err != nil { + t.Fatalf("err: %v", err) + } + unc, err := conn.Read(p) + if err != nil { + t.Fatalf("err: %v", err) + } - // We can't see the compressed status given the DNS API, so we just make - // sure the message is smaller to see if it's respecting the flag. - if compressed == 0 || unc == 0 || compressed >= unc { - t.Fatalf("doesn't look compressed: %d vs. %d", compressed, unc) - } - }) + // We can't see the compressed status given the DNS API, so we just make + // sure the message is smaller to see if it's respecting the flag. + if compressed == 0 || unc == 0 || compressed >= unc { + t.Fatalf("doesn't look compressed: %d vs. %d", compressed, unc) } } @@ -3338,7 +3131,6 @@ func TestDNS_V1ConfigReload(t *testing.T) { min_ttl = 4 } } - experiments = ["v1dns"] `) defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") @@ -3347,7 +3139,7 @@ func TestDNS_V1ConfigReload(t *testing.T) { server, ok := s.(*DNSServer) require.True(t, ok) - cfg := server.config.Load().(*dnsConfig) + cfg := server.config.Load().(*dnsServerConfig) require.Equal(t, []string{"8.8.8.8:53"}, cfg.Recursors) require.Equal(t, structs.RecursorStrategy("sequential"), cfg.RecursorStrategy) require.False(t, cfg.AllowStale) @@ -3397,7 +3189,7 @@ func TestDNS_V1ConfigReload(t *testing.T) { server, ok := s.(*DNSServer) require.True(t, ok) - cfg := server.config.Load().(*dnsConfig) + cfg := server.config.Load().(*dnsServerConfig) require.Equal(t, []string{"1.1.1.1:53"}, cfg.Recursors) require.Equal(t, structs.RecursorStrategy("random"), cfg.RecursorStrategy) require.True(t, cfg.AllowStale) @@ -3424,319 +3216,70 @@ func TestDNS_V1ConfigReload(t *testing.T) { } } -// TestDNS_V2ConfigReload_WithV1DataFetcher validates that the dns configuration is saved to the -// DNS server when v2 DNS is configured with V1 catalog and reload config internal is called. -func TestDNS_V2ConfigReload_WithV1DataFetcher(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - a := NewTestAgent(t, ` - experiments=["v2dns"] - recursors = ["8.8.8.8:53"] - dns_config = { - allow_stale = false - max_stale = "20s" - node_ttl = "10s" - service_ttl = { - "my_services*" = "5s" - "my_specific_service" = "30s" - } - enable_truncate = false - only_passing = false - recursor_strategy = "sequential" - recursor_timeout = "15s" - disable_compression = false - a_record_limit = 1 - enable_additional_node_meta_txt = false - soa = { - refresh = 1 - retry = 2 - expire = 3 - min_ttl = 4 - } - } - `) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") - - for _, s := range a.dnsServers { - server, ok := s.(*dnsConsul.Server) - require.True(t, ok) - - cfg := server.Router.GetConfig() - require.Equal(t, []string{"8.8.8.8:53"}, cfg.Recursors) - require.Equal(t, structs.RecursorStrategy("sequential"), cfg.RecursorStrategy) - df := a.catalogDataFetcher.(*discovery.V1DataFetcher) - dfCfg := df.GetConfig() - - require.False(t, dfCfg.AllowStale) - require.Equal(t, 20*time.Second, dfCfg.MaxStale) - require.Equal(t, 10*time.Second, cfg.NodeTTL) - ttl, _ := cfg.GetTTLForService("my_services_1") - require.Equal(t, 5*time.Second, ttl) - ttl, _ = cfg.GetTTLForService("my_specific_service") - require.Equal(t, 30*time.Second, ttl) - require.False(t, cfg.EnableTruncate) - require.False(t, dfCfg.OnlyPassing) - require.Equal(t, 15*time.Second, cfg.RecursorTimeout) - require.False(t, cfg.DisableCompression) - require.Equal(t, 1, cfg.ARecordLimit) - require.False(t, cfg.NodeMetaTXT) - require.Equal(t, uint32(1), cfg.SOAConfig.Refresh) - require.Equal(t, uint32(2), cfg.SOAConfig.Retry) - require.Equal(t, uint32(3), cfg.SOAConfig.Expire) - require.Equal(t, uint32(4), cfg.SOAConfig.Minttl) - } - - newCfg := *a.Config - newCfg.DNSRecursors = []string{"1.1.1.1:53"} - newCfg.DNSAllowStale = true - newCfg.DNSMaxStale = 21 * time.Second - newCfg.DNSNodeTTL = 11 * time.Second - newCfg.DNSServiceTTL = map[string]time.Duration{ - "2_my_services*": 6 * time.Second, - "2_my_specific_service": 31 * time.Second, - } - newCfg.DNSEnableTruncate = true - newCfg.DNSOnlyPassing = true - newCfg.DNSRecursorStrategy = "random" - newCfg.DNSRecursorTimeout = 16 * time.Second - newCfg.DNSDisableCompression = true - newCfg.DNSARecordLimit = 2 - newCfg.DNSNodeMetaTXT = true - newCfg.DNSSOA.Refresh = 10 - newCfg.DNSSOA.Retry = 20 - newCfg.DNSSOA.Expire = 30 - newCfg.DNSSOA.Minttl = 40 - - err := a.reloadConfigInternal(&newCfg) - require.NoError(t, err) - - for _, s := range a.dnsServers { - server, ok := s.(*dnsConsul.Server) - require.True(t, ok) - - cfg := server.Router.GetConfig() - require.Equal(t, []string{"1.1.1.1:53"}, cfg.Recursors) - require.Equal(t, structs.RecursorStrategy("random"), cfg.RecursorStrategy) - df := a.catalogDataFetcher.(*discovery.V1DataFetcher) - dfCfg := df.GetConfig() - require.True(t, dfCfg.AllowStale) - require.Equal(t, 21*time.Second, dfCfg.MaxStale) - require.Equal(t, 11*time.Second, cfg.NodeTTL) - ttl, _ := cfg.GetTTLForService("my_services_1") - require.Equal(t, time.Duration(0), ttl) - ttl, _ = cfg.GetTTLForService("2_my_services_1") - require.Equal(t, 6*time.Second, ttl) - ttl, _ = cfg.GetTTLForService("my_specific_service") - require.Equal(t, time.Duration(0), ttl) - ttl, _ = cfg.GetTTLForService("2_my_specific_service") - require.Equal(t, 31*time.Second, ttl) - require.True(t, cfg.EnableTruncate) - require.True(t, dfCfg.OnlyPassing) - require.Equal(t, 16*time.Second, cfg.RecursorTimeout) - require.True(t, cfg.DisableCompression) - require.Equal(t, 2, cfg.ARecordLimit) - require.True(t, cfg.NodeMetaTXT) - require.Equal(t, uint32(10), cfg.SOAConfig.Refresh) - require.Equal(t, uint32(20), cfg.SOAConfig.Retry) - require.Equal(t, uint32(30), cfg.SOAConfig.Expire) - require.Equal(t, uint32(40), cfg.SOAConfig.Minttl) - } -} - -// TestDNS_V2ConfigReload_WithV2DataFetcher validates that the dns configuration is saved to the -// DNS server when v2 DNS is configured with V1 catalog and reload config internal is called. -func TestDNS_V2ConfigReload_WithV2DataFetcher(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - a := NewTestAgent(t, ` - experiments=["v2dns", "resource-apis"] - recursors = ["8.8.8.8:53"] - dns_config = { - allow_stale = false - max_stale = "20s" - node_ttl = "10s" - service_ttl = { - "my_services*" = "5s" - "my_specific_service" = "30s" - } - enable_truncate = false - only_passing = false - recursor_strategy = "sequential" - recursor_timeout = "15s" - disable_compression = false - a_record_limit = 1 - enable_additional_node_meta_txt = false - soa = { - refresh = 1 - retry = 2 - expire = 3 - min_ttl = 4 - } - } - `) - defer a.Shutdown() - // use WaitForRaftLeader with v2 resource apis - testrpc.WaitForRaftLeader(t, a.RPC, "dc1") - - for _, s := range a.dnsServers { - server, ok := s.(*dnsConsul.Server) - require.True(t, ok) - - cfg := server.Router.GetConfig() - require.Equal(t, []string{"8.8.8.8:53"}, cfg.Recursors) - require.Equal(t, structs.RecursorStrategy("sequential"), cfg.RecursorStrategy) - df := a.catalogDataFetcher.(*discovery.V2DataFetcher) - dfCfg := df.GetConfig() - - //require.False(t, dfCfg.AllowStale) - //require.Equal(t, 20*time.Second, dfCfg.MaxStale) - require.Equal(t, 10*time.Second, cfg.NodeTTL) - ttl, _ := cfg.GetTTLForService("my_services_1") - require.Equal(t, 5*time.Second, ttl) - ttl, _ = cfg.GetTTLForService("my_specific_service") - require.Equal(t, 30*time.Second, ttl) - require.False(t, cfg.EnableTruncate) - require.False(t, dfCfg.OnlyPassing) - require.Equal(t, 15*time.Second, cfg.RecursorTimeout) - require.False(t, cfg.DisableCompression) - require.Equal(t, 1, cfg.ARecordLimit) - require.False(t, cfg.NodeMetaTXT) - require.Equal(t, uint32(1), cfg.SOAConfig.Refresh) - require.Equal(t, uint32(2), cfg.SOAConfig.Retry) - require.Equal(t, uint32(3), cfg.SOAConfig.Expire) - require.Equal(t, uint32(4), cfg.SOAConfig.Minttl) - } - - newCfg := *a.Config - newCfg.DNSRecursors = []string{"1.1.1.1:53"} - newCfg.DNSAllowStale = true - newCfg.DNSMaxStale = 21 * time.Second - newCfg.DNSNodeTTL = 11 * time.Second - newCfg.DNSServiceTTL = map[string]time.Duration{ - "2_my_services*": 6 * time.Second, - "2_my_specific_service": 31 * time.Second, - } - newCfg.DNSEnableTruncate = true - newCfg.DNSOnlyPassing = true - newCfg.DNSRecursorStrategy = "random" - newCfg.DNSRecursorTimeout = 16 * time.Second - newCfg.DNSDisableCompression = true - newCfg.DNSARecordLimit = 2 - newCfg.DNSNodeMetaTXT = true - newCfg.DNSSOA.Refresh = 10 - newCfg.DNSSOA.Retry = 20 - newCfg.DNSSOA.Expire = 30 - newCfg.DNSSOA.Minttl = 40 - - err := a.reloadConfigInternal(&newCfg) - require.NoError(t, err) - - for _, s := range a.dnsServers { - server, ok := s.(*dnsConsul.Server) - require.True(t, ok) - - cfg := server.Router.GetConfig() - require.Equal(t, []string{"1.1.1.1:53"}, cfg.Recursors) - require.Equal(t, structs.RecursorStrategy("random"), cfg.RecursorStrategy) - df := a.catalogDataFetcher.(*discovery.V2DataFetcher) - dfCfg := df.GetConfig() - //require.True(t, dfCfg.AllowStale) - //require.Equal(t, 21*time.Second, dfCfg.MaxStale) - require.Equal(t, 11*time.Second, cfg.NodeTTL) - ttl, _ := cfg.GetTTLForService("my_services_1") - require.Equal(t, time.Duration(0), ttl) - ttl, _ = cfg.GetTTLForService("2_my_services_1") - require.Equal(t, 6*time.Second, ttl) - ttl, _ = cfg.GetTTLForService("my_specific_service") - require.Equal(t, time.Duration(0), ttl) - ttl, _ = cfg.GetTTLForService("2_my_specific_service") - require.Equal(t, 31*time.Second, ttl) - require.True(t, cfg.EnableTruncate) - require.True(t, dfCfg.OnlyPassing) - require.Equal(t, 16*time.Second, cfg.RecursorTimeout) - require.True(t, cfg.DisableCompression) - require.Equal(t, 2, cfg.ARecordLimit) - require.True(t, cfg.NodeMetaTXT) - require.Equal(t, uint32(10), cfg.SOAConfig.Refresh) - require.Equal(t, uint32(20), cfg.SOAConfig.Retry) - require.Equal(t, uint32(30), cfg.SOAConfig.Expire) - require.Equal(t, uint32(40), cfg.SOAConfig.Minttl) - } -} - func TestDNS_ReloadConfig_DuringQuery(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") } - for name, experimentsHCL := range getVersionHCL(true) { - t.Run(name, func(t *testing.T) { - a := NewTestAgent(t, experimentsHCL) - defer a.Shutdown() - testrpc.WaitForLeader(t, a.RPC, "dc1") + a := NewTestAgent(t, "") + defer a.Shutdown() + testrpc.WaitForLeader(t, a.RPC, "dc1") - m := MockPreparedQuery{ - executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { - time.Sleep(100 * time.Millisecond) - reply.Nodes = structs.CheckServiceNodes{ - { - Node: &structs.Node{ - ID: "my_node", - Address: "127.0.0.1", - }, - Service: &structs.NodeService{ - Address: "127.0.0.1", - Port: 8080, - }, - }, - } - return nil + m := MockPreparedQuery{ + executeFn: func(args *structs.PreparedQueryExecuteRequest, reply *structs.PreparedQueryExecuteResponse) error { + time.Sleep(100 * time.Millisecond) + reply.Nodes = structs.CheckServiceNodes{ + { + Node: &structs.Node{ + ID: "my_node", + Address: "127.0.0.1", + }, + Service: &structs.NodeService{ + Address: "127.0.0.1", + Port: 8080, + }, }, } + return nil + }, + } - err := a.registerEndpoint("PreparedQuery", &m) - require.NoError(t, err) + err := a.registerEndpoint("PreparedQuery", &m) + require.NoError(t, err) - { - m := new(dns.Msg) - m.SetQuestion("nope.query.consul.", dns.TypeA) + { + m := new(dns.Msg) + m.SetQuestion("nope.query.consul.", dns.TypeA) - timeout := time.NewTimer(time.Second) - res := make(chan *dns.Msg) - errs := make(chan error) + timeout := time.NewTimer(time.Second) + res := make(chan *dns.Msg) + errs := make(chan error) - go func() { - c := new(dns.Client) - in, _, err := c.Exchange(m, a.DNSAddr()) - if err != nil { - errs <- err - return - } - res <- in - }() - - time.Sleep(50 * time.Millisecond) - - // reload the config halfway through, that should not affect the ongoing query - newCfg := *a.Config - newCfg.DNSAllowStale = true - a.reloadConfigInternal(&newCfg) - - select { - case in := <-res: - require.Equal(t, "127.0.0.1", in.Answer[0].(*dns.A).A.String()) - case err := <-errs: - require.NoError(t, err) - case <-timeout.C: - require.FailNow(t, "timeout") - } + go func() { + c := new(dns.Client) + in, _, err := c.Exchange(m, a.DNSAddr()) + if err != nil { + errs <- err + return } - }) + res <- in + }() + + time.Sleep(50 * time.Millisecond) + + // reload the config halfway through, that should not affect the ongoing query + newCfg := *a.Config + newCfg.DNSAllowStale = true + a.reloadConfigInternal(&newCfg) + + select { + case in := <-res: + require.Equal(t, "127.0.0.1", in.Answer[0].(*dns.A).A.String()) + case err := <-errs: + require.NoError(t, err) + case <-timeout.C: + require.FailNow(t, "timeout") + } } } @@ -3841,9 +3384,13 @@ func TestDNS_ParseLocality(t *testing.T) { d := &DNSServer{ defaultEnterpriseMeta: tc.defaultEntMeta, } - actualResult, actualOK := d.parseLocality(tc.labels, &dnsConfig{ - enterpriseDNSConfig: tc.enterpriseDNSConfig, - }) + actualResult, actualOK := d.parseLocality(tc.labels, + &dnsRequestConfig{ + dnsServerConfig: &dnsServerConfig{ + enterpriseDNSConfig: tc.enterpriseDNSConfig, + }, + defaultEnterpriseMeta: tc.defaultEntMeta, + }) require.Equal(t, tc.expectedOK, actualOK) require.Equal(t, tc.expectedResult, actualResult) diff --git a/agent/grpc-external/services/dns/server.go b/agent/grpc-external/services/dns/server.go index 3485bd2f13..120b1875ef 100644 --- a/agent/grpc-external/services/dns/server.go +++ b/agent/grpc-external/services/dns/server.go @@ -6,6 +6,7 @@ package dns import ( "context" "fmt" + agentdns "github.com/hashicorp/consul/agent/dns" "net" "github.com/hashicorp/go-hclog" @@ -41,61 +42,6 @@ func (s *Server) Register(registrar grpc.ServiceRegistrar) { pbdns.RegisterDNSServiceServer(registrar, s) } -// BufferResponseWriter writes a DNS response to a byte buffer. -type BufferResponseWriter struct { - responseBuffer []byte - LocalAddress net.Addr - RemoteAddress net.Addr - Logger hclog.Logger -} - -// LocalAddr returns the net.Addr of the server -func (b *BufferResponseWriter) LocalAddr() net.Addr { - return b.LocalAddress -} - -// RemoteAddr returns the net.Addr of the client that sent the current request. -func (b *BufferResponseWriter) RemoteAddr() net.Addr { - return b.RemoteAddress -} - -// WriteMsg writes a reply back to the client. -func (b *BufferResponseWriter) WriteMsg(m *dns.Msg) error { - // Pack message to bytes first. - msgBytes, err := m.Pack() - if err != nil { - b.Logger.Error("error packing message", "err", err) - return err - } - b.responseBuffer = msgBytes - return nil -} - -// Write writes a raw buffer back to the client. -func (b *BufferResponseWriter) Write(m []byte) (int, error) { - b.Logger.Debug("Write was called") - return copy(b.responseBuffer, m), nil -} - -// Close closes the connection. -func (b *BufferResponseWriter) Close() error { - // There's nothing for us to do here as we don't handle the connection. - return nil -} - -// TsigStatus returns the status of the Tsig. -func (b *BufferResponseWriter) TsigStatus() error { - // TSIG doesn't apply to this response writer. - return nil -} - -// TsigTimersOnly sets the tsig timers only boolean. -func (b *BufferResponseWriter) TsigTimersOnly(bool) {} - -// Hijack lets the caller take over the connection. -// After a call to Hijack(), the DNS package will not do anything with the connection. { -func (b *BufferResponseWriter) Hijack() {} - // Query is a gRPC endpoint that will serve dns requests. It will be consumed primarily by the // consul dataplane to proxy dns requests to consul. func (s *Server) Query(ctx context.Context, req *pbdns.QueryRequest) (*pbdns.QueryResponse, error) { @@ -121,21 +67,29 @@ func (s *Server) Query(ctx context.Context, req *pbdns.QueryRequest) (*pbdns.Que return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("error protocol type not set: %v", req.GetProtocol())) } - respWriter := &BufferResponseWriter{ - LocalAddress: local, - RemoteAddress: remote, - Logger: s.Logger, + reqCtx, err := agentdns.NewContextFromGRPCContext(ctx) + if err != nil { + s.Logger.Error("error parsing DNS context from grpc metadata", "err", err) + return nil, status.Error(codes.Internal, fmt.Sprintf("error parsing DNS context from grpc metadata: %s", err.Error())) + } + + respWriter := &agentdns.BufferResponseWriter{ + LocalAddress: local, + RemoteAddress: remote, + Logger: s.Logger, + RequestContext: reqCtx, } msg := &dns.Msg{} - err := msg.Unpack(req.Msg) + err = msg.Unpack(req.Msg) if err != nil { s.Logger.Error("error unpacking message", "err", err) return nil, status.Error(codes.Internal, fmt.Sprintf("failure decoding dns request: %s", err.Error())) } + s.DNSServeMux.ServeDNS(respWriter, msg) - queryResponse := &pbdns.QueryResponse{Msg: respWriter.responseBuffer} + queryResponse := &pbdns.QueryResponse{Msg: respWriter.ResponseBuffer()} return queryResponse, nil } diff --git a/agent/grpc-external/services/dns/server_v2.go b/agent/grpc-external/services/dns/server_v2.go deleted file mode 100644 index 848361535f..0000000000 --- a/agent/grpc-external/services/dns/server_v2.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "context" - "fmt" - "net" - - "github.com/miekg/dns" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/peer" - "google.golang.org/grpc/status" - - "github.com/hashicorp/go-hclog" - - agentdns "github.com/hashicorp/consul/agent/dns" - "github.com/hashicorp/consul/proto-public/pbdns" -) - -type ConfigV2 struct { - DNSRouter agentdns.DNSRouter - Logger hclog.Logger - TokenFunc func() string -} - -var _ pbdns.DNSServiceServer = (*ServerV2)(nil) - -// ServerV2 is a gRPC server that implements pbdns.DNSServiceServer. -// It is compatible with the refactored V2 DNS server and suitable for -// passing additional metadata along the grpc connection to catalog queries. -type ServerV2 struct { - ConfigV2 -} - -func NewServerV2(cfg ConfigV2) *ServerV2 { - return &ServerV2{cfg} -} - -func (s *ServerV2) Register(registrar grpc.ServiceRegistrar) { - pbdns.RegisterDNSServiceServer(registrar, s) -} - -// Query is a gRPC endpoint that will serve dns requests. It will be consumed primarily by the -// consul dataplane to proxy dns requests to consul. -func (s *ServerV2) Query(ctx context.Context, req *pbdns.QueryRequest) (*pbdns.QueryResponse, error) { - pr, ok := peer.FromContext(ctx) - if !ok { - return nil, fmt.Errorf("error retrieving peer information from context") - } - - var remote net.Addr - // We do this so that we switch to udp/tcp when handling the request since it will be proxied - // through consul through gRPC, and we need to 'fake' the protocol so that the message is trimmed - // according to whether it is UDP or TCP. - switch req.GetProtocol() { - case pbdns.Protocol_PROTOCOL_TCP: - remote = pr.Addr - case pbdns.Protocol_PROTOCOL_UDP: - remoteAddr := pr.Addr.(*net.TCPAddr) - remote = &net.UDPAddr{IP: remoteAddr.IP, Port: remoteAddr.Port} - default: - return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("error protocol type not set: %v", req.GetProtocol())) - } - - msg := &dns.Msg{} - err := msg.Unpack(req.Msg) - if err != nil { - s.Logger.Error("error unpacking message", "err", err) - return nil, status.Error(codes.Internal, fmt.Sprintf("failure decoding dns request: %s", err.Error())) - } - - reqCtx, err := agentdns.NewContextFromGRPCContext(ctx) - if err != nil { - s.Logger.Error("error parsing DNS context from grpc metadata", "err", err) - return nil, status.Error(codes.Internal, fmt.Sprintf("error parsing DNS context from grpc metadata: %s", err.Error())) - } - - resp := s.DNSRouter.HandleRequest(msg, reqCtx, remote) - data, err := resp.Pack() - if err != nil { - s.Logger.Error("error packing message", "err", err) - return nil, status.Error(codes.Internal, fmt.Sprintf("failure encoding dns request: %s", err.Error())) - } - - queryResponse := &pbdns.QueryResponse{Msg: data} - return queryResponse, nil -} diff --git a/agent/grpc-external/services/dns/server_v2_test.go b/agent/grpc-external/services/dns/server_v2_test.go deleted file mode 100644 index 06c7d4f96a..0000000000 --- a/agent/grpc-external/services/dns/server_v2_test.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package dns - -import ( - "context" - "errors" - - "github.com/hashicorp/go-hclog" - "github.com/miekg/dns" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "google.golang.org/grpc/metadata" - - agentdns "github.com/hashicorp/consul/agent/dns" - "github.com/hashicorp/consul/proto-public/pbdns" -) - -func basicResponse() *dns.Msg { - return &dns.Msg{ - MsgHdr: dns.MsgHdr{ - Opcode: dns.OpcodeQuery, - Response: true, - Authoritative: true, - }, - Compress: true, - Question: []dns.Question{ - { - Name: "abc.com.", - Qtype: dns.TypeANY, - Qclass: dns.ClassINET, - }, - }, - Extra: []dns.RR{ - &dns.TXT{ - Hdr: dns.RR_Header{ - Name: "abc.com.", - Rrtype: dns.TypeTXT, - Class: dns.ClassINET, - Ttl: 0, - }, - Txt: txtRR, - }, - }, - } -} - -func (s *DNSTestSuite) TestProxy_V2Success() { - - testCases := map[string]struct { - question string - configureRouter func(router *agentdns.MockDNSRouter) - clientQuery func(qR *pbdns.QueryRequest) - metadata map[string]string - expectedErr error - }{ - - "happy path udp": { - question: "abc.com.", - configureRouter: func(router *agentdns.MockDNSRouter) { - router.On("HandleRequest", mock.Anything, mock.Anything, mock.Anything). - Return(basicResponse(), nil) - }, - clientQuery: func(qR *pbdns.QueryRequest) { - qR.Protocol = pbdns.Protocol_PROTOCOL_UDP - }, - }, - "happy path tcp": { - question: "abc.com.", - configureRouter: func(router *agentdns.MockDNSRouter) { - router.On("HandleRequest", mock.Anything, mock.Anything, mock.Anything). - Return(basicResponse(), nil) - }, - clientQuery: func(qR *pbdns.QueryRequest) { - qR.Protocol = pbdns.Protocol_PROTOCOL_TCP - }, - }, - "happy path with context variables set": { - question: "abc.com.", - configureRouter: func(router *agentdns.MockDNSRouter) { - router.On("HandleRequest", mock.Anything, mock.Anything, mock.Anything). - Run(func(args mock.Arguments) { - ctx, ok := args.Get(1).(agentdns.Context) - require.True(s.T(), ok, "error casting to agentdns.Context") - require.Equal(s.T(), "test-token", ctx.Token, "token not set in context") - require.Equal(s.T(), "test-namespace", ctx.DefaultNamespace, "namespace not set in context") - require.Equal(s.T(), "test-partition", ctx.DefaultPartition, "partition not set in context") - }). - Return(basicResponse(), nil) - }, - clientQuery: func(qR *pbdns.QueryRequest) { - qR.Protocol = pbdns.Protocol_PROTOCOL_UDP - }, - metadata: map[string]string{ - "x-consul-token": "test-token", - "x-consul-namespace": "test-namespace", - "x-consul-partition": "test-partition", - }, - }, - "No protocol set": { - question: "abc.com.", - clientQuery: func(qR *pbdns.QueryRequest) {}, - expectedErr: errors.New("error protocol type not set: PROTOCOL_UNSET_UNSPECIFIED"), - }, - "Invalid question": { - question: "notvalid", - clientQuery: func(qR *pbdns.QueryRequest) { - qR.Protocol = pbdns.Protocol_PROTOCOL_UDP - }, - expectedErr: errors.New("failure decoding dns request"), - }, - } - - for name, tc := range testCases { - s.Run(name, func() { - router := agentdns.NewMockDNSRouter(s.T()) - - if tc.configureRouter != nil { - tc.configureRouter(router) - } - - server := NewServerV2(ConfigV2{ - Logger: hclog.Default(), - DNSRouter: router, - TokenFunc: func() string { return "" }, - }) - - client := testClient(s.T(), server) - - req := dns.Msg{} - req.SetQuestion(tc.question, dns.TypeA) - - bytes, _ := req.Pack() - - ctx := context.Background() - if len(tc.metadata) > 0 { - md := metadata.MD{} - for k, v := range tc.metadata { - md.Set(k, v) - } - ctx = metadata.NewOutgoingContext(ctx, md) - } - - clientReq := &pbdns.QueryRequest{Msg: bytes} - tc.clientQuery(clientReq) - clientResp, err := client.Query(ctx, clientReq) - if tc.expectedErr != nil { - s.Require().Error(err, "no errror calling gRPC endpoint") - s.Require().ErrorContains(err, tc.expectedErr.Error()) - } else { - s.Require().NoError(err, "error calling gRPC endpoint") - - resp := clientResp.GetMsg() - var dnsResp dns.Msg - - err = dnsResp.Unpack(resp) - s.Require().NoError(err, "error unpacking dns response") - rr := dnsResp.Extra[0].(*dns.TXT) - s.Require().EqualValues(rr.Txt, txtRR) - } - }) - } -} diff --git a/agent/setup.go b/agent/setup.go index e9103fb75a..ce64aa7eb2 100644 --- a/agent/setup.go +++ b/agent/setup.go @@ -28,7 +28,6 @@ import ( "github.com/hashicorp/consul/agent/consul/stream" "github.com/hashicorp/consul/agent/consul/usagemetrics" "github.com/hashicorp/consul/agent/consul/xdscapacity" - "github.com/hashicorp/consul/agent/discovery" "github.com/hashicorp/consul/agent/grpc-external/limiter" grpcInt "github.com/hashicorp/consul/agent/grpc-internal" "github.com/hashicorp/consul/agent/grpc-internal/balancer" @@ -437,7 +436,6 @@ func getPrometheusDefs(cfg *config.RuntimeConfig, isServer bool) ([]prometheus.G consul.CatalogCounters, consul.ClientCounters, consul.RPCCounters, - discovery.DNSCounters, grpcWare.StatsCounters, local.StateCounters, xds.StatsCounters, diff --git a/agent/structs/errors.go b/agent/structs/errors.go index b92731770c..9b62de648d 100644 --- a/agent/structs/errors.go +++ b/agent/structs/errors.go @@ -24,6 +24,7 @@ const ( errNotPrimaryDatacenter = "not the primary datacenter" errStateReadOnly = "CA Provider State is read-only" errUsingV2CatalogExperiment = "V1 catalog is disabled when V2 is enabled" + errSamenessGroupNotFound = "Sameness Group not found" errSamenessGroupMustBeDefaultForFailover = "Sameness Group must have DefaultForFailover set to true in order to use this endpoint" ) @@ -42,6 +43,7 @@ var ( ErrNotPrimaryDatacenter = errors.New(errNotPrimaryDatacenter) ErrStateReadOnly = errors.New(errStateReadOnly) ErrUsingV2CatalogExperiment = errors.New(errUsingV2CatalogExperiment) + ErrSamenessGroupNotFound = errors.New(errSamenessGroupNotFound) ErrSamenessGroupMustBeDefaultForFailover = errors.New(errSamenessGroupMustBeDefaultForFailover) ) @@ -65,6 +67,10 @@ func IsErrUsingV2CatalogExperiment(err error) bool { return err != nil && strings.Contains(err.Error(), errUsingV2CatalogExperiment) } +func IsErrSamenessGroupNotFound(err error) bool { + return err != nil && strings.Contains(err.Error(), errSamenessGroupNotFound) +} + func IsErrSamenessGroupMustBeDefaultForFailover(err error) bool { return err != nil && strings.Contains(err.Error(), errSamenessGroupMustBeDefaultForFailover) } diff --git a/website/content/docs/k8s/helm.mdx b/website/content/docs/k8s/helm.mdx index 624dce732b..42635dc2ca 100644 --- a/website/content/docs/k8s/helm.mdx +++ b/website/content/docs/k8s/helm.mdx @@ -766,14 +766,11 @@ Use these links to navigate to a particular top-level stanza. - `experiments` ((#v-global-experiments)) (`array: []`) - Consul feature flags that will be enabled across components. Supported feature flags: - - `v1dns`: - When this flag is set, Consul agents use the legacy DNS implementation. - This setting exists in the case a DNS bug is found after the refactoring introduced in v1.19.0. Example: ```yaml - experiments: [ "v1dns" ] + experiments: [ "" ] ``` ### server ((#h-server)) @@ -1787,7 +1784,7 @@ Use these links to navigate to a particular top-level stanza. or may not be broadly accessible depending on your Kubernetes cluster. Set this to false to skip syncing ClusterIP services. - - `syncLoadBalancerEndpoints` ((#v-synccatalog-syncloadbalancerendpoints)) (`boolean: false`) - If true, LoadBalancer service endpoints instead of ingress addresses will be synced to Consul. + - `syncLoadBalancerEndpoints` ((#v-synccatalog-syncloadbalancerendpoints)) (`boolean: false`) - If true, LoadBalancer service endpoints instead of ingress addresses will be synced to Consul. If false, LoadBalancer endpoints are not synced to Consul. - `ingress` ((#v-synccatalog-ingress)) diff --git a/website/content/docs/release-notes/consul/v1_19_x.mdx b/website/content/docs/release-notes/consul/v1_19_x.mdx index 5c8851112a..1c753d00f3 100644 --- a/website/content/docs/release-notes/consul/v1_19_x.mdx +++ b/website/content/docs/release-notes/consul/v1_19_x.mdx @@ -17,13 +17,13 @@ We are pleased to announce the following Consul updates. - **API Gateway metrics**: The Consul API Gateway now provides a Prometheus metrics endpoint you can use to gather information about the health of the gateway, as well as traffic for proxied connections or requests. -- **File system certificate configuration entry**: A new [`file-system-certificate` configuration entry](/consul/docs/connect/config-entries/file-system-certificate) supports specifying a filepath to the certificate and private key for Consul API Gateway on VMs on the local system. Previously, the certificate and private key were specified directly in the `inline-certificate` configuration entry. When using the file system certificates, the Consul server never sees the contents of these files. +- **File system certificate configuration entry**: A new [`file-system-certificate` configuration entry](/consul/docs/connect/config-entries/file-system-certificate) supports specifying a filepath to the certificate and private key for Consul API Gateway on VMs on the local system. Previously, the certificate and private key were specified directly in the `inline-certificate` configuration entry. When using the file system certificates, the Consul server never sees the contents of these files. File system certificates also include a file system watch that allows for changing the certificate and key without restarting the gateway. This feature requires that you have access to the gateway’s file system in order to place the certificate or update it. Consul on Kubernetes deployments that use `consul-k8s` Helm chart v1.5.0 or later use file system certificates without additional configuration. For more information, refer to [File system certificate configuration reference](/consul/docs/connect/config-entries/file-system-certificate). -- **Argo Rollouts Plugin**: A new Argo Rollouts plugin for progressive delivery is now available for `consul-k8s`. This plugin supports canary deployments by allowing you to incrementally release and test new versions of applications and roll back to previous versions by splitting traffic between subsets of services. Refer to [Argo Rollouts Progressive Delivery with Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/argo-rollouts-configuration) for more information. +- **Argo Rollouts Plugin**: A new Argo Rollouts plugin for progressive delivery is now available for `consul-k8s`. This plugin supports canary deployments by allowing you to incrementally release and test new versions of applications and roll back to previous versions by splitting traffic between subsets of services. Refer to [Argo Rollouts Progressive Delivery with Consul on Kubernetes](/consul/docs/k8s/deployment-configurations/argo-rollouts-configuration) for more information. ## What's deprecated @@ -37,14 +37,14 @@ For more detailed information, please refer to the [upgrade details page](/consu The following issues are known to exist in the v1.19.x releases: -- v1.19.0 - There are known issues with the new DNS server implementation. -To revert to the old DNS behavior, set `experiments: [ "v1dns" ]` in the agent configuration. -Fixes will be included in Consul v1.19.1. +- v1.19.0 & v1.19.1 - There are known issues with the DNS server implementation. +To revert to the old DNS behavior on 1.19.0 and 1.19.1, set `experiments: [ "v1dns" ]` in the agent configuration. +In v1.19.2, the modified DNS subsystem will be reverted and the old DNS behavior will be restored resolving these issues. - DNS SRV records for registrations that specify a service address instead of a node address return identical `.service` hostnames instead of unique `.addr` addresses. As a result, it is impossible to resolve the individual service addresses. This bug can affect Nomad installations using Consul for service discovery because the service address field is always specified to Consul. [[GH-21325](https://github.com/hashicorp/consul/issues/21325)]. - - DNS Tags are not resolved when using the Standard query format, `tag.name.service.consul`. + - DNS Tags are not resolved when using the Standard query format, `tag.name.service.consul`. [[GH-21326](https://github.com/hashicorp/consul/issues/21336)]. ## Changelogs From a570858a352c2f4b5aaf1b752b261adfda338893 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Wed, 14 Aug 2024 12:59:13 -0400 Subject: [PATCH 114/185] docs: Update compatibility.mdx for OpenShift (#21600) Remove note that OpenShift 4.16 is not yet available, now that it's been released. It will be added to the matrix in a future update once we've tested compatibility across eligible `consul-k8s` versions. --- website/content/docs/k8s/compatibility.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/website/content/docs/k8s/compatibility.mdx b/website/content/docs/k8s/compatibility.mdx index 950cd0a2ed..e3b7ecd743 100644 --- a/website/content/docs/k8s/compatibility.mdx +++ b/website/content/docs/k8s/compatibility.mdx @@ -27,11 +27,11 @@ compared to non-LTS Enterprise and community edition releases. Unless otherwise noted, rows in the following compatibility table apply to both Consul Enterprise and Consul community edition (CE). -| Consul version | Compatible `consul-k8s` versions | Compatible Kubernetes versions | Compatible OpenShift versions | -| -------------- | -------------------------------- | -------------------------------| -------------------------------------- | -| 1.19.x | 1.5.x | 1.27.x - 1.29.x | 4.13.x - 4.15.x (4.16.x not available) | -| 1.18.x CE | 1.4.x | 1.26.x - 1.29.x | 4.13.x - 4.15.x (4.16.x not available) | -| 1.17.x | 1.3.x | 1.25.x - 1.28.x | 4.12.x - 4.15.x | +| Consul version | Compatible `consul-k8s` versions | Compatible Kubernetes versions | Compatible OpenShift versions | +| -------------- | -------------------------------- | -------------------------------| ------------------------------| +| 1.19.x | 1.5.x | 1.27.x - 1.29.x | 4.13.x - 4.15.x | +| 1.18.x CE | 1.4.x | 1.26.x - 1.29.x | 4.13.x - 4.15.x | +| 1.17.x | 1.3.x | 1.25.x - 1.28.x | 4.12.x - 4.15.x | #### Enterprise Long Term Support releases @@ -40,10 +40,10 @@ Active Consul Enterprise releases expand their Kubernetes version compatibility window until the LTS release reaches its end of maintenance. -| Consul version | Compatible `consul-k8s` versions | Compatible Kubernetes versions | Compatible OpenShift versions | -| -------------- | -------------------------------- | -------------------------------| -------------------------------------- | -| 1.18.x Ent | 1.4.x | 1.26.x - 1.29.x | 4.13.x - 4.15.x (4.16.x not available) | -| 1.15.x Ent | 1.1.x | 1.23.x - 1.28.x | 4.10.x - 4.15.x | +| Consul version | Compatible `consul-k8s` versions | Compatible Kubernetes versions | Compatible OpenShift versions | +| -------------- | -------------------------------- | -------------------------------| ------------------------------| +| 1.18.x Ent | 1.4.x | 1.26.x - 1.29.x | 4.13.x - 4.15.x | +| 1.15.x Ent | 1.1.x | 1.23.x - 1.28.x | 4.10.x - 4.15.x | ### Version-specific upgrade requirements From 85554046620f278db1fb933bbc13fdf691c6251d Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 14 Aug 2024 15:00:00 -0400 Subject: [PATCH 115/185] [NET-10733] fix generation of xds resources (#21603) fix generation of xds resources --- agent/xds/resources_test.go | 130 +++++++++++++++++------------------- 1 file changed, 62 insertions(+), 68 deletions(-) diff --git a/agent/xds/resources_test.go b/agent/xds/resources_test.go index a1afeaee07..58cbdd727a 100644 --- a/agent/xds/resources_test.go +++ b/agent/xds/resources_test.go @@ -445,25 +445,25 @@ func getConnectProxyTransparentProxyGoldenTestCases() []goldenTestCase { } func getConnectProxyDiscoChainTests(enterprise bool) []goldenTestCase { - return []goldenTestCase{ + cases := []goldenTestCase{ { name: "connect-proxy-with-chain", create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", false, nil, nil) + 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", false, nil, nil) + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) }, alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-failover", create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", false, nil, nil) + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", enterprise, nil, nil) }, alsoRunTestForV2: true, }, @@ -487,10 +487,9 @@ func getConnectProxyDiscoChainTests(enterprise bool) []goldenTestCase { name: "custom-upstream-default-chain", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", enterprise, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "myservice", - }) + ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "myservice", + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -602,10 +601,9 @@ func getConnectProxyDiscoChainTests(enterprise bool) []goldenTestCase { name: "connect-proxy-with-default-chain-and-custom-cluster", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", enterprise, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "myservice", - }) + ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "myservice", + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -667,10 +665,9 @@ func getConnectProxyDiscoChainTests(enterprise bool) []goldenTestCase { uid := proxycfg.NewUpstreamID(&ns.Proxy.Upstreams[i]) - ns.Proxy.Upstreams[i].Config["envoy_listener_json"] = - customListenerJSON(t, customListenerJSONOptions{ - Name: uid.EnvoyID() + ":custom-upstream", - }) + ns.Proxy.Upstreams[i].Config["envoy_listener_json"] = customListenerJSON(t, customListenerJSONOptions{ + Name: uid.EnvoyID() + ":custom-upstream", + }) } }, nil) }, @@ -731,6 +728,14 @@ func getConnectProxyDiscoChainTests(enterprise bool) []goldenTestCase { alsoRunTestForV2: true, }, } + + if enterprise { + for i := range cases { + cases[i].name = "enterprise-" + cases[i].name + } + } + + return cases } func getMeshGatewayGoldenTestCases() []goldenTestCase { @@ -896,6 +901,7 @@ func getMeshGatewayGoldenTestCases() []goldenTestCase { }, } } + func getMeshGatewayPeeringGoldenTestCases() []goldenTestCase { return []goldenTestCase{ { @@ -1426,7 +1432,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }, } - }, []structs.BoundRoute{ &structs.TCPRouteConfigEntry{ Name: "tcp-route", @@ -1596,7 +1601,8 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { {Kind: structs.HTTPRoute, Name: "backend-route"}, {Kind: structs.HTTPRoute, Name: "frontend-route"}, {Kind: structs.HTTPRoute, Name: "generic-route"}, - }}, + }, + }, } }, []structs.BoundRoute{ @@ -1735,10 +1741,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { name: "custom-upstream-default-chain", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", enterprise, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "myservice", - }) + ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "myservice", + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -1748,10 +1753,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { name: "custom-local-app", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Config["envoy_local_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "mylocal", - }) + ns.Proxy.Config["envoy_local_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "mylocal", + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -1761,10 +1765,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { name: "custom-upstream", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "myservice", - }) + ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "myservice", + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -1775,12 +1778,11 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { overrideGoldenName: "custom-upstream", // should be the same create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "myservice", - // Attempt to override the TLS context should be ignored - TLSContext: `"allowRenegotiation": false`, - }) + ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "myservice", + // Attempt to override the TLS context should be ignored + TLSContext: `"allowRenegotiation": false`, + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -1791,7 +1793,6 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { 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 { @@ -1803,10 +1804,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { // 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", - }) + 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 @@ -1936,10 +1936,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { name: "connect-proxy-with-default-chain-and-custom-cluster", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "default", enterprise, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customAppClusterJSON(t, customClusterJSONOptions{ - Name: "myservice", - }) + ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = customAppClusterJSON(t, customClusterJSONOptions{ + Name: "myservice", + }) }, nil) }, // TODO(proxystate): requires custom cluster work @@ -1949,10 +1948,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { name: "custom-public-listener", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Config["envoy_public_listener_json"] = - customListenerJSON(t, customListenerJSONOptions{ - Name: "custom-public-listen", - }) + ns.Proxy.Config["envoy_public_listener_json"] = customListenerJSON(t, customListenerJSONOptions{ + Name: "custom-public-listen", + }) }, nil) }, }, @@ -1961,10 +1959,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { ns.Proxy.Config["protocol"] = "http" - ns.Proxy.Config["envoy_public_listener_json"] = - customHTTPListenerJSON(t, customHTTPListenerJSONOptions{ - Name: "custom-public-listen", - }) + ns.Proxy.Config["envoy_public_listener_json"] = customHTTPListenerJSON(t, customHTTPListenerJSONOptions{ + Name: "custom-public-listen", + }) }, nil) }, }, @@ -1973,11 +1970,10 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { ns.Proxy.Config["protocol"] = "http" - ns.Proxy.Config["envoy_public_listener_json"] = - customHTTPListenerJSON(t, customHTTPListenerJSONOptions{ - Name: "custom-public-listen", - HTTPConnectionManagerName: httpConnectionManagerNewName, - }) + ns.Proxy.Config["envoy_public_listener_json"] = customHTTPListenerJSON(t, customHTTPListenerJSONOptions{ + Name: "custom-public-listen", + HTTPConnectionManagerName: httpConnectionManagerNewName, + }) }, nil) }, }, @@ -1986,10 +1982,9 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { ns.Proxy.Config["protocol"] = "http" - ns.Proxy.Config["envoy_public_listener_json"] = - customListenerJSON(t, customListenerJSONOptions{ - Name: "custom-public-listen", - }) + ns.Proxy.Config["envoy_public_listener_json"] = customListenerJSON(t, customListenerJSONOptions{ + Name: "custom-public-listen", + }) }, nil) }, }, @@ -1998,12 +1993,11 @@ func getCustomConfigurationGoldenTestCases(enterprise bool) []goldenTestCase { overrideGoldenName: "custom-public-listener", // should be the same create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Config["envoy_public_listener_json"] = - customListenerJSON(t, customListenerJSONOptions{ - Name: "custom-public-listen", - // Attempt to override the TLS context should be ignored - TLSContext: `"allowRenegotiation": false`, - }) + ns.Proxy.Config["envoy_public_listener_json"] = customListenerJSON(t, customListenerJSONOptions{ + Name: "custom-public-listen", + // Attempt to override the TLS context should be ignored + TLSContext: `"allowRenegotiation": false`, + }) }, nil) }, }, From 1fa428552b30f7da868315d5b1540af49acadb9d Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 14 Aug 2024 15:41:02 -0400 Subject: [PATCH 116/185] [NET-10719] Fix cluster generation for jwt clusters for external jwt providers (#21604) * Fix cluster generation for jwt clusters for external jwt providers * add changelog --- .changelog/21604.txt | 3 +++ agent/xds/clusters.go | 6 +++--- agent/xds/jwt_authn_ce.go | 7 +++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 .changelog/21604.txt diff --git a/.changelog/21604.txt b/.changelog/21604.txt new file mode 100644 index 0000000000..f544140343 --- /dev/null +++ b/.changelog/21604.txt @@ -0,0 +1,3 @@ +```release-note:bug +api-gateway: **(Enterprise only)** ensure clusters are properly created for JWT providers with a remote URI for the JWKS endpoint +``` diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index f8abdc0e91..f6a3532447 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -148,7 +148,7 @@ func (s *ResourceGenerator) clustersFromSnapshotConnectProxy(cfgSnap *proxycfg.C // add clusters for jwt-providers for _, prov := range cfgSnap.JWTProviders { - //skip cluster creation for local providers + // skip cluster creation for local providers if prov.JSONWebKeySet == nil || prov.JSONWebKeySet.Remote == nil { continue } @@ -923,7 +923,6 @@ func (s *ResourceGenerator) injectGatewayDestinationAddons(cfgSnap *proxycfg.Con } c.TransportSocket = transportSocket } - } return nil } @@ -1004,6 +1003,8 @@ func (s *ResourceGenerator) clustersFromSnapshotAPIGateway(cfgSnap *proxycfg.Con createdClusters[uid] = true } + + clusters = append(clusters, makeAPIGatewayJWKClusters(s.Logger, cfgSnap)...) } return clusters, nil } @@ -1145,7 +1146,6 @@ func (s *ResourceGenerator) makeUpstreamClusterForPeerService( } upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil { return c, err } diff --git a/agent/xds/jwt_authn_ce.go b/agent/xds/jwt_authn_ce.go index f8cf52957d..5b08de5e5e 100644 --- a/agent/xds/jwt_authn_ce.go +++ b/agent/xds/jwt_authn_ce.go @@ -8,8 +8,11 @@ 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" + "google.golang.org/protobuf/proto" + "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/go-hclog" ) type GatewayAuthFilterBuilder struct { @@ -22,3 +25,7 @@ type GatewayAuthFilterBuilder struct { func (g *GatewayAuthFilterBuilder) makeGatewayAuthFilters() ([]*envoy_http_v3.HttpFilter, error) { return nil, nil } + +func makeAPIGatewayJWKClusters(_ hclog.Logger, _ *proxycfg.ConfigSnapshot) []proto.Message { + return nil +} From 58fad92cd35e0f68985645102d5c3cc50ce972ab Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 14 Aug 2024 16:03:00 -0400 Subject: [PATCH 117/185] fix where jwt clusters are generated (#21606) --- agent/xds/clusters.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index f6a3532447..ba04dada22 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -1003,9 +1003,9 @@ func (s *ResourceGenerator) clustersFromSnapshotAPIGateway(cfgSnap *proxycfg.Con createdClusters[uid] = true } - - clusters = append(clusters, makeAPIGatewayJWKClusters(s.Logger, cfgSnap)...) } + + clusters = append(clusters, makeAPIGatewayJWKClusters(s.Logger, cfgSnap)...) return clusters, nil } From e2bb1b76cc77bd051d6ba69d4cbe398e4f87950d Mon Sep 17 00:00:00 2001 From: danielehc <40759828+danielehc@users.noreply.github.com> Date: Thu, 15 Aug 2024 09:07:30 +0200 Subject: [PATCH 118/185] CE-657 - Move Application leader election tutorial to docs (#21366) * First commit * Fix navigation * Add some commands * Structure draft * Complete usage doc structure * Fix link * Apply suggestions from code review Co-authored-by: Aimee Ukasick * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Apply suggestions from code review * Replace tutorial path * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: Aimee Ukasick Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: boruszak --- website/content/api-docs/kv.mdx | 2 +- website/content/api-docs/session.mdx | 2 +- website/content/commands/lock.mdx | 2 +- .../docs/dynamic-app-config/kv/index.mdx | 2 +- .../sessions/application-leader-election.mdx | 396 ++++++++++++++++++ .../{sessions.mdx => sessions/index.mdx} | 6 +- website/data/docs-nav-data.json | 11 +- 7 files changed, 413 insertions(+), 8 deletions(-) create mode 100644 website/content/docs/dynamic-app-config/sessions/application-leader-election.mdx rename website/content/docs/dynamic-app-config/{sessions.mdx => sessions/index.mdx} (97%) diff --git a/website/content/api-docs/kv.mdx b/website/content/api-docs/kv.mdx index 912a8b6944..3eef6eb27f 100644 --- a/website/content/api-docs/kv.mdx +++ b/website/content/api-docs/kv.mdx @@ -212,7 +212,7 @@ The corresponding CLI command is [`consul kv put`](/consul/commands/kv/put). session has locked the key.** For an example of how to use the lock feature, check the - [Leader Election tutorial](/consul/tutorials/developer-configuration/application-leader-elections). + [Leader Election tutorial](/consul/docs/dynamic-app-config/sessions/application-leader-election). - `release` `(string: "")` - Supply a session ID to use in a release operation. This is useful when paired with `?acquire=` as it allows clients to yield a lock. This diff --git a/website/content/api-docs/session.mdx b/website/content/api-docs/session.mdx index 30dd005a1c..3f13f178d7 100644 --- a/website/content/api-docs/session.mdx +++ b/website/content/api-docs/session.mdx @@ -77,7 +77,7 @@ The table below shows this endpoint's support for 86400s). If provided, the session is invalidated if it is not renewed before the TTL expires. The lowest practical TTL should be used to keep the number of managed sessions low. When locks are forcibly expired, such as when following - the [leader election pattern](/consul/tutorials/developer-configuration/application-leader-elections) in an application, + the [leader election pattern](/consul/docs/dynamic-app-config/sessions/application-leader-election) in an application, sessions may not be reaped for up to double this TTL, so long TTL values (> 1 hour) should be avoided. Valid time units include "s", "m" and "h". diff --git a/website/content/commands/lock.mdx b/website/content/commands/lock.mdx index d4f405324c..85a1568051 100644 --- a/website/content/commands/lock.mdx +++ b/website/content/commands/lock.mdx @@ -18,7 +18,7 @@ communication is disrupted, the child process is terminated. The number of lock holders is configurable with the `-n` flag. By default, a single holder is allowed, and a lock is used for mutual exclusion. This -uses the [leader election algorithm](/consul/tutorials/developer-configuration/application-leader-elections). +uses the [leader election algorithm](/consul/docs/dynamic-app-config/sessions/application-leader-election). If the lock holder count is more than one, then a semaphore is used instead. A semaphore allows more than a single holder, but this is less efficient than diff --git a/website/content/docs/dynamic-app-config/kv/index.mdx b/website/content/docs/dynamic-app-config/kv/index.mdx index 982c772938..677037321d 100644 --- a/website/content/docs/dynamic-app-config/kv/index.mdx +++ b/website/content/docs/dynamic-app-config/kv/index.mdx @@ -111,7 +111,7 @@ increment to the `LockIndex` and the session value is updated to reflect the session holding the lock. Review the session documentation for more information on the [integration](/consul/docs/dynamic-app-config/sessions#k-v-integration). -Review the following tutorials to learn how to use Consul sessions for [application leader election](/consul/tutorials/developer-configuration/application-leader-elections) and +Review the following tutorials to learn how to use Consul sessions for [application leader election](/consul/docs/dynamic-app-config/sessions/application-leader-election) and to [build distributed semaphores](/consul/tutorials/developer-configuration/distributed-semaphore). ### Vault diff --git a/website/content/docs/dynamic-app-config/sessions/application-leader-election.mdx b/website/content/docs/dynamic-app-config/sessions/application-leader-election.mdx new file mode 100644 index 0000000000..5b14bcdc9e --- /dev/null +++ b/website/content/docs/dynamic-app-config/sessions/application-leader-election.mdx @@ -0,0 +1,396 @@ +--- +layout: docs +page_title: Application leader election +description: >- + Learn how to perform client-side leader elections using sessions and Consul key/value (KV) store. +--- + +# Application leader election + +This topic describes the process for building client-side leader elections for service instances using Consul's [session mechanism for building distributed locks](/consul/docs/dynamic-app-config/sessions) and the [Consul key/value store](/consul/docs/dynamic-app-config/kv), which is Consul's key/value datastore. + +This topic is not related to Consul's leader election. For more information about the Raft leader election used internally by Consul, refer to +[consensus protocol](/consul/docs/architecture/consensus) documentation. + +## Background + +Some distributed applications, like HDFS or ActiveMQ, require setting up one instance as a leader to ensure application data is current and stable. + +Consul's support for [sessions](/consul/docs/dynamic-app-config/sessions) and [watches](/consul/docs/dynamic-app-config/watches) allows you to build a client-side leader election process where clients use a lock on a key in the KV datastore to ensure mutual exclusion and to gracefully handle failures. + +All service instances that are participating should coordinate on a key format. We recommend the following pattern: + +```plaintext +service//leader +``` + +## Requirements + +- A running Consul server +- A path in the Consul KV datastore to acquire locks and to store information about the leader. The instructions on this page use the following key: `service/leader`. +- If ACLs are enabled, a token with the following permissions: + - `session:write` permissions over the service session name + - `key:write` permissions over the key + - The `curl` command + +Expose the token using the `CONSUL_HTTP_TOKEN` environment variable. + +## Client-side leader election procedure + +The workflow for building a client-side leader election process has the following steps: + +- For each client trying to acquire the lock: + 1. [Create a session](#create-a-new-session) associated with the client node. + 1. [Acquire the lock](#acquire-the-lock) on the designated key in the KV store using the `acquire` parameter. + 1. [Watch the KV key](#watch-the-kv-key-for-locks) to verify if the lock was released. If no lock is present, try to acquire a lock. + +- For the client that acquires the lock: + 1. Periodically, [renew the session](#renew-a-session) to avoid expiration. + 1. Optionally, [release the lock](#release-a-lock). + +- For other services: + 1. [Watch the KV key](#watch-the-kv-key-for-locks) to verify there is at least one process holding the lock. + 1. Use the values written under the KV path to identify the leader and update configurations accordingly. + +## Create a new session + +Create a configuration for the session. +The minimum viable configuration requires that you specify the session name. The following example demonstrates this configuration. + + + +```json +{ + "Name": "session_name" +} +``` + + + +Create a session using the [`/session` Consul HTTP API](/consul/api-docs/session) endpoint. In the following example, the node's `hostname` is the session name. + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --data '{"Name": "'`hostname`'"}' \ + --request PUT \ + http://127.0.0.1:8500/v1/session/create | jq +``` + + +The command returns a JSON object containing the ID of the newly created session. + +```json +{ + "ID": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6" +} +``` + +### Verify session + +Use the `/v1/session/list` endpoint to retrieve existing sessions. + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --request GET \ + http://127.0.0.1:8500/v1/session/list | jq +``` + +The command returns a JSON array containing all available sessions in the system. + + + +```json +[ + { + "ID": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6", + "Name": "hashicups-db-0", + "Node": "hashicups-db-0", + "LockDelay": 15000000000, + "Behavior": "release", + "TTL": "", + "NodeChecks": [ + "serfHealth" + ], + "ServiceChecks": null, + "CreateIndex": 11956, + "ModifyIndex": 11956 + } +] +``` + + + +You can verify from the output that the session is associated with the `hashicups-db-0` node, which is the client agent where the API request was made. + +With the exception of the `Name`, all parameters are set to their default values. The session is created without a `TTL` value, which means that it never expires and requires you to delete it explicitly. + +Depending on your needs you can create sessions specifying more parameters such as: + +- `TTL` - If provided, the session is invalidated and deleted if it is not renewed before the TTL expires. +- `ServiceChecks` - Specifies a list of service checks to monitor. The session is invalidated if the checks return a critical state. + +By setting these extra parameters, you can create a client-side leader election workflow that automatically releases the lock after a specified amount of time since the last renew, or that automatically releases locks when the service holding them fails. + +For a full list of parameters available refer to the [`/session/create` endpoint documentation](/consul/api-docs/session#create-session). + +## Acquire the lock + +Create the data object to associate to the lock request. + +The data of the request should be a JSON object representing the local instance. This value is opaque to Consul, but it should contain whatever information clients require to communicate with your application. For example, it could be a JSON object that contains the node's name and the application's port. + + + +```json +{ + "Node": "node-name", + "Port": "8080" +} +``` + + + + + + +Acquire a lock for a given key using the PUT method on a [KV entry](/consul/api-docs/kv) with the +`?acquire=` query parameter. + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --data '{"Node": "'`hostname`'"}' \ + --request PUT \ + http://localhost:8500/v1/kv/service/leader?acquire=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 | jq +``` + +This request returns either `true` or `false`. If `true`, the lock was acquired and +the local service instance is now the leader. If `false`, a different node acquired +the lock. + + + + + +```shell-session +$ consul kv put -acquire -session=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 /service/leader '{"Node": "'`hostname`'"}' +``` + +In case of success, the command exits with exit code `0` and outputs the following message. + + + +```plaintext +Success! Lock acquired on: service/leader +``` + + + +If the lock was already acquired by another node, the command exits with exit code `1` and outputs the following message. + + + +```plaintext +Error! Did not acquire lock +``` + + + + + + +This example used the node's `hostname` as the key data. This data can be used by the other services to create configuration files. + +Be aware that this locking system has no enforcement mechanism that requires clients to acquire a lock before they perform an operation. Any client can read, write, and delete a key without owning the corresponding lock. + +## Watch the KV key for locks + +Existing locks need to be monitored by all nodes involved in the client-side leader elections, as well as by the other nodes that need to know the identity of the leader. + + - Lock holders need to monitor the lock because the session might get invalidated by an operator. + - Other services that want to acquire the lock need to monitor it to check if the lock is released so they can try acquire the lock. + - Other nodes need to monitor the lock to see if the value of the key changed and update their configuration accordingly. + + + + +Monitor the lock using the GET method on a [KV entry](/consul/api-docs/kv) with the blocking query enabled. + +First, verify the latest index for the current value. + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --request GET \ + http://127.0.0.1:8500/v1/kv/service/leader?index=1 | jq +``` + +The command outputs the key data, including the `ModifyIndex` for the object. + + + +```json +[ + { + "LockIndex": 0, + "Key": "service/leader", + "Flags": 0, + "Value": "eyJOb2RlIjogImhhc2hpY3Vwcy1kYi0wIn0=", + "Session": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6", + "CreateIndex": 12399, + "ModifyIndex": 13061 + } +] +``` + + + +Using the value of the `ModifyIndex`, run a [blocking query](/consul/api-docs/features/blocking) against the lock. + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --request GET \ + http://127.0.0.1:8500/v1/kv/service/leader?index=13061 | jq +``` +The command hangs until a change is made on the KV path and after that the path data prints on the console. + + + +```json +[ + { + "LockIndex": 0, + "Key": "service/leader", + "Flags": 0, + "Value": "eyJOb2RlIjogImhhc2hpY3Vwcy1kYi0xIn0=", + "Session": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6", + "CreateIndex": 12399, + "ModifyIndex": 13329 + } +] +``` + + + +For automation purposes, add logic to the blocking query mechanism to trigger a command every time a change is returned. +A better approach is to use the CLI command `consul watch`. + + + + +Monitor the lock using the [`consul watch`](/consul/commands/watch) command. + +```shell-session +$ consul watch -type=key -key=service/leader cat | jq +``` + +In this example, the command output prints to the shell. However, it is possible to pass more complex option to the command as well as a script that contains more complex logic to react to the lock data change. + +An example output for the command is: + + + +```json +{ + "Key": "service/leader", + "CreateIndex": 12399, + "ModifyIndex": 13061, + "LockIndex": 0, + "Flags": 0, + "Value": "eyJOb2RlIjogImhhc2hpY3Vwcy1kYi0wIn0=", + "Session": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6" +} +``` + + + +The `consul watch` command polls the KV path for changes and runs the specified command on the output when a change is made. + + + + +From the output, notice that once the lock is acquired, the `Session` parameter contains the ID of the session that holds the lock. + +## Renew a session + +If a session is created with a `TTL` value set, you need to renew the session before the TTL expires. + +Use the [`/v1/session/renew`](/consul/api-docs/session#renew-session) endpoint to renew existing sessions. + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --request PUT \ + http://127.0.0.1:8500/v1/session/renew/f027470f-2759-6b53-542d-066ae4185e67 | jq +``` + +If the command succeeds, the session information in JSON format is printed. + + + +```json +[ + { + "ID": "f027470f-2759-6b53-542d-066ae4185e67", + "Name": "test", + "Node": "consul-server-0", + "LockDelay": 15000000000, + "Behavior": "release", + "TTL": "30s", + "NodeChecks": [ + "serfHealth" + ], + "ServiceChecks": null, + "CreateIndex": 11842, + "ModifyIndex": 11842 + } +] +``` + + + +## Release a lock + +A lock associated with a session with no `TTL` value set might never be released, even when the service holding it fails. + +In such cases, you need to manually release the lock. + + + + +```shell-session +$ curl --silent \ + --header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \ + --data '{"Node": "'`hostname`'"}' \ + --request PUT \ + http://localhost:8500/v1/kv/service/leader?release=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 | jq +``` + +The command prints `true` on success. + + + + +```shell-session +$ consul kv put -release -session=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 service/leader '{"Node": "'`hostname`'"}' +``` + +On success, the command outputs a success message. + + + +```plaintext +Success! Lock released on: service/leader +``` + + + + + + +After a lock is released, the key data do not show a value for `Session` in the results. +Other clients can use this as a way to coordinate their lock requests. + diff --git a/website/content/docs/dynamic-app-config/sessions.mdx b/website/content/docs/dynamic-app-config/sessions/index.mdx similarity index 97% rename from website/content/docs/dynamic-app-config/sessions.mdx rename to website/content/docs/dynamic-app-config/sessions/index.mdx index eb0c4cf495..3eb26f558f 100644 --- a/website/content/docs/dynamic-app-config/sessions.mdx +++ b/website/content/docs/dynamic-app-config/sessions/index.mdx @@ -134,9 +134,9 @@ the goal of Consul to protect against misbehaving clients. ## Leader Election -The primitives provided by sessions and the locking mechanisms of the KV -store can be used to build client-side leader election algorithms. -These are covered in more detail in the [Leader Election guide](/consul/tutorials/developer-configuration/application-leader-elections). +You can use the primitives provided by sessions and the locking mechanisms of the KV +store to build client-side leader election algorithms. +These are covered in more detail in the [Leader Election guide](/consul/docs/dynamic-app-config/sessions/application-leader-election). ## Prepared Query Integration diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index c883f29a5b..8af621f8d3 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -1054,7 +1054,16 @@ }, { "title": "Sessions", - "path": "dynamic-app-config/sessions" + "routes": [ + { + "title": "Overview", + "path": "dynamic-app-config/sessions" + }, + { + "title": "Application leader election", + "path": "dynamic-app-config/sessions/application-leader-election" + } + ] }, { "title": "Watches", From f76da16000bebce8cdb112c17107b05de81eec97 Mon Sep 17 00:00:00 2001 From: John Murret Date: Thu, 15 Aug 2024 12:09:09 -0600 Subject: [PATCH 119/185] Fix TestDNS_ServiceLookup_ARecordLimits so that it only creates test agents the minimal amount of time (#21608) * get rid of unused column * get rid of duplicate section now that deletion of unused column makes the section duplicate.. * explicit set protocol rathern than infer it in checkDNSService * explicit have attribute for whether to set EDNS0 in the test cases rathern than infer it in checkDNSService * now modify so that test agents are only created for each unique configuration which is based on the a_record_limit. * Fix TestDNS_ServiceLookup_AnswerLimits so that it only creates test agents the minimal amount of time. (#21609) Fix TestDNS_ServiceLookup_AnswerLimits so that it only creates test agents the minimal amount of time --- agent/dns_service_lookup_test.go | 359 ++++++++++++++----------------- 1 file changed, 167 insertions(+), 192 deletions(-) diff --git a/agent/dns_service_lookup_test.go b/agent/dns_service_lookup_test.go index ef2a9dbe6d..34a48b75ba 100644 --- a/agent/dns_service_lookup_test.go +++ b/agent/dns_service_lookup_test.go @@ -2919,62 +2919,8 @@ func TestDNS_ServiceLookup_LargeResponses(t *testing.T) { } } -func testDNSServiceLookupResponseLimits(t *testing.T, answerLimit int, qType uint16, - expectedService, expectedQuery, expectedQueryID int, additionalHCL string) (bool, error) { - a := NewTestAgent(t, ` - node_name = "test-node" - dns_config { - udp_answer_limit = `+fmt.Sprintf("%d", answerLimit)+` - } - `+additionalHCL) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6) - for i := 0; i < generateNumNodes; i++ { - nodeAddress := fmt.Sprintf("127.0.0.%d", i+1) - if choices[i] { - nodeAddress = fmt.Sprintf("fe80::%d", i+1) - } - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("foo%d", i), - Address: nodeAddress, - Service: &structs.NodeService{ - Service: "api-tier", - Port: 8080, - }, - } - - var out struct{} - if err := a.RPC(context.Background(), "Catalog.Register", args, &out); err != nil { - return false, fmt.Errorf("err: %v", err) - } - } - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "api-tier", - Service: structs.ServiceQuery{ - Service: "api-tier", - }, - }, - } - - if err := a.RPC(context.Background(), "PreparedQuery.Apply", args, &id); err != nil { - return false, fmt.Errorf("err: %v", err) - } - } - - // Look up the service directly and via prepared query. - questions := []string{ - "api-tier.service.consul.", - "api-tier.query.consul.", - id + ".query.consul.", - } +func testDNSServiceLookupResponseLimits(questions []string, answerLimit int, qType uint16, + expectedService, expectedQuery, expectedQueryID int, a *TestAgent) (bool, error) { for idx, question := range questions { m := new(dns.Msg) m.SetQuestion(question, qType) @@ -3011,78 +2957,24 @@ func testDNSServiceLookupResponseLimits(t *testing.T, answerLimit int, qType uin func checkDNSService( t *testing.T, - generateNumNodes int, - aRecordLimit int, + protocol string, + questions []string, + a *TestAgent, qType uint16, expectedResultsCount int, udpSize uint16, + setEDNS0 bool, ) { - a := NewTestAgent(t, ` - node_name = "test-node" - dns_config { - a_record_limit = `+fmt.Sprintf("%d", aRecordLimit)+` - udp_answer_limit = `+fmt.Sprintf("%d", aRecordLimit)+` - } - `) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6) - for i := 0; i < generateNumNodes; i++ { - nodeAddress := fmt.Sprintf("127.0.0.%d", i+1) - if choices[i] { - nodeAddress = fmt.Sprintf("fe80::%d", i+1) - } - args := &structs.RegisterRequest{ - Datacenter: "dc1", - Node: fmt.Sprintf("foo%d", i), - Address: nodeAddress, - Service: &structs.NodeService{ - Service: "api-tier", - Port: 8080, - }, - } - - var out struct{} - require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) - } - var id string - { - args := &structs.PreparedQueryRequest{ - Datacenter: "dc1", - Op: structs.PreparedQueryCreate, - Query: &structs.PreparedQuery{ - Name: "api-tier", - Service: structs.ServiceQuery{ - Service: "api-tier", - }, - }, - } - - require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &id)) - } - - // Look up the service directly and via prepared query. - questions := []string{ - "api-tier.service.consul.", - "api-tier.query.consul.", - id + ".query.consul.", - } for _, question := range questions { - question := question t.Run("question: "+question, func(t *testing.T) { m := new(dns.Msg) m.SetQuestion(question, qType) - protocol := "tcp" - if udpSize > 0 { - protocol = "udp" - } - if udpSize > 512 { + if setEDNS0 { m.SetEdns0(udpSize, true) } - c := &dns.Client{Net: protocol, UDPSize: 8192} + c := &dns.Client{Net: protocol, UDPSize: udpSize} in, _, err := c.Exchange(m, a.DNSAddr()) require.NoError(t, err) @@ -3094,82 +2986,154 @@ func checkDNSService( } } +func registerServicesAndPreparedQuery(t *testing.T, generateNumNodes int, a *TestAgent, serviceUniquenessKey string) []string { + choices := perfectlyRandomChoices(generateNumNodes, pctNodesWithIPv6) + serviceName := fmt.Sprintf("api-tier-%s", serviceUniquenessKey) + for i := 0; i < generateNumNodes; i++ { + nodeAddress := fmt.Sprintf("127.0.0.%d", i+1) + if choices[i] { + nodeAddress = fmt.Sprintf("fe80::%d", i+1) + } + args := &structs.RegisterRequest{ + Datacenter: "dc1", + Node: fmt.Sprintf("foo%d", i), + Address: nodeAddress, + Service: &structs.NodeService{ + Service: serviceName, + Port: 8080, + }, + } + + var out struct{} + require.NoError(t, a.RPC(context.Background(), "Catalog.Register", args, &out)) + } + var preparedQueryID string + { + args := &structs.PreparedQueryRequest{ + Datacenter: "dc1", + Op: structs.PreparedQueryCreate, + Query: &structs.PreparedQuery{ + Name: serviceName, + Service: structs.ServiceQuery{ + Service: serviceName, + }, + }, + } + + require.NoError(t, a.RPC(context.Background(), "PreparedQuery.Apply", args, &preparedQueryID)) + } + + // Look up the service directly and via prepared query. + questions := []string{ + fmt.Sprintf("%s.service.consul.", serviceName), + fmt.Sprintf("%s.query.consul.", serviceName), + preparedQueryID + ".query.consul.", + } + return questions +} + func TestDNS_ServiceLookup_ARecordLimits(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") } + const ( + UDP = "udp" + TCP = "tcp" + ) - tests := []struct { - name string - aRecordLimit int - expectedAResults int - expectedAAAAResults int - expectedANYResults int - expectedSRVResults int - numNodesTotal int - udpSize uint16 - _unused_udpAnswerLimit int // NOTE: this field is not used - }{ + type testCase struct { + protocol string + aRecordLimit int + expectedAResults int + expectedAAAAResults int + expectedANYResults int + expectedSRVResults int + numNodesTotal int + udpSize uint16 + setEDNS0 bool + } + + type aRecordLimit struct { + name string + limit int + } + + tests := map[string]testCase{ // UDP + EDNS - {"udp-edns-1", 1, 1, 1, 1, 30, 30, 8192, 3}, - {"udp-edns-2", 2, 2, 2, 2, 30, 30, 8192, 3}, - {"udp-edns-3", 3, 3, 3, 3, 30, 30, 8192, 3}, - {"udp-edns-4", 4, 4, 4, 4, 30, 30, 8192, 3}, - {"udp-edns-5", 5, 5, 5, 5, 30, 30, 8192, 3}, - {"udp-edns-6", 6, 6, 6, 6, 30, 30, 8192, 3}, - {"udp-edns-max", 6, 2, 1, 3, 3, 3, 8192, 3}, - // All UDP without EDNS have a limit of 2 answers due to udpAnswerLimit - // Even SRV records are limit to 2 records - {"udp-limit-1", 1, 1, 0, 1, 1, 1, 512, 2}, - {"udp-limit-2", 2, 1, 1, 2, 2, 2, 512, 2}, - // AAAA results limited by size of payload - {"udp-limit-3", 3, 1, 1, 2, 2, 2, 512, 2}, - {"udp-limit-4", 4, 1, 1, 2, 2, 2, 512, 2}, - {"udp-limit-5", 5, 1, 1, 2, 2, 2, 512, 2}, - {"udp-limit-6", 6, 1, 1, 2, 2, 2, 512, 2}, - {"udp-limit-max", 6, 1, 1, 2, 2, 2, 512, 2}, + "udp-edns-1": {UDP, 1, 1, 1, 1, 30, 30, 8192, true}, + "udp-edns-2": {UDP, 2, 2, 2, 2, 30, 30, 8192, true}, + "udp-edns-3": {UDP, 3, 3, 3, 3, 30, 30, 8192, true}, + "udp-edns-4": {UDP, 4, 4, 4, 4, 30, 30, 8192, true}, + "udp-edns-5": {UDP, 5, 5, 5, 5, 30, 30, 8192, true}, + "udp-edns-6": {UDP, 6, 6, 6, 6, 30, 30, 8192, true}, + "udp-edns-max": {UDP, 6, 2, 1, 3, 3, 3, 8192, true}, // All UDP without EDNS and no udpAnswerLimit // Size of records is limited by UDP payload - {"udp-1", 1, 1, 0, 1, 1, 1, 512, 0}, - {"udp-2", 2, 1, 1, 2, 2, 2, 512, 0}, - {"udp-3", 3, 1, 1, 2, 2, 2, 512, 0}, - {"udp-4", 4, 1, 1, 2, 2, 2, 512, 0}, - {"udp-5", 5, 1, 1, 2, 2, 2, 512, 0}, - {"udp-6", 6, 1, 1, 2, 2, 2, 512, 0}, + "udp-1": {UDP, 1, 1, 0, 1, 1, 1, 512, false}, + "udp-2": {UDP, 2, 1, 1, 2, 2, 2, 512, false}, + "udp-3": {UDP, 3, 1, 1, 2, 2, 2, 512, false}, + "udp-4": {UDP, 4, 1, 1, 2, 2, 2, 512, false}, + "udp-5": {UDP, 5, 1, 1, 2, 2, 2, 512, false}, + "udp-6": {UDP, 6, 1, 1, 2, 2, 2, 512, false}, // Only 3 A and 3 SRV records on 512 bytes - {"udp-max", 6, 1, 1, 2, 2, 2, 512, 0}, + "udp-max": {UDP, 6, 1, 1, 2, 2, 2, 512, false}, - {"tcp-1", 1, 1, 1, 1, 30, 30, 0, 0}, - {"tcp-2", 2, 2, 2, 2, 30, 30, 0, 0}, - {"tcp-3", 3, 3, 3, 3, 30, 30, 0, 0}, - {"tcp-4", 4, 4, 4, 4, 30, 30, 0, 0}, - {"tcp-5", 5, 5, 5, 5, 30, 30, 0, 0}, - {"tcp-6", 6, 6, 6, 6, 30, 30, 0, 0}, - {"tcp-max", 6, 1, 1, 2, 2, 2, 0, 0}, + "tcp-1": {TCP, 1, 1, 1, 1, 30, 30, 0, false}, + "tcp-2": {TCP, 2, 2, 2, 2, 30, 30, 0, false}, + "tcp-3": {TCP, 3, 3, 3, 3, 30, 30, 0, false}, + "tcp-4": {TCP, 4, 4, 4, 4, 30, 30, 0, false}, + "tcp-5": {TCP, 5, 5, 5, 5, 30, 30, 0, false}, + "tcp-6": {TCP, 6, 6, 6, 6, 30, 30, 0, false}, + "tcp-max": {TCP, 6, 1, 1, 2, 2, 2, 0, false}, } - for _, test := range tests { - test := test // capture loop var + for _, recordLimit := range []aRecordLimit{ + {"1", 1}, + {"2", 2}, + {"3", 3}, + {"4", 4}, + {"5", 5}, + {"6", 6}, + {"max", 6}, + } { + t.Run("record-limit-"+recordLimit.name, func(t *testing.T) { + a := NewTestAgent(t, ` + node_name = "test-node" + dns_config { + a_record_limit = `+fmt.Sprintf("%d", recordLimit.limit)+` + udp_answer_limit = `+fmt.Sprintf("%d", recordLimit.limit)+` + } + `) - t.Run(test.name, func(t *testing.T) { + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") - // All those queries should have at max queriesLimited elements + for _, testName := range []string{ + fmt.Sprintf("udp-edns-%s", recordLimit.name), + fmt.Sprintf("udp-%s", recordLimit.name), + fmt.Sprintf("tcp-%s", recordLimit.name), + } { + t.Run(testName, func(t *testing.T) { + test := tests[testName] + questions := registerServicesAndPreparedQuery(t, test.numNodesTotal, a, testName) - t.Run("A", func(t *testing.T) { - checkDNSService(t, test.numNodesTotal, test.aRecordLimit, dns.TypeA, test.expectedAResults, test.udpSize) - }) + t.Run("A", func(t *testing.T) { + checkDNSService(t, test.protocol, questions, a, dns.TypeA, test.expectedAResults, test.udpSize, test.setEDNS0) + }) - t.Run("AAAA", func(t *testing.T) { - checkDNSService(t, test.numNodesTotal, test.aRecordLimit, dns.TypeAAAA, test.expectedAAAAResults, test.udpSize) - }) + t.Run("AAAA", func(t *testing.T) { + checkDNSService(t, test.protocol, questions, a, dns.TypeAAAA, test.expectedAAAAResults, test.udpSize, test.setEDNS0) + }) - t.Run("ANY", func(t *testing.T) { - checkDNSService(t, test.numNodesTotal, test.aRecordLimit, dns.TypeANY, test.expectedANYResults, test.udpSize) - }) + t.Run("ANY", func(t *testing.T) { + checkDNSService(t, test.protocol, questions, a, dns.TypeANY, test.expectedANYResults, test.udpSize, test.setEDNS0) + }) - // No limits but the size of records for SRV records, since not subject to randomization issues - t.Run("SRV", func(t *testing.T) { - checkDNSService(t, test.expectedSRVResults, test.aRecordLimit, dns.TypeSRV, test.numNodesTotal, test.udpSize) - }) + // No limits but the size of records for SRV records, since not subject to randomization issues + t.Run("SRV", func(t *testing.T) { + checkDNSService(t, test.protocol, questions, a, dns.TypeSRV, test.numNodesTotal, test.udpSize, test.setEDNS0) + }) + }) + } }) } } @@ -3217,25 +3181,36 @@ func TestDNS_ServiceLookup_AnswerLimits(t *testing.T) { } for _, test := range tests { test := test // capture loop var - t.Run(fmt.Sprintf("A lookup %v", test), func(t *testing.T) { - ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeA, test.expectedAService, test.expectedAQuery, test.expectedAQueryID, "") - if !ok { - t.Fatalf("Expected service A lookup %s to pass: %v", test.name, err) - } - }) + t.Run(fmt.Sprintf("answer-limit-%s", test.name), func(t *testing.T) { + a := NewTestAgent(t, fmt.Sprintf(` + node_name = "test-node" + dns_config { + udp_answer_limit = %d + }`, test.udpAnswerLimit)) + defer a.Shutdown() + testrpc.WaitForTestAgent(t, a.RPC, "dc1") + questions := registerServicesAndPreparedQuery(t, generateNumNodes, a, test.name) - t.Run(fmt.Sprintf("AAAA lookup %v", test), func(t *testing.T) { - ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeAAAA, test.expectedAAAAService, test.expectedAAAAQuery, test.expectedAAAAQueryID, "") - if !ok { - t.Fatalf("Expected service AAAA lookup %s to pass: %v", test.name, err) - } - }) + t.Run(fmt.Sprintf("A lookup %v", test), func(t *testing.T) { + ok, err := testDNSServiceLookupResponseLimits(questions, test.udpAnswerLimit, dns.TypeA, test.expectedAService, test.expectedAQuery, test.expectedAQueryID, a) + if !ok { + t.Fatalf("Expected service A lookup %s to pass: %v", test.name, err) + } + }) - t.Run(fmt.Sprintf("ANY lookup %v", test), func(t *testing.T) { - ok, err := testDNSServiceLookupResponseLimits(t, test.udpAnswerLimit, dns.TypeANY, test.expectedANYService, test.expectedANYQuery, test.expectedANYQueryID, "") - if !ok { - t.Fatalf("Expected service ANY lookup %s to pass: %v", test.name, err) - } + t.Run(fmt.Sprintf("AAAA lookup %v", test), func(t *testing.T) { + ok, err := testDNSServiceLookupResponseLimits(questions, test.udpAnswerLimit, dns.TypeAAAA, test.expectedAAAAService, test.expectedAAAAQuery, test.expectedAAAAQueryID, a) + if !ok { + t.Fatalf("Expected service AAAA lookup %s to pass: %v", test.name, err) + } + }) + + t.Run(fmt.Sprintf("ANY lookup %v", test), func(t *testing.T) { + ok, err := testDNSServiceLookupResponseLimits(questions, test.udpAnswerLimit, dns.TypeANY, test.expectedANYService, test.expectedANYQuery, test.expectedANYQueryID, a) + if !ok { + t.Fatalf("Expected service ANY lookup %s to pass: %v", test.name, err) + } + }) }) } } From bc4c479a31a88313edba65ada3590bfa8f69a6d3 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Mon, 19 Aug 2024 11:49:05 -0400 Subject: [PATCH 120/185] [NET-10737] Add CI Checks for Generated Testdata (#21613) * Add checks to CI to ensure that generated golden files for xds tests are up to date * fix file permissions * debugging * more debugging * more debugging * more debugging * more debugging * I can't type * this might be correct * removing debug prints --- .github/scripts/goldenfile_checker.sh | 21 +++++++++++++++++ .github/workflows/goldenfile-checker.yml | 30 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100755 .github/scripts/goldenfile_checker.sh create mode 100644 .github/workflows/goldenfile-checker.yml diff --git a/.github/scripts/goldenfile_checker.sh b/.github/scripts/goldenfile_checker.sh new file mode 100755 index 0000000000..61eb8e5724 --- /dev/null +++ b/.github/scripts/goldenfile_checker.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +set -euo pipefail + +# check if there is a diff in the xds testdata directory after running `make envoy-regen` +echo "regenerating xds files" +make envoy-regen &>/dev/null + +echo "calculating changed files" +changed_xds_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/$GITHUB_BRANCH_REF")" | egrep "agent/xds/testdata/.*" || true) +# If we do not find a file in .changelog/, we fail the check +if [ -z "$changed_xds_files" ]; then + # pass status check if no changes were found for xds files + echo "Found no changes to xds golden files" + exit 0 +else + echo "Found diffs with xds golden files run 'make envoy-regen' to update them and check that output is expected" + exit 0 +fi diff --git a/.github/workflows/goldenfile-checker.yml b/.github/workflows/goldenfile-checker.yml new file mode 100644 index 0000000000..fed1f30471 --- /dev/null +++ b/.github/workflows/goldenfile-checker.yml @@ -0,0 +1,30 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# This workflow checks that are no changes necessary to golden files for xds +# tests ensuring they are up to date + +name: Golden File Checker + +on: + pull_request: + types: [opened, synchronize, labeled] + # Runs on PRs to main and all release branches + branches: + - main + - release/* + +jobs: + # checks that there is no diff between the existing golden files + goldenfile-check: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 # by default the checkout action doesn't checkout all branches + - name: Check for golden file xds tests in diff + run: ./.github/scripts/goldenfile_checker.sh + env: + GITHUB_BRANCH_REF: ${{ github.event.pull_request.head.ref }} From b88ddb8f9fe7d2c7bb826be6ab3b0edc9bacd72c Mon Sep 17 00:00:00 2001 From: John Maguire Date: Mon, 19 Aug 2024 14:14:13 -0400 Subject: [PATCH 121/185] update goldenfile checker for running in ent repo (#21617) --- .github/scripts/goldenfile_checker.sh | 2 +- .github/workflows/goldenfile-checker.yml | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/scripts/goldenfile_checker.sh b/.github/scripts/goldenfile_checker.sh index 61eb8e5724..0bdcfa35d0 100755 --- a/.github/scripts/goldenfile_checker.sh +++ b/.github/scripts/goldenfile_checker.sh @@ -6,7 +6,7 @@ set -euo pipefail # check if there is a diff in the xds testdata directory after running `make envoy-regen` echo "regenerating xds files" -make envoy-regen &>/dev/null +make envoy-regen echo "calculating changed files" changed_xds_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/$GITHUB_BRANCH_REF")" | egrep "agent/xds/testdata/.*" || true) diff --git a/.github/workflows/goldenfile-checker.yml b/.github/workflows/goldenfile-checker.yml index fed1f30471..6f3d1ca681 100644 --- a/.github/workflows/goldenfile-checker.yml +++ b/.github/workflows/goldenfile-checker.yml @@ -15,16 +15,29 @@ on: - release/* jobs: + get-go-version: + uses: ./.github/workflows/reusable-get-go-version.yml # checks that there is no diff between the existing golden files goldenfile-check: runs-on: ubuntu-latest - + needs: + - get-go-version steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches + # 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@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + with: + go-version: ${{ needs.get-go-version.outputs.go-version }} + - name: Download Modules + run: go mod download - name: Check for golden file xds tests in diff run: ./.github/scripts/goldenfile_checker.sh env: GITHUB_BRANCH_REF: ${{ github.event.pull_request.head.ref }} + CONSUL_LICENSE: ${{ secrets.CONSUL_LICENSE }} From ed738a6f981b74c7ef0e266b478edb03bd4db741 Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Mon, 19 Aug 2024 22:39:28 -0700 Subject: [PATCH 122/185] fix: use Envoy's default for validate_clusters to fix breaking routes when some backend clusters don't exist (#21587) --- .changelog/21587.txt | 3 + agent/structs/config_entry_mesh.go | 8 + agent/xds/resources_test.go | 10 + agent/xds/routes.go | 81 +- ...teway-with-service-resolvers.latest.golden | 3 - .../lambda-terminating-gateway.latest.golden | 1 - ...es-to-local-upstreams-tproxy.latest.golden | 2 - ...ic-upstream-service-splitter.latest.golden | 1 - ...ch-specific-upstream-service.latest.golden | 3 +- ...r-and-mesh-validate-clusters.latest.golden | 289 ++ ...r-and-mesh-validate-clusters.latest.golden | 75 + ...r-and-mesh-validate-clusters.latest.golden | 137 + ...ttp-listener-with-http-route.latest.golden | 1 - ...ener-with-tcp-and-http-route.latest.golden | 1 - ...-route-timeoutfilter-one-set.latest.golden | 1 - .../api-gateway-with-http-route.latest.golden | 1 - ...eway-with-multiple-hostnames.latest.golden | 1 - ...connect-proxy-lb-in-resolver.latest.golden | 1 - ...nnect-proxy-resolver-with-lb.latest.golden | 1 - ...t-proxy-route-to-lb-resolver.latest.golden | 1 - ...ct-proxy-splitter-overweight.latest.golden | 1 - ...oxy-with-chain-and-overrides.latest.golden | 1 - ...-proxy-with-chain-and-router.latest.golden | 1 - ...r-and-mesh-validate-clusters.latest.golden | 139 + ...roxy-with-chain-and-splitter.latest.golden | 1 - ...onnect-proxy-with-grpc-chain.latest.golden | 1 - ...nnect-proxy-with-grpc-router.latest.golden | 1 - ...onnect-proxy-with-http-chain.latest.golden | 1 - ...nnect-proxy-with-http2-chain.latest.golden | 1 - ...gress-grpc-multiple-services.latest.golden | 1 - ...gress-http-multiple-services.latest.golden | 2 - .../ingress-lb-in-resolver.latest.golden | 1 - ...-listeners-duplicate-service.latest.golden | 2 - ...itter-with-resolver-redirect.latest.golden | 1 - ...hain-and-router-header-manip.latest.golden | 1 - ...ngress-with-chain-and-router.latest.golden | 1 - ...ress-with-chain-and-splitter.latest.golden | 1 - .../ingress-with-grpc-router.latest.golden | 1 - ...ith-grpc-single-tls-listener.latest.golden | 2 - ...d-grpc-multiple-tls-listener.latest.golden | 2 - ...th-http2-single-tls-listener.latest.golden | 2 - ...h-sds-listener+service-level.latest.golden | 2 - ...h-sds-listener-gw-level-http.latest.golden | 1 - ...-sds-listener-level-wildcard.latest.golden | 1 - ...ress-with-sds-listener-level.latest.golden | 1 - ...ess-with-sds-service-level-2.latest.golden | 2 - ...s-service-level-mixed-no-tls.latest.golden | 2 - ...-sds-service-level-mixed-tls.latest.golden | 2 - ...gress-with-sds-service-level.latest.golden | 2 - ...ess-with-single-tls-listener.latest.golden | 2 - ...n-listeners-gateway-defaults.latest.golden | 5 - ...ixed-cipher-suites-listeners.latest.golden | 2 - ...ess-with-tls-mixed-listeners.latest.golden | 2 - ...-mixed-max-version-listeners.latest.golden | 3 - ...-mixed-min-version-listeners.latest.golden | 3 - ...ed-services-http-with-router.latest.golden | 1 - ...xported-peered-services-http.latest.golden | 3 - ...itter-with-resolver-redirect.latest.golden | 1 - ...way-hostname-service-subsets.latest.golden | 4 - ...teway-ignore-extra-resolvers.latest.golden | 3 - ...y-lb-config-no-hash-policies.latest.golden | 3 - ...erminating-gateway-lb-config.latest.golden | 3 - ...ting-gateway-service-subsets.latest.golden | 3 - ...arent-proxy-destination-http.latest.golden | 2 - ...ng-gateway-destinations-only.latest.golden | 2 - ...meout-ms-ingress-with-router.latest.golden | 1 - ...fetch-timeout-ms-mgw-peering.latest.golden | 3 - ...xds-fetch-timeout-ms-sidecar.latest.golden | 1 - ...xds-fetch-timeout-ms-term-gw.latest.golden | 3 - ...imeout-ms-tproxy-passthrough.latest.golden | 2 - ...r-and-mesh-validate-clusters.latest.golden | 5 + agent/xds/xds_protocol_helpers_test.go | 3 +- agent/xdsv2/route_resources.go | 4 - ...mixed-multi-destination-default-bar.golden | 3 +- ...d-multi-destination-default-default.golden | 3 +- .../mixed-multi-destination-foo-bar.golden | 3 +- ...mixed-multi-destination-foo-default.golden | 3 +- ...cit-destinations-tproxy-default-bar.golden | 6 +- ...destinations-tproxy-default-default.golden | 6 +- ...mplicit-destinations-tproxy-foo-bar.golden | 6 +- ...cit-destinations-tproxy-foo-default.golden | 6 +- ...icit-destination-tproxy-default-bar.golden | 3 +- ...-destination-tproxy-default-default.golden | 3 +- ...implicit-destination-tproxy-foo-bar.golden | 3 +- ...icit-destination-tproxy-foo-default.golden | 3 +- ...ltiple-workloads-tproxy-default-bar.golden | 3 +- ...le-workloads-tproxy-default-default.golden | 3 +- ...h-multiple-workloads-tproxy-foo-bar.golden | 3 +- ...ltiple-workloads-tproxy-foo-default.golden | 3 +- api/config_entry_mesh.go | 8 + .../private/pbconfigentry/config_entry.gen.go | 2 + .../private/pbconfigentry/config_entry.pb.go | 3079 +++++++++-------- .../private/pbconfigentry/config_entry.proto | 1 + .../docs/connect/config-entries/mesh.mdx | 11 + 94 files changed, 2300 insertions(+), 1723 deletions(-) create mode 100644 .changelog/21587.txt create mode 100644 agent/xds/testdata/clusters/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden create mode 100644 agent/xds/testdata/endpoints/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden create mode 100644 agent/xds/testdata/listeners/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden create mode 100644 agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden create mode 100644 agent/xds/testdata/secrets/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden diff --git a/.changelog/21587.txt b/.changelog/21587.txt new file mode 100644 index 0000000000..f83db38c95 --- /dev/null +++ b/.changelog/21587.txt @@ -0,0 +1,3 @@ +```release-note:improvement +Use Envoy's default for a route's validate_clusters option, which is false. This fixes a case where non-existent clusters could cause a route to no longer route to any of its backends, including existing ones. +``` diff --git a/agent/structs/config_entry_mesh.go b/agent/structs/config_entry_mesh.go index c16cbf4243..210e82c87d 100644 --- a/agent/structs/config_entry_mesh.go +++ b/agent/structs/config_entry_mesh.go @@ -20,6 +20,14 @@ type MeshConfigEntry struct { // MutualTLSMode=permissive in either service-defaults or proxy-defaults. AllowEnablingPermissiveMutualTLS bool `json:",omitempty" alias:"allow_enabling_permissive_mutual_tls"` + // ValidateClusters controls whether the clusters the route table refers to are validated. The default value is + // false. When set to false and a route refers to a cluster that does not exist, the route table loads and routing + // to a non-existent cluster results in a 404. When set to true and the route is set to a cluster that do not exist, + // the route table will not load. For more information, refer to + // [HTTP route configuration in the Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto#envoy-v3-api-field-config-route-v3-routeconfiguration-validate-clusters) + // for more details. + ValidateClusters bool `json:",omitempty" alias:"validate_clusters"` + TLS *MeshTLSConfig `json:",omitempty"` HTTP *MeshHTTPConfig `json:",omitempty"` diff --git a/agent/xds/resources_test.go b/agent/xds/resources_test.go index 58cbdd727a..7a38a44b5e 100644 --- a/agent/xds/resources_test.go +++ b/agent/xds/resources_test.go @@ -623,6 +623,16 @@ func getConnectProxyDiscoChainTests(enterprise bool) []goldenTestCase { }, alsoRunTestForV2: true, }, + { + name: "connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + cfgSnap := proxycfg.TestConfigSnapshotDiscoveryChain(t, "chain-and-splitter", enterprise, nil, nil) + cfgSnap.ConnectProxy.MeshConfig = &structs.MeshConfigEntry{ + ValidateClusters: true, + } + return cfgSnap + }, + }, { name: "connect-proxy-with-grpc-router", create: func(t testinf.T) *proxycfg.ConfigSnapshot { diff --git a/agent/xds/routes.go b/agent/xds/routes.go index 41309b674e..a2ad845eb3 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -51,10 +51,19 @@ func (s *ResourceGenerator) routesFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) } } +func meshValidateClusters(cfgSnap *proxycfg.ConfigSnapshot) bool { + validate := false + if mesh := cfgSnap.MeshConfig(); mesh != nil { + validate = mesh.ValidateClusters + } + return validate +} + // routesFromSnapshotConnectProxy returns the xDS API representation of the // "routes" in the snapshot. func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { var resources []proto.Message + validateClusters := meshValidateClusters(cfgSnap) for uid, chain := range cfgSnap.ConnectProxy.DiscoveryChain { if chain.Default { continue @@ -76,10 +85,9 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh route := &envoy_route_v3.RouteConfiguration{ Name: uid.EnvoyID(), VirtualHosts: []*envoy_route_v3.VirtualHost{virtualHost}, - // 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), + } + if validateClusters { + route.ValidateClusters = response.MakeBoolValue(true) } resources = append(resources, route) } @@ -112,7 +120,7 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh } for routeName, clusters := range addressesMap { - routes, err := s.makeRoutesForAddresses(routeName, clusters) + routes, err := s.makeRoutesForAddresses(routeName, clusters, validateClusters) if err != nil { return nil, err } @@ -125,10 +133,10 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh return resources, nil } -func (s *ResourceGenerator) makeRoutesForAddresses(routeName string, addresses map[string]string) ([]proto.Message, error) { +func (s *ResourceGenerator) makeRoutesForAddresses(routeName string, addresses map[string]string, validateClusters bool) ([]proto.Message, error) { var resources []proto.Message - route, err := makeNamedAddressesRoute(routeName, addresses) + route, err := makeNamedAddressesRoute(routeName, addresses, validateClusters) if err != nil { s.Logger.Error("failed to make route", "cluster", "error", err) return nil, err @@ -223,7 +231,8 @@ func (s *ResourceGenerator) makeRoutes( if resolver.LoadBalancer != nil { lb = resolver.LoadBalancer } - route, err := makeNamedDefaultRouteWithLB(clusterName, lb, resolver.RequestTimeout, autoHostRewrite) + validateClusters := meshValidateClusters(cfgSnap) + route, err := makeNamedDefaultRouteWithLB(clusterName, lb, resolver.RequestTimeout, autoHostRewrite, validateClusters) if err != nil { s.Logger.Error("failed to make route", "cluster", clusterName, "error", err) return nil, err @@ -233,7 +242,7 @@ func (s *ResourceGenerator) makeRoutes( // If there is a service-resolver for this service then also setup routes for each subset for name := range resolver.Subsets { clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) - route, err := makeNamedDefaultRouteWithLB(clusterName, lb, resolver.RequestTimeout, autoHostRewrite) + route, err := makeNamedDefaultRouteWithLB(clusterName, lb, resolver.RequestTimeout, autoHostRewrite, validateClusters) if err != nil { s.Logger.Error("failed to make route", "cluster", clusterName, "error", err) return nil, err @@ -276,10 +285,9 @@ func (s *ResourceGenerator) routesForMeshGateway(cfgSnap *proxycfg.ConfigSnapsho route := &envoy_route_v3.RouteConfiguration{ Name: uid.EnvoyID(), VirtualHosts: []*envoy_route_v3.VirtualHost{virtualHost}, - // 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), + } + if meshValidateClusters(cfgSnap) { + route.ValidateClusters = response.MakeBoolValue(true) } resources = append(resources, route) } @@ -287,7 +295,7 @@ func (s *ResourceGenerator) routesForMeshGateway(cfgSnap *proxycfg.ConfigSnapsho return resources, nil } -func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer, timeout time.Duration, autoHostRewrite bool) (*envoy_route_v3.RouteConfiguration, error) { +func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer, timeout time.Duration, autoHostRewrite bool, validateClusters bool) (*envoy_route_v3.RouteConfiguration, error) { action := makeRouteActionFromName(clusterName) if err := injectLBToRouteAction(lb, action.Route); err != nil { @@ -305,7 +313,7 @@ func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer, t action.Route.Timeout = durationpb.New(timeout) } - return &envoy_route_v3.RouteConfiguration{ + route := &envoy_route_v3.RouteConfiguration{ Name: clusterName, VirtualHosts: []*envoy_route_v3.VirtualHost{ { @@ -319,20 +327,19 @@ 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), - }, nil + } + if validateClusters { + route.ValidateClusters = response.MakeBoolValue(true) + } + return route, nil } -func makeNamedAddressesRoute(routeName string, addresses map[string]string) (*envoy_route_v3.RouteConfiguration, error) { +func makeNamedAddressesRoute(routeName string, addresses map[string]string, validateClusters bool) (*envoy_route_v3.RouteConfiguration, error) { route := &envoy_route_v3.RouteConfiguration{ Name: routeName, - // 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), + } + if validateClusters { + route.ValidateClusters = response.MakeBoolValue(true) } for clusterName, address := range addresses { action := makeRouteActionFromName(clusterName) @@ -371,10 +378,10 @@ func (s *ResourceGenerator) routesForIngressGateway(cfgSnap *proxycfg.ConfigSnap // don't have custom filter chains and routes to this. defaultRoute := &envoy_route_v3.RouteConfiguration{ Name: listenerKey.RouteName(), - // 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 := meshValidateClusters(cfgSnap) + if validateClusters { + defaultRoute.ValidateClusters = response.MakeBoolValue(true) } for _, u := range upstreams { @@ -422,9 +429,11 @@ func (s *ResourceGenerator) routesForIngressGateway(cfgSnap *proxycfg.ConfigSnap defaultRoute.VirtualHosts = append(defaultRoute.VirtualHosts, virtualHost) } else { svcRoute := &envoy_route_v3.RouteConfiguration{ - Name: svcRouteName, - ValidateClusters: response.MakeBoolValue(true), - VirtualHosts: []*envoy_route_v3.VirtualHost{virtualHost}, + Name: svcRouteName, + VirtualHosts: []*envoy_route_v3.VirtualHost{virtualHost}, + } + if validateClusters { + svcRoute.ValidateClusters = response.MakeBoolValue(true) } result = append(result, svcRoute) } @@ -460,10 +469,10 @@ func (s *ResourceGenerator) routesForAPIGateway(cfgSnap *proxycfg.ConfigSnapshot listenerRoute := &envoy_route_v3.RouteConfiguration{ Name: readyListener.listenerKey.RouteName(), - // 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 := meshValidateClusters(cfgSnap) + if validateClusters { + listenerRoute.ValidateClusters = response.MakeBoolValue(true) } // Consolidate all routes for this listener into the minimum possible set based on hostname matching. 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 192eed0b6c..3888c533f2 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -27,7 +26,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -50,7 +48,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 5e25d5fdfa..de8175e81e 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 0f3440e32e..f91d4715d1 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 @@ -4,7 +4,6 @@ { "@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": [ { "domains": [ @@ -27,7 +26,6 @@ { "@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": [ { "domains": [ 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 50acae3b21..29ba8ff7c2 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 @@ -5,7 +5,6 @@ "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "mostSpecificHeaderMutationsWins": true, "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service.latest.golden index 095330c684..1b9284c991 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service.latest.golden @@ -22,8 +22,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden new file mode 100644 index 0000000000..930870b006 --- /dev/null +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden @@ -0,0 +1,289 @@ +{ + "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "altStatName": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "circuitBreakers": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "connectTimeout": "5s", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "big-side.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": { + "matchTypedSubjectAltNames": [ + { + "matcher": { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/big-side" + }, + "sanType": "URI" + } + ], + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\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": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + }, + "type": "EDS" + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "circuitBreakers": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "connectTimeout": "25s", + "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": { + "matchTypedSubjectAltNames": [ + { + "matcher": { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + }, + "sanType": "URI" + } + ], + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\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": { + "matchTypedSubjectAltNames": [ + { + "matcher": { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + }, + "sanType": "URI" + }, + { + "matcher": { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + }, + "sanType": "URI" + } + ], + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\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", + "altStatName": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "circuitBreakers": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "connectTimeout": "5s", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "goldilocks-side.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": { + "matchTypedSubjectAltNames": [ + { + "matcher": { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/goldilocks-side" + }, + "sanType": "URI" + } + ], + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\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": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + }, + "type": "EDS" + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "altStatName": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "circuitBreakers": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "connectTimeout": "5s", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "name": "lil-bit-side.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": { + "matchTypedSubjectAltNames": [ + { + "matcher": { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/lil-bit-side" + }, + "sanType": "URI" + } + ], + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\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": "lil-bit-side.default.dc1.internal.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/endpoints/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden new file mode 100644 index 0000000000..b4372a3439 --- /dev/null +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden @@ -0,0 +1,75 @@ +{ + "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/listeners/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden new file mode 100644 index 0000000000..96c6814291 --- /dev/null +++ b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden @@ -0,0 +1,137 @@ +{ + "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.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": "db" + }, + "statPrefix": "upstream.db.default.default.dc1", + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "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.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/routes/api-gateway-http-listener-with-http-route.latest.golden b/agent/xds/testdata/routes/api-gateway-http-listener-with-http-route.latest.golden index 3409e2f0da..92e5c9dfe0 100644 --- a/agent/xds/testdata/routes/api-gateway-http-listener-with-http-route.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-http-listener-with-http-route.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden b/agent/xds/testdata/routes/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden index 9a3033d238..282058fc7d 100644 --- a/agent/xds/testdata/routes/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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-timeoutfilter-one-set.latest.golden index ac6f2a1c2e..f404529d1a 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-timeoutfilter-one-set.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 index 85dd47d993..6e9eb721b8 100644 --- a/agent/xds/testdata/routes/api-gateway-with-http-route.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-with-http-route.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 b268a5e5ac..bd70cabf2e 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 195aa3f77a..14558185b2 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 index 6d9d524203..2ff828f425 100644 --- a/agent/xds/testdata/routes/connect-proxy-resolver-with-lb.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-resolver-with-lb.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 index 3ab67ba8f2..dd7498471d 100644 --- 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden b/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden index 486f8021b8..bb98b73d0e 100644 --- a/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 5d8b1dd41e..9acc0918c9 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 3f590b178e..3456b42bf8 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden new file mode 100644 index 0000000000..fe5c69a399 --- /dev/null +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden @@ -0,0 +1,139 @@ +{ + "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "validateClusters": true, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "db", + "routes": [ + { + "match": { + "prefix": "/big-side" + }, + "route": { + "cluster": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "idleTimeout": "0s", + "timeout": "10s" + } + }, + { + "match": { + "prefix": "/lil-bit-side" + }, + "route": { + "cluster": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + }, + { + "match": { + "prefix": "/" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "requestHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "db" + } + } + ], + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "db" + } + } + ], + "weight": 100 + }, + { + "name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "requestHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "big" + } + } + ], + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "big" + } + } + ], + "weight": 9550 + }, + { + "name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "requestHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "goldilocks" + } + } + ], + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "goldilocks" + } + } + ], + "weight": 300 + }, + { + "name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "requestHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "small" + } + } + ], + "responseHeadersToAdd": [ + { + "appendAction": "OVERWRITE_IF_EXISTS_OR_ADD", + "header": { + "key": "x-split-leg", + "value": "small" + } + } + ], + "weight": 50 + } + ] + } + } + } + ] + } + ] + } + ], + "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-splitter.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.latest.golden index fe5c69a399..5ff17ff047 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/connect-proxy-with-grpc-chain.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-grpc-chain.latest.golden index 9a73db46e0..5440895b8e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-grpc-chain.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-grpc-chain.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 474ac19cd7..5ba0bfe348 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/connect-proxy-with-http-chain.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-http-chain.latest.golden index 9a73db46e0..5440895b8e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-http-chain.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-http-chain.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/connect-proxy-with-http2-chain.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-http2-chain.latest.golden index 9a73db46e0..5440895b8e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-http2-chain.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-http2-chain.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 41c70e3de1..cdb43b252c 100644 --- a/agent/xds/testdata/routes/ingress-grpc-multiple-services.latest.golden +++ b/agent/xds/testdata/routes/ingress-grpc-multiple-services.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 a15b997a8f..a461171d21 100644 --- a/agent/xds/testdata/routes/ingress-http-multiple-services.latest.golden +++ b/agent/xds/testdata/routes/ingress-http-multiple-services.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "443", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -45,7 +44,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 71f6e9893f..53a49ce05f 100644 --- a/agent/xds/testdata/routes/ingress-lb-in-resolver.latest.golden +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-multiple-listeners-duplicate-service.latest.golden b/agent/xds/testdata/routes/ingress-multiple-listeners-duplicate-service.latest.golden index cb29b2bdab..413e4ac227 100644 --- a/agent/xds/testdata/routes/ingress-multiple-listeners-duplicate-service.latest.golden +++ b/agent/xds/testdata/routes/ingress-multiple-listeners-duplicate-service.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "443", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 d3a2ea2219..219dfac078 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 25fa94d0f3..4bf0ec2a3d 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 ba8f0fa73d..d0eca099f4 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 6d9c31be1c..295bc827bf 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 25afe4ee6d..f3ab8fee7e 100644 --- a/agent/xds/testdata/routes/ingress-with-grpc-router.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-grpc-router.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-grpc-single-tls-listener.latest.golden b/agent/xds/testdata/routes/ingress-with-grpc-single-tls-listener.latest.golden index a5fd13c151..18c50d1c89 100644 --- a/agent/xds/testdata/routes/ingress-with-grpc-single-tls-listener.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-grpc-single-tls-listener.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden b/agent/xds/testdata/routes/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden index a5fd13c151..18c50d1c89 100644 --- a/agent/xds/testdata/routes/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-http2-single-tls-listener.latest.golden b/agent/xds/testdata/routes/ingress-with-http2-single-tls-listener.latest.golden index a5fd13c151..18c50d1c89 100644 --- a/agent/xds/testdata/routes/ingress-with-http2-single-tls-listener.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-http2-single-tls-listener.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-sds-listener+service-level.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-listener+service-level.latest.golden index de35eeddfd..96c1f714da 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-listener+service-level.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-listener+service-level.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080_s1", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-sds-listener-gw-level-http.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-listener-gw-level-http.latest.golden index 70dcd59106..a7b6e583c4 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-listener-gw-level-http.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-listener-gw-level-http.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 cf218b1c95..ddf8aed433 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9191", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 350f1605f6..12dc9cc93c 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9191", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-sds-service-level-2.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-service-level-2.latest.golden index 48d9d7b774..358936f270 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-service-level-2.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-service-level-2.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9191_foo", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -29,7 +28,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9191_web", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-no-tls.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-no-tls.latest.golden index de35eeddfd..96c1f714da 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-no-tls.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-no-tls.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080_s1", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 8cd0610d70..590fd05c62 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9191", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -29,7 +28,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9191_web", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 be0cb1f2a4..a6edbbfca1 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080_s1", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080_s2", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-single-tls-listener.latest.golden b/agent/xds/testdata/routes/ingress-with-single-tls-listener.latest.golden index a5fd13c151..18c50d1c89 100644 --- a/agent/xds/testdata/routes/ingress-with-single-tls-listener.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-single-tls-listener.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden b/agent/xds/testdata/routes/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden index 8dd74e7de7..ed40b5faab 100644 --- a/agent/xds/testdata/routes/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8082", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -76,7 +73,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8083", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -100,7 +96,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8084", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden b/agent/xds/testdata/routes/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden index a5fd13c151..18c50d1c89 100644 --- a/agent/xds/testdata/routes/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-tls-mixed-listeners.latest.golden b/agent/xds/testdata/routes/ingress-with-tls-mixed-listeners.latest.golden index 78f110c770..866fc179e6 100644 --- a/agent/xds/testdata/routes/ingress-with-tls-mixed-listeners.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-tls-mixed-listeners.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "9090", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-tls-mixed-max-version-listeners.latest.golden b/agent/xds/testdata/routes/ingress-with-tls-mixed-max-version-listeners.latest.golden index 977c827264..f295797b3d 100644 --- a/agent/xds/testdata/routes/ingress-with-tls-mixed-max-version-listeners.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-tls-mixed-max-version-listeners.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8082", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/ingress-with-tls-mixed-min-version-listeners.latest.golden b/agent/xds/testdata/routes/ingress-with-tls-mixed-min-version-listeners.latest.golden index 977c827264..f295797b3d 100644 --- a/agent/xds/testdata/routes/ingress-with-tls-mixed-min-version-listeners.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-tls-mixed-min-version-listeners.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8081", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8082", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 74385c3103..9f4796ed05 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 4737a59e31..96bd040bf9 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 @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "bar", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -27,7 +26,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "foo", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -50,7 +48,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "gir", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 40722e65ce..7684d14c97 100644 --- a/agent/xds/testdata/routes/splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/routes/splitter-with-resolver-redirect.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/terminating-gateway-hostname-service-subsets.latest.golden b/agent/xds/testdata/routes/terminating-gateway-hostname-service-subsets.latest.golden index f05a3fc603..d30d528f00 100644 --- a/agent/xds/testdata/routes/terminating-gateway-hostname-service-subsets.latest.golden +++ b/agent/xds/testdata/routes/terminating-gateway-hostname-service-subsets.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -76,7 +73,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/terminating-gateway-ignore-extra-resolvers.latest.golden b/agent/xds/testdata/routes/terminating-gateway-ignore-extra-resolvers.latest.golden index fa5dbf99a4..e0fae21af9 100644 --- a/agent/xds/testdata/routes/terminating-gateway-ignore-extra-resolvers.latest.golden +++ b/agent/xds/testdata/routes/terminating-gateway-ignore-extra-resolvers.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config-no-hash-policies.latest.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config-no-hash-policies.latest.golden index 39689dc5b2..33c3081ecf 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config-no-hash-policies.latest.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config-no-hash-policies.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -29,7 +28,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -54,7 +52,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 1e7cdde138..1115f38e8f 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.latest.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -48,7 +47,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -92,7 +90,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/terminating-gateway-service-subsets.latest.golden b/agent/xds/testdata/routes/terminating-gateway-service-subsets.latest.golden index fa5dbf99a4..e0fae21af9 100644 --- a/agent/xds/testdata/routes/terminating-gateway-service-subsets.latest.golden +++ b/agent/xds/testdata/routes/terminating-gateway-service-subsets.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ 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 0f3440e32e..f91d4715d1 100644 --- a/agent/xds/testdata/routes/transparent-proxy-destination-http.latest.golden +++ b/agent/xds/testdata/routes/transparent-proxy-destination-http.latest.golden @@ -4,7 +4,6 @@ { "@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": [ { "domains": [ @@ -27,7 +26,6 @@ { "@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": [ { "domains": [ 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 14ac8198ff..25897fa65e 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 @@ -4,7 +4,6 @@ { "@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": [ { "domains": [ @@ -27,7 +26,6 @@ { "@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": [ { "domains": [ diff --git a/agent/xds/testdata/routes/xds-fetch-timeout-ms-ingress-with-router.latest.golden b/agent/xds/testdata/routes/xds-fetch-timeout-ms-ingress-with-router.latest.golden index ba8f0fa73d..d0eca099f4 100644 --- a/agent/xds/testdata/routes/xds-fetch-timeout-ms-ingress-with-router.latest.golden +++ b/agent/xds/testdata/routes/xds-fetch-timeout-ms-ingress-with-router.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/xds-fetch-timeout-ms-mgw-peering.latest.golden b/agent/xds/testdata/routes/xds-fetch-timeout-ms-mgw-peering.latest.golden index 4737a59e31..96bd040bf9 100644 --- a/agent/xds/testdata/routes/xds-fetch-timeout-ms-mgw-peering.latest.golden +++ b/agent/xds/testdata/routes/xds-fetch-timeout-ms-mgw-peering.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "bar", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -27,7 +26,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "foo", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -50,7 +48,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "gir", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/xds-fetch-timeout-ms-sidecar.latest.golden b/agent/xds/testdata/routes/xds-fetch-timeout-ms-sidecar.latest.golden index 3f590b178e..3456b42bf8 100644 --- a/agent/xds/testdata/routes/xds-fetch-timeout-ms-sidecar.latest.golden +++ b/agent/xds/testdata/routes/xds-fetch-timeout-ms-sidecar.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/xds-fetch-timeout-ms-term-gw.latest.golden b/agent/xds/testdata/routes/xds-fetch-timeout-ms-term-gw.latest.golden index fa5dbf99a4..e0fae21af9 100644 --- a/agent/xds/testdata/routes/xds-fetch-timeout-ms-term-gw.latest.golden +++ b/agent/xds/testdata/routes/xds-fetch-timeout-ms-term-gw.latest.golden @@ -4,7 +4,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -28,7 +27,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ @@ -52,7 +50,6 @@ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { "domains": [ diff --git a/agent/xds/testdata/routes/xds-fetch-timeout-ms-tproxy-passthrough.latest.golden b/agent/xds/testdata/routes/xds-fetch-timeout-ms-tproxy-passthrough.latest.golden index 0f3440e32e..f91d4715d1 100644 --- a/agent/xds/testdata/routes/xds-fetch-timeout-ms-tproxy-passthrough.latest.golden +++ b/agent/xds/testdata/routes/xds-fetch-timeout-ms-tproxy-passthrough.latest.golden @@ -4,7 +4,6 @@ { "@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": [ { "domains": [ @@ -27,7 +26,6 @@ { "@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": [ { "domains": [ diff --git a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden new file mode 100644 index 0000000000..82e4565065 --- /dev/null +++ b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-splitter-and-mesh-validate-clusters.latest.golden @@ -0,0 +1,5 @@ +{ + "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/xds_protocol_helpers_test.go b/agent/xds/xds_protocol_helpers_test.go index c2cd4e6e50..ac1ec14594 100644 --- a/agent/xds/xds_protocol_helpers_test.go +++ b/agent/xds/xds_protocol_helpers_test.go @@ -798,8 +798,7 @@ func makeTestRoute(t *testing.T, fixtureName string) *envoy_route_v3.RouteConfig switch fixtureName { case "http2:db", "http:db": return &envoy_route_v3.RouteConfiguration{ - Name: "db", - ValidateClusters: response.MakeBoolValue(true), + Name: "db", VirtualHosts: []*envoy_route_v3.VirtualHost{ { Name: "db", diff --git a/agent/xdsv2/route_resources.go b/agent/xdsv2/route_resources.go index d2b106f3b6..90de1b0cb9 100644 --- a/agent/xdsv2/route_resources.go +++ b/agent/xdsv2/route_resources.go @@ -35,10 +35,6 @@ func (pr *ProxyResources) makeEnvoyRoute(name string) (*envoy_route_v3.RouteConf 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() { diff --git a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-bar.golden b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-bar.golden index 0f219c7321..258acc5be1 100644 --- a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-bar.golden @@ -58,8 +58,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-default.golden b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-default.golden index 01c1151dd9..8b81dfe58e 100644 --- a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-default.golden +++ b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-default.golden @@ -58,8 +58,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-bar.golden b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-bar.golden index 2a5dfa6d98..f496774ab0 100644 --- a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-bar.golden @@ -58,8 +58,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-default.golden b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-default.golden index 2013c631ab..f6b0d792d6 100644 --- a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-default.golden +++ b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-default.golden @@ -58,8 +58,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden index 966ba94181..cbc19abec0 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", @@ -44,8 +43,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden index 36b5a1dc96..344c55a548 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", @@ -44,8 +43,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden index c506d6f03f..711493e27b 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", @@ -44,8 +43,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden index c768c7787d..c9d3543867 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", @@ -44,8 +43,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden index c8c28c4395..a941adbdd6 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden index b9dfecfe03..d35ec34d7e 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden index e10da7d0ee..9f6e9f785f 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden index 9196875e82..f241c36db5 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden index c8c28c4395..a941adbdd6 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden index b9dfecfe03..d35ec34d7e 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden index e10da7d0ee..9f6e9f785f 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden index 9196875e82..f241c36db5 100644 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden @@ -21,8 +21,7 @@ } ] } - ], - "validateClusters": true + ] } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", diff --git a/api/config_entry_mesh.go b/api/config_entry_mesh.go index 1a1ebb8b53..e035d15967 100644 --- a/api/config_entry_mesh.go +++ b/api/config_entry_mesh.go @@ -26,6 +26,14 @@ type MeshConfigEntry struct { // MutualTLSMode=permissive in either service-defaults or proxy-defaults. AllowEnablingPermissiveMutualTLS bool `json:",omitempty" alias:"allow_enabling_permissive_mutual_tls"` + // ValidateClusters controls whether the clusters the route table refers to are validated. The default value is + // false. When set to false and a route refers to a cluster that does not exist, the route table loads and routing + // to a non-existent cluster results in a 404. When set to true and the route is set to a cluster that do not exist, + // the route table will not load. For more information, refer to + // [HTTP route configuration in the Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto#envoy-v3-api-field-config-route-v3-routeconfiguration-validate-clusters) + // for more details. + ValidateClusters bool `json:",omitempty" alias:"validate_clusters"` + TLS *MeshTLSConfig `json:",omitempty"` HTTP *MeshHTTPConfig `json:",omitempty"` diff --git a/proto/private/pbconfigentry/config_entry.gen.go b/proto/private/pbconfigentry/config_entry.gen.go index 6be789d791..0793a503d2 100644 --- a/proto/private/pbconfigentry/config_entry.gen.go +++ b/proto/private/pbconfigentry/config_entry.gen.go @@ -1710,6 +1710,7 @@ func MeshConfigToStructs(s *MeshConfig, t *structs.MeshConfigEntry) { TransparentProxyMeshConfigToStructs(s.TransparentProxy, &t.TransparentProxy) } t.AllowEnablingPermissiveMutualTLS = s.AllowEnablingPermissiveMutualTLS + t.ValidateClusters = s.ValidateClusters if s.TLS != nil { var x structs.MeshTLSConfig MeshTLSConfigToStructs(s.TLS, &x) @@ -1738,6 +1739,7 @@ func MeshConfigFromStructs(t *structs.MeshConfigEntry, s *MeshConfig) { s.TransparentProxy = &x } s.AllowEnablingPermissiveMutualTLS = t.AllowEnablingPermissiveMutualTLS + s.ValidateClusters = t.ValidateClusters if t.TLS != nil { var x MeshTLSConfig MeshTLSConfigFromStructs(t.TLS, &x) diff --git a/proto/private/pbconfigentry/config_entry.pb.go b/proto/private/pbconfigentry/config_entry.pb.go index 2ff1f82b5f..7bdb0c0303 100644 --- a/proto/private/pbconfigentry/config_entry.pb.go +++ b/proto/private/pbconfigentry/config_entry.pb.go @@ -1131,6 +1131,7 @@ type MeshConfig struct { Peering *PeeringMeshConfig `protobuf:"bytes,5,opt,name=Peering,proto3" json:"Peering,omitempty"` AllowEnablingPermissiveMutualTLS bool `protobuf:"varint,6,opt,name=AllowEnablingPermissiveMutualTLS,proto3" json:"AllowEnablingPermissiveMutualTLS,omitempty"` Hash uint64 `protobuf:"varint,7,opt,name=Hash,proto3" json:"Hash,omitempty"` + ValidateClusters bool `protobuf:"varint,8,opt,name=ValidateClusters,proto3" json:"ValidateClusters,omitempty"` } func (x *MeshConfig) Reset() { @@ -1214,6 +1215,13 @@ func (x *MeshConfig) GetHash() uint64 { return 0 } +func (x *MeshConfig) GetValidateClusters() bool { + if x != nil { + return x.ValidateClusters + } + return false +} + // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.TransparentProxyMeshConfig @@ -8557,7 +8565,7 @@ var file_private_pbconfigentry_config_entry_proto_rawDesc = []byte{ 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x15, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x07, 0x0a, 0x05, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xcc, 0x04, 0x0a, 0x0a, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xf8, 0x04, 0x0a, 0x0a, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x6d, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, @@ -8590,1584 +8598,1587 @@ var file_private_pbconfigentry_config_entry_proto_rawDesc = []byte{ 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0x50, 0x0a, 0x1a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x32, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x14, 0x4d, 0x65, 0x73, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0xc9, 0x01, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x68, 0x54, - 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5b, 0x0a, 0x08, 0x49, 0x6e, 0x63, 0x6f, - 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 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, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x49, 0x6e, 0x63, - 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x5b, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, - 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, 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, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x54, - 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, - 0x6e, 0x67, 0x22, 0x8a, 0x01, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x68, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x24, 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x61, 0x78, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, - 0x53, 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, 0x03, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, - 0x54, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x68, 0x48, 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x42, 0x0a, 0x1c, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x58, 0x46, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, - 0x65, 0x58, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x43, 0x65, 0x72, 0x74, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, - 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x17, 0x50, 0x65, - 0x65, 0x72, 0x54, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x50, 0x65, 0x65, - 0x72, 0x54, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x73, 0x22, 0xcd, 0x08, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, 0x5d, - 0x0a, 0x07, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x73, 0x18, 0x02, 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, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x73, 0x12, 0x5a, 0x0a, - 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 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, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x52, - 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x60, 0x0a, 0x08, 0x46, 0x61, 0x69, - 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x76, 0x65, 0x72, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x08, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 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, 0x0e, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x57, - 0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 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, 0x61, - 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x42, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, - 0x07, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x41, 0x0a, - 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 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, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x12, 0x7e, 0x0a, 0x14, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x42, 0x79, - 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, - 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, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, - 0x42, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x14, 0x50, 0x72, 0x69, 0x6f, - 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, - 0x48, 0x61, 0x73, 0x68, 0x1a, 0x78, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x73, 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, 0x52, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 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, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, - 0x73, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x7b, - 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 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, 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, 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, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 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, 0x51, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x4f, 0x6e, 0x6c, 0x79, 0x50, 0x61, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4f, 0x6e, 0x6c, 0x79, - 0x50, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x22, 0xef, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, - 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, - 0x73, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x1e, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, - 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, - 0x65, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, - 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xfd, 0x02, 0x0a, 0x17, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, - 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, - 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x5e, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, - 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x5c, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, - 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, - 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x4d, 0x0a, 0x1d, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, - 0x6f, 0x76, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4d, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x07, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x39, 0x0a, 0x23, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6f, 0x72, - 0x69, 0x74, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, - 0x12, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4d, - 0x6f, 0x64, 0x65, 0x22, 0xcf, 0x01, 0x0a, 0x1d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, - 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, - 0x72, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x50, 0x65, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x5d, - 0x0a, 0x0e, 0x52, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 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, 0x52, - 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x52, - 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69, 0x0a, - 0x12, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 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, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x12, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x55, 0x0a, 0x0c, 0x48, 0x61, 0x73, 0x68, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x04, 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, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x52, 0x0c, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, - 0x64, 0x0a, 0x0e, 0x52, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, - 0x53, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x4d, 0x69, 0x6e, 0x69, - 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4d, - 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, - 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x36, 0x0a, 0x12, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x43, - 0x68, 0x6f, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0b, 0x43, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd3, 0x01, - 0x0a, 0x0a, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x57, 0x0a, 0x0c, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 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, 0x6f, 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x43, - 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x50, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x50, 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x65, 0x72, 0x6d, 0x69, - 0x6e, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x54, 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, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, - 0x03, 0x54, 0x54, 0x4c, 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, 0x54, 0x54, 0x4c, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, - 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x22, 0xac, - 0x03, 0x0a, 0x0e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x12, 0x49, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x18, 0x01, 0x20, 0x01, 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, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, - 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x54, 0x0a, 0x09, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x73, 0x12, 0x53, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x3f, 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, 0x67, 0x72, 0x65, 0x73, 0x73, - 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, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 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, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, - 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, - 0x48, 0x61, 0x73, 0x68, 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, 0x8f, 0x02, - 0x0a, 0x14, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 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, 0x0d, 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, 0x0d, 0x52, 0x15, 0x4d, - 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 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, 0x04, 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, 0x22, - 0xea, 0x01, 0x0a, 0x10, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x4c, - 0x0a, 0x03, 0x53, 0x44, 0x53, 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, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x53, 0x44, - 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x53, 0x44, 0x53, 0x12, 0x24, 0x0a, 0x0d, - 0x54, 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, 0x53, 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, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, - 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x13, - 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x53, 0x44, 0x53, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x65, 0x72, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x0f, 0x49, 0x6e, - 0x67, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, - 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x6f, 0x72, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x51, 0x0a, - 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x12, 0x49, 0x0a, 0x03, 0x54, 0x4c, 0x53, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x22, 0xb7, 0x06, 0x0a, 0x0e, - 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 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, 0x14, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x18, - 0x03, 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, 0x47, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x4c, 0x53, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x62, 0x0a, 0x0e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 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, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x64, - 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 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, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x73, 0x52, 0x0f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x12, 0x53, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0x07, 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, 0x26, 0x0a, 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 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, 0x09, 0x20, 0x01, 0x28, 0x0d, 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, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x4d, 0x61, 0x78, 0x43, - 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 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, 0x0b, 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, 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, 0x67, 0x0a, 0x17, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x4c, 0x0a, 0x03, 0x53, 0x44, 0x53, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, - 0x53, 0x44, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x53, 0x44, 0x53, 0x22, 0xcb, - 0x02, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0x55, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x18, 0x01, 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, 0x48, 0x54, 0x54, 0x50, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x2e, - 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x41, 0x64, 0x64, 0x12, 0x55, 0x0a, - 0x03, 0x53, 0x65, 0x74, 0x18, 0x02, 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, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x03, 0x53, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 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, 0xdc, 0x02, 0x0a, - 0x11, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x07, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 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, 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, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x50, 0x0a, 0x03, - 0x4a, 0x57, 0x54, 0x18, 0x03, 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, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x03, 0x4a, 0x57, 0x54, 0x12, 0x12, - 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, - 0x73, 0x68, 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, 0x17, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x59, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x73, 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, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x73, 0x22, 0x94, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 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, 0x68, - 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x74, - 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 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, 0x49, 0x0a, 0x1d, 0x49, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x69, 0x6f, 0x6e, 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, 0xcc, 0x06, 0x0a, 0x0f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x41, - 0x63, 0x74, 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, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x0b, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x65, - 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, - 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x65, 0x67, - 0x61, 0x63, 0x79, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4c, 0x65, 0x67, - 0x61, 0x63, 0x79, 0x49, 0x44, 0x12, 0x4e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 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, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x66, 0x0a, 0x0a, 0x4c, 0x65, 0x67, 0x61, 0x63, - 0x79, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 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, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0a, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x12, - 0x46, 0x0a, 0x10, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x69, 0x6d, 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, 0x10, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x4c, 0x65, 0x67, 0x61, 0x63, - 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0a, 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, 0x10, 0x4c, - 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, - 0x61, 0x18, 0x0b, 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, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, - 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x24, 0x0a, - 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x1a, 0x3d, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 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, 0x8b, 0x02, 0x0a, 0x13, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x41, 0x63, - 0x74, 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, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x04, 0x48, 0x54, - 0x54, 0x50, 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, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x48, 0x54, 0x54, 0x50, 0x12, 0x50, - 0x0a, 0x03, 0x4a, 0x57, 0x54, 0x18, 0x03, 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, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x03, 0x4a, 0x57, 0x54, - 0x22, 0xed, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, - 0x54, 0x50, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 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, 0x5c, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x06, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, - 0x22, 0xc1, 0x01, 0x0a, 0x1d, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, - 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x45, 0x78, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x45, 0x78, 0x61, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x16, - 0x0a, 0x06, 0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 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, 0xf9, 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, 0x01, - 0x28, 0x0e, 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, 0x50, 0x72, 0x6f, 0x78, 0x79, - 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x5a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 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, 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, 0x4b, 0x0a, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x73, 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, 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, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x4e, 0x49, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x4e, 0x49, - 0x12, 0x64, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x07, 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, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5a, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 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, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x15, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x15, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4c, 0x6f, 0x63, 0x61, - 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, - 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x34, - 0x0a, 0x15, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x4c, - 0x6f, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x4d, 0x73, 0x12, 0x3c, 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, + 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, 0x10, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6c, 0x75, 0x73, 0x74, 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, 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, + 0x22, 0x50, 0x0a, 0x1a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, + 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x4d, 0x65, + 0x73, 0x68, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x6e, + 0x6c, 0x79, 0x22, 0xc9, 0x01, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x4c, 0x53, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5b, 0x0a, 0x08, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 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, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x4c, + 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, + 0x67, 0x12, 0x5b, 0x0a, 0x08, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 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, 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, + 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x22, 0x8a, + 0x01, 0x0a, 0x18, 0x4d, 0x65, 0x73, 0x68, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x54, + 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, 0x53, 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, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x43, + 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x0e, 0x4d, + 0x65, 0x73, 0x68, 0x48, 0x54, 0x54, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, + 0x1c, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x58, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x1c, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x58, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, + 0x74, 0x22, 0x4d, 0x0a, 0x11, 0x50, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x68, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x17, 0x50, 0x65, 0x65, 0x72, 0x54, 0x68, + 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x50, 0x65, 0x65, 0x72, 0x54, 0x68, 0x72, + 0x6f, 0x75, 0x67, 0x68, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, + 0x22, 0xcd, 0x08, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, + 0x75, 0x62, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x44, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, 0x5d, 0x0a, 0x07, 0x53, 0x75, + 0x62, 0x73, 0x65, 0x74, 0x73, 0x18, 0x02, 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, 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, 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, + 0x74, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x72, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x07, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x73, 0x12, 0x5a, 0x0a, 0x08, 0x52, 0x65, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 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, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x52, 0x08, 0x52, 0x65, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x60, 0x0a, 0x08, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2e, + 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x46, + 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 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, 0xca, 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, + 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, 0x12, 0x57, 0x0a, 0x0c, 0x4c, 0x6f, + 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x33, 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, 0x61, 0x64, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x07, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x0e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 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, 0x0e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x7e, 0x0a, 0x14, + 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x04, 0x48, 0x61, 0x73, 0x68, 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, + 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, + 0x65, 0x72, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x42, 0x79, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x14, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, + 0x7a, 0x65, 0x42, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, + 0x1a, 0x78, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x73, 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, 0x52, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 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, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x7b, 0x0a, 0x0d, 0x46, 0x61, + 0x69, 0x6c, 0x6f, 0x76, 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, 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, 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, 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, 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, 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, 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, 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, 0xf1, - 0x03, 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, 0x12, 0x60, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0x1a, 0x7b, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x65, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4a, 0x0a, - 0x03, 0x52, 0x65, 0x66, 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, 0x03, 0x52, 0x65, 0x66, 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, - 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, 0x82, 0x02, 0x0a, 0x15, 0x46, 0x69, - 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x5a, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x46, 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, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0xfa, - 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, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 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, 0x51, 0x0a, 0x15, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x4f, 0x6e, 0x6c, 0x79, 0x50, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4f, 0x6e, 0x6c, 0x79, 0x50, 0x61, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x22, 0xef, 0x01, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x44, + 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x50, + 0x65, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, + 0x24, 0x0a, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xfd, 0x02, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x5e, 0x0a, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x44, 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, 0x12, 0x12, - 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, - 0x73, 0x68, 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, 0xad, 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, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, + 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x73, 0x12, 0x5c, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x44, 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, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, + 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x24, 0x0a, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x4d, 0x0a, 0x1d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x52, 0x65, 0x67, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x39, 0x0a, 0x23, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, + 0x65, 0x42, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4d, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x22, + 0xcf, 0x01, 0x0a, 0x1d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x73, 0x65, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x44, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, + 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x5d, 0x0a, 0x0e, 0x52, 0x69, + 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x52, 0x69, 0x6e, 0x67, 0x48, + 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x52, 0x69, 0x6e, 0x67, 0x48, + 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69, 0x0a, 0x12, 0x4c, 0x65, 0x61, + 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x65, + 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x12, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x55, 0x0a, 0x0c, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x18, 0x04, 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, 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, 0x12, 0x12, - 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, - 0x73, 0x68, 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, 0x68, 0x61, + 0x72, 0x79, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0c, 0x48, + 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0e, 0x52, + 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x28, 0x0a, + 0x0f, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, + 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x4d, 0x61, 0x78, 0x69, 0x6d, + 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0f, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, + 0x65, 0x22, 0x36, 0x0a, 0x12, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x68, 0x6f, 0x69, 0x63, + 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x43, 0x68, + 0x6f, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x0a, 0x48, 0x61, + 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1e, + 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x57, + 0x0a, 0x0c, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 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, 0x6f, + 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x43, 0x6f, 0x6f, 0x6b, 0x69, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x50, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x50, 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x54, 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, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x03, 0x54, 0x54, 0x4c, + 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, 0x54, 0x54, 0x4c, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x22, 0xac, 0x03, 0x0a, 0x0e, 0x49, + 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x49, 0x0a, + 0x03, 0x54, 0x4c, 0x53, 0x18, 0x01, 0x20, 0x01, 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, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x54, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 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, 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, 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, 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, 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, + 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x52, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x53, + 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 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, 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, 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, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 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, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, + 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, 0x8f, 0x02, 0x0a, 0x14, 0x49, 0x6e, + 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 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, 0x0d, 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, 0x0d, 0x52, 0x15, 0x4d, 0x61, 0x78, 0x43, 0x6f, + 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 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, 0x04, 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, 0x22, 0xea, 0x01, 0x0a, 0x10, + 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x18, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x03, 0x53, 0x44, + 0x53, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, + 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x53, 0x44, 0x53, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x03, 0x53, 0x44, 0x53, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x4d, + 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, + 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x4d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x4c, 0x53, 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, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x69, 0x70, 0x68, + 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x13, 0x47, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x53, 0x44, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x20, 0x0a, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x51, 0x0a, 0x08, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 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, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x03, + 0x54, 0x4c, 0x53, 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, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x22, 0xb7, 0x06, 0x0a, 0x0e, 0x49, 0x6e, 0x67, 0x72, + 0x65, 0x73, 0x73, 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, 0x14, + 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x48, + 0x6f, 0x73, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x18, 0x03, 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, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x62, 0x0a, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x48, 0x65, 0x61, 0x64, 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, 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, + 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x64, 0x0a, 0x0f, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 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, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, + 0x0f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x12, 0x53, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0x07, 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, + 0x26, 0x0a, 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 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, 0x09, 0x20, + 0x01, 0x28, 0x0d, 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, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 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, 0x0b, 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, 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, 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, + 0x01, 0x22, 0x67, 0x0a, 0x17, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4c, 0x0a, 0x03, + 0x53, 0x44, 0x53, 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, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x53, 0x44, 0x53, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x53, 0x44, 0x53, 0x22, 0xcb, 0x02, 0x0a, 0x13, 0x48, + 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x73, 0x12, 0x55, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x18, 0x01, 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, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x41, 0x64, 0x64, 0x12, 0x55, 0x0a, 0x03, 0x53, 0x65, 0x74, + 0x18, 0x02, 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, 0x48, + 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x73, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x53, 0x65, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 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, 0xdc, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, + 0x0a, 0x07, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x56, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 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, 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, + 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x50, 0x0a, 0x03, 0x4a, 0x57, 0x54, 0x18, + 0x03, 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, + 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x03, 0x4a, 0x57, 0x54, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, + 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0x17, 0x49, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x59, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 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, 0x49, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x94, 0x01, + 0x0a, 0x14, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 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, 0x68, 0x0a, 0x0c, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x44, 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, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 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, 0x49, 0x0a, 0x1d, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 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, + 0xcc, 0x06, 0x0a, 0x0f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x41, 0x63, 0x74, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 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, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x50, 0x72, 0x65, 0x63, 0x65, + 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x49, + 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x49, + 0x44, 0x12, 0x4e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x06, 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, 0x6e, 0x66, + 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x66, 0x0a, 0x0a, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4d, 0x65, 0x74, + 0x61, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 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, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x0a, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x46, 0x0a, 0x10, 0x4c, + 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 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, 0x10, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x0a, 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, 0x10, 0x4c, 0x65, 0x67, 0x61, 0x63, + 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x45, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x0b, 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, 0x90, 0x03, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x04, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x61, 0x6d, + 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x1a, + 0x3d, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 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, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8b, + 0x02, 0x0a, 0x13, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x41, 0x63, 0x74, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x48, 0x54, 0x54, 0x50, 0x12, 0x50, 0x0a, 0x03, 0x4a, 0x57, + 0x54, 0x18, 0x03, 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, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x03, 0x4a, 0x57, 0x54, 0x22, 0xed, 0x01, 0x0a, + 0x17, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 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, 0x5c, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x22, 0xc1, 0x01, 0x0a, + 0x1d, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x45, 0x78, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x78, 0x61, + 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x75, + 0x66, 0x66, 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 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, 0xf9, 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, 0x01, 0x28, 0x0e, 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, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, + 0x52, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x12, 0x5a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 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, 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, 0x4b, 0x0a, + 0x06, 0x45, 0x78, 0x70, 0x6f, 0x73, 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, 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, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x06, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x4e, 0x49, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x53, 0x4e, 0x49, 0x12, 0x64, 0x0a, 0x0e, + 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, + 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, 0x55, 0x70, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x5a, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x08, 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, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x0b, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, + 0x0a, 0x15, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x4d, + 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x15, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x4d, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, 0x4c, 0x6f, 0x63, 0x61, 0x6c, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, + 0x12, 0x3c, 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, 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, 0x12, + 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, + 0x61, 0x73, 0x68, 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, 0x22, 0xc8, 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0xf1, - 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, + 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, 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, + 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, - 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, + 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, 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, 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, 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, 0x22, - 0x80, 0x03, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 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, 0x55, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 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, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, - 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x5a, 0x0a, - 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 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, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 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, 0xaa, 0x01, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 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, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x5d, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3f, 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, - 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x22, - 0x72, 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, 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, 0x12, 0x24, 0x0a, - 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x2a, 0xe2, 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, 0x12, - 0x18, 0x0a, 0x14, 0x4b, 0x69, 0x6e, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x10, 0x0d, 0x12, 0x1d, 0x0a, 0x19, 0x4b, 0x69, 0x6e, - 0x64, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x10, 0x0e, 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, 0x32, 0xd5, 0x01, 0x0a, - 0x12, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0xbe, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x76, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x49, 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, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x4a, - 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, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, - 0x08, 0x02, 0x10, 0x0c, 0x42, 0xae, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, + 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, 0xca, 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, 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, + 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, 0x12, 0x12, 0x0a, + 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, + 0x68, 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, 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, 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, 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, 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, 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, 0xf1, 0x03, 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, 0x12, 0x60, 0x0a, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x44, 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, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0x1a, 0x7b, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4f, 0x66, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x65, + 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x66, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x03, 0x52, 0x65, 0x66, + 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, 0x03, 0x52, 0x65, 0x66, 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, 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, 0x82, 0x02, 0x0a, 0x15, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, + 0x5a, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x46, 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, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 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, 0x12, 0x12, 0x0a, + 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, + 0x68, 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, 0xfa, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, + 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0xad, 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, + 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0x90, 0x03, 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, 0x12, 0x12, 0x0a, + 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, + 0x68, 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, 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, 0xc8, 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 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, 0xf1, 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, 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, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x04, 0x48, 0x61, 0x73, 0x68, 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, 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, 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, 0x22, 0x80, 0x03, 0x0a, 0x10, + 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 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, 0x55, + 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 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, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x5a, 0x0a, 0x08, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 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, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x08, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 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, 0xaa, + 0x01, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 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, 0x1c, + 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x09, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3f, 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, 0x72, 0x74, 0x65, 0x64, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x52, 0x09, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x22, 0x72, 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, 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, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x61, 0x6d, + 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2a, + 0xe2, 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, 0x12, 0x18, 0x0a, 0x14, 0x4b, + 0x69, 0x6e, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x10, 0x0d, 0x12, 0x1d, 0x0a, 0x19, 0x4b, 0x69, 0x6e, 0x64, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x10, 0x0e, 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, 0x32, 0xd5, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0xbe, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x45, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, + 0x49, 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, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x4a, 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, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08, 0x02, 0x10, 0x0c, + 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 ( diff --git a/proto/private/pbconfigentry/config_entry.proto b/proto/private/pbconfigentry/config_entry.proto index e0dc43358b..00350fb943 100644 --- a/proto/private/pbconfigentry/config_entry.proto +++ b/proto/private/pbconfigentry/config_entry.proto @@ -96,6 +96,7 @@ message MeshConfig { PeeringMeshConfig Peering = 5; bool AllowEnablingPermissiveMutualTLS = 6; uint64 Hash = 7; + bool ValidateClusters = 8; } // mog annotation: diff --git a/website/content/docs/connect/config-entries/mesh.mdx b/website/content/docs/connect/config-entries/mesh.mdx index 4b5bb7ee2d..9352b2cc24 100644 --- a/website/content/docs/connect/config-entries/mesh.mdx +++ b/website/content/docs/connect/config-entries/mesh.mdx @@ -342,6 +342,17 @@ Note that the Kubernetes example does not include a `partition` field. Configura description: 'Controls whether `MutualTLSMode=permissive` can be set in the `proxy-defaults` and `service-defaults` configuration entries. ' }, + { + name: 'ValidateClusters', + type: 'bool: false', + description: + `Controls whether the clusters the route table refers to are validated. The default value is false. When set to + false and a route refers to a cluster that does not exist, the route table loads and routing to a non-existent + cluster results in a 404. When set to true and the route is set to a cluster that do not exist, the route table + will not load. For more information, refer to + [HTTP route configuration in the Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route.proto#envoy-v3-api-field-config-route-v3-routeconfiguration-validate-clusters) + for more details. `, + }, { name: 'TLS', type: 'TLSConfig: ', From 9d06fc33808b22111025fcd3a5fc67bf0391066d Mon Sep 17 00:00:00 2001 From: John Maguire Date: Tue, 20 Aug 2024 11:18:13 -0400 Subject: [PATCH 123/185] remove consul-k8s submodule (#21622) --- consul-k8s | 1 - 1 file changed, 1 deletion(-) delete mode 160000 consul-k8s diff --git a/consul-k8s b/consul-k8s deleted file mode 160000 index 0d85bbc313..0000000000 --- a/consul-k8s +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0d85bbc3131ce8be23c57e30b213ba6056623976 From 0e47b380b2b86ab1c232dcd19e7c116e85ed6d69 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Tue, 20 Aug 2024 12:33:07 -0400 Subject: [PATCH 124/185] [NET-10774] Fix Group Reference in GatewayPolcy Docs (#21625) fix group reference for gateway policy --- .../gateways/api-gateway/configuration/gatewaypolicy.mdx | 6 +++--- .../gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx b/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx index 1e0111a323..f74a9ed77c 100644 --- a/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx +++ b/website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx @@ -53,7 +53,7 @@ spec: targetRef: name: gateway kind: Gateway - group: gateway.networking.kubernetes.io + group: gateway.networking.k8s.io/v1beta1 sectionName: override: jwt: @@ -153,7 +153,7 @@ The following table describes the members of the `targetRef` map: | `namespace` | Specifies the namespace that the target reference is a member of. | String | `default` | | `name` | Specifies the name of the API gateway that the policy attaches to. | String | None | | `kind` | Specifies the type of resource that the policy attaches to. Must be set to `Gateway`. | String | None | -| `group` | Specifies the resource group. Must be set to `gateway.networking.kubernetes.io`. | String | None | +| `group` | Specifies the resource group. Must be set to `gateway.networking.k8s.io/v1beta1`. | String | None | | `sectionName` | Specifies a part of the gateway that the policy applies to. | String | None | ### `spec.override` @@ -237,7 +237,7 @@ spec: targetRef: name: gateway kind: Gateway - group: gateway.networking.kubernetes.io + group: gateway.networking.k8s.io/v1beta1 sectionName: to-server override: jwt: diff --git a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx index 87fd27dae8..6bd8f28ccd 100644 --- a/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx +++ b/website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx @@ -67,7 +67,7 @@ Create a `GatewayPolicy` CRD that defines default and override settings for JWT - `metadata.name`: Specifies a name for the policy. - `spec.targetRef.name`: Specifies the name of the API gateway to attach the policy to. - `spec.targetRef.kind`: Specifies the kind of resource to attach to the policy to. Must be set to `Gateway`. -- `spec.targetRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kubernetes.io`. +- `spec.targetRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.k8s.io/v1beta1`. - `spec.targetRef.sectionName`: Specifies a part of the gateway that the policy applies to. - `spec.targetRef.override.jwt.providers`: Specifies a list of providers and claims used to verify requests to the gateway. The override settings take precedence over the default and route-specific JWT verification settings. - `spec.targetRef.default.jwt.providers`: Specifies a list of default providers and claims used to verify requests to the gateway. @@ -176,7 +176,7 @@ For more information about the fields you can configure, refer to [`RouteAuthFil In the `filters` field of your HTTPRoute configuration, define the filter behavior that results from JWT verification. - `type: extensionRef`: Declare list of extension references. -- `extensionRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.kubernetes.io`. +- `extensionRef.group`: Specifies the resource group. Unless you have created a custom group, this should be set to `gateway.networking.k8s.io/v1beta1`. - `extensionRef.kind`: Specifies the type of extension reference to attach to the route. Must be `RouteAuthFilter` - `extensionRef.name`: Specifies the name of the auth filter. From 53c225b1987cafaddbd80e29edf3d1a439417944 Mon Sep 17 00:00:00 2001 From: John Murret Date: Thu, 22 Aug 2024 09:59:33 -0600 Subject: [PATCH 125/185] add build support script to print out the submodule versions required in other submodules (#21635) * add build support script to print out the submodule versions required in other submodules * update help and usage. exclude current submodule in output. --- build-support/functions/10-util.sh | 18 +++++++ .../consul-module-versions-in-consul.sh | 54 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100755 build-support/scripts/consul-module-versions-in-consul.sh diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index 4bb9f35a9f..8cbcb11c68 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -667,3 +667,21 @@ function go_mod_assert { fi return 0 } + +function get_consul_module_versions { + local module_directories + module_directories=( "." "api" "envoyextensions" "proto-public" "sdk" "troubleshoot") + for module_dir in "${module_directories[@]}"; do + echo "Module versions for directory: '$module_dir':" + echo "--------------" + (cd "$module_dir" && go list -m all | grep -e github.com/hashicorp/consul/api \ + -e github.com/hashicorp/consul/envoyextensions \ + -e github.com/hashicorp/consul/proto-public \ + -e github.com/hashicorp/consul/sdk \ + -e github.com/hashicorp/consul/troubleshoot \ + | if [ "$module_dir" != "." ]; then grep -v "consul/$module_dir"; else cat; fi) + echo "--------------" + echo "" + done + return 0 +} diff --git a/build-support/scripts/consul-module-versions-in-consul.sh b/build-support/scripts/consul-module-versions-in-consul.sh new file mode 100755 index 0000000000..46941d2413 --- /dev/null +++ b/build-support/scripts/consul-module-versions-in-consul.sh @@ -0,0 +1,54 @@ +#!/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" + +function usage { +cat <<-EOF +Usage: ${SCRIPT_NAME} [] + +Description: + + This script reports the consul module versions in each of the go.mod files in the Consul repository. + +Options: + -h | --help Print this help text. +EOF +} + +function err_usage { + err "$1" + err "" + err "$(usage)" +} + +function main { + while test $# -gt 0 + do + case "$1" in + -h | --help ) + usage + return 0 + ;; + *) + err_usage "ERROR: Unknown argument: '$1'" + return 1 + ;; + esac + done + + get_consul_module_versions || return 1 + + return 0 +} + +main "$@" +exit $? + From 5710cbd7bac1ca4a5d5214863088813ecd0b2a33 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 22 Aug 2024 13:32:01 -0400 Subject: [PATCH 126/185] ci: fix workflow graph for 1.18 Envoy int tests (#21642) This branch is no longer active on CE, so its jobs should all be skipped via check-ent. One job was missed so it fails nightly right now. --- .github/workflows/nightly-test-integrations-1.18.x.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/nightly-test-integrations-1.18.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml index c432dc1c09..59df23bb81 100644 --- a/.github/workflows/nightly-test-integrations-1.18.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -54,6 +54,7 @@ jobs: ref: release/1.18.x get-envoy-versions: + needs: [check-ent] uses: ./.github/workflows/reusable-get-envoy-versions.yml with: ref: release/1.18.x From cc2c8fb92b6eb7a0ce318d269ff5c4d2bcd5f712 Mon Sep 17 00:00:00 2001 From: Poonam Jadhav Date: Mon, 26 Aug 2024 11:10:57 -0400 Subject: [PATCH 127/185] NET-5912/service-defaults protocol validation (#21593) * fix: add validation for protocol field on service-defaults config entry * test: update test cases with correct protocol --- agent/config/builder.go | 4 +++- agent/config_endpoint_test.go | 4 ++-- agent/consul/config_endpoint.go | 4 +++- agent/consul/config_replication_test.go | 6 +++--- agent/structs/config_entry.go | 9 ++++++-- agent/structs/config_entry_test.go | 10 ++++++++- api/config_entry_test.go | 6 +++--- command/config/write/config_write_test.go | 25 +++++++++++++++++++++-- 8 files changed, 53 insertions(+), 15 deletions(-) diff --git a/agent/config/builder.go b/agent/config/builder.go index 64e9120fde..5c2eba5c55 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -22,12 +22,13 @@ import ( "time" "github.com/armon/go-metrics/prometheus" + "golang.org/x/time/rate" + "github.com/hashicorp/go-bexpr" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-multierror" "github.com/hashicorp/go-sockaddr/template" "github.com/hashicorp/memberlist" - "golang.org/x/time/rate" "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/checks" @@ -774,6 +775,7 @@ func (b *builder) build() (rt RuntimeConfig, err error) { if err != nil { return RuntimeConfig{}, fmt.Errorf("config_entries.bootstrap[%d]: %s", i, err) } + // Ensure Normalize is called before Validate for accurate validation if err := entry.Normalize(); err != nil { return RuntimeConfig{}, fmt.Errorf("config_entries.bootstrap[%d]: %s", i, err) } diff --git a/agent/config_endpoint_test.go b/agent/config_endpoint_test.go index 8697b55e5b..ec00b172d1 100644 --- a/agent/config_endpoint_test.go +++ b/agent/config_endpoint_test.go @@ -612,7 +612,7 @@ func TestConfig_Apply_CAS(t *testing.T) { { "Kind": "service-defaults", "Name": "foo", - "Protocol": "udp" + "Protocol": "http" } `)) req, _ = http.NewRequest("PUT", "/v1/config?cas=0", body) @@ -628,7 +628,7 @@ func TestConfig_Apply_CAS(t *testing.T) { { "Kind": "service-defaults", "Name": "foo", - "Protocol": "udp" + "Protocol": "http" } `)) req, _ = http.NewRequest("PUT", fmt.Sprintf("/v1/config?cas=%d", entry.GetRaftIndex().ModifyIndex), body) diff --git a/agent/consul/config_endpoint.go b/agent/consul/config_endpoint.go index a78859c350..96906dac68 100644 --- a/agent/consul/config_endpoint.go +++ b/agent/consul/config_endpoint.go @@ -10,10 +10,11 @@ import ( metrics "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" + hashstructure_v2 "github.com/mitchellh/hashstructure/v2" + "github.com/hashicorp/go-bexpr" "github.com/hashicorp/go-hclog" memdb "github.com/hashicorp/go-memdb" - hashstructure_v2 "github.com/mitchellh/hashstructure/v2" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/configentry" @@ -85,6 +86,7 @@ func (c *ConfigEntry) Apply(args *structs.ConfigEntryRequest, reply *bool) error } // Normalize and validate the incoming config entry as if it came from a user. + // Ensure Normalize is called before Validate for accurate validation if err := args.Entry.Normalize(); err != nil { return err } diff --git a/agent/consul/config_replication_test.go b/agent/consul/config_replication_test.go index e2c4fbee8d..3117e046a4 100644 --- a/agent/consul/config_replication_test.go +++ b/agent/consul/config_replication_test.go @@ -6,11 +6,11 @@ package consul import ( "context" "fmt" - "github.com/oklog/ulid/v2" - "github.com/stretchr/testify/assert" "os" "testing" + "github.com/oklog/ulid/v2" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/hashicorp/consul/agent/structs" @@ -129,7 +129,7 @@ func TestReplication_ConfigEntries(t *testing.T) { Entry: &structs.ServiceConfigEntry{ Kind: structs.ServiceDefaults, Name: fmt.Sprintf("svc-%d", i), - Protocol: "udp", + Protocol: "tcp", }, } diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index 5d419e0832..32b4e0c89d 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -12,12 +12,11 @@ import ( "time" "github.com/miekg/dns" - - "github.com/hashicorp/go-multierror" "github.com/mitchellh/hashstructure" "github.com/mitchellh/mapstructure" "github.com/hashicorp/consul-net-rpc/go-msgpack/codec" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/cache" @@ -269,6 +268,12 @@ func (e *ServiceConfigEntry) Validate() error { validationErr = multierror.Append(validationErr, fmt.Errorf("invalid value for balance_inbound_connections: %v", e.BalanceInboundConnections)) } + switch e.Protocol { + case "", "http", "http2", "grpc", "tcp": + default: + validationErr = multierror.Append(validationErr, fmt.Errorf("invalid value for protocol: %v", e.Protocol)) + } + // External endpoints are invalid with an existing service's upstream configuration if e.UpstreamConfig != nil && e.Destination != nil { validationErr = multierror.Append(validationErr, errors.New("UpstreamConfig and Destination are mutually exclusive for service defaults")) diff --git a/agent/structs/config_entry_test.go b/agent/structs/config_entry_test.go index e57e2c4041..4c092acc46 100644 --- a/agent/structs/config_entry_test.go +++ b/agent/structs/config_entry_test.go @@ -10,12 +10,12 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/hashicorp/hcl" "github.com/mitchellh/copystructure" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/hashicorp/consul-net-rpc/go-msgpack/codec" + "github.com/hashicorp/hcl" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/cache" @@ -3225,6 +3225,14 @@ func TestServiceConfigEntry(t *testing.T) { }, validateErr: `Invalid MutualTLSMode "invalid-mtls-mode". Must be one of "", "strict", or "permissive".`, }, + "validate: invalid Protocol in service-defaults": { + entry: &ServiceConfigEntry{ + Kind: ServiceDefaults, + Name: "web", + Protocol: "blah", + }, + validateErr: `invalid value for protocol: blah`, + }, } testConfigEntryNormalizeAndValidate(t, cases) } diff --git a/api/config_entry_test.go b/api/config_entry_test.go index 2461c387b3..d6fe8373c9 100644 --- a/api/config_entry_test.go +++ b/api/config_entry_test.go @@ -104,7 +104,7 @@ func TestAPI_ConfigEntries(t *testing.T) { service := &ServiceConfigEntry{ Kind: ServiceDefaults, Name: "foo", - Protocol: "udp", + Protocol: "http", MutualTLSMode: MutualTLSModeStrict, Meta: map[string]string{ "foo": "bar", @@ -124,7 +124,7 @@ func TestAPI_ConfigEntries(t *testing.T) { service2 := &ServiceConfigEntry{ Kind: ServiceDefaults, Name: "bar", - Protocol: "tcp", + Protocol: "http", Destination: dest, } @@ -176,7 +176,7 @@ func TestAPI_ConfigEntries(t *testing.T) { require.True(t, written) // update no cas - service.Protocol = "http" + service.Protocol = "tcp" _, wm, err = config_entries.Set(service, nil) require.NoError(t, err) diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index 15e7a47465..ae782c0826 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -43,7 +43,7 @@ func TestConfigWrite(t *testing.T) { _, err := f.WriteString(` Kind = "service-defaults" Name = "web" - Protocol = "udp" + Protocol = "tcp" `) require.NoError(t, err) @@ -65,7 +65,7 @@ func TestConfigWrite(t *testing.T) { require.True(t, ok) require.Equal(t, api.ServiceDefaults, svc.Kind) require.Equal(t, "web", svc.Name) - require.Equal(t, "udp", svc.Protocol) + require.Equal(t, "tcp", svc.Protocol) }) t.Run("Stdin", func(t *testing.T) { @@ -170,6 +170,27 @@ kind = "proxy-defaults" `Config entry written: proxy-defaults/global`) require.Equal(t, 0, code) }) + + // Test that protocol field is first normalized and then validated + // before writing the config entry + t.Run("service defaults config entry mixed case in protocol field", func(t *testing.T) { + stdin := new(bytes.Buffer) + stdin.WriteString(` + Kind = "service-defaults" + Name = "web" + Protocol = "TcP" +`) + + ui := cli.NewMockUi() + c := New(ui) + c.testStdin = stdin + + code := c.Run([]string{"-http-addr=" + a.HTTPAddr(), "-"}) + require.Empty(t, ui.ErrorWriter.String()) + require.Contains(t, ui.OutputWriter.String(), + `Config entry written: service-defaults/web`) + require.Equal(t, 0, code) + }) } func TestConfigWrite_Warning(t *testing.T) { From 2a99624859ff572e0002df01606d47ca8e29e32c Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 26 Aug 2024 12:39:35 -0400 Subject: [PATCH 128/185] test: update pause Docker image in Envoy int tests (#21659) k8s.gcr.io has been migrated to registry.k8s.io for several years now, and the old registry is being shut down, causing image pull failures. Update to target the new registry when pulling the pause image used in Envoy integration tests. --- test/integration/connect/envoy/run-tests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integration/connect/envoy/run-tests.sh b/test/integration/connect/envoy/run-tests.sh index 46dcb9965f..1efebe7cf6 100755 --- a/test/integration/connect/envoy/run-tests.sh +++ b/test/integration/connect/envoy/run-tests.sh @@ -553,8 +553,7 @@ function suite_setup { docker run --sysctl net.ipv6.conf.all.disable_ipv6=1 -d --name envoy_workdir_1 \ $WORKDIR_SNIPPET \ --net=none \ - k8s.gcr.io/pause &>/dev/null - # TODO(rb): switch back to "${HASHICORP_DOCKER_PROXY}/google/pause" once that is cached + registry.k8s.io/pause &>/dev/null # pre-build the verify container echo "Rebuilding 'bats-verify' image..." From 9c02eff1cddbb276bf2a91b55283b3768d5e242b Mon Sep 17 00:00:00 2001 From: John Murret Date: Mon, 26 Aug 2024 11:49:51 -0600 Subject: [PATCH 129/185] add module retractions (#21665) --- api/go.mod | 6 +++++- envoyextensions/go.mod | 2 ++ troubleshoot/go.mod | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/api/go.mod b/api/go.mod index 0a1f7fee6f..e0c7f19f1a 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,7 +7,11 @@ replace ( github.com/hashicorp/consul/sdk => ../sdk ) -retract v1.28.0 // tag was mutated +retract ( + v1.28.0 // tag was mutated + v1.27.1 // tag was mutated + v1.21.2 // tag was mutated +) require ( github.com/google/go-cmp v0.5.9 diff --git a/envoyextensions/go.mod b/envoyextensions/go.mod index c9bb9cb6f0..57b8c96636 100644 --- a/envoyextensions/go.mod +++ b/envoyextensions/go.mod @@ -8,6 +8,8 @@ replace ( github.com/hashicorp/consul/sdk => ../sdk ) +retract v0.7.2 // tag was mutated + require ( github.com/envoyproxy/go-control-plane v0.12.0 github.com/google/go-cmp v0.5.9 diff --git a/troubleshoot/go.mod b/troubleshoot/go.mod index 9af318f62f..b6c579ee3a 100644 --- a/troubleshoot/go.mod +++ b/troubleshoot/go.mod @@ -14,6 +14,12 @@ exclude ( github.com/hashicorp/go-msgpack v1.1.6 // contains retractions but same as v1.1.5 ) +retract ( + v0.6.4 // tag was mutated + v0.6.2 // tag has incorrect line of deps + v0.6.1 // tag has incorrect line of deps +) + require ( github.com/envoyproxy/go-control-plane v0.12.0 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e From f187b92e3ade7545cace8355adf648b7c4468c39 Mon Sep 17 00:00:00 2001 From: John Murret Date: Mon, 26 Aug 2024 14:12:54 -0600 Subject: [PATCH 130/185] run integration tests on push in main and release/* (#21666) * run integration tests on push in main and release/* * Update .github/workflows/test-integrations.yml Co-authored-by: Michael Zalimeni --------- Co-authored-by: Michael Zalimeni --- .github/workflows/test-integrations.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 3d57c90994..a6fa149bba 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -13,6 +13,11 @@ on: - 'backport/docs/**' - 'backport/ui/**' - 'backport/mktg-**' + push: + branches: + # Push events on the main branch + - main + - release/** env: TEST_RESULTS_DIR: /tmp/test-results From ab794b59f84abf9d705263b8a46a74395047c41c Mon Sep 17 00:00:00 2001 From: John Murret Date: Wed, 28 Aug 2024 09:39:12 -0600 Subject: [PATCH 131/185] update version, changelog, and submodules after 1.19.2, 1.18.4, 1.17.7 and 1.15.14 releases (#21676) * update changelog * Update CHANGELOG.md * remove duplicate 1.19.1 section * update version * update go.mod with most recent modules --- CHANGELOG.md | 46 ++++++++++++++++++++++++ api/go.mod | 2 +- envoyextensions/go.mod | 2 +- go.mod | 8 ++--- test-integ/go.mod | 4 +-- test/integration/consul-container/go.mod | 6 ++-- testing/deployer/go.mod | 4 +-- troubleshoot/go.mod | 4 +-- version/VERSION | 2 +- 9 files changed, 62 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acc8bbe298..6d3f07d436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,49 @@ +## 1.19.2 (August 26, 2024) + +SECURITY: + +* ui: Upgrade modules with d3-color as a dependency to address denial of service issue in d3-color < 3.1.0 [[GH-21588](https://github.com/hashicorp/consul/issues/21588)] + +IMPROVEMENTS: + +* Use Envoy's default for a route's validate_clusters option, which is false. This fixes a case where non-existent clusters could cause a route to no longer route to any of its backends, including existing ones. [[GH-21587](https://github.com/hashicorp/consul/issues/21587)] + +BUG FIXES: + +* api-gateway: **(Enterprise only)** ensure clusters are properly created for JWT providers with a remote URI for the JWKS endpoint [[GH-21604](https://github.com/hashicorp/consul/issues/21604)] + +## 1.18.4 Enterprise (August 26, 2024) + +Enterprise LTS: Consul Enterprise 1.18 is a Long-Term Support (LTS) release. + +SECURITY: +* ui: Upgrade modules with d3-color as a dependency to address denial of service issue in d3-color < 3.1.0 + +IMPROVEMENTS: + +* Use Envoy's default for a route's validate_clusters option, which is false. This fixes a case where non-existent clusters could cause a route to no longer route to any of its backends, including existing ones. [[GH-21587](https://github.com/hashicorp/consul/issues/21587)] + +## 1.17.7 Enterprise (August 26, 2024) + +SECURITY: +* ui: Upgrade modules with d3-color as a dependency to address denial of service issue in d3-color < 3.1.0 + +IMPROVEMENTS: + +* Use Envoy's default for a route's validate_clusters option, which is false. This fixes a case where non-existent clusters could cause a route to no longer route to any of its backends, including existing ones. [[GH-21587](https://github.com/hashicorp/consul/issues/21587)] + +## 1.15.14 Enterprise (August 26, 2024) + +Enterprise LTS: Consul Enterprise 1.15 is a Long-Term Support (LTS) release. + +SECURITY: + +* ui: Upgrade modules with d3-color as a dependency to address denial of service issue in d3-color < 3.1.0 [[GH-21588](https://github.com/hashicorp/consul/issues/21588)] + +IMPROVEMENTS: + +* Use Envoy's default for a route's validate_clusters option, which is false. This fixes a case where non-existent clusters could cause a route to no longer route to any of its backends, including existing ones. [[GH-21587](https://github.com/hashicorp/consul/issues/21587)] + ## 1.19.1 (July 11, 2024) SECURITY: diff --git a/api/go.mod b/api/go.mod index e0c7f19f1a..e4de0fa6c1 100644 --- a/api/go.mod +++ b/api/go.mod @@ -15,7 +15,7 @@ retract ( require ( github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/proto-public v0.6.2 github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.5.0 diff --git a/envoyextensions/go.mod b/envoyextensions/go.mod index 57b8c96636..9970e5d71f 100644 --- a/envoyextensions/go.mod +++ b/envoyextensions/go.mod @@ -13,7 +13,7 @@ retract v0.7.2 // tag was mutated require ( github.com/envoyproxy/go-control-plane v0.12.0 github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/api v1.29.1 + github.com/hashicorp/consul/api v1.29.4 github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 diff --git a/go.mod b/go.mod index a6ebcbaabd..1feee6383c 100644 --- a/go.mod +++ b/go.mod @@ -43,11 +43,11 @@ require ( github.com/hashi-derek/grpc-proxy v0.0.0-20231207191910-191266484d75 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.29.1 - github.com/hashicorp/consul/envoyextensions v0.7.0 - github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/api v1.29.4 + github.com/hashicorp/consul/envoyextensions v0.7.3 + github.com/hashicorp/consul/proto-public v0.6.2 github.com/hashicorp/consul/sdk v0.16.1 - github.com/hashicorp/consul/troubleshoot v0.6.1 + github.com/hashicorp/consul/troubleshoot v0.7.1 github.com/hashicorp/go-bexpr v0.1.2 github.com/hashicorp/go-checkpoint v0.5.0 github.com/hashicorp/go-cleanhttp v0.5.2 diff --git a/test-integ/go.mod b/test-integ/go.mod index 072dda44ac..7a91a5a20e 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -6,8 +6,8 @@ toolchain go1.22.5 require ( github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/api v1.29.1 - github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/api v1.29.4 + github.com/hashicorp/consul/proto-public v0.6.2 github.com/hashicorp/consul/sdk v0.16.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 diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index d1e077db52..e7803fa6e9 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -12,9 +12,9 @@ require ( github.com/evanphx/json-patch v4.12.0+incompatible github.com/go-jose/go-jose/v3 v3.0.3 github.com/hashicorp/consul v1.16.1 - github.com/hashicorp/consul/api v1.29.1 - github.com/hashicorp/consul/envoyextensions v0.7.0 - github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/api v1.29.4 + github.com/hashicorp/consul/envoyextensions v0.7.3 + github.com/hashicorp/consul/proto-public v0.6.2 github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373 github.com/hashicorp/go-cleanhttp v0.5.2 diff --git a/testing/deployer/go.mod b/testing/deployer/go.mod index 0dd3855e3b..e1bd6711a3 100644 --- a/testing/deployer/go.mod +++ b/testing/deployer/go.mod @@ -6,8 +6,8 @@ require ( github.com/avast/retry-go v3.0.0+incompatible github.com/google/go-cmp v0.5.9 github.com/hashicorp/consul-server-connection-manager v0.1.4 - github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/proto-public v0.6.1 + github.com/hashicorp/consul/api v1.29.4 + github.com/hashicorp/consul/proto-public v0.6.2 github.com/hashicorp/consul/sdk v0.16.1 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.5.0 diff --git a/troubleshoot/go.mod b/troubleshoot/go.mod index b6c579ee3a..753fd9e099 100644 --- a/troubleshoot/go.mod +++ b/troubleshoot/go.mod @@ -23,8 +23,8 @@ retract ( require ( github.com/envoyproxy/go-control-plane v0.12.0 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e - github.com/hashicorp/consul/api v1.29.1 - github.com/hashicorp/consul/envoyextensions v0.7.0 + github.com/hashicorp/consul/api v1.29.4 + github.com/hashicorp/consul/envoyextensions v0.7.3 github.com/hashicorp/consul/sdk v0.16.1 github.com/stretchr/testify v1.8.4 google.golang.org/protobuf v1.33.0 diff --git a/version/VERSION b/version/VERSION index 734375f897..ece450e8fe 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -1.20.0-dev +1.19.3-dev From d12f9cf4d1617d3128e28a3199cc8de3ccd8475f Mon Sep 17 00:00:00 2001 From: Jorge Marey <6938602+jorgemarey@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:51:44 +0200 Subject: [PATCH 132/185] Set replication metric to 0 when losing leadership (#20665) * Set replication metric to 0 when losing leadership * Fix replication metrics on replication.go also --------- Co-authored-by: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> --- agent/consul/leader.go | 6 ++++++ agent/consul/replication.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/agent/consul/leader.go b/agent/consul/leader.go index 53312c7fe5..f8340d2b32 100644 --- a/agent/consul/leader.go +++ b/agent/consul/leader.go @@ -771,6 +771,12 @@ func (s *Server) runACLReplicator( index, exit, err := replicateFunc(ctx, logger, lastRemoteIndex) if exit { + metrics.SetGauge([]string{"leader", "replication", metricName, "status"}, + 0, + ) + metrics.SetGauge([]string{"leader", "replication", metricName, "index"}, + 0, + ) return nil } diff --git a/agent/consul/replication.go b/agent/consul/replication.go index 08b8811129..ebed1377e1 100644 --- a/agent/consul/replication.go +++ b/agent/consul/replication.go @@ -153,6 +153,12 @@ func (r *Replicator) Run(ctx context.Context) error { // Perform a single round of replication index, exit, err := r.delegate.Replicate(ctx, atomic.LoadUint64(&r.lastRemoteIndex), r.logger) if exit { + metrics.SetGauge([]string{"leader", "replication", r.delegate.MetricName(), "status"}, + 0, + ) + metrics.SetGauge([]string{"leader", "replication", r.delegate.MetricName(), "index"}, + 0, + ) return nil } if err != nil { From c1d0fc938a7573df620d805f020da45358c6a2c9 Mon Sep 17 00:00:00 2001 From: Aimee Ukasick Date: Thu, 29 Aug 2024 11:57:32 -0500 Subject: [PATCH 133/185] Docs CE-709: Remove circular links (#21685) Docs CE-70: Remove circular links Remove links to tutorials that no longer exist and redirect back to the ACL overview page. --- website/content/docs/security/acl/index.mdx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/website/content/docs/security/acl/index.mdx b/website/content/docs/security/acl/index.mdx index e29ac995e5..f8b8b97ec8 100644 --- a/website/content/docs/security/acl/index.mdx +++ b/website/content/docs/security/acl/index.mdx @@ -9,15 +9,6 @@ description: >- This topic describes core concepts associated with the optional access control list (ACL) system shipped with Consul. ACLs authenticate requests and authorize access to resources. They also control access to the Consul UI, API, and CLI, as well as secure service-to-service and agent-to-agent communication. -Refer to the following tutorials for step-by-step instructions on how to get started using ACLs: - -- [Bootstrap and Explore ACLs] -- [Secure Consul with ACLs] -- [Troubleshoot the ACL System](/consul/tutorials/security/access-control-troubleshoot) - -[bootstrap and explore acls]: /consul/tutorials/security/access-control-setup-production?utm_source=docs -[secure consul with acls]: /consul/tutorials/security/access-control-setup-production - Refer to the [ACL API reference](/consul/api-docs/acl) and [ACL CLI reference](/consul/commands/acl) for additional usage information. ## Workflow overview From 64683180f3a72dacb0b8ae01503acbb4d97cb504 Mon Sep 17 00:00:00 2001 From: Deniz Onur Duzgun <59659739+dduzgun-security@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:04:51 -0400 Subject: [PATCH 134/185] security(deps): bump aws-sdk-go to v1.55.5 (#21684) * security(deps): bump aws-sdk-go to v1.55.5 * add changelog * edit changelog --- .changelog/21684.txt | 6 ++++++ go.mod | 2 +- go.sum | 8 ++------ 3 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 .changelog/21684.txt diff --git a/.changelog/21684.txt b/.changelog/21684.txt new file mode 100644 index 0000000000..3702737cb0 --- /dev/null +++ b/.changelog/21684.txt @@ -0,0 +1,6 @@ +```release-note:security +Upgrade to support aws/aws-sdk-go `v1.55.5 or higher`. This resolves CVEs +[CVE-2020-8911](https://nvd.nist.gov/vuln/detail/cve-2020-8911) and +[CVE-2020-8912](https://nvd.nist.gov/vuln/detail/cve-2020-8912). +``` + diff --git a/go.mod b/go.mod index 1feee6383c..649a591606 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e github.com/armon/go-metrics v0.4.1 github.com/armon/go-radix v1.0.0 - github.com/aws/aws-sdk-go v1.44.289 + github.com/aws/aws-sdk-go v1.55.5 github.com/coreos/go-oidc/v3 v3.9.0 github.com/deckarep/golang-set/v2 v2.3.1 github.com/docker/go-connections v0.4.0 diff --git a/go.sum b/go.sum index 86dbf3e57d..89ac14fdd6 100644 --- a/go.sum +++ b/go.sum @@ -121,8 +121,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 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/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= 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= @@ -1013,7 +1013,6 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx 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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= @@ -1125,7 +1124,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc 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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1134,7 +1132,6 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= @@ -1150,7 +1147,6 @@ 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= From 188af1ccb0f366464fc86438fefe67ceb2e5d8b3 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Fri, 30 Aug 2024 16:25:27 -0400 Subject: [PATCH 135/185] test: fix Envoy int tests and add container logs (#21674) Correctly set the the version of Consul built by the `dev-build` job, which is then copied into the Consul dev image used in integration tests. This was causing failures starting sidecar proxies via `consul connect envoy` due to a mismatch between the (incorrect) Consul binary's supported Envoy versions and the (correct) Envoy version under test. Also add debug log uploads to each int test so we can more easily diagnose this sort of failure in the future, as it was entirely hidden in test output. --- .../nightly-test-integrations-1.15.x.yml | 21 +++++++++++++++++++ .../nightly-test-integrations-1.17.x.yml | 18 ++++++++++++++++ .../nightly-test-integrations-1.18.x.yml | 20 +++++++++++++++++- .../nightly-test-integrations-1.19.x.yml | 20 +++++++++++++++++- .github/workflows/test-integrations.yml | 18 ++++++++++++++++ 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index 8ac92f282f..abb24520ef 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -146,11 +146,15 @@ jobs: path: ./bin - name: restore mode+x run: chmod +x ./bin/consul + - name: Set up Docker Buildx uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 + - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin + - name: Envoy Integration Tests + id: envoy-integration-tests env: GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml GOTESTSUM_FORMAT: standard-verbose @@ -171,6 +175,23 @@ jobs: --packages=./test/integration/connect/envoy \ -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" + # See https://github.com/orgs/community/discussions/8945#discussioncomment-9897011 + # and overall topic discussion for why this is necessary. + - name: Generate artifact ID + id: generate-artifact-id + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + run: | + ARTIFACT_ID=$(uuidgen) + echo "Artifact ID: $ARTIFACT_ID (search this in job summary for download link)" + echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_ENV" + + - name: Upload failure logs + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: envoy-${{ matrix.envoy-version }}-logs-${{ env.artifact_id }} + path: test/integration/connect/envoy/workdir/logs/ + # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml index df952d8234..471cdb163f 100644 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ b/.github/workflows/nightly-test-integrations-1.17.x.yml @@ -154,6 +154,7 @@ jobs: run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - name: Envoy Integration Tests + id: envoy-integration-tests env: GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml GOTESTSUM_FORMAT: standard-verbose @@ -174,6 +175,23 @@ jobs: --packages=./test/integration/connect/envoy \ -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" + # See https://github.com/orgs/community/discussions/8945#discussioncomment-9897011 + # and overall topic discussion for why this is necessary. + - name: Generate artifact ID + id: generate-artifact-id + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + run: | + ARTIFACT_ID=$(uuidgen) + echo "Artifact ID: $ARTIFACT_ID (search this in job summary for download link)" + echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_ENV" + + - name: Upload failure logs + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: envoy-${{ matrix.envoy-version }}-logs-${{ env.artifact_id }} + path: test/integration/connect/envoy/workdir/logs/ + # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} diff --git a/.github/workflows/nightly-test-integrations-1.18.x.yml b/.github/workflows/nightly-test-integrations-1.18.x.yml index 59df23bb81..2d358cda69 100644 --- a/.github/workflows/nightly-test-integrations-1.18.x.yml +++ b/.github/workflows/nightly-test-integrations-1.18.x.yml @@ -68,7 +68,7 @@ jobs: runs-on: ${{ needs.setup.outputs.compute-large }} repository-name: ${{ github.repository }} uploaded-binary-name: 'consul-bin' - branch-name: "release/1.17.x" + branch-name: "release/1.18.x" go-version: ${{ needs.get-go-version.outputs.go-version }} secrets: elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} @@ -154,6 +154,7 @@ jobs: run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - name: Envoy Integration Tests + id: envoy-integration-tests env: GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml GOTESTSUM_FORMAT: standard-verbose @@ -174,6 +175,23 @@ jobs: --packages=./test/integration/connect/envoy \ -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" + # See https://github.com/orgs/community/discussions/8945#discussioncomment-9897011 + # and overall topic discussion for why this is necessary. + - name: Generate artifact ID + id: generate-artifact-id + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + run: | + ARTIFACT_ID=$(uuidgen) + echo "Artifact ID: $ARTIFACT_ID (search this in job summary for download link)" + echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_ENV" + + - name: Upload failure logs + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: envoy-${{ matrix.envoy-version }}-logs-${{ env.artifact_id }} + path: test/integration/connect/envoy/workdir/logs/ + # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} diff --git a/.github/workflows/nightly-test-integrations-1.19.x.yml b/.github/workflows/nightly-test-integrations-1.19.x.yml index 452d174e1e..327907d184 100644 --- a/.github/workflows/nightly-test-integrations-1.19.x.yml +++ b/.github/workflows/nightly-test-integrations-1.19.x.yml @@ -59,7 +59,7 @@ jobs: runs-on: ${{ needs.setup.outputs.compute-large }} repository-name: ${{ github.repository }} uploaded-binary-name: 'consul-bin' - branch-name: "release/1.17.x" + branch-name: "release/1.19.x" go-version: ${{ needs.get-go-version.outputs.go-version }} secrets: elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} @@ -145,6 +145,7 @@ jobs: run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - name: Envoy Integration Tests + id: envoy-integration-tests env: GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml GOTESTSUM_FORMAT: standard-verbose @@ -165,6 +166,23 @@ jobs: --packages=./test/integration/connect/envoy \ -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" + # See https://github.com/orgs/community/discussions/8945#discussioncomment-9897011 + # and overall topic discussion for why this is necessary. + - name: Generate artifact ID + id: generate-artifact-id + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + run: | + ARTIFACT_ID=$(uuidgen) + echo "Artifact ID: $ARTIFACT_ID (search this in job summary for download link)" + echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_ENV" + + - name: Upload failure logs + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: envoy-${{ matrix.envoy-version }}-logs-${{ env.artifact_id }} + path: test/integration/connect/envoy/workdir/logs/ + # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index a6fa149bba..8b14ec8e4d 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -340,6 +340,7 @@ jobs: run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - name: Envoy Integration Tests + id: envoy-integration-tests env: GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml GOTESTSUM_FORMAT: standard-verbose @@ -360,6 +361,23 @@ jobs: --packages=./test/integration/connect/envoy \ -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" + # See https://github.com/orgs/community/discussions/8945#discussioncomment-9897011 + # and overall topic discussion for why this is necessary. + - name: Generate artifact ID + id: generate-artifact-id + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + run: | + ARTIFACT_ID=$(uuidgen) + echo "Artifact ID: $ARTIFACT_ID (search this in job summary for download link)" + echo "artifact_id=$ARTIFACT_ID" >> "$GITHUB_ENV" + + - name: Upload failure logs + if: ${{ failure() && steps.envoy-integration-tests.conclusion == 'failure' }} + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + with: + name: envoy-${{ matrix.envoy-version }}-logs-${{ env.artifact_id }} + path: test/integration/connect/envoy/workdir/logs/ + # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault if: ${{ !cancelled() && endsWith(github.repository, '-enterprise') }} From 3e6f1c1fe104081681bcec800d30aea9bd71ce80 Mon Sep 17 00:00:00 2001 From: "R.B. Boyer" <4903+rboyer@users.noreply.github.com> Date: Thu, 5 Sep 2024 09:50:46 -0500 Subject: [PATCH 136/185] remove v2 tenancy, catalog, and mesh (#21592) * remove v2 tenancy, catalog, and mesh - Inline the v2tenancy experiment to false - Inline the resource-apis experiment to false - Inline the hcp-v2-resource-apis experiment to false - Remove ACL policy templates and rule language changes related to workload identities (a v2-only concept) (e.g. identity and identity_prefix) - Update the gRPC endpoint used by consul-dataplane to no longer respond specially for v2 - Remove stray v2 references scattered throughout the DNS v1.5 newer implementation. * changelog * go mod tidy on consul containers * lint fixes from ENT --------- Co-authored-by: John Murret --- .changelog/21592.txt | 3 + Makefile | 1 - acl/MockAuthorizer.go | 25 - acl/acl_test.go | 188 -- acl/authorizer.go | 55 - acl/authorizer_test.go | 28 - acl/chained_authorizer.go | 29 - acl/policy.go | 35 +- acl/policy_authorizer.go | 73 - acl/policy_authorizer_test.go | 42 - acl/policy_test.go | 176 -- agent/acl_endpoint_test.go | 29 +- agent/ae/ae.go | 8 - agent/agent.go | 67 +- agent/agent_endpoint_test.go | 49 +- agent/catalog_endpoint_test.go | 48 +- agent/config/builder.go | 17 - agent/config/builder_test.go | 75 - agent/config/runtime_test.go | 18 - agent/config_endpoint_test.go | 17 - agent/connect/uri.go | 28 - agent/connect/uri_service.go | 12 - agent/connect/uri_signing.go | 6 - agent/connect/uri_signing_test.go | 24 - agent/connect/uri_test.go | 55 - agent/connect/uri_workload_identity.go | 40 - agent/connect/uri_workload_identity_ce.go | 18 - agent/connect/uri_workload_identity_test.go | 31 - agent/consul/leader.go | 145 - agent/consul/leader_ce.go | 17 - agent/consul/leader_ce_test.go | 48 - agent/consul/leader_connect_ca.go | 18 +- agent/consul/leader_connect_ca_test.go | 24 +- agent/consul/leader_registrator_v2.go | 411 --- agent/consul/leader_registrator_v2_test.go | 583 ---- agent/consul/leader_test.go | 69 +- agent/consul/options.go | 29 - agent/consul/server.go | 168 +- agent/consul/server_ce.go | 1 - agent/consul/server_grpc.go | 30 +- agent/consul/server_test.go | 28 +- .../testdata/v2-resource-dependencies.md | 51 +- agent/consul/type_registry.go | 8 - .../dataplane/get_envoy_bootstrap_params.go | 76 +- .../get_envoy_bootstrap_params_test.go | 253 -- .../services/dataplane/server.go | 5 - .../grpc-external/services/resource/delete.go | 17 - .../services/resource/delete_ce.go | 15 - .../services/resource/delete_test.go | 283 +- agent/grpc-external/services/resource/list.go | 4 - .../services/resource/list_by_owner.go | 4 - .../services/resource/list_by_owner_test.go | 2 - .../services/resource/list_test.go | 2 - .../services/resource/mutate_and_validate.go | 4 - .../resource/mutate_and_validate_test.go | 134 +- agent/grpc-external/services/resource/read.go | 4 - .../services/resource/read_test.go | 70 - .../services/resource/server_ce.go | 18 - .../services/resource/testing/builder.go | 62 +- .../services/resource/testing/builder_ce.go | 14 +- .../services/resource/testing/testing_ce.go | 45 - .../grpc-external/services/resource/watch.go | 4 - .../services/resource/watch_test.go | 2 - .../services/resource/write_status_test.go | 62 - .../services/resource/write_test.go | 282 -- agent/health_endpoint_test.go | 22 +- agent/http.go | 81 +- agent/leafcert/generate.go | 11 +- agent/leafcert/leafcert_test_helpers.go | 48 +- agent/leafcert/structs.go | 19 +- .../proxycfg-sources/catalog/config_source.go | 12 +- .../catalog/config_source_oss.go | 15 - .../catalog/config_source_test.go | 52 +- .../catalog/mock_ConfigManager.go | 18 +- .../proxycfg-sources/catalog/mock_Watcher.go | 29 +- agent/proxycfg-sources/local/config_source.go | 12 +- .../local/mock_ConfigManager.go | 18 +- agent/proxycfg-sources/local/sync.go | 4 +- agent/proxycfg/manager.go | 24 +- agent/proxycfg/manager_test.go | 9 +- agent/proxycfg_test.go | 11 +- agent/rpc/peering/service_test.go | 7 +- agent/structs/acl.go | 9 +- agent/structs/acl_templated_policy.go | 40 +- agent/structs/acl_templated_policy_ce.go | 3 - agent/structs/acl_templated_policy_ce_test.go | 15 - .../policies/ce/workload-identity.hcl | 3 - .../schemas/workload-identity.json | 13 - agent/structs/connect_ca.go | 8 +- agent/structs/connect_proxy_config.go | 43 - agent/structs/errors.go | 6 - agent/testagent.go | 23 +- agent/ui_endpoint_test.go | 25 +- agent/uiserver/ui_template_data.go | 9 - agent/uiserver/uiserver_test.go | 51 +- agent/xds/accesslogs/accesslogs.go | 34 +- agent/xds/delta.go | 113 +- agent/xds/proxystateconverter/clusters.go | 1259 -------- agent/xds/proxystateconverter/converter.go | 135 - agent/xds/proxystateconverter/endpoints.go | 674 ----- .../proxystateconverter/failover_policy.go | 142 - .../proxystateconverter/failover_policy_ce.go | 14 - agent/xds/proxystateconverter/listeners.go | 1678 ----------- .../proxystateconverter/locality_policy.go | 21 - .../proxystateconverter/locality_policy_ce.go | 14 - agent/xds/proxystateconverter/routes.go | 805 ----- agent/xds/rbac_test.go | 456 --- agent/xds/resources_test.go | 406 +-- agent/xds/server.go | 16 +- agent/xds/xds_protocol_helpers_test.go | 18 +- agent/xdsv2/cluster_resources.go | 405 --- agent/xdsv2/endpoint_resources.go | 46 - agent/xdsv2/listener_resources.go | 1142 ------- agent/xdsv2/rbac_resources.go | 486 --- agent/xdsv2/resources.go | 91 - agent/xdsv2/resources_test.go | 182 -- agent/xdsv2/route_resources.go | 542 ---- ...cit-destinations-tproxy-default-bar.golden | 116 - ...destinations-tproxy-default-default.golden | 116 - ...xplicit-destinations-tproxy-foo-bar.golden | 116 - ...cit-destinations-tproxy-foo-default.golden | 116 - .../l4-multi-destination-default-bar.golden | 217 -- ...4-multi-destination-default-default.golden | 217 -- .../l4-multi-destination-foo-bar.golden | 217 -- .../l4-multi-destination-foo-default.golden | 217 -- ...cit-destinations-tproxy-default-bar.golden | 116 - ...destinations-tproxy-default-default.golden | 116 - ...mplicit-destinations-tproxy-foo-bar.golden | 116 - ...cit-destinations-tproxy-foo-default.golden | 116 - ...on-ip-port-bind-address-default-bar.golden | 115 - ...p-port-bind-address-default-default.golden | 115 - ...nation-ip-port-bind-address-foo-bar.golden | 115 - ...on-ip-port-bind-address-foo-default.golden | 115 - ...nix-socket-bind-address-default-bar.golden | 58 - ...socket-bind-address-default-default.golden | 58 - ...on-unix-socket-bind-address-foo-bar.golden | 58 - ...nix-socket-bind-address-foo-default.golden | 58 - ...icit-destination-tproxy-default-bar.golden | 65 - ...-destination-tproxy-default-default.golden | 65 - ...implicit-destination-tproxy-foo-bar.golden | 65 - ...icit-destination-tproxy-foo-default.golden | 65 - ...mixed-multi-destination-default-bar.golden | 285 -- ...d-multi-destination-default-default.golden | 285 -- .../mixed-multi-destination-foo-bar.golden | 285 -- ...mixed-multi-destination-foo-default.golden | 285 -- ...cit-destinations-tproxy-default-bar.golden | 320 -- ...destinations-tproxy-default-default.golden | 320 -- ...mplicit-destinations-tproxy-foo-bar.golden | 320 -- ...cit-destinations-tproxy-foo-default.golden | 320 -- ...icit-destination-tproxy-default-bar.golden | 167 -- ...-destination-tproxy-default-default.golden | 167 -- ...implicit-destination-tproxy-foo-bar.golden | 167 -- ...icit-destination-tproxy-foo-default.golden | 167 -- ...ltiple-workloads-tproxy-default-bar.golden | 167 -- ...le-workloads-tproxy-default-default.golden | 167 -- ...h-multiple-workloads-tproxy-foo-bar.golden | 167 -- ...ltiple-workloads-tproxy-foo-default.golden | 167 -- .../source/l7-expose-paths-default-bar.golden | 87 - .../l7-expose-paths-default-default.golden | 87 - .../source/l7-expose-paths-foo-bar.golden | 87 - .../source/l7-expose-paths-foo-default.golden | 87 - ...and-inbound-connections-default-bar.golden | 127 - ...inbound-connections-default-default.golden | 127 - ...cal-and-inbound-connections-foo-bar.golden | 127 - ...and-inbound-connections-foo-default.golden | 127 - ...ses-with-specific-ports-default-bar.golden | 119 - ...with-specific-ports-default-default.golden | 119 - ...dresses-with-specific-ports-foo-bar.golden | 119 - ...ses-with-specific-ports-foo-default.golden | 119 - ...addresses-without-ports-default-bar.golden | 119 - ...esses-without-ports-default-default.golden | 119 - ...oad-addresses-without-ports-foo-bar.golden | 119 - ...addresses-without-ports-foo-default.golden | 119 - ...ses-with-specific-ports-default-bar.golden | 55 - ...with-specific-ports-default-default.golden | 55 - ...dresses-with-specific-ports-foo-bar.golden | 55 - ...ses-with-specific-ports-foo-default.golden | 55 - ...addresses-without-ports-default-bar.golden | 55 - ...esses-without-ports-default-default.golden | 55 - ...oad-addresses-without-ports-foo-bar.golden | 55 - ...addresses-without-ports-foo-default.golden | 55 - ...oad-with-only-mesh-port-default-bar.golden | 12 - ...with-only-mesh-port-default-default.golden | 12 - ...orkload-with-only-mesh-port-foo-bar.golden | 12 - ...oad-with-only-mesh-port-foo-default.golden | 12 - ...ses-with-specific-ports-default-bar.golden | 63 - ...with-specific-ports-default-default.golden | 63 - ...dresses-with-specific-ports-foo-bar.golden | 63 - ...ses-with-specific-ports-foo-default.golden | 63 - ...addresses-without-ports-default-bar.golden | 95 - ...esses-without-ports-default-default.golden | 95 - ...oad-addresses-without-ports-foo-bar.golden | 95 - ...addresses-without-ports-foo-default.golden | 95 - ...d-address-without-ports-default-bar.golden | 119 - ...dress-without-ports-default-default.golden | 119 - ...kload-address-without-ports-foo-bar.golden | 119 - ...d-address-without-ports-foo-default.golden | 119 - ...cit-destinations-tproxy-default-bar.golden | 49 - ...destinations-tproxy-default-default.golden | 49 - ...xplicit-destinations-tproxy-foo-bar.golden | 49 - ...cit-destinations-tproxy-foo-default.golden | 49 - .../l4-multi-destination-default-bar.golden | 91 - ...4-multi-destination-default-default.golden | 91 - .../l4-multi-destination-foo-bar.golden | 91 - .../l4-multi-destination-foo-default.golden | 91 - ...cit-destinations-tproxy-default-bar.golden | 49 - ...destinations-tproxy-default-default.golden | 49 - ...mplicit-destinations-tproxy-foo-bar.golden | 49 - ...cit-destinations-tproxy-foo-default.golden | 49 - ...on-ip-port-bind-address-default-bar.golden | 49 - ...p-port-bind-address-default-default.golden | 49 - ...nation-ip-port-bind-address-foo-bar.golden | 49 - ...on-ip-port-bind-address-foo-default.golden | 49 - ...nix-socket-bind-address-default-bar.golden | 28 - ...socket-bind-address-default-default.golden | 28 - ...on-unix-socket-bind-address-foo-bar.golden | 28 - ...nix-socket-bind-address-foo-default.golden | 28 - ...icit-destination-tproxy-default-bar.golden | 28 - ...-destination-tproxy-default-default.golden | 28 - ...implicit-destination-tproxy-foo-bar.golden | 28 - ...icit-destination-tproxy-foo-default.golden | 28 - ...mixed-multi-destination-default-bar.golden | 91 - ...d-multi-destination-default-default.golden | 91 - .../mixed-multi-destination-foo-bar.golden | 91 - ...mixed-multi-destination-foo-default.golden | 91 - ...cit-destinations-tproxy-default-bar.golden | 133 - ...destinations-tproxy-default-default.golden | 133 - ...mplicit-destinations-tproxy-foo-bar.golden | 133 - ...cit-destinations-tproxy-foo-default.golden | 133 - ...icit-destination-tproxy-default-bar.golden | 70 - ...-destination-tproxy-default-default.golden | 70 - ...implicit-destination-tproxy-foo-bar.golden | 70 - ...icit-destination-tproxy-foo-default.golden | 70 - ...ltiple-workloads-tproxy-default-bar.golden | 70 - ...le-workloads-tproxy-default-default.golden | 70 - ...h-multiple-workloads-tproxy-foo-bar.golden | 70 - ...ltiple-workloads-tproxy-foo-default.golden | 70 - .../source/l7-expose-paths-default-bar.golden | 5 - .../l7-expose-paths-default-default.golden | 5 - .../source/l7-expose-paths-foo-bar.golden | 5 - .../source/l7-expose-paths-foo-default.golden | 5 - ...and-inbound-connections-default-bar.golden | 5 - ...inbound-connections-default-default.golden | 5 - ...cal-and-inbound-connections-foo-bar.golden | 5 - ...and-inbound-connections-foo-default.golden | 5 - ...ses-with-specific-ports-default-bar.golden | 5 - ...with-specific-ports-default-default.golden | 5 - ...dresses-with-specific-ports-foo-bar.golden | 5 - ...ses-with-specific-ports-foo-default.golden | 5 - ...addresses-without-ports-default-bar.golden | 5 - ...esses-without-ports-default-default.golden | 5 - ...oad-addresses-without-ports-foo-bar.golden | 5 - ...addresses-without-ports-foo-default.golden | 5 - ...ses-with-specific-ports-default-bar.golden | 5 - ...with-specific-ports-default-default.golden | 5 - ...dresses-with-specific-ports-foo-bar.golden | 5 - ...ses-with-specific-ports-foo-default.golden | 5 - ...addresses-without-ports-default-bar.golden | 5 - ...esses-without-ports-default-default.golden | 5 - ...oad-addresses-without-ports-foo-bar.golden | 5 - ...addresses-without-ports-foo-default.golden | 5 - ...oad-with-only-mesh-port-default-bar.golden | 5 - ...with-only-mesh-port-default-default.golden | 5 - ...orkload-with-only-mesh-port-foo-bar.golden | 5 - ...oad-with-only-mesh-port-foo-default.golden | 5 - ...ses-with-specific-ports-default-bar.golden | 5 - ...with-specific-ports-default-default.golden | 5 - ...dresses-with-specific-ports-foo-bar.golden | 5 - ...ses-with-specific-ports-foo-default.golden | 5 - ...addresses-without-ports-default-bar.golden | 5 - ...esses-without-ports-default-default.golden | 5 - ...oad-addresses-without-ports-foo-bar.golden | 5 - ...addresses-without-ports-foo-default.golden | 5 - ...d-address-without-ports-default-bar.golden | 5 - ...dress-without-ports-default-default.golden | 5 - ...kload-address-without-ports-foo-bar.golden | 5 - ...d-address-without-ports-foo-default.golden | 5 - ...cit-destinations-tproxy-default-bar.golden | 90 - ...destinations-tproxy-default-default.golden | 90 - ...xplicit-destinations-tproxy-foo-bar.golden | 90 - ...cit-destinations-tproxy-foo-default.golden | 90 - .../l4-multi-destination-default-bar.golden | 137 - ...4-multi-destination-default-default.golden | 137 - .../l4-multi-destination-foo-bar.golden | 137 - .../l4-multi-destination-foo-default.golden | 137 - ...cit-destinations-tproxy-default-bar.golden | 86 - ...destinations-tproxy-default-default.golden | 86 - ...mplicit-destinations-tproxy-foo-bar.golden | 86 - ...cit-destinations-tproxy-foo-default.golden | 86 - ...on-ip-port-bind-address-default-bar.golden | 47 - ...p-port-bind-address-default-default.golden | 47 - ...nation-ip-port-bind-address-foo-bar.golden | 47 - ...on-ip-port-bind-address-foo-default.golden | 47 - ...nix-socket-bind-address-default-bar.golden | 32 - ...socket-bind-address-default-default.golden | 32 - ...on-unix-socket-bind-address-foo-bar.golden | 32 - ...nix-socket-bind-address-foo-default.golden | 32 - ...icit-destination-tproxy-default-bar.golden | 61 - ...-destination-tproxy-default-default.golden | 61 - ...implicit-destination-tproxy-foo-bar.golden | 61 - ...icit-destination-tproxy-foo-default.golden | 61 - ...mixed-multi-destination-default-bar.golden | 119 - ...d-multi-destination-default-default.golden | 119 - .../mixed-multi-destination-foo-bar.golden | 119 - ...mixed-multi-destination-foo-default.golden | 119 - ...cit-destinations-tproxy-default-bar.golden | 222 -- ...destinations-tproxy-default-default.golden | 222 -- ...mplicit-destinations-tproxy-foo-bar.golden | 222 -- ...cit-destinations-tproxy-foo-default.golden | 222 -- ...icit-destination-tproxy-default-bar.golden | 125 - ...-destination-tproxy-default-default.golden | 125 - ...implicit-destination-tproxy-foo-bar.golden | 125 - ...icit-destination-tproxy-foo-default.golden | 125 - ...ltiple-workloads-tproxy-default-bar.golden | 125 - ...le-workloads-tproxy-default-default.golden | 125 - ...h-multiple-workloads-tproxy-foo-bar.golden | 125 - ...ltiple-workloads-tproxy-foo-default.golden | 125 - .../source/l7-expose-paths-default-bar.golden | 201 -- .../l7-expose-paths-default-default.golden | 201 -- .../source/l7-expose-paths-foo-bar.golden | 201 -- .../source/l7-expose-paths-foo-default.golden | 201 -- ...and-inbound-connections-default-bar.golden | 309 -- ...inbound-connections-default-default.golden | 309 -- ...cal-and-inbound-connections-foo-bar.golden | 309 -- ...and-inbound-connections-foo-default.golden | 309 -- ...ses-with-specific-ports-default-bar.golden | 443 --- ...with-specific-ports-default-default.golden | 443 --- ...dresses-with-specific-ports-foo-bar.golden | 443 --- ...ses-with-specific-ports-foo-default.golden | 443 --- ...addresses-without-ports-default-bar.golden | 359 --- ...esses-without-ports-default-default.golden | 359 --- ...oad-addresses-without-ports-foo-bar.golden | 359 --- ...addresses-without-ports-foo-default.golden | 359 --- ...ses-with-specific-ports-default-bar.golden | 128 - ...with-specific-ports-default-default.golden | 128 - ...dresses-with-specific-ports-foo-bar.golden | 128 - ...ses-with-specific-ports-foo-default.golden | 128 - ...addresses-without-ports-default-bar.golden | 128 - ...esses-without-ports-default-default.golden | 128 - ...oad-addresses-without-ports-foo-bar.golden | 128 - ...addresses-without-ports-foo-default.golden | 128 - ...oad-with-only-mesh-port-default-bar.golden | 40 - ...with-only-mesh-port-default-default.golden | 40 - ...orkload-with-only-mesh-port-foo-bar.golden | 40 - ...oad-with-only-mesh-port-foo-default.golden | 40 - ...ses-with-specific-ports-default-bar.golden | 206 -- ...with-specific-ports-default-default.golden | 206 -- ...dresses-with-specific-ports-foo-bar.golden | 206 -- ...ses-with-specific-ports-foo-default.golden | 206 -- ...addresses-without-ports-default-bar.golden | 309 -- ...esses-without-ports-default-default.golden | 309 -- ...oad-addresses-without-ports-foo-bar.golden | 309 -- ...addresses-without-ports-foo-default.golden | 309 -- ...d-address-without-ports-default-bar.golden | 359 --- ...dress-without-ports-default-default.golden | 359 --- ...kload-address-without-ports-foo-bar.golden | 359 --- ...d-address-without-ports-foo-default.golden | 359 --- ...cit-destinations-tproxy-default-bar.golden | 5 - ...destinations-tproxy-default-default.golden | 5 - ...xplicit-destinations-tproxy-foo-bar.golden | 5 - ...cit-destinations-tproxy-foo-default.golden | 5 - .../l4-multi-destination-default-bar.golden | 5 - ...4-multi-destination-default-default.golden | 5 - .../l4-multi-destination-foo-bar.golden | 5 - .../l4-multi-destination-foo-default.golden | 5 - ...cit-destinations-tproxy-default-bar.golden | 5 - ...destinations-tproxy-default-default.golden | 5 - ...mplicit-destinations-tproxy-foo-bar.golden | 5 - ...cit-destinations-tproxy-foo-default.golden | 5 - ...on-ip-port-bind-address-default-bar.golden | 5 - ...p-port-bind-address-default-default.golden | 5 - ...nation-ip-port-bind-address-foo-bar.golden | 5 - ...on-ip-port-bind-address-foo-default.golden | 5 - ...nix-socket-bind-address-default-bar.golden | 5 - ...socket-bind-address-default-default.golden | 5 - ...on-unix-socket-bind-address-foo-bar.golden | 5 - ...nix-socket-bind-address-foo-default.golden | 5 - ...icit-destination-tproxy-default-bar.golden | 5 - ...-destination-tproxy-default-default.golden | 5 - ...implicit-destination-tproxy-foo-bar.golden | 5 - ...icit-destination-tproxy-foo-default.golden | 5 - ...mixed-multi-destination-default-bar.golden | 66 - ...d-multi-destination-default-default.golden | 66 - .../mixed-multi-destination-foo-bar.golden | 66 - ...mixed-multi-destination-foo-default.golden | 66 - ...cit-destinations-tproxy-default-bar.golden | 51 - ...destinations-tproxy-default-default.golden | 51 - ...mplicit-destinations-tproxy-foo-bar.golden | 51 - ...cit-destinations-tproxy-foo-default.golden | 51 - ...icit-destination-tproxy-default-bar.golden | 29 - ...-destination-tproxy-default-default.golden | 29 - ...implicit-destination-tproxy-foo-bar.golden | 29 - ...icit-destination-tproxy-foo-default.golden | 29 - ...ltiple-workloads-tproxy-default-bar.golden | 29 - ...le-workloads-tproxy-default-default.golden | 29 - ...h-multiple-workloads-tproxy-foo-bar.golden | 29 - ...ltiple-workloads-tproxy-foo-default.golden | 29 - .../source/l7-expose-paths-default-bar.golden | 5 - .../l7-expose-paths-default-default.golden | 5 - .../source/l7-expose-paths-foo-bar.golden | 5 - .../source/l7-expose-paths-foo-default.golden | 5 - ...and-inbound-connections-default-bar.golden | 5 - ...inbound-connections-default-default.golden | 5 - ...cal-and-inbound-connections-foo-bar.golden | 5 - ...and-inbound-connections-foo-default.golden | 5 - ...ses-with-specific-ports-default-bar.golden | 5 - ...with-specific-ports-default-default.golden | 5 - ...dresses-with-specific-ports-foo-bar.golden | 5 - ...ses-with-specific-ports-foo-default.golden | 5 - ...addresses-without-ports-default-bar.golden | 5 - ...esses-without-ports-default-default.golden | 5 - ...oad-addresses-without-ports-foo-bar.golden | 5 - ...addresses-without-ports-foo-default.golden | 5 - ...ses-with-specific-ports-default-bar.golden | 5 - ...with-specific-ports-default-default.golden | 5 - ...dresses-with-specific-ports-foo-bar.golden | 5 - ...ses-with-specific-ports-foo-default.golden | 5 - ...addresses-without-ports-default-bar.golden | 5 - ...esses-without-ports-default-default.golden | 5 - ...oad-addresses-without-ports-foo-bar.golden | 5 - ...addresses-without-ports-foo-default.golden | 5 - ...oad-with-only-mesh-port-default-bar.golden | 5 - ...with-only-mesh-port-default-default.golden | 5 - ...orkload-with-only-mesh-port-foo-bar.golden | 5 - ...oad-with-only-mesh-port-foo-default.golden | 5 - ...ses-with-specific-ports-default-bar.golden | 5 - ...with-specific-ports-default-default.golden | 5 - ...dresses-with-specific-ports-foo-bar.golden | 5 - ...ses-with-specific-ports-foo-default.golden | 5 - ...addresses-without-ports-default-bar.golden | 5 - ...esses-without-ports-default-default.golden | 5 - ...oad-addresses-without-ports-foo-bar.golden | 5 - ...addresses-without-ports-foo-default.golden | 5 - ...d-address-without-ports-default-bar.golden | 5 - ...dress-without-ports-default-default.golden | 5 - ...kload-address-without-ports-foo-bar.golden | 5 - ...d-address-without-ports-foo-default.golden | 5 - api/acl.go | 13 +- api/go.sum | 2 +- command/acl/templatedpolicy/formatter.go | 2 - command/resource/apply-grpc/apply_test.go | 2 +- command/resource/apply/apply_test.go | 4 +- command/resource/testdata/nested_data.hcl | 36 +- .../controller-architecture/testing.md | 2 - go.mod | 2 +- internal/auth/exports.go | 41 - .../auth/internal/controllers/register.go | 18 - .../controllers/trafficpermissions/builder.go | 96 - .../trafficpermissions/controller.go | 361 --- .../trafficpermissions/controller_test.go | 1219 -------- .../expander/expander_ce.go | 14 - .../expander/expander_ce/expander_ce.go | 35 - .../trafficpermissions/expander/interface.go | 20 - .../trafficpermissions/helpers_ce.go | 32 - .../controllers/trafficpermissions/index.go | 43 - .../controllers/trafficpermissions/status.go | 68 - .../traffic_permissions_mapper.go | 73 - .../types/computed_traffic_permissions.go | 77 - .../computed_traffic_permissions_test.go | 147 - internal/auth/internal/types/errors.go | 17 - .../types/namespace_traffic_permissions.go | 68 - .../namespace_traffic_permissions_test.go | 145 - .../types/partition_traffic_permissions.go | 68 - .../partition_traffic_permissions_test.go | 145 - .../internal/types/traffic_permissions.go | 148 - .../types/traffic_permissions_test.go | 1012 ------- internal/auth/internal/types/types.go | 28 - internal/auth/internal/types/validate.go | 203 -- internal/auth/internal/types/validate_ce.go | 25 - .../auth/internal/types/workload_identity.go | 59 - .../internal/types/workload_identity_test.go | 104 - .../helpers/acl_hooks_test_helpers.go | 21 - .../v2beta1/api-service.json | 36 - .../v2beta1/api-workload-1-health.json | 31 - .../v2beta1/api-workload-1.json | 45 - .../v2beta1/api-workload-10-health.json | 31 - .../v2beta1/api-workload-10.json | 45 - .../v2beta1/api-workload-11-health.json | 31 - .../v2beta1/api-workload-11.json | 45 - .../v2beta1/api-workload-12-health.json | 31 - .../v2beta1/api-workload-12.json | 45 - .../v2beta1/api-workload-13-health.json | 31 - .../v2beta1/api-workload-13.json | 45 - .../v2beta1/api-workload-14-health.json | 31 - .../v2beta1/api-workload-14.json | 45 - .../v2beta1/api-workload-15-health.json | 31 - .../v2beta1/api-workload-15.json | 45 - .../v2beta1/api-workload-16-health.json | 31 - .../v2beta1/api-workload-16.json | 45 - .../v2beta1/api-workload-17-health.json | 31 - .../v2beta1/api-workload-17.json | 44 - .../v2beta1/api-workload-18-health.json | 31 - .../v2beta1/api-workload-18.json | 44 - .../v2beta1/api-workload-19-health.json | 31 - .../v2beta1/api-workload-19.json | 44 - .../v2beta1/api-workload-2-health.json | 31 - .../v2beta1/api-workload-2.json | 45 - .../v2beta1/api-workload-20-health.json | 31 - .../v2beta1/api-workload-20.json | 44 - .../v2beta1/api-workload-3-health.json | 31 - .../v2beta1/api-workload-3.json | 45 - .../v2beta1/api-workload-4-health.json | 31 - .../v2beta1/api-workload-4.json | 45 - .../v2beta1/api-workload-5-health.json | 31 - .../v2beta1/api-workload-5.json | 45 - .../v2beta1/api-workload-6-health.json | 31 - .../v2beta1/api-workload-6.json | 45 - .../v2beta1/api-workload-7-health.json | 31 - .../v2beta1/api-workload-7.json | 45 - .../v2beta1/api-workload-8-health.json | 31 - .../v2beta1/api-workload-8.json | 45 - .../v2beta1/api-workload-9-health.json | 31 - .../v2beta1/api-workload-9.json | 45 - .../v2beta1/foo-service-endpoints.json | 45 - .../v2beta1/foo-service.json | 23 - .../v2beta1/grpc-api-service.json | 41 - .../v2beta1/http-api-service.json | 28 - .../v2beta1/node-1-health.json | 29 - .../integration_test_data/v2beta1/node-1.json | 25 - .../v2beta1/node-2-health.json | 29 - .../integration_test_data/v2beta1/node-2.json | 25 - .../v2beta1/node-3-health.json | 29 - .../integration_test_data/v2beta1/node-3.json | 25 - .../v2beta1/node-4-health.json | 29 - .../integration_test_data/v2beta1/node-4.json | 25 - internal/catalog/catalogtest/run_test.go | 40 - .../catalogtest/test_integration_v2beta1.go | 764 ----- .../catalogtest/test_lifecycle_v2beta1.go | 730 ----- internal/catalog/exports.go | 113 - .../internal/controllers/endpoints/bound.go | 46 - .../controllers/endpoints/bound_test.go | 63 - .../controllers/endpoints/controller.go | 389 --- .../controllers/endpoints/controller_test.go | 875 ------ .../internal/controllers/endpoints/status.go | 61 - .../controllers/failover/controller.go | 420 --- .../controllers/failover/controller_test.go | 479 --- .../failover/expander/expander_ce.go | 12 - .../failover/expander/expander_ce/expander.go | 38 - .../expander/expander_ce/expander_test.go | 67 - .../failover/expander/interface.go | 17 - .../controllers/failover/helpers_ce.go | 14 - .../internal/controllers/failover/status.go | 109 - .../controllers/nodehealth/controller.go | 104 - .../controllers/nodehealth/controller_test.go | 419 --- .../internal/controllers/nodehealth/status.go | 54 - .../catalog/internal/controllers/register.go | 20 - .../controllers/workloadhealth/controller.go | 223 -- .../workloadhealth/controller_test.go | 780 ----- .../controllers/workloadhealth/status.go | 139 - .../testhelpers/acl_hooks_test_helpers.go | 198 -- .../types/computed_failover_policy.go | 78 - .../types/computed_failover_policy_test.go | 250 -- internal/catalog/internal/types/errors.go | 73 - .../catalog/internal/types/errors_test.go | 74 - .../catalog/internal/types/failover_policy.go | 359 --- .../internal/types/failover_policy_test.go | 741 ----- .../catalog/internal/types/health_checks.go | 85 - .../internal/types/health_checks_test.go | 207 -- .../catalog/internal/types/health_status.go | 90 - .../internal/types/health_status_test.go | 274 -- internal/catalog/internal/types/node.go | 89 - .../internal/types/node_health_status.go | 90 - .../internal/types/node_health_status_test.go | 271 -- internal/catalog/internal/types/node_test.go | 174 -- internal/catalog/internal/types/service.go | 132 - .../internal/types/service_endpoints.go | 176 -- .../internal/types/service_endpoints_test.go | 322 -- .../catalog/internal/types/service_test.go | 286 -- .../errDNSPassingWeightOutOfRange.golden | 1 - .../errDNSWarningWeightOutOfRange.golden | 1 - .../errInvalidEndpointsOwnerName.golden | 1 - .../testdata/errInvalidNodeHostFormat.golden | 1 - .../testdata/errInvalidPhysicalPort.golden | 1 - .../testdata/errInvalidPortReference.golden | 1 - .../testdata/errInvalidVirtualPort.golden | 1 - .../errInvalidWorkloadHostFormat.golden | 1 - .../testdata/errLocalityZoneNoRegion.golden | 1 - .../types/testdata/errNotDNSLabel.golden | 1 - .../types/testdata/errNotIPAddress.golden | 1 - .../types/testdata/errTooMuchMesh.golden | 1 - .../testdata/errUnixSocketMultiport.golden | 1 - .../testdata/errVirtualPortReused.golden | 1 - internal/catalog/internal/types/types.go | 22 - internal/catalog/internal/types/types_test.go | 47 - internal/catalog/internal/types/validators.go | 411 --- .../catalog/internal/types/validators_test.go | 844 ------ .../catalog/internal/types/virtual_ips.go | 52 - .../internal/types/virtual_ips_test.go | 127 - internal/catalog/internal/types/workload.go | 183 -- .../catalog/internal/types/workload_test.go | 496 ---- internal/catalog/workloadselector/acls.go | 47 - .../catalog/workloadselector/acls_test.go | 123 - internal/catalog/workloadselector/gather.go | 114 - .../catalog/workloadselector/gather_test.go | 258 -- internal/catalog/workloadselector/index.go | 72 - .../catalog/workloadselector/index_test.go | 131 - .../catalog/workloadselector/integ_test.go | 151 - internal/catalog/workloadselector/mapper.go | 45 - .../catalog/workloadselector/mapper_test.go | 180 -- .../catalog/workloadselector/selecting.go | 16 - .../cache/indexers/ref_indexer_test.go | 16 +- internal/controller/controllertest/builder.go | 6 - .../internal/controllers/link/controller.go | 22 +- .../controllers/link/controller_test.go | 67 - internal/hcp/internal/controllers/register.go | 6 +- internal/hcp/internal/types/link_test.go | 3 +- internal/mesh/exports.go | 52 - .../controllers/apigateways/controller.go | 106 - .../apigateways/controller_test.go | 166 -- .../apigateways/fetcher/data_fetcher.go | 44 - .../apigateways/fetcher/data_fetcher_test.go | 113 - .../explicitdestinations/controller.go | 319 -- .../explicitdestinations/controller_test.go | 957 ------ .../explicitdestinations/mapper/mapper.go | 74 - .../explicitdestinations/status.go | 121 - .../builder/api_gateway_builder.go | 154 - .../builder/mesh_gateway_builder.go | 426 --- .../builder/mesh_gateway_builder_test.go | 343 --- .../controllers/gatewayproxy/controller.go | 288 -- .../gatewayproxy/controller_test.go | 318 -- .../gatewayproxy/fetcher/data_fetcher.go | 165 - .../gatewayproxy/fetcher/data_fetcher_test.go | 266 -- .../mapper/apigatewayworkloads.go | 55 - .../mapper/meshgatewayworkloads.go | 51 - .../implicitdestinations/auth_helper_test.go | 88 - .../implicitdestinations/controller.go | 314 -- .../implicitdestinations/controller_test.go | 1573 ---------- .../controllers/implicitdestinations/index.go | 194 -- .../implicitdestinations/index_test.go | 256 -- .../implicitdestinations/mapper.go | 171 -- .../implicitdestinations/status.go | 7 - .../meshconfiguration/controller.go | 33 - .../meshconfiguration/controller_test.go | 30 - .../controllers/meshgateways/controller.go | 80 - .../proxyconfiguration/controller.go | 188 -- .../proxyconfiguration/controller_test.go | 358 --- .../controllers/proxyconfiguration/sort.go | 108 - .../proxyconfiguration/sort_test.go | 160 - .../mesh/internal/controllers/register.go | 60 - .../internal/controllers/routes/controller.go | 208 -- .../controllers/routes/controller_test.go | 1687 ----------- .../routes/destination_policy_validation.go | 60 - .../destination_policy_validation_test.go | 121 - .../internal/controllers/routes/generate.go | 861 ------ .../controllers/routes/generate_test.go | 1977 ------------ .../controllers/routes/intermediate.go | 72 - .../controllers/routes/loader/loader.go | 320 -- .../controllers/routes/loader/loader_test.go | 442 --- .../controllers/routes/loader/memoized.go | 93 - .../controllers/routes/loader/related.go | 233 -- .../controllers/routes/pending_status.go | 92 - .../controllers/routes/ref_validation.go | 136 - .../controllers/routes/ref_validation_test.go | 275 -- .../routes/routestest/routestest.go | 104 - .../internal/controllers/routes/sort_rules.go | 230 -- .../controllers/routes/sort_rules_test.go | 492 --- .../internal/controllers/routes/status.go | 238 -- .../mesh/internal/controllers/routes/util.go | 20 - .../routes/xroutemapper/.mockery.yaml | 15 - .../controllers/routes/xroutemapper/util.go | 58 - .../routes/xroutemapper/xroutemapper.go | 298 -- .../routes/xroutemapper/xroutemapper_test.go | 731 ----- ...mock_ResolveFailoverServiceDestinations.go | 95 - .../sidecarproxy/builder/builder.go | 124 - .../sidecarproxy/builder/builder_test.go | 36 - .../builder/destination_multiport_test.go | 266 -- .../sidecarproxy/builder/destinations.go | 706 ----- .../sidecarproxy/builder/destinations_test.go | 576 ---- .../sidecarproxy/builder/expose_paths.go | 153 - .../sidecarproxy/builder/expose_paths_test.go | 111 - .../sidecarproxy/builder/local_app.go | 563 ---- .../builder/local_app_multiport_test.go | 173 -- .../sidecarproxy/builder/local_app_test.go | 1122 ------- .../sidecarproxy/builder/naming.go | 49 - .../sidecarproxy/builder/routes.go | 595 ---- ...cit-destinations-tproxy-default-bar.golden | 193 -- ...destinations-tproxy-default-default.golden | 193 -- ...xplicit-destinations-tproxy-foo-bar.golden | 193 -- ...cit-destinations-tproxy-foo-default.golden | 193 -- .../l4-multi-destination-default-bar.golden | 319 -- ...4-multi-destination-default-default.golden | 319 -- .../l4-multi-destination-foo-bar.golden | 319 -- .../l4-multi-destination-foo-default.golden | 319 -- ...cit-destinations-tproxy-default-bar.golden | 192 -- ...destinations-tproxy-default-default.golden | 192 -- ...mplicit-destinations-tproxy-foo-bar.golden | 192 -- ...cit-destinations-tproxy-foo-default.golden | 192 -- ...on-ip-port-bind-address-default-bar.golden | 164 - ...p-port-bind-address-default-default.golden | 164 - ...nation-ip-port-bind-address-foo-bar.golden | 164 - ...on-ip-port-bind-address-foo-default.golden | 164 - ...nix-socket-bind-address-default-bar.golden | 96 - ...socket-bind-address-default-default.golden | 96 - ...on-unix-socket-bind-address-foo-bar.golden | 96 - ...nix-socket-bind-address-foo-default.golden | 96 - ...icit-destination-tproxy-default-bar.golden | 127 - ...-destination-tproxy-default-default.golden | 127 - ...implicit-destination-tproxy-foo-bar.golden | 127 - ...icit-destination-tproxy-foo-default.golden | 127 - ...mixed-multi-destination-default-bar.golden | 414 --- ...d-multi-destination-default-default.golden | 414 --- .../mixed-multi-destination-foo-bar.golden | 414 --- ...mixed-multi-destination-foo-default.golden | 414 --- ...cit-destinations-tproxy-default-bar.golden | 494 --- ...destinations-tproxy-default-default.golden | 494 --- ...mplicit-destinations-tproxy-foo-bar.golden | 494 --- ...cit-destinations-tproxy-foo-default.golden | 494 --- ...icit-destination-tproxy-default-bar.golden | 275 -- ...-destination-tproxy-default-default.golden | 275 -- ...implicit-destination-tproxy-foo-bar.golden | 275 -- ...icit-destination-tproxy-foo-default.golden | 275 -- ...ltiple-workloads-tproxy-default-bar.golden | 275 -- ...le-workloads-tproxy-default-default.golden | 275 -- ...h-multiple-workloads-tproxy-foo-bar.golden | 275 -- ...ltiple-workloads-tproxy-foo-default.golden | 275 -- .../source/l7-expose-paths-default-bar.golden | 211 -- .../l7-expose-paths-default-default.golden | 211 -- .../source/l7-expose-paths-foo-bar.golden | 211 -- .../source/l7-expose-paths-foo-default.golden | 211 -- .../testdata/source/l7-expose-paths.golden | 211 -- ...and-inbound-connections-default-bar.golden | 303 -- ...inbound-connections-default-default.golden | 303 -- ...cal-and-inbound-connections-foo-bar.golden | 303 -- ...and-inbound-connections-foo-default.golden | 303 -- .../local-and-inbound-connections.golden | 303 -- ...ses-with-specific-ports-default-bar.golden | 338 --- ...with-specific-ports-default-default.golden | 338 --- ...dresses-with-specific-ports-foo-bar.golden | 338 --- ...ses-with-specific-ports-foo-default.golden | 338 --- ...kload-addresses-with-specific-ports.golden | 338 --- ...addresses-without-ports-default-bar.golden | 290 -- ...esses-without-ports-default-default.golden | 290 -- ...oad-addresses-without-ports-foo-bar.golden | 290 -- ...addresses-without-ports-foo-default.golden | 290 -- ...le-workload-addresses-without-ports.golden | 290 -- ...ses-with-specific-ports-default-bar.golden | 129 - ...with-specific-ports-default-default.golden | 129 - ...dresses-with-specific-ports-foo-bar.golden | 129 - ...ses-with-specific-ports-foo-default.golden | 129 - ...kload-addresses-with-specific-ports.golden | 129 - ...addresses-without-ports-default-bar.golden | 129 - ...esses-without-ports-default-default.golden | 129 - ...oad-addresses-without-ports-foo-bar.golden | 129 - ...addresses-without-ports-foo-default.golden | 129 - ...le-workload-addresses-without-ports.golden | 129 - ...d-address-without-ports-default-bar.golden | 129 - ...dress-without-ports-default-default.golden | 129 - ...kload-address-without-ports-foo-bar.golden | 129 - ...d-address-without-ports-foo-default.golden | 129 - ...ngle-workload-address-without-ports.golden | 129 - ...oad-with-only-mesh-port-default-bar.golden | 60 - ...with-only-mesh-port-default-default.golden | 60 - ...orkload-with-only-mesh-port-foo-bar.golden | 60 - ...oad-with-only-mesh-port-foo-default.golden | 60 - ...ort-l4-workload-with-only-mesh-port.golden | 60 - ...ses-with-specific-ports-default-bar.golden | 182 -- ...with-specific-ports-default-default.golden | 182 -- ...dresses-with-specific-ports-foo-bar.golden | 182 -- ...ses-with-specific-ports-foo-default.golden | 182 -- ...kload-addresses-with-specific-ports.golden | 182 -- ...addresses-without-ports-default-bar.golden | 249 -- ...esses-without-ports-default-default.golden | 249 -- ...oad-addresses-without-ports-foo-bar.golden | 249 -- ...addresses-without-ports-foo-default.golden | 249 -- ...le-workload-addresses-without-ports.golden | 249 -- ...d-address-without-ports-default-bar.golden | 249 -- ...dress-without-ports-default-default.golden | 249 -- ...kload-address-without-ports-foo-bar.golden | 249 -- ...d-address-without-ports-foo-default.golden | 249 -- ...ngle-workload-address-without-ports.golden | 249 -- ...d-address-without-ports-default-bar.golden | 290 -- ...dress-without-ports-default-default.golden | 290 -- ...kload-address-without-ports-foo-bar.golden | 290 -- ...d-address-without-ports-foo-default.golden | 290 -- ...ngle-workload-address-without-ports.golden | 290 -- .../controllers/sidecarproxy/controller.go | 350 --- .../sidecarproxy/controller_test.go | 1004 ------- .../controllers/sidecarproxy/data_fetcher.go | 333 --- .../sidecarproxy/data_fetcher_test.go | 516 ---- .../controllers/sidecarproxy/helper_test.go | 87 - .../controllers/sidecarproxy/mapper.go | 210 -- .../internal/controllers/xds/controller.go | 418 --- .../controllers/xds/controller_test.go | 1333 --------- .../controllers/xds/endpoint_builder.go | 78 - .../controllers/xds/endpoint_builder_test.go | 347 --- .../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 - ...cit-destinations-tproxy-default-bar.golden | 185 -- ...destinations-tproxy-default-default.golden | 184 -- ...xplicit-destinations-tproxy-foo-bar.golden | 185 -- ...cit-destinations-tproxy-foo-default.golden | 185 -- .../l4-multi-destination-default-bar.golden | 301 -- ...4-multi-destination-default-default.golden | 300 -- .../l4-multi-destination-foo-bar.golden | 301 -- .../l4-multi-destination-foo-default.golden | 301 -- ...cit-destinations-tproxy-default-bar.golden | 184 -- ...destinations-tproxy-default-default.golden | 183 -- ...mplicit-destinations-tproxy-foo-bar.golden | 184 -- ...cit-destinations-tproxy-foo-default.golden | 184 -- ...on-ip-port-bind-address-default-bar.golden | 156 - ...p-port-bind-address-default-default.golden | 155 - ...nation-ip-port-bind-address-foo-bar.golden | 156 - ...on-ip-port-bind-address-foo-default.golden | 156 - ...nix-socket-bind-address-default-bar.golden | 93 - ...socket-bind-address-default-default.golden | 92 - ...on-unix-socket-bind-address-foo-bar.golden | 93 - ...nix-socket-bind-address-foo-default.golden | 93 - ...icit-destination-tproxy-default-bar.golden | 124 - ...-destination-tproxy-default-default.golden | 123 - ...implicit-destination-tproxy-foo-bar.golden | 124 - ...icit-destination-tproxy-foo-default.golden | 124 - ...mixed-multi-destination-default-bar.golden | 380 --- ...d-multi-destination-default-default.golden | 379 --- .../mixed-multi-destination-foo-bar.golden | 380 --- ...mixed-multi-destination-foo-default.golden | 380 --- ...cit-destinations-tproxy-default-bar.golden | 466 --- ...destinations-tproxy-default-default.golden | 465 --- ...mplicit-destinations-tproxy-foo-bar.golden | 466 --- ...cit-destinations-tproxy-foo-default.golden | 466 --- ...icit-destination-tproxy-default-bar.golden | 262 -- ...-destination-tproxy-default-default.golden | 261 -- ...implicit-destination-tproxy-foo-bar.golden | 262 -- ...icit-destination-tproxy-foo-default.golden | 262 -- ...ltiple-workloads-tproxy-default-bar.golden | 262 -- ...le-workloads-tproxy-default-default.golden | 261 -- ...h-multiple-workloads-tproxy-foo-bar.golden | 262 -- ...ltiple-workloads-tproxy-foo-default.golden | 262 -- .../source/l7-expose-paths-default-bar.golden | 213 -- .../l7-expose-paths-default-default.golden | 212 -- .../source/l7-expose-paths-foo-bar.golden | 213 -- .../source/l7-expose-paths-foo-default.golden | 213 -- .../testdata/source/l7-expose-paths.golden | 212 -- ...and-inbound-connections-default-bar.golden | 305 -- ...inbound-connections-default-default.golden | 304 -- ...cal-and-inbound-connections-foo-bar.golden | 305 -- ...and-inbound-connections-foo-default.golden | 305 -- .../local-and-inbound-connections.golden | 304 -- ...ses-with-specific-ports-default-bar.golden | 340 --- ...with-specific-ports-default-default.golden | 339 --- ...dresses-with-specific-ports-foo-bar.golden | 340 --- ...ses-with-specific-ports-foo-default.golden | 340 --- ...kload-addresses-with-specific-ports.golden | 339 --- ...addresses-without-ports-default-bar.golden | 292 -- ...esses-without-ports-default-default.golden | 291 -- ...oad-addresses-without-ports-foo-bar.golden | 292 -- ...addresses-without-ports-foo-default.golden | 292 -- ...le-workload-addresses-without-ports.golden | 291 -- ...ses-with-specific-ports-default-bar.golden | 131 - ...with-specific-ports-default-default.golden | 130 - ...dresses-with-specific-ports-foo-bar.golden | 131 - ...ses-with-specific-ports-foo-default.golden | 131 - ...kload-addresses-with-specific-ports.golden | 130 - ...addresses-without-ports-default-bar.golden | 131 - ...esses-without-ports-default-default.golden | 130 - ...oad-addresses-without-ports-foo-bar.golden | 131 - ...addresses-without-ports-foo-default.golden | 131 - ...le-workload-addresses-without-ports.golden | 130 - ...ngle-workload-address-without-ports.golden | 128 - ...oad-with-only-mesh-port-default-bar.golden | 62 - ...with-only-mesh-port-default-default.golden | 61 - ...orkload-with-only-mesh-port-foo-bar.golden | 62 - ...oad-with-only-mesh-port-foo-default.golden | 62 - ...ort-l4-workload-with-only-mesh-port.golden | 61 - ...ses-with-specific-ports-default-bar.golden | 184 -- ...with-specific-ports-default-default.golden | 183 -- ...dresses-with-specific-ports-foo-bar.golden | 184 -- ...ses-with-specific-ports-foo-default.golden | 184 -- ...kload-addresses-with-specific-ports.golden | 183 -- ...addresses-without-ports-default-bar.golden | 251 -- ...esses-without-ports-default-default.golden | 250 -- ...oad-addresses-without-ports-foo-bar.golden | 251 -- ...addresses-without-ports-foo-default.golden | 251 -- ...le-workload-addresses-without-ports.golden | 250 -- ...ngle-workload-address-without-ports.golden | 247 -- ...d-address-without-ports-default-bar.golden | 292 -- ...dress-without-ports-default-default.golden | 291 -- ...kload-address-without-ports-foo-bar.golden | 292 -- ...d-address-without-ports-foo-default.golden | 292 -- ...ngle-workload-address-without-ports.golden | 291 -- .../mappers/common/workload_selector_util.go | 58 - .../common/workload_selector_util_test.go | 68 - .../workload_selection_mapper.go | 80 - .../workload_selection_mapper_test.go | 145 - .../internal/meshindexes/computed_routes.go | 66 - .../meshindexes/computed_routes_test.go | 169 -- internal/mesh/internal/types/api_gateway.go | 20 - .../types/computed_explicit_destinations.go | 19 - .../types/computed_implicit_destinations.go | 102 - .../computed_implicit_destinations_test.go | 268 -- .../types/computed_proxy_configuration.go | 17 - .../mesh/internal/types/computed_routes.go | 152 - .../internal/types/computed_routes_test.go | 199 -- internal/mesh/internal/types/decoded.go | 36 - .../mesh/internal/types/destination_policy.go | 275 -- .../internal/types/destination_policy_test.go | 609 ---- internal/mesh/internal/types/destinations.go | 169 -- .../types/destinations_configuration.go | 40 - .../types/destinations_configuration_test.go | 90 - .../mesh/internal/types/destinations_test.go | 414 --- 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 - .../mesh/internal/types/mesh_configuration.go | 22 - internal/mesh/internal/types/mesh_gateway.go | 44 - .../mesh/internal/types/mesh_gateway_test.go | 97 - .../internal/types/proxy_configuration.go | 211 -- .../types/proxy_configuration_test.go | 360 --- .../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 | 27 - internal/mesh/internal/types/types_test.go | 49 - 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 | 77 - internal/mesh/proxy-tracker/proxy_tracker.go | 267 -- .../mesh/proxy-tracker/proxy_tracker_test.go | 340 --- internal/multicluster/exports.go | 21 - .../controllers/exportedservices/builder.go | 166 -- .../exportedservices/controller.go | 390 --- .../exportedservices/controller_test.go | 976 ------ .../exportedservices/expander/expander_ce.go | 12 - .../expander/expander_ce/expander.go | 47 - .../expander/expander_ce/expander_test.go | 57 - .../exportedservices/expander/types/types.go | 10 - .../exportedservices/helpers_ce.go | 14 - .../controllers/exportedservices/status.go | 42 - .../internal/controllers/register.go | 9 - .../controllers/v1compat/controller.go | 9 +- .../controllers/v1compat/controller_test.go | 3 +- .../multicluster/internal/types/decoded.go | 3 - internal/multicluster/internal/types/types.go | 8 - .../multicluster/internal/types/types_ce.go | 12 - internal/resource/demo/demo.go | 18 + .../selectiontracker/selection_tracker.go | 209 -- .../selection_tracker_test.go | 375 --- internal/resource/resource_test.go | 8 +- .../resourcehcl/testdata/destinations.golden | 1 - .../resourcehcl/testdata/destinations.hcl | 25 - .../resourcehcl/testdata/no-blocks.golden | 1 - internal/resourcehcl/testdata/no-blocks.hcl | 33 - internal/resourcehcl/unmarshal_test.go | 3 - internal/tenancy/exports.go | 34 - .../tenancy/internal/bridge/tenancy_bridge.go | 76 - .../internal/bridge/tenancy_bridge_ce.go | 21 - .../internal/controllers/common/common.go | 196 -- .../controllers/namespace/controller.go | 94 - .../tenancy/internal/controllers/register.go | 12 - .../internal/controllers/register_ce.go | 15 - internal/tenancy/internal/types/errors.go | 11 - internal/tenancy/internal/types/namespace.go | 69 - internal/tenancy/internal/types/types.go | 10 - internal/tenancy/internal/types/types_ce.go | 12 - internal/tenancy/internal/types/types_test.go | 121 - .../tenancytest/namespace_controller_test.go | 156 - .../tenancy/tenancytest/namespace_test.go | 116 - proto-public/go.mod | 8 - proto-public/go.sum | 20 - .../computed_traffic_permissions.pb.binary.go | 18 - .../computed_traffic_permissions.pb.go | 223 -- .../computed_traffic_permissions.proto | 22 - ...mputed_traffic_permissions_deepcopy.gen.go | 27 - .../computed_traffic_permissions_json.gen.go | 22 - .../pbauth/v2beta1/resources.rtypes.go | 50 - .../v2beta1/traffic_permission_extras_test.go | 63 - .../v2beta1/traffic_permissions.pb.binary.go | 108 - .../pbauth/v2beta1/traffic_permissions.pb.go | 1194 -------- .../pbauth/v2beta1/traffic_permissions.proto | 141 - .../v2beta1/traffic_permissions_addon.go | 25 - .../traffic_permissions_deepcopy.gen.go | 216 -- .../v2beta1/traffic_permissions_extras.go | 60 - .../v2beta1/traffic_permissions_json.gen.go | 121 - .../v2beta1/workload_identity.pb.binary.go | 18 - .../pbauth/v2beta1/workload_identity.pb.go | 158 - .../pbauth/v2beta1/workload_identity.proto | 12 - .../v2beta1/workload_identity_deepcopy.gen.go | 27 - .../v2beta1/workload_identity_json.gen.go | 22 - .../computed_failover_policy.pb.binary.go | 18 - .../v2beta1/computed_failover_policy.pb.go | 227 -- .../v2beta1/computed_failover_policy.proto | 26 - .../computed_failover_policy_deepcopy.gen.go | 27 - .../computed_failover_policy_extras.go | 48 - .../computed_failover_policy_extras_test.go | 70 - .../computed_failover_policy_json.gen.go | 22 - .../v2beta1/failover_policy.pb.binary.go | 38 - .../pbcatalog/v2beta1/failover_policy.pb.go | 467 --- .../pbcatalog/v2beta1/failover_policy.proto | 60 - .../v2beta1/failover_policy_deepcopy.gen.go | 69 - .../v2beta1/failover_policy_extras.go | 15 - .../v2beta1/failover_policy_extras_test.go | 110 - .../v2beta1/failover_policy_json.gen.go | 44 - .../pbcatalog/v2beta1/health.pb.binary.go | 108 - proto-public/pbcatalog/v2beta1/health.pb.go | 1158 -------- proto-public/pbcatalog/v2beta1/health.proto | 105 - .../pbcatalog/v2beta1/health_deepcopy.gen.go | 216 -- .../pbcatalog/v2beta1/health_json.gen.go | 121 - .../pbcatalog/v2beta1/node.pb.binary.go | 28 - proto-public/pbcatalog/v2beta1/node.pb.go | 247 -- proto-public/pbcatalog/v2beta1/node.proto | 23 - .../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/resources.rtypes.go | 85 - .../pbcatalog/v2beta1/selector.pb.binary.go | 18 - proto-public/pbcatalog/v2beta1/selector.pb.go | 185 -- proto-public/pbcatalog/v2beta1/selector.proto | 13 - .../v2beta1/selector_deepcopy.gen.go | 27 - .../pbcatalog/v2beta1/selector_json.gen.go | 22 - .../pbcatalog/v2beta1/service.pb.binary.go | 28 - proto-public/pbcatalog/v2beta1/service.pb.go | 310 -- proto-public/pbcatalog/v2beta1/service.proto | 46 - .../pbcatalog/v2beta1/service_addon.go | 120 - .../pbcatalog/v2beta1/service_addon_test.go | 208 -- .../pbcatalog/v2beta1/service_deepcopy.gen.go | 48 - .../v2beta1/service_endpoints.pb.binary.go | 28 - .../pbcatalog/v2beta1/service_endpoints.pb.go | 336 --- .../pbcatalog/v2beta1/service_endpoints.proto | 41 - .../v2beta1/service_endpoints_addon.go | 29 - .../v2beta1/service_endpoints_addon_test.go | 52 - .../v2beta1/service_endpoints_deepcopy.gen.go | 48 - .../v2beta1/service_endpoints_json.gen.go | 33 - .../pbcatalog/v2beta1/service_json.gen.go | 33 - .../pbcatalog/v2beta1/vip.pb.binary.go | 28 - proto-public/pbcatalog/v2beta1/vip.pb.go | 247 -- proto-public/pbcatalog/v2beta1/vip.proto | 24 - .../pbcatalog/v2beta1/vip_deepcopy.gen.go | 48 - .../pbcatalog/v2beta1/vip_json.gen.go | 33 - .../pbcatalog/v2beta1/workload.pb.binary.go | 68 - proto-public/pbcatalog/v2beta1/workload.pb.go | 675 ----- proto-public/pbcatalog/v2beta1/workload.proto | 81 - .../pbcatalog/v2beta1/workload_addon.go | 80 - .../pbcatalog/v2beta1/workload_addon_test.go | 262 -- .../v2beta1/workload_deepcopy.gen.go | 132 - .../pbcatalog/v2beta1/workload_json.gen.go | 77 - proto-public/pbdataplane/dataplane.pb.go | 296 +- proto-public/pbdataplane/dataplane.proto | 4 +- .../pbmesh/v2beta1/api_gateway.pb.binary.go | 38 - proto-public/pbmesh/v2beta1/api_gateway.pb.go | 398 --- proto-public/pbmesh/v2beta1/api_gateway.proto | 54 - .../v2beta1/api_gateway_deepcopy.gen.go | 69 - .../pbmesh/v2beta1/api_gateway_json.gen.go | 44 - .../pbmesh/v2beta1/common.pb.binary.go | 28 - proto-public/pbmesh/v2beta1/common.pb.go | 280 -- proto-public/pbmesh/v2beta1/common.proto | 37 - .../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_gateway_routes.pb.binary.go | 18 - .../v2beta1/computed_gateway_routes.pb.go | 215 -- .../v2beta1/computed_gateway_routes.proto | 27 - .../computed_gateway_routes_deepcopy.gen.go | 27 - .../computed_gateway_routes_json.gen.go | 22 - ...omputed_implicit_destinations.pb.binary.go | 28 - .../computed_implicit_destinations.pb.go | 273 -- .../computed_implicit_destinations.proto | 24 - ...uted_implicit_destinations_deepcopy.gen.go | 48 - ...computed_implicit_destinations_json.gen.go | 33 - .../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 | 1625 ---------- .../pbmesh/v2beta1/computed_routes.proto | 175 -- .../v2beta1/computed_routes_deepcopy.gen.go | 300 -- .../v2beta1/computed_routes_json.gen.go | 165 - .../pbmesh/v2beta1/connection.pb.binary.go | 28 - 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 | 1106 ------- .../pbmesh/v2beta1/destination_policy.proto | 163 - .../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 | 671 ----- .../pbmesh/v2beta1/destinations.proto | 80 - .../destinations_configuration.pb.binary.go | 58 - .../v2beta1/destinations_configuration.pb.go | 704 ----- .../v2beta1/destinations_configuration.proto | 112 - ...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 - .../pbmesh/v2beta1/expose.pb.binary.go | 28 - 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 - .../v2beta1/mesh_configuration.pb.binary.go | 18 - .../pbmesh/v2beta1/mesh_configuration.pb.go | 160 - .../pbmesh/v2beta1/mesh_configuration.proto | 14 - .../mesh_configuration_deepcopy.gen.go | 27 - .../v2beta1/mesh_configuration_json.gen.go | 22 - .../pbmesh/v2beta1/mesh_gateway.pb.binary.go | 28 - .../pbmesh/v2beta1/mesh_gateway.pb.go | 289 -- .../pbmesh/v2beta1/mesh_gateway.proto | 31 - .../v2beta1/mesh_gateway_deepcopy.gen.go | 48 - .../pbmesh/v2beta1/mesh_gateway_json.gen.go | 33 - .../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 | 700 ----- .../pbproxystate/header_mutations.proto | 50 - .../header_mutations_deepcopy.gen.go | 132 - .../pbproxystate/header_mutations_json.gen.go | 77 - .../v2beta1/pbproxystate/intentions.pb.go | 211 -- .../pbproxystate/listener.pb.binary.go | 88 - .../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 | 22 - .../pbproxystate/references.pb.binary.go | 38 - .../v2beta1/pbproxystate/references.pb.go | 382 --- .../v2beta1/pbproxystate/references.proto | 31 - .../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 | 78 - .../pbproxystate/traffic_permissions.pb.go | 799 ----- .../pbproxystate/traffic_permissions.proto | 64 - .../traffic_permissions_deepcopy.gen.go | 153 - .../traffic_permissions_json.gen.go | 88 - .../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 - .../v2beta1/proxy_configuration.pb.binary.go | 68 - .../pbmesh/v2beta1/proxy_configuration.pb.go | 1227 -------- .../pbmesh/v2beta1/proxy_configuration.proto | 173 -- .../v2beta1/proxy_configuration_addon.go | 14 - .../v2beta1/proxy_configuration_addon_test.go | 53 - .../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/resources.rtypes.go | 127 - proto-public/pbmesh/v2beta1/routing.pb.go | 183 -- proto-public/pbmesh/v2beta1/routing.proto | 38 - .../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 | 173 -- .../v2beta1/resources.rtypes.go | 22 - .../v2beta1/sameness_group.pb.binary.go | 28 - .../v2beta1/sameness_group.pb.go | 292 -- .../v2beta1/sameness_group.proto | 22 - .../v2beta1/sameness_group_deepcopy.gen.go | 48 - .../v2beta1/sameness_group_json.gen.go | 33 - .../pbtenancy/v2beta1/namespace.pb.binary.go | 18 - .../pbtenancy/v2beta1/namespace.pb.go | 174 -- .../pbtenancy/v2beta1/namespace.proto | 19 - .../v2beta1/namespace_deepcopy.gen.go | 27 - .../pbtenancy/v2beta1/namespace_json.gen.go | 22 - .../pbtenancy/v2beta1/partition.pb.binary.go | 18 - .../pbtenancy/v2beta1/partition.pb.go | 183 -- .../pbtenancy/v2beta1/partition.proto | 20 - .../v2beta1/partition_deepcopy.gen.go | 27 - .../pbtenancy/v2beta1/partition_json.gen.go | 22 - .../pbtenancy/v2beta1/resources.rtypes.go | 29 - proto/private/pbconnect/connect.gen.go | 4 - proto/private/pbconnect/connect.pb.go | 100 +- proto/private/pbconnect/connect.proto | 6 +- proto/private/pbdemo/v2/demo.pb.binary.go | 10 + proto/private/pbdemo/v2/demo.pb.go | 252 +- proto/private/pbdemo/v2/demo.proto | 12 + proto/private/pbdemo/v2/resources.rtypes.go | 11 +- test/integration/consul-container/go.mod | 2 +- .../consul-container/libs/assert/service.go | 69 +- testing/deployer/util/v2.go | 7 - 1247 files changed, 963 insertions(+), 186769 deletions(-) create mode 100644 .changelog/21592.txt 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_test.go delete mode 100644 agent/consul/leader_ce.go delete mode 100644 agent/consul/leader_registrator_v2.go delete mode 100644 agent/consul/leader_registrator_v2_test.go delete mode 100644 agent/grpc-external/services/resource/delete_ce.go delete mode 100644 agent/proxycfg-sources/catalog/config_source_oss.go delete mode 100644 agent/structs/acltemplatedpolicy/policies/ce/workload-identity.hcl delete mode 100644 agent/structs/acltemplatedpolicy/schemas/workload-identity.json 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 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-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/mixed-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/mixed-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/mixed-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/mixed-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l7-expose-paths-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l7-expose-paths-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l7-expose-paths-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l7-expose-paths-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/local-and-inbound-connections-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/local-and-inbound-connections-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/local-and-inbound-connections-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/local-and-inbound-connections-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l7-expose-paths-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l7-expose-paths-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l7-expose-paths-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l7-expose-paths-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/mixed-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/mixed-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/mixed-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/mixed-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l7-expose-paths-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l7-expose-paths-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l7-expose-paths-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l7-expose-paths-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/local-and-inbound-connections-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/local-and-inbound-connections-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/local-and-inbound-connections-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/local-and-inbound-connections-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/mixed-multi-destination-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/mixed-multi-destination-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l7-expose-paths-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l7-expose-paths-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l7-expose-paths-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l7-expose-paths-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/local-and-inbound-connections-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/local-and-inbound-connections-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/local-and-inbound-connections-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/local-and-inbound-connections-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/single-workload-address-without-ports-default-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/single-workload-address-without-ports-default-default.golden delete mode 100644 agent/xdsv2/testdata/routes/source/single-workload-address-without-ports-foo-bar.golden delete mode 100644 agent/xdsv2/testdata/routes/source/single-workload-address-without-ports-foo-default.golden delete mode 100644 internal/auth/exports.go delete mode 100644 internal/auth/internal/controllers/register.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/builder.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/expander/expander_ce.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/expander/expander_ce/expander_ce.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/expander/interface.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/helpers_ce.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/index.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/namespace_traffic_permissions.go delete mode 100644 internal/auth/internal/types/namespace_traffic_permissions_test.go delete mode 100644 internal/auth/internal/types/partition_traffic_permissions.go delete mode 100644 internal/auth/internal/types/partition_traffic_permissions_test.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/validate.go delete mode 100644 internal/auth/internal/types/validate_ce.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 delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-service.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service-endpoints.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/grpc-api-service.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/http-api-service.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-1-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-1.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-2-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-2.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-3-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-3.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-4-health.json delete mode 100644 internal/catalog/catalogtest/integration_test_data/v2beta1/node-4.json delete mode 100644 internal/catalog/catalogtest/run_test.go delete mode 100644 internal/catalog/catalogtest/test_integration_v2beta1.go delete mode 100644 internal/catalog/catalogtest/test_lifecycle_v2beta1.go delete mode 100644 internal/catalog/exports.go delete mode 100644 internal/catalog/internal/controllers/endpoints/bound.go delete mode 100644 internal/catalog/internal/controllers/endpoints/bound_test.go delete mode 100644 internal/catalog/internal/controllers/endpoints/controller.go delete mode 100644 internal/catalog/internal/controllers/endpoints/controller_test.go delete mode 100644 internal/catalog/internal/controllers/endpoints/status.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/expander/expander_ce.go delete mode 100644 internal/catalog/internal/controllers/failover/expander/expander_ce/expander.go delete mode 100644 internal/catalog/internal/controllers/failover/expander/expander_ce/expander_test.go delete mode 100644 internal/catalog/internal/controllers/failover/expander/interface.go delete mode 100644 internal/catalog/internal/controllers/failover/helpers_ce.go delete mode 100644 internal/catalog/internal/controllers/failover/status.go delete mode 100644 internal/catalog/internal/controllers/nodehealth/controller.go delete mode 100644 internal/catalog/internal/controllers/nodehealth/controller_test.go delete mode 100644 internal/catalog/internal/controllers/nodehealth/status.go delete mode 100644 internal/catalog/internal/controllers/register.go delete mode 100644 internal/catalog/internal/controllers/workloadhealth/controller.go delete mode 100644 internal/catalog/internal/controllers/workloadhealth/controller_test.go delete mode 100644 internal/catalog/internal/controllers/workloadhealth/status.go delete mode 100644 internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go delete mode 100644 internal/catalog/internal/types/computed_failover_policy.go delete mode 100644 internal/catalog/internal/types/computed_failover_policy_test.go delete mode 100644 internal/catalog/internal/types/errors.go delete mode 100644 internal/catalog/internal/types/errors_test.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/health_checks.go delete mode 100644 internal/catalog/internal/types/health_checks_test.go delete mode 100644 internal/catalog/internal/types/health_status.go delete mode 100644 internal/catalog/internal/types/health_status_test.go delete mode 100644 internal/catalog/internal/types/node.go delete mode 100644 internal/catalog/internal/types/node_health_status.go delete mode 100644 internal/catalog/internal/types/node_health_status_test.go delete mode 100644 internal/catalog/internal/types/node_test.go delete mode 100644 internal/catalog/internal/types/service.go delete mode 100644 internal/catalog/internal/types/service_endpoints.go delete mode 100644 internal/catalog/internal/types/service_endpoints_test.go delete mode 100644 internal/catalog/internal/types/service_test.go delete mode 100644 internal/catalog/internal/types/testdata/errDNSPassingWeightOutOfRange.golden delete mode 100644 internal/catalog/internal/types/testdata/errDNSWarningWeightOutOfRange.golden delete mode 100644 internal/catalog/internal/types/testdata/errInvalidEndpointsOwnerName.golden delete mode 100644 internal/catalog/internal/types/testdata/errInvalidNodeHostFormat.golden delete mode 100644 internal/catalog/internal/types/testdata/errInvalidPhysicalPort.golden delete mode 100644 internal/catalog/internal/types/testdata/errInvalidPortReference.golden delete mode 100644 internal/catalog/internal/types/testdata/errInvalidVirtualPort.golden delete mode 100644 internal/catalog/internal/types/testdata/errInvalidWorkloadHostFormat.golden delete mode 100644 internal/catalog/internal/types/testdata/errLocalityZoneNoRegion.golden delete mode 100644 internal/catalog/internal/types/testdata/errNotDNSLabel.golden delete mode 100644 internal/catalog/internal/types/testdata/errNotIPAddress.golden delete mode 100644 internal/catalog/internal/types/testdata/errTooMuchMesh.golden delete mode 100644 internal/catalog/internal/types/testdata/errUnixSocketMultiport.golden delete mode 100644 internal/catalog/internal/types/testdata/errVirtualPortReused.golden delete mode 100644 internal/catalog/internal/types/types.go delete mode 100644 internal/catalog/internal/types/types_test.go delete mode 100644 internal/catalog/internal/types/validators.go delete mode 100644 internal/catalog/internal/types/validators_test.go delete mode 100644 internal/catalog/internal/types/virtual_ips.go delete mode 100644 internal/catalog/internal/types/virtual_ips_test.go delete mode 100644 internal/catalog/internal/types/workload.go delete mode 100644 internal/catalog/internal/types/workload_test.go delete mode 100644 internal/catalog/workloadselector/acls.go delete mode 100644 internal/catalog/workloadselector/acls_test.go delete mode 100644 internal/catalog/workloadselector/gather.go delete mode 100644 internal/catalog/workloadselector/gather_test.go delete mode 100644 internal/catalog/workloadselector/index.go delete mode 100644 internal/catalog/workloadselector/index_test.go delete mode 100644 internal/catalog/workloadselector/integ_test.go delete mode 100644 internal/catalog/workloadselector/mapper.go delete mode 100644 internal/catalog/workloadselector/mapper_test.go delete mode 100644 internal/catalog/workloadselector/selecting.go delete mode 100644 internal/mesh/exports.go delete mode 100644 internal/mesh/internal/controllers/apigateways/controller.go delete mode 100644 internal/mesh/internal/controllers/apigateways/controller_test.go delete mode 100644 internal/mesh/internal/controllers/apigateways/fetcher/data_fetcher.go delete mode 100644 internal/mesh/internal/controllers/apigateways/fetcher/data_fetcher_test.go 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/gatewayproxy/builder/api_gateway_builder.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/builder/mesh_gateway_builder.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/builder/mesh_gateway_builder_test.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/controller.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/controller_test.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/fetcher/data_fetcher.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/fetcher/data_fetcher_test.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/mapper/apigatewayworkloads.go delete mode 100644 internal/mesh/internal/controllers/gatewayproxy/mapper/meshgatewayworkloads.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/auth_helper_test.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/controller.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/controller_test.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/index.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/index_test.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/mapper.go delete mode 100644 internal/mesh/internal/controllers/implicitdestinations/status.go delete mode 100644 internal/mesh/internal/controllers/meshconfiguration/controller.go delete mode 100644 internal/mesh/internal/controllers/meshconfiguration/controller_test.go delete mode 100644 internal/mesh/internal/controllers/meshgateways/controller.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/controller.go delete mode 100644 internal/mesh/internal/controllers/routes/controller_test.go delete mode 100644 internal/mesh/internal/controllers/routes/destination_policy_validation.go delete mode 100644 internal/mesh/internal/controllers/routes/destination_policy_validation_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/.mockery.yaml 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/routes/xroutemapper/xroutemappermock/mock_ResolveFailoverServiceDestinations.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections-foo-default.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/multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports-foo-default.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/builder/testdata/source/single-workload-address-without-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports.golden 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/data_fetcher.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/data_fetcher_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/helper_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/mapper.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections-foo-default.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/multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports-foo-default.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-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports-foo-default.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/controllers/xds/testdata/source/single-workload-address-without-ports-default-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/single-workload-address-without-ports-default-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/single-workload-address-without-ports-foo-bar.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/single-workload-address-without-ports-foo-default.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/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/meshindexes/computed_routes.go delete mode 100644 internal/mesh/internal/meshindexes/computed_routes_test.go delete mode 100644 internal/mesh/internal/types/api_gateway.go delete mode 100644 internal/mesh/internal/types/computed_explicit_destinations.go delete mode 100644 internal/mesh/internal/types/computed_implicit_destinations.go delete mode 100644 internal/mesh/internal/types/computed_implicit_destinations_test.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/mesh_configuration.go delete mode 100644 internal/mesh/internal/types/mesh_gateway.go delete mode 100644 internal/mesh/internal/types/mesh_gateway_test.go delete mode 100644 internal/mesh/internal/types/proxy_configuration.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 delete mode 100644 internal/mesh/internal/types/types.go delete mode 100644 internal/mesh/internal/types/types_test.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/internal/controllers/exportedservices/builder.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/controller.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/controller_test.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/expander/expander_ce.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/expander/expander_ce/expander.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/expander/expander_ce/expander_test.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/expander/types/types.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/helpers_ce.go delete mode 100644 internal/multicluster/internal/controllers/exportedservices/status.go delete mode 100644 internal/multicluster/internal/types/types_ce.go delete mode 100644 internal/resource/mappers/selectiontracker/selection_tracker.go delete mode 100644 internal/resource/mappers/selectiontracker/selection_tracker_test.go delete mode 100644 internal/resourcehcl/testdata/destinations.golden delete mode 100644 internal/resourcehcl/testdata/destinations.hcl delete mode 100644 internal/resourcehcl/testdata/no-blocks.golden delete mode 100644 internal/resourcehcl/testdata/no-blocks.hcl 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/common/common.go delete mode 100644 internal/tenancy/internal/controllers/namespace/controller.go delete mode 100644 internal/tenancy/internal/controllers/register.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_controller_test.go delete mode 100644 internal/tenancy/tenancytest/namespace_test.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/resources.rtypes.go delete mode 100644 proto-public/pbauth/v2beta1/traffic_permission_extras_test.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_extras.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 delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy.pb.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy.proto delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy_extras.go delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy_extras_test.go delete mode 100644 proto-public/pbcatalog/v2beta1/computed_failover_policy_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.pb.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/health.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/health.proto 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.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/node.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/node.proto 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/resources.rtypes.go delete mode 100644 proto-public/pbcatalog/v2beta1/selector.pb.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/selector.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/selector.proto 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.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/service.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/service.proto 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.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints.proto 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.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/vip.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/vip.proto 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.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload.proto 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/pbmesh/v2beta1/api_gateway.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/api_gateway.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/api_gateway.proto delete mode 100644 proto-public/pbmesh/v2beta1/api_gateway_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/api_gateway_json.gen.go 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_gateway_routes.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_gateway_routes.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_gateway_routes.proto delete mode 100644 proto-public/pbmesh/v2beta1/computed_gateway_routes_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_gateway_routes_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_implicit_destinations.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_implicit_destinations.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_implicit_destinations.proto delete mode 100644 proto-public/pbmesh/v2beta1/computed_implicit_destinations_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_implicit_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.binary.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.binary.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/mesh_configuration.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_configuration.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_configuration.proto delete mode 100644 proto-public/pbmesh/v2beta1/mesh_configuration_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_configuration_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_gateway.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_gateway.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_gateway.proto delete mode 100644 proto-public/pbmesh/v2beta1/mesh_gateway_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/mesh_gateway_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.binary.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.binary.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/resources.rtypes.go delete mode 100644 proto-public/pbmesh/v2beta1/routing.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/routing.proto 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/resources.rtypes.go delete mode 100644 proto-public/pbmulticluster/v2beta1/sameness_group.pb.binary.go delete mode 100644 proto-public/pbmulticluster/v2beta1/sameness_group.pb.go delete mode 100644 proto-public/pbmulticluster/v2beta1/sameness_group.proto delete mode 100644 proto-public/pbmulticluster/v2beta1/sameness_group_deepcopy.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/sameness_group_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/partition.pb.binary.go delete mode 100644 proto-public/pbtenancy/v2beta1/partition.pb.go delete mode 100644 proto-public/pbtenancy/v2beta1/partition.proto delete mode 100644 proto-public/pbtenancy/v2beta1/partition_deepcopy.gen.go delete mode 100644 proto-public/pbtenancy/v2beta1/partition_json.gen.go delete mode 100644 proto-public/pbtenancy/v2beta1/resources.rtypes.go diff --git a/.changelog/21592.txt b/.changelog/21592.txt new file mode 100644 index 0000000000..a8a69f0d9b --- /dev/null +++ b/.changelog/21592.txt @@ -0,0 +1,3 @@ +```release-note:feature +server: remove v2 tenancy, catalog, and mesh experiments +``` diff --git a/Makefile b/Makefile index 71dcbef074..6ad1da52a1 100644 --- a/Makefile +++ b/Makefile @@ -294,7 +294,6 @@ lint-container-test-deps: ## Check that the test-container module only imports a @cd test/integration/consul-container && \ $(CURDIR)/build-support/scripts/check-allowed-imports.sh \ github.com/hashicorp/consul \ - "internal/catalog/catalogtest" \ "internal/resource/resourcetest" ##@ Testing diff --git a/acl/MockAuthorizer.go b/acl/MockAuthorizer.go index e3a97ceec9..7e41db074f 100644 --- a/acl/MockAuthorizer.go +++ b/acl/MockAuthorizer.go @@ -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 { diff --git a/acl/acl_test.go b/acl/acl_test.go index 28542024e9..3f4c882b0e 100644 --- a/acl/acl_test.go +++ b/acl/acl_test.go @@ -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)) } @@ -196,22 +180,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)) } @@ -360,22 +328,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)) } @@ -516,10 +468,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}, @@ -554,10 +502,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}, @@ -597,10 +541,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}, @@ -1000,134 +940,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 39bac5f7b0..937d861129 100644 --- a/acl/authorizer.go +++ b/acl/authorizer.go @@ -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. // @@ -267,40 +253,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 -} - // IntentionReadAllowed determines if a specific intention can be read. func (a AllowAuthorizer) IntentionReadAllowed(name string, ctx *AuthorizerContext) error { if a.Authorizer.IntentionRead(name, ctx) != Allow { @@ -579,13 +531,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_test.go b/acl/authorizer_test.go index d538a04ad7..09cba85fa6 100644 --- a/acl/authorizer_test.go +++ b/acl/authorizer_test.go @@ -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 26f0c2dfe7..15016e9849 100644 --- a/acl/chained_authorizer.go +++ b/acl/chained_authorizer.go @@ -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 { diff --git a/acl/policy.go b/acl/policy.go index 0c88a9041b..86c9e83cfc 100644 --- a/acl/policy.go +++ b/acl/policy.go @@ -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"` @@ -77,6 +75,11 @@ type PolicyRules struct { Operator string `hcl:"operator"` Mesh string `hcl:"mesh"` Peering string `hcl:"peering"` + + // Deprecated: exists just to track the former field for decoding + Identities []*IdentityRule `hcl:"identity,expand"` + // Deprecated: exists just to track the former field for decoding + IdentityPrefixes []*IdentityRule `hcl:"identity_prefix,expand"` } // Policy is used to represent the policy specified by an ACL configuration. @@ -93,6 +96,8 @@ type AgentRule struct { } // IdentityRule represents a policy for a workload identity +// +// Deprecated: exists just to track the former field for decoding type IdentityRule struct { Name string `hcl:",key"` Policy string @@ -183,29 +188,9 @@ 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) - } - } + // Identity rules are deprecated, zero them out. + pr.Identities = nil + pr.IdentityPrefixes = nil // Validate the key policy for _, kp := range pr.Keys { diff --git a/acl/policy_authorizer.go b/acl/policy_authorizer.go index 11d19609ef..16ffa743f9 100644 --- a/acl/policy_authorizer.go +++ b/acl/policy_authorizer.go @@ -14,9 +14,6 @@ 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 @@ -186,48 +183,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 { @@ -397,7 +352,6 @@ 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(), @@ -578,33 +532,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 { diff --git a/acl/policy_authorizer_test.go b/acl/policy_authorizer_test.go index 96272d8b12..a2f9b929f1 100644 --- a/acl/policy_authorizer_test.go +++ b/acl/policy_authorizer_test.go @@ -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}, @@ -190,29 +187,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", @@ -400,22 +374,6 @@ func TestPolicyAuthorizer(t *testing.T) { {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: "IntentionReadPrefixAllowed", prefix: "fo", check: checkAllowIntentionRead}, {name: "IntentionWritePrefixDenied", prefix: "fo", check: checkDenyIntentionWrite}, {name: "IntentionReadPrefixAllowed", prefix: "for", check: checkAllowIntentionRead}, diff --git a/acl/policy_test.go b/acl/policy_test.go index 599c8c977e..2ce0b32892 100644 --- a/acl/policy_test.go +++ b/acl/policy_test.go @@ -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/agent/acl_endpoint_test.go b/agent/acl_endpoint_test.go index 060f1f03ef..7b484e092b 100644 --- a/agent/acl_endpoint_test.go +++ b/agent/acl_endpoint_test.go @@ -15,9 +15,10 @@ import ( "time" "github.com/go-jose/go-jose/v3/jwt" - "github.com/hashicorp/go-uuid" "github.com/stretchr/testify/require" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/consul/authmethod/testauth" "github.com/hashicorp/consul/agent/structs" @@ -1407,7 +1408,7 @@ func TestACL_HTTP(t *testing.T) { var list map[string]api.ACLTemplatedPolicyResponse require.NoError(t, json.NewDecoder(resp.Body).Decode(&list)) - require.Len(t, list, 7) + require.Len(t, list, 6) require.Equal(t, api.ACLTemplatedPolicyResponse{ TemplateName: api.ACLTemplatedPolicyServiceName, @@ -2225,7 +2226,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}, @@ -2311,16 +2312,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", @@ -2471,16 +2462,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", @@ -2587,8 +2568,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/ae/ae.go b/agent/ae/ae.go index f8b9a331d1..94db2a7cf0 100644 --- a/agent/ae/ae.go +++ b/agent/ae/ae.go @@ -152,14 +152,6 @@ 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() { diff --git a/agent/agent.go b/agent/agent.go index a3916922df..a509ea2b34 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -69,7 +69,6 @@ import ( "github.com/hashicorp/consul/api/watch" libdns "github.com/hashicorp/consul/internal/dnsutil" "github.com/hashicorp/consul/internal/gossip/librtt" - 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" @@ -639,9 +638,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 { @@ -673,10 +669,6 @@ 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 { @@ -716,13 +708,7 @@ func (a *Agent) Start(ctx context.Context) error { nil, ) - 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) + consulServer, err = consul.NewServer(consulCfg, a.baseDeps.Deps, a.externalGRPCServer, incomingRPCLimiter, serverLogger) if err != nil { return fmt.Errorf("Failed to start Consul server: %v", err) } @@ -746,10 +732,6 @@ func (a *Agent) Start(ctx context.Context) error { } } } else { - if a.baseDeps.UseV2Resources() { - return fmt.Errorf("can't start agent: client agents are not supported with v2 resources") - } - // the conn is used to connect to the consul server agent conn, err := a.baseDeps.GRPCConnPool.ClientConn(a.baseDeps.RuntimeConfig.Datacenter) if err != nil { @@ -895,7 +877,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(consulServer); err != nil { return err } @@ -956,28 +938,20 @@ func (a *Agent) configureXDSServer(proxyWatcher xds.ProxyWatcher, server *consul // 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 - } + 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 } a.xdsServer = xds.NewServer( a.config.NodeName, @@ -991,16 +965,11 @@ func (a *Agent) configureXDSServer(proxyWatcher xds.ProxyWatcher, server *consul a.xdsServer.Register(a.externalGRPCServer) } -func (a *Agent) listenAndServeGRPC(proxyTracker *proxytracker.ProxyTracker, server *consul.Server) error { +func (a *Agent) listenAndServeGRPC(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) - } + var proxyWatcher xds.ProxyWatcher = localproxycfg.NewConfigSource(a.proxyConfig) a.configureXDSServer(proxyWatcher, server) diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go index 9fd76fae4f..69551d7c36 100644 --- a/agent/agent_endpoint_test.go +++ b/agent/agent_endpoint_test.go @@ -21,14 +21,15 @@ import ( "time" "github.com/armon/go-metrics" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" - "github.com/hashicorp/serf/serf" "github.com/mitchellh/hashstructure" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/time/rate" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/serf/serf" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/agent/config" @@ -79,46 +80,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") @@ -1660,6 +1621,7 @@ func newDefaultBaseDeps(t *testing.T) BaseDeps { } func TestHTTPHandlers_AgentMetricsStream_ACLDeny(t *testing.T) { + t.Skip("this test panics without a license manager in enterprise") bd := newDefaultBaseDeps(t) bd.Tokens = new(tokenStore.Store) sink := metrics.NewInmemSink(30*time.Millisecond, time.Second) @@ -1691,6 +1653,7 @@ func TestHTTPHandlers_AgentMetricsStream_ACLDeny(t *testing.T) { } func TestHTTPHandlers_AgentMetricsStream(t *testing.T) { + t.Skip("this test panics without a license manager in enterprise") bd := newDefaultBaseDeps(t) bd.Tokens = new(tokenStore.Store) sink := metrics.NewInmemSink(20*time.Millisecond, time.Second) diff --git a/agent/catalog_endpoint_test.go b/agent/catalog_endpoint_test.go index 4aafc8a029..c06efc748c 100644 --- a/agent/catalog_endpoint_test.go +++ b/agent/catalog_endpoint_test.go @@ -6,18 +6,17 @@ package agent import ( "context" "fmt" - "io" "net/http" "net/http/httptest" "net/url" - "strings" "testing" "time" - "github.com/hashicorp/serf/coordinate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/hashicorp/serf/coordinate" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" @@ -31,49 +30,6 @@ func addQueryParam(req *http.Request, param, value string) { req.URL.RawQuery = q.Encode() } -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/config/builder.go b/agent/config/builder.go index 5c2eba5c55..f8d0df7b5c 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -1144,23 +1144,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 - if !stringslice.Contains(rt.Experiments, consul.HCPAllowV2ResourceAPIs) { - return RuntimeConfig{}, fmt.Errorf("`experiments` cannot include 'resource-apis' when HCP `cloud` configuration is set") - } - } - - // For now, disallow usage of several v2 experiments in secondary datacenters. - if rt.ServerMode && rt.PrimaryDatacenter != rt.Datacenter { - for _, name := range rt.Experiments { - if !consul.IsExperimentAllowedOnSecondaries(name) { - return RuntimeConfig{}, fmt.Errorf("`experiments` cannot include `%s` for servers in secondary datacenters", name) - } - } - } - if rt.UIConfig.MetricsProvider == "prometheus" { // Handle defaulting for the built-in version of prometheus. if len(rt.UIConfig.MetricsProxy.PathAllowlist) == 0 { diff --git a/agent/config/builder_test.go b/agent/config/builder_test.go index a587dec132..26d20bdfba 100644 --- a/agent/config/builder_test.go +++ b/agent/config/builder_test.go @@ -615,23 +615,9 @@ func TestBuilder_CheckExperimentsInSecondaryDatacenters(t *testing.T) { "primary server no experiments": { hcl: primary + `experiments = []`, }, - "primary server v2catalog": { - hcl: primary + `experiments = ["resource-apis"]`, - }, - "primary server v2tenancy": { - hcl: primary + `experiments = ["v2tenancy"]`, - }, "secondary server no experiments": { hcl: secondary + `experiments = []`, }, - "secondary server v2catalog": { - hcl: secondary + `experiments = ["resource-apis"]`, - expectErr: true, - }, - "secondary server v2tenancy": { - hcl: secondary + `experiments = ["v2tenancy"]`, - expectErr: true, - }, } for name, tc := range cases { @@ -641,67 +627,6 @@ func TestBuilder_CheckExperimentsInSecondaryDatacenters(t *testing.T) { } } -func TestBuilder_WarnCloudConfigWithResourceApis(t *testing.T) { - tests := []struct { - name string - hcl string - expectErr 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", "hcp-v2-resource-apis"] - cloud{ resource_id = "abc" client_id = "abc" client_secret = "abc"}`, - }, - } - 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, - }, - }, - } - _, err := Load(builderOpts) - if tc.expectErr { - require.Error(t, err) - require.Contains(t, err.Error(), "cannot include 'resource-apis' when HCP") - } else { - require.NoError(t, err) - } - } -} - func TestBuilder_CloudConfigWithEnvironmentVars(t *testing.T) { tests := map[string]struct { hcl string diff --git a/agent/config/runtime_test.go b/agent/config/runtime_test.go index 257f320a55..a36d5f67da 100644 --- a/agent/config/runtime_test.go +++ b/agent/config/runtime_test.go @@ -6015,24 +6015,6 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { 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.WAL.SegmentSize = 64 * 1024 * 1024 - rt.Experiments = []string{"resource-apis"} - }, - }) run(t, testCase{ // this was a bug in the initial config commit. Specifying part of this // stanza should still result in sensible defaults for the other parts. diff --git a/agent/config_endpoint_test.go b/agent/config_endpoint_test.go index ec00b172d1..42de720c79 100644 --- a/agent/config_endpoint_test.go +++ b/agent/config_endpoint_test.go @@ -20,23 +20,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/connect/uri.go b/agent/connect/uri.go index bc898f7865..d9d5aa037d 100644 --- a/agent/connect/uri.go +++ b/agent/connect/uri.go @@ -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_service.go b/agent/connect/uri_service.go index b35d1e0df4..3be7cf4797 100644 --- a/agent/connect/uri_service.go +++ b/agent/connect/uri_service.go @@ -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_signing.go b/agent/connect/uri_signing.go index 1913ae6bdf..9f2807d2ba 100644 --- a/agent/connect/uri_signing.go +++ b/agent/connect/uri_signing.go @@ -51,12 +51,6 @@ 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 // ascii case folding (since hostnames are case-insensitive). Later we might diff --git a/agent/connect/uri_signing_test.go b/agent/connect/uri_signing_test.go index 737ca46054..edd3d46893 100644 --- a/agent/connect/uri_signing_test.go +++ b/agent/connect/uri_signing_test.go @@ -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 5211684597..fcbcf42ab3 100644 --- a/agent/connect/uri_test.go +++ b/agent/connect/uri_test.go @@ -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 83e022bde6..0000000000 --- a/agent/connect/uri_workload_identity.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package connect - -import ( - "fmt" - "net/url" -) - -// SpiffeIDWorkloadIdentity is the structure to represent the SPIFFE ID for a workload. -type SpiffeIDWorkloadIdentity struct { - TrustDomain string - Partition string - Namespace string - WorkloadIdentity string -} - -// 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.Partition, - id.Namespace, - 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 0350561634..0000000000 --- a/agent/connect/uri_workload_identity_ce.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package connect - -import ( - "github.com/hashicorp/consul/acl" -) - -// TODO: this will need to somehow be updated to set namespace here when we include namespaces in CE - -// 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{} -} diff --git a/agent/connect/uri_workload_identity_test.go b/agent/connect/uri_workload_identity_test.go deleted file mode 100644 index 94beb80f58..0000000000 --- a/agent/connect/uri_workload_identity_test.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package connect - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSpiffeIDWorkloadURI(t *testing.T) { - t.Run("spiffe id workload uri default tenancy", func(t *testing.T) { - wl := &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - WorkloadIdentity: "web", - Partition: "default", - Namespace: "default", - } - require.Equal(t, "spiffe://1234.consul/ap/default/ns/default/identity/web", wl.URI().String()) - }) - t.Run("spiffe id workload uri non-default tenancy", func(t *testing.T) { - wl := &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - WorkloadIdentity: "web", - Partition: "part1", - Namespace: "dev", - } - require.Equal(t, "spiffe://1234.consul/ap/part1/ns/dev/identity/web", wl.URI().String()) - }) -} diff --git a/agent/consul/leader.go b/agent/consul/leader.go index f8340d2b32..8b0db34b23 100644 --- a/agent/consul/leader.go +++ b/agent/consul/leader.go @@ -5,7 +5,6 @@ package consul import ( "context" - "errors" "fmt" "net" "strconv" @@ -16,10 +15,7 @@ import ( "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" - "github.com/google/go-cmp/cmp" - "github.com/oklog/ulid/v2" "golang.org/x/time/rate" - "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-uuid" @@ -32,13 +28,8 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs/aclfilter" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logging" - 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" ) var LeaderSummaries = []prometheus.SummaryDefinition{ @@ -349,18 +340,6 @@ func (s *Server) establishLeadership(ctx context.Context) error { s.startLogVerification(ctx) } - if s.useV2Tenancy { - if err := s.initTenancy(ctx, s.storageBackend); err != nil { - return err - } - } - - if s.useV2Resources { - if err := s.initConsulService(ctx, pbresource.NewResourceServiceClient(s.insecureSafeGRPCChan)); err != nil { - return err - } - } - if s.config.Reporting.License.Enabled && s.reportingManager != nil { s.reportingManager.StartReportingAgent() } @@ -771,12 +750,6 @@ func (s *Server) runACLReplicator( index, exit, err := replicateFunc(ctx, logger, lastRemoteIndex) if exit { - metrics.SetGauge([]string{"leader", "replication", metricName, "status"}, - 0, - ) - metrics.SetGauge([]string{"leader", "replication", metricName, "index"}, - 0, - ) return nil } @@ -1316,121 +1289,3 @@ func (s *serversIntentionsAsConfigEntriesInfo) update(srv *metadata.Server) bool // prevent continuing server evaluation return false } - -func (s *Server) initConsulService(ctx context.Context, client pbresource.ResourceServiceClient) error { - service := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{consulWorkloadPrefix}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: consulPortNameServer, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - // No virtual port defined for now, as we assume this is generally for Service Discovery - }, - }, - } - - serviceData, err := anypb.New(service) - if err != nil { - return fmt.Errorf("could not convert Service to `any` message: %w", err) - } - - // create a default namespace in default partition - serviceID := &pbresource.ID{ - Type: pbcatalog.ServiceType, - Name: structs.ConsulServiceName, - Tenancy: resource.DefaultNamespacedTenancy(), - } - - serviceResource := &pbresource.Resource{ - Id: serviceID, - Data: serviceData, - } - - res, err := client.Read(ctx, &pbresource.ReadRequest{Id: serviceID}) - if err != nil && !grpcNotFoundErr(err) { - return fmt.Errorf("failed to read the %s Service: %w", structs.ConsulServiceName, err) - } - - if err == nil { - existingService := res.GetResource() - s.logger.Debug("existingService consul Service found") - - // If the Service is identical, we're done. - if cmp.Equal(serviceResource, existingService, resourceCmpOptions...) { - s.logger.Debug("no updates to perform on consul Service") - return nil - } - - // If the existing Service is different, add the Version to the patch for CAS write. - serviceResource.Id = existingService.Id - serviceResource.Version = existingService.Version - } - - _, err = client.Write(ctx, &pbresource.WriteRequest{Resource: serviceResource}) - if err != nil { - return fmt.Errorf("failed to create the %s service: %w", structs.ConsulServiceName, err) - } - - s.logger.Info("Created consul Service in catalog") - return nil -} - -func (s *Server) initTenancy(ctx context.Context, b storage.Backend) error { - // we write these defaults directly to the storage backend - // without going through the resource service since tenancy - // validation hooks block writes to the default namespace - // and partition. - if err := s.createDefaultPartition(ctx, b); err != nil { - return err - } - - if err := s.createDefaultNamespace(ctx, b); err != nil { - return err - } - return nil -} - -func (s *Server) createDefaultNamespace(ctx context.Context, b storage.Backend) error { - readID := &pbresource.ID{ - Type: pbtenancy.NamespaceType, - Name: resource.DefaultNamespaceName, - Tenancy: resource.DefaultPartitionedTenancy(), - } - - read, err := b.Read(ctx, storage.StrongConsistency, readID) - - if err != nil && !errors.Is(err, storage.ErrNotFound) { - return fmt.Errorf("failed to read the %q namespace: %v", resource.DefaultNamespaceName, err) - } - if read == nil && errors.Is(err, storage.ErrNotFound) { - nsData, err := anypb.New(&pbtenancy.Namespace{Description: "default namespace in default partition"}) - if err != nil { - return err - } - - // create a default namespace in default partition - nsID := &pbresource.ID{ - Type: pbtenancy.NamespaceType, - Name: resource.DefaultNamespaceName, - Tenancy: resource.DefaultPartitionedTenancy(), - Uid: ulid.Make().String(), - } - - _, 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 fmt.Errorf("failed to create the %q namespace: %v", resource.DefaultNamespaceName, err) - } - } - s.logger.Info("Created", "namespace", resource.DefaultNamespaceName) - return nil -} diff --git a/agent/consul/leader_ce.go b/agent/consul/leader_ce.go deleted file mode 100644 index 2d67b7bded..0000000000 --- a/agent/consul/leader_ce.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package consul - -import ( - "context" - - "github.com/hashicorp/consul/internal/storage" -) - -func (s *Server) createDefaultPartition(ctx context.Context, b storage.Backend) error { - // no-op - return nil -} diff --git a/agent/consul/leader_ce_test.go b/agent/consul/leader_ce_test.go index 79e3cbc61a..367a9fbcae 100644 --- a/agent/consul/leader_ce_test.go +++ b/agent/consul/leader_ce_test.go @@ -6,17 +6,7 @@ package consul import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/internal/gossip/libserf" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/storage" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" - "github.com/hashicorp/consul/testrpc" ) func updateSerfTags(s *Server, key, value string) { @@ -26,41 +16,3 @@ func updateSerfTags(s *Server, key, value string) { libserf.UpdateTag(s.serfWAN, key, value) } } - -func TestServer_InitTenancy(t *testing.T) { - t.Parallel() - - _, conf := testServerConfig(t) - deps := newDefaultDeps(t, conf) - deps.Experiments = []string{"v2tenancy"} - deps.Registry = NewTypeRegistry() - - s, err := newServerWithDeps(t, conf, deps) - require.NoError(t, err) - - // first initTenancy call happens here - waitForLeaderEstablishment(t, s) - testrpc.WaitForLeader(t, s.RPC, "dc1") - - nsID := &pbresource.ID{ - Type: pbtenancy.NamespaceType, - Tenancy: resource.DefaultPartitionedTenancy(), - Name: resource.DefaultNamespaceName, - } - - ns, err := s.storageBackend.Read(context.Background(), storage.StrongConsistency, nsID) - require.NoError(t, err) - require.Equal(t, resource.DefaultNamespaceName, ns.Id.Name) - - // explicitly call initiTenancy to verify we do not re-create namespace - err = s.initTenancy(context.Background(), s.storageBackend) - require.NoError(t, err) - - // read again - actual, err := s.storageBackend.Read(context.Background(), storage.StrongConsistency, nsID) - require.NoError(t, err) - - require.Equal(t, ns.Id.Uid, actual.Id.Uid) - require.Equal(t, ns.Generation, actual.Generation) - require.Equal(t, ns.Version, actual.Version) -} diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go index 92cdf40a6a..ee6562912f 100644 --- a/agent/consul/leader_connect_ca.go +++ b/agent/consul/leader_connect_ca.go @@ -14,9 +14,10 @@ import ( "sync" "time" + "golang.org/x/time/rate" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-uuid" - "golang.org/x/time/rate" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/connect" @@ -1455,11 +1456,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 { @@ -1520,7 +1516,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 +1525,6 @@ 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 +1647,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 e372c010a7..4560e97380 100644 --- a/agent/consul/leader_connect_ca_test.go +++ b/agent/consul/leader_connect_ca_test.go @@ -19,13 +19,14 @@ import ( "testing" "time" - msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" - "github.com/hashicorp/consul-net-rpc/net/rpc" - vaultapi "github.com/hashicorp/vault/api" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc" + msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" + "github.com/hashicorp/consul-net-rpc/net/rpc" + vaultapi "github.com/hashicorp/vault/api" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/connect/ca" @@ -566,7 +567,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 +1318,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 +1413,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_registrator_v2.go b/agent/consul/leader_registrator_v2.go deleted file mode 100644 index 671fcc85d1..0000000000 --- a/agent/consul/leader_registrator_v2.go +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package consul - -import ( - "context" - "fmt" - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/serf/serf" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/testing/protocmp" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/metadata" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/types" -) - -const ( - consulWorkloadPrefix = "consul-server-" - consulPortNameServer = "server" -) - -var _ ConsulRegistrator = (*V2ConsulRegistrator)(nil) - -var resourceCmpOptions = []cmp.Option{ - protocmp.IgnoreFields(&pbresource.Resource{}, "status", "generation", "version"), - protocmp.IgnoreFields(&pbresource.ID{}, "uid"), - protocmp.Transform(), - // Stringify any type passed to the sorter so that we can reliably compare most values. - cmpopts.SortSlices(func(a, b any) bool { return fmt.Sprintf("%v", a) < fmt.Sprintf("%v", b) }), -} - -type V2ConsulRegistrator struct { - Logger hclog.Logger - NodeName string - EntMeta *acl.EnterpriseMeta - - Client pbresource.ResourceServiceClient -} - -// HandleAliveMember is used to ensure the server is registered as a Workload -// with a passing health check. -func (r V2ConsulRegistrator) HandleAliveMember(member serf.Member, nodeEntMeta *acl.EnterpriseMeta, joinServer func(m serf.Member, parts *metadata.Server) error) error { - valid, parts := metadata.IsConsulServer(member) - if !valid { - return nil - } - - if nodeEntMeta == nil { - nodeEntMeta = structs.NodeEnterpriseMetaInDefaultPartition() - } - - // Attempt to join the consul server, regardless of the existing catalog state - if err := joinServer(member, parts); err != nil { - return err - } - - r.Logger.Info("member joined, creating catalog entries", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - - workloadResource, err := r.createWorkloadFromMember(member, parts, nodeEntMeta) - if err != nil { - return err - } - - // Check if the Workload already exists and if it's the same - res, err := r.Client.Read(context.TODO(), &pbresource.ReadRequest{Id: workloadResource.Id}) - if err != nil && !grpcNotFoundErr(err) { - return fmt.Errorf("error checking for existing Workload %s: %w", workloadResource.Id.Name, err) - } - - if err == nil { - existingWorkload := res.GetResource() - - r.Logger.Debug("existing Workload matching the member found", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - - // If the Workload is identical, move to updating the health status - if cmp.Equal(workloadResource, existingWorkload, resourceCmpOptions...) { - r.Logger.Debug("no updates to perform on member Workload", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - goto HEALTHSTATUS - } - - // If the existing Workload different, add the existing Version into the patch for CAS write - workloadResource.Id = existingWorkload.Id - workloadResource.Version = existingWorkload.Version - } - - if _, err := r.Client.Write(context.TODO(), &pbresource.WriteRequest{Resource: workloadResource}); err != nil { - return fmt.Errorf("failed to write Workload %s: %w", workloadResource.Id.Name, err) - } - - r.Logger.Info("updated consul Workload in catalog", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - -HEALTHSTATUS: - hsResource, err := r.createHealthStatusFromMember(member, workloadResource.Id, true, nodeEntMeta) - if err != nil { - return err - } - - // Check if the HealthStatus already exists and if it's the same - res, err = r.Client.Read(context.TODO(), &pbresource.ReadRequest{Id: hsResource.Id}) - if err != nil && !grpcNotFoundErr(err) { - return fmt.Errorf("error checking for existing HealthStatus %s: %w", hsResource.Id.Name, err) - } - - if err == nil { - existingHS := res.GetResource() - - r.Logger.Debug("existing HealthStatus matching the member found", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - - // If the HealthStatus is identical, we're done. - if cmp.Equal(hsResource, existingHS, resourceCmpOptions...) { - r.Logger.Debug("no updates to perform on member HealthStatus", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return nil - } - - // If the existing HealthStatus is different, add the Version to the patch for CAS write. - hsResource.Id = existingHS.Id - hsResource.Version = existingHS.Version - } - - if _, err := r.Client.Write(context.TODO(), &pbresource.WriteRequest{Resource: hsResource}); err != nil { - return fmt.Errorf("failed to write HealthStatus %s: %w", hsResource.Id.Name, err) - } - r.Logger.Info("updated consul HealthStatus in catalog", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return nil -} - -func (r V2ConsulRegistrator) createWorkloadFromMember(member serf.Member, parts *metadata.Server, nodeEntMeta *acl.EnterpriseMeta) (*pbresource.Resource, error) { - workloadMeta := map[string]string{ - "read_replica": strconv.FormatBool(member.Tags["read_replica"] == "1"), - "raft_version": strconv.Itoa(parts.RaftVersion), - "serf_protocol_current": strconv.FormatUint(uint64(member.ProtocolCur), 10), - "serf_protocol_min": strconv.FormatUint(uint64(member.ProtocolMin), 10), - "serf_protocol_max": strconv.FormatUint(uint64(member.ProtocolMax), 10), - "version": parts.Build.String(), - } - - if parts.ExternalGRPCPort > 0 { - workloadMeta["grpc_port"] = strconv.Itoa(parts.ExternalGRPCPort) - } - if parts.ExternalGRPCTLSPort > 0 { - workloadMeta["grpc_tls_port"] = strconv.Itoa(parts.ExternalGRPCTLSPort) - } - - if parts.Port < 0 || parts.Port > 65535 { - return nil, fmt.Errorf("invalid port: %d", parts.Port) - } - - workload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: member.Addr.String(), Ports: []string{consulPortNameServer}}, - }, - // Don't include identity since Consul is not routable through the mesh. - // Don't include locality because these values are not passed along through serf, and they are probably - // different from the leader's values. - Ports: map[string]*pbcatalog.WorkloadPort{ - consulPortNameServer: { - Port: uint32(parts.Port), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - // TODO: add other agent ports - }, - } - - workloadData, err := anypb.New(workload) - if err != nil { - return nil, fmt.Errorf("could not convert Workload to 'any' type: %w", err) - } - - workloadId := &pbresource.ID{ - Name: fmt.Sprintf("%s%s", consulWorkloadPrefix, types.NodeID(member.Tags["id"])), - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - workloadId.Tenancy.Partition = nodeEntMeta.PartitionOrDefault() - - return &pbresource.Resource{ - Id: workloadId, - Data: workloadData, - Metadata: workloadMeta, - }, nil -} - -func (r V2ConsulRegistrator) createHealthStatusFromMember(member serf.Member, workloadId *pbresource.ID, passing bool, nodeEntMeta *acl.EnterpriseMeta) (*pbresource.Resource, error) { - hs := &pbcatalog.HealthStatus{ - Type: string(structs.SerfCheckID), - Description: structs.SerfCheckName, - } - - if passing { - hs.Status = pbcatalog.Health_HEALTH_PASSING - hs.Output = structs.SerfCheckAliveOutput - } else { - hs.Status = pbcatalog.Health_HEALTH_CRITICAL - hs.Output = structs.SerfCheckFailedOutput - } - - hsData, err := anypb.New(hs) - if err != nil { - return nil, fmt.Errorf("could not convert HealthStatus to 'any' type: %w", err) - } - - hsId := &pbresource.ID{ - Name: fmt.Sprintf("%s%s", consulWorkloadPrefix, types.NodeID(member.Tags["id"])), - Type: pbcatalog.HealthStatusType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - hsId.Tenancy.Partition = nodeEntMeta.PartitionOrDefault() - - return &pbresource.Resource{ - Id: hsId, - Data: hsData, - Owner: workloadId, - }, nil -} - -// HandleFailedMember is used to mark the workload's associated HealthStatus. -func (r V2ConsulRegistrator) HandleFailedMember(member serf.Member, nodeEntMeta *acl.EnterpriseMeta) error { - if valid, _ := metadata.IsConsulServer(member); !valid { - return nil - } - - if nodeEntMeta == nil { - nodeEntMeta = structs.NodeEnterpriseMetaInDefaultPartition() - } - - r.Logger.Info("member failed", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - - // Validate that the associated workload exists - workloadId := &pbresource.ID{ - Name: fmt.Sprintf("%s%s", consulWorkloadPrefix, types.NodeID(member.Tags["id"])), - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - workloadId.Tenancy.Partition = nodeEntMeta.PartitionOrDefault() - - res, err := r.Client.Read(context.TODO(), &pbresource.ReadRequest{Id: workloadId}) - if err != nil && !grpcNotFoundErr(err) { - return fmt.Errorf("error checking for existing Workload %s: %w", workloadId.Name, err) - } - if grpcNotFoundErr(err) { - r.Logger.Info("ignoring failed event for member because it does not exist in the catalog", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return nil - } - // Overwrite the workload ID with the one that has UID populated. - existingWorkload := res.GetResource() - - hsResource, err := r.createHealthStatusFromMember(member, existingWorkload.Id, false, nodeEntMeta) - if err != nil { - return err - } - - res, err = r.Client.Read(context.TODO(), &pbresource.ReadRequest{Id: hsResource.Id}) - if err != nil && !grpcNotFoundErr(err) { - return fmt.Errorf("error checking for existing HealthStatus %s: %w", hsResource.Id.Name, err) - } - - if err == nil { - existingHS := res.GetResource() - r.Logger.Debug("existing HealthStatus matching the member found", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - - // If the HealthStatus is identical, we're done. - if cmp.Equal(hsResource, existingHS, resourceCmpOptions...) { - r.Logger.Debug("no updates to perform on member HealthStatus", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return nil - } - - // If the existing HealthStatus is different, add the Version to the patch for CAS write. - hsResource.Id = existingHS.Id - hsResource.Version = existingHS.Version - } - - if _, err := r.Client.Write(context.TODO(), &pbresource.WriteRequest{Resource: hsResource}); err != nil { - return fmt.Errorf("failed to write HealthStatus %s: %w", hsResource.Id.Name, err) - } - r.Logger.Info("updated consul HealthStatus in catalog", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return nil -} - -// HandleLeftMember is used to handle members that gracefully -// left. They are removed if necessary. -func (r V2ConsulRegistrator) HandleLeftMember(member serf.Member, nodeEntMeta *acl.EnterpriseMeta, removeServerFunc func(m serf.Member) error) error { - return r.handleDeregisterMember("left", member, nodeEntMeta, removeServerFunc) -} - -// HandleReapMember is used to handle members that have been -// reaped after a prolonged failure. They are removed from the catalog. -func (r V2ConsulRegistrator) HandleReapMember(member serf.Member, nodeEntMeta *acl.EnterpriseMeta, removeServerFunc func(m serf.Member) error) error { - return r.handleDeregisterMember("reaped", member, nodeEntMeta, removeServerFunc) -} - -// handleDeregisterMember is used to remove a member of a given reason -func (r V2ConsulRegistrator) handleDeregisterMember(reason string, member serf.Member, nodeEntMeta *acl.EnterpriseMeta, removeServerFunc func(m serf.Member) error) error { - if valid, _ := metadata.IsConsulServer(member); !valid { - return nil - } - - if nodeEntMeta == nil { - nodeEntMeta = structs.NodeEnterpriseMetaInDefaultPartition() - } - - r.Logger.Info("removing member", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - "reason", reason, - ) - - if err := removeServerFunc(member); err != nil { - return err - } - - // Do not remove our self. This can only happen if the current leader - // is leaving. Instead, we should allow a follower to take-over and - // remove us later. - if strings.EqualFold(member.Name, r.NodeName) && - strings.EqualFold(nodeEntMeta.PartitionOrDefault(), r.EntMeta.PartitionOrDefault()) { - r.Logger.Warn("removing self should be done by follower", - "name", r.NodeName, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - "reason", reason, - ) - return nil - } - - // Check if the workload exists - workloadID := &pbresource.ID{ - Name: fmt.Sprintf("%s%s", consulWorkloadPrefix, types.NodeID(member.Tags["id"])), - Type: pbcatalog.WorkloadType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - workloadID.Tenancy.Partition = nodeEntMeta.PartitionOrDefault() - - res, err := r.Client.Read(context.TODO(), &pbresource.ReadRequest{Id: workloadID}) - if err != nil && !grpcNotFoundErr(err) { - return fmt.Errorf("error checking for existing Workload %s: %w", workloadID.Name, err) - } - if grpcNotFoundErr(err) { - r.Logger.Info("ignoring reap event for member because it does not exist in the catalog", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return nil - } - existingWorkload := res.GetResource() - - // The HealthStatus should be reaped automatically - if _, err := r.Client.Delete(context.TODO(), &pbresource.DeleteRequest{Id: existingWorkload.Id}); err != nil { - return fmt.Errorf("failed to delete Workload %s: %w", existingWorkload.Id.Name, err) - } - r.Logger.Info("deleted consul Workload", - "member", member.Name, - "partition", getSerfMemberEnterpriseMeta(member).PartitionOrDefault(), - ) - return err -} - -func grpcNotFoundErr(err error) bool { - if err == nil { - return false - } - s, ok := status.FromError(err) - return ok && s.Code() == codes.NotFound -} diff --git a/agent/consul/leader_registrator_v2_test.go b/agent/consul/leader_registrator_v2_test.go deleted file mode 100644 index c2729c47ff..0000000000 --- a/agent/consul/leader_registrator_v2_test.go +++ /dev/null @@ -1,583 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package consul - -import ( - "fmt" - "net" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/serf/serf" - "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" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/metadata" - "github.com/hashicorp/consul/agent/structs" - mockpbresource "github.com/hashicorp/consul/grpcmocks/proto-public/pbresource" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -var ( - fakeWrappedErr = fmt.Errorf("fake test error") -) - -type testCase struct { - name string - member serf.Member - nodeNameOverride string // This is used in the HandleLeftMember test to avoid deregistering ourself - - existingWorkload *pbresource.Resource - workloadReadErr bool - workloadWriteErr bool - workloadDeleteErr bool - - existingHealthStatus *pbresource.Resource - healthstatusReadErr bool - healthstatusWriteErr bool - - mutatedWorkload *pbresource.Resource // leaving one of these out means the mock expects not to have a write/delete called - mutatedHealthStatus *pbresource.Resource - expErr string -} - -func Test_HandleAliveMember(t *testing.T) { - t.Parallel() - - run := func(t *testing.T, tt testCase) { - client := mockpbresource.NewResourceServiceClient(t) - mockClient := client.EXPECT() - - // Build mock expectations based on the order of HandleAliveMember resource calls - setupReadExpectation(t, mockClient, getTestWorkloadId(), tt.existingWorkload, tt.workloadReadErr) - setupWriteExpectation(t, mockClient, tt.mutatedWorkload, tt.workloadWriteErr) - if !tt.workloadReadErr && !tt.workloadWriteErr { - // We expect to bail before this read if there is an error earlier in the function - setupReadExpectation(t, mockClient, getTestHealthstatusId(), tt.existingHealthStatus, tt.healthstatusReadErr) - } - setupWriteExpectation(t, mockClient, tt.mutatedHealthStatus, tt.healthstatusWriteErr) - - registrator := V2ConsulRegistrator{ - Logger: hclog.New(&hclog.LoggerOptions{}), - NodeName: "test-server-1", - Client: client, - } - - // Mock join function - var joinMockCalled bool - joinMock := func(_ serf.Member, _ *metadata.Server) error { - joinMockCalled = true - return nil - } - - err := registrator.HandleAliveMember(tt.member, acl.DefaultEnterpriseMeta(), joinMock) - if tt.expErr != "" { - require.Contains(t, err.Error(), tt.expErr) - } else { - require.NoError(t, err) - } - require.True(t, joinMockCalled, "the mock join function was not called") - } - - tests := []testCase{ - { - name: "New alive member", - member: getTestSerfMember(serf.StatusAlive), - mutatedWorkload: getTestWorkload(t), - mutatedHealthStatus: getTestHealthStatus(t, true), - }, - { - name: "No updates needed", - member: getTestSerfMember(serf.StatusAlive), - existingWorkload: getTestWorkload(t), - existingHealthStatus: getTestHealthStatus(t, true), - }, - { - name: "Existing Workload and HS need to be updated", - member: getTestSerfMember(serf.StatusAlive), - existingWorkload: getTestWorkloadWithPort(t, 8301), - existingHealthStatus: getTestHealthStatus(t, false), - mutatedWorkload: getTestWorkload(t), - mutatedHealthStatus: getTestHealthStatus(t, true), - }, - { - name: "Only the HS needs to be updated", - member: getTestSerfMember(serf.StatusAlive), - existingWorkload: getTestWorkload(t), - existingHealthStatus: getTestHealthStatus(t, false), - mutatedHealthStatus: getTestHealthStatus(t, true), - }, - { - name: "Error reading Workload", - member: getTestSerfMember(serf.StatusAlive), - workloadReadErr: true, - expErr: "error checking for existing Workload", - }, - { - name: "Error writing Workload", - member: getTestSerfMember(serf.StatusAlive), - workloadWriteErr: true, - mutatedWorkload: getTestWorkload(t), - expErr: "failed to write Workload", - }, - { - name: "Error reading HealthStatus", - member: getTestSerfMember(serf.StatusAlive), - healthstatusReadErr: true, - mutatedWorkload: getTestWorkload(t), - expErr: "error checking for existing HealthStatus", - }, - { - name: "Error writing HealthStatus", - member: getTestSerfMember(serf.StatusAlive), - healthstatusWriteErr: true, - mutatedWorkload: getTestWorkload(t), - mutatedHealthStatus: getTestHealthStatus(t, true), - expErr: "failed to write HealthStatus", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - run(t, tt) - }) - } -} - -func Test_HandleFailedMember(t *testing.T) { - t.Parallel() - - run := func(t *testing.T, tt testCase) { - client := mockpbresource.NewResourceServiceClient(t) - mockClient := client.EXPECT() - - // Build mock expectations based on the order of HandleFailed resource calls - setupReadExpectation(t, mockClient, getTestWorkloadId(), tt.existingWorkload, tt.workloadReadErr) - if !tt.workloadReadErr && tt.existingWorkload != nil { - // We expect to bail before this read if there is an error earlier in the function or there is no workload - setupReadExpectation(t, mockClient, getTestHealthstatusId(), tt.existingHealthStatus, tt.healthstatusReadErr) - } - setupWriteExpectation(t, mockClient, tt.mutatedHealthStatus, tt.healthstatusWriteErr) - - registrator := V2ConsulRegistrator{ - Logger: hclog.New(&hclog.LoggerOptions{}), - NodeName: "test-server-1", - Client: client, - } - - err := registrator.HandleFailedMember(tt.member, acl.DefaultEnterpriseMeta()) - if tt.expErr != "" { - require.Contains(t, err.Error(), tt.expErr) - } else { - require.NoError(t, err) - } - } - - tests := []testCase{ - { - name: "Update non-existent HealthStatus", - member: getTestSerfMember(serf.StatusFailed), - existingWorkload: getTestWorkload(t), - mutatedHealthStatus: getTestHealthStatus(t, false), - }, - { - name: "Underlying Workload does not exist", - member: getTestSerfMember(serf.StatusFailed), - }, - { - name: "Update an existing HealthStatus", - member: getTestSerfMember(serf.StatusFailed), - existingWorkload: getTestWorkload(t), - existingHealthStatus: getTestHealthStatus(t, true), - mutatedHealthStatus: getTestHealthStatus(t, false), - }, - { - name: "HealthStatus is already critical - no updates needed", - member: getTestSerfMember(serf.StatusFailed), - existingWorkload: getTestWorkload(t), - existingHealthStatus: getTestHealthStatus(t, false), - }, - { - name: "Error reading Workload", - member: getTestSerfMember(serf.StatusFailed), - workloadReadErr: true, - expErr: "error checking for existing Workload", - }, - { - name: "Error reading HealthStatus", - member: getTestSerfMember(serf.StatusFailed), - existingWorkload: getTestWorkload(t), - healthstatusReadErr: true, - expErr: "error checking for existing HealthStatus", - }, - { - name: "Error writing HealthStatus", - member: getTestSerfMember(serf.StatusFailed), - existingWorkload: getTestWorkload(t), - healthstatusWriteErr: true, - mutatedHealthStatus: getTestHealthStatus(t, false), - expErr: "failed to write HealthStatus", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - run(t, tt) - }) - } -} - -// Test_HandleLeftMember also tests HandleReapMembers, which are the same core logic with some different logs. -func Test_HandleLeftMember(t *testing.T) { - t.Parallel() - - run := func(t *testing.T, tt testCase) { - client := mockpbresource.NewResourceServiceClient(t) - mockClient := client.EXPECT() - - // Build mock expectations based on the order of HandleLeftMember resource calls - // We check for the override, which we use to skip self de-registration - if tt.nodeNameOverride == "" { - setupReadExpectation(t, mockClient, getTestWorkloadId(), tt.existingWorkload, tt.workloadReadErr) - if tt.existingWorkload != nil && !tt.workloadReadErr { - setupDeleteExpectation(t, mockClient, tt.mutatedWorkload, tt.workloadDeleteErr) - } - } - - nodeName := "test-server-2" // This is not the same as the serf node so we don't dergister ourself. - if tt.nodeNameOverride != "" { - nodeName = tt.nodeNameOverride - } - - registrator := V2ConsulRegistrator{ - Logger: hclog.New(&hclog.LoggerOptions{}), - NodeName: nodeName, // We change this so that we don't deregister ourself - Client: client, - } - - // Mock join function - var removeMockCalled bool - removeMock := func(_ serf.Member) error { - removeMockCalled = true - return nil - } - - err := registrator.HandleLeftMember(tt.member, acl.DefaultEnterpriseMeta(), removeMock) - if tt.expErr != "" { - require.Contains(t, err.Error(), tt.expErr) - } else { - require.NoError(t, err) - } - require.True(t, removeMockCalled, "the mock remove function was not called") - } - - tests := []testCase{ - { - name: "Remove member", - member: getTestSerfMember(serf.StatusAlive), - existingWorkload: getTestWorkload(t), - mutatedWorkload: getTestWorkload(t), - }, - { - name: "Don't deregister ourself", - member: getTestSerfMember(serf.StatusAlive), - nodeNameOverride: "test-server-1", - }, - { - name: "Don't do anything if the Workload is already gone", - member: getTestSerfMember(serf.StatusAlive), - }, - { - name: "Remove member regardless of Workload payload", - member: getTestSerfMember(serf.StatusAlive), - existingWorkload: getTestWorkloadWithPort(t, 8301), - mutatedWorkload: getTestWorkload(t), - }, - { - name: "Error reading Workload", - member: getTestSerfMember(serf.StatusAlive), - workloadReadErr: true, - expErr: "error checking for existing Workload", - }, - { - name: "Error deleting Workload", - member: getTestSerfMember(serf.StatusAlive), - workloadDeleteErr: true, - existingWorkload: getTestWorkloadWithPort(t, 8301), - mutatedWorkload: getTestWorkload(t), - expErr: "failed to delete Workload", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - run(t, tt) - }) - } -} - -func setupReadExpectation( - t *testing.T, - mockClient *mockpbresource.ResourceServiceClient_Expecter, - expectedId *pbresource.ID, - existingResource *pbresource.Resource, - sendErr bool) { - - if sendErr { - mockClient.Read(mock.Anything, mock.Anything). - Return(nil, fakeWrappedErr). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.True(t, proto.Equal(expectedId, req.Id)) - }) - } else if existingResource != nil { - mockClient.Read(mock.Anything, mock.Anything). - Return(&pbresource.ReadResponse{ - Resource: existingResource, - }, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.True(t, proto.Equal(expectedId, req.Id)) - }) - } else { - mockClient.Read(mock.Anything, mock.Anything). - Return(nil, status.Error(codes.NotFound, "not found")). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.ReadRequest) - require.True(t, proto.Equal(expectedId, req.Id)) - }) - } -} - -func setupWriteExpectation( - t *testing.T, - mockClient *mockpbresource.ResourceServiceClient_Expecter, - expectedResource *pbresource.Resource, - sendErr bool) { - - // If there is no expected resource, we take that to mean we don't expect any client writes. - if expectedResource == nil { - return - } - - if sendErr { - mockClient.Write(mock.Anything, mock.Anything). - Return(nil, fakeWrappedErr). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.WriteRequest) - require.True(t, proto.Equal(expectedResource, req.Resource)) - }) - } else { - mockClient.Write(mock.Anything, mock.Anything). - Return(nil, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.WriteRequest) - require.True(t, proto.Equal(expectedResource, req.Resource)) - }) - } -} - -func setupDeleteExpectation( - t *testing.T, - mockClient *mockpbresource.ResourceServiceClient_Expecter, - expectedResource *pbresource.Resource, - sendErr bool) { - - expectedId := expectedResource.GetId() - - if sendErr { - mockClient.Delete(mock.Anything, mock.Anything). - Return(nil, fakeWrappedErr). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.DeleteRequest) - require.True(t, proto.Equal(expectedId, req.Id)) - }) - } else { - mockClient.Delete(mock.Anything, mock.Anything). - Return(nil, nil). - Once(). - Run(func(args mock.Arguments) { - req := args.Get(1).(*pbresource.DeleteRequest) - require.True(t, proto.Equal(expectedId, req.Id)) - }) - } -} - -func getTestWorkload(t *testing.T) *pbresource.Resource { - return getTestWorkloadWithPort(t, 8300) -} - -func getTestWorkloadWithPort(t *testing.T, port int) *pbresource.Resource { - workload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{consulPortNameServer}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - consulPortNameServer: { - Port: uint32(port), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - }, - } - data, err := anypb.New(workload) - require.NoError(t, err) - - return &pbresource.Resource{ - Id: getTestWorkloadId(), - Data: data, - Metadata: map[string]string{ - "read_replica": "false", - "raft_version": "3", - "serf_protocol_current": "2", - "serf_protocol_min": "1", - "serf_protocol_max": "5", - "version": "1.18.0", - "grpc_port": "8502", - }, - } -} - -func getTestWorkloadId() *pbresource.ID { - return &pbresource.ID{ - Tenancy: resource.DefaultNamespacedTenancy(), - Type: pbcatalog.WorkloadType, - Name: "consul-server-72af047d-1857-2493-969e-53614a70b25a", - } -} - -func getTestHealthStatus(t *testing.T, passing bool) *pbresource.Resource { - healthStatus := &pbcatalog.HealthStatus{ - Type: string(structs.SerfCheckID), - Description: structs.SerfCheckName, - } - - if passing { - healthStatus.Status = pbcatalog.Health_HEALTH_PASSING - healthStatus.Output = structs.SerfCheckAliveOutput - } else { - healthStatus.Status = pbcatalog.Health_HEALTH_CRITICAL - healthStatus.Output = structs.SerfCheckFailedOutput - } - - data, err := anypb.New(healthStatus) - require.NoError(t, err) - - return &pbresource.Resource{ - Id: getTestHealthstatusId(), - Data: data, - Owner: getTestWorkloadId(), - } -} - -func getTestHealthstatusId() *pbresource.ID { - return &pbresource.ID{ - Tenancy: resource.DefaultNamespacedTenancy(), - Type: pbcatalog.HealthStatusType, - Name: "consul-server-72af047d-1857-2493-969e-53614a70b25a", - } -} - -func getTestSerfMember(status serf.MemberStatus) serf.Member { - return serf.Member{ - Name: "test-server-1", - Addr: net.ParseIP("127.0.0.1"), - Port: 8300, - // representative tags from a local dev deployment of ENT - Tags: map[string]string{ - "vsn_min": "2", - "vsn": "2", - "acls": "1", - "ft_si": "1", - "raft_vsn": "3", - "grpc_port": "8502", - "wan_join_port": "8500", - "dc": "dc1", - "segment": "", - "id": "72af047d-1857-2493-969e-53614a70b25a", - "ft_admpart": "1", - "role": "consul", - "build": "1.18.0", - "ft_ns": "1", - "vsn_max": "3", - "bootstrap": "1", - "expect": "1", - "port": "8300", - }, - Status: status, - ProtocolMin: 1, - ProtocolMax: 5, - ProtocolCur: 2, - DelegateMin: 2, - DelegateMax: 5, - DelegateCur: 4, - } -} - -// Test_ResourceCmpOptions_GeneratedFieldInsensitive makes sure are protocmp options are working as expected. -func Test_ResourceCmpOptions_GeneratedFieldInsensitive(t *testing.T) { - t.Parallel() - - res1 := getTestWorkload(t) - res2 := getTestWorkload(t) - - // Modify the generated fields - res2.Id.Uid = "123456" - res2.Version = "789" - res2.Generation = "millenial" - res2.Status = map[string]*pbresource.Status{ - "foo": {ObservedGeneration: "124"}, - } - - require.True(t, cmp.Equal(res1, res2, resourceCmpOptions...)) - - res1.Metadata["foo"] = "bar" - - require.False(t, cmp.Equal(res1, res2, resourceCmpOptions...)) -} - -// Test gRPC Error Codes Conditions -func Test_grpcNotFoundErr(t *testing.T) { - t.Parallel() - tests := []struct { - name string - err error - expected bool - }{ - { - name: "Nil Error", - }, - { - name: "Nonsense Error", - err: fmt.Errorf("boooooo!"), - }, - { - name: "gRPC Permission Denied Error", - err: status.Error(codes.PermissionDenied, "permission denied is not NotFound"), - }, - { - name: "gRPC NotFound Error", - err: status.Error(codes.NotFound, "bingo: not found"), - expected: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.expected, grpcNotFoundErr(tt.err)) - }) - } -} diff --git a/agent/consul/leader_test.go b/agent/consul/leader_test.go index 619d6ae6da..9709e391eb 100644 --- a/agent/consul/leader_test.go +++ b/agent/consul/leader_test.go @@ -14,84 +14,23 @@ import ( "testing" "time" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" - "github.com/hashicorp/serf/serf" "github.com/stretchr/testify/require" "google.golang.org/grpc" msgpackrpc "github.com/hashicorp/consul-net-rpc/net-rpc-msgpackrpc" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/serf/serf" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/leafcert" "github.com/hashicorp/consul/agent/structs" tokenStore "github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" ) -func enableV2(t *testing.T) func(deps *Deps) { - return func(deps *Deps) { - deps.Experiments = []string{"resource-apis"} - m, _ := leafcert.NewTestManager(t, nil) - deps.LeafCertManager = m - } -} - -// Test that Consul service is created in V2. -// In V1, the service is implicitly created - this is covered in leader_registrator_v1_test.go -func Test_InitConsulService(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - dir, s := testServerWithDepsAndConfig(t, enableV2(t), - func(c *Config) { - c.PrimaryDatacenter = "dc1" - c.ACLsEnabled = true - c.ACLInitialManagementToken = "root" - c.ACLResolverSettings.ACLDefaultPolicy = "deny" - }) - defer os.RemoveAll(dir) - defer s.Shutdown() - - testrpc.WaitForRaftLeader(t, s.RPC, "dc1", testrpc.WithToken("root")) - - client := pbresource.NewResourceServiceClient(s.insecureSafeGRPCChan) - - consulServiceID := &pbresource.ID{ - Name: structs.ConsulServiceName, - Type: pbcatalog.ServiceType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - - retry.Run(t, func(r *retry.R) { - res, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: consulServiceID}) - if err != nil { - r.Fatalf("err: %v", err) - } - data := res.GetResource().GetData() - require.NotNil(r, data) - - var service pbcatalog.Service - err = data.UnmarshalTo(&service) - require.NoError(r, err) - - // Spot check the Service - require.Equal(r, service.GetWorkloads().GetPrefixes(), []string{consulWorkloadPrefix}) - require.GreaterOrEqual(r, len(service.GetPorts()), 1) - - //Since we're not running a full agent w/ serf, we can't check for valid endpoints - }) -} - func TestLeader_TombstoneGC_Reset(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") @@ -834,7 +773,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/options.go b/agent/consul/options.go index ced36bcad5..8c9fe05f48 100644 --- a/agent/consul/options.go +++ b/agent/consul/options.go @@ -6,8 +6,6 @@ package consul import ( "google.golang.org/grpc" - "github.com/hashicorp/consul/lib/stringslice" - "github.com/hashicorp/consul-net-rpc/net/rpc" "github.com/hashicorp/go-hclog" @@ -50,33 +48,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 -} - -// HCPAllowV2Resources returns true if "hcp-v2-resource-apis" is present in the Experiments -// array of the agent config. -func (d Deps) HCPAllowV2Resources() bool { - if stringslice.Contains(d.Experiments, HCPAllowV2ResourceAPIs) { - return true - } - return false -} - type GRPCClientConner interface { ClientConn(datacenter string) (*grpc.ClientConn, error) ClientConnLeader() (*grpc.ClientConn, error) diff --git a/agent/consul/server.go b/agent/consul/server.go index 12386cc9df..979d9e3cd4 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -63,25 +63,18 @@ 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/gossip/librtt" hcpctl "github.com/hashicorp/consul/internal/hcp" - "github.com/hashicorp/consul/internal/mesh" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" "github.com/hashicorp/consul/internal/multicluster" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/resource/reaper" "github.com/hashicorp/consul/internal/storage" 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/tlsutil" "github.com/hashicorp/consul/types" @@ -131,25 +124,9 @@ const ( // and wait for a periodic reconcile. reconcileChSize = 256 - LeaderTransferMinVersion = "1.6.0" - CatalogResourceExperimentName = "resource-apis" - V2TenancyExperimentName = "v2tenancy" - HCPAllowV2ResourceAPIs = "hcp-v2-resource-apis" + LeaderTransferMinVersion = "1.6.0" ) -// IsExperimentAllowedOnSecondaries returns true if an experiment is currently -// disallowed for wan federated secondary datacenters. -// -// Likely these will all be short lived exclusions. -func IsExperimentAllowedOnSecondaries(name string) bool { - switch name { - case CatalogResourceExperimentName, V2TenancyExperimentName: - return false - default: - return true - } -} - const ( aclPolicyReplicationRoutineName = "ACL policy replication" aclRoleReplicationRoutineName = "ACL role replication" @@ -474,15 +451,6 @@ type Server struct { reportingManager *reporting.ReportingManager registry resource.Registry - - useV2Resources bool - - // useV2Tenancy is tied to the "v2tenancy" feature flag. - useV2Tenancy bool - - // whether v2 resources are enabled for use with HCP - // TODO(CC-6389): Remove once resource-apis is no longer considered experimental and is supported by HCP - hcpAllowV2Resources bool } func (s *Server) DecrementBlockingQueries() uint64 { @@ -504,22 +472,10 @@ 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) { + incomingRPCLimiter rpcRate.RequestLimitsHandler, serverLogger hclog.InterceptLogger) (*Server, error) { logger := flat.Logger if err := config.CheckProtocolVersion(); err != nil { return nil, err @@ -572,9 +528,6 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, incomingRPCLimiter: incomingRPCLimiter, routineManager: routine.NewManager(logger.Named(logging.ConsulServer)), registry: flat.Registry, - useV2Resources: flat.UseV2Resources(), - useV2Tenancy: flat.UseV2Tenancy(), - hcpAllowV2Resources: flat.HCPAllowV2Resources(), } incomingRPCLimiter.Register(s) @@ -636,15 +589,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)), - ), + middleware.GetNetRPCRateLimitingInterceptor(s.incomingRPCLimiter, middleware.NewPanicHandler(s.logger)), ), } @@ -747,7 +692,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) } @@ -925,7 +870,7 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, pbresource.NewResourceServiceClient(s.insecureUnsafeGRPCChan), s.loggers.Named(logging.ControllerRuntime), ) - if err := s.registerControllers(flat, proxyUpdater); err != nil { + if err := s.registerControllers(flat); err != nil { return nil, err } go s.controllerManager.Run(&lib.StopChannelContext{StopCh: shutdownCh}) @@ -943,22 +888,12 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, // as establishing leadership could attempt to use autopilot and cause a panic. s.initAutopilot(config) - // Construct the registrator that makes sense for the catalog version - if s.useV2Resources { - s.registrator = V2ConsulRegistrator{ - Logger: serverLogger, - NodeName: s.config.NodeName, - EntMeta: s.config.AgentEnterpriseMeta(), - Client: pbresource.NewResourceServiceClient(s.insecureSafeGRPCChan), - } - } else { - s.registrator = V1ConsulRegistrator{ - Datacenter: s.config.Datacenter, - FSM: s.fsm, - Logger: serverLogger, - NodeName: s.config.NodeName, - RaftApplyFunc: s.raftApplyMsgpack, - } + s.registrator = V1ConsulRegistrator{ + Datacenter: s.config.Datacenter, + FSM: s.fsm, + Logger: serverLogger, + NodeName: s.config.NodeName, + RaftApplyFunc: s.raftApplyMsgpack, } // Start monitoring leadership. This must happen after Serf is set up @@ -993,86 +928,17 @@ 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 { +func (s *Server) registerControllers(deps Deps) error { if s.config.Cloud.IsConfigured() { hcpctl.RegisterControllers( s.controllerManager, hcpctl.ControllerDependencies{ - ResourceApisEnabled: s.useV2Resources, - HCPAllowV2ResourceApis: s.hcpAllowV2Resources, - CloudConfig: deps.HCP.Config, + CloudConfig: deps.HCP.Config, }, ) } - // When not enabled, the v1 tenancy bridge is used by default. - if s.useV2Tenancy { - tenancy.RegisterControllers( - s.controllerManager, - tenancy.Dependencies{Registry: deps.Registry}, - ) - } - - if s.useV2Resources { - catalog.RegisterControllers(s.controllerManager) - 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()) - multicluster.RegisterControllers(s.controllerManager) - } else { - shim := NewExportedServicesShim(s) - multicluster.RegisterCompatControllers(s.controllerManager, multicluster.DefaultCompatControllerDependencies(shim)) - } + shim := NewExportedServicesShim(s) + multicluster.RegisterCompatControllers(s.controllerManager, multicluster.DefaultCompatControllerDependencies(shim)) reaper.RegisterControllers(s.controllerManager) @@ -1109,7 +975,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 { @@ -1190,7 +1056,7 @@ func (s *Server) setupRaft(isCatalogResourceExperiment bool) error { 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 { + if s.config.LogStoreConfig.Backend == LogStoreBackendDefault && !boltFileExists { s.config.LogStoreConfig.Backend = LogStoreBackendWAL if !s.config.LogStoreConfig.Verification.Enabled { s.config.LogStoreConfig.Verification.Enabled = true diff --git a/agent/consul/server_ce.go b/agent/consul/server_ce.go index b744f2ec72..dae8dc1516 100644 --- a/agent/consul/server_ce.go +++ b/agent/consul/server_ce.go @@ -205,6 +205,5 @@ func (s *Server) newResourceServiceConfig(typeRegistry resource.Registry, resolv ACLResolver: resolver, Logger: s.loggers.Named(logging.GRPCAPI).Named(logging.Resource), TenancyBridge: tenancyBridge, - UseV2Tenancy: s.useV2Tenancy, } } diff --git a/agent/consul/server_grpc.go b/agent/consul/server_grpc.go index a4ff866095..a190c44a05 100644 --- a/agent/consul/server_grpc.go +++ b/agent/consul/server_grpc.go @@ -29,8 +29,6 @@ import ( "github.com/hashicorp/consul/agent/rpc/peering" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/tenancy" - "github.com/hashicorp/consul/lib/stringslice" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/pbsubscribe" @@ -316,7 +314,6 @@ func (s *Server) setupGRPCServices(config *Config, deps Deps) error { // for anything internal in Consul to use the service. If that changes // we could register it on the in-process interfaces as well. err = s.registerDataplaneServer( - deps, s.externalGRPCServer, ) if err != nil { @@ -344,20 +341,7 @@ func (s *Server) registerResourceServiceServer(typeRegistry resource.Registry, r return fmt.Errorf("storage backend cannot be nil") } - var tenancyBridge resourcegrpc.TenancyBridge - if s.useV2Tenancy { - tenancyBridge = tenancy.NewV2TenancyBridge().WithClient( - // This assumes that the resource service will be registered with - // the insecureUnsafeGRPCChan. We are using the insecure and unsafe - // channel here because the V2 Tenancy bridge only reads data - // from the client and does not modify it. Therefore sharing memory - // with the resource services canonical immutable data is advantageous - // to prevent wasting CPU time for every resource op to clone things. - pbresource.NewResourceServiceClient(s.insecureUnsafeGRPCChan), - ) - } else { - tenancyBridge = NewV1TenancyBridge(s) - } + tenancyBridge := NewV1TenancyBridge(s) // Create the Resource Service Server srv := resourcegrpc.NewServer(s.newResourceServiceConfig(typeRegistry, resolver, tenancyBridge)) @@ -510,14 +494,12 @@ func (s *Server) registerConnectCAServer(registrars ...grpc.ServiceRegistrar) er return nil } -func (s *Server) registerDataplaneServer(deps Deps, registrars ...grpc.ServiceRegistrar) error { +func (s *Server) registerDataplaneServer(registrars ...grpc.ServiceRegistrar) error { srv := dataplane.NewServer(dataplane.Config{ - GetStore: func() dataplane.StateStore { return s.FSM().State() }, - Logger: s.loggers.Named(logging.GRPCAPI).Named(logging.Dataplane), - ACLResolver: s.ACLResolver, - Datacenter: s.config.Datacenter, - EnableV2: stringslice.Contains(deps.Experiments, CatalogResourceExperimentName), - ResourceAPIClient: pbresource.NewResourceServiceClient(s.insecureSafeGRPCChan), + GetStore: func() dataplane.StateStore { return s.FSM().State() }, + Logger: s.loggers.Named(logging.GRPCAPI).Named(logging.Dataplane), + ACLResolver: s.ACLResolver, + Datacenter: s.config.Datacenter, }) for _, reg := range registrars { diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go index e685f25ca4..f157fa6dd5 100644 --- a/agent/consul/server_test.go +++ b/agent/consul/server_test.go @@ -19,10 +19,6 @@ import ( "github.com/armon/go-metrics" "github.com/google/tcpproxy" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" - "github.com/hashicorp/memberlist" - "github.com/hashicorp/raft" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "golang.org/x/time/rate" @@ -30,6 +26,10 @@ import ( "google.golang.org/grpc/keepalive" "github.com/hashicorp/consul-net-rpc/net/rpc" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/memberlist" + "github.com/hashicorp/raft" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/multilimiter" @@ -43,7 +43,6 @@ import ( "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" @@ -352,8 +351,7 @@ func newServerWithDeps(t testutil.TestingTB, c *Config, deps Deps) (*Server, err } } grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler(), keepalive.ServerParameters{}, nil) - 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 } @@ -1260,7 +1258,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) } @@ -1298,7 +1296,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) } @@ -1332,7 +1330,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") @@ -1351,7 +1349,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") @@ -2315,7 +2313,7 @@ func TestServer_ControllerDependencies(t *testing.T) { _, conf := testServerConfig(t) deps := newDefaultDeps(t, conf) - deps.Experiments = []string{"resource-apis", "v2tenancy"} + deps.Experiments = []string{"resource-apis"} deps.LeafCertManager = &leafcert.Manager{} s1, err := newServerWithDeps(t, conf, deps) @@ -2325,6 +2323,10 @@ func TestServer_ControllerDependencies(t *testing.T) { // gotest.tools/v3 defines CLI flags which are incompatible wit the golden package // Once we eliminate gotest.tools/v3 from usage within Consul we could uncomment this // actual := fmt.Sprintf("```mermaid\n%s\n```", s1.controllerManager.CalculateDependencies(s1.registry.Types()).ToMermaid()) - // expected := golden.Get(t, actual, "v2-resource-dependencies") + // markdownFileName := "v2-resource-dependencies" + // if versiontest.IsEnterprise() { + // markdownFileName += "-enterprise" + // } + // expected := golden.Get(t, actual, markdownFileName) // require.Equal(t, expected, actual) } diff --git a/agent/consul/testdata/v2-resource-dependencies.md b/agent/consul/testdata/v2-resource-dependencies.md index e394247866..7bcb0d55c4 100644 --- a/agent/consul/testdata/v2-resource-dependencies.md +++ b/agent/consul/testdata/v2-resource-dependencies.md @@ -1,24 +1,5 @@ ```mermaid flowchart TD - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/namespacetrafficpermissions - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/partitiontrafficpermissions - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/trafficpermissions - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/workloadidentity - auth/v2beta1/namespacetrafficpermissions - auth/v2beta1/partitiontrafficpermissions - auth/v2beta1/trafficpermissions - auth/v2beta1/workloadidentity - catalog/v2beta1/computedfailoverpolicy --> catalog/v2beta1/failoverpolicy - catalog/v2beta1/computedfailoverpolicy --> catalog/v2beta1/service - catalog/v2beta1/failoverpolicy - catalog/v2beta1/healthstatus - catalog/v2beta1/node --> catalog/v2beta1/nodehealthstatus - catalog/v2beta1/nodehealthstatus - 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 @@ -27,42 +8,12 @@ flowchart TD demo/v2/album demo/v2/artist hcp/v2/link - hcp/v2/telemetrystate --> hcp/v2/link + hcp/v2/telemetrystate 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/computedfailoverpolicy - 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/meshconfiguration - mesh/v2beta1/meshgateway - mesh/v2beta1/proxyconfiguration - mesh/v2beta1/proxystatetemplate --> auth/v2beta1/computedtrafficpermissions - mesh/v2beta1/proxystatetemplate --> catalog/v2beta1/service - mesh/v2beta1/proxystatetemplate --> catalog/v2beta1/serviceendpoints - 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/proxystatetemplate --> multicluster/v2/computedexportedservices - mesh/v2beta1/tcproute - multicluster/v2/computedexportedservices --> catalog/v2beta1/service multicluster/v2/computedexportedservices --> multicluster/v2/exportedservices multicluster/v2/computedexportedservices --> multicluster/v2/namespaceexportedservices multicluster/v2/computedexportedservices --> multicluster/v2/partitionexportedservices multicluster/v2/exportedservices multicluster/v2/namespaceexportedservices multicluster/v2/partitionexportedservices - tenancy/v2beta1/namespace ``` \ No newline at end of file diff --git a/agent/consul/type_registry.go b/agent/consul/type_registry.go index 450cef7e05..cd2087e48f 100644 --- a/agent/consul/type_registry.go +++ b/agent/consul/type_registry.go @@ -4,14 +4,10 @@ package consul import ( - "github.com/hashicorp/consul/internal/auth" - "github.com/hashicorp/consul/internal/catalog" "github.com/hashicorp/consul/internal/hcp" - "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 @@ -25,10 +21,6 @@ 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) hcp.RegisterTypes(registry) 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 ea4852efab..bbc2390a77 100644 --- a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go +++ b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go @@ -8,16 +8,12 @@ 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/go-hclog" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/configentry" @@ -50,72 +46,6 @@ 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) @@ -181,9 +111,9 @@ func (s *Server) GetEnvoyBootstrapParams(ctx context.Context, req *pbdataplane.G }, nil } -func makeAccessLogs(logs structs.AccessLogs, logger hclog.Logger) []string { +func makeAccessLogs(logs *structs.AccessLogsConfig, logger hclog.Logger) []string { var accessLogs []string - if logs.GetEnabled() { + if logs.Enabled { envoyLoggers, err := accesslogs.MakeAccessLogs(logs, false) if err != nil { logger.Warn("Error creating the envoy access log config", "error", err) 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 2a50094029..bcff21cce5 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 @@ -18,18 +18,9 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" external "github.com/hashicorp/consul/agent/grpc-external" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" "github.com/hashicorp/consul/agent/grpc-external/testutils" "github.com/hashicorp/consul/agent/structs" - "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" "github.com/hashicorp/consul/proto-public/pbdataplane" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" ) const ( @@ -252,156 +243,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.NewResourceServiceBuilder(). - WithRegisterFns(catalog.RegisterTypes, mesh.RegisterTypes). - Run(t) - - 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 @@ -483,100 +324,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.NewResourceServiceBuilder(). - WithRegisterFns(catalog.RegisterTypes, mesh.RegisterTypes). - Run(t) - - 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/server.go b/agent/grpc-external/services/dataplane/server.go index 3a1809cc04..68972ce252 100644 --- a/agent/grpc-external/services/dataplane/server.go +++ b/agent/grpc-external/services/dataplane/server.go @@ -4,7 +4,6 @@ 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/resource/delete.go b/agent/grpc-external/services/resource/delete.go index dbfdf07edb..839bc7fa70 100644 --- a/agent/grpc-external/services/resource/delete.go +++ b/agent/grpc-external/services/resource/delete.go @@ -19,7 +19,6 @@ import ( "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" ) // Delete deletes a resource. @@ -200,17 +199,10 @@ func (s *Server) ensureDeleteRequestValid(req *pbresource.DeleteRequest) (*resou return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Id.Type); err != nil { - return nil, err - } - if err := validateScopedTenancy(reg.Scope, reg.Type, req.Id.Tenancy, false); err != nil { return nil, err } - if err := blockBuiltinsDeletion(reg.Type, req.Id); err != nil { - return nil, err - } return reg, nil } @@ -220,12 +212,3 @@ func TombstoneNameFor(deleteId *pbresource.ID) string { // deleteId.Name is just included for easier identification return fmt.Sprintf("tombstone-%v-%v", deleteId.Name, strings.ToLower(deleteId.Uid)) } - -func blockDefaultNamespaceDeletion(rtype *pbresource.Type, id *pbresource.ID) error { - if id.Name == resource.DefaultNamespaceName && - id.Tenancy.Partition == resource.DefaultPartitionName && - resource.EqualType(rtype, pbtenancy.NamespaceType) { - return status.Errorf(codes.InvalidArgument, "cannot delete default namespace") - } - return nil -} diff --git a/agent/grpc-external/services/resource/delete_ce.go b/agent/grpc-external/services/resource/delete_ce.go deleted file mode 100644 index d2ff805a24..0000000000 --- a/agent/grpc-external/services/resource/delete_ce.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package resource - -import "github.com/hashicorp/consul/proto-public/pbresource" - -func blockBuiltinsDeletion(rtype *pbresource.Type, id *pbresource.ID) error { - if err := blockDefaultNamespaceDeletion(rtype, id); err != nil { - return err - } - return nil -} diff --git a/agent/grpc-external/services/resource/delete_test.go b/agent/grpc-external/services/resource/delete_test.go index 76403bb4d6..25a8012051 100644 --- a/agent/grpc-external/services/resource/delete_test.go +++ b/agent/grpc-external/services/resource/delete_test.go @@ -5,7 +5,6 @@ package resource_test import ( "context" - "fmt" "strings" "testing" @@ -22,7 +21,6 @@ import ( "github.com/hashicorp/consul/internal/resource/demo" rtest "github.com/hashicorp/consul/internal/resource/resourcetest" "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v1" ) @@ -137,37 +135,28 @@ func TestDelete_InputValidation(t *testing.T) { }, } - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - run(t, client, tc) - }) - } + for desc, tc := range testCases { + t.Run(desc, func(t *testing.T) { + run(t, client, tc) }) } } func TestDelete_TypeNotRegistered(t *testing.T) { - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder().WithV2Tenancy(useV2Tenancy).Run(t) + client := svctest.NewResourceServiceBuilder().Run(t) - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) - // delete artist with unregistered type - _, err = client.Delete(context.Background(), &pbresource.DeleteRequest{Id: artist.Id, Version: ""}) - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, "not registered") - }) - } + // delete artist with unregistered type + _, err = client.Delete(context.Background(), &pbresource.DeleteRequest{Id: artist.Id, Version: ""}) + require.Error(t, err) + require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) + require.ErrorContains(t, err, "not registered") } func TestDelete_ACLs(t *testing.T) { @@ -274,15 +263,10 @@ func TestDelete_Success(t *testing.T) { t.Run(desc, func(t *testing.T) { for tenancyDesc, modFn := range tenancyCases() { t.Run(tenancyDesc, func(t *testing.T) { - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) - run(t, client, tc, modFn) - }) - } + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) + run(t, client, tc, modFn) }) } }) @@ -338,46 +322,41 @@ func TestDelete_NonCAS_Retry(t *testing.T) { func TestDelete_TombstoneDeletionDoesNotCreateNewTombstone(t *testing.T) { t.Parallel() - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - ctx := context.Background() - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) + ctx := context.Background() + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) - rsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - artist = rsp.Resource + rsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: artist}) + require.NoError(t, err) + artist = rsp.Resource - // delete artist - _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: artist.Id, Version: ""}) - require.NoError(t, err) + // delete artist + _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: artist.Id, Version: ""}) + require.NoError(t, err) - // verify artist's tombstone created - rsp2, err := client.Read(ctx, &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: svc.TombstoneNameFor(artist.Id), - Type: resource.TypeV1Tombstone, - Tenancy: artist.Id.Tenancy, - }, - }) - require.NoError(t, err) - tombstone := rsp2.Resource + // verify artist's tombstone created + rsp2, err := client.Read(ctx, &pbresource.ReadRequest{ + Id: &pbresource.ID{ + Name: svc.TombstoneNameFor(artist.Id), + Type: resource.TypeV1Tombstone, + Tenancy: artist.Id.Tenancy, + }, + }) + require.NoError(t, err) + tombstone := rsp2.Resource - // delete artist's tombstone - _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: tombstone.Id, Version: tombstone.Version}) - require.NoError(t, err) + // delete artist's tombstone + _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: tombstone.Id, Version: tombstone.Version}) + require.NoError(t, err) - // verify no new tombstones created and artist's existing tombstone deleted - rsp3, err := client.List(ctx, &pbresource.ListRequest{Type: resource.TypeV1Tombstone, Tenancy: artist.Id.Tenancy}) - require.NoError(t, err) - require.Empty(t, rsp3.Resources) - }) - } + // verify no new tombstones created and artist's existing tombstone deleted + rsp3, err := client.List(ctx, &pbresource.ListRequest{Type: resource.TypeV1Tombstone, Tenancy: artist.Id.Tenancy}) + require.NoError(t, err) + require.Empty(t, rsp3.Resources) } func TestDelete_NotFound(t *testing.T) { @@ -392,18 +371,13 @@ func TestDelete_NotFound(t *testing.T) { require.NoError(t, err) } - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - for desc, tc := range deleteTestCases() { - t.Run(desc, func(t *testing.T) { - run(t, client, tc) - }) - } + for desc, tc := range deleteTestCases() { + t.Run(desc, func(t *testing.T) { + run(t, client, tc) }) } } @@ -411,115 +385,86 @@ func TestDelete_NotFound(t *testing.T) { func TestDelete_VersionMismatch(t *testing.T) { t.Parallel() - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) + rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: artist}) + require.NoError(t, err) - // delete with a version that is different from the stored version - _, err = client.Delete(context.Background(), &pbresource.DeleteRequest{Id: rsp.Resource.Id, Version: "non-existent-version"}) - require.Error(t, err) - require.Equal(t, codes.Aborted.String(), status.Code(err).String()) - require.ErrorContains(t, err, "CAS operation failed") - }) - } + // delete with a version that is different from the stored version + _, err = client.Delete(context.Background(), &pbresource.DeleteRequest{Id: rsp.Resource.Id, Version: "non-existent-version"}) + require.Error(t, err) + require.Equal(t, codes.Aborted.String(), status.Code(err).String()) + require.ErrorContains(t, err, "CAS operation failed") } func TestDelete_MarkedForDeletionWhenFinalizersPresent(t *testing.T) { - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - ctx := context.Background() - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) + ctx := context.Background() + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - // Create a resource with a finalizer - res := rtest.Resource(demo.TypeV1Artist, "manwithnoname"). - WithTenancy(resource.DefaultClusteredTenancy()). - WithData(t, &pbdemo.Artist{Name: "Man With No Name"}). - WithMeta(resource.FinalizerKey, "finalizer1"). - Write(t, client) + // Create a resource with a finalizer + res := rtest.Resource(demo.TypeV1Artist, "manwithnoname"). + WithTenancy(resource.DefaultClusteredTenancy()). + WithData(t, &pbdemo.Artist{Name: "Man With No Name"}). + WithMeta(resource.FinalizerKey, "finalizer1"). + Write(t, client) - // Delete it - _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) + // Delete it + _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) + require.NoError(t, err) - // Verify resource has been marked for deletion - rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - require.True(t, resource.IsMarkedForDeletion(rsp.Resource)) + // Verify resource has been marked for deletion + rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) + require.NoError(t, err) + require.True(t, resource.IsMarkedForDeletion(rsp.Resource)) - // Delete again - should be no-op - _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) + // Delete again - should be no-op + _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) + require.NoError(t, err) - // Verify no-op by checking version still the same - rsp2, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - rtest.RequireVersionUnchanged(t, rsp2.Resource, rsp.Resource.Version) - }) - } + // Verify no-op by checking version still the same + rsp2, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) + require.NoError(t, err) + rtest.RequireVersionUnchanged(t, rsp2.Resource, rsp.Resource.Version) } func TestDelete_ImmediatelyDeletedAfterFinalizersRemoved(t *testing.T) { - for _, useV2Tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", useV2Tenancy), func(t *testing.T) { - ctx := context.Background() - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(useV2Tenancy). - WithRegisterFns(demo.RegisterTypes). - Run(t) + ctx := context.Background() + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - // Create a resource with a finalizer - res := rtest.Resource(demo.TypeV1Artist, "manwithnoname"). - WithTenancy(resource.DefaultClusteredTenancy()). - WithData(t, &pbdemo.Artist{Name: "Man With No Name"}). - WithMeta(resource.FinalizerKey, "finalizer1"). - Write(t, client) + // Create a resource with a finalizer + res := rtest.Resource(demo.TypeV1Artist, "manwithnoname"). + WithTenancy(resource.DefaultClusteredTenancy()). + WithData(t, &pbdemo.Artist{Name: "Man With No Name"}). + WithMeta(resource.FinalizerKey, "finalizer1"). + Write(t, client) - // Delete should mark it for deletion - _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) + // Delete should mark it for deletion + _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) + require.NoError(t, err) - // Remove the finalizer - rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - resource.RemoveFinalizer(rsp.Resource, "finalizer1") - _, err = client.Write(ctx, &pbresource.WriteRequest{Resource: rsp.Resource}) - require.NoError(t, err) + // Remove the finalizer + rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) + require.NoError(t, err) + resource.RemoveFinalizer(rsp.Resource, "finalizer1") + _, err = client.Write(ctx, &pbresource.WriteRequest{Resource: rsp.Resource}) + require.NoError(t, err) - // Delete should be immediate - _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: rsp.Resource.Id}) - require.NoError(t, err) + // Delete should be immediate + _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: rsp.Resource.Id}) + require.NoError(t, err) - // Verify deleted - _, err = client.Read(ctx, &pbresource.ReadRequest{Id: rsp.Resource.Id}) - require.Error(t, err) - require.Equal(t, codes.NotFound.String(), status.Code(err).String()) - }) - } -} - -func TestDelete_BlockDeleteDefaultNamespace(t *testing.T) { - client := svctest.NewResourceServiceBuilder().WithV2Tenancy(true).Run(t) - - id := &pbresource.ID{ - Name: resource.DefaultNamespaceName, - Type: pbtenancy.NamespaceType, - Tenancy: &pbresource.Tenancy{Partition: resource.DefaultPartitionName}, - } - _, err := client.Delete(context.Background(), &pbresource.DeleteRequest{Id: id}) + // Verify deleted + _, err = client.Read(ctx, &pbresource.ReadRequest{Id: rsp.Resource.Id}) require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, "cannot delete default namespace") + require.Equal(t, codes.NotFound.String(), status.Code(err).String()) } type deleteTestCase struct { diff --git a/agent/grpc-external/services/resource/list.go b/agent/grpc-external/services/resource/list.go index 62ec2d7975..2e51c443d4 100644 --- a/agent/grpc-external/services/resource/list.go +++ b/agent/grpc-external/services/resource/list.go @@ -104,10 +104,6 @@ func (s *Server) ensureListRequestValid(req *pbresource.ListRequest) (*resource. // not enabled in the license. _ = s.FeatureCheck(reg) - if err = checkV2Tenancy(s.UseV2Tenancy, req.Type); err != nil { - return nil, err - } - if err := validateWildcardTenancy(req.Tenancy, req.NamePrefix); err != nil { return nil, err } diff --git a/agent/grpc-external/services/resource/list_by_owner.go b/agent/grpc-external/services/resource/list_by_owner.go index bb1868a620..29e14e4072 100644 --- a/agent/grpc-external/services/resource/list_by_owner.go +++ b/agent/grpc-external/services/resource/list_by_owner.go @@ -100,10 +100,6 @@ func (s *Server) ensureListByOwnerRequestValid(req *pbresource.ListByOwnerReques return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Owner.Type); err != nil { - return nil, err - } - if err = validateScopedTenancy(reg.Scope, reg.Type, req.Owner.Tenancy, true); err != nil { return nil, err } 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 92167042ea..23c537dcd6 100644 --- a/agent/grpc-external/services/resource/list_by_owner_test.go +++ b/agent/grpc-external/services/resource/list_by_owner_test.go @@ -27,8 +27,6 @@ import ( "github.com/hashicorp/consul/proto/private/prototest" ) -// TODO: Update all tests to use true/false table test for v2tenancy - func TestListByOwner_InputValidation(t *testing.T) { client := svctest.NewResourceServiceBuilder(). WithRegisterFns(demo.RegisterTypes). diff --git a/agent/grpc-external/services/resource/list_test.go b/agent/grpc-external/services/resource/list_test.go index efcfa3cafd..43d5def0c3 100644 --- a/agent/grpc-external/services/resource/list_test.go +++ b/agent/grpc-external/services/resource/list_test.go @@ -27,8 +27,6 @@ import ( "github.com/hashicorp/consul/proto/private/prototest" ) -// TODO: Update all tests to use true/false table test for v2tenancy - func TestList_InputValidation(t *testing.T) { client := svctest.NewResourceServiceBuilder(). WithRegisterFns(demo.RegisterTypes). diff --git a/agent/grpc-external/services/resource/mutate_and_validate.go b/agent/grpc-external/services/resource/mutate_and_validate.go index 7aa3519f38..c58fd4a095 100644 --- a/agent/grpc-external/services/resource/mutate_and_validate.go +++ b/agent/grpc-external/services/resource/mutate_and_validate.go @@ -127,10 +127,6 @@ func (s *Server) ensureResourceValid(res *pbresource.Resource, enforceLicenseChe return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, res.Id.Type); err != nil { - return nil, err - } - // Check scope if reg.Scope == resource.ScopePartition && res.Id.Tenancy.Namespace != "" { return nil, status.Errorf( diff --git a/agent/grpc-external/services/resource/mutate_and_validate_test.go b/agent/grpc-external/services/resource/mutate_and_validate_test.go index 8f163e778c..6644f108d4 100644 --- a/agent/grpc-external/services/resource/mutate_and_validate_test.go +++ b/agent/grpc-external/services/resource/mutate_and_validate_test.go @@ -4,7 +4,6 @@ package resource_test import ( - "fmt" "testing" "github.com/stretchr/testify/require" @@ -34,18 +33,13 @@ func TestMutateAndValidate_InputValidation(t *testing.T) { require.ErrorContains(t, err, tc.errContains) } - for _, v2tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", v2tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithRegisterFns(demo.RegisterTypes). - WithV2Tenancy(v2tenancy). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - for desc, tc := range resourceValidTestCases(t) { - t.Run(desc, func(t *testing.T) { - run(t, client, tc) - }) - } + for desc, tc := range resourceValidTestCases(t) { + t.Run(desc, func(t *testing.T) { + run(t, client, tc) }) } } @@ -66,39 +60,27 @@ func TestMutateAndValidate_OwnerValidation(t *testing.T) { require.ErrorContains(t, err, tc.errorContains) } - for _, v2tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", v2tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithRegisterFns(demo.RegisterTypes). - WithV2Tenancy(v2tenancy). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - for desc, tc := range ownerValidationTestCases(t) { - t.Run(desc, func(t *testing.T) { - run(t, client, tc) - }) - } + for desc, tc := range ownerValidationTestCases(t) { + t.Run(desc, func(t *testing.T) { + run(t, client, tc) }) } } func TestMutateAndValidate_TypeNotFound(t *testing.T) { - run := func(t *testing.T, client pbresource.ResourceServiceClient) { - res, err := demo.GenerateV2Artist() - require.NoError(t, err) + client := svctest.NewResourceServiceBuilder().Run(t) - _, err = client.MutateAndValidate(testContext(t), &pbresource.MutateAndValidateRequest{Resource: res}) - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.Contains(t, err.Error(), "resource type demo.v2.Artist not registered") - } + res, err := demo.GenerateV2Artist() + require.NoError(t, err) - for _, v2tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", v2tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder().WithV2Tenancy(v2tenancy).Run(t) - run(t, client) - }) - } + _, err = client.MutateAndValidate(testContext(t), &pbresource.MutateAndValidateRequest{Resource: res}) + require.Error(t, err) + require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) + require.Contains(t, err.Error(), "resource type demo.v2.Artist not registered") } func TestMutateAndValidate_Success(t *testing.T) { @@ -114,72 +96,40 @@ func TestMutateAndValidate_Success(t *testing.T) { prototest.AssertDeepEqual(t, tc.expectedTenancy, rsp.Resource.Id.Tenancy) } - for _, v2tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", v2tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithRegisterFns(demo.RegisterTypes). - WithV2Tenancy(v2tenancy). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - for desc, tc := range mavOrWriteSuccessTestCases(t) { - t.Run(desc, func(t *testing.T) { - run(t, client, tc) - }) - } + for desc, tc := range mavOrWriteSuccessTestCases(t) { + t.Run(desc, func(t *testing.T) { + run(t, client, tc) }) } } func TestMutateAndValidate_Mutate(t *testing.T) { - for _, v2tenancy := range []bool{false, true} { - t.Run(fmt.Sprintf("v2tenancy %v", v2tenancy), func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithRegisterFns(demo.RegisterTypes). - WithV2Tenancy(v2tenancy). - Run(t) + client := svctest.NewResourceServiceBuilder(). + WithRegisterFns(demo.RegisterTypes). + Run(t) - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) - artistData := &pbdemov2.Artist{} - artist.Data.UnmarshalTo(artistData) - require.NoError(t, err) + artistData := &pbdemov2.Artist{} + artist.Data.UnmarshalTo(artistData) + require.NoError(t, err) - // mutate hook sets genre to disco when unspecified - artistData.Genre = pbdemov2.Genre_GENRE_UNSPECIFIED - artist.Data.MarshalFrom(artistData) - require.NoError(t, err) + // mutate hook sets genre to disco when unspecified + artistData.Genre = pbdemov2.Genre_GENRE_UNSPECIFIED + artist.Data.MarshalFrom(artistData) + require.NoError(t, err) - rsp, err := client.MutateAndValidate(testContext(t), &pbresource.MutateAndValidateRequest{Resource: artist}) - require.NoError(t, err) + rsp, err := client.MutateAndValidate(testContext(t), &pbresource.MutateAndValidateRequest{Resource: artist}) + require.NoError(t, err) - // verify mutate hook set genre to disco - require.NoError(t, rsp.Resource.Data.UnmarshalTo(artistData)) - require.Equal(t, pbdemov2.Genre_GENRE_DISCO, artistData.Genre) - }) - } -} - -func TestMutateAndValidate_Tenancy_NotFound(t *testing.T) { - for desc, tc := range mavOrWriteTenancyNotFoundTestCases(t) { - t.Run(desc, func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - _, err = client.MutateAndValidate(testContext(t), &pbresource.MutateAndValidateRequest{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) - }) - } + // verify mutate hook set genre to disco + require.NoError(t, rsp.Resource.Data.UnmarshalTo(artistData)) + require.Equal(t, pbdemov2.Genre_GENRE_DISCO, artistData.Genre) } func TestMutateAndValidate_TenancyMarkedForDeletion_Fails(t *testing.T) { diff --git a/agent/grpc-external/services/resource/read.go b/agent/grpc-external/services/resource/read.go index 48d07a3375..bf69e2549a 100644 --- a/agent/grpc-external/services/resource/read.go +++ b/agent/grpc-external/services/resource/read.go @@ -106,10 +106,6 @@ func (s *Server) ensureReadRequestValid(req *pbresource.ReadRequest) (*resource. // not enabled in the license. _ = s.FeatureCheck(reg) - if err = checkV2Tenancy(s.UseV2Tenancy, req.Id.Type); err != nil { - return nil, err - } - // Check scope if err = validateScopedTenancy(reg.Scope, req.Id.Type, req.Id.Tenancy, false); err != nil { return nil, err diff --git a/agent/grpc-external/services/resource/read_test.go b/agent/grpc-external/services/resource/read_test.go index b7367e6390..fbea0137af 100644 --- a/agent/grpc-external/services/resource/read_test.go +++ b/agent/grpc-external/services/resource/read_test.go @@ -30,8 +30,6 @@ import ( "github.com/hashicorp/consul/sdk/testutil" ) -// TODO: Update all tests to use true/false table test for v2tenancy - func TestRead_InputValidation(t *testing.T) { client := svctest.NewResourceServiceBuilder(). WithRegisterFns(demo.RegisterTypes). @@ -162,74 +160,6 @@ func TestRead_TypeNotFound(t *testing.T) { require.Contains(t, err.Error(), "resource type demo.v2.Artist not registered") } -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) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - _, err = client.Write(context.Background(), &pbresource.WriteRequest{Resource: recordLabel}) - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - _, err = client.Write(context.Background(), &pbresource.WriteRequest{Resource: 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) - }) - } - }) - } -} - func TestRead_GroupVersionMismatch(t *testing.T) { for desc, tc := range readTestCases() { t.Run(desc, func(t *testing.T) { diff --git a/agent/grpc-external/services/resource/server_ce.go b/agent/grpc-external/services/resource/server_ce.go index 6b2551b06b..88f6e60add 100644 --- a/agent/grpc-external/services/resource/server_ce.go +++ b/agent/grpc-external/services/resource/server_ce.go @@ -6,15 +6,11 @@ package resource import ( - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "github.com/hashicorp/go-hclog" "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 { @@ -31,15 +27,6 @@ func v1EntMetaToV2Tenancy(reg *resource.Registration, entMeta *acl.EnterpriseMet } } -// 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 -} - type Config struct { Logger hclog.Logger Registry Registry @@ -50,11 +37,6 @@ type Config struct { // 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" experiment is active, false otherwise. - // Attempts to create v2 tenancy resources (partition or namespace) will fail when the - // flag is false. - UseV2Tenancy bool } // FeatureCheck does not apply to the community edition. diff --git a/agent/grpc-external/services/resource/testing/builder.go b/agent/grpc-external/services/resource/testing/builder.go index ea61928ce3..8c42096746 100644 --- a/agent/grpc-external/services/resource/testing/builder.go +++ b/agent/grpc-external/services/resource/testing/builder.go @@ -15,7 +15,6 @@ import ( "github.com/hashicorp/consul/agent/grpc-external/testutils" "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" ) @@ -26,25 +25,14 @@ import ( // making requests. func NewResourceServiceBuilder() *Builder { b := &Builder{ - useV2Tenancy: false, - registry: resource.NewRegistry(), - // Regardless of whether using mock of v2tenancy, always make sure - // the builtin tenancy exists. + registry: resource.NewRegistry(), + // Always make sure the builtin tenancy exists. tenancies: []*pbresource.Tenancy{resource.DefaultNamespacedTenancy()}, cloning: true, } return b } -// WithV2Tenancy configures which tenancy bridge is used. -// -// true => real v2 default partition and namespace via v2 tenancy bridge -// false => mock default partition and namespace since v1 tenancy bridge can't be used (not spinning up an entire server here) -func (b *Builder) WithV2Tenancy(useV2Tenancy bool) *Builder { - b.useV2Tenancy = useV2Tenancy - return b -} - // Registry provides access to the constructed registry post-Run() when // needed by other test dependencies. func (b *Builder) Registry() resource.Registry { @@ -106,33 +94,22 @@ func (b *Builder) Run(t testutil.TestingTB) pbresource.ResourceServiceClient { t.Cleanup(cancel) go backend.Run(ctx) - // Automatically add tenancy types if v2 tenancy enabled - if b.useV2Tenancy { - b.registerFns = append(b.registerFns, tenancy.RegisterTypes) - } - for _, registerFn := range b.registerFns { registerFn(b.registry) } - var tenancyBridge resource.TenancyBridge - if !b.useV2Tenancy { - // use mock tenancy bridge. default/default has already been added out of the box - mockTenancyBridge := &svc.MockTenancyBridge{} + // use mock tenancy bridge. default/default has already been added out of the box + mockTenancyBridge := &svc.MockTenancyBridge{} - for _, tenancy := range b.tenancies { - mockTenancyBridge.On("PartitionExists", tenancy.Partition).Return(true, nil) - mockTenancyBridge.On("NamespaceExists", tenancy.Partition, tenancy.Namespace).Return(true, nil) - mockTenancyBridge.On("IsPartitionMarkedForDeletion", tenancy.Partition).Return(false, nil) - mockTenancyBridge.On("IsNamespaceMarkedForDeletion", tenancy.Partition, tenancy.Namespace).Return(false, nil) - } - - tenancyBridge = mockTenancyBridge - } else { - // use v2 tenancy bridge. population comes later after client injected. - tenancyBridge = tenancy.NewV2TenancyBridge() + for _, tenancy := range b.tenancies { + mockTenancyBridge.On("PartitionExists", tenancy.Partition).Return(true, nil) + mockTenancyBridge.On("NamespaceExists", tenancy.Partition, tenancy.Namespace).Return(true, nil) + mockTenancyBridge.On("IsPartitionMarkedForDeletion", tenancy.Partition).Return(false, nil) + mockTenancyBridge.On("IsNamespaceMarkedForDeletion", tenancy.Partition, tenancy.Namespace).Return(false, nil) } + tenancyBridge := mockTenancyBridge + if b.aclResolver == nil { // When not provided (regardless of V1 tenancy or V2 tenancy), configure an ACL resolver // that has ACLs disabled and fills in "default" for the partition and namespace when @@ -172,22 +149,5 @@ func (b *Builder) Run(t testutil.TestingTB) pbresource.ResourceServiceClient { client = pbresource.NewCloningResourceServiceClient(client) } - // HACK ALERT: The client needs to be injected into the V2TenancyBridge - // after it has been created due the circular dependency. This will - // go away when the tenancy bridge is removed and V1 is no more, however - // long that takes. - switch config.TenancyBridge.(type) { - case *tenancy.V2TenancyBridge: - config.TenancyBridge.(*tenancy.V2TenancyBridge).WithClient(client) - // Default partition and namespace can finally be created - require.NoError(t, initTenancy(ctx, backend)) - - for _, tenancy := range b.tenancies { - if tenancy.Partition == resource.DefaultPartitionName && tenancy.Namespace == resource.DefaultNamespaceName { - continue - } - t.Fatalf("TODO: implement creation of passed in v2 tenancy: %v", tenancy) - } - } return client } diff --git a/agent/grpc-external/services/resource/testing/builder_ce.go b/agent/grpc-external/services/resource/testing/builder_ce.go index d7f9a7c733..90954e4bfb 100644 --- a/agent/grpc-external/services/resource/testing/builder_ce.go +++ b/agent/grpc-external/services/resource/testing/builder_ce.go @@ -14,13 +14,12 @@ import ( ) type Builder struct { - registry resource.Registry - registerFns []func(resource.Registry) - useV2Tenancy bool - tenancies []*pbresource.Tenancy - aclResolver svc.ACLResolver - serviceImpl *svc.Server - cloning bool + registry resource.Registry + registerFns []func(resource.Registry) + tenancies []*pbresource.Tenancy + aclResolver svc.ACLResolver + serviceImpl *svc.Server + cloning bool } func (b *Builder) ensureLicenseManager() { @@ -33,6 +32,5 @@ func (b *Builder) newConfig(logger hclog.Logger, backend svc.Backend, tenancyBri Backend: backend, ACLResolver: b.aclResolver, TenancyBridge: tenancyBridge, - UseV2Tenancy: b.useV2Tenancy, } } diff --git a/agent/grpc-external/services/resource/testing/testing_ce.go b/agent/grpc-external/services/resource/testing/testing_ce.go index 926acf6d38..023fa5189c 100644 --- a/agent/grpc-external/services/resource/testing/testing_ce.go +++ b/agent/grpc-external/services/resource/testing/testing_ce.go @@ -6,19 +6,7 @@ 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) { @@ -28,36 +16,3 @@ func FillEntMeta(entMeta *acl.EnterpriseMeta) { func FillAuthorizerContext(authzContext *acl.AuthorizerContext) { // nothing to to in CE. } - -// initTenancy creates the builtin v2 namespace resource only. The builtin -// v2 partition is not created because we're in CE. -func initTenancy(ctx context.Context, b *inmem.Backend) error { - 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 511802f2cc..246ae4e296 100644 --- a/agent/grpc-external/services/resource/watch.go +++ b/agent/grpc-external/services/resource/watch.go @@ -130,10 +130,6 @@ func (s *Server) ensureWatchListRequestValid(req *pbresource.WatchListRequest) ( req.Tenancy = wildcardTenancyFor(reg.Scope) } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Type); err != nil { - return nil, err - } - if err := validateWildcardTenancy(req.Tenancy, req.NamePrefix); err != nil { return nil, err } diff --git a/agent/grpc-external/services/resource/watch_test.go b/agent/grpc-external/services/resource/watch_test.go index 5ccdb609ba..73f164e1a9 100644 --- a/agent/grpc-external/services/resource/watch_test.go +++ b/agent/grpc-external/services/resource/watch_test.go @@ -27,8 +27,6 @@ import ( "github.com/hashicorp/consul/proto/private/prototest" ) -// TODO: Update all tests to use true/false table test for v2tenancy - func TestWatchList_InputValidation(t *testing.T) { client := svctest.NewResourceServiceBuilder(). WithRegisterFns(demo.RegisterTypes). diff --git a/agent/grpc-external/services/resource/write_status_test.go b/agent/grpc-external/services/resource/write_status_test.go index 57431eac54..4c52443025 100644 --- a/agent/grpc-external/services/resource/write_status_test.go +++ b/agent/grpc-external/services/resource/write_status_test.go @@ -23,8 +23,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -// TODO: Update all tests to use true/false table test for v2tenancy - func TestWriteStatus_ACL(t *testing.T) { type testCase struct { authz resolver.Result @@ -371,66 +369,6 @@ func TestWriteStatus_Tenancy_Defaults(t *testing.T) { } } -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) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - // 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) { client := svctest.NewResourceServiceBuilder(). WithRegisterFns(demo.RegisterTypes). diff --git a/agent/grpc-external/services/resource/write_test.go b/agent/grpc-external/services/resource/write_test.go index beb47b6f22..c14aaad0e1 100644 --- a/agent/grpc-external/services/resource/write_test.go +++ b/agent/grpc-external/services/resource/write_test.go @@ -4,16 +4,13 @@ package resource_test import ( - "context" "testing" - "time" "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/types/known/anypb" "github.com/hashicorp/consul/acl/resolver" svc "github.com/hashicorp/consul/agent/grpc-external/services/resource" @@ -22,14 +19,11 @@ import ( "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/v1" 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" ) -// TODO: Update all tests to use true/false table test for v2tenancy - func TestWrite_InputValidation(t *testing.T) { client := svctest.NewResourceServiceBuilder(). WithRegisterFns(demo.RegisterTypes). @@ -186,46 +180,6 @@ func TestWrite_Create_Success(t *testing.T) { } } -func TestWrite_Create_Tenancy_NotFound(t *testing.T) { - for desc, tc := range mavOrWriteTenancyNotFoundTestCases(t) { - t.Run(desc, func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - 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_Create_With_DeletionTimestamp_Fails(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - res := rtest.Resource(demo.TypeV1Artist, "blur"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbdemov1.Artist{Name: "Blur"}). - WithMeta(resource.DeletionTimestampKey, time.Now().Format(time.RFC3339)). - Build() - - _, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: res}) - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.Contains(t, err.Error(), resource.DeletionTimestampKey) -} - func TestWrite_Create_With_TenancyMarkedForDeletion_Fails(t *testing.T) { for desc, tc := range mavOrWriteTenancyMarkedForDeletionTestCases(t) { t.Run(desc, func(t *testing.T) { @@ -690,239 +644,3 @@ func TestEnsureFinalizerRemoved(t *testing.T) { }) } } - -func TestWrite_ResourceFrozenAfterMarkedForDeletion(t *testing.T) { - type testCase struct { - modFn func(res *pbresource.Resource) - errContains string - } - testCases := map[string]testCase{ - "no-op write rejected": { - modFn: func(res *pbresource.Resource) {}, - errContains: "cannot no-op write resource marked for deletion", - }, - "remove one finalizer": { - modFn: func(res *pbresource.Resource) { - resource.RemoveFinalizer(res, "finalizer1") - }, - }, - "remove all finalizers": { - modFn: func(res *pbresource.Resource) { - resource.RemoveFinalizer(res, "finalizer1") - resource.RemoveFinalizer(res, "finalizer2") - }, - }, - "adding finalizer fails": { - modFn: func(res *pbresource.Resource) { - resource.AddFinalizer(res, "finalizer3") - }, - errContains: "expected at least one finalizer to be removed", - }, - "remove deletionTimestamp fails": { - modFn: func(res *pbresource.Resource) { - delete(res.Metadata, resource.DeletionTimestampKey) - }, - errContains: "cannot remove deletionTimestamp", - }, - "modify deletionTimestamp fails": { - modFn: func(res *pbresource.Resource) { - res.Metadata[resource.DeletionTimestampKey] = "bad" - }, - errContains: "cannot modify deletionTimestamp", - }, - "modify data fails": { - modFn: func(res *pbresource.Resource) { - var err error - res.Data, err = anypb.New(&pbdemo.Artist{Name: "New Order"}) - require.NoError(t, err) - }, - errContains: "cannot modify data", - }, - } - - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - // Create a resource with finalizers - res := rtest.Resource(demo.TypeV1Artist, "joydivision"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbdemo.Artist{Name: "Joy Division"}). - WithMeta(resource.FinalizerKey, "finalizer1 finalizer2"). - Write(t, client) - - // Mark for deletion - resource should now be frozen - _, err := client.Delete(context.Background(), &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - // Verify marked for deletion - rsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - require.True(t, resource.IsMarkedForDeletion(rsp.Resource)) - - // Apply test case mods - tc.modFn(rsp.Resource) - - // Verify write results - _, err = client.Write(context.Background(), &pbresource.WriteRequest{Resource: rsp.Resource}) - if tc.errContains == "" { - require.NoError(t, err) - } else { - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) - } - }) - } -} - -func TestWrite_NonCASWritePreservesFinalizers(t *testing.T) { - type testCase struct { - existingMeta map[string]string - inputMeta map[string]string - expectedMeta map[string]string - } - testCases := map[string]testCase{ - "input nil metadata preserves existing finalizers": { - inputMeta: nil, - existingMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - expectedMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - }, - "input metadata and no finalizer key preserves existing finalizers": { - inputMeta: map[string]string{}, - existingMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - expectedMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - }, - "input metadata and with empty finalizer key overwrites existing finalizers": { - inputMeta: map[string]string{resource.FinalizerKey: ""}, - existingMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - expectedMeta: map[string]string{resource.FinalizerKey: ""}, - }, - "input metadata with one finalizer key overwrites multiple existing finalizers": { - inputMeta: map[string]string{resource.FinalizerKey: "finalizer2"}, - existingMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - expectedMeta: map[string]string{resource.FinalizerKey: "finalizer2"}, - }, - } - - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - // Create the resource based on tc.existingMetadata - builder := rtest.Resource(demo.TypeV1Artist, "joydivision"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbdemo.Artist{Name: "Joy"}) - - if tc.existingMeta != nil { - for k, v := range tc.existingMeta { - builder.WithMeta(k, v) - } - } - res := builder.Write(t, client) - - // Build resource for user write based on tc.inputMetadata - builder = rtest.Resource(demo.TypeV1Artist, res.Id.Name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbdemo.Artist{Name: "Joy Division"}) - - if tc.inputMeta != nil { - for k, v := range tc.inputMeta { - builder.WithMeta(k, v) - } - } - userRes := builder.Build() - - // Perform the user write - rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: userRes}) - require.NoError(t, err) - - // Verify write result preserved metadata based on testcase.expecteMetadata - for k := range tc.expectedMeta { - require.Equal(t, tc.expectedMeta[k], rsp.Resource.Metadata[k]) - } - require.Equal(t, len(tc.expectedMeta), len(rsp.Resource.Metadata)) - }) - } -} - -func TestWrite_NonCASWritePreservesDeletionTimestamp(t *testing.T) { - type testCase struct { - existingMeta map[string]string - inputMeta map[string]string - expectedMeta map[string]string - } - - // deletionTimestamp has to be generated via Delete() call and can't be embedded in testdata - // even though testcase desc refers to it. - testCases := map[string]testCase{ - "input metadata no deletion timestamp preserves existing deletion timestamp and removes single finalizer": { - inputMeta: map[string]string{resource.FinalizerKey: "finalizer1"}, - existingMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - expectedMeta: map[string]string{resource.FinalizerKey: "finalizer1"}, - }, - "input metadata no deletion timestamp preserves existing deletion timestamp and removes all finalizers": { - inputMeta: map[string]string{resource.FinalizerKey: ""}, - existingMeta: map[string]string{resource.FinalizerKey: "finalizer1 finalizer2"}, - expectedMeta: map[string]string{resource.FinalizerKey: ""}, - }, - } - - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - client := svctest.NewResourceServiceBuilder(). - WithV2Tenancy(true). - WithRegisterFns(demo.RegisterTypes). - Run(t) - - // Create the resource based on tc.existingMetadata - builder := rtest.Resource(demo.TypeV1Artist, "joydivision"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbdemo.Artist{Name: "Joy Division"}) - - if tc.existingMeta != nil { - for k, v := range tc.existingMeta { - builder.WithMeta(k, v) - } - } - res := builder.Write(t, client) - - // Mark for deletion - _, err := client.Delete(context.Background(), &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - // Re-read the deleted res for future comparison of deletionTimestamp - delRsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - - // Build resource for user write based on tc.inputMetadata - builder = rtest.Resource(demo.TypeV1Artist, res.Id.Name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbdemo.Artist{Name: "Joy Division"}) - - if tc.inputMeta != nil { - for k, v := range tc.inputMeta { - builder.WithMeta(k, v) - } - } - userRes := builder.Build() - - // Perform the non-CAS user write - rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: userRes}) - require.NoError(t, err) - - // Verify write result preserved metadata based on testcase.expectedMetadata - for k := range tc.expectedMeta { - require.Equal(t, tc.expectedMeta[k], rsp.Resource.Metadata[k]) - } - // Verify deletion timestamp preserved even though it wasn't passed in to the write - require.Equal(t, delRsp.Resource.Metadata[resource.DeletionTimestampKey], rsp.Resource.Metadata[resource.DeletionTimestampKey]) - }) - } -} diff --git a/agent/health_endpoint_test.go b/agent/health_endpoint_test.go index 98f4eaa714..0768cbb223 100644 --- a/agent/health_endpoint_test.go +++ b/agent/health_endpoint_test.go @@ -15,10 +15,11 @@ import ( "time" "github.com/armon/go-metrics" - "github.com/hashicorp/serf/coordinate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/hashicorp/serf/coordinate" + "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil" @@ -27,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") diff --git a/agent/http.go b/agent/http.go index 66c3a8bd36..e7ba26825a 100644 --- a/agent/http.go +++ b/agent/http.go @@ -22,12 +22,13 @@ import ( "github.com/NYTimes/gziphandler" "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" - "github.com/hashicorp/go-cleanhttp" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/hashicorp/go-cleanhttp" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/config" @@ -397,11 +398,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", @@ -463,14 +459,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 @@ -506,10 +494,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) @@ -586,12 +570,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" @@ -633,46 +612,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) { @@ -1149,20 +1088,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/leafcert/generate.go b/agent/leafcert/generate.go index 19dbdbbaf4..dc9c3b2871 100644 --- a/agent/leafcert/generate.go +++ b/agent/leafcert/generate.go @@ -230,15 +230,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 +272,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 diff --git a/agent/leafcert/leafcert_test_helpers.go b/agent/leafcert/leafcert_test_helpers.go index 0779033dcc..5b0b3226cb 100644 --- a/agent/leafcert/leafcert_test_helpers.go +++ b/agent/leafcert/leafcert_test_helpers.go @@ -180,16 +180,10 @@ 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: return nil, fmt.Errorf("unexpected spiffeID type %T", spiffeID) } @@ -270,35 +264,19 @@ 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 - } + // 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 } type testRootsReader struct { diff --git a/agent/leafcert/structs.go b/agent/leafcert/structs.go index 685756c8dc..8cd7375731 100644 --- a/agent/leafcert/structs.go +++ b/agent/leafcert/structs.go @@ -31,27 +31,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, diff --git a/agent/proxycfg-sources/catalog/config_source.go b/agent/proxycfg-sources/catalog/config_source.go index deb1bbeac8..ec4aabeeb1 100644 --- a/agent/proxycfg-sources/catalog/config_source.go +++ b/agent/proxycfg-sources/catalog/config_source.go @@ -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" @@ -53,13 +51,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, proxycfg.SrcTerminatedChan, 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.SrcTerminatedChan, context.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. @@ -290,7 +286,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, context.CancelFunc) Register(proxyID proxycfg.ProxyID, service *structs.NodeService, source proxycfg.ProxySource, token string, overwrite bool) error Deregister(proxyID proxycfg.ProxyID, source proxycfg.ProxySource) } @@ -303,7 +299,7 @@ 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, proxycfg.SrcTerminatedChan, proxysnapshot.CancelFunc, error) + Watch(proxyID structs.ServiceID, nodeName string, token string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.SrcTerminatedChan, context.CancelFunc, error) } //go:generate mockery --name SessionLimiter --inpackage 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 233ad64cee..0000000000 --- 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 7b267023a6..79a7a85789 100644 --- a/agent/proxycfg-sources/catalog/config_source_test.go +++ b/agent/proxycfg-sources/catalog/config_source_test.go @@ -10,10 +10,11 @@ import ( "testing" "time" - "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/consul/agent/consul/state" "github.com/hashicorp/consul/agent/consul/stream" "github.com/hashicorp/consul/agent/grpc-external/limiter" @@ -21,9 +22,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) { @@ -80,15 +78,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") } @@ -112,7 +110,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") } @@ -131,13 +129,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) @@ -171,7 +169,7 @@ 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() + proxyID := serviceID nodeName := "node-1" token := "token" @@ -180,7 +178,7 @@ func TestConfigSource_LocallyManagedService(t *testing.T) { localWatcher := NewMockWatcher(t) localWatcher.On("Watch", proxyID, nodeName, token). - Return(make(<-chan proxysnapshot.ProxySnapshot), nil, nil, proxysnapshot.CancelFunc(func() {}), nil) + Return(make(<-chan *proxycfg.ConfigSnapshot), nil, nil, context.CancelFunc(func() {}), nil) mgr := NewConfigSource(Config{ NodeName: nodeName, @@ -214,12 +212,12 @@ func TestConfigSource_ErrorRegisteringService(t *testing.T) { })) var canceledWatch bool - cancel := proxysnapshot.CancelFunc(func() { canceledWatch = true }) + cancel := context.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")) @@ -239,7 +237,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") @@ -276,9 +274,9 @@ func TestConfigSource_ErrorInSyncLoop(t *testing.T) { NodeName: nodeName, 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), context.CancelFunc(func() {}), nil) // Answer the register call successfully for session 1 starting (Repeatability = 1). // Session 2 should not have caused a re-register to happen. @@ -330,21 +328,21 @@ func TestConfigSource_ErrorInSyncLoop(t *testing.T) { }) t.Cleanup(mgr.Shutdown) - snapCh, termCh, cfgSrcTerminated1, cancelWatch1, err := mgr.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID(), nodeName, token) + snapCh, termCh, cfgSrcTerminated1, 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") } // Start another watch. - _, termCh2, cfgSrcTerminated2, cancelWatch2, err := mgr.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID(), nodeName, token) + _, termCh2, cfgSrcTerminated2, cancelWatch2, err := mgr.Watch(serviceID, nodeName, token) require.NoError(t, err) require.Equal(t, session2TermCh, termCh2) @@ -424,12 +422,12 @@ func TestConfigSource_NotProxyService(t *testing.T) { })) var canceledWatch bool - cancel := proxysnapshot.CancelFunc(func() { canceledWatch = true }) + cancel := context.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, @@ -440,7 +438,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") @@ -457,7 +455,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", ) @@ -475,9 +473,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), context.CancelFunc(func() {}), nil) cfgMgr.On("Register", mock.Anything, mock.Anything, source, token, false). Run(func(args mock.Arguments) { diff --git a/agent/proxycfg-sources/catalog/mock_ConfigManager.go b/agent/proxycfg-sources/catalog/mock_ConfigManager.go index 2c1608f241..dbd82e702b 100644 --- a/agent/proxycfg-sources/catalog/mock_ConfigManager.go +++ b/agent/proxycfg-sources/catalog/mock_ConfigManager.go @@ -5,8 +5,8 @@ package catalog import ( proxycfg "github.com/hashicorp/consul/agent/proxycfg" mock "github.com/stretchr/testify/mock" + "context" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" structs "github.com/hashicorp/consul/agent/structs" ) @@ -36,27 +36,27 @@ 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, context.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 { + var r0 <-chan *proxycfg.ConfigSnapshot + var r1 context.CancelFunc + if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) (<-chan *proxycfg.ConfigSnapshot, context.CancelFunc)); ok { return rf(req) } - if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) <-chan proxysnapshot.ProxySnapshot); ok { + 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 { + if rf, ok := ret.Get(1).(func(proxycfg.ProxyID) context.CancelFunc); ok { r1 = rf(req) } else { if ret.Get(1) != nil { - r1 = ret.Get(1).(proxysnapshot.CancelFunc) + r1 = ret.Get(1).(context.CancelFunc) } } diff --git a/agent/proxycfg-sources/catalog/mock_Watcher.go b/agent/proxycfg-sources/catalog/mock_Watcher.go index f77ca13283..1fc6ba7c6e 100644 --- a/agent/proxycfg-sources/catalog/mock_Watcher.go +++ b/agent/proxycfg-sources/catalog/mock_Watcher.go @@ -5,12 +5,9 @@ package catalog import ( limiter "github.com/hashicorp/consul/agent/grpc-external/limiter" mock "github.com/stretchr/testify/mock" - - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - + "github.com/hashicorp/consul/agent/structs" proxycfg "github.com/hashicorp/consul/agent/proxycfg" - - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" + "context" ) // MockWatcher is an autogenerated mock type for the Watcher type @@ -19,26 +16,26 @@ 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, proxycfg.SrcTerminatedChan, proxysnapshot.CancelFunc, error) { +func (_m *MockWatcher) Watch(proxyID structs.ServiceID, nodeName string, token string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.SrcTerminatedChan, context.CancelFunc, error) { ret := _m.Called(proxyID, nodeName, token) - var r0 <-chan proxysnapshot.ProxySnapshot + var r0 <-chan *proxycfg.ConfigSnapshot var r1 limiter.SessionTerminatedChan var r2 proxycfg.SrcTerminatedChan - var r3 proxysnapshot.CancelFunc + var r3 context.CancelFunc var r4 error - if rf, ok := ret.Get(0).(func(*pbresource.ID, string, string) (<-chan proxysnapshot.ProxySnapshot, limiter.SessionTerminatedChan, proxycfg.SrcTerminatedChan, proxysnapshot.CancelFunc, error)); ok { + if rf, ok := ret.Get(0).(func(structs.ServiceID, string, string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.SrcTerminatedChan, context.CancelFunc, error)); ok { return rf(proxyID, nodeName, token) } - if rf, ok := ret.Get(0).(func(*pbresource.ID, string, string) <-chan proxysnapshot.ProxySnapshot); ok { + 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 { + 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 { @@ -46,7 +43,7 @@ func (_m *MockWatcher) Watch(proxyID *pbresource.ID, nodeName string, token stri } } - if rf, ok := ret.Get(2).(func(*pbresource.ID, string, string) proxycfg.SrcTerminatedChan); ok { + if rf, ok := ret.Get(2).(func(structs.ServiceID, string, string) proxycfg.SrcTerminatedChan); ok { r2 = rf(proxyID, nodeName, token) } else { if ret.Get(2) != nil { @@ -54,15 +51,15 @@ func (_m *MockWatcher) Watch(proxyID *pbresource.ID, nodeName string, token stri } } - if rf, ok := ret.Get(3).(func(*pbresource.ID, string, string) proxysnapshot.CancelFunc); ok { + if rf, ok := ret.Get(3).(func(structs.ServiceID, string, string) context.CancelFunc); ok { r3 = rf(proxyID, nodeName, token) } else { if ret.Get(3) != nil { - r3 = ret.Get(3).(proxysnapshot.CancelFunc) + r3 = ret.Get(3).(context.CancelFunc) } } - if rf, ok := ret.Get(4).(func(*pbresource.ID, string, string) error); ok { + if rf, ok := ret.Get(4).(func(structs.ServiceID, string, string) error); ok { r4 = rf(proxyID, nodeName, token) } else { r4 = ret.Error(4) diff --git a/agent/proxycfg-sources/local/config_source.go b/agent/proxycfg-sources/local/config_source.go index d30edc1b7b..e3176c597d 100644 --- a/agent/proxycfg-sources/local/config_source.go +++ b/agent/proxycfg-sources/local/config_source.go @@ -4,12 +4,11 @@ package local import ( + "context" + "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,14 +22,13 @@ func NewConfigSource(cfgMgr ConfigManager) *ConfigSource { return &ConfigSource{cfgMgr} } -func (m *ConfigSource) Watch(proxyID *pbresource.ID, nodeName string, _ string) ( - <-chan proxysnapshot.ProxySnapshot, +func (m *ConfigSource) Watch(serviceID structs.ServiceID, nodeName string, _ string) ( + <-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.SrcTerminatedChan, - proxysnapshot.CancelFunc, + context.CancelFunc, error, ) { - serviceID := structs.NewServiceID(proxyID.Name, catalog.GetEnterpriseMetaFromResourceID(proxyID)) watchCh, cancelWatch := m.manager.Watch(proxycfg.ProxyID{ ServiceID: serviceID, NodeName: nodeName, diff --git a/agent/proxycfg-sources/local/mock_ConfigManager.go b/agent/proxycfg-sources/local/mock_ConfigManager.go index e3b2d3a445..66b204d131 100644 --- a/agent/proxycfg-sources/local/mock_ConfigManager.go +++ b/agent/proxycfg-sources/local/mock_ConfigManager.go @@ -5,8 +5,8 @@ package local import ( proxycfg "github.com/hashicorp/consul/agent/proxycfg" mock "github.com/stretchr/testify/mock" + "context" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" structs "github.com/hashicorp/consul/agent/structs" ) @@ -52,27 +52,27 @@ 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, context.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 { + var r0 <-chan *proxycfg.ConfigSnapshot + var r1 context.CancelFunc + if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) (<-chan *proxycfg.ConfigSnapshot, context.CancelFunc)); ok { return rf(id) } - if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) <-chan proxysnapshot.ProxySnapshot); ok { + 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 { + if rf, ok := ret.Get(1).(func(proxycfg.ProxyID) context.CancelFunc); ok { r1 = rf(id) } else { if ret.Get(1) != nil { - r1 = ret.Get(1).(proxysnapshot.CancelFunc) + r1 = ret.Get(1).(context.CancelFunc) } } diff --git a/agent/proxycfg-sources/local/sync.go b/agent/proxycfg-sources/local/sync.go index 54d95e6594..a8047c82f1 100644 --- a/agent/proxycfg-sources/local/sync.go +++ b/agent/proxycfg-sources/local/sync.go @@ -7,8 +7,6 @@ import ( "context" "time" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - "github.com/hashicorp/go-hclog" "github.com/hashicorp/consul/agent/local" @@ -148,7 +146,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, context.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/manager.go b/agent/proxycfg/manager.go index 4d3dd6cbc7..f2f7978a0a 100644 --- a/agent/proxycfg/manager.go +++ b/agent/proxycfg/manager.go @@ -4,17 +4,17 @@ package proxycfg import ( + "context" "errors" "runtime/debug" "sync" - "github.com/hashicorp/consul/lib/channels" - - "github.com/hashicorp/go-hclog" "golang.org/x/time/rate" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/consul/agent/structs" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" + "github.com/hashicorp/consul/lib/channels" "github.com/hashicorp/consul/tlsutil" ) @@ -58,7 +58,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 } @@ -109,7 +109,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 @@ -265,12 +265,12 @@ 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 proxysnapshot.ProxySnapshot, ch chan proxysnapshot.ProxySnapshot) { - m.Logger.Trace("delivering latest proxy snapshot to proxy", "proxyID", snap.(*ConfigSnapshot).ProxyID) +func (m *Manager) deliverLatest(snap *ConfigSnapshot, ch chan *ConfigSnapshot) { + m.Logger.Trace("delivering latest proxy snapshot to proxy", "proxyID", snap.ProxyID) err := channels.DeliverLatest(snap, ch) if err != nil { m.Logger.Error("failed to deliver proxyState to proxy", - "proxy", snap.(*ConfigSnapshot).ProxyID, + "proxy", snap.ProxyID, ) } @@ -280,16 +280,16 @@ func (m *Manager) deliverLatest(snap proxysnapshot.ProxySnapshot, ch chan proxys // 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, context.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 7c83b5c770..e751364ddb 100644 --- a/agent/proxycfg/manager_test.go +++ b/agent/proxycfg/manager_test.go @@ -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" ) @@ -471,7 +470,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 { @@ -481,7 +480,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 { @@ -519,7 +518,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) @@ -535,7 +534,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_test.go b/agent/proxycfg_test.go index 568d616486..d692c25789 100644 --- a/agent/proxycfg_test.go +++ b/agent/proxycfg_test.go @@ -4,6 +4,7 @@ package agent import ( + "context" "encoding/json" "net/http" "net/http/httptest" @@ -13,11 +14,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" ) @@ -64,9 +63,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 context.CancelFunc ) defer func() { if cancel != nil { @@ -87,7 +86,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/rpc/peering/service_test.go b/agent/rpc/peering/service_test.go index efc3bff697..f385a11c28 100644 --- a/agent/rpc/peering/service_test.go +++ b/agent/rpc/peering/service_test.go @@ -16,8 +16,6 @@ import ( "time" "github.com/google/tcpproxy" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" "github.com/stretchr/testify/require" gogrpc "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -26,6 +24,9 @@ import ( grpcstatus "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul" @@ -1835,7 +1836,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{}, nil) - 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()) diff --git a/agent/structs/acl.go b/agent/structs/acl.go index d856ce0af2..579e8d231e 100644 --- a/agent/structs/acl.go +++ b/agent/structs/acl.go @@ -13,13 +13,12 @@ import ( "strings" "time" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/lib/stringslice" - "golang.org/x/crypto/blake2b" "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/lib/stringslice" ) type ACLMode string @@ -63,10 +62,6 @@ agent_prefix "" { event_prefix "" { policy = "%[1]s" } -identity_prefix "" { - policy = "%[1]s" - intentions = "%[1]s" -} key_prefix "" { policy = "%[1]s" } diff --git a/agent/structs/acl_templated_policy.go b/agent/structs/acl_templated_policy.go index 52bdb0d66f..076d6ae256 100644 --- a/agent/structs/acl_templated_policy.go +++ b/agent/structs/acl_templated_policy.go @@ -11,10 +11,11 @@ import ( "hash/fnv" "text/template" - "github.com/hashicorp/go-multierror" "github.com/xeipuuv/gojsonschema" "golang.org/x/exp/slices" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib/stringslice" @@ -26,30 +27,26 @@ var ACLTemplatedPolicyNodeSchema string //go:embed acltemplatedpolicy/schemas/service.json var ACLTemplatedPolicyServiceSchema string -//go:embed acltemplatedpolicy/schemas/workload-identity.json -var ACLTemplatedPolicyWorkloadIdentitySchema string - //go:embed acltemplatedpolicy/schemas/api-gateway.json var ACLTemplatedPolicyAPIGatewaySchema 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" - ACLTemplatedPolicyAPIGatewayID = "00000000-0000-0000-0000-000000000008" - ACLTemplatedPolicyNomadClientID = "00000000-0000-0000-0000-000000000009" + ACLTemplatedPolicyServiceID = "00000000-0000-0000-0000-000000000003" + ACLTemplatedPolicyNodeID = "00000000-0000-0000-0000-000000000004" + ACLTemplatedPolicyDNSID = "00000000-0000-0000-0000-000000000005" + ACLTemplatedPolicyNomadServerID = "00000000-0000-0000-0000-000000000006" + _ = "00000000-0000-0000-0000-000000000007" // formerly workload identity + ACLTemplatedPolicyAPIGatewayID = "00000000-0000-0000-0000-000000000008" + ACLTemplatedPolicyNomadClientID = "00000000-0000-0000-0000-000000000009" - ACLTemplatedPolicyServiceDescription = "Gives the token or role permissions to register a service and discover services in the Consul catalog. It also gives the specified service's sidecar proxy the permission to discover and route traffic to other services." - ACLTemplatedPolicyNodeDescription = "Gives the token or role permissions for a register an agent/node into the catalog. A node is typically a consul agent but can also be a physical server, cloud instance or a container." - ACLTemplatedPolicyDNSDescription = "Gives the token or role permissions for the Consul DNS to query services in the network." - ACLTemplatedPolicyNomadServerDescription = "Gives the token or role permissions required for integration with a nomad server." - ACLTemplatedPolicyWorkloadIdentityDescription = "Gives the token or role permissions for a specific workload identity." - ACLTemplatedPolicyAPIGatewayDescription = "Gives the token or role permissions for a Consul api gateway" - ACLTemplatedPolicyNomadClientDescription = "Gives the token or role permissions required for integration with a nomad client." + ACLTemplatedPolicyServiceDescription = "Gives the token or role permissions to register a service and discover services in the Consul catalog. It also gives the specified service's sidecar proxy the permission to discover and route traffic to other services." + ACLTemplatedPolicyNodeDescription = "Gives the token or role permissions for a register an agent/node into the catalog. A node is typically a consul agent but can also be a physical server, cloud instance or a container." + ACLTemplatedPolicyDNSDescription = "Gives the token or role permissions for the Consul DNS to query services in the network." + ACLTemplatedPolicyNomadServerDescription = "Gives the token or role permissions required for integration with a nomad server." + ACLTemplatedPolicyAPIGatewayDescription = "Gives the token or role permissions for a Consul api gateway" + ACLTemplatedPolicyNomadClientDescription = "Gives the token or role permissions required for integration with a nomad client." ACLTemplatedPolicyNoRequiredVariablesSchema = "" // catch-all schema for all templated policy that don't require a schema ) @@ -96,13 +93,6 @@ var ( Template: ACLTemplatedPolicyNomadServer, Description: ACLTemplatedPolicyNomadServerDescription, }, - api.ACLTemplatedPolicyWorkloadIdentityName: { - TemplateID: ACLTemplatedPolicyWorkloadIdentityID, - TemplateName: api.ACLTemplatedPolicyWorkloadIdentityName, - Schema: ACLTemplatedPolicyWorkloadIdentitySchema, - Template: ACLTemplatedPolicyWorkloadIdentity, - Description: ACLTemplatedPolicyWorkloadIdentityDescription, - }, api.ACLTemplatedPolicyAPIGatewayName: { TemplateID: ACLTemplatedPolicyAPIGatewayID, TemplateName: api.ACLTemplatedPolicyAPIGatewayName, diff --git a/agent/structs/acl_templated_policy_ce.go b/agent/structs/acl_templated_policy_ce.go index 23e656f0fb..3cbaa22217 100644 --- a/agent/structs/acl_templated_policy_ce.go +++ b/agent/structs/acl_templated_policy_ce.go @@ -19,9 +19,6 @@ 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 - //go:embed acltemplatedpolicy/policies/ce/api-gateway.hcl var ACLTemplatedPolicyAPIGateway string diff --git a/agent/structs/acl_templated_policy_ce_test.go b/agent/structs/acl_templated_policy_ce_test.go index f212928062..63f42ca83e 100644 --- a/agent/structs/acl_templated_policy_ce_test.go +++ b/agent/structs/acl_templated_policy_ce_test.go @@ -80,21 +80,6 @@ service_prefix "" { } 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" }`, }, }, 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 ccd1e05646..0000000000 --- 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/workload-identity.json b/agent/structs/acltemplatedpolicy/schemas/workload-identity.json deleted file mode 100644 index 31064f36af..0000000000 --- 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/connect_ca.go b/agent/structs/connect_ca.go index 267aeba5e6..5fa7b07715 100644 --- a/agent/structs/connect_ca.go +++ b/agent/structs/connect_ca.go @@ -8,12 +8,11 @@ import ( "reflect" "time" - "github.com/hashicorp/consul/lib/stringslice" - "github.com/mitchellh/mapstructure" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/lib" + "github.com/hashicorp/consul/lib/stringslice" ) const ( @@ -217,11 +216,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. diff --git a/agent/structs/connect_proxy_config.go b/agent/structs/connect_proxy_config.go index d84953e1b0..3bd5276f82 100644 --- a/agent/structs/connect_proxy_config.go +++ b/agent/structs/connect_proxy_config.go @@ -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/errors.go b/agent/structs/errors.go index 9b62de648d..029f958ec4 100644 --- a/agent/structs/errors.go +++ b/agent/structs/errors.go @@ -23,7 +23,6 @@ const ( 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" errSamenessGroupNotFound = "Sameness Group not found" errSamenessGroupMustBeDefaultForFailover = "Sameness Group must have DefaultForFailover set to true in order to use this endpoint" ) @@ -42,7 +41,6 @@ var ( 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) ErrSamenessGroupNotFound = errors.New(errSamenessGroupNotFound) ErrSamenessGroupMustBeDefaultForFailover = errors.New(errSamenessGroupMustBeDefaultForFailover) ) @@ -63,10 +61,6 @@ func IsErrRPCRateExceeded(err error) bool { return err != nil && strings.Contains(err.Error(), errRPCRateExceeded) } -func IsErrUsingV2CatalogExperiment(err error) bool { - return err != nil && strings.Contains(err.Error(), errUsingV2CatalogExperiment) -} - func IsErrSamenessGroupNotFound(err error) bool { return err != nil && strings.Contains(err.Error(), errSamenessGroupNotFound) } diff --git a/agent/testagent.go b/agent/testagent.go index a18dee1ead..5f0225c425 100644 --- a/agent/testagent.go +++ b/agent/testagent.go @@ -19,9 +19,10 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/stretchr/testify/require" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-uuid" - "github.com/stretchr/testify/require" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" @@ -105,7 +106,7 @@ type TestAgentOpts struct { // NewTestAgent returns a started agent with the given configuration. It fails // the test if the Agent could not be started. -func NewTestAgent(t *testing.T, hcl string, opts ...TestAgentOpts) *TestAgent { +func NewTestAgent(t testing.TB, hcl string, opts ...TestAgentOpts) *TestAgent { // This varargs approach is used so that we don't have to modify all of the `NewTestAgent()` calls // in order to introduce more optional arguments. require.LessOrEqual(t, len(opts), 1, "NewTestAgent cannot accept more than one opts argument") @@ -133,7 +134,7 @@ func NewTestAgentWithConfigFile(t *testing.T, hcl string, configFiles []string) // // The caller is responsible for calling Shutdown() to stop the agent and remove // temporary directories. -func StartTestAgent(t *testing.T, a TestAgent) *TestAgent { +func StartTestAgent(t testing.TB, a TestAgent) *TestAgent { t.Helper() retry.RunWith(retry.ThreeTimes(), t, func(r *retry.R) { r.Helper() @@ -315,22 +316,6 @@ func (a *TestAgent) waitForUp() error { } } - 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, diff --git a/agent/ui_endpoint_test.go b/agent/ui_endpoint_test.go index dd1c6d8134..2df3cb7849 100644 --- a/agent/ui_endpoint_test.go +++ b/agent/ui_endpoint_test.go @@ -18,10 +18,11 @@ import ( "testing" "time" - cleanhttp "github.com/hashicorp/go-cleanhttp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + cleanhttp "github.com/hashicorp/go-cleanhttp" + "github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" @@ -32,28 +33,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/ui_template_data.go b/agent/uiserver/ui_template_data.go index 34d3a453b0..726207b148 100644 --- a/agent/uiserver/ui_template_data.go +++ b/agent/uiserver/ui_template_data.go @@ -31,14 +31,6 @@ func uiTemplateDataFromConfig(cfg *config.RuntimeConfig) (map[string]interface{} uiCfg["metrics_provider_options"] = json.RawMessage(cfg.UIConfig.MetricsProviderOptionsJSON) } - v2CatalogEnabled := false - for _, experiment := range cfg.Experiments { - if experiment == "resource-apis" { - v2CatalogEnabled = true - break - } - } - d := map[string]interface{}{ "ContentPath": cfg.UIConfig.ContentPath, "ACLsEnabled": cfg.ACLsEnabled, @@ -47,7 +39,6 @@ func uiTemplateDataFromConfig(cfg *config.RuntimeConfig) (map[string]interface{} "LocalDatacenter": cfg.Datacenter, "PrimaryDatacenter": cfg.PrimaryDatacenter, "PeeringEnabled": cfg.PeeringEnabled, - "V2CatalogEnabled": v2CatalogEnabled, } // Also inject additional provider scripts if needed, otherwise strip the diff --git a/agent/uiserver/uiserver_test.go b/agent/uiserver/uiserver_test.go index d86baf1f48..c1e21ce745 100644 --- a/agent/uiserver/uiserver_test.go +++ b/agent/uiserver/uiserver_test.go @@ -13,10 +13,11 @@ import ( "strings" "testing" - "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" "golang.org/x/net/html" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/sdk/testutil" ) @@ -51,8 +52,7 @@ func TestUIServerIndex(t *testing.T) { "metrics_provider": "", "metrics_proxy_enabled": false, "dashboard_url_templates": null - }, - "V2CatalogEnabled": false + } }`, }, { @@ -91,8 +91,7 @@ func TestUIServerIndex(t *testing.T) { }, "metrics_proxy_enabled": false, "dashboard_url_templates": null - }, - "V2CatalogEnabled": false + } }`, }, { @@ -113,8 +112,7 @@ func TestUIServerIndex(t *testing.T) { "metrics_provider": "", "metrics_proxy_enabled": false, "dashboard_url_templates": null - }, - "V2CatalogEnabled": false + } }`, }, { @@ -135,30 +133,7 @@ func TestUIServerIndex(t *testing.T) { "metrics_provider": "", "metrics_proxy_enabled": false, "dashboard_url_templates": null - }, - "V2CatalogEnabled": false - }`, - }, - { - name: "v2 catalog enabled", - cfg: basicUIEnabledConfig(withV2CatalogEnabled()), - path: "/", - wantStatus: http.StatusOK, - wantContains: []string{"