From 2ea94a80ec530325741bedede0fd36ab27fe2e5c Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Wed, 8 Dec 2021 09:01:29 -0700
Subject: [PATCH 001/225] chore: created an issue template for Consul docs day
---
.github/ISSUE_TEMPLATE/docs_day.md | 58 ++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/docs_day.md
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
new file mode 100644
index 000000000..a5e01b324
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/docs_day.md
@@ -0,0 +1,58 @@
+---
+name: Consul docs day task
+about: This is a HashiCorp internal documentation task for the purpose of the Consul docs day event.
+labels: ['consul', 'placeholder']
+assignees:
+ - karl-cardenas-coding
+ - jkirschner-hashicorp
+ - trujillo-adam
+---
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this Consul docs event task request!
+ - type: dropdown
+ id: Category
+ attributes:
+ label: Category
+ description: What category is this task for?
+ options:
+ - Add/Improve Examples
+ - Structural Improvements and Cleanup
+ - Visual Aids
+ validations:
+ required: true
+ - type: input
+ id: Short Name
+ attributes:
+ label: Short Name
+ description: Please provide a short name for this task.
+ placeholder: ex. PKI Overview
+ validations:
+ required: true
+ - type: textarea
+ id: Description
+ attributes:
+ label: Description
+ description: Please provide details about the task?
+ placeholder: Tell us what you see!
+ validations:
+ required: true
+
+ - type: textarea
+ id: link
+ attributes:
+ label: Documentation page link
+ description: Please provide a link to the documentation page (if applicable)
+ placeholder: ex: https://www.consul.io/docs/connect/gateways#gateways
+ validations:
+ required: true
+
+ - type: textarea
+ id: logs
+ attributes:
+ label: Relevant log output
+ description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
+ render: shell
\ No newline at end of file
From db5f4eaadc9f2b91302623ac040d18f4e038d426 Mon Sep 17 00:00:00 2001
From: Marco Molteni
Date: Wed, 8 Dec 2021 20:16:36 +0100
Subject: [PATCH 002/225] cli: consul tls: create private keys with mode 0600
This applies to
consul tls ca create
consul tls cert create -client
consul tls cert create -server
Closes: #11741
---
command/tls/ca/create/tls_ca_create.go | 2 +-
command/tls/ca/create/tls_ca_create_test.go | 9 +++++++++
command/tls/cert/create/tls_cert_create.go | 2 +-
command/tls/cert/create/tls_cert_create_test.go | 9 +++++++++
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/command/tls/ca/create/tls_ca_create.go b/command/tls/ca/create/tls_ca_create.go
index ceef70b37..810d452c4 100644
--- a/command/tls/ca/create/tls_ca_create.go
+++ b/command/tls/ca/create/tls_ca_create.go
@@ -83,7 +83,7 @@ func (c *cmd) Run(args []string) int {
}
c.UI.Output("==> Saved " + certFileName)
- if err := file.WriteAtomicWithPerms(pkFileName, []byte(pk), 0755, 0666); err != nil {
+ if err := file.WriteAtomicWithPerms(pkFileName, []byte(pk), 0755, 0600); err != nil {
c.UI.Error(err.Error())
return 1
}
diff --git a/command/tls/ca/create/tls_ca_create_test.go b/command/tls/ca/create/tls_ca_create_test.go
index 568958959..19c5fb965 100644
--- a/command/tls/ca/create/tls_ca_create_test.go
+++ b/command/tls/ca/create/tls_ca_create_test.go
@@ -3,6 +3,7 @@ package create
import (
"crypto"
"crypto/x509"
+ "io/fs"
"io/ioutil"
"os"
"strings"
@@ -120,6 +121,14 @@ func expectFiles(t *testing.T, caPath, keyPath string) (*x509.Certificate, crypt
require.FileExists(t, caPath)
require.FileExists(t, keyPath)
+ fi, err := os.Stat(keyPath)
+ if err != nil {
+ t.Fatal("should not happen", err)
+ }
+ if want, have := fs.FileMode(0600), fi.Mode().Perm(); want != have {
+ t.Fatalf("private key file %s: permissions: want: %o; have: %o", keyPath, want, have)
+ }
+
caData, err := ioutil.ReadFile(caPath)
require.NoError(t, err)
keyData, err := ioutil.ReadFile(keyPath)
diff --git a/command/tls/cert/create/tls_cert_create.go b/command/tls/cert/create/tls_cert_create.go
index 6281ca3ae..b1cdaa131 100644
--- a/command/tls/cert/create/tls_cert_create.go
+++ b/command/tls/cert/create/tls_cert_create.go
@@ -196,7 +196,7 @@ func (c *cmd) Run(args []string) int {
}
c.UI.Output("==> Saved " + certFileName)
- if err := file.WriteAtomicWithPerms(pkFileName, []byte(priv), 0755, 0666); err != nil {
+ if err := file.WriteAtomicWithPerms(pkFileName, []byte(priv), 0755, 0600); err != nil {
c.UI.Error(err.Error())
return 1
}
diff --git a/command/tls/cert/create/tls_cert_create_test.go b/command/tls/cert/create/tls_cert_create_test.go
index 306eed8df..78f75eb11 100644
--- a/command/tls/cert/create/tls_cert_create_test.go
+++ b/command/tls/cert/create/tls_cert_create_test.go
@@ -3,6 +3,7 @@ package create
import (
"crypto"
"crypto/x509"
+ "io/fs"
"io/ioutil"
"net"
"os"
@@ -242,6 +243,14 @@ func expectFiles(t *testing.T, certPath, keyPath string) (*x509.Certificate, cry
require.FileExists(t, certPath)
require.FileExists(t, keyPath)
+ fi, err := os.Stat(keyPath)
+ if err != nil {
+ t.Fatal("should not happen", err)
+ }
+ if want, have := fs.FileMode(0600), fi.Mode().Perm(); want != have {
+ t.Fatalf("private key file %s: permissions: want: %o; have: %o", keyPath, want, have)
+ }
+
certData, err := ioutil.ReadFile(certPath)
require.NoError(t, err)
keyData, err := ioutil.ReadFile(keyPath)
From 74e92316dea8f062c37d32379d7e7a02796bb8d8 Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Thu, 9 Dec 2021 18:57:22 -0500
Subject: [PATCH 003/225] testing: remove old config.Build version
DefaultConfig already sets the version to version.Version, so by removing this
our tests will run with the version that matches the code.
---
agent/consul/server_test.go | 2 --
agent/consul/system_metadata_test.go | 23 +++++++++++++----------
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go
index d608b8fa0..da24f3220 100644
--- a/agent/consul/server_test.go
+++ b/agent/consul/server_test.go
@@ -164,8 +164,6 @@ func testServerConfig(t *testing.T) (string, *Config) {
config.ServerHealthInterval = 50 * time.Millisecond
config.AutopilotInterval = 100 * time.Millisecond
- config.Build = "1.7.2"
-
config.CoordinateUpdatePeriod = 100 * time.Millisecond
config.LeaveDrainTime = 1 * time.Millisecond
diff --git a/agent/consul/system_metadata_test.go b/agent/consul/system_metadata_test.go
index 30f57defd..61f62c8d1 100644
--- a/agent/consul/system_metadata_test.go
+++ b/agent/consul/system_metadata_test.go
@@ -4,9 +4,10 @@ import (
"os"
"testing"
+ "github.com/stretchr/testify/require"
+
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/testrpc"
- "github.com/stretchr/testify/require"
)
func TestLeader_SystemMetadata_CRUD(t *testing.T) {
@@ -32,10 +33,10 @@ func TestLeader_SystemMetadata_CRUD(t *testing.T) {
state := srv.fsm.State()
- // Initially has no entries
+ // Initially has one entry for virtual-ips feature flag
_, entries, err := state.SystemMetadataList(nil)
require.NoError(t, err)
- require.Len(t, entries, 0)
+ require.Len(t, entries, 1)
// Create 3
require.NoError(t, srv.setSystemMetadataKey("key1", "val1"))
@@ -52,12 +53,13 @@ func TestLeader_SystemMetadata_CRUD(t *testing.T) {
_, entries, err = state.SystemMetadataList(nil)
require.NoError(t, err)
- require.Len(t, entries, 3)
+ require.Len(t, entries, 4)
require.Equal(t, map[string]string{
- "key1": "val1",
- "key2": "val2",
- "key3": "",
+ structs.SystemMetadataVirtualIPsEnabled: "true",
+ "key1": "val1",
+ "key2": "val2",
+ "key3": "",
}, mapify(entries))
// Update one and delete one.
@@ -66,10 +68,11 @@ func TestLeader_SystemMetadata_CRUD(t *testing.T) {
_, entries, err = state.SystemMetadataList(nil)
require.NoError(t, err)
- require.Len(t, entries, 2)
+ require.Len(t, entries, 3)
require.Equal(t, map[string]string{
- "key2": "val2",
- "key3": "val3",
+ structs.SystemMetadataVirtualIPsEnabled: "true",
+ "key2": "val2",
+ "key3": "val3",
}, mapify(entries))
}
From 6444d1d4b3aedb3582eb623b65b7544ed2c0975f Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Thu, 9 Dec 2021 19:08:40 -0500
Subject: [PATCH 004/225] testing: Deprecate functions for creating a server.
These helper functions actually end up hiding important setup details
that should be visible from the test case. We already have a convenient
way of setting this config when calling newTestServerWithConfig.
---
agent/consul/autopilot_test.go | 9 ++--
agent/consul/intention_endpoint_test.go | 2 +-
agent/consul/internal_endpoint_test.go | 2 +-
agent/consul/server_test.go | 60 ++++++++++---------------
4 files changed, 31 insertions(+), 42 deletions(-)
diff --git a/agent/consul/autopilot_test.go b/agent/consul/autopilot_test.go
index 8b2632411..1935fc5e8 100644
--- a/agent/consul/autopilot_test.go
+++ b/agent/consul/autopilot_test.go
@@ -6,12 +6,13 @@ import (
"testing"
"time"
- "github.com/hashicorp/consul/agent/structs"
- "github.com/hashicorp/consul/sdk/testutil/retry"
- "github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/raft"
"github.com/hashicorp/serf/serf"
"github.com/stretchr/testify/require"
+
+ "github.com/hashicorp/consul/agent/structs"
+ "github.com/hashicorp/consul/sdk/testutil/retry"
+ "github.com/hashicorp/consul/testrpc"
)
func TestAutopilot_IdempotentShutdown(t *testing.T) {
@@ -19,7 +20,7 @@ func TestAutopilot_IdempotentShutdown(t *testing.T) {
t.Skip("too slow for testing.Short")
}
- dir1, s1 := testServerWithConfig(t, nil)
+ dir1, s1 := testServerWithConfig(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
retry.Run(t, func(r *retry.R) { r.Check(waitForLeader(s1)) })
diff --git a/agent/consul/intention_endpoint_test.go b/agent/consul/intention_endpoint_test.go
index ec3941348..ec8349f82 100644
--- a/agent/consul/intention_endpoint_test.go
+++ b/agent/consul/intention_endpoint_test.go
@@ -1599,7 +1599,7 @@ func TestIntentionList_acl(t *testing.T) {
t.Parallel()
- dir1, s1 := testServerWithConfig(t, testServerACLConfig(nil))
+ dir1, s1 := testServerWithConfig(t, testServerACLConfig)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
diff --git a/agent/consul/internal_endpoint_test.go b/agent/consul/internal_endpoint_test.go
index f9105304f..7a354e7b5 100644
--- a/agent/consul/internal_endpoint_test.go
+++ b/agent/consul/internal_endpoint_test.go
@@ -1784,7 +1784,7 @@ func TestInternal_GatewayIntentions_aclDeny(t *testing.T) {
t.Skip("too slow for testing.Short")
}
- dir1, s1 := testServerWithConfig(t, testServerACLConfig(nil))
+ dir1, s1 := testServerWithConfig(t, testServerACLConfig)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
codec := rpcClient(t, s1)
diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go
index da24f3220..0c7b84223 100644
--- a/agent/consul/server_test.go
+++ b/agent/consul/server_test.go
@@ -66,21 +66,12 @@ func testTLSCertificates(serverName string) (cert string, key string, cacert str
return cert, privateKey, ca, nil
}
-// testServerACLConfig wraps another arbitrary Config altering callback
-// to setup some common ACL configurations. A new callback func will
-// be returned that has the original callback invoked after setting
-// up all of the ACL configurations (so they can still be overridden)
-func testServerACLConfig(cb func(*Config)) func(*Config) {
- return func(c *Config) {
- c.PrimaryDatacenter = "dc1"
- c.ACLsEnabled = true
- c.ACLInitialManagementToken = TestDefaultMasterToken
- c.ACLResolverSettings.ACLDefaultPolicy = "deny"
-
- if cb != nil {
- cb(c)
- }
- }
+// testServerACLConfig setup some common ACL configurations.
+func testServerACLConfig(c *Config) {
+ c.PrimaryDatacenter = "dc1"
+ c.ACLsEnabled = true
+ c.ACLInitialManagementToken = TestDefaultMasterToken
+ c.ACLResolverSettings.ACLDefaultPolicy = "deny"
}
func configureTLS(config *Config) {
@@ -185,14 +176,12 @@ func testServerConfig(t *testing.T) (string, *Config) {
return dir, config
}
+// Deprecated: use testServerWithConfig instead. It does the same thing and more.
func testServer(t *testing.T) (string, *Server) {
- return testServerWithConfig(t, func(c *Config) {
- c.Datacenter = "dc1"
- c.PrimaryDatacenter = "dc1"
- c.Bootstrap = true
- })
+ return testServerWithConfig(t)
}
+// Deprecated: use testServerWithConfig
func testServerDC(t *testing.T, dc string) (string, *Server) {
return testServerWithConfig(t, func(c *Config) {
c.Datacenter = dc
@@ -200,6 +189,7 @@ func testServerDC(t *testing.T, dc string) (string, *Server) {
})
}
+// Deprecated: use testServerWithConfig
func testServerDCBootstrap(t *testing.T, dc string, bootstrap bool) (string, *Server) {
return testServerWithConfig(t, func(c *Config) {
c.Datacenter = dc
@@ -208,6 +198,7 @@ func testServerDCBootstrap(t *testing.T, dc string, bootstrap bool) (string, *Se
})
}
+// Deprecated: use testServerWithConfig
func testServerDCExpect(t *testing.T, dc string, expect int) (string, *Server) {
return testServerWithConfig(t, func(c *Config) {
c.Datacenter = dc
@@ -216,16 +207,7 @@ func testServerDCExpect(t *testing.T, dc string, expect int) (string, *Server) {
})
}
-func testServerDCExpectNonVoter(t *testing.T, dc string, expect int) (string, *Server) {
- return testServerWithConfig(t, func(c *Config) {
- c.Datacenter = dc
- c.Bootstrap = false
- c.BootstrapExpect = expect
- c.ReadReplica = true
- })
-}
-
-func testServerWithConfig(t *testing.T, cb func(*Config)) (string, *Server) {
+func testServerWithConfig(t *testing.T, configOpts ...func(*Config)) (string, *Server) {
var dir string
var srv *Server
@@ -233,8 +215,8 @@ func testServerWithConfig(t *testing.T, cb func(*Config)) (string, *Server) {
retry.RunWith(retry.ThreeTimes(), t, func(r *retry.R) {
var config *Config
dir, config = testServerConfig(t)
- if cb != nil {
- cb(config)
+ for _, fn := range configOpts {
+ fn(config)
}
// Apply config to copied fields because many tests only set the old
@@ -255,8 +237,11 @@ func testServerWithConfig(t *testing.T, cb func(*Config)) (string, *Server) {
// cb is a function that can alter the test servers configuration prior to the server starting.
func testACLServerWithConfig(t *testing.T, cb func(*Config), initReplicationToken bool) (string, *Server, rpc.ClientCodec) {
- dir, srv := testServerWithConfig(t, testServerACLConfig(cb))
- t.Cleanup(func() { srv.Shutdown() })
+ opts := []func(*Config){testServerACLConfig}
+ if cb != nil {
+ opts = append(opts, cb)
+ }
+ dir, srv := testServerWithConfig(t, opts...)
if initReplicationToken {
// setup some tokens here so we get less warnings in the logs
@@ -264,7 +249,6 @@ func testACLServerWithConfig(t *testing.T, cb func(*Config), initReplicationToke
}
codec := rpcClient(t, srv)
- t.Cleanup(func() { codec.Close() })
return dir, srv, codec
}
@@ -1282,7 +1266,11 @@ func TestServer_Expect_NonVoters(t *testing.T) {
}
t.Parallel()
- dir1, s1 := testServerDCExpectNonVoter(t, "dc1", 2)
+ dir1, s1 := testServerWithConfig(t, func(c *Config) {
+ c.Bootstrap = false
+ c.BootstrapExpect = 2
+ c.ReadReplica = true
+ })
defer os.RemoveAll(dir1)
defer s1.Shutdown()
From 8b8c79ea7262d25e669db926d25aefe6a6f4238b Mon Sep 17 00:00:00 2001
From: Jared Kirschner
Date: Mon, 13 Dec 2021 08:29:54 -0800
Subject: [PATCH 005/225] http: improve UI not enabled response message
Response now clearly indicates:
- the UI is disabled
- how to enable the UI
---
.changelog/11820.txt | 3 +++
agent/http.go | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
create mode 100644 .changelog/11820.txt
diff --git a/.changelog/11820.txt b/.changelog/11820.txt
new file mode 100644
index 000000000..3a19f0a40
--- /dev/null
+++ b/.changelog/11820.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+http: when a user attempts to access the UI but can't because it's disabled, explain this and how to fix it
+```
\ No newline at end of file
diff --git a/agent/http.go b/agent/http.go
index a1d8461d0..f1604a9cc 100644
--- a/agent/http.go
+++ b/agent/http.go
@@ -593,7 +593,7 @@ func (s *HTTPHandlers) Index(resp http.ResponseWriter, req *http.Request) {
// Give them something helpful if there's no UI so they at least know
// what this server is.
if !s.IsUIEnabled() {
- fmt.Fprint(resp, "Consul Agent")
+ fmt.Fprint(resp, "Consul Agent: UI disabled. To enable, set ui_config.enabled=true in the agent configuration and restart.")
return
}
From 478e9882060e21db02768a2affb9c823fed5d62e Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Wed, 15 Dec 2021 13:11:52 -0800
Subject: [PATCH 006/225] clarify mesh gateway docs use cases; include admin
partition flow
---
.../content/docs/connect/gateways/index.mdx | 26 +--
.../docs/connect/gateways/ingress-gateway.mdx | 7 +-
.../connect/gateways/mesh-gateway/index.mdx | 215 ------------------
...service-to-service-traffic-datacenters.mdx | 205 +++++++++++++++++
.../service-to-service-traffic-partitions.mdx | 173 ++++++++++++++
website/data/docs-nav-data.json | 18 +-
6 files changed, 404 insertions(+), 240 deletions(-)
delete mode 100644 website/content/docs/connect/gateways/mesh-gateway/index.mdx
create mode 100644 website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
create mode 100644 website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
diff --git a/website/content/docs/connect/gateways/index.mdx b/website/content/docs/connect/gateways/index.mdx
index 31fdb4f10..dafdcb092 100644
--- a/website/content/docs/connect/gateways/index.mdx
+++ b/website/content/docs/connect/gateways/index.mdx
@@ -7,31 +7,29 @@ description: >-
# Gateways
-Gateways provide connectivity into, out of, and between Consul service meshes.
+This topic provides an overview of the gateway features shipped with Consul. Gateways provide connectivity into, out of, and between Consul service meshes. You can configure the following types of gateways:
-- Enable service-to-service traffic between Consul datacenters with [mesh gateways](#mesh-gateways).
-- Accept traffic from outside the Consul service mesh to services in the mesh with [ingress gateways](#ingress-gateways).
-- Route traffic from services in the Consul service mesh to external services with [terminating gateways](#terminating-gateways).
+- [Mesh gateways](#mesh-gateways) enable service-to-service traffic between Consul datacenters or between Consul admin partitions. They also enable datacenters to be federated across wide area networks.
+- [Ingress gateways](#ingress-gateways) enable services to accept traffic from outside the Consul service mesh.
+- [Terminating gateways](#terminating-gateways) enable you to route traffic from services in the Consul service mesh to external services.
## Mesh Gateways
-> **1.6.0+:** This feature is available in Consul versions 1.6.0 and newer.
-Mesh gateways enable routing of service mesh traffic between different Consul datacenters. Those datacenters can reside
+Mesh gateways enable service mesh traffic to be routed between different Consul datacenters and admin partitions. The datacenters or partitions can reside
in different clouds or runtime environments where general interconnectivity between all services in all datacenters
-isn't feasible. One scenario where this is useful is when connecting networks with overlapping IP address space.
+isn't feasible.
-These gateways operate by sniffing the SNI header out of the mTLS connection and then routing the connection to the
-appropriate destination based on the server name requested. The data within the mTLS session is not decrypted by
-the Gateway.
+They operate by sniffing and extracting the server name indication (SNI) header from the service mesh session and routing the connection to the appropriate destination based on the server name requested. The gateway does not decrypt the data within the mTLS session.
-As of Consul 1.8.0, mesh gateways can also forward gossip and RPC traffic between Consul servers.
-This is enabled by [WAN federation via mesh gateways](/docs/connect/gateways/wan-federation-via-mesh-gateways).
+Mesh gateways enable the following scenarios:
-For more information about mesh gateways, review the [complete documentation](/docs/connect/gateways/mesh-gateway)
-and the [mesh gateway tutorial](https://learn.hashicorp.com/tutorials/consul/service-mesh-gateways).
+* **Federate multiple datacenters across a WAN**. Since Consul 1.8.0, mesh gateways can forward gossip and RPC traffic between Consul servers. See [WAN federation via mesh gateways](/docs/connect/gateways/wan-federation-via-mesh-gateways) for additional information.
+* **Service-to-service communication across datacenters**. Refer to [Enabling Service-to-service Traffic Accross Datacenters](/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters) for additional information.
+* **Service-to-service communication across admin partitions**. Since Consul 1.11.0, you can create administrative boundaries for single Consul deployements called "admin partitions". You can use mesh gateways to facilitate cross-partition communication. Refer to [Enabling Service-to-service Traffic Accross Admin Partitions](/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions) for additional information.
-![Mesh Gateway Architecture](/img/mesh-gateways.png)
+-> **Mesh gateway tutorial**: Follow the [mesh gateway tutorial](https://learn.hashicorp.com/tutorials/consul/service-mesh-gateways) to learn concepts associated with mesh gateways.
## Ingress Gateways
diff --git a/website/content/docs/connect/gateways/ingress-gateway.mdx b/website/content/docs/connect/gateways/ingress-gateway.mdx
index ec969d9a6..50997b563 100644
--- a/website/content/docs/connect/gateways/ingress-gateway.mdx
+++ b/website/content/docs/connect/gateways/ingress-gateway.mdx
@@ -1,10 +1,9 @@
---
layout: docs
-page_title: External <> Internal Services - Ingress Gateways
+page_title: Using Ingress Gateways to Connect External Traffic to Internal Services
description: >-
- An ingress gateway enables ingress traffic from services outside the Consul
- service mesh to services inside the Consul service mesh. This section details
- how to use Envoy and describes how you can plug in a gateway of your choice.
+ This topic describes how ingress gateways enable traffic from external services to reach services inside the Consul service mesh.
+ It provides guidance on how to use Envoy and how to plug into your preferred gateway.
---
# Ingress Gateways
diff --git a/website/content/docs/connect/gateways/mesh-gateway/index.mdx b/website/content/docs/connect/gateways/mesh-gateway/index.mdx
deleted file mode 100644
index 533821c5d..000000000
--- a/website/content/docs/connect/gateways/mesh-gateway/index.mdx
+++ /dev/null
@@ -1,215 +0,0 @@
----
-layout: docs
-page_title: Connect Datacenters - Mesh Gateways
-description: >-
- A Mesh Gateway enables better routing of a Connect service's data to upstreams
- in other datacenters. This section details how to use Envoy and describes how
- you can plug in a gateway of your choice.
----
-
-# Mesh Gateways
-
--> **1.6.0+:** This feature is available in Consul versions 1.6.0 and newer.
-
-Mesh gateways enable routing of Connect traffic between different Consul datacenters. Those datacenters
-can reside in different clouds or runtime environments where general interconnectivity between all services
-in all datacenters isn't feasible. These gateways operate by sniffing the SNI header out of the Connect session
-and then route the connection to the appropriate destination based on the server name requested. The data
-within the mTLS session is not decrypted by the Gateway.
-
-![Mesh Gateway Architecture](/img/mesh-gateways.png)
-
-For a complete example of how to connect services across datacenters,
-review the [mesh gateway tutorial](https://learn.hashicorp.com/tutorials/consul/service-mesh-gateways).
-
-## Prerequisites
-
-Each mesh gateway needs three things:
-
-1. A local Consul agent to manage its configuration.
-2. General network connectivity to all services within its local Consul datacenter.
-3. General network connectivity to all mesh gateways within remote Consul datacenters.
-
-Mesh gateways also require that your Consul datacenters are configured correctly:
-
-- Consul version 1.6.0 or newer is required.
-- Consul [Connect](/docs/agent/options#connect) must be enabled in both datacenters.
-- Each of your [datacenters](/docs/agent/options#datacenter) must have a unique name.
-- Your datacenters must be [WAN joined](https://learn.hashicorp.com/tutorials/consul/federarion-gossip-wan).
-- The [primary datacenter](/docs/agent/options#primary_datacenter) must be set to the same value in both datacenters. This specifies which datacenter is the authority for Connect certificates and is required for services in all datacenters to establish mutual TLS with each other.
-- [gRPC](/docs/agent/options#grpc_port) must be enabled.
-- If you want to [enable gateways globally](/docs/connect/mesh-gateway#enabling-gateways-globally) you must enable [centralized configuration](/docs/agent/options#enable_central_service_config).
-
-Currently, Envoy is the only proxy with mesh gateway capabilities in Consul.
-
-- Mesh gateway proxies receive their configuration through Consul, which
- automatically generates it based on the proxy's registration. Currently Consul
- can only translate mesh gateway registration information into Envoy
- configuration, therefore the proxies acting as mesh gateways must be Envoy.
-
-- Sidecar proxies that send traffic to an upstream service through a gateway
- need to know the location of that gateway. They discover the gateway based on
- their sidecar proxy registrations. Consul can only translate the gateway
- registration information into Envoy configuration, so any sidecars that send
- upstream traffic through a gateway must be Envoy.
-
-Sidecar proxies that don't send upstream traffic through a gateway aren't
-affected when you deploy gateways. If you are using Consul's built-in proxy as a
-Connect sidecar it will continue to work for intra-datacenter traffic and will
-receive incoming traffic even if that traffic has passed through a gateway.
-
-## Modes of Operation
-
-Each upstream of a Connect proxy can be configured to be routed through a mesh gateway. Depending on
-your network, the proxy's connection to the gateway can happen in one of the following modes
-illustrated in the diagram above:
-
-- `local` - In this mode the Connect proxy makes its outbound connection to a gateway running in the
- same datacenter. That gateway is then responsible for ensuring the data gets forwarded along to
- gateways in the destination datacenter. This is the mode of operation depicted in the diagram at
- the beginning of the page.
-
-- `remote` - In this mode the Connect proxy makes its outbound connection to a gateway running in the
- destination datacenter. That gateway will then forward the data to the final destination service.
-
-- `none` - In this mode, no gateway is used and a Connect proxy makes its outbound connections directly
- to the destination services.
-
-## Mesh Gateway Configuration
-
-Mesh gateways are defined similarly to other services registered with Consul, with two exceptions.
-The first is that the [service kind](/api/agent/service#kind) must be "mesh-gateway". Second,
-the mesh gateway service definition may contain a `Proxy.Config` entry, just like a
-Connect proxy service, to define opaque configuration parameters useful for the actual proxy software.
-For Envoy there are some supported [gateway options](/docs/connect/proxies/envoy#gateway-options) as well as
-[escape-hatch overrides](/docs/connect/proxies/envoy#escape-hatch-overrides).
-
--> **Note:** If ACLs are enabled, a token granting `service:write` for the gateway's service name
-and `service:read` for all services in the datacenter must be added to the gateway's service definition.
-These permissions authorize the token to route communications for other Connect services but does not
-allow decrypting any of their communications.
-
-## Connect Proxy Configuration
-
-Configuring a Connect Proxy to use gateways is as simple as setting its mode of operation. This can be done
-in several different places allowing for global to more fine grained control. If the gateway mode is configured
-in multiple locations the order of precedence is as follows
-
-1. Upstream Definition
-2. Service Instance Definition
-3. Centralized `service-defaults` configuration entry
-4. Centralized `proxy-defaults` configuration entry.
-
-### Enabling Gateways Globally
-
-The following `proxy-defaults` configuration will enable gateways for all Connect services in the `local` mode.
-
-```hcl
-Kind = "proxy-defaults"
-Name = "global"
-MeshGateway {
- Mode = "local"
-}
-```
-
-### Enabling Gateways Per-Service
-
-The following `service-defaults` configuration will enable gateways for all Connect services with the name "web".
-
-```hcl
-Kind = "service-defaults"
-Name = "web"
-MeshGateway {
- Mode = "local"
-}
-```
-
-### Enabling Gateways for a Service Instance
-
-The following [Proxy Service Registration](/docs/connect/registration/service-registration)
-definition will enable gateways for the service instance in the `remote` mode.
-
-```hcl
-service {
- name = "web-sidecar-proxy"
- kind = "connect-proxy"
- port = 8181
- proxy {
- destination_service_name = "web"
- mesh_gateway {
- mode = "remote"
- }
- upstreams = [
- {
- destination_name = "api"
- datacenter = "secondary"
- local_bind_port = 10000
- }
- ]
- }
-}
-```
-
-Or alternatively inline with the service definition:
-
-```hcl
-service {
- name = "web"
- port = 8181
- connect {
- sidecar_service {
- proxy {
- mesh_gateway {
- mode = "remote"
- }
- upstreams = [
- {
- destination_name = "api"
- datacenter = "secondary"
- local_bind_port = 10000
- }
- ]
- }
- }
- }
-}
-```
-
-### Enabling Gateways for a Proxy Upstream
-
-The following service definition will enable gateways in the `local` mode for one upstream, the `remote` mode
-for a second upstream and will disable gateways for a third upstream.
-
-```hcl
-service {
- name = "web-sidecar-proxy"
- kind = "connect-proxy"
- port = 8181
- proxy {
- destination_service_name = "web"
- upstreams = [
- {
- destination_name = "api"
- local_bind_port = 10000
- mesh_gateway {
- mode = "remote"
- }
- },
- {
- destination_name = "db"
- local_bind_port = 10001
- mesh_gateway {
- mode = "local"
- }
- },
- {
- destination_name = "logging"
- local_bind_port = 10002
- mesh_gateway {
- mode = "none"
- }
- },
- ]
- }
-}
-```
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
new file mode 100644
index 000000000..e6ce374eb
--- /dev/null
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
@@ -0,0 +1,205 @@
+---
+layout: docs
+page_title: Service-to-service Traffic Across Datacenters
+description: >-
+ This topic describes how to configure mesh gateways to route a service's data to upstreams
+ in other datacenters. It describes how to use Envoy and how you can integrate with your preferred gateway.
+---
+
+# Service-to-service Traffic Across Datacenters
+
+-> **1.6.0+:** This feature is available in Consul versions 1.6.0 and newer.
+
+Mesh gateways enable service mesh traffic to be routed between different Consul datacenters.
+Datacenters can reside in different clouds or runtime environments where general interconnectivity between all services
+in all datacenters isn't feasible.
+
+Mesh gateways operate by sniffing and extracting the server name indication (SNI) header from the service mesh session and routing the connection to the appropriate destination based on the server name requested. The gateway does not decrypt the data within the mTLS session.
+
+The following diagram describes the architecture for using mesh gateways for cross-datacenter communication:
+
+![Mesh Gateway Architecture](/img/mesh-gateways.png)
+
+-> **Mesh Gateway Tutorial**: Follow the [mesh gateway tutorial](https://learn.hashicorp.com/tutorials/consul/service-mesh-gateways) to learn important concepts associated with using mesh gateways for connecting services across datacenters.
+
+## Prerequisites
+
+Ensure that your Consul environment meets the following requirements.
+
+### Consul
+
+* Consul version 1.6.0 or newer.
+* A local Consul agent is required to manage its configuration.
+* Consul [Connect](/docs/agent/options#connect) must be enabled in both datacenters.
+* Each [datacenter](/docs/agent/options#datacenter) must have a unique name.
+* Each datacenters must be [WAN joined](https://learn.hashicorp.com/tutorials/consul/federarion-gossip-wan).
+* The [primary datacenter](/docs/agent/options#primary_datacenter) must be set to the same value in both datacenters. This specifies which datacenter is the authority for Connect certificates and is required for services in all datacenters to establish mutual TLS with each other.
+* [gRPC](/docs/agent/options#grpc_port) must be enabled.
+* If you want to [enable gateways globally](/docs/connect/mesh-gateway#enabling-gateways-globally) you must enable [centralized configuration](/docs/agent/options#enable_central_service_config).
+
+### Network
+
+* General network connectivity to all services within its local Consul datacenter.
+* General network connectivity to all mesh gateways within remote Consul datacenters.
+
+### Proxy
+
+Envoy is the only proxy with mesh gateway capabilities in Consul.
+
+Mesh gateway proxies receive their configuration through Consul, which automatically generates it based on the proxy's registration.
+Consul can only translate mesh gateway registration information into Envoy configuration.
+
+Sidecar proxies that send traffic to an upstream service through a gateway need to know the location of that gateway. They discover the gateway based on their sidecar proxy registrations. Consul can only translate the gateway registration information into Envoy configuration.
+
+Sidecar proxies that do not send upstream traffic through a gateway are not affected when you deploy gateways. If you are using Consul's built-in proxy as a Connect sidecar it will continue to work for intra-datacenter traffic and will receive incoming traffic even if that traffic has passed through a gateway.
+
+## Configuration
+
+Configure the following settings to register the mesh gateway as a service in Consul.
+
+* Specify `mesh-gateway` in the `kind` field to register the gateway with Consul.
+* Define the `Proxy.Config` settings using opaque parameters compatible with your proxy, i.e., Envoy. For Envoy, refer to the [Gateway Options](/docs/connect/proxies/envoy#gateway-options) and [Escape-hatch Overrides](/docs/connect/proxies/envoy#escape-hatch-overrides) documentation for additional configuration information.
+* If ACLs are enabled, a token granting `service:write` for the gateway's service name and `service:read` for all services in the datacenter or partition must be added to the gateway's service definition. These permissions authorize the token to route communications for other Consul service mesh services, but does not allow decrypting any of their communications.
+
+### Modes
+
+Each upstream associated with a service mesh proxy can be configured so that it is routed through a mesh gateway.
+Depending on your network, the proxy's connection to the gateway can operate in one of the following modes (refer to the [mesh-architecture-diagram](#mesh-architecture-diagram)):
+
+* `none` - (Default) No gateway is used and a service mesh connect proxy makes its outbound connections directly
+ to the destination services.
+
+* `local` - The service mesh connect proxy makes an outbound connection to a gateway running in the
+ same datacenter. That gateway is responsible for ensuring that the data is forwarded to gateways in the destination datacenter.
+ Refer to the flow labeled `local` in the [mesh-architecture-diagram](#mesh-architecture-diagram).
+
+* `remote` - The service mesh proxy makes an outbound connection to a gateway running in the destination datacenter.
+ The gateway forwards the data to the final destination service.
+ Refer to the flow labeled `remote` in the [mesh-architecture-diagram](#mesh-architecture-diagram).
+
+### Connect Proxy Configuration
+
+Set the proxy to the preferred [mode](#modes) to configure the service mesh proxy. You can specify the mode globally or within child configurations to control proxy behaviors at a lower level. Consul recognizes the following order of precedence if the gateway mode is configured in multiple locations the order of precedence:
+
+1. Upstream definition (highest priority)
+2. Service instance definition
+3. Centralized `service-defaults` configuration entry
+4. Centralized `proxy-defaults` configuration entry
+
+## Example Configurations
+
+Use the following example configurations to help you understand some of the common scenarios.
+
+### Enabling Gateways Globally
+
+The following `proxy-defaults` configuration will enable gateways for all Connect services in the `local` mode.
+
+```hcl
+Kind = "proxy-defaults"
+Name = "global"
+MeshGateway {
+ Mode = "local"
+}
+```
+
+### Enabling Gateways Per-Service
+
+The following `service-defaults` configuration will enable gateways for all Connect services with the name "web".
+
+```hcl
+Kind = "service-defaults"
+Name = "web"
+MeshGateway {
+ Mode = "local"
+}
+```
+
+### Enabling Gateways for a Service Instance
+
+The following [Proxy Service Registration](/docs/connect/registration/service-registration)
+definition will enable gateways for the service instance in the `remote` mode.
+
+```hcl
+service {
+ name = "web-sidecar-proxy"
+ kind = "connect-proxy"
+ port = 8181
+ proxy {
+ destination_service_name = "web"
+ mesh_gateway {
+ mode = "remote"
+ }
+ upstreams = [
+ {
+ destination_name = "api"
+ datacenter = "secondary"
+ local_bind_port = 10000
+ }
+ ]
+ }
+}
+```
+
+Or alternatively inline with the service definition:
+
+```hcl
+service {
+ name = "web"
+ port = 8181
+ connect {
+ sidecar_service {
+ proxy {
+ mesh_gateway {
+ mode = "remote"
+ }
+ upstreams = [
+ {
+ destination_name = "api"
+ datacenter = "secondary"
+ local_bind_port = 10000
+ }
+ ]
+ }
+ }
+ }
+}
+```
+
+### Enabling Gateways for a Proxy Upstream
+
+The following service definition will enable gateways in the `local` mode for one upstream, the `remote` mode
+for a second upstream and will disable gateways for a third upstream.
+
+```hcl
+service {
+ name = "web-sidecar-proxy"
+ kind = "connect-proxy"
+ port = 8181
+ proxy {
+ destination_service_name = "web"
+ upstreams = [
+ {
+ destination_name = "api"
+ local_bind_port = 10000
+ mesh_gateway {
+ mode = "remote"
+ }
+ },
+ {
+ destination_name = "db"
+ local_bind_port = 10001
+ mesh_gateway {
+ mode = "local"
+ }
+ },
+ {
+ destination_name = "logging"
+ local_bind_port = 10002
+ mesh_gateway {
+ mode = "none"
+ }
+ },
+ ]
+ }
+}
+```
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
new file mode 100644
index 000000000..70a2e9c4c
--- /dev/null
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
@@ -0,0 +1,173 @@
+---
+layout: docs
+page_title: Service-to-service Traffic Across Partitions
+description: >-
+ This topic describes how to configure mesh gateways to route a service's data to upstreams
+ in other partitions. It describes how to use Envoy and how you can integrate with your preferred gateway.
+---
+
+# Service-to-service Traffic Across Partitions
+
+-> **Consul Enterprise 1.11.0+:** Admin partitions are supported in Consul Enterprise versions 1.11.0 and newer.
+
+Mesh gateways enable you to route service mesh traffic between different Consul [admin partitions](/docs/enteprise/admin-partitions).
+Partitions can reside in different clouds or runtime environments where general interconnectivity between all services
+in all partitions isn't feasible.
+
+Mesh gateways operate by sniffing and extracting the server name indication (SNI) header from the service mesh session and routing the connection to the appropriate destination based on the server name requested. The gateway does not decrypt the data within the mTLS session.
+
+## Prerequisites
+
+Ensure that your Consul environment meets the following requirements.
+
+### Consul
+
+* Consul Enterprise version 1.11.0 or newer.
+* A local Consul agent is required to manage its configuration.
+* Consul service mesh must be enabled in all partitions. Refer to the [`connect` documentation](/docs/agent/options#connect) for details.
+* Each partition must have a unique name. Refer to the [admin partitions documentation](/docs/enteprise/admin-partitions) for details.
+* If you want to [enable gateways globally](/docs/connect/mesh-gateway#enabling-gateways-globally) you must enable [centralized configuration](/docs/agent/options#enable_central_service_config).
+
+### Proxy
+
+Envoy is the only proxy with mesh gateway capabilities in Consul.
+
+Mesh gateway proxies receive their configuration through Consul, which automatically generates it based on the proxy's registration.
+Consul can only translate mesh gateway registration information into Envoy configuration.
+
+Sidecar proxies that send traffic to an upstream service through a gateway need to know the location of that gateway. They discover the gateway based on their sidecar proxy registrations. Consul can only translate the gateway registration information into Envoy configuration.
+
+Sidecar proxies that do not send upstream traffic through a gateway are not affected when you deploy gateways. If you are using Consul's built-in proxy as a Connect sidecar it will continue to work for intra-datacenter traffic and will receive incoming traffic even if that traffic has passed through a gateway.
+
+## Configuration
+
+Configure the following settings to register the mesh gateway as a service in Consul.
+
+* Specify `mesh-gateway` in the `kind` field to register the gateway with Consul.
+* Define the `Proxy.Config` settings using opaque parameters compatible with your proxy, i.e., Envoy. For Envoy, refer to the [Gateway Options](/docs/connect/proxies/envoy#gateway-options) and [Escape-hatch Overrides](/docs/connect/proxies/envoy#escape-hatch-overrides) documentation for additional configuration information.
+* Configure the `proxy.upstreams` parameters to route traffic to the correct service, namespace, and partition. Refer to the [`upstreams` documentation](/docs/connect/registration/service-registration#upstream-configuration-reference) for details.
+* Configure the `exported-services` configuration entry to enable Consul to export services contained in an admin partition to one or more additional partitions. Refer to the [Exported Services documentation](/docs/connect/config-entries/exported-services) for details.
+* If ACLs are enabled, a token granting `service:write` for the gateway's service name and `service:read` for all services in the datacenter or partition must be added to the gateway's service definition. These permissions authorize the token to route communications for other Consul service mesh services, but does not allow decrypting any of their communications.
+
+
+### Modes
+
+Each upstream associated with a service mesh proxy can be configured so that it is routed through a mesh gateway.
+Depending on your network, the proxy's connection to the gateway can operate in one of the following modes:
+
+* `none` - (Default) No gateway is used and a service mesh connect proxy makes its outbound connections directly
+ to the destination services.
+
+* `local` - The service mesh connect proxy makes an outbound connection to a gateway running in the same datacenter. The gateway at the outbound connection is responsible for ensuring that the data is forwarded to gateways in the destination partition.
+
+* `remote` - The service mesh connect proxy makes an outbound connection to a gateway running in the destination datacenter.
+ The gateway forwards the data to the final destination service.
+
+### Connect Proxy Configuration
+
+Set the proxy to the preferred [mode](#modes) to configure the service mesh proxy. You can specify the mode globally or within child configurations to control proxy behaviors at a lower level. Consul recognizes the following order of precedence if the gateway mode is configured in multiple locations the order of precedence:
+
+1. Upstream definition (highest priority)
+2. Service instance definition
+3. Centralized `service-defaults` configuration entry
+4. Centralized `proxy-defaults` configuration entry
+
+## Example Configurations
+
+Use the following example configurations to help you understand some of the common scenarios.
+
+### Enabling Gateways Globally
+
+The following `proxy-defaults` configuration will enable gateways for all Connect services in the `local` mode.
+
+```hcl
+Kind = "proxy-defaults"
+Name = "global"
+MeshGateway {
+ Mode = "local"
+}
+```
+
+### Enabling Gateways Per-Service
+
+The following `service-defaults` configuration will enable gateways for all Connect services with the name `web`.
+
+```hcl
+Kind = "service-defaults"
+Name = "web"
+MeshGateway {
+ Mode = "local"
+}
+```
+
+### Enabling Gateways for a Service Instance
+
+The following [Proxy Service Registration](/docs/connect/registration/service-registration)
+definition will enable gateways for `web` service instances in the `finance` partition.
+
+```hcl
+service {
+ name = "web-sidecar-proxy"
+ kind = "connect-proxy"
+ port = 8181
+ proxy {
+ destination_service_name = "web"
+ mesh_gateway {
+ mode = "local"
+ }
+ upstreams = [
+ {
+ destination_partition = "finance"
+ destination_namespace = "default"
+ destination_type = "service"
+ destination_name = "billing"
+ local_bind_port = 9090
+ }
+ ]
+ }
+}
+```
+
+### Enabling Gateways for a Proxy Upstream
+
+The following service definition will enable gateways in `local` mode for three different partitions. Note that each service exists in the same namepace, but are separated by admin partition.
+
+```hcl
+service {
+ name = "web-sidecar-proxy"
+ kind = "connect-proxy"
+ port = 8181
+ proxy {
+ destination_service_name = "web"
+ upstreams = [
+ {
+ destination_name = "api"
+ destination_namespace = "dev"
+ destination_partition = "api"
+ local_bind_port = 10000
+ mesh_gateway {
+ mode = "local"
+ }
+ },
+ {
+ destination_name = "db"
+ destination_namespace = "dev"
+ destination_partition = "db"
+ local_bind_port = 10001
+ mesh_gateway {
+ mode = "local"
+ }
+ },
+ {
+ destination_name = "logging"
+ destination_namespace = "dev"
+ destination_partition = "logging"
+ local_bind_port = 10002
+ mesh_gateway {
+ mode = "local"
+ }
+ },
+ ]
+ }
+}
+```
\ No newline at end of file
diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json
index 47f87740b..fcba21bbd 100644
--- a/website/data/docs-nav-data.json
+++ b/website/data/docs-nav-data.json
@@ -277,24 +277,28 @@
"path": "connect/gateways"
},
{
- "title": "Connect Datacenters - Mesh Gateways",
+ "title": "Mesh Gateways",
"routes": [
- {
- "title": "Overview",
- "path": "connect/gateways/mesh-gateway"
- },
{
"title": "WAN Federation",
"path": "connect/gateways/mesh-gateway/wan-federation-via-mesh-gateways"
+ },
+ {
+ "title": "Enabling Service-to-service Traffic Across Datacenters",
+ "path": "connect/gateways/mesh-gateway/service-to-service-traffic-datacenters"
+ },
+ {
+ "title": "Enabling Service-to-service Traffic Across Admin Partitions",
+ "path": "connect/gateways/mesh-gateway/service-to-service-traffic-partitions"
}
]
},
{
- "title": "External <> Internal Services - Ingress Gateways",
+ "title": "Ingress Gateways",
"path": "connect/gateways/ingress-gateway"
},
{
- "title": "Internal <> External Services - Terminating Gateways",
+ "title": "Terminating Gateways",
"path": "connect/gateways/terminating-gateway"
}
]
From 70757f617df649e13e33eadaebef56882d74f4a1 Mon Sep 17 00:00:00 2001
From: Scott Macfarlane
Date: Wed, 15 Dec 2021 13:17:16 -0800
Subject: [PATCH 007/225] Update ECR tag in CRT Builds
This updates the ECR tag to the correct naming convention.
Signed-off-by: Scott Macfarlane
---
.github/workflows/build.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 850f2b9b5..e4261c1d1 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -249,4 +249,4 @@ jobs:
arch: ${{matrix.arch}}
tags: |
docker.io/hashicorp/${{env.repo}}:${{env.version}}
- ecr.public.aws/hashicorp/${{env.repo}}:${{env.version}}
+ public.ecr.aws/hashicorp/${{env.repo}}:${{env.version}}
From 2b0bb8c62befaf8b4260212279df8681d1df266d Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Thu, 16 Dec 2021 17:24:46 -0800
Subject: [PATCH 008/225] ACL system docs updates re: admin partitions in
Consul v1.11.0
---
.../content/docs/security/acl/acl-system.mdx | 120 ++++++++++++++----
1 file changed, 98 insertions(+), 22 deletions(-)
diff --git a/website/content/docs/security/acl/acl-system.mdx b/website/content/docs/security/acl/acl-system.mdx
index 927e0838d..7de5783a2 100644
--- a/website/content/docs/security/acl/acl-system.mdx
+++ b/website/content/docs/security/acl/acl-system.mdx
@@ -69,16 +69,53 @@ If the ACL system becomes inoperable, you can follow the
### ACL Policies
-An ACL policy is a named set of rules and is composed of the following elements:
+An ACL policy (not to be confused with [policy dispositions](/docs/security/acl/acl-rules#policy-dispositions)) is a named set of rules and several attributes that define the policy domain. The ID is generated when policy is created, but you can specify the attributes when creating the policy. Refer to the [ACL policy command line](https://www.consul.io/commands/acl/policy) documentation or [ACL policy API](/api-docs/acl/policies) documentation for additional information on how to create policies.
-- **ID** - The policy's auto-generated public identifier.
-- **Name** - A unique meaningful name for the policy.
-- **Description** - A human readable description of the policy. (Optional)
-- **Rules** - Set of rules granting or denying permissions. See the [Rule Specification](/docs/acl/acl-rules#rule-specification) documentation for more details.
-- **Datacenters** - A list of datacenters the policy is valid within.
-- **Namespace** - - The namespace this policy resides within. (Added in Consul Enterprise 1.7.0)
+ACL policies can have the following attributes:
--> **Consul Enterprise Namespacing** - Rules defined in a policy in any namespace other than `default` will be [restricted](/docs/acl/acl-rules#namespace-rules) to being able to grant a subset of the overall privileges and only affecting that single namespace.
+| Attribute | Description | Required | Default |
+| --- | --- | --- | --- |
+| `ID` | The policy's auto-generated public identifier. | N/A | N/A |
+| `name` | Unique name for the policy. | Required | none |
+| `description` | Human readable description of the policy. | Optional | none |
+| `rules` | Set of rules granting or denying permissions. See the [Rule Specification](/docs/acl/acl-rules#rule-specification) documentation for more details. | Optional | none |
+| `datacenter` | Datacenter in which the policy is valid. More than one datacenter can be specified. | Optional | none |
+| `namespace` | Namespace in which the policy is valid. Added in Consul Enterprise 1.7.0. | Optional | `default` |
+| `partition` | Admin partition in which the policy is valid. Added in Consul Enterprise 1.11.0 | Optional | `default` |
+
+-> **Non-default Namespaces and Partitions** - Rules defined in a policy tied to an namespace or admin partition other than `default` can only grant a subset of privileges that affect the namespace or partition. See [Namespace Rules](/docs/acl/acl-rules#namespace-rules) and [Admin Partition Rules](/docs/acl/acl-rules#admin-partition-rules) for additional information.
+
+You can view the current ACL policies on the command line or through the API. The following example demonstrates the command line usage:
+
+```shell-session
+$ consul acl policy list -format json -token
+[
+ {
+ "ID": "56595ec1-52e4-d6de-e566-3b78696d5459",
+ "Name": "b-policy",
+ "Description": "",
+ "Datacenters": null,
+ "Hash": "ULwaXlI6Ecqb9YSPegXWgVL1LlwctY9TeeAOhp5HGBA=",
+ "CreateIndex": 126,
+ "ModifyIndex": 126,
+ "Namespace": "default",
+ "Partition": "default"
+ },
+ {
+ "ID": "00000000-0000-0000-0000-000000000001",
+ "Name": "global-management",
+ "Description": "Builtin Policy that grants unlimited access",
+ "Datacenters": null,
+ "Hash": "W1bQuDAlAlxEb4ZWwnVHplnt3I5oPKOZJQITh79Xlog=",
+ "CreateIndex": 70,
+ "ModifyIndex": 70,
+ "Namespace": "default",
+ "Partition": "default"
+ }
+]
+```
+
+Note that the `Hash`, `CreateIndex`, and `ModifyIndex` attributes are also printed. These attributes are printed for all responses and are not specific to ACL policies.
#### Builtin Policies
@@ -130,8 +167,7 @@ node_prefix "" {
The [API documentation for roles](/api/acl/roles#sample-payload) has some
examples of using a service identity.
--> **Consul Enterprise Namespacing** - Service Identity rules will be scoped to the single namespace that
-the corresponding ACL Token or Role resides within.
+-> **Service Scope for Namespace and Admin Partition** - Service identity rules in Consul Enterprise are scoped to the namespace or admin partition within which the corresponding ACL token or role resides.
### ACL Node Identities
@@ -179,26 +215,66 @@ of the following elements:
- **Service Identity Set** - The list of service identities that are applicable for the role.
- **Namespace** - The namespace this policy resides within. (Added in Consul Enterprise 1.7.0)
--> **Consul Enterprise Namespacing** - Roles may only link to policies defined in the same namespace as the role itself.
+-> **Linking Roles to Policies in Consul Enterprise** - Roles can only be linked to policies that are defined in the same namespace or admin partition.
### ACL Tokens
-ACL tokens are used to determine if the caller is authorized to perform an action. An ACL token is composed of the following
-elements:
+Consul uses ACL tokens to determine if the caller is authorized to perform an action. An ACL token is composed of several attributes that you can specify when creating the token. Refer to the [ACL token command line](https://www.consul.io/commands/acl/token) documentation or [ACL token API](/api-docs/acl/tokens) documentation for additional information on how to create policies.:
- **Accessor ID** - The token's public identifier.
- **Secret ID** -The bearer token used when making requests to Consul.
-- **Description** - A human readable description of the token. (Optional)
- **Policy Set** - The list of policies that are applicable for the token.
-- **Role Set** - The list of roles that are applicable for the token. (Added in Consul 1.5.0)
-- **Service Identity Set** - The list of service identities that are applicable for the token. (Added in Consul 1.5.0)
-- **Locality** - Indicates whether the token should be local to the datacenter it was created within or created in
- the primary datacenter and globally replicated.
-- **Expiration Time** - The time at which this token is revoked. (Optional; Added in Consul 1.5.0)
-- **Namespace** - The namespace this policy resides within. (Added in Consul Enterprise 1.7.0)
+- **Role Set** - The list of roles that are applicable for the token. Added in Consul 1.5.0.
+- **Service Identity Set** - The list of service identities that are applicable for the token. Added in Consul 1.5.0
+- **Local** - Indicates whether the token is local to the datacenter in which it was created. The attribute also can specify if the token was created in the primary datacenter and globally replicated.
+- **CreateTime** - Timestamp indicating when the token was created.
+- **Expiration Time** - The time at which this token is revoked. This attribute is option when creating a token. Added in Consul 1.5.0.
+- **Namespace** - The namespace in which the policy resides. Added in Consul Enterprise 1.7.0.
+- **Partition** - The partition in which the policy resides. Added in Consul Enterprise 1.11.0.
--> **Consul Enterprise Namespacing** - Tokens may only link to policies and roles defined in the same namespace as
-the token itself.
+-> **Linking Tokens to Policies in Consul Enterprise** - Tokens can only be linked to policies that are defined in the same namespace or admin partition.
+
+You can view the current ACL tokens on the command line or through the API. The following example demonstrates the command line usage:
+
+```shell-session
+$ consul acl token list -format json -token
+[
+ {
+ "CreateIndex": 75,
+ "ModifyIndex": 75,
+ "AccessorID": "c3274caa-fbe4-b457-f4af-c05ba89a048d",
+ "SecretID": "105c016a-ae9c-2006-ce23-4ef8823ba2af",
+ "Description": "Bootstrap Token (Global Management)",
+ "Policies": [
+ {
+ "ID": "00000000-0000-0000-0000-000000000001",
+ "Name": "global-management"
+ }
+ ],
+ "Local": false,
+ "CreateTime": "2021-12-16T10:22:08.906291-08:00",
+ "Hash": "Wda9obh/gvreyTbVhbyJ3ipX0M/apF4kpqowPQQx+u8=",
+ "Legacy": false,
+ "Namespace": "default",
+ "Partition": "default"
+ },
+ {
+ "CreateIndex": 71,
+ "ModifyIndex": 71,
+ "AccessorID": "00000000-0000-0000-0000-000000000002",
+ "SecretID": "anonymous",
+ "Description": "Anonymous Token",
+ "Local": false,
+ "CreateTime": "2021-12-16T10:21:11.996298-08:00",
+ "Hash": "tgCOyeidw+oaoZXQ9mHy6+EnY7atKoGaBzg2ndTwXl0=",
+ "Legacy": false,
+ "Namespace": "default",
+ "Partition": "default"
+ }
+]
+```
+
+Note that the `CreateIndex`, `ModifyIndex`, and `Hash` attributes are also printed. These attributes are printed for all responses and are not specific to ACL tokens.
#### Builtin Tokens
From 94da06f6ee372e836a4e10e8bcd50d20d89db2b4 Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Fri, 17 Dec 2021 09:46:50 -0800
Subject: [PATCH 009/225] additional clarification on upstream configurations
for x-dc and x-partition traffic
---
.../mesh-gateway/service-to-service-traffic-datacenters.mdx | 3 ++-
.../mesh-gateway/service-to-service-traffic-partitions.mdx | 5 ++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
index e6ce374eb..f7c153a34 100644
--- a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
@@ -58,7 +58,8 @@ Sidecar proxies that do not send upstream traffic through a gateway are not affe
Configure the following settings to register the mesh gateway as a service in Consul.
* Specify `mesh-gateway` in the `kind` field to register the gateway with Consul.
-* Define the `Proxy.Config` settings using opaque parameters compatible with your proxy, i.e., Envoy. For Envoy, refer to the [Gateway Options](/docs/connect/proxies/envoy#gateway-options) and [Escape-hatch Overrides](/docs/connect/proxies/envoy#escape-hatch-overrides) documentation for additional configuration information.
+* Configure the `proxy.upstreams` parameters to route traffic to the correct service, namespace, and datacenter. Refer to the [`upstreams` documentation](/docs/connect/registration/service-registration#upstream-configuration-reference) for details. The service `proxy.upstreams.destination_name` is always required. The `proxy.upstreams.datacenter` must be configured to enable cross-datacenter traffic. The `proxy.upstreams.destination_namespace` configuration is only necessary if the destination service is in a different namespace.
+* Define the `Proxy.Config` settings using opaque parameters compatible with your proxy (i.e., Envoy). For Envoy, refer to the [Gateway Options](/docs/connect/proxies/envoy#gateway-options) and [Escape-hatch Overrides](/docs/connect/proxies/envoy#escape-hatch-overrides) documentation for additional configuration information.
* If ACLs are enabled, a token granting `service:write` for the gateway's service name and `service:read` for all services in the datacenter or partition must be added to the gateway's service definition. These permissions authorize the token to route communications for other Consul service mesh services, but does not allow decrypting any of their communications.
### Modes
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
index 70a2e9c4c..2a0b91751 100644
--- a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
@@ -44,12 +44,11 @@ Sidecar proxies that do not send upstream traffic through a gateway are not affe
Configure the following settings to register the mesh gateway as a service in Consul.
* Specify `mesh-gateway` in the `kind` field to register the gateway with Consul.
-* Define the `Proxy.Config` settings using opaque parameters compatible with your proxy, i.e., Envoy. For Envoy, refer to the [Gateway Options](/docs/connect/proxies/envoy#gateway-options) and [Escape-hatch Overrides](/docs/connect/proxies/envoy#escape-hatch-overrides) documentation for additional configuration information.
-* Configure the `proxy.upstreams` parameters to route traffic to the correct service, namespace, and partition. Refer to the [`upstreams` documentation](/docs/connect/registration/service-registration#upstream-configuration-reference) for details.
+* Configure the `proxy.upstreams` parameters to route traffic to the correct service, namespace, and partition. Refer to the [`upstreams` documentation](/docs/connect/registration/service-registration#upstream-configuration-reference) for details. The service `proxy.upstreams.destination_name` is always required. The `proxy.upstreams.destination_partition` must be configured to enable cross-partition traffic. The `proxy.upstreams.destination_namespace` configuration is only necessary if the destination service is in a different namespace.
* Configure the `exported-services` configuration entry to enable Consul to export services contained in an admin partition to one or more additional partitions. Refer to the [Exported Services documentation](/docs/connect/config-entries/exported-services) for details.
+* Define the `Proxy.Config` settings using opaque parameters compatible with your proxy, i.e., Envoy. For Envoy, refer to the [Gateway Options](/docs/connect/proxies/envoy#gateway-options) and [Escape-hatch Overrides](/docs/connect/proxies/envoy#escape-hatch-overrides) documentation for additional configuration information.
* If ACLs are enabled, a token granting `service:write` for the gateway's service name and `service:read` for all services in the datacenter or partition must be added to the gateway's service definition. These permissions authorize the token to route communications for other Consul service mesh services, but does not allow decrypting any of their communications.
-
### Modes
Each upstream associated with a service mesh proxy can be configured so that it is routed through a mesh gateway.
From 0288678e00f971acbb6d02838cd1553124cfb892 Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Mon, 20 Dec 2021 16:30:39 -0800
Subject: [PATCH 010/225] updated configuration entry params for admin
partitions 1.11
---
.../config-entries/ingress-gateway.mdx | 305 ++++++++++++++----
.../docs/connect/config-entries/mesh.mdx | 33 +-
.../connect/config-entries/proxy-defaults.mdx | 17 +-
.../config-entries/service-defaults.mdx | 15 +
.../config-entries/service-intentions.mdx | 30 +-
.../config-entries/service-resolver.mdx | 20 +-
.../connect/config-entries/service-router.mdx | 18 +-
.../config-entries/service-splitter.mdx | 18 +-
.../config-entries/terminating-gateway.mdx | 12 +-
9 files changed, 379 insertions(+), 89 deletions(-)
diff --git a/website/content/docs/connect/config-entries/ingress-gateway.mdx b/website/content/docs/connect/config-entries/ingress-gateway.mdx
index cdfe9e6c7..2d276cb70 100644
--- a/website/content/docs/connect/config-entries/ingress-gateway.mdx
+++ b/website/content/docs/connect/config-entries/ingress-gateway.mdx
@@ -8,21 +8,162 @@ description: >-
# Ingress Gateway
--> **v1.8.4+:** On Kubernetes, the `IngressGateway` custom resource is supported in Consul versions 1.8.4+.
-**v1.8.0+:** On other platforms, this config entry is supported in Consul versions 1.8.0+.
+This topic provides reference information for the `ingress-gateway` configuration entry.
-The `ingress-gateway` config entry kind (`IngressGateway` on Kubernetes) allows you to configure ingress gateways
-with listeners that expose a set of services outside the Consul service mesh.
+## Introduction
+
+You can define an `ingress-gateway` configuration entry to connect the Consul service mesh to a set of external services. The specification for ingress gateways include a `listeners` configuration, which exposes the service mesh to the external services. Use camel case (`IngressGateway`) to declare an ingress gateway configuration entry on Kubernetes.
+
+Refer to the [Kubernetes Ingress Gateway](/docs/k8s/connect/ingress-gateways) documentation for information about configuring ingress gateways on Kubernetes.
-For Kubernetes, see [Kubernetes Ingress Gateway](/docs/k8s/connect/ingress-gateways) for more information.
For other platforms, see [Ingress Gateway](/docs/connect/ingress-gateway).
-~> **Note:** [Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies
-across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different
-sets of services within their datacenter then the ingress gateways **must** be registered with different names.
-See [Ingress Gateway](/docs/connect/ingress-gateway) for more information.
+## Requirements
-## Wildcard service specification
+* Consul versions 1.8.4+ is required to use the `IngressGateway` custom resource on Kubernetes.
+* Consul versions 1.8.0+ is required to use the `ingress-gateway` custom resource on all other platforms.
+
+## Usage
+
+1. Verify that your datacenter meets the conditions specified in the [Requirements](#requirements).
+1. Specify the `ingress-gateway` (`IngressGateway`) configuration in the agent configuration file (see [config_entries](/docs/agent/options#config_entries)) as described in [Configuration](#configuration).
+1. Apply the configuration using one of the following methods:
+ * Kubernetes CRD: Refer to the [Custom Resource Definitions](/docs/k8s/crds) documentation for details.
+ * Issue the `consul config write` command: Refer to the [Consul Config Write](/commands/config/write) documentation for details.
+
+## Configuration
+
+Use the following syntax to configure an ingress gateway.
+
+
+
+
+
+```hcl
+Kind = "ingress-gateway"
+Name = ""
+
+Listeners = [
+ {
+ Port =
+ Protocol = ""
+ Services = [
+ {
+ Name = ""
+ }
+ ]
+
+ }
+]
+
+```
+
+```yaml
+apiVersion: consul.hashicorp.com/v1alpha1
+kind: IngressGateway
+metadata:
+ name:
+spec:
+ listeners:
+ - port:
+ protocol:
+ services:
+ - name:
+```
+
+```json
+{
+ "Kind": "ingress-gateway",
+ "Name": "",
+ "Listeners": [
+ {
+ "Port": ,
+ "Protocol": "",
+ "Services": [
+ {
+ "Name": ""
+ }
+ ]
+ }
+ ]
+}
+
+```
+
+
+
+
+
+
+
+```hcl
+Kind = "ingress-gateway"
+Name = ""
+Namespace = ""
+Partition = ""
+
+Listeners = [
+ {
+ Port =
+ Protocol = ""
+ Services = [
+ {
+ Name = ""
+ }
+ ]
+
+ }
+]
+
+```
+
+```yaml
+apiVersion: consul.hashicorp.com/v1alpha1
+kind: IngressGateway
+metadata:
+ name:
+ namespace:
+ partition:
+
+spec:
+ listeners:
+ - port:
+ protocol:
+ services:
+ - name:
+```
+
+```json
+{
+ "Kind": "ingress-gateway",
+ "Name": "",
+ "Namespace": "",
+ "Partition": "",
+
+ "Listeners": [
+ {
+ "Port": ,
+ "Protocol": "",
+ "Services": [
+ {
+ "Name": ""
+ }
+ ]
+ }
+ ]
+}
+```
+
+
+
+
+Refer to the [Available Fields](#available-fields) section for complete information about all ingress gateway configuraiton entry options and to the [Example Configurations](#example-configurations) section for example use-cases.
+
+### Scope
+
+[Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different sets of services within their datacenter then the ingress gateways **must** be registered with different names. See [Ingress Gateway](/docs/connect/ingress-gateway) for more information.
+
+### Wildcard Service Specification
Ingress gateways can optionally target all services within a Consul namespace by
specifying a wildcard `*` as the service name. A wildcard specifier allows
@@ -43,15 +184,27 @@ gateway:
A wildcard specifier cannot be set on a listener of protocol `tcp`.
-## Sample Config Entries
+### ACLs
+
+Configuration entries may be protected by [ACLs](/docs/security/acl).
+
+Reading an `ingress-gateway` config entry requires `service:read` on the `Name`
+field of the config entry.
+
+Creating, updating, or deleting an `ingress-gateway` config entry requires
+`operator:write`.
+
+### Example Configurations
+
+The following examples describe possible use-cases for ingress gateway configuration entries.
+
+#### TCP listener
+
+The following example sets up a TCP listener on an ingress gateway named `us-east-ingress` to proxy traffic to the `db` service. The Consul Enterprise version also posits the gateway listener inside the `default` [namespace](/docs/enterprise/namespaces) and the `team-frontend` [admin partition](/docs/enterprise/admin-partitions):
-### TCP listener
-
-Set up a TCP listener on an ingress gateway named "us-east-ingress" to proxy traffic to the "db" service:
-
```hcl
@@ -106,16 +259,13 @@ spec:
-
-Set up a TCP listener on an ingress gateway named "us-east-ingress" in the default namespace
-to proxy traffic to the "db" service in the ops namespace:
-
```hcl
Kind = "ingress-gateway"
Name = "us-east-ingress"
Namespace = "default"
+Partition = "team-frontend"
Listeners = [
{
@@ -137,6 +287,7 @@ kind: IngressGateway
metadata:
name: us-east-ingress
namespace: default
+ partition: team-frontend
spec:
listeners:
- port: 3456
@@ -151,6 +302,7 @@ spec:
"Kind": "ingress-gateway",
"Name": "us-east-ingress",
"Namespace": "default",
+ "Partition": "team-frontend",
"Listeners": [
{
"Port": 3456,
@@ -171,14 +323,21 @@ spec:
-### Wildcard HTTP listener
+#### Wildcard HTTP Listener
+
+In the following example, two listeners are configured on an ingress gateway named `us-east-ingress`:
+
+* The first listener is configred to listen on port `8080` and uses a wildcard (`*`) to proxy traffic to all services in the datacenter.
+* The second listener exposes the `api` and `web` services on port `4567` at user-provided hosts.
+* TLS is enabled on every listener.
+
+The Consul Enterprise version implements the following additional configurations:
+
+* The ingress gateway is set up in the `default` [namespace](/docs/enterprise/namespaces) and proxies traffic to all services in the `frontend` namespace.
+* The `api` and `web` services are proxied to team-specific [admin partitions](/docs/enterprise/admin-partitions):
-
-Set up a wildcard HTTP listener on an ingress gateway named "us-east-ingress" to proxy traffic to all services in the datacenter.
-Also make two services available over a custom port with user-provided hosts, and enable TLS on every listener:
-
```hcl
@@ -277,10 +436,6 @@ spec:
-
-Set up a wildcard HTTP listener on an ingress gateway named "us-east-ingress" to proxy traffic to all services in the frontend namespace.
-Also make two services in the frontend namespace available over a custom port with user-provided hosts, and enable TLS on every listener:
-
```hcl
@@ -311,11 +466,13 @@ Listeners = [
Namespace = "frontend"
Name = "api"
Hosts = ["foo.example.com"]
+ Partition = "api-team"
},
{
Namespace = "frontend"
Name = "web"
Hosts = ["website.example.com"]
+ Partition = "web-team"
}
]
}
@@ -343,9 +500,11 @@ spec:
- name: api
namespace: frontend
hosts: ['foo.example.com']
+ partition: api-team
- name: web
namespace: frontend
hosts: ['website.example.com']
+ partition: web-team
```
```json
@@ -374,12 +533,14 @@ spec:
{
"Namespace": "frontend",
"Name": "api",
- "Hosts": ["foo.example.com"]
+ "Hosts": ["foo.example.com"],
+ "Partition": "api-team"
},
{
"Namespace": "frontend",
"Name": "web",
- "Hosts": ["website.example.com"]
+ "Hosts": ["website.example.com"],
+ "Partition": "web-team"
}
]
}
@@ -392,18 +553,16 @@ spec:
-### HTTP listener with path-based routing
+#### HTTP listener with Path-based Routing
+
+The following example sets up an HTTP listener on an ingress gateway named `us-east-ingress` to proxy
+traffic to a virtual service named `api`. In the Consul Enterprise version, `us-east-ingress` is set up in the `default` namespace and `default` partition.
+
+In this use-case, internal-only debug headers should be stripped before responding to external clients.
+Requests to internal services should also be labelled to indicate which gateway they came through.
-
-Set up an HTTP listener on an ingress gateway named "us-east-ingress" to proxy
-traffic to a virtual service named "api".
-
-Additionally, ensure internal-only debug headers are stripped before responding
-to external clients, and that requests to internal services are labelled to
-indicate which gateway they came through.
-
```hcl
@@ -442,7 +601,7 @@ spec:
protocol: http
services:
- name: api
- # HTTP Header manipulation is not yet supported in Kubernetes CRD
+ # HTTP Header manipulation is not supported in Kubernetes CRD
```
```json
@@ -475,20 +634,13 @@ spec:
-
-Set up an HTTP listener on an ingress gateway named "us-east-ingress" in the
-default namespace to proxy traffic to a virtual service named "api".
-
-Additionally, ensure internal-only debug headers are stripped before responding
-to external clients, and that requests to internal services are labelled to
-indicate which gateway they came through.
-
```hcl
Kind = "ingress-gateway"
Name = "us-east-ingress"
Namespace = "default"
+Partition = "default"
Listeners = [
{
@@ -518,6 +670,7 @@ kind: IngressGateway
metadata:
name: us-east-ingress
namespace: default
+ partition: default
spec:
listeners:
- port: 80
@@ -525,7 +678,7 @@ spec:
services:
- name: api
namespace: frontend
- # HTTP Header manipulation is not yet supported in Kubernetes CRD
+ # HTTP Header manipulation is not supported in Kubernetes CRD
```
```json
@@ -533,6 +686,7 @@ spec:
"Kind": "ingress-gateway",
"Name": "us-east-ingress",
"Namespace": "default",
+ "Partition": "default",
"Listeners": [
{
"Port": 80,
@@ -561,10 +715,7 @@ spec:
-The `api` service is not an actual registered service. It exist as a "virtual"
-service for L7 configuration only. A `service-router` (`ServiceRouter` on Kubernetes) is defined for this
-virtual service which uses path-based routing to route requests to different
-backend services:
+For this use-case, the `api` service is not an actual registered service. It exists as a virtual service for L7 configuration only. A `service-router` (`ServiceRouter` on Kubernetes) is defined for the virtual service that uses path-based routing to route requests to different backend services:
@@ -659,6 +810,7 @@ spec:
Kind = "service-router"
Name = "api"
Namespace = "default"
+Partition = "default"
Routes = [
{
Match {
@@ -693,6 +845,7 @@ kind: ServiceRouter
metadata:
name: api
namespace: default
+ partition: default
spec:
routes:
- match:
@@ -714,6 +867,7 @@ spec:
"Kind": "service-router",
"Name": "api",
"Namespace": "default",
+ "Partition": "default",
"Routes": [
{
"Match": {
@@ -748,6 +902,8 @@ spec:
## Available Fields
+You can specify the following parameters to configure ingress gateway configuration entries.
+
-## ACLs
-
-Configuration entries may be protected by [ACLs](/docs/security/acl).
-
-Reading an `ingress-gateway` config entry requires `service:read` on the `Name`
-field of the config entry.
-
-Creating, updating, or deleting an `ingress-gateway` config entry requires
-`operator:write`.
diff --git a/website/content/docs/connect/config-entries/mesh.mdx b/website/content/docs/connect/config-entries/mesh.mdx
index e80e86445..335121472 100644
--- a/website/content/docs/connect/config-entries/mesh.mdx
+++ b/website/content/docs/connect/config-entries/mesh.mdx
@@ -10,13 +10,12 @@ description: >-
# Mesh
--> **v1.10.0+:** This config entry is supported in Consul versions 1.10.0+.
+-> **v1.10.0+:** This configuration entry is supported in Consul versions 1.10.0+.
-The `mesh` config entry kind allows for globally defining
-default configuration that applies to all service mesh proxies.
+The `mesh` configuration entry allows you to define a global default configuration that applies to all service mesh proxies.
Settings in this config entry apply across all namespaces and federated datacenters.
-## Sample Config Entries
+## Sample Configuration Entries
### Mesh Destinations Only
@@ -58,14 +57,14 @@ spec:
--> **Note**: The `mesh` config entry can only be created in the `default`
-namespace and it will apply to proxies across **all** namespaces.
+The `mesh` configuration entry can only be created in the `default` namespace and will apply to proxies across **all** namespaces.
```hcl
Kind = "mesh"
Namespace = "default" # Can only be set to "default".
+Partition = "default"
TransparentProxy {
MeshDestinationsOnly = true
@@ -77,6 +76,8 @@ apiVersion: consul.hashicorp.com/v1alpha1
kind: Mesh
metadata:
name: mesh
+ namespace: default
+ partition: default
spec:
transparentProxy:
meshDestinationsOnly: true
@@ -86,6 +87,7 @@ spec:
{
"Kind": "mesh",
"Namespace": "default",
+ "Partition": "default",
"TransparentProxy": {
"MeshDestinationsOnly": true
}
@@ -118,7 +120,15 @@ spec:
type: `string: "default"`,
enterprise: true,
description:
- 'Must be set to default. Config will apply to all namespaces.',
+ 'Must be set to `default`. The configuration will apply to all namespaces.',
+ yaml: false,
+ },
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ 'Specifies the name of the admin partition in which the configuration entry applies. Refer to the [Admin Partitions documentation](/docs/enterprise/admin-partitions) for additional information.',
yaml: false,
},
{
@@ -137,8 +147,15 @@ spec:
},
{
name: 'namespace',
+ enterprise: true,
description:
- 'If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/docs/k8s/crds#consul-enterprise) for more details.',
+ 'Must be set tot `default`. If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/docs/k8s/crds#consul-enterprise) for additional information.',
+ },
+ {
+ name: 'partition',
+ enterprise: true,
+ description:
+ 'Specifies the admin partition in which the configuration will apply. The current partition is used if unspecified. Refer to the [Admin Partitions documentation](/docs/enterprise/admin-partitions) for details. The partitions parameter is not supported in Consul OSS.',
},
],
hcl: false,
diff --git a/website/content/docs/connect/config-entries/proxy-defaults.mdx b/website/content/docs/connect/config-entries/proxy-defaults.mdx
index 74bfb7038..8993915a8 100644
--- a/website/content/docs/connect/config-entries/proxy-defaults.mdx
+++ b/website/content/docs/connect/config-entries/proxy-defaults.mdx
@@ -203,7 +203,15 @@ spec:
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
- description: 'Specifies the namespace the config entry will apply to.',
+ description: 'Must be set to `default`. The configuration will apply to all namespaces.',
+ yaml: false,
+ },
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ 'Specifies the name of the admin partition in which the configuration entry applies. Refer to the [Admin Partitions documentation](/docs/enterprise/admin-partitions) for additional information.',
yaml: false,
},
{
@@ -222,9 +230,16 @@ spec:
},
{
name: 'namespace',
+ enterprise: true,
description:
'If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/docs/k8s/crds#consul-enterprise) for more details.',
},
+ {
+ name: 'partition',
+ enterprise: true,
+ description:
+ 'Specifies the admin partition in which the configuration will apply. The current partition is used if unspecified. Refer to the [Admin Partitions documentation](/docs/enterprise/admin-partitions) for details. The partitions parameter is not supported in Consul OSS.',
+ },
],
hcl: false,
},
diff --git a/website/content/docs/connect/config-entries/service-defaults.mdx b/website/content/docs/connect/config-entries/service-defaults.mdx
index 8a5b64779..82b585e02 100644
--- a/website/content/docs/connect/config-entries/service-defaults.mdx
+++ b/website/content/docs/connect/config-entries/service-defaults.mdx
@@ -265,6 +265,15 @@ spec:
description: 'Specifies the namespace the config entry will apply to.',
yaml: false,
},
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ 'Specifies the name of the admin partition in which the configuration entry applies. Refer to the [Admin Partitions documentation](/docs/enterprise/admin-partitions) for additional information.',
+ yaml: false,
+ },
+
{
name: 'Meta',
type: 'map: nil',
@@ -284,6 +293,12 @@ spec:
description:
'If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/docs/k8s/crds#consul-enterprise) for more details.',
},
+ {
+ name: 'partition',
+ enterprise: true,
+ description:
+ 'Specifies the admin partition in which the configuration will apply. The current partition is used if unspecified. Refer to the [Admin Partitions documentation](/docs/enterprise/admin-partitions) for details. The partitions parameter is not supported in Consul OSS.',
+ },
],
hcl: false,
},
diff --git a/website/content/docs/connect/config-entries/service-intentions.mdx b/website/content/docs/connect/config-entries/service-intentions.mdx
index b3bc3981c..048d1a30c 100644
--- a/website/content/docs/connect/config-entries/service-intentions.mdx
+++ b/website/content/docs/connect/config-entries/service-intentions.mdx
@@ -34,9 +34,11 @@ or globally via [`proxy-defaults`](/docs/connect/config-entries/proxy-defaults)
## Sample Config Entries
+The following examples demonstrate potential use-cases for the `service-intentions` configuration entry.
+
### REST Access
-Grant some clients more REST access than others:
+In the following example, the `admin-dashboard` and `report-generator` services have different levels of access when making REST calls:
@@ -134,9 +136,8 @@ spec:
### gRPC
-Selectively deny some gRPC service methods. Since gRPC method calls [are
-HTTP/2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), we can
-use an HTTP path match rule to control traffic:
+In the following use-case, access to the `IssueRefund` gRPC service method is set to `deny`. Because gRPC method calls [are
+HTTP/2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md), an HTTP path-matching rule can be used to control traffic:
@@ -367,6 +368,14 @@ spec:
"Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (`*`) to match all services in all namespaces that don't otherwise have intentions defined. Wildcard intentions cannot be used when defining L7 [`Permissions`](/docs/connect/config-entries/service-intentions#permissions).",
yaml: false,
},
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ "Specifies the admin partition on which the configuration entry will apply. Wildcard characters (`*`) are not supported. Admin partitions must specified explicitly.",
+ yaml: false,
+ },
{
name: 'Meta',
type: 'map: nil',
@@ -438,6 +447,7 @@ spec:
},
{
name: 'Namespace',
+ enterprise: true,
type: 'string',
description: {
hcl:
@@ -445,8 +455,18 @@ spec:
yaml:
'The namespace of the source service. Defaults to the namespace of the destination service (i.e. `spec.destination.namespace`)',
},
- enterprise: true,
},
+ {
+ name: 'Partition',
+ enterprise: true,
+ type: 'string',
+ description: {
+ hcl:
+ "Specifies the admin partition of the source service. Defaults to the destination service's partition, i.e., the configuration entry's partition",
+ yaml:
+ "Specifies the admin partiation of the source service. Defaults to the destination service's partition, i.e. `spec.destination.namespace`",
+ },
+ },
{
name: 'Action',
type: 'string: ""',
diff --git a/website/content/docs/connect/config-entries/service-resolver.mdx b/website/content/docs/connect/config-entries/service-resolver.mdx
index 6afe1265e..8618c2d90 100644
--- a/website/content/docs/connect/config-entries/service-resolver.mdx
+++ b/website/content/docs/connect/config-entries/service-resolver.mdx
@@ -246,7 +246,14 @@ spec:
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
- description: 'Specifies the namespace the config entry will apply to.',
+ description: 'Specifies the namespace in which the configuration entry will apply.',
+ yaml: false,
+ },
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description: 'Specifies the admin partition in which the configuration entry will apply.',
yaml: false,
},
{
@@ -348,13 +355,20 @@ spec:
enterprise: true,
type: 'string: ""',
description:
- 'The namespace to resolve the service from instead of the current one.',
+ 'Specifies the source namespace to resolve the service from.',
+ },
+ {
+ name: 'Partition',
+ enterprise: true,
+ type: 'string: ""',
+ description:
+ 'Specifies the source admin partition to resolve the service from.',
},
{
name: 'Datacenter',
type: 'string: ""',
description:
- 'The datacenter to resolve the service from instead of the current one.',
+ 'Specifies the source datacenter to resolve the service from.',
},
],
},
diff --git a/website/content/docs/connect/config-entries/service-router.mdx b/website/content/docs/connect/config-entries/service-router.mdx
index 3e02f1601..ddd348988 100644
--- a/website/content/docs/connect/config-entries/service-router.mdx
+++ b/website/content/docs/connect/config-entries/service-router.mdx
@@ -302,7 +302,14 @@ spec:
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
- description: 'Specifies the namespace the config entry will apply to.',
+ description: 'Specifies the namespace to which the configuration entry will apply.',
+ yaml: false,
+ },
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description: 'Specifies the admin partition to which the configuration will apply.',
yaml: false,
},
{
@@ -538,7 +545,14 @@ spec:
name: 'Namespace',
type: 'string: ""',
description:
- 'The Consul namespace to resolve the service from instead of the current namespace. If empty the current namespace is assumed.',
+ 'The Consul namespace to resolve the service from instead of the current namespace. If empty, the current namespace is used.',
+ enterprise: true,
+ },
+ {
+ name: 'Partition',
+ type: 'string: ""',
+ description:
+ 'The Consul admin partition to resolve the service from instead of the current partition. If empty, the current partition is used.',
enterprise: true,
},
{
diff --git a/website/content/docs/connect/config-entries/service-splitter.mdx b/website/content/docs/connect/config-entries/service-splitter.mdx
index f6eb62ddf..3aba56208 100644
--- a/website/content/docs/connect/config-entries/service-splitter.mdx
+++ b/website/content/docs/connect/config-entries/service-splitter.mdx
@@ -234,7 +234,14 @@ Splits = [
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
- description: 'Specifies the namespace the config entry will apply to.',
+ description: 'Specifies the namespace to which the configuration entry will apply.',
+ yaml: false,
+ },
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description: 'Specifies the admin partition to which the configuration entry will apply.',
yaml: false,
},
{
@@ -291,7 +298,14 @@ Splits = [
enterprise: true,
type: 'string: ""',
description:
- 'The namespace to resolve the service from instead of the current namespace. If empty the current namespace is assumed.',
+ 'The namespace to resolve the service from instead of the current namespace. If empty, the current namespace is used.',
+ },
+ {
+ name: 'Partition',
+ enterprise: true,
+ type: 'string: ""',
+ description:
+ 'The admin partition to resolve the service from instead of the current partition. If empty, the current partition is used.',
},
{
yaml: false,
diff --git a/website/content/docs/connect/config-entries/terminating-gateway.mdx b/website/content/docs/connect/config-entries/terminating-gateway.mdx
index 5ba891635..b89fcc1c6 100644
--- a/website/content/docs/connect/config-entries/terminating-gateway.mdx
+++ b/website/content/docs/connect/config-entries/terminating-gateway.mdx
@@ -567,11 +567,21 @@ spec:
type: `string: "default"`,
enterprise: true,
description:
- 'Specifies the namespace the config entry will apply to. This must be the namespace the gateway is registered in.' +
+ 'Specifies the namespace to which the configuration entry will apply. This must match the namespace in which the gateway is registered.' +
' If omitted, the namespace will be inherited from [the request](/api/config#ns)' +
' or will default to the `default` namespace.',
yaml: false,
},
+ {
+ name: 'Partition',
+ type: `string: "default"`,
+ enterprise: true,
+ description:
+ 'Specifies the admin partition to which the configuration entry will apply. This must match the partition in which the gateway is registered.' +
+ ' If omitted, the partition will be inherited from [the request](/api/config)' +
+ ' or will default to the `default` partition.',
+ yaml: false,
+ },
{
name: 'Meta',
type: 'map: nil',
From 9114e8786575c4b5c5296bb2c450471783e4a006 Mon Sep 17 00:00:00 2001
From: Blake Covarrubias
Date: Fri, 17 Dec 2021 22:26:17 -0800
Subject: [PATCH 011/225] Minor doc fixes to K8s CA and Admin Partitions guides
K8s Vault CA config docs:
* Re-add filename label on K8s Connect CA config.
* Remove call to `jq` when retrieving CA configuration.
* Clarify `connect.ca_config` and `connect.ca_provider` agent configs
are only used at cluster initialization.
Admin Partitions tutorial:
* Fix Helm client values filename.
* Use kubectl's template output to base64 decode Consul bootstrap token.
---
.../docs/enterprise/admin-partitions.mdx | 4 +--
.../docs/k8s/connect/connect-ca-provider.mdx | 30 ++++++++++++++-----
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/website/content/docs/enterprise/admin-partitions.mdx b/website/content/docs/enterprise/admin-partitions.mdx
index ab8c2aabf..3a88138d9 100644
--- a/website/content/docs/enterprise/admin-partitions.mdx
+++ b/website/content/docs/enterprise/admin-partitions.mdx
@@ -187,7 +187,7 @@ Verify that your Consul deployment meets the [Kubernetes Requirements](#kubernet
```
1. Create the workload configuration for client nodes in your cluster. Create a configuration for each admin partition. In the following example, the external IP address and the Kubernetes authentication method IP address from the previous steps have been applied:
-
+
```yaml
@@ -252,7 +252,7 @@ You can log into the Consul UI to verify that the partitions appear as expected.
1. If ACLs are enabled, you will need the partitions ACL token, which can be read from the Kubernetes secret. The token is an encoded string that must be decoded in base64, e.g.:
```shell-session
- kubectl get secret server-consul-bootstrap-acl-token -o json | jq -r .data.token | base64 -d -
+ kubectl get secret server-consul-bootstrap-acl-token --template "{{ .data.token | base64decode }}"
```
The example command gets the token using the secret name configured in the values file (`bootstrap.secretName`), decodes the secret, and prints the usable token to the console in JSON format.
diff --git a/website/content/docs/k8s/connect/connect-ca-provider.mdx b/website/content/docs/k8s/connect/connect-ca-provider.mdx
index baddd34c3..de1bca22a 100644
--- a/website/content/docs/k8s/connect/connect-ca-provider.mdx
+++ b/website/content/docs/k8s/connect/connect-ca-provider.mdx
@@ -26,8 +26,8 @@ To configure the Vault Connect Provider please see [Vault as the Service Mesh Ce
~> **NOTE:** The following instructions are only valid for Consul-k8s 0.37.0 and prior.
Below we will go over the process for configuring Vault as the Connect CA.
-However, other providers can be configured similarly by providing the appropriate `ca_config`
-and `ca_provider` values for the provider you're using.
+However, other providers can similarly be configured during initial bootstrap of the cluster
+by providing the appropriate [`ca_config`] and [`ca_provider`] values for the provider you're using.
## Configuring Vault as a Connect CA (Consul K8s 0.37.0 and earlier)
@@ -55,8 +55,9 @@ kubectl create secret generic vault-ca --from-file vault.ca=/path/to/your/vault/
And then reference it like this in the provider configuration:
-```shell-session
-$ cat vault-config.json
+
+
+```json
{
"connect": [
{
@@ -75,6 +76,8 @@ $ cat vault-config.json
}
```
+
+
This example configuration file is pointing to a Vault instance running in the same Kubernetes cluster,
which has been deployed with TLS enabled. Note that the `ca_file` is pointing to the file location
based on the Kubernetes secret for the Vault CA that we have created before.
@@ -94,6 +97,8 @@ $ kubectl create secret generic vault-config --from-file=config=vault-config.jso
We will provide this secret and the Vault CA secret, to the Consul server via the
`server.extraVolumes` Helm value.
+
+
```yaml
global:
name: consul
@@ -112,6 +117,8 @@ We will provide this secret and the Vault CA secret, to the Consul server via th
enabled: true
```
+
+
Finally, [install](/docs/k8s/installation/install#installing-consul) the Helm chart using the above config file:
```shell-session
@@ -121,7 +128,7 @@ $ helm install consul -f config.yaml hashicorp/consul
Verify that the CA provider is set correctly:
```shell-session
-$ kubectl exec consul-server-0 -- curl -s http://localhost:8500/v1/connect/ca/configuration | jq .
+$ kubectl exec consul-server-0 -- curl -s http://localhost:8500/v1/connect/ca/configuration\?pretty
{
"Provider": "vault",
"Config": {
@@ -149,6 +156,8 @@ for which this configuration is intended.
You will similarly need to create a Vault token and a Kubernetes secret with
Vault's CA in each secondary Kubernetes cluster.
+
+
```json
{
"connect": [
@@ -168,6 +177,8 @@ Vault's CA in each secondary Kubernetes cluster.
}
```
+
+
Note that all secondary datacenters need to have access to the same Vault instance as the primary.
### Manually Rotating Vault Tokens
@@ -177,11 +188,16 @@ then you will need to manually renew or rotate the Vault token before it expires
#### Rotating Vault Token
-Once the cluster is running, subsequent changes to the `ca_provider` config are **ignored**–even if `consul reload` is run or the servers are restarted.
+The [`ca_config`] and [`ca_provider`] options defined in the Consul agent
+configuration are only used when initially bootstrapping the cluster. Once the
+cluster is running, subsequent changes to the [`ca_provider`] config are **ignored**–even if `consul reload` is run or the servers are restarted.
-To update any settings under this key, you must use Consul's [Update CA Configuration](/api/connect/ca#update-ca-configuration) API or the [`consul connect ca set-config`](/commands/connect/ca#set-config) command.
+To update any settings under these keys, you must use Consul's [Update CA Configuration](/api/connect/ca#update-ca-configuration) API or the [`consul connect ca set-config`](/commands/connect/ca#set-config) command.
#### Renewing Vault Token
To renew the Vault token, use the [`vault token renew`](https://www.vaultproject.io/docs/commands/token/renew) CLI command
or API.
+
+[`ca_config`]: /docs/agent/options#connect_ca_config
+[`ca_provider`]: /docs/agent/options#connect_ca_provider
From dc22aa9e448c4afc3418c7b59ee07b587f1a723b Mon Sep 17 00:00:00 2001
From: mrspanishviking
Date: Tue, 21 Dec 2021 14:05:15 -0700
Subject: [PATCH 012/225] Apply suggestions from code review
Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>
---
.github/ISSUE_TEMPLATE/docs_day.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
index a5e01b324..f6fb83b35 100644
--- a/.github/ISSUE_TEMPLATE/docs_day.md
+++ b/.github/ISSUE_TEMPLATE/docs_day.md
@@ -1,7 +1,7 @@
---
name: Consul docs day task
about: This is a HashiCorp internal documentation task for the purpose of the Consul docs day event.
-labels: ['consul', 'placeholder']
+labels: ['type/docs', 'placeholder']
assignees:
- karl-cardenas-coding
- jkirschner-hashicorp
@@ -37,15 +37,15 @@ body:
attributes:
label: Description
description: Please provide details about the task?
- placeholder: Tell us what you see!
+ placeholder: What I'll change and why this is important
validations:
required: true
- type: textarea
id: link
attributes:
- label: Documentation page link
- description: Please provide a link to the documentation page (if applicable)
+ label: Documentation page link(s)
+ description: Please provide link(s) to the documentation page(s) to be modified, if applicable
placeholder: ex: https://www.consul.io/docs/connect/gateways#gateways
validations:
required: true
From c7a9abdeb645abe3c33f5b0a4acb82b00db07d8a Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Tue, 21 Dec 2021 14:07:32 -0700
Subject: [PATCH 013/225] removed unused text area
---
.github/ISSUE_TEMPLATE/docs_day.md | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
index f6fb83b35..4b892c860 100644
--- a/.github/ISSUE_TEMPLATE/docs_day.md
+++ b/.github/ISSUE_TEMPLATE/docs_day.md
@@ -48,11 +48,4 @@ body:
description: Please provide link(s) to the documentation page(s) to be modified, if applicable
placeholder: ex: https://www.consul.io/docs/connect/gateways#gateways
validations:
- required: true
-
- - type: textarea
- id: logs
- attributes:
- label: Relevant log output
- description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
- render: shell
\ No newline at end of file
+ required: true
\ No newline at end of file
From 2182a6f0a3b73d81026e2adbd268fa1fbab978e3 Mon Sep 17 00:00:00 2001
From: Andy Assareh
Date: Fri, 17 Dec 2021 12:00:21 -0800
Subject: [PATCH 014/225] usage example given uses outdated arguments
the usage example shows incorrect arguments for ca cert and key. the correct arguments are now -ca and -key
---
command/tls/cert/tls_cert.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/command/tls/cert/tls_cert.go b/command/tls/cert/tls_cert.go
index c706f0c6f..c15a39c2b 100644
--- a/command/tls/cert/tls_cert.go
+++ b/command/tls/cert/tls_cert.go
@@ -40,7 +40,7 @@ Usage: consul tls cert [options] [filename-prefix]
Create a certificate with your own CA:
- $ consul tls cert create -server -ca-file my-ca.pem -ca-key-file my-ca-key.pem
+ $ consul tls cert create -server -ca my-ca.pem -key my-ca-key.pem
==> saved dc1-server-consul.pem
==> saved dc1-server-consul-key.pem
From 800ed2c830832002da986ec9c4f547aacf87dfd8 Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Tue, 21 Dec 2021 14:34:56 -0700
Subject: [PATCH 015/225] added consul infograhic
---
website/content/docs/intro/index.mdx | 15 +++++++++++++--
website/public/img/intro_why_consul_diagram.png | 3 +++
2 files changed, 16 insertions(+), 2 deletions(-)
create mode 100644 website/public/img/intro_why_consul_diagram.png
diff --git a/website/content/docs/intro/index.mdx b/website/content/docs/intro/index.mdx
index 6ab45c8da..366a452fe 100644
--- a/website/content/docs/intro/index.mdx
+++ b/website/content/docs/intro/index.mdx
@@ -16,7 +16,7 @@ with Consul. We cover what Consul is, what problems it can solve, how it compare
to existing software, and how you can get started using it. If you are familiar
with the basics of Consul, the [documentation](/docs) provides a more
detailed reference of available features. If you're ready to get hands-on
-experience, deploy Consul locally with our
+experience, deploy Consul locally with our
[HashiCorp Learn tutorial](https://learn.hashicorp.com/tutorials/consul/get-started-install).
## What is Consul?
@@ -103,9 +103,20 @@ Each datacenter runs a cluster of Consul servers. When a cross-datacenter
service discovery or configuration request is made, the local Consul servers
forward the request to the remote datacenter and return the result.
+## Why Consul?
+
+Consul solves the challenges that organizations of all sizes encounter with microservices architectures, operating in various distributed environments, and securing all application traffic.
+The world is rapidly changing and evolving, so is the computing networking layer.
+
+The world is rapidly changing and evolving, so is the computing networking layer. Today's network must quickly adapt and ensure communication is encrypted at all times.
+Consul enables organizations to embrace a [zero trust](https://www.hashicorp.com/solutions/zero-trust-security) model while scaling up.
+Consul can achieve all this while reducing the burden on both operators and developers through automation of crucial networking tasks
+
+![Diagram that explains why Consul](/img/intro_why_consul_diagram.png)
+
## Next Steps
- See [how Consul compares to other software](/intro/vs) to assess how it fits into your
existing infrastructure.
- Continue onwards with [HashiCorp Learn](https://learn.hashicorp.com/tutorials/consul/get-started-install)
- to get Consul up and running.
+ to learn more about Consul and how to get Consul up and running.
diff --git a/website/public/img/intro_why_consul_diagram.png b/website/public/img/intro_why_consul_diagram.png
new file mode 100644
index 000000000..773b78e81
--- /dev/null
+++ b/website/public/img/intro_why_consul_diagram.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:647df0e9c29eefa8f94d9c8e60f9ea45f7d9d483b359f78ec4f47db6f08eada2
+size 173342
From 67c8cb98e81a05e4ba15a69bfa07e80f34610ef3 Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Tue, 21 Dec 2021 14:42:42 -0700
Subject: [PATCH 016/225] updated text to why consul
---
website/content/docs/intro/index.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/content/docs/intro/index.mdx b/website/content/docs/intro/index.mdx
index 366a452fe..557e162f5 100644
--- a/website/content/docs/intro/index.mdx
+++ b/website/content/docs/intro/index.mdx
@@ -105,7 +105,7 @@ forward the request to the remote datacenter and return the result.
## Why Consul?
-Consul solves the challenges that organizations of all sizes encounter with microservices architectures, operating in various distributed environments, and securing all application traffic.
+Consul solves the challenges that organizations of all sizes encounter with microservices architectures. This ranges from operating in various distributed environments and geographical locations, to meeting the need of securing all application traffic.
The world is rapidly changing and evolving, so is the computing networking layer.
The world is rapidly changing and evolving, so is the computing networking layer. Today's network must quickly adapt and ensure communication is encrypted at all times.
From 6b2501344a3772858e03f8c2e68fdbaa306948ff Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Tue, 21 Dec 2021 16:45:45 -0500
Subject: [PATCH 017/225] Add changelog
---
.changelog/11781.txt | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 .changelog/11781.txt
diff --git a/.changelog/11781.txt b/.changelog/11781.txt
new file mode 100644
index 000000000..754d9e01b
--- /dev/null
+++ b/.changelog/11781.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+cli: when creating a private key, save the file with mode 0600 so that only the user has read permission.
+```
From d48b8642dc0e35f3c2f4bb6124e18f86891733e1 Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Tue, 21 Dec 2021 15:05:12 -0700
Subject: [PATCH 018/225] using svg instead of png
---
website/content/docs/intro/index.mdx | 21 +++++++++----------
.../public/img/intro_why_consul_diagram.png | 3 ---
.../public/img/intro_why_consul_diagram.svg | 1 +
3 files changed, 11 insertions(+), 14 deletions(-)
delete mode 100644 website/public/img/intro_why_consul_diagram.png
create mode 100644 website/public/img/intro_why_consul_diagram.svg
diff --git a/website/content/docs/intro/index.mdx b/website/content/docs/intro/index.mdx
index 557e162f5..febb4e095 100644
--- a/website/content/docs/intro/index.mdx
+++ b/website/content/docs/intro/index.mdx
@@ -19,6 +19,16 @@ detailed reference of available features. If you're ready to get hands-on
experience, deploy Consul locally with our
[HashiCorp Learn tutorial](https://learn.hashicorp.com/tutorials/consul/get-started-install).
+## Why Consul?
+
+Consul solves the challenges that organizations of all sizes encounter with microservices architectures. This ranges from operating in various distributed environments and geographical locations, to meeting the need of securing all application traffic.
+The world is rapidly changing and evolving, so is the computing networking layer.
+
+Today's network must quickly adapt and ensure communication is encrypted at all times. Consul enables organizations to embrace a [zero trust](https://www.hashicorp.com/solutions/zero-trust-security) model while scaling up.
+Consul can achieve all this while reducing the burden on both operators and developers through automation of crucial networking tasks
+
+![Diagram that explains why Consul](/img/intro_why_consul_diagram.svg)
+
## What is Consul?
Consul is a service mesh solution providing a full featured control plane
@@ -103,17 +113,6 @@ Each datacenter runs a cluster of Consul servers. When a cross-datacenter
service discovery or configuration request is made, the local Consul servers
forward the request to the remote datacenter and return the result.
-## Why Consul?
-
-Consul solves the challenges that organizations of all sizes encounter with microservices architectures. This ranges from operating in various distributed environments and geographical locations, to meeting the need of securing all application traffic.
-The world is rapidly changing and evolving, so is the computing networking layer.
-
-The world is rapidly changing and evolving, so is the computing networking layer. Today's network must quickly adapt and ensure communication is encrypted at all times.
-Consul enables organizations to embrace a [zero trust](https://www.hashicorp.com/solutions/zero-trust-security) model while scaling up.
-Consul can achieve all this while reducing the burden on both operators and developers through automation of crucial networking tasks
-
-![Diagram that explains why Consul](/img/intro_why_consul_diagram.png)
-
## Next Steps
- See [how Consul compares to other software](/intro/vs) to assess how it fits into your
diff --git a/website/public/img/intro_why_consul_diagram.png b/website/public/img/intro_why_consul_diagram.png
deleted file mode 100644
index 773b78e81..000000000
--- a/website/public/img/intro_why_consul_diagram.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:647df0e9c29eefa8f94d9c8e60f9ea45f7d9d483b359f78ec4f47db6f08eada2
-size 173342
diff --git a/website/public/img/intro_why_consul_diagram.svg b/website/public/img/intro_why_consul_diagram.svg
new file mode 100644
index 000000000..35da266b4
--- /dev/null
+++ b/website/public/img/intro_why_consul_diagram.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
From 952bb3c4a27be6f7e09ed0277663385279e78836 Mon Sep 17 00:00:00 2001
From: Blake Covarrubias
Date: Tue, 21 Dec 2021 21:46:44 -0800
Subject: [PATCH 019/225] docs: Fix service_id description on agent deregister
API
---
website/content/api-docs/agent/service.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/content/api-docs/agent/service.mdx b/website/content/api-docs/agent/service.mdx
index 5ecc0d00b..b475b36e4 100644
--- a/website/content/api-docs/agent/service.mdx
+++ b/website/content/api-docs/agent/service.mdx
@@ -769,7 +769,7 @@ The table below shows this endpoint's support for
### Parameters
- `service_id` `(string: )` - Specifies the ID of the service to
- deregister. This is specifi### Parameters
+ deregister. This is specified as part of the URL.
- `ns` `(string: "")` - Specifies the namespace in which
to deregister the service. This value can be specified as the `ns` URL query
From ec6aff8dc0433f4a5194f343e5fb87a9d9e7cc29 Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Wed, 22 Dec 2021 11:18:06 -0800
Subject: [PATCH 020/225] applied feedback
---
...service-to-service-traffic-datacenters.mdx | 75 +++++++++++++++++--
.../service-to-service-traffic-partitions.mdx | 74 +++++++++++++++++-
2 files changed, 140 insertions(+), 9 deletions(-)
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
index f7c153a34..6add2cee0 100644
--- a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.mdx
@@ -95,6 +95,8 @@ Use the following example configurations to help you understand some of the comm
The following `proxy-defaults` configuration will enable gateways for all Connect services in the `local` mode.
+
+
```hcl
Kind = "proxy-defaults"
Name = "global"
@@ -103,9 +105,19 @@ MeshGateway {
}
```
-### Enabling Gateways Per-Service
+```yaml
+Kind: proxy-defaults
+MeshGateway:
+- Mode: local
+Name: global
+```
+
-The following `service-defaults` configuration will enable gateways for all Connect services with the name "web".
+### Enabling Gateways Per Service
+
+The following `service-defaults` configuration will enable gateways for all Connect services with the name `web`.
+
+
```hcl
Kind = "service-defaults"
@@ -115,11 +127,22 @@ MeshGateway {
}
```
+```yaml
+Kind: service-defaults
+MeshGateway:
+- Mode: local
+Name: web
+```
+
+
+
### Enabling Gateways for a Service Instance
The following [Proxy Service Registration](/docs/connect/registration/service-registration)
definition will enable gateways for the service instance in the `remote` mode.
+
+
```hcl
service {
name = "web-sidecar-proxy"
@@ -139,11 +162,9 @@ service {
]
}
}
-```
-Or alternatively inline with the service definition:
+# Or alternatively inline with the service definition:
-```hcl
service {
name = "web"
port = 8181
@@ -166,10 +187,28 @@ service {
}
```
+```yaml
+service:
+- kind: connect-proxy
+ name: web-sidecar-proxy
+ port: 8181
+ proxy:
+ - destination_service_name: web
+ mesh_gateway:
+ - mode: remote
+ upstreams:
+ - datacenter: secondary
+ destination_name: api
+ local_bind_port: 100
+```
+
+
+
### Enabling Gateways for a Proxy Upstream
-The following service definition will enable gateways in the `local` mode for one upstream, the `remote` mode
-for a second upstream and will disable gateways for a third upstream.
+The following service definition will enable gateways in the `local` mode for one upstream, the `remote` mode for a second upstream and will disable gateways for a third upstream.
+
+
```hcl
service {
@@ -204,3 +243,25 @@ service {
}
}
```
+```yaml
+service:
+- kind: connect-proxy
+ name: web-sidecar-proxy
+ port: 8181
+ proxy:
+ - destination_service_name: web
+ upstreams:
+ - destination_name: api
+ local_bind_port: 10000
+ mesh_gateway:
+ - mode: remote
+ - destination_name: db
+ local_bind_port: 10001
+ mesh_gateway:
+ - mode: local
+ - destination_name: logging
+ local_bind_port: 10002
+ mesh_gateway:
+ - mode: none
+ ```
+
\ No newline at end of file
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
index 2a0b91751..0191c8b19 100644
--- a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
@@ -79,6 +79,8 @@ Use the following example configurations to help you understand some of the comm
The following `proxy-defaults` configuration will enable gateways for all Connect services in the `local` mode.
+
+
```hcl
Kind = "proxy-defaults"
Name = "global"
@@ -86,11 +88,20 @@ MeshGateway {
Mode = "local"
}
```
+```yaml
+Kind: proxy-defaults
+MeshGateway:
+- Mode: local
+Name: global
+```
-### Enabling Gateways Per-Service
+
+
+### Enabling Gateways Per Service
The following `service-defaults` configuration will enable gateways for all Connect services with the name `web`.
+
```hcl
Kind = "service-defaults"
Name = "web"
@@ -99,11 +110,21 @@ MeshGateway {
}
```
+```yaml
+Kind: service-defaults
+MeshGateway:
+- Mode: local
+Name: web
+```
+
+
### Enabling Gateways for a Service Instance
The following [Proxy Service Registration](/docs/connect/registration/service-registration)
definition will enable gateways for `web` service instances in the `finance` partition.
+
+
```hcl
service {
name = "web-sidecar-proxy"
@@ -127,10 +148,30 @@ service {
}
```
+```yaml
+service:
+- kind: connect-proxy
+ name: web-sidecar-proxy
+ port: 8181
+ proxy:
+ - destination_service_name: web
+ mesh_gateway:
+ - mode: local
+ upstreams:
+ - destination_name: billing
+ destination_namespace: default
+ destination_partition: finance
+ destination_type: service
+ local_bind_port: 9090
+```
+
+
### Enabling Gateways for a Proxy Upstream
The following service definition will enable gateways in `local` mode for three different partitions. Note that each service exists in the same namepace, but are separated by admin partition.
+
+
```hcl
service {
name = "web-sidecar-proxy"
@@ -169,4 +210,33 @@ service {
]
}
}
-```
\ No newline at end of file
+```
+
+```yaml
+service:
+- kind: connect-proxy
+ name: web-sidecar-proxy
+ port: 8181
+ proxy:
+ - destination_service_name: web
+ upstreams:
+ - destination_name: api
+ destination_namespace: dev
+ destination_partition: api
+ local_bind_port: 10000
+ mesh_gateway:
+ - mode: local
+ - destination_name: db
+ destination_namespace: dev
+ destination_partition: db
+ local_bind_port: 10001
+ mesh_gateway:
+ - mode: local
+ - destination_name: logging
+ destination_namespace: dev
+ destination_partition: logging
+ local_bind_port: 10002
+ mesh_gateway:
+ - mode: local
+```
+
\ No newline at end of file
From ca41ee4484dee3a47fcc8c35b201801d25291b1f Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Wed, 22 Dec 2021 11:40:26 -0800
Subject: [PATCH 021/225] fixed bad md syntax
---
.../mesh-gateway/service-to-service-traffic-partitions.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
index 0191c8b19..bc529496f 100644
--- a/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
+++ b/website/content/docs/connect/gateways/mesh-gateway/service-to-service-traffic-partitions.mdx
@@ -88,6 +88,7 @@ MeshGateway {
Mode = "local"
}
```
+
```yaml
Kind: proxy-defaults
MeshGateway:
@@ -102,6 +103,7 @@ Name: global
The following `service-defaults` configuration will enable gateways for all Connect services with the name `web`.
+
```hcl
Kind = "service-defaults"
Name = "web"
From ff54cc651b427e2b2dab7ccaff54d193528e889e Mon Sep 17 00:00:00 2001
From: Noel Quiles <3746694+EnMod@users.noreply.github.com>
Date: Wed, 22 Dec 2021 15:04:39 -0500
Subject: [PATCH 022/225] website: Upgrade & (#11894)
* Update @hashicorp/react-subnav
* Upgrade to latest/upgrade product-downloads-page
---
website/package-lock.json | 28 ++++++++++++++--------------
website/package.json | 4 ++--
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/website/package-lock.json b/website/package-lock.json
index 57bef68fc..c49355f4d 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -34,12 +34,12 @@
"@hashicorp/react-inline-svg": "^6.0.3",
"@hashicorp/react-learn-callout": "^2.0.1",
"@hashicorp/react-markdown-page": "^1.4.3",
- "@hashicorp/react-product-downloads-page": "^2.5.2",
+ "@hashicorp/react-product-downloads-page": "^2.5.3",
"@hashicorp/react-product-features-list": "^5.0.0",
"@hashicorp/react-search": "^6.1.1",
"@hashicorp/react-section-header": "^5.0.4",
"@hashicorp/react-stepped-feature-list": "^4.0.3",
- "@hashicorp/react-subnav": "^9.3.0",
+ "@hashicorp/react-subnav": "^9.3.2",
"@hashicorp/react-tabs": "^7.0.1",
"@hashicorp/react-text-split": "^4.0.0",
"@hashicorp/react-text-split-with-code": "^3.3.8",
@@ -1983,9 +1983,9 @@
}
},
"node_modules/@hashicorp/react-product-downloads-page": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/@hashicorp/react-product-downloads-page/-/react-product-downloads-page-2.5.2.tgz",
- "integrity": "sha512-F/3rHGbd+aSbYGMw9HtYtE3PbIPgyXuTEzEkeeRVHU/2CfxzW0rYADgZFCHbV82TYNG/Z7Pr0wTnmmIus4jyww==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@hashicorp/react-product-downloads-page/-/react-product-downloads-page-2.5.3.tgz",
+ "integrity": "sha512-SY3sEM/xYZDbd7XSDaqkT4L+DVRdGJYPpF/0WRDHfR0PObf2zE+iqRjm2APaIACg32sAM1NIZPuc+oQv6vKq5A==",
"dependencies": {
"@hashicorp/platform-product-meta": "^0.1.0",
"@hashicorp/react-button": "^6.0.0",
@@ -2086,9 +2086,9 @@
}
},
"node_modules/@hashicorp/react-subnav": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hashicorp/react-subnav/-/react-subnav-9.3.0.tgz",
- "integrity": "sha512-AjqtseK82RMeb8/9bhOJ11JJ5AVUi9eNf7d93DsJtLGggva5yN/BC6RTnGLgTvev7JqiYJa0LDoRExtb27Ttrw==",
+ "version": "9.3.2",
+ "resolved": "https://registry.npmjs.org/@hashicorp/react-subnav/-/react-subnav-9.3.2.tgz",
+ "integrity": "sha512-UoMnQgV/KnqNX/bwKKsnw5ph4egJhQPFHwrnplRlBuRMlHgblMMP5jsPi/07wkpIv4iyV0yc1ttaFN4RPVTa5w==",
"dependencies": {
"@hashicorp/mktg-logos": "^1.0.2",
"@hashicorp/platform-product-meta": "^0.1.0",
@@ -21459,9 +21459,9 @@
"requires": {}
},
"@hashicorp/react-product-downloads-page": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/@hashicorp/react-product-downloads-page/-/react-product-downloads-page-2.5.2.tgz",
- "integrity": "sha512-F/3rHGbd+aSbYGMw9HtYtE3PbIPgyXuTEzEkeeRVHU/2CfxzW0rYADgZFCHbV82TYNG/Z7Pr0wTnmmIus4jyww==",
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/@hashicorp/react-product-downloads-page/-/react-product-downloads-page-2.5.3.tgz",
+ "integrity": "sha512-SY3sEM/xYZDbd7XSDaqkT4L+DVRdGJYPpF/0WRDHfR0PObf2zE+iqRjm2APaIACg32sAM1NIZPuc+oQv6vKq5A==",
"requires": {
"@hashicorp/platform-product-meta": "^0.1.0",
"@hashicorp/react-button": "^6.0.0",
@@ -21538,9 +21538,9 @@
}
},
"@hashicorp/react-subnav": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@hashicorp/react-subnav/-/react-subnav-9.3.0.tgz",
- "integrity": "sha512-AjqtseK82RMeb8/9bhOJ11JJ5AVUi9eNf7d93DsJtLGggva5yN/BC6RTnGLgTvev7JqiYJa0LDoRExtb27Ttrw==",
+ "version": "9.3.2",
+ "resolved": "https://registry.npmjs.org/@hashicorp/react-subnav/-/react-subnav-9.3.2.tgz",
+ "integrity": "sha512-UoMnQgV/KnqNX/bwKKsnw5ph4egJhQPFHwrnplRlBuRMlHgblMMP5jsPi/07wkpIv4iyV0yc1ttaFN4RPVTa5w==",
"requires": {
"@hashicorp/mktg-logos": "^1.0.2",
"@hashicorp/platform-product-meta": "^0.1.0",
diff --git a/website/package.json b/website/package.json
index e0617040b..93b687950 100644
--- a/website/package.json
+++ b/website/package.json
@@ -30,12 +30,12 @@
"@hashicorp/react-inline-svg": "^6.0.3",
"@hashicorp/react-learn-callout": "^2.0.1",
"@hashicorp/react-markdown-page": "^1.4.3",
- "@hashicorp/react-product-downloads-page": "^2.5.2",
+ "@hashicorp/react-product-downloads-page": "^2.5.3",
"@hashicorp/react-product-features-list": "^5.0.0",
"@hashicorp/react-search": "^6.1.1",
"@hashicorp/react-section-header": "^5.0.4",
"@hashicorp/react-stepped-feature-list": "^4.0.3",
- "@hashicorp/react-subnav": "^9.3.0",
+ "@hashicorp/react-subnav": "^9.3.2",
"@hashicorp/react-tabs": "^7.0.1",
"@hashicorp/react-text-split": "^4.0.0",
"@hashicorp/react-text-split-with-code": "^3.3.8",
From 6f9592107405aa2fd90b129073163c55e5a8a70b Mon Sep 17 00:00:00 2001
From: trujillo-adam <47586768+trujillo-adam@users.noreply.github.com>
Date: Wed, 22 Dec 2021 12:04:45 -0800
Subject: [PATCH 023/225] Apply suggestions from code review
applied review feedback
Co-authored-by: mrspanishviking
Co-authored-by: Freddy
---
website/content/docs/security/acl/acl-system.mdx | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/website/content/docs/security/acl/acl-system.mdx b/website/content/docs/security/acl/acl-system.mdx
index 7de5783a2..8f951d004 100644
--- a/website/content/docs/security/acl/acl-system.mdx
+++ b/website/content/docs/security/acl/acl-system.mdx
@@ -69,7 +69,7 @@ If the ACL system becomes inoperable, you can follow the
### ACL Policies
-An ACL policy (not to be confused with [policy dispositions](/docs/security/acl/acl-rules#policy-dispositions)) is a named set of rules and several attributes that define the policy domain. The ID is generated when policy is created, but you can specify the attributes when creating the policy. Refer to the [ACL policy command line](https://www.consul.io/commands/acl/policy) documentation or [ACL policy API](/api-docs/acl/policies) documentation for additional information on how to create policies.
+An ACL policy (not to be confused with [policy dispositions](/docs/security/acl/acl-rules#policy-dispositions)) is a named set of rules and several attributes that define the policy domain. The ID is generated when the policy is created, but you can specify the attributes when creating the policy. Refer to the [ACL policy command line](https://www.consul.io/commands/acl/policy) documentation or [ACL policy API](/api-docs/acl/policies) documentation for additional information on how to create policies.
ACL policies can have the following attributes:
@@ -215,11 +215,11 @@ of the following elements:
- **Service Identity Set** - The list of service identities that are applicable for the role.
- **Namespace** - The namespace this policy resides within. (Added in Consul Enterprise 1.7.0)
--> **Linking Roles to Policies in Consul Enterprise** - Roles can only be linked to policies that are defined in the same namespace or admin partition.
+-> **Linking Roles to Policies in Consul Enterprise** - Roles can only be linked to policies that are defined in the same namespace and admin partition.
### ACL Tokens
-Consul uses ACL tokens to determine if the caller is authorized to perform an action. An ACL token is composed of several attributes that you can specify when creating the token. Refer to the [ACL token command line](https://www.consul.io/commands/acl/token) documentation or [ACL token API](/api-docs/acl/tokens) documentation for additional information on how to create policies.:
+Consul uses ACL tokens to determine if the caller is authorized to perform an action. An ACL token is composed of several attributes that you can specify when creating the token. Refer to the [ACL token command line](https://www.consul.io/commands/acl/token) documentation or [ACL token API](/api-docs/acl/tokens) documentation for additional information on how to create tokens.:
- **Accessor ID** - The token's public identifier.
- **Secret ID** -The bearer token used when making requests to Consul.
@@ -229,10 +229,10 @@ Consul uses ACL tokens to determine if the caller is authorized to perform an ac
- **Local** - Indicates whether the token is local to the datacenter in which it was created. The attribute also can specify if the token was created in the primary datacenter and globally replicated.
- **CreateTime** - Timestamp indicating when the token was created.
- **Expiration Time** - The time at which this token is revoked. This attribute is option when creating a token. Added in Consul 1.5.0.
-- **Namespace** - The namespace in which the policy resides. Added in Consul Enterprise 1.7.0.
-- **Partition** - The partition in which the policy resides. Added in Consul Enterprise 1.11.0.
+- **Namespace** - The namespace in which the token resides. Added in Consul Enterprise 1.7.0.
+- **Partition** - The partition in which the token resides. Added in Consul Enterprise 1.11.0.
--> **Linking Tokens to Policies in Consul Enterprise** - Tokens can only be linked to policies that are defined in the same namespace or admin partition.
+-> **Linking Tokens to Policies in Consul Enterprise** - Tokens can only be linked to policies that are defined in the same namespace and admin partition.
You can view the current ACL tokens on the command line or through the API. The following example demonstrates the command line usage:
From 5e6c934135a526e463106f51f55bd0253b5cda6d Mon Sep 17 00:00:00 2001
From: saurabh-sp-tripathi
Date: Wed, 22 Dec 2021 15:32:32 -0600
Subject: [PATCH 024/225] Fix typo, Layer 7 is application layer not network
---
website/content/docs/connect/intentions.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/content/docs/connect/intentions.mdx b/website/content/docs/connect/intentions.mdx
index a6e90523f..3fa7c6023 100644
--- a/website/content/docs/connect/intentions.mdx
+++ b/website/content/docs/connect/intentions.mdx
@@ -22,7 +22,7 @@ application](/docs/connect/native).
Depending upon the [protocol] in use by the destination service, you can define
intentions to control Connect traffic authorization either at networking layer
-4 (e.g. TCP) and networking layer 7 (e.g. HTTP):
+4 (e.g. TCP) and application layer 7 (e.g. HTTP):
- **Identity-based** - All intentions may enforce access based on identities
encoded within [TLS
From d85d16a0c93f382d1a2e564a4c2282aa825c826c Mon Sep 17 00:00:00 2001
From: "Chris S. Kim"
Date: Thu, 23 Dec 2021 19:00:02 -0500
Subject: [PATCH 025/225] Fix integration test with updated file perms (#11916)
---
test/integration/connect/envoy/case-wanfed-gw/global-setup.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh b/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh
index f9ada15a4..fee985add 100755
--- a/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh
+++ b/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh
@@ -37,4 +37,8 @@ for f in \
docker cp "${container}:/out/$f" workdir/secondary/tls
done
+# Private keys have 600 perms but tests are run as another user
+chmod 666 workdir/primary/tls/primary-server-consul-0-key.pem
+chmod 666 workdir/secondary/tls/secondary-server-consul-0-key.pem
+
docker rm -f "$container" >/dev/null || true
From c2342a343b27b713ce3b8d30f1b14256413d0a7f Mon Sep 17 00:00:00 2001
From: Jeff Escalante
Date: Fri, 24 Dec 2021 14:53:07 -0500
Subject: [PATCH 026/225] add enterprise downloads page (#10550)
* add enterprise downloads page
* remove beta block
* clean up prop repetition, add hcp callout
* move around external props pattern
* add legal notice to ent page
---
package-lock.json | 217 -------------------
website/components/downloads-props/index.jsx | 92 ++++++++
website/package-lock.json | 75 ++++++-
website/pages/downloads/enterprise.jsx | 38 ++++
website/pages/downloads/index.jsx | 73 +------
website/pages/downloads/style.module.css | 32 +++
6 files changed, 236 insertions(+), 291 deletions(-)
delete mode 100644 package-lock.json
create mode 100644 website/components/downloads-props/index.jsx
create mode 100644 website/pages/downloads/enterprise.jsx
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index b7ef8bc2b..000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,217 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "@algolia/cache-browser-local-storage": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.3.0.tgz",
- "integrity": "sha512-91Cf3IPUk84PF2wvR8ys8XO42FqaJEtIh/dyR0WvwMdv0x13GORkAvoBJgkFI2wofZqUY86jNimvHWfsWzPQ+g==",
- "requires": {
- "@algolia/cache-common": "4.3.0"
- }
- },
- "@algolia/cache-common": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.3.0.tgz",
- "integrity": "sha512-AHTbOn9lk0f5IkjssXXmDgnaZfsUJVZ61sqOH1W3LyJdAscDzCj0KtwijELn8FHlLXQak7+K93/O3Oct0uHncQ=="
- },
- "@algolia/cache-in-memory": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.3.0.tgz",
- "integrity": "sha512-8BZS5IFEtiSFkA6vNQUXJXIWABDbSanQdkGX5LArlhbCjuykZqF68yaCjXWG10EZTySnkZLmKc+5ozYVOktJaQ==",
- "requires": {
- "@algolia/cache-common": "4.3.0"
- }
- },
- "@algolia/client-account": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.3.0.tgz",
- "integrity": "sha512-8LJSvWooc+fe+XZXeu+h4dhpo9lsu3sb7rV9cpPhymYSHgEJAHaDkZEcPM1u/PBMvFe0mZXaW6nabeb3jeIRcw==",
- "requires": {
- "@algolia/client-common": "4.3.0",
- "@algolia/client-search": "4.3.0",
- "@algolia/transporter": "4.3.0"
- }
- },
- "@algolia/client-analytics": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.3.0.tgz",
- "integrity": "sha512-BFH4ddyrqI2pE3bUctn5KtJgYqgvO0Ap9vJEHBNj6mjSKqFbTnZeVEPG3yWrOuWRCqPHR3ewcWRisNwJHG3+Mw==",
- "requires": {
- "@algolia/client-common": "4.3.0",
- "@algolia/client-search": "4.3.0",
- "@algolia/requester-common": "4.3.0",
- "@algolia/transporter": "4.3.0"
- }
- },
- "@algolia/client-common": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.3.0.tgz",
- "integrity": "sha512-8Ohj6zXZkpwDKc8ZWVTZo2wPO4+LT5D258suGg/C6nh4UxOrFOp6QaqeQo8JZ1eqMqtfb3zv5SHgW4fZ00NCLQ==",
- "requires": {
- "@algolia/requester-common": "4.3.0",
- "@algolia/transporter": "4.3.0"
- }
- },
- "@algolia/client-recommendation": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/client-recommendation/-/client-recommendation-4.3.0.tgz",
- "integrity": "sha512-jCMIAWPA2hsxc5CCtoTtQAcohaG+10CxXK122Tc47t4w1K8qzSJnCjC2cHvM4UNJO+k7NrmjOYW0EXp9RKc7SQ==",
- "requires": {
- "@algolia/client-common": "4.3.0",
- "@algolia/requester-common": "4.3.0",
- "@algolia/transporter": "4.3.0"
- }
- },
- "@algolia/client-search": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.3.0.tgz",
- "integrity": "sha512-KCgcIsNMW1/0F5OILiFTddbTAKduJHRvXQS4NxY1H9gQWMTVeWJS7VZQ/ukKBiUMLatwUQHJz2qpYm9fmqOjkQ==",
- "requires": {
- "@algolia/client-common": "4.3.0",
- "@algolia/requester-common": "4.3.0",
- "@algolia/transporter": "4.3.0"
- }
- },
- "@algolia/logger-common": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.3.0.tgz",
- "integrity": "sha512-vQ+aukjZkRAyO9iyINBefT366UtF/B9QoA1Kw8PlY67T6fYmklFgYp3LNH/e7h/gz0py5LYY/HIwSsaTKk8/VQ=="
- },
- "@algolia/logger-console": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.3.0.tgz",
- "integrity": "sha512-7pWtcv1cSSa7F48gRBOZLcEWN073+WbnKjbpRrIGej+abZppw/h+22jtVZZORC8EIjFffGqz2/2e6bZiX+Jg7A==",
- "requires": {
- "@algolia/logger-common": "4.3.0"
- }
- },
- "@algolia/requester-browser-xhr": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.3.0.tgz",
- "integrity": "sha512-CpUwgQhXZsnZmjEd5DTwQv1BKQNCt83bzyVdUqvljsFxZOsNQacS6lOYs0B1eD18tKHCwVMuwbYqTaLPGBXTKQ==",
- "requires": {
- "@algolia/requester-common": "4.3.0"
- }
- },
- "@algolia/requester-common": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.3.0.tgz",
- "integrity": "sha512-1v73KyspJBiTzfyXupjHxikxTYjh5MoxI6mOIvAtQxRqc4ehUPAEdPCNHEvvLiCK96iKWzZaULmV0U7pj3yvTw=="
- },
- "@algolia/requester-node-http": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.3.0.tgz",
- "integrity": "sha512-Hg9Y8sUeSGQgoO1FpoL5jbkDzCtXI/8HXHybU6bimsX93DAz3HZWaoQFKmIpQDNhQ8G9FLgAtzDAxS6eckDxzg==",
- "requires": {
- "@algolia/requester-common": "4.3.0"
- }
- },
- "@algolia/transporter": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.3.0.tgz",
- "integrity": "sha512-BTKHAtdQdfOJ0xzZkiyEK/2QVQJTiVgBZlOBfXp2gBtztjV26OqfW4n6Xz0o7eBRzLEwY1ot3mHF5QIVUjAsMg==",
- "requires": {
- "@algolia/cache-common": "4.3.0",
- "@algolia/logger-common": "4.3.0",
- "@algolia/requester-common": "4.3.0"
- }
- },
- "algoliasearch": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.3.0.tgz",
- "integrity": "sha512-H2woXyqmd1nFYDrQKLZXgghNkLBTcBXJ7Q/bxQ+F9WWS4H0Kb7IlQvNi7bDzHyldhDhIthImaUwcKqr5iiyMFQ==",
- "requires": {
- "@algolia/cache-browser-local-storage": "4.3.0",
- "@algolia/cache-common": "4.3.0",
- "@algolia/cache-in-memory": "4.3.0",
- "@algolia/client-account": "4.3.0",
- "@algolia/client-analytics": "4.3.0",
- "@algolia/client-common": "4.3.0",
- "@algolia/client-recommendation": "4.3.0",
- "@algolia/client-search": "4.3.0",
- "@algolia/logger-common": "4.3.0",
- "@algolia/logger-console": "4.3.0",
- "@algolia/requester-browser-xhr": "4.3.0",
- "@algolia/requester-common": "4.3.0",
- "@algolia/requester-node-http": "4.3.0",
- "@algolia/transporter": "4.3.0"
- }
- },
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "requires": {
- "sprintf-js": "~1.0.2"
- }
- },
- "dotenv": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
- "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
- },
- "esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "gray-matter": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.2.tgz",
- "integrity": "sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw==",
- "requires": {
- "js-yaml": "^3.11.0",
- "kind-of": "^6.0.2",
- "section-matter": "^1.0.0",
- "strip-bom-string": "^1.0.0"
- }
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
- },
- "js-yaml": {
- "version": "3.14.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
- "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
- },
- "kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
- },
- "section-matter": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
- "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==",
- "requires": {
- "extend-shallow": "^2.0.1",
- "kind-of": "^6.0.0"
- }
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
- },
- "strip-bom-string": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
- "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI="
- }
- }
-}
diff --git a/website/components/downloads-props/index.jsx b/website/components/downloads-props/index.jsx
new file mode 100644
index 000000000..eda0fbbec
--- /dev/null
+++ b/website/components/downloads-props/index.jsx
@@ -0,0 +1,92 @@
+import Button from '@hashicorp/react-button'
+import s from '../../pages/downloads/style.module.css'
+
+export default function DownloadsProps(preMerchandisingSlot) {
+ return {
+ getStartedDescription:
+ 'Follow step-by-step tutorials on the essentials of Consul.',
+ getStartedLinks: [
+ {
+ label: 'CLI Quickstart',
+ href: 'https://learn.hashicorp.com/collections/consul/getting-started',
+ },
+ {
+ label: 'HCP Consul',
+ href:
+ 'https://learn.hashicorp.com/collections/consul/cloud-get-started',
+ },
+ {
+ label: 'HCS on Azure',
+ href: 'https://learn.hashicorp.com/collections/consul/hcs-azure',
+ },
+ {
+ label: 'Kubernetes Quickstart',
+ href:
+ 'https: //learn.hashicorp.com/collections/consul/gs-consul-service-mesh',
+ },
+ {
+ label: 'View all Consul tutorials',
+ href: 'https://learn.hashicorp.com/consul',
+ },
+ ],
+ tutorialLink: {
+ href: 'https://learn.hashicorp.com/consul',
+ label: 'View Tutorials at HashiCorp Learn',
+ },
+ logo: (
+
+ ),
+ merchandisingSlot: (
+ <>
+ {preMerchandisingSlot && preMerchandisingSlot}
+
+
+
+ Looking for a way to secure and automate application networking
+ without the added complexity of managing the infrastructure?
+
- >
- }
- {...staticProps}
- />
- )
+ return
}
export async function getStaticProps() {
diff --git a/website/pages/downloads/style.module.css b/website/pages/downloads/style.module.css
index 0503dac9b..9a2958923 100644
--- a/website/pages/downloads/style.module.css
+++ b/website/pages/downloads/style.module.css
@@ -20,3 +20,35 @@
margin-bottom: 0;
}
}
+
+.merchandisingSlot {
+ width: 100%;
+ border: 1px solid var(--gray-6);
+ padding: 16px;
+ display: flex;
+ justify-content: center;
+ margin-bottom: 58px;
+
+ & .centerWrapper {
+ display: flex;
+ align-items: center;
+
+ & p {
+ margin: 0;
+ max-width: 490px;
+ margin-right: 26px;
+ }
+
+ @media (max-width: 800px) {
+ flex-direction: column;
+ & p {
+ text-align: center;
+ margin-bottom: 12px;
+ }
+ }
+ }
+}
+
+.legalNotice {
+ margin-bottom: 60px;
+}
From b36538962e33cb347e18913655c0213b29509f58 Mon Sep 17 00:00:00 2001
From: Artem Kozlenkov <37898216+artemkozlenkov@users.noreply.github.com>
Date: Mon, 27 Dec 2021 17:50:49 +0100
Subject: [PATCH 027/225] Update install.mdx
add port-forwad missing namespace flag
---
website/content/docs/k8s/installation/install.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/content/docs/k8s/installation/install.mdx b/website/content/docs/k8s/installation/install.mdx
index 7d08773cf..71dd57ab9 100644
--- a/website/content/docs/k8s/installation/install.mdx
+++ b/website/content/docs/k8s/installation/install.mdx
@@ -191,7 +191,7 @@ use `kubectl port-forward` to visit the UI.
If running with TLS disabled, the Consul UI will be accessible via http on port 8500:
```shell-session
-$ kubectl port-forward service/consul-server 8500:8500
+$ kubectl port-forward service/consul-server -n consul 8500:8500
...
```
From 039cddf9fbf2209e0cadb5da500d010e72fb78f0 Mon Sep 17 00:00:00 2001
From: Artem Kozlenkov <37898216+artemkozlenkov@users.noreply.github.com>
Date: Mon, 27 Dec 2021 17:54:35 +0100
Subject: [PATCH 028/225] add the missing `-n consul` namespace to `k pf ..`
---
website/content/docs/k8s/installation/install.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/content/docs/k8s/installation/install.mdx b/website/content/docs/k8s/installation/install.mdx
index 71dd57ab9..09577c4e2 100644
--- a/website/content/docs/k8s/installation/install.mdx
+++ b/website/content/docs/k8s/installation/install.mdx
@@ -202,7 +202,7 @@ Once the port is forwarded navigate to [http://localhost:8500](http://localhost:
If running with TLS enabled, the Consul UI will be accessible via https on port 8501:
```shell-session
-$ kubectl port-forward service/consul-server 8501:8501
+$ kubectl port-forward service/consul-server -n consul 8501:8501
...
```
From 7d1f2157eb29ea3c9ec0cc49f728651b61b80b9d Mon Sep 17 00:00:00 2001
From: littlestar642
Date: Sat, 16 Oct 2021 00:35:58 +0530
Subject: [PATCH 029/225] add path escape and unescape to path params
---
.changelog/11335.txt | 3 ++
agent/agent_endpoint.go | 83 +++++++++++++++++++++++++++++++++--------
agent/http.go | 12 ++++++
agent/http_test.go | 39 +++++++++++++++++++
api/agent.go | 24 ++++++------
5 files changed, 134 insertions(+), 27 deletions(-)
create mode 100644 .changelog/11335.txt
diff --git a/.changelog/11335.txt b/.changelog/11335.txt
new file mode 100644
index 000000000..26253e038
--- /dev/null
+++ b/.changelog/11335.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+api: URL-encode/decode resource names for v1/agent endpoints in API
+```
\ No newline at end of file
diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go
index 463ba87ce..d4becc95e 100644
--- a/agent/agent_endpoint.go
+++ b/agent/agent_endpoint.go
@@ -380,7 +380,10 @@ func (s *HTTPHandlers) AgentServices(resp http.ResponseWriter, req *http.Request
// blocking watch using hash-based blocking.
func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// Get the proxy ID. Note that this is the ID of a proxy's service instance.
- id := strings.TrimPrefix(req.URL.Path, "/v1/agent/service/")
+ id, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/service/")
+ if err != nil {
+ return nil, err
+ }
// Maybe block
var queryOpts structs.QueryOptions
@@ -400,7 +403,7 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
}
// need to resolve to default the meta
- _, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, nil)
+ _, err = s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, nil)
if err != nil {
return nil, err
}
@@ -641,7 +644,10 @@ func (s *HTTPHandlers) AgentJoin(resp http.ResponseWriter, req *http.Request) (i
}
// Get the address
- addr := strings.TrimPrefix(req.URL.Path, "/v1/agent/join/")
+ addr, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/join/")
+ if err != nil {
+ return nil, err
+ }
if wan {
if s.agent.config.ConnectMeshGatewayWANFederationEnabled {
@@ -701,7 +707,10 @@ func (s *HTTPHandlers) AgentForceLeave(resp http.ResponseWriter, req *http.Reque
// Check if the WAN is being queried
_, wan := req.URL.Query()["wan"]
- addr := strings.TrimPrefix(req.URL.Path, "/v1/agent/force-leave/")
+ addr, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/force-leave/")
+ if err != nil {
+ return nil, err
+ }
if wan {
return nil, s.agent.ForceLeaveWAN(addr, prune, entMeta)
} else {
@@ -788,7 +797,11 @@ func (s *HTTPHandlers) AgentRegisterCheck(resp http.ResponseWriter, req *http.Re
}
func (s *HTTPHandlers) AgentDeregisterCheck(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- checkID := structs.NewCheckID(types.CheckID(strings.TrimPrefix(req.URL.Path, "/v1/agent/check/deregister/")), nil)
+ ID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/check/deregister/")
+ if err != nil {
+ return nil, err
+ }
+ checkID := structs.NewCheckID(types.CheckID(ID), nil)
// Get the provided token, if any, and vet against any ACL policies.
var token string
@@ -822,13 +835,21 @@ func (s *HTTPHandlers) AgentDeregisterCheck(resp http.ResponseWriter, req *http.
}
func (s *HTTPHandlers) AgentCheckPass(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- checkID := types.CheckID(strings.TrimPrefix(req.URL.Path, "/v1/agent/check/pass/"))
+ ID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/check/pass/")
+ if err != nil {
+ return nil, err
+ }
+ checkID := types.CheckID(ID)
note := req.URL.Query().Get("note")
return s.agentCheckUpdate(resp, req, checkID, api.HealthPassing, note)
}
func (s *HTTPHandlers) AgentCheckWarn(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- checkID := types.CheckID(strings.TrimPrefix(req.URL.Path, "/v1/agent/check/warn/"))
+ ID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/check/warn/")
+ if err != nil {
+ return nil, err
+ }
+ checkID := types.CheckID(ID)
note := req.URL.Query().Get("note")
return s.agentCheckUpdate(resp, req, checkID, api.HealthWarning, note)
@@ -836,7 +857,11 @@ func (s *HTTPHandlers) AgentCheckWarn(resp http.ResponseWriter, req *http.Reques
}
func (s *HTTPHandlers) AgentCheckFail(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- checkID := types.CheckID(strings.TrimPrefix(req.URL.Path, "/v1/agent/check/fail/"))
+ ID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/check/fail/")
+ if err != nil {
+ return nil, err
+ }
+ checkID := types.CheckID(ID)
note := req.URL.Query().Get("note")
return s.agentCheckUpdate(resp, req, checkID, api.HealthCritical, note)
@@ -875,7 +900,12 @@ func (s *HTTPHandlers) AgentCheckUpdate(resp http.ResponseWriter, req *http.Requ
return nil, nil
}
- checkID := types.CheckID(strings.TrimPrefix(req.URL.Path, "/v1/agent/check/update/"))
+ ID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/check/update/")
+ if err != nil {
+ return nil, err
+ }
+
+ checkID := types.CheckID(ID)
return s.agentCheckUpdate(resp, req, checkID, update.Status, update.Output)
}
@@ -958,7 +988,10 @@ func returnTextPlain(req *http.Request) bool {
// AgentHealthServiceByID return the local Service Health given its ID
func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// Pull out the service id (service id since there may be several instance of the same service on this host)
- serviceID := strings.TrimPrefix(req.URL.Path, "/v1/agent/health/service/id/")
+ serviceID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/health/service/id/")
+ if err != nil {
+ return nil, err
+ }
if serviceID == "" {
return nil, &BadRequestError{Reason: "Missing serviceID"}
}
@@ -1017,7 +1050,11 @@ func (s *HTTPHandlers) AgentHealthServiceByID(resp http.ResponseWriter, req *htt
// AgentHealthServiceByName return the worse status of all the services with given name on an agent
func (s *HTTPHandlers) AgentHealthServiceByName(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// Pull out the service name
- serviceName := strings.TrimPrefix(req.URL.Path, "/v1/agent/health/service/name/")
+ serviceName, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/health/service/name/")
+ if err != nil {
+ return nil, err
+ }
+
if serviceName == "" {
return nil, &BadRequestError{Reason: "Missing service Name"}
}
@@ -1247,7 +1284,12 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http.
}
func (s *HTTPHandlers) AgentDeregisterService(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- sid := structs.NewServiceID(strings.TrimPrefix(req.URL.Path, "/v1/agent/service/deregister/"), nil)
+ serviceID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/service/deregister/")
+ if err != nil {
+ return nil, err
+ }
+
+ sid := structs.NewServiceID(serviceID, nil)
// Get the provided token, if any, and vet against any ACL policies.
var token string
@@ -1283,7 +1325,12 @@ func (s *HTTPHandlers) AgentDeregisterService(resp http.ResponseWriter, req *htt
func (s *HTTPHandlers) AgentServiceMaintenance(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// Ensure we have a service ID
- sid := structs.NewServiceID(strings.TrimPrefix(req.URL.Path, "/v1/agent/service/maintenance/"), nil)
+ serviceID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/service/maintenance/")
+ if err != nil {
+ return nil, err
+ }
+
+ sid := structs.NewServiceID(serviceID, nil)
if sid.ID == "" {
resp.WriteHeader(http.StatusBadRequest)
@@ -1496,7 +1543,10 @@ func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) (
}
// Figure out the target token.
- target := strings.TrimPrefix(req.URL.Path, "/v1/agent/token/")
+ target, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/token/")
+ if err != nil {
+ return nil, err
+ }
err = s.agent.tokens.WithPersistenceLock(func() error {
triggerAntiEntropySync := false
@@ -1569,7 +1619,10 @@ func (s *HTTPHandlers) AgentConnectCARoots(resp http.ResponseWriter, req *http.R
func (s *HTTPHandlers) AgentConnectCALeafCert(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
// Get the service name. Note that this is the name of the service,
// not the ID of the service instance.
- serviceName := strings.TrimPrefix(req.URL.Path, "/v1/agent/connect/ca/leaf/")
+ serviceName, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/connect/ca/leaf/")
+ if err != nil {
+ return nil, err
+ }
args := cachetype.ConnectCALeafRequest{
Service: serviceName, // Need name not ID
diff --git a/agent/http.go b/agent/http.go
index a1d8461d0..cf63c4e42 100644
--- a/agent/http.go
+++ b/agent/http.go
@@ -1120,3 +1120,15 @@ func (s *HTTPHandlers) parseFilter(req *http.Request, filter *string) {
*filter = other
}
}
+
+func getPathSuffixUnescaped(path string, prefixToTrim string) (string, error) {
+ // The suffix may be URL-encoded, so attempt to decode
+ suffixRaw := strings.TrimPrefix(path, prefixToTrim)
+ suffixUnescaped, err := url.PathUnescape(suffixRaw)
+
+ if err != nil {
+ return suffixRaw, fmt.Errorf("failure in unescaping path param %q: %v", suffixRaw, err)
+ }
+
+ return suffixUnescaped, nil
+}
diff --git a/agent/http_test.go b/agent/http_test.go
index 33e2e7867..b6ead02f0 100644
--- a/agent/http_test.go
+++ b/agent/http_test.go
@@ -1680,3 +1680,42 @@ func TestRPC_HTTPSMaxConnsPerClient(t *testing.T) {
})
}
}
+
+func TestGetPathSuffixUnescaped(t *testing.T) {
+ t.Parallel()
+
+ cases := []struct {
+ name string
+ pathInput string
+ pathPrefix string
+ suffixResult string
+ errString string
+ }{
+ // No decoding required (resource name must be unaffected by the decode)
+ {"Normal Valid", "/foo/bar/resource-1", "/foo/bar/", "resource-1", ""},
+ // This function is not responsible for enforcing a valid URL, just for decoding escaped values.
+ // If there's an invalid URL segment in the path, it will be returned as is.
+ {"Unencoded Invalid", "/foo/bar/resource 1", "/foo/bar/", "resource 1", ""},
+ // Decode the encoded value properly
+ {"Encoded Valid", "/foo/bar/re%2Fsource%201", "/foo/bar/", "re/source 1", ""},
+ // Fail to decode an invalidly encoded input
+ {"Encoded Invalid", "/foo/bar/re%Fsource%201", "/foo/bar/", "re%Fsource%201", "failure in unescaping path param"},
+ }
+
+ for _, tc := range cases {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+
+ suffixResult, err := getPathSuffixUnescaped(tc.pathInput, tc.pathPrefix)
+
+ require.Equal(t, suffixResult, tc.suffixResult)
+
+ if tc.errString == "" {
+ require.NoError(t, err)
+ } else {
+ require.Error(t, err)
+ require.Contains(t, err.Error(), tc.errString)
+ }
+ })
+ }
+}
diff --git a/api/agent.go b/api/agent.go
index e3b5d362a..04dd059d9 100644
--- a/api/agent.go
+++ b/api/agent.go
@@ -707,7 +707,7 @@ func (a *Agent) AgentHealthServiceByNameOpts(service string, q *QueryOptions) (s
// agent-local state. That means there is no persistent raft index so we block
// based on object hash instead.
func (a *Agent) Service(serviceID string, q *QueryOptions) (*AgentService, *QueryMeta, error) {
- r := a.c.newRequest("GET", "/v1/agent/service/"+serviceID)
+ r := a.c.newRequest("GET", "/v1/agent/service/"+url.PathEscape(serviceID))
r.setQueryOptions(q)
rtt, resp, err := a.c.doRequest(r)
if err != nil {
@@ -812,7 +812,7 @@ func (a *Agent) serviceRegister(service *AgentServiceRegistration, opts ServiceR
// ServiceDeregister is used to deregister a service with
// the local agent
func (a *Agent) ServiceDeregister(serviceID string) error {
- r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+serviceID)
+ r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+url.PathEscape(serviceID))
_, resp, err := a.c.doRequest(r)
if err != nil {
return err
@@ -827,7 +827,7 @@ func (a *Agent) ServiceDeregister(serviceID string) error {
// ServiceDeregisterOpts is used to deregister a service with
// the local agent with QueryOptions.
func (a *Agent) ServiceDeregisterOpts(serviceID string, q *QueryOptions) error {
- r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+serviceID)
+ r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+url.PathEscape(serviceID))
r.setQueryOptions(q)
_, resp, err := a.c.doRequest(r)
if err != nil {
@@ -884,7 +884,7 @@ func (a *Agent) updateTTL(checkID, note, status string) error {
default:
return fmt.Errorf("Invalid status: %s", status)
}
- endpoint := fmt.Sprintf("/v1/agent/check/%s/%s", status, checkID)
+ endpoint := fmt.Sprintf("/v1/agent/check/%s/%s", url.PathEscape(status), url.PathEscape(checkID))
r := a.c.newRequest("PUT", endpoint)
r.params.Set("note", note)
_, resp, err := a.c.doRequest(r)
@@ -932,7 +932,7 @@ func (a *Agent) UpdateTTLOpts(checkID, output, status string, q *QueryOptions) e
return fmt.Errorf("Invalid status: %s", status)
}
- endpoint := fmt.Sprintf("/v1/agent/check/update/%s", checkID)
+ endpoint := fmt.Sprintf("/v1/agent/check/update/%s", url.PathEscape(checkID))
r := a.c.newRequest("PUT", endpoint)
r.setQueryOptions(q)
r.obj = &checkUpdate{
@@ -976,7 +976,7 @@ func (a *Agent) CheckDeregister(checkID string) error {
// CheckDeregisterOpts is used to deregister a check with
// the local agent using query options
func (a *Agent) CheckDeregisterOpts(checkID string, q *QueryOptions) error {
- r := a.c.newRequest("PUT", "/v1/agent/check/deregister/"+checkID)
+ r := a.c.newRequest("PUT", "/v1/agent/check/deregister/"+url.PathEscape(checkID))
r.setQueryOptions(q)
_, resp, err := a.c.doRequest(r)
if err != nil {
@@ -992,7 +992,7 @@ func (a *Agent) CheckDeregisterOpts(checkID string, q *QueryOptions) error {
// Join is used to instruct the agent to attempt a join to
// another cluster member
func (a *Agent) Join(addr string, wan bool) error {
- r := a.c.newRequest("PUT", "/v1/agent/join/"+addr)
+ r := a.c.newRequest("PUT", "/v1/agent/join/"+url.PathEscape(addr))
if wan {
r.params.Set("wan", "1")
}
@@ -1044,7 +1044,7 @@ func (a *Agent) ForceLeavePrune(node string) error {
// ForceLeaveOpts is used to have the agent eject a failed node or remove it
// completely from the list of members.
func (a *Agent) ForceLeaveOpts(node string, opts ForceLeaveOpts) error {
- r := a.c.newRequest("PUT", "/v1/agent/force-leave/"+node)
+ r := a.c.newRequest("PUT", "/v1/agent/force-leave/"+url.PathEscape(node))
if opts.Prune {
r.params.Set("prune", "1")
}
@@ -1108,7 +1108,7 @@ func (a *Agent) ConnectCARoots(q *QueryOptions) (*CARootList, *QueryMeta, error)
// ConnectCALeaf gets the leaf certificate for the given service ID.
func (a *Agent) ConnectCALeaf(serviceID string, q *QueryOptions) (*LeafCert, *QueryMeta, error) {
- r := a.c.newRequest("GET", "/v1/agent/connect/ca/leaf/"+serviceID)
+ r := a.c.newRequest("GET", "/v1/agent/connect/ca/leaf/"+url.PathEscape(serviceID))
r.setQueryOptions(q)
rtt, resp, err := a.c.doRequest(r)
if err != nil {
@@ -1136,7 +1136,7 @@ func (a *Agent) EnableServiceMaintenance(serviceID, reason string) error {
}
func (a *Agent) EnableServiceMaintenanceOpts(serviceID, reason string, q *QueryOptions) error {
- r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+serviceID)
+ r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+url.PathEscape(serviceID))
r.setQueryOptions(q)
r.params.Set("enable", "true")
r.params.Set("reason", reason)
@@ -1158,7 +1158,7 @@ func (a *Agent) DisableServiceMaintenance(serviceID string) error {
}
func (a *Agent) DisableServiceMaintenanceOpts(serviceID string, q *QueryOptions) error {
- r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+serviceID)
+ r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+url.PathEscape(serviceID))
r.setQueryOptions(q)
r.params.Set("enable", "false")
_, resp, err := a.c.doRequest(r)
@@ -1355,7 +1355,7 @@ func (a *Agent) updateTokenFallback(token string, q *WriteOptions, targets ...st
}
func (a *Agent) updateTokenOnce(target, token string, q *WriteOptions) (*WriteMeta, int, error) {
- r := a.c.newRequest("PUT", fmt.Sprintf("/v1/agent/token/%s", target))
+ r := a.c.newRequest("PUT", fmt.Sprintf("/v1/agent/token/%s", url.PathEscape(target)))
r.setWriteOptions(q)
r.obj = &AgentToken{Token: token}
From 933faeb1246229bb55e9b27395ec604f16b8b472 Mon Sep 17 00:00:00 2001
From: mrspanishviking
Date: Mon, 3 Jan 2022 09:46:32 -0700
Subject: [PATCH 030/225] Apply suggestions from code review
Co-authored-by: Jared Kirschner <85913323+jkirschner-hashicorp@users.noreply.github.com>
---
.github/ISSUE_TEMPLATE/docs_day.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
index 4b892c860..212ad141e 100644
--- a/.github/ISSUE_TEMPLATE/docs_day.md
+++ b/.github/ISSUE_TEMPLATE/docs_day.md
@@ -1,7 +1,7 @@
---
name: Consul docs day task
about: This is a HashiCorp internal documentation task for the purpose of the Consul docs day event.
-labels: ['type/docs', 'placeholder']
+labels: ['type/docs', 'event/consul-docs-day', `meta/maintainer-preferred`]
assignees:
- karl-cardenas-coding
- jkirschner-hashicorp
@@ -22,6 +22,7 @@ body:
- Add/Improve Examples
- Structural Improvements and Cleanup
- Visual Aids
+ - Other
validations:
required: true
- type: input
@@ -36,7 +37,7 @@ body:
id: Description
attributes:
label: Description
- description: Please provide details about the task?
+ description: Please provide details about the task.
placeholder: What I'll change and why this is important
validations:
required: true
From 0eb34a694e8e231ad94968e800c75ebf9faefa5b Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Mon, 3 Jan 2022 10:49:56 -0700
Subject: [PATCH 031/225] updating Consul docs day issue template
---
.github/ISSUE_TEMPLATE/docs_day.md | 60 ++++++++++--------------------
1 file changed, 19 insertions(+), 41 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
index 212ad141e..ab437e4e4 100644
--- a/.github/ISSUE_TEMPLATE/docs_day.md
+++ b/.github/ISSUE_TEMPLATE/docs_day.md
@@ -8,45 +8,23 @@ assignees:
- trujillo-adam
---
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for taking the time to fill out this Consul docs event task request!
- - type: dropdown
- id: Category
- attributes:
- label: Category
- description: What category is this task for?
- options:
- - Add/Improve Examples
- - Structural Improvements and Cleanup
- - Visual Aids
- - Other
- validations:
- required: true
- - type: input
- id: Short Name
- attributes:
- label: Short Name
- description: Please provide a short name for this task.
- placeholder: ex. PKI Overview
- validations:
- required: true
- - type: textarea
- id: Description
- attributes:
- label: Description
- description: Please provide details about the task.
- placeholder: What I'll change and why this is important
- validations:
- required: true
+*Thanks for taking the time to fill out this Consul docs event task request!*
- - type: textarea
- id: link
- attributes:
- label: Documentation page link(s)
- description: Please provide link(s) to the documentation page(s) to be modified, if applicable
- placeholder: ex: https://www.consul.io/docs/connect/gateways#gateways
- validations:
- required: true
\ No newline at end of file
+## Category
+What category is this task for?
+options:
+ - Add/Improve Examples
+ - Structural Improvements and Cleanup
+ - Visual Aids
+ - Other
+
+## Short Name
+Please provide a short name for this task. **Use the short name for the title**
+
+
+## Description
+Please provide details about the task.
+
+
+## Links
+Please provide link(s) to the documentation page(s) to be modified, if applicable
From ea6bef42e551a52afb906087bec466f9f788bc9a Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Mon, 3 Jan 2022 10:54:31 -0700
Subject: [PATCH 032/225] style update
---
.github/ISSUE_TEMPLATE/docs_day.md | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
index ab437e4e4..c66ee858b 100644
--- a/.github/ISSUE_TEMPLATE/docs_day.md
+++ b/.github/ISSUE_TEMPLATE/docs_day.md
@@ -11,20 +11,18 @@ assignees:
*Thanks for taking the time to fill out this Consul docs event task request!*
## Category
-What category is this task for?
-options:
- - Add/Improve Examples
- - Structural Improvements and Cleanup
- - Visual Aids
- - Other
+What category is this task for? Available Options:
+- Add/Improve Examples
+- Structural Improvements and Cleanup
+- Visual Aids
+- Other
## Short Name
-Please provide a short name for this task. **Use the short name for the title**
-
+Please provide a short name for this task.
+**IMPORTANT**: Use the short name for the title
## Description
Please provide details about the task.
-
## Links
Please provide link(s) to the documentation page(s) to be modified, if applicable
From 807d358129d4413a2a81ee5e7d96bea509b3277d Mon Sep 17 00:00:00 2001
From: Karl Cardenas
Date: Mon, 3 Jan 2022 11:06:09 -0700
Subject: [PATCH 033/225] removing markdown file for consul docs day issue
---
.github/ISSUE_TEMPLATE/docs_day.md | 28 ----------------------------
1 file changed, 28 deletions(-)
delete mode 100644 .github/ISSUE_TEMPLATE/docs_day.md
diff --git a/.github/ISSUE_TEMPLATE/docs_day.md b/.github/ISSUE_TEMPLATE/docs_day.md
deleted file mode 100644
index c66ee858b..000000000
--- a/.github/ISSUE_TEMPLATE/docs_day.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-name: Consul docs day task
-about: This is a HashiCorp internal documentation task for the purpose of the Consul docs day event.
-labels: ['type/docs', 'event/consul-docs-day', `meta/maintainer-preferred`]
-assignees:
- - karl-cardenas-coding
- - jkirschner-hashicorp
- - trujillo-adam
----
-
-*Thanks for taking the time to fill out this Consul docs event task request!*
-
-## Category
-What category is this task for? Available Options:
-- Add/Improve Examples
-- Structural Improvements and Cleanup
-- Visual Aids
-- Other
-
-## Short Name
-Please provide a short name for this task.
-**IMPORTANT**: Use the short name for the title
-
-## Description
-Please provide details about the task.
-
-## Links
-Please provide link(s) to the documentation page(s) to be modified, if applicable
From 078003955b36c15fb821746d32979976725e4efd Mon Sep 17 00:00:00 2001
From: trujillo-adam <47586768+trujillo-adam@users.noreply.github.com>
Date: Mon, 3 Jan 2022 11:32:14 -0800
Subject: [PATCH 034/225] Apply suggestions from code review
typos and minor corrections
Co-authored-by: Freddy
---
.../docs/connect/config-entries/ingress-gateway.mdx | 8 ++++----
.../docs/connect/config-entries/service-intentions.mdx | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/website/content/docs/connect/config-entries/ingress-gateway.mdx b/website/content/docs/connect/config-entries/ingress-gateway.mdx
index 2d276cb70..763253bde 100644
--- a/website/content/docs/connect/config-entries/ingress-gateway.mdx
+++ b/website/content/docs/connect/config-entries/ingress-gateway.mdx
@@ -157,11 +157,11 @@ spec:
-Refer to the [Available Fields](#available-fields) section for complete information about all ingress gateway configuraiton entry options and to the [Example Configurations](#example-configurations) section for example use-cases.
+Refer to the [Available Fields](#available-fields) section for complete information about all ingress gateway configuration entry options and to the [Example Configurations](#example-configurations) section for example use-cases.
### Scope
-[Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies across all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different sets of services within their datacenter then the ingress gateways **must** be registered with different names. See [Ingress Gateway](/docs/connect/ingress-gateway) for more information.
+[Configuration entries](/docs/agent/config-entries) are global in scope. A configuration entry for a gateway name applies across the default partition of all federated Consul datacenters. If ingress gateways in different Consul datacenters need to route to different sets of services within their datacenter then the ingress gateways **must** be registered with different names or partitions. See [Ingress Gateway](/docs/connect/ingress-gateway) for more information.
### Wildcard Service Specification
@@ -327,7 +327,7 @@ spec:
In the following example, two listeners are configured on an ingress gateway named `us-east-ingress`:
-* The first listener is configred to listen on port `8080` and uses a wildcard (`*`) to proxy traffic to all services in the datacenter.
+* The first listener is configured to listen on port `8080` and uses a wildcard (`*`) to proxy traffic to all services in the datacenter.
* The second listener exposes the `api` and `web` services on port `4567` at user-provided hosts.
* TLS is enabled on every listener.
@@ -947,7 +947,7 @@ You can specify the following parameters to configure ingress gateway configurat
enterprise: true,
description:
'Specifies the admin partition in which the configuration will apply. The value must match the partition in which the gateway is registered.' +
- ' If omitted, the partition will be inhereited from the request (refer to the [`config` API endpoint documentation](/api/config)).' +
+ ' If omitted, the partition will be inherited from the request (refer to the [`config` API endpoint documentation](/api/config)).' +
' See [Admin Partitions](/docs/enterprise/admin-partitions) for additional information.',
yaml: false,
},
diff --git a/website/content/docs/connect/config-entries/service-intentions.mdx b/website/content/docs/connect/config-entries/service-intentions.mdx
index 048d1a30c..64317d51c 100644
--- a/website/content/docs/connect/config-entries/service-intentions.mdx
+++ b/website/content/docs/connect/config-entries/service-intentions.mdx
@@ -464,7 +464,7 @@ spec:
hcl:
"Specifies the admin partition of the source service. Defaults to the destination service's partition, i.e., the configuration entry's partition",
yaml:
- "Specifies the admin partiation of the source service. Defaults to the destination service's partition, i.e. `spec.destination.namespace`",
+ "Specifies the admin partition of the source service. Defaults to the destination service's partition, i.e. `spec.destination.partition`",
},
},
{
From c64c512d1b6bc855ff4b538d55f258ef7eb45b9b Mon Sep 17 00:00:00 2001
From: David Yu
Date: Mon, 3 Jan 2022 14:17:55 -0800
Subject: [PATCH 035/225] docs: Clarification of Vault Consul K8s requirements
for Auth Method (#11929)
* docs: Clarification of Vault Consul K8s requirements
* link back to requirements
* Update gossip.mdx
* Update index.mdx
* add details for K8s auth method requirement
* Update gossip.mdx
* Update server-tls.mdx
* Update connect-ca.mdx
* Update gossip.mdx
* Update server-tls.mdx
* Update website/content/docs/k8s/installation/vault/gossip.mdx
Co-authored-by: mrspanishviking
* Update website/content/docs/k8s/installation/vault/index.mdx
Co-authored-by: mrspanishviking
* Update website/content/docs/k8s/installation/vault/index.mdx
Co-authored-by: mrspanishviking
* Update website/content/docs/k8s/installation/vault/index.mdx
Co-authored-by: mrspanishviking
* Update website/content/docs/k8s/installation/vault/server-tls.mdx
Co-authored-by: mrspanishviking
* Update website/content/docs/k8s/installation/vault/index.mdx
Co-authored-by: mrspanishviking
* Update website/content/docs/k8s/installation/vault/index.mdx
Co-authored-by: mrspanishviking
* Update index.mdx
* Update index.mdx
Co-authored-by: mrspanishviking
---
.../k8s/installation/vault/connect-ca.mdx | 2 ++
.../docs/k8s/installation/vault/gossip.mdx | 6 +---
.../docs/k8s/installation/vault/index.mdx | 35 +++++++++++++++++++
.../k8s/installation/vault/server-tls.mdx | 6 +---
4 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/website/content/docs/k8s/installation/vault/connect-ca.mdx b/website/content/docs/k8s/installation/vault/connect-ca.mdx
index 693c0b195..6c33e161a 100644
--- a/website/content/docs/k8s/installation/vault/connect-ca.mdx
+++ b/website/content/docs/k8s/installation/vault/connect-ca.mdx
@@ -11,6 +11,8 @@ description: >-
Consul allows using Kubernetes auth methods to configure Connect CA.
This allows for automatic token rotation once the renewal is no longer possible.
+In order to create Vault auth roles for the Consul servers for this feature, ensure that the Vault Kubernetes auth method is enabled as described in [Vault Kubernetes Auth Method](/docs/k8s/installation/vault#vault-kubernetes-auth-method).
+
To configure [Vault as the provider](/docs/connect/ca/vault) for the Consul service certificates,
you will first need to decide on the type of policy that is suitable for you.
To see the permissions that Consul would need in Vault, please see [Vault ACL policies](/docs/connect/ca/vault#vault-acl-policies)
diff --git a/website/content/docs/k8s/installation/vault/gossip.mdx b/website/content/docs/k8s/installation/vault/gossip.mdx
index b5933cb29..cea8d6923 100644
--- a/website/content/docs/k8s/installation/vault/gossip.mdx
+++ b/website/content/docs/k8s/installation/vault/gossip.mdx
@@ -34,11 +34,7 @@ path "secret/data/consul/gossip" {
vault policy write gossip-policy gossip-policy.hcl
```
-Prior to creating auth roles for the Consul server and client, ensure that the Vault Kubernetes auth method is enabled:
-
-```shell-session
-vault auth enable kubernetes
-```
+Prior to creating Vault auth roles for the Consul servers and clients, ensure that the Vault Kubernetes auth method is enabled as described in [Vault Kubernetes Auth Method](/docs/k8s/installation/vault#vault-kubernetes-auth-method).
Next, we will create Kubernetes auth roles for the Consul server and client:
diff --git a/website/content/docs/k8s/installation/vault/index.mdx b/website/content/docs/k8s/installation/vault/index.mdx
index 9008d5bd4..df1bc25dc 100644
--- a/website/content/docs/k8s/installation/vault/index.mdx
+++ b/website/content/docs/k8s/installation/vault/index.mdx
@@ -25,12 +25,47 @@ At a high level, there are two points of integration with Vault:
1. `global.tls.enableAutoencrypt=true` is required if TLS is enabled for the Consul installation when using the Vault secrets backend.
1. The Vault installation must have been initialized, unsealed and the KV2 and PKI secrets engines enabled and the Kubernetes Auth Method enabled.
+### Vault Helm Config
+
A minimal valid installation of Vault must include the Agent Injector:
```yaml
injector:
enabled: "true"
```
+### Vault Kubernetes Auth Method
+
+Prior to creating Vault auth roles for the Consul servers and clients, ensure that the Vault Kubernetes auth method is enabled:
+
+```shell-session
+$ vault auth enable kubernetes
+```
+
+After enabling the Kubernetes auth method, in Vault, ensure that you have configured the Kubernetes Auth method properly as described in [Kubernetes Auth Method Configuration](https://www.vaultproject.io/docs/auth/kubernetes#configuration). The command should look simliar to the following with a custom `kubernetes_host` config provided from the information provided via `kubectl cluster-info`.
+
+```shell-session
+$ vault write auth/kubernetes/config \
+ token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
+ kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
+ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+```
+
+### Vault KV Secrets Engine - Version 2
+
+In order to utlize Vault as a secrets backend, we must enable thne [Vault KV secrets engine - Version 2](https://www.vaultproject.io/docs/secrets/kv/kv-v2).
+
+```shell-session
+$ vault secrets enable -path=consul kv-v2
+```
+
+### Vault PKI Engine
+
+The Vault PKI Engine must be enabled in order to leverage Vault for issuiing Consul Server TLS certificates. More details for configuring the PKI Engine is found in [Bootstrapping the PKI Engine](https://www.consul.io/docs/k8s/installation/vault/server-tls#bootstrapping-the-pki-engine) under the Server TLS section.
+
+```shell-session
+$ vault secrets enable pki
+```
+
## Known Limitations
- TLS
diff --git a/website/content/docs/k8s/installation/vault/server-tls.mdx b/website/content/docs/k8s/installation/vault/server-tls.mdx
index 40d221d1f..f0ad83183 100644
--- a/website/content/docs/k8s/installation/vault/server-tls.mdx
+++ b/website/content/docs/k8s/installation/vault/server-tls.mdx
@@ -100,11 +100,7 @@ export DATACENTER=dc1
echo allowed_domains=\"$DATACENTER.consul, $NAME-server, $NAME-server.$NAMESPACE, $NAME-server.$NAMESPACE.svc\"
```
-Prior to creating the Kubernetes auth roles required for Consul to securely access Vault, ensure that the Vault Kubernetes Auth method is enabled:
-
-```shell-session
-vault auth enable kubernetes
-```
+Prior to creating Vault auth roles for the Consul server and the Consul components, ensure that the Vault Kubernetes auth method is enabled as described in [Vault Kubernetes Auth Method](/docs/k8s/installation/vault#vault-kubernetes-auth-method).
Finally, two Kubernetes auth roles need to be created, one for the Consul servers and one for the Consul components:
From f072adc61823e73e992e372a1ddd971338cc5f4c Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Mon, 3 Jan 2022 14:40:03 -0800
Subject: [PATCH 036/225] proposed language about why there is no
.meta.partition field
---
.../docs/connect/config-entries/mesh.mdx | 11 +-
.../config-entries/service-defaults.mdx | 160 +++++++++---------
.../config-entries/service-resolver.mdx | 12 +-
3 files changed, 89 insertions(+), 94 deletions(-)
diff --git a/website/content/docs/connect/config-entries/mesh.mdx b/website/content/docs/connect/config-entries/mesh.mdx
index 335121472..519048631 100644
--- a/website/content/docs/connect/config-entries/mesh.mdx
+++ b/website/content/docs/connect/config-entries/mesh.mdx
@@ -77,7 +77,6 @@ kind: Mesh
metadata:
name: mesh
namespace: default
- partition: default
spec:
transparentProxy:
meshDestinationsOnly: true
@@ -99,6 +98,8 @@ spec:
+Note that the Kuberetes example does not include a `partition` field. Configuration entries are applied on Kubernetes using [custom resource definitions (CRD)](/docs/k8s/crds), which can only reference their own partition.
+
## Available Fields
: nil',
@@ -338,23 +337,22 @@ spec:
type: 'array: []',
description: `A list of optional overrides for per-upstream configuration.`,
children: [
- {
- name: 'Name',
- type: 'string: ""',
- description:
- 'The upstream name to apply the configuration to. This should not be set to the wildcard specifier `*`.',
- },
- {
- name: 'Namespace',
- type: 'string: ""',
- description:
- 'The namespace of the upstream. This should not be set to the wildcard specifier `*`.',
- },
- {
- name: 'Protocol',
- type: 'string: ""',
- description:
- `The protocol for the upstream listener.
+ {
+ name: 'Name',
+ type: 'string: ""',
+ description:
+ 'The upstream name to apply the configuration to. This should not be set to the wildcard specifier `*`.',
+ },
+ {
+ name: 'Namespace',
+ type: 'string: ""',
+ description:
+ 'The namespace of the upstream. This should not be set to the wildcard specifier `*`.',
+ },
+ {
+ name: 'Protocol',
+ type: 'string: ""',
+ description: `The protocol for the upstream listener.
NOTE: The protocol of a service should ideally be configured via the
[\`protocol\`](/docs/connect/config-entries/service-defaults#protocol)
field of a
@@ -364,12 +362,12 @@ spec:
[L7 features](/docs/connect/l7-traffic-management).
It is supported here for backwards compatibility with Consul versions prior to 1.6.0.
`,
- },
- {
- name: 'ConnectTimeoutMs',
- type: 'int: 5000',
- description: {
- hcl: `The number of milliseconds to allow when making upstream connections before timing out.
+ },
+ {
+ name: 'ConnectTimeoutMs',
+ type: 'int: 5000',
+ description: {
+ hcl: `The number of milliseconds to allow when making upstream connections before timing out.
NOTE: The connect timeout of a service should ideally be configured via the
[\`connect_timeout\`](/docs/connect/config-entries/service-resolver#connecttimeout)
field of a
@@ -379,7 +377,7 @@ spec:
[L7 features](/docs/connect/l7-traffic-management).
It is supported here for backwards compatibility with Consul versions prior to 1.6.0.
`,
- yaml: `The number of milliseconds to allow when making upstream connections before timing out.
+ yaml: `The number of milliseconds to allow when making upstream connections before timing out.
NOTE: The connect timeout of a service should ideally be configured via the
[\`connectTimeout\`](/docs/connect/config-entries/service-resolver#connecttimeout)
field of a
@@ -389,82 +387,82 @@ spec:
[L7 features](/docs/connect/l7-traffic-management).
It is supported here for backwards compatibility with Consul versions prior to 1.6.0.
`,
- },
},
- {
- name: 'MeshGateway',
- type: 'MeshGatewayConfig: ',
- description: `Controls the default
+ },
+ {
+ name: 'MeshGateway',
+ type: 'MeshGatewayConfig: ',
+ description: `Controls the default
[mesh gateway configuration](/docs/connect/mesh-gateway#connect-proxy-configuration)
for this upstream.`,
- children: [
- {
- name: 'Mode',
- type: 'string: ""',
- description: 'One of `none`, `local`, or `remote`.',
- },
- ],
- },
- {
- name: 'Limits',
- type: 'Limits: ',
- description: `A set of limits to apply when connecting to the upstream service.
+ children: [
+ {
+ name: 'Mode',
+ type: 'string: ""',
+ description: 'One of `none`, `local`, or `remote`.',
+ },
+ ],
+ },
+ {
+ name: 'Limits',
+ type: 'Limits: ',
+ description: `A set of limits to apply when connecting to the upstream service.
These limits are applied on a per-service-instance basis.
The following limits are respected.`,
- children: [
- {
- name: 'MaxConnections',
- type: 'int: 0',
- description: `The maximum number of connections a service instance
+ children: [
+ {
+ name: 'MaxConnections',
+ type: 'int: 0',
+ description: `The maximum number of connections a service instance
will be allowed to establish against the given upstream. Use this to limit
HTTP/1.1 traffic, since HTTP/1.1 has a request per connection.`,
- },
- {
- name: 'MaxPendingRequests',
- type: 'int: 0',
- description: `The maximum number of requests that will be queued
+ },
+ {
+ name: 'MaxPendingRequests',
+ type: 'int: 0',
+ description: `The maximum number of requests that will be queued
while waiting for a connection to be established. For this configuration to
be respected, a L7 protocol must be defined in the \`protocol\` field.`,
- },
- {
- name: 'MaxConcurrentRequests',
- type: 'int: 0',
- description: `The maximum number of concurrent requests that
+ },
+ {
+ name: 'MaxConcurrentRequests',
+ type: 'int: 0',
+ description: `The maximum number of concurrent requests that
will be allowed at a single point in time. Use this to limit HTTP/2 traffic,
since HTTP/2 has many requests per connection. For this configuration to be
respected, a L7 protocol must be defined in the \`protocol\` field.`,
- },
- ],
- },
- {
- name: 'PassiveHealthCheck',
- type: 'PassiveHealthCheck: ',
- description: `Passive health checks are used to remove hosts from
+ },
+ ],
+ },
+ {
+ name: 'PassiveHealthCheck',
+ type: 'PassiveHealthCheck: ',
+ description: `Passive health checks are used to remove hosts from
the upstream cluster which are unreachable or are returning errors..`,
- children: [
- {
- name: 'Interval',
- type: 'duration: 0s',
- description: {
- hcl: `The time between checks. Each check will cause hosts which
+ children: [
+ {
+ name: 'Interval',
+ type: 'duration: 0s',
+ description: {
+ hcl: `The time between checks. Each check will cause hosts which
have exceeded \`max_failures\` to be removed from the load balancer, and
any hosts which have passed their ejection time to be returned to the
load balancer.`,
- yaml: `The time between checks. Each check will cause hosts which
+ yaml: `The time between checks. Each check will cause hosts which
have exceeded \`maxFailures\` to be removed from the load balancer, and
any hosts which have passed their ejection time to be returned to the
load balancer.`,
- },
},
- {
- name: 'MaxFailures',
- type: 'int: 0',
- description: `The number of consecutive failures which cause a host to be
+ },
+ {
+ name: 'MaxFailures',
+ type: 'int: 0',
+ description: `The number of consecutive failures which cause a host to be
removed from the load balancer.`,
- },
- ],
- },
- ],
+ },
+ ],
+ },
+ ],
},
{
name: 'Defaults',
@@ -702,7 +700,7 @@ spec:
],
},
],
- }
+ },
]}
/>
diff --git a/website/content/docs/connect/config-entries/service-resolver.mdx b/website/content/docs/connect/config-entries/service-resolver.mdx
index 8618c2d90..dbb6b468d 100644
--- a/website/content/docs/connect/config-entries/service-resolver.mdx
+++ b/website/content/docs/connect/config-entries/service-resolver.mdx
@@ -246,14 +246,16 @@ spec:
name: 'Namespace',
type: `string: "default"`,
enterprise: true,
- description: 'Specifies the namespace in which the configuration entry will apply.',
+ description:
+ 'Specifies the namespace in which the configuration entry will apply.',
yaml: false,
},
{
name: 'Partition',
type: `string: "default"`,
enterprise: true,
- description: 'Specifies the admin partition in which the configuration entry will apply.',
+ description:
+ 'Specifies the admin partition in which the configuration entry will apply.',
yaml: false,
},
{
@@ -355,20 +357,20 @@ spec:
enterprise: true,
type: 'string: ""',
description:
- 'Specifies the source namespace to resolve the service from.',
+ 'Specifies the destination namespace to resolve the service from.',
},
{
name: 'Partition',
enterprise: true,
type: 'string: ""',
description:
- 'Specifies the source admin partition to resolve the service from.',
+ 'Specifies the destination admin partition to resolve the service from.',
},
{
name: 'Datacenter',
type: 'string: ""',
description:
- 'Specifies the source datacenter to resolve the service from.',
+ 'Specifies the destination datacenter to resolve the service from.',
},
],
},
From 31551b49f498ffb08b21454a2c1975e0ad6a6ef4 Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Mon, 3 Jan 2022 15:31:58 -0800
Subject: [PATCH 037/225] added line about wildcard intentions not supported
for admin partitions
---
website/content/docs/connect/intentions.mdx | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/website/content/docs/connect/intentions.mdx b/website/content/docs/connect/intentions.mdx
index 3fa7c6023..85b380007 100644
--- a/website/content/docs/connect/intentions.mdx
+++ b/website/content/docs/connect/intentions.mdx
@@ -94,11 +94,11 @@ accepted.
### Wildcard Intentions
-You can use the `*` wildcard when defining an intention source or destination. The wildcard matches _any_ value and can serve as a "catch-all" entry for intentions that should have a wide scope.
+You can use the `*` wildcard to match service names when defining an intention source or destination. The wildcard matches _any_ value, which enables you to set a wide initial scope when configuring intentions.
-You can use a wildcard to match service names. If you are using Consul Enterprise, you can also use a wildcard to match a namespace.
+The wildcard is supported in Consul Enterprise `namespace` fields (see [Namespaces](/docs/enterprise/namespaces) for additional information), but it _is not supported_ in `partition` fields (see [Admin Partitions](/docs/enterprise/admin-partitions) for additional information).
-This example says that the "web" service cannot connect to _any_ service:
+In the following example, the `web` service cannot connect to _any_ service:
```hcl
Kind = "service-intentions"
@@ -111,7 +111,7 @@ Sources = [
]
```
-And this example says that _no_ service can connect to the "db" service:
+The `db` service is configured to deny all connection in the following example:
```hcl
Kind = "service-intentions"
@@ -124,8 +124,8 @@ Sources = [
]
```
- This example grants Prometheus
-access to any service in any namespace.
+ This example grants Prometheus access to any service in
+any namespace.
```hcl
Kind = "service-intentions"
From 2e571b64062d67661580bbc1ce463dc04bc385b7 Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Tue, 4 Jan 2022 14:55:32 +0000
Subject: [PATCH 038/225] ui: Ensure disconnect error doesn't appear w/auth
change on some pages (#11905)
---
.changelog/11905.txt | 3 +++
ui/packages/consul-ui/app/components/data-loader/index.hbs | 6 +++---
2 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 .changelog/11905.txt
diff --git a/.changelog/11905.txt b/.changelog/11905.txt
new file mode 100644
index 000000000..510e305d0
--- /dev/null
+++ b/.changelog/11905.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+ui: Prevent disconnection notice appearing with auth change on certain pages
+```
diff --git a/ui/packages/consul-ui/app/components/data-loader/index.hbs b/ui/packages/consul-ui/app/components/data-loader/index.hbs
index b29d59a58..6f38827ab 100644
--- a/ui/packages/consul-ui/app/components/data-loader/index.hbs
+++ b/ui/packages/consul-ui/app/components/data-loader/index.hbs
@@ -50,10 +50,10 @@
+ {{#if (not (eq error.status '401'))}}
{{#yield-slot name="disconnected" params=(block-params (action dispatch "RESET"))}}
- {{yield api}}
+ {{yield api}}
{{else}}
- {{#if (not eq error.status '401')}}
- {{/if}}
{{/yield-slot}}
+ {{/if}}
{{#if (eq error.status "403")}}
{{#yield-slot name="error"}}
From 177924625780cdf3a86814a5e1654f38b561a06e Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Tue, 4 Jan 2022 16:08:06 +0000
Subject: [PATCH 039/225] ui: Fix URL params decoding (#11931)
* ui: Move wildcard param decoding to routlet service
---
.changelog/11931.txt | 3 ++
ui/packages/consul-ui/app/routing/route.js | 30 +++++--------------
ui/packages/consul-ui/app/services/routlet.js | 29 +++++++++++++++---
.../consul-ui/app/templates/dc/kv/edit.hbs | 2 +-
.../tests/acceptance/dc/kvs/edit.feature | 19 ++++++++++--
.../consul-ui/tests/pages/dc/kv/edit.js | 3 ++
6 files changed, 56 insertions(+), 30 deletions(-)
create mode 100644 .changelog/11931.txt
diff --git a/.changelog/11931.txt b/.changelog/11931.txt
new file mode 100644
index 000000000..b76c2849f
--- /dev/null
+++ b/.changelog/11931.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+ui: Fixes a bug with URL decoding within KV area
+```
diff --git a/ui/packages/consul-ui/app/routing/route.js b/ui/packages/consul-ui/app/routing/route.js
index 2eaabc836..2028c96df 100644
--- a/ui/packages/consul-ui/app/routing/route.js
+++ b/ui/packages/consul-ui/app/routing/route.js
@@ -2,17 +2,14 @@ import Route from '@ember/routing/route';
import { get, setProperties, action } from '@ember/object';
import { inject as service } from '@ember/service';
-// paramsFor
import { routes } from 'consul-ui/router';
-import wildcard from 'consul-ui/utils/routing/wildcard';
-
-const isWildcard = wildcard(routes);
export default class BaseRoute extends Route {
@service('container') container;
@service('env') env;
@service('repository/permission') permissions;
@service('router') router;
+ @service('routlet') routlet;
_setRouteName() {
super._setRouteName(...arguments);
@@ -114,27 +111,14 @@ export default class BaseRoute extends Route {
}
/**
- * Adds urldecoding to any wildcard route `params` passed into ember `model`
- * hooks, plus of course anywhere else where `paramsFor` is used. This means
- * the entire ember app is now changed so that all paramsFor calls returns
- * urldecoded params instead of raw ones.
- * For example we use this largely for URLs for the KV store:
- * /kv/*key > /ui/kv/%25-kv-name/%25-here > key = '%-kv-name/%-here'
+ * Normalizes any params passed into ember `model` hooks, plus of course
+ * anywhere else where `paramsFor` is used. This means the entire ember app
+ * is now changed so that all paramsFor calls returns normalized params
+ * instead of raw ones. For example we use this largely for URLs for the KV
+ * store: /kv/*key > /ui/kv/%25-kv-name/%25-here > key = '%-kv-name/%-here'
*/
paramsFor(name) {
- const params = super.paramsFor(...arguments);
- if (isWildcard(this.routeName)) {
- return Object.keys(params).reduce(function(prev, item) {
- if (typeof params[item] !== 'undefined') {
- prev[item] = decodeURIComponent(params[item]);
- } else {
- prev[item] = params[item];
- }
- return prev;
- }, {});
- } else {
- return params;
- }
+ return this.routlet.normalizeParamsFor(this.routeName, super.paramsFor(...arguments));
}
@action
diff --git a/ui/packages/consul-ui/app/services/routlet.js b/ui/packages/consul-ui/app/services/routlet.js
index a2a286f74..b743e51b6 100644
--- a/ui/packages/consul-ui/app/services/routlet.js
+++ b/ui/packages/consul-ui/app/services/routlet.js
@@ -1,6 +1,11 @@
import Service, { inject as service } from '@ember/service';
import { schedule } from '@ember/runloop';
+import wildcard from 'consul-ui/utils/routing/wildcard';
+import { routes } from 'consul-ui/router';
+
+const isWildcard = wildcard(routes);
+
class Outlets {
constructor() {
this.map = new Map();
@@ -87,6 +92,24 @@ export default class RoutletService extends Service {
return {};
}
+ /**
+ * Adds urldecoding to any wildcard route `params`
+ */
+ normalizeParamsFor(name, params = {}) {
+ if (isWildcard(name)) {
+ return Object.keys(params).reduce(function(prev, item) {
+ if (typeof params[item] !== 'undefined') {
+ prev[item] = decodeURIComponent(params[item]);
+ } else {
+ prev[item] = params[item];
+ }
+ return prev;
+ }, {});
+ } else {
+ return params;
+ }
+ }
+
paramsFor(name) {
let outletParams = {};
const outlet = outlets.get(name);
@@ -102,16 +125,14 @@ export default class RoutletService extends Service {
// of the specified params with the values specified
let current = route;
let parent;
- let routeParams = {
- ...current.params,
- };
+ let routeParams = this.normalizeParamsFor(name, current.params);
// TODO: Not entirely sure whether we are ok exposing queryParams here
// seeing as accessing them from here means you can get them but not set
// them as yet
// let queryParams = {};
while ((parent = current.parent)) {
routeParams = {
- ...parent.params,
+ ...this.normalizeParamsFor(parent.name, parent.params),
...routeParams,
};
// queryParams = {
diff --git a/ui/packages/consul-ui/app/templates/dc/kv/edit.hbs b/ui/packages/consul-ui/app/templates/dc/kv/edit.hbs
index b84750d09..e441d26fd 100644
--- a/ui/packages/consul-ui/app/templates/dc/kv/edit.hbs
+++ b/ui/packages/consul-ui/app/templates/dc/kv/edit.hbs
@@ -83,7 +83,7 @@ as |parts|}}
-
+
{{#if (and item.Key (not-eq item.Key parentKey))}}
{{left-trim item.Key parentKey}}
diff --git a/ui/packages/consul-ui/tests/acceptance/dc/kvs/edit.feature b/ui/packages/consul-ui/tests/acceptance/dc/kvs/edit.feature
index 832c8209e..fd26b2169 100644
--- a/ui/packages/consul-ui/tests/acceptance/dc/kvs/edit.feature
+++ b/ui/packages/consul-ui/tests/acceptance/dc/kvs/edit.feature
@@ -1,6 +1,19 @@
@setupApplicationTest
Feature: dc / kvs / edit: KV Viewing
- Scenario:
+ Scenario: Viewing a KV with a URL unsafe character
+ Given 1 datacenter model with the value "datacenter"
+ And 1 kv model from yaml
+ ---
+ Key: "@key"
+ ---
+ When I visit the kv page for yaml
+ ---
+ dc: datacenter
+ kv: "@key"
+ ---
+ Then the url should be /datacenter/kv/%40key/edit
+ And I see Key on the kv like "@key"
+ Scenario: Viewing a Session attached to a KV
Given 1 datacenter model with the value "datacenter"
And 1 kv model from yaml
---
@@ -14,7 +27,9 @@ Feature: dc / kvs / edit: KV Viewing
---
Then the url should be /datacenter/kv/key/edit
And I see ID on the session like "session-id"
- Given 1 kv model from yaml
+ Scenario: Viewing a Session attached to a KV
+ Given 1 datacenter model with the value "datacenter"
+ And 1 kv model from yaml
---
Key: another-key
Session: ~
diff --git a/ui/packages/consul-ui/tests/pages/dc/kv/edit.js b/ui/packages/consul-ui/tests/pages/dc/kv/edit.js
index bb577470d..e3fe94cf9 100644
--- a/ui/packages/consul-ui/tests/pages/dc/kv/edit.js
+++ b/ui/packages/consul-ui/tests/pages/dc/kv/edit.js
@@ -11,6 +11,9 @@ export default function(visitable, attribute, present, submitable, deletable, ca
...submitable({}, 'main'),
...cancelable(),
...deletable(),
+ kv: {
+ Key: attribute('data-test-kv-key', '[data-test-kv-key]')
+ },
session: {
warning: present('[data-test-session-warning]'),
ID: attribute('data-test-session', '[data-test-session]'),
From 91abfe4b01b78a9bd251a700322c18de2d1708d3 Mon Sep 17 00:00:00 2001
From: James Tran
Date: Tue, 4 Jan 2022 11:24:09 -0500
Subject: [PATCH 040/225] ui: Add XML syntax highlighting to key/value editor
(#11785)
* ui: Add XML syntax highlighting to key/value editor
* ui: Make explicit options that are specific to XML for clarity
---
.../consul-ui/app/components/code-editor/index.js | 11 +++++++++--
.../consul-ui/app/components/code-editor/skin.scss | 4 ++++
.../app/instance-initializers/ivy-codemirror.js | 2 ++
.../consul-ui/app/services/code-mirror/linter.js | 10 ++++++++++
ui/packages/consul-ui/ember-cli-build.js | 4 ++++
.../consul-ui/lib/startup/templates/body.html.js | 3 ++-
6 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/ui/packages/consul-ui/app/components/code-editor/index.js b/ui/packages/consul-ui/app/components/code-editor/index.js
index 8fd0aee41..2d54bbb61 100644
--- a/ui/packages/consul-ui/app/components/code-editor/index.js
+++ b/ui/packages/consul-ui/app/components/code-editor/index.js
@@ -31,11 +31,18 @@ export default Component.extend({
}
},
setMode: function(mode) {
- set(this, 'options', {
+ let options = {
...DEFAULTS,
mode: mode.mime,
readOnly: this.readonly,
- });
+ };
+ if (mode.name === 'XML') {
+ options.htmlMode = mode.htmlMode;
+ options.matchClosing = mode.matchClosing;
+ options.alignCDATA = mode.alignCDATA;
+ }
+ set(this, 'options', options);
+
const editor = this.editor;
editor.setOption('mode', mode.mime);
this.helper.lint(editor, mode.mode);
diff --git a/ui/packages/consul-ui/app/components/code-editor/skin.scss b/ui/packages/consul-ui/app/components/code-editor/skin.scss
index f4b35e6bd..6ba316787 100644
--- a/ui/packages/consul-ui/app/components/code-editor/skin.scss
+++ b/ui/packages/consul-ui/app/components/code-editor/skin.scss
@@ -128,6 +128,10 @@ $syntax-dark-gray: #535f73;
color: var(--syntax-packer);
}
+ span.cm-error {
+ color: var(--syntax-red);
+ }
+
span.cm-attribute {
color: #9fca56;
}
diff --git a/ui/packages/consul-ui/app/instance-initializers/ivy-codemirror.js b/ui/packages/consul-ui/app/instance-initializers/ivy-codemirror.js
index 7c17b7ba8..5b23f3987 100644
--- a/ui/packages/consul-ui/app/instance-initializers/ivy-codemirror.js
+++ b/ui/packages/consul-ui/app/instance-initializers/ivy-codemirror.js
@@ -16,6 +16,8 @@ export function initialize(application) {
return fs.get(['codemirror', 'mode', 'ruby', 'ruby.js'].join('/'));
case 'yaml':
return fs.get(['codemirror', 'mode', 'yaml', 'yaml.js'].join('/'));
+ case 'xml':
+ return fs.get(['codemirror', 'mode', 'xml', 'xml.js'].join('/'));
}
},
};
diff --git a/ui/packages/consul-ui/app/services/code-mirror/linter.js b/ui/packages/consul-ui/app/services/code-mirror/linter.js
index c89ba0b95..1e8a4f6b9 100644
--- a/ui/packages/consul-ui/app/services/code-mirror/linter.js
+++ b/ui/packages/consul-ui/app/services/code-mirror/linter.js
@@ -16,6 +16,16 @@ const MODES = [
alias: ['jruby', 'macruby', 'rake', 'rb', 'rbx'],
},
{ name: 'YAML', mime: 'text/x-yaml', mode: 'yaml', ext: ['yaml', 'yml'], alias: ['yml'] },
+ {
+ name: 'XML',
+ mime: 'application/xml',
+ mode: 'xml',
+ htmlMode: false,
+ matchClosing: true,
+ alignCDATA: false,
+ ext: ['xml'],
+ alias: ['xml'],
+ },
];
export default class LinterService extends Service {
diff --git a/ui/packages/consul-ui/ember-cli-build.js b/ui/packages/consul-ui/ember-cli-build.js
index 4bff448c2..b6fea5edc 100644
--- a/ui/packages/consul-ui/ember-cli-build.js
+++ b/ui/packages/consul-ui/ember-cli-build.js
@@ -206,6 +206,10 @@ module.exports = function(defaults, $ = process.env) {
app.import('node_modules/codemirror/mode/yaml/yaml.js', {
outputFile: 'assets/codemirror/mode/yaml/yaml.js',
});
+ // XML linting support. Possibly dynamically loaded via CodeMirror linting. See services/code-mirror/linter.js
+ app.import('node_modules/codemirror/mode/xml/xml.js', {
+ outputFile: 'assets/codemirror/mode/xml/xml.js',
+ });
// metrics-providers
app.import('vendor/metrics-providers/consul.js', {
outputFile: 'assets/metrics-providers/consul.js',
diff --git a/ui/packages/consul-ui/lib/startup/templates/body.html.js b/ui/packages/consul-ui/lib/startup/templates/body.html.js
index cb9016821..72738c9af 100644
--- a/ui/packages/consul-ui/lib/startup/templates/body.html.js
+++ b/ui/packages/consul-ui/lib/startup/templates/body.html.js
@@ -38,7 +38,8 @@ ${environment === 'production' ? `{{jsonEncode .}}` : JSON.stringify(config.oper
"css.escape/css.escape.js": "${rootURL}assets/css.escape.js",
"codemirror/mode/javascript/javascript.js": "${rootURL}assets/codemirror/mode/javascript/javascript.js",
"codemirror/mode/ruby/ruby.js": "${rootURL}assets/codemirror/mode/ruby/ruby.js",
- "codemirror/mode/yaml/yaml.js": "${rootURL}assets/codemirror/mode/yaml/yaml.js"
+ "codemirror/mode/yaml/yaml.js": "${rootURL}assets/codemirror/mode/yaml/yaml.js",
+ "codemirror/mode/xml/xml.js": "${rootURL}assets/codemirror/mode/xml/xml.js"
}
From d87fe70a828b6b995c9b2956fe629a53f78e6444 Mon Sep 17 00:00:00 2001
From: "Chris S. Kim"
Date: Tue, 4 Jan 2022 11:24:56 -0500
Subject: [PATCH 041/225] testing: Revert assertion for virtual IP flag
(#11932)
---
agent/consul/system_metadata_test.go | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/agent/consul/system_metadata_test.go b/agent/consul/system_metadata_test.go
index 61f62c8d1..633aa6bc4 100644
--- a/agent/consul/system_metadata_test.go
+++ b/agent/consul/system_metadata_test.go
@@ -33,10 +33,10 @@ func TestLeader_SystemMetadata_CRUD(t *testing.T) {
state := srv.fsm.State()
- // Initially has one entry for virtual-ips feature flag
+ // Initially has no entries
_, entries, err := state.SystemMetadataList(nil)
require.NoError(t, err)
- require.Len(t, entries, 1)
+ require.Len(t, entries, 0)
// Create 3
require.NoError(t, srv.setSystemMetadataKey("key1", "val1"))
@@ -53,13 +53,12 @@ func TestLeader_SystemMetadata_CRUD(t *testing.T) {
_, entries, err = state.SystemMetadataList(nil)
require.NoError(t, err)
- require.Len(t, entries, 4)
+ require.Len(t, entries, 3)
require.Equal(t, map[string]string{
- structs.SystemMetadataVirtualIPsEnabled: "true",
- "key1": "val1",
- "key2": "val2",
- "key3": "",
+ "key1": "val1",
+ "key2": "val2",
+ "key3": "",
}, mapify(entries))
// Update one and delete one.
@@ -68,11 +67,10 @@ func TestLeader_SystemMetadata_CRUD(t *testing.T) {
_, entries, err = state.SystemMetadataList(nil)
require.NoError(t, err)
- require.Len(t, entries, 3)
+ require.Len(t, entries, 2)
require.Equal(t, map[string]string{
- structs.SystemMetadataVirtualIPsEnabled: "true",
- "key2": "val2",
- "key3": "val3",
+ "key2": "val2",
+ "key3": "val3",
}, mapify(entries))
}
From a9371f18e5f6598ae0bc874af77a17c10b56a587 Mon Sep 17 00:00:00 2001
From: Jared Kirschner
Date: Fri, 20 Aug 2021 22:03:24 -0400
Subject: [PATCH 042/225] Clarify service and check error messages (use ID)
Error messages related to service and check operations previously included
the following substrings:
- service %q
- check %q
From this error message, it isn't clear that the expected field is the ID for
the entity, not the name. For example, if the user has a service named test,
the error message would read 'Unknown service "test"'. This is misleading -
a service with that *name* does exist, but not with that *ID*.
The substrings above have been modified to make it clear that ID is needed,
not name:
- service with ID %q
- check with ID %q
---
.changelog/10894.txt | 3 +++
agent/acl.go | 10 ++++++++--
agent/agent_endpoint.go | 4 +++-
agent/agent_endpoint_test.go | 2 +-
agent/consul/catalog_endpoint.go | 8 ++++----
agent/local/state.go | 17 ++++++++++++-----
agent/local/state_test.go | 32 ++++++++++++++++++++++++++++++--
7 files changed, 61 insertions(+), 15 deletions(-)
create mode 100644 .changelog/10894.txt
diff --git a/.changelog/10894.txt b/.changelog/10894.txt
new file mode 100644
index 000000000..2799a4537
--- /dev/null
+++ b/.changelog/10894.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+api: Improve error message if service or health check not found by stating that the entity must be referred to by ID, not name
+```
diff --git a/agent/acl.go b/agent/acl.go
index 550299216..ae7efdde1 100644
--- a/agent/acl.go
+++ b/agent/acl.go
@@ -84,7 +84,13 @@ func (a *Agent) vetServiceUpdateWithAuthorizer(authz acl.Authorizer, serviceID s
structs.ServiceIDString(existing.Service, &existing.EnterpriseMeta))
}
} else {
- return NotFoundError{Reason: fmt.Sprintf("Unknown service %q", serviceID)}
+ // Take care if modifying this error message.
+ // agent/local/state.go's deleteService assumes the Catalog.Deregister RPC call
+ // will include "Unknown service"in the error if deregistration fails due to a
+ // service with that ID not existing.
+ return NotFoundError{Reason: fmt.Sprintf(
+ "Unknown service ID %q. Ensure that the service ID is passed, not the service name.",
+ serviceID)}
}
return nil
@@ -143,7 +149,7 @@ func (a *Agent) vetCheckUpdateWithAuthorizer(authz acl.Authorizer, checkID struc
}
}
} else {
- return fmt.Errorf("Unknown check %q", checkID.String())
+ return fmt.Errorf("Unknown check ID %q. Ensure that the check ID is passed, not the check name.", checkID.String())
}
return nil
diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go
index 623897ac8..297f96cbf 100644
--- a/agent/agent_endpoint.go
+++ b/agent/agent_endpoint.go
@@ -424,7 +424,9 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
svcState := s.agent.State.ServiceState(sid)
if svcState == nil {
resp.WriteHeader(http.StatusNotFound)
- fmt.Fprintf(resp, "unknown service ID: %s", sid.String())
+ fmt.Fprintf(resp,
+ "Unknown service ID %q. Ensure that the service ID is passed, not the service name.",
+ sid.String())
return "", nil, nil
}
diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go
index 3d4a80beb..a240aebed 100644
--- a/agent/agent_endpoint_test.go
+++ b/agent/agent_endpoint_test.go
@@ -4751,7 +4751,7 @@ func TestAgent_ServiceMaintenance_BadRequest(t *testing.T) {
resp := httptest.NewRecorder()
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, 404, resp.Code)
- require.Contains(t, resp.Body.String(), `Unknown service "_nope_"`)
+ require.Contains(t, resp.Body.String(), `Unknown service ID "_nope_"`)
})
}
diff --git a/agent/consul/catalog_endpoint.go b/agent/consul/catalog_endpoint.go
index 4de46558a..eb107193a 100644
--- a/agent/consul/catalog_endpoint.go
+++ b/agent/consul/catalog_endpoint.go
@@ -309,12 +309,12 @@ func vetRegisterWithACL(
// Service-level check for some other service. Make sure they've
// got write permissions for that service.
if ns == nil {
- return fmt.Errorf("Unknown service '%s' for check '%s'", check.ServiceID, check.CheckID)
+ return fmt.Errorf("Unknown service ID '%s' for check ID '%s'", check.ServiceID, check.CheckID)
}
other, ok := ns.Services[check.ServiceID]
if !ok {
- return fmt.Errorf("Unknown service '%s' for check '%s'", check.ServiceID, check.CheckID)
+ return fmt.Errorf("Unknown service ID '%s' for check ID '%s'", check.ServiceID, check.CheckID)
}
// We are only adding a check here, so we don't add the scope,
@@ -417,7 +417,7 @@ func vetDeregisterWithACL(
// ignore them from an ACL perspective.
if subj.ServiceID != "" {
if ns == nil {
- return fmt.Errorf("Unknown service '%s'", subj.ServiceID)
+ return fmt.Errorf("Unknown service ID '%s'", subj.ServiceID)
}
ns.FillAuthzContext(&authzContext)
@@ -427,7 +427,7 @@ func vetDeregisterWithACL(
}
} else if subj.CheckID != "" {
if nc == nil {
- return fmt.Errorf("Unknown check '%s'", subj.CheckID)
+ return fmt.Errorf("Unknown check ID '%s'", subj.CheckID)
}
nc.FillAuthzContext(&authzContext)
diff --git a/agent/local/state.go b/agent/local/state.go
index a729bf06c..03db0badb 100644
--- a/agent/local/state.go
+++ b/agent/local/state.go
@@ -272,7 +272,7 @@ func (l *State) addServiceLocked(service *structs.NodeService, token string) err
}
if l.agentEnterpriseMeta.PartitionOrDefault() != service.PartitionOrDefault() {
- return fmt.Errorf("cannot add service %q to node in partition %q", service.CompoundServiceID(), l.config.Partition)
+ return fmt.Errorf("cannot add service ID %q to node in partition %q", service.CompoundServiceID(), l.config.Partition)
}
l.setServiceStateLocked(&ServiceState{
@@ -328,7 +328,14 @@ func (l *State) RemoveServiceWithChecks(serviceID structs.ServiceID, checkIDs []
func (l *State) removeServiceLocked(id structs.ServiceID) error {
s := l.services[id]
if s == nil || s.Deleted {
- return fmt.Errorf("Service %q does not exist", id)
+ // Take care if modifying this error message.
+ // deleteService assumes the Catalog.Deregister RPC call will include "Unknown service"
+ // in the error if deregistration fails due to a service with that ID not existing.
+
+ // When the service register endpoint is called, this error message is also typically
+ // shadowed by vetServiceUpdateWithAuthorizer, which checks for the existence of the
+ // service and, if none is found, returns an error before this function is ever called.
+ return fmt.Errorf("Unknown service ID %q. Ensure that the service ID is passed, not the service name.", id)
}
// To remove the service on the server we need the token.
@@ -539,7 +546,7 @@ func (l *State) addCheckLocked(check *structs.HealthCheck, token string) error {
// if there is a serviceID associated with the check, make sure it exists before adding it
// NOTE - This logic may be moved to be handled within the Agent's Addcheck method after a refactor
if _, ok := l.services[check.CompoundServiceID()]; check.ServiceID != "" && !ok {
- return fmt.Errorf("Check %q refers to non-existent service %q", check.CheckID, check.ServiceID)
+ return fmt.Errorf("Check ID %q refers to non-existent service ID %q", check.CheckID, check.ServiceID)
}
l.setCheckStateLocked(&CheckState{
@@ -561,7 +568,7 @@ func (l *State) AddAliasCheck(checkID structs.CheckID, srcServiceID structs.Serv
defer l.Unlock()
if l.agentEnterpriseMeta.PartitionOrDefault() != checkID.PartitionOrDefault() {
- return fmt.Errorf("cannot add alias check %q to node in partition %q", checkID.String(), l.config.Partition)
+ return fmt.Errorf("cannot add alias check ID %q to node in partition %q", checkID.String(), l.config.Partition)
}
if l.agentEnterpriseMeta.PartitionOrDefault() != srcServiceID.PartitionOrDefault() {
return fmt.Errorf("cannot add alias check for %q to node in partition %q", srcServiceID.String(), l.config.Partition)
@@ -612,7 +619,7 @@ func (l *State) RemoveCheck(id structs.CheckID) error {
func (l *State) removeCheckLocked(id structs.CheckID) error {
c := l.checks[id]
if c == nil || c.Deleted {
- return fmt.Errorf("Check %q does not exist", id)
+ return fmt.Errorf("Check ID %q does not exist", id)
}
// If this is a check for an aliased service, then notify the waiters.
diff --git a/agent/local/state_test.go b/agent/local/state_test.go
index af8944309..62ebd4040 100644
--- a/agent/local/state_test.go
+++ b/agent/local/state_test.go
@@ -1952,7 +1952,7 @@ func TestAgent_AddCheckFailure(t *testing.T) {
ServiceID: "redis",
Status: api.HealthPassing,
}
- wantErr := errors.New(`Check "redis:1" refers to non-existent service "redis"`)
+ wantErr := errors.New(`Check ID "redis:1" refers to non-existent service ID "redis"`)
got := l.AddCheck(chk, "")
require.Equal(t, wantErr, got)
@@ -2114,7 +2114,7 @@ func servicesInSync(state *local.State, wantServices int, entMeta *structs.Enter
}
for id, s := range services {
if !s.InSync {
- return fmt.Errorf("service %q should be in sync %+v", id.String(), s)
+ return fmt.Errorf("service ID %q should be in sync %+v", id.String(), s)
}
}
return nil
@@ -2133,6 +2133,34 @@ func checksInSync(state *local.State, wantChecks int, entMeta *structs.Enterpris
return nil
}
+func TestState_RemoveServiceErrorMessages(t *testing.T) {
+ state := local.NewState(local.Config{}, hclog.New(nil), &token.Store{})
+
+ // Stub state syncing
+ state.TriggerSyncChanges = func() {}
+
+ require := require.New(t)
+
+ // Add 1 service
+ err := state.AddService(&structs.NodeService{
+ ID: "web-id",
+ Service: "web-name",
+ }, "")
+ require.NoError(err)
+
+ // Attempt to remove service that doesn't exist
+ err = state.RemoveService(structs.NewServiceID("db", nil))
+ require.Contains(err.Error(), `Unknown service ID "db"`)
+
+ // Attempt to remove service by name (which isn't valid)
+ err = state.RemoveService(structs.NewServiceID("web-name", nil))
+ require.Contains(err.Error(), `Unknown service ID "web-name"`)
+
+ // Attempt to remove service by id (valid)
+ err = state.RemoveService(structs.NewServiceID("web-id", nil))
+ require.NoError(err)
+}
+
func TestState_Notify(t *testing.T) {
t.Parallel()
logger := hclog.New(&hclog.LoggerOptions{
From 2c047e1c3ab961bde2e73f60f0e020486cdaf0b7 Mon Sep 17 00:00:00 2001
From: Noel Quiles <3746694+EnMod@users.noreply.github.com>
Date: Tue, 4 Jan 2022 15:29:46 -0500
Subject: [PATCH 043/225] website: Update copy (#11853)
---
website/content/docs/connect/nomad.mdx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/website/content/docs/connect/nomad.mdx b/website/content/docs/connect/nomad.mdx
index e5ac1e7aa..d141e30a1 100644
--- a/website/content/docs/connect/nomad.mdx
+++ b/website/content/docs/connect/nomad.mdx
@@ -10,7 +10,8 @@ description: >-
# Connect on Nomad
Consul Connect can be used with [Nomad](https://www.nomadproject.io) to provide
-secure service-to-service communication between Nomad jobs and task groups. The ability to
+secure service-to-service communication between Nomad jobs and task groups.
+Nomad is a simple, flexible scheduler and workload orchestrator. The ability to
use the [dynamic port](https://www.nomadproject.io/docs/job-specification/network#dynamic-ports)
feature of Nomad makes Connect reduces operational complexity.
From 4a36e4ee24b520196414e178ac07bea07d9b8a96 Mon Sep 17 00:00:00 2001
From: Blake Covarrubias
Date: Tue, 4 Jan 2022 12:44:43 -0800
Subject: [PATCH 045/225] cli: Show node identities in acl token list output
(#11926)
Fix the pretty CLI output of `consul acl token list` so that it
properly displays node identities that are associated with a token.
---
.changelog/11926.txt | 3 +++
command/acl/token/formatter.go | 10 +++-------
.../FormatTokenList/complex.pretty-meta.golden | 4 ++--
.../FormatTokenList/complex.pretty.golden | 4 ++--
website/content/commands/acl/token/list.mdx | 18 ++++++++++--------
5 files changed, 20 insertions(+), 19 deletions(-)
create mode 100644 .changelog/11926.txt
diff --git a/.changelog/11926.txt b/.changelog/11926.txt
new file mode 100644
index 000000000..29ce1b043
--- /dev/null
+++ b/.changelog/11926.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+cli: Display assigned node identities in output of `consul acl token list`.
+```
diff --git a/command/acl/token/formatter.go b/command/acl/token/formatter.go
index ad6d3ae79..e88ee28ba 100644
--- a/command/acl/token/formatter.go
+++ b/command/acl/token/formatter.go
@@ -173,13 +173,9 @@ func (f *prettyFormatter) formatTokenListEntry(token *api.ACLTokenListEntry) str
}
}
if len(token.NodeIdentities) > 0 {
- buffer.WriteString(fmt.Sprintln("Service Identities:"))
- for _, svcid := range token.ServiceIdentities {
- if len(svcid.Datacenters) > 0 {
- buffer.WriteString(fmt.Sprintf(" %s (Datacenters: %s)\n", svcid.ServiceName, strings.Join(svcid.Datacenters, ", ")))
- } else {
- buffer.WriteString(fmt.Sprintf(" %s (Datacenters: all)\n", svcid.ServiceName))
- }
+ buffer.WriteString(fmt.Sprintln("Node Identities:"))
+ for _, nodeid := range token.NodeIdentities {
+ buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter))
}
}
return buffer.String()
diff --git a/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden b/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden
index 7ef9e8a55..11e05cfe4 100644
--- a/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden
+++ b/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden
@@ -18,5 +18,5 @@ Roles:
6c9d1e1d-34bc-4d55-80f3-add0890ad791 - west-farthing
Service Identities:
gardener (Datacenters: middleearth-northwest)
-Service Identities:
- gardener (Datacenters: middleearth-northwest)
+Node Identities:
+ bagend (Datacenter: middleearth-northwest)
diff --git a/command/acl/token/testdata/FormatTokenList/complex.pretty.golden b/command/acl/token/testdata/FormatTokenList/complex.pretty.golden
index 9005d254b..596d7aba0 100644
--- a/command/acl/token/testdata/FormatTokenList/complex.pretty.golden
+++ b/command/acl/token/testdata/FormatTokenList/complex.pretty.golden
@@ -15,5 +15,5 @@ Roles:
6c9d1e1d-34bc-4d55-80f3-add0890ad791 - west-farthing
Service Identities:
gardener (Datacenters: middleearth-northwest)
-Service Identities:
- gardener (Datacenters: middleearth-northwest)
+Node Identities:
+ bagend (Datacenter: middleearth-northwest)
diff --git a/website/content/commands/acl/token/list.mdx b/website/content/commands/acl/token/list.mdx
index bca01c369..2458a102e 100644
--- a/website/content/commands/acl/token/list.mdx
+++ b/website/content/commands/acl/token/list.mdx
@@ -46,14 +46,6 @@ Legacy: false
Policies:
00000000-0000-0000-0000-000000000001 - global-management
-AccessorID: 59f86a9b-d3b6-166c-32a0-be4ab3f94caa
-Description: Super User
-Local: false
-Create Time: 2018-10-22 15:35:28.787003 -0400 EDT
-Legacy: false
-Policies:
- 00000000-0000-0000-0000-000000000001 - global-management
-
AccessorID: 00000000-0000-0000-0000-000000000002
Description: Anonymous Token
Local: false
@@ -69,4 +61,14 @@ Create Time: 2018-10-22 15:33:39.01789 -0400 EDT
Legacy: false
Policies:
06acc965-df4b-5a99-58cb-3250930c6324 - node-services-read
+Service Identities:
+ wonderservice (Datacenters: all)
+
+AccessorID: def4895d-eeb9-f78a-fbb9-2a15a568af31
+Description: Node 1 agent token
+Local: false
+Create Time: 2020-12-22 04:19:30.552528733 +0000 UTC
+Legacy: false
+Node Identities:
+ node1 (Datacenter: dc1)
```
From 98aac0855cc13a8aeeea6d65700f3ff070aef68e Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Wed, 5 Jan 2022 09:34:28 +0000
Subject: [PATCH 046/225] ui: Configure routes in route config rather than
classes (#11900)
---
.../vendor/consul-nspaces/routes.js | 25 +-
.../vendor/consul-partitions/routes.js | 25 +-
ui/packages/consul-ui/app/router.js | 227 +++++++++++++++++-
ui/packages/consul-ui/app/routes/dc/index.js | 6 -
.../app/routes/dc/intentions/create.js | 5 -
.../app/routes/dc/intentions/index.js | 16 --
.../consul-ui/app/routes/dc/kv/create.js | 5 -
.../consul-ui/app/routes/dc/kv/folder.js | 2 -
.../consul-ui/app/routes/dc/kv/index.js | 9 -
.../consul-ui/app/routes/dc/kv/root-create.js | 3 -
.../consul-ui/app/routes/dc/nodes/index.js | 16 --
.../app/routes/dc/nodes/show/healthchecks.js | 18 --
.../app/routes/dc/nodes/show/services.js | 17 --
.../consul-ui/app/routes/dc/services/index.js | 18 --
.../dc/services/instance/healthchecks.js | 17 --
.../app/routes/dc/services/instance/index.js | 6 -
.../routes/dc/services/instance/upstreams.js | 15 --
.../dc/services/show/intentions/create.js | 5 -
.../dc/services/show/intentions/index.js | 16 --
.../app/routes/dc/services/show/services.js | 16 --
.../app/routes/dc/services/show/upstreams.js | 16 --
ui/packages/consul-ui/app/routing/route.js | 40 +--
.../tests/unit/routes/dc/index-test.js | 11 -
.../unit/routes/dc/intentions/create-test.js | 11 -
.../unit/routes/dc/intentions/index-test.js | 11 -
.../tests/unit/routes/dc/kv/create-test.js | 11 -
.../tests/unit/routes/dc/kv/index-test.js | 11 -
.../unit/routes/dc/kv/root-create-test.js | 11 -
28 files changed, 268 insertions(+), 321 deletions(-)
delete mode 100644 ui/packages/consul-ui/app/routes/dc/index.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/intentions/create.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/intentions/index.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/kv/create.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/kv/root-create.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/nodes/index.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/nodes/show/healthchecks.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/nodes/show/services.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/index.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/instance/healthchecks.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/instance/index.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/instance/upstreams.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/show/intentions/create.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/show/intentions/index.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/show/services.js
delete mode 100644 ui/packages/consul-ui/app/routes/dc/services/show/upstreams.js
delete mode 100644 ui/packages/consul-ui/tests/unit/routes/dc/index-test.js
delete mode 100644 ui/packages/consul-ui/tests/unit/routes/dc/intentions/create-test.js
delete mode 100644 ui/packages/consul-ui/tests/unit/routes/dc/intentions/index-test.js
delete mode 100644 ui/packages/consul-ui/tests/unit/routes/dc/kv/create-test.js
delete mode 100644 ui/packages/consul-ui/tests/unit/routes/dc/kv/index-test.js
delete mode 100644 ui/packages/consul-ui/tests/unit/routes/dc/kv/root-create-test.js
diff --git a/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js b/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js
index 3f8a0f904..b4f0976c9 100644
--- a/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js
+++ b/ui/packages/consul-nspaces/vendor/consul-nspaces/routes.js
@@ -3,18 +3,23 @@
nspaces: {
_options: {
path: '/namespaces',
- queryParams: {
- sortBy: 'sort',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Description', 'Role', 'Policy']],
- },
- search: {
- as: 'filter',
- replace: true,
+ abilities: ['read nspaces'],
+ },
+ index: {
+ _options: {
+ path: '/',
+ queryParams: {
+ sortBy: 'sort',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['Name', 'Description', 'Role', 'Policy']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
},
},
- abilities: ['read nspaces'],
},
edit: {
_options: { path: '/:name' },
diff --git a/ui/packages/consul-partitions/vendor/consul-partitions/routes.js b/ui/packages/consul-partitions/vendor/consul-partitions/routes.js
index 3ef4d56a3..a60c5ba22 100644
--- a/ui/packages/consul-partitions/vendor/consul-partitions/routes.js
+++ b/ui/packages/consul-partitions/vendor/consul-partitions/routes.js
@@ -3,18 +3,23 @@
partitions: {
_options: {
path: '/partitions',
- queryParams: {
- sortBy: 'sort',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Description']],
- },
- search: {
- as: 'filter',
- replace: true,
+ abilities: ['read partitions'],
+ },
+ index: {
+ _options: {
+ path: '/',
+ queryParams: {
+ sortBy: 'sort',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['Name', 'Description']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
},
},
- abilities: ['read partitions'],
},
edit: {
_options: { path: '/:name' },
diff --git a/ui/packages/consul-ui/app/router.js b/ui/packages/consul-ui/app/router.js
index 6ecbd29a0..1ac7c4da1 100644
--- a/ui/packages/consul-ui/app/router.js
+++ b/ui/packages/consul-ui/app/router.js
@@ -19,33 +19,123 @@ export const routes = merge.all(
// Our parent datacenter resource sets the namespace
// for the entire application
dc: {
- _options: { path: '/:dc' },
+ _options: {
+ path: '/:dc',
+ },
+ index: {
+ _options: {
+ path: '/',
+ redirect: '../services',
+ },
+ },
// Services represent a consul service
services: {
_options: { path: '/services' },
+ index: {
+ _options: {
+ path: '/',
+ queryParams: {
+ sortBy: 'sort',
+ status: 'status',
+ source: 'source',
+ kind: 'kind',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['Name', 'Tags']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
+ },
// Show an individual service
show: {
_options: { path: '/:name' },
instances: {
- _options: { path: '/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: true,
+ },
+ },
+ },
},
intentions: {
_options: { path: '/intentions' },
+ index: {
+ _options: {
+ path: '',
+ queryParams: {
+ sortBy: 'sort',
+ access: 'access',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['SourceName', 'DestinationName']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
+ },
edit: {
_options: { path: '/:intention_id' },
},
create: {
- _options: { path: '/create' },
+ _options: {
+ template: 'dc/services/show/intentions/edit',
+ path: '/create',
+ },
},
},
topology: {
_options: { path: '/topology' },
},
services: {
- _options: { path: '/services' },
+ _options: {
+ path: '/services',
+ queryParams: {
+ sortBy: 'sort',
+ instance: 'instance',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['Name', 'Tags']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
},
upstreams: {
- _options: { path: '/upstreams' },
+ _options: {
+ path: '/upstreams',
+ queryParams: {
+ sortBy: 'sort',
+ instance: 'instance',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['Name', 'Tags']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
},
routing: {
_options: { path: '/routing' },
@@ -55,12 +145,43 @@ export const routes = merge.all(
},
},
instance: {
- _options: { path: '/:name/instances/:node/:id' },
+ _options: {
+ path: '/:name/instances/:node/:id',
+ redirect: './healthchecks',
+ },
healthchecks: {
- _options: { path: '/health-checks' },
+ _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: true,
+ },
+ },
+ },
},
upstreams: {
- _options: { path: '/upstreams' },
+ _options: {
+ path: '/upstreams',
+ queryParams: {
+ sortBy: 'sort',
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['DestinationName', 'LocalBindAddress', 'LocalBindPort']],
+ },
+ },
+ },
},
exposedpaths: {
_options: { path: '/exposed-paths' },
@@ -79,14 +200,62 @@ export const routes = merge.all(
// Nodes represent a consul node
nodes: {
_options: { path: '/nodes' },
+ index: {
+ _options: {
+ path: '',
+ queryParams: {
+ sortBy: 'sort',
+ status: 'status',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['Node', 'Address', 'Meta']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
+ },
// Show an individual node
show: {
_options: { path: '/:name' },
healthchecks: {
- _options: { path: '/health-checks' },
+ _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: true,
+ },
+ },
+ },
},
services: {
- _options: { path: '/service-instances' },
+ _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: true,
+ },
+ },
+ },
},
rtt: {
_options: { path: '/round-trip-time' },
@@ -102,6 +271,23 @@ export const routes = merge.all(
// Intentions represent a consul intention
intentions: {
_options: { path: '/intentions' },
+ index: {
+ _options: {
+ path: '/',
+ queryParams: {
+ sortBy: 'sort',
+ access: 'access',
+ searchproperty: {
+ as: 'searchproperty',
+ empty: [['SourceName', 'DestinationName']],
+ },
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
+ },
edit: {
_options: {
path: '/:intention_id',
@@ -110,6 +296,7 @@ export const routes = merge.all(
},
create: {
_options: {
+ template: 'dc/intentions/edit',
path: '/create',
abilities: ['create intentions'],
},
@@ -118,20 +305,38 @@ export const routes = merge.all(
// Key/Value
kv: {
_options: { path: '/kv' },
+ index: {
+ _options: {
+ path: '/',
+ queryParams: {
+ sortBy: 'sort',
+ kind: 'kind',
+ search: {
+ as: 'filter',
+ replace: true,
+ },
+ },
+ },
+ },
folder: {
- _options: { path: '/*key' },
+ _options: {
+ template: 'dc/kv/index',
+ path: '/*key',
+ },
},
edit: {
_options: { path: '/*key/edit' },
},
create: {
_options: {
+ template: 'dc/kv/edit',
path: '/*key/create',
abilities: ['create kvs'],
},
},
'root-create': {
_options: {
+ template: 'dc/kv/edit',
path: '/create',
abilities: ['create kvs'],
},
diff --git a/ui/packages/consul-ui/app/routes/dc/index.js b/ui/packages/consul-ui/app/routes/dc/index.js
deleted file mode 100644
index 6503c013f..000000000
--- a/ui/packages/consul-ui/app/routes/dc/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import Route from 'consul-ui/routing/route';
-import to from 'consul-ui/utils/routing/redirect-to';
-
-export default class IndexRoute extends Route {
- redirect = to('services');
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/intentions/create.js b/ui/packages/consul-ui/app/routes/dc/intentions/create.js
deleted file mode 100644
index 416c50354..000000000
--- a/ui/packages/consul-ui/app/routes/dc/intentions/create.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class CreateRoute extends Route {
- templateName = 'dc/intentions/edit';
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/intentions/index.js b/ui/packages/consul-ui/app/routes/dc/intentions/index.js
deleted file mode 100644
index abbb2483e..000000000
--- a/ui/packages/consul-ui/app/routes/dc/intentions/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class IndexRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- access: 'access',
- searchproperty: {
- as: 'searchproperty',
- empty: [['SourceName', 'DestinationName']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/kv/create.js b/ui/packages/consul-ui/app/routes/dc/kv/create.js
deleted file mode 100644
index 07a6d95be..000000000
--- a/ui/packages/consul-ui/app/routes/dc/kv/create.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class CreateRoute extends Route {
- templateName = 'dc/kv/edit';
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/kv/folder.js b/ui/packages/consul-ui/app/routes/dc/kv/folder.js
index 335447023..bc38291c1 100644
--- a/ui/packages/consul-ui/app/routes/dc/kv/folder.js
+++ b/ui/packages/consul-ui/app/routes/dc/kv/folder.js
@@ -1,8 +1,6 @@
import Route from './index';
export default class FolderRoute extends Route {
- templateName = 'dc/kv/index';
-
beforeModel(transition) {
super.beforeModel(...arguments);
const params = this.paramsFor('dc.kv.folder');
diff --git a/ui/packages/consul-ui/app/routes/dc/kv/index.js b/ui/packages/consul-ui/app/routes/dc/kv/index.js
index 0131797b1..8c3999b21 100644
--- a/ui/packages/consul-ui/app/routes/dc/kv/index.js
+++ b/ui/packages/consul-ui/app/routes/dc/kv/index.js
@@ -3,15 +3,6 @@ import { action } from '@ember/object';
import isFolder from 'consul-ui/utils/isFolder';
export default class IndexRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- kind: 'kind',
- search: {
- as: 'filter',
- replace: true,
- },
- };
-
beforeModel() {
// we are index or folder, so if the key doesn't have a trailing slash
// add one to force a fake findBySlug
diff --git a/ui/packages/consul-ui/app/routes/dc/kv/root-create.js b/ui/packages/consul-ui/app/routes/dc/kv/root-create.js
deleted file mode 100644
index 796723b13..000000000
--- a/ui/packages/consul-ui/app/routes/dc/kv/root-create.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Route from './create';
-
-export default class RootCreateRoute extends Route {}
diff --git a/ui/packages/consul-ui/app/routes/dc/nodes/index.js b/ui/packages/consul-ui/app/routes/dc/nodes/index.js
deleted file mode 100644
index c3ed3a894..000000000
--- a/ui/packages/consul-ui/app/routes/dc/nodes/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class IndexRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- status: 'status',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Node', 'Address', 'Meta']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/nodes/show/healthchecks.js b/ui/packages/consul-ui/app/routes/dc/nodes/show/healthchecks.js
deleted file mode 100644
index 665b16a93..000000000
--- a/ui/packages/consul-ui/app/routes/dc/nodes/show/healthchecks.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class HealthchecksRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- status: 'status',
- kind: 'kind',
- check: 'check',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Service', 'CheckID', 'Notes', 'Output', 'ServiceTags']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/nodes/show/services.js b/ui/packages/consul-ui/app/routes/dc/nodes/show/services.js
deleted file mode 100644
index 8920d28ab..000000000
--- a/ui/packages/consul-ui/app/routes/dc/nodes/show/services.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class ServicesRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- status: 'status',
- source: 'source',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Tags', 'ID', 'Address', 'Port', 'Service.Meta']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/index.js b/ui/packages/consul-ui/app/routes/dc/services/index.js
deleted file mode 100644
index 3de9104fc..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/index.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class IndexRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- status: 'status',
- source: 'source',
- kind: 'kind',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Tags']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/instance/healthchecks.js b/ui/packages/consul-ui/app/routes/dc/services/instance/healthchecks.js
deleted file mode 100644
index cc0a1b1f7..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/instance/healthchecks.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class HealthchecksRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- status: 'status',
- check: 'check',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Node', 'CheckID', 'Notes', 'Output', 'ServiceTags']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/instance/index.js b/ui/packages/consul-ui/app/routes/dc/services/instance/index.js
deleted file mode 100644
index 37898e3e3..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/instance/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import Route from 'consul-ui/routing/route';
-import to from 'consul-ui/utils/routing/redirect-to';
-
-export default class InstanceIndexRoute extends Route {
- redirect = to('healthchecks');
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/instance/upstreams.js b/ui/packages/consul-ui/app/routes/dc/services/instance/upstreams.js
deleted file mode 100644
index 2179c8c20..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/instance/upstreams.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class UpstreamsRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- search: {
- as: 'filter',
- replace: true,
- },
- searchproperty: {
- as: 'searchproperty',
- empty: [['DestinationName', 'LocalBindAddress', 'LocalBindPort']],
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/show/intentions/create.js b/ui/packages/consul-ui/app/routes/dc/services/show/intentions/create.js
deleted file mode 100644
index 818d5e8aa..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/show/intentions/create.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class CreateRoute extends Route {
- templateName = 'dc/services/show/intentions/edit';
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/show/intentions/index.js b/ui/packages/consul-ui/app/routes/dc/services/show/intentions/index.js
deleted file mode 100644
index abbb2483e..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/show/intentions/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class IndexRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- access: 'access',
- searchproperty: {
- as: 'searchproperty',
- empty: [['SourceName', 'DestinationName']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/show/services.js b/ui/packages/consul-ui/app/routes/dc/services/show/services.js
deleted file mode 100644
index 55025bfb2..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/show/services.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class ServicesRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- instance: 'instance',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Tags']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routes/dc/services/show/upstreams.js b/ui/packages/consul-ui/app/routes/dc/services/show/upstreams.js
deleted file mode 100644
index 023f37902..000000000
--- a/ui/packages/consul-ui/app/routes/dc/services/show/upstreams.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import Route from 'consul-ui/routing/route';
-
-export default class UpstreamsRoute extends Route {
- queryParams = {
- sortBy: 'sort',
- instance: 'instance',
- searchproperty: {
- as: 'searchproperty',
- empty: [['Name', 'Tags']],
- },
- search: {
- as: 'filter',
- replace: true,
- },
- };
-}
diff --git a/ui/packages/consul-ui/app/routing/route.js b/ui/packages/consul-ui/app/routing/route.js
index 2028c96df..0499b849f 100644
--- a/ui/packages/consul-ui/app/routing/route.js
+++ b/ui/packages/consul-ui/app/routing/route.js
@@ -13,36 +13,40 @@ export default class BaseRoute extends Route {
_setRouteName() {
super._setRouteName(...arguments);
- const routeName = this.routeName
- .split('.')
- .filter(item => item !== 'index')
- .join('.');
- const template = get(routes, `${routeName}._options.template`);
- if (template) {
+
+ const template = get(routes, `${this.routeName}._options.template`);
+ if (typeof template !== 'undefined') {
this.templateName = template;
}
- const queryParams = get(routes, `${routeName}._options.queryParams`);
- if (
- queryParams &&
- ['dc.partitions.index', 'dc.nspaces.index', 'oauth-provider-debug'].includes(this.routeName)
- ) {
+
+ const queryParams = get(routes, `${this.routeName}._options.queryParams`);
+ if (typeof queryParams !== 'undefined') {
this.queryParams = queryParams;
}
}
redirect(model, transition) {
- // remove any references to index as it is the same as the root routeName
- const routeName = this.routeName
- .split('.')
- .filter(item => item !== 'index')
- .join('.');
- const to = get(routes, `${routeName}._options.redirect`);
+ let to = get(routes, `${this.routeName}._options.redirect`);
if (typeof to !== 'undefined') {
+ // simple path resolve
+ to = to
+ .split('/')
+ .reduce((prev, item, i, items) => {
+ if (item !== '.') {
+ if (item === '..') {
+ prev.pop();
+ } else if (item !== '' || i === items.length - 1) {
+ prev.push(item);
+ }
+ }
+ return prev;
+ }, this.routeName.split('.'))
+ .join('.');
// TODO: Does this need to return?
// Almost remember things getting strange if you returned from here
// which is why I didn't do it originally so be sure to look properly if
// you feel like adding a return
- this.replaceWith(`${routeName}${to}`, model);
+ this.replaceWith(`${to}`, model);
}
}
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/index-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/index-test.js
deleted file mode 100644
index 705db7668..000000000
--- a/ui/packages/consul-ui/tests/unit/routes/dc/index-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'ember-qunit';
-
-module('Unit | Route | dc/index', function(hooks) {
- setupTest(hooks);
-
- test('it exists', function(assert) {
- let route = this.owner.lookup('route:dc/index');
- assert.ok(route);
- });
-});
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/intentions/create-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/intentions/create-test.js
deleted file mode 100644
index ab1b5a8f7..000000000
--- a/ui/packages/consul-ui/tests/unit/routes/dc/intentions/create-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'ember-qunit';
-
-module('Unit | Route | dc/intentions/create', function(hooks) {
- setupTest(hooks);
-
- test('it exists', function(assert) {
- let route = this.owner.lookup('route:dc/intentions/create');
- assert.ok(route);
- });
-});
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/intentions/index-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/intentions/index-test.js
deleted file mode 100644
index 24e410426..000000000
--- a/ui/packages/consul-ui/tests/unit/routes/dc/intentions/index-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'ember-qunit';
-
-module('Unit | Route | dc/intentions/index', function(hooks) {
- setupTest(hooks);
-
- test('it exists', function(assert) {
- let route = this.owner.lookup('route:dc/intentions/index');
- assert.ok(route);
- });
-});
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/kv/create-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/kv/create-test.js
deleted file mode 100644
index fc868ed2a..000000000
--- a/ui/packages/consul-ui/tests/unit/routes/dc/kv/create-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, skip } from 'qunit';
-import { setupTest } from 'ember-qunit';
-
-module('Unit | Route | dc/kv/create', function(hooks) {
- setupTest(hooks);
-
- skip('it exists', function(assert) {
- let route = this.subject();
- assert.ok(route);
- });
-});
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/kv/index-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/kv/index-test.js
deleted file mode 100644
index b9e9b1012..000000000
--- a/ui/packages/consul-ui/tests/unit/routes/dc/kv/index-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'ember-qunit';
-
-module('Unit | Route | dc/kv/index', function(hooks) {
- setupTest(hooks);
-
- test('it exists', function(assert) {
- let route = this.owner.lookup('route:dc/kv/index');
- assert.ok(route);
- });
-});
diff --git a/ui/packages/consul-ui/tests/unit/routes/dc/kv/root-create-test.js b/ui/packages/consul-ui/tests/unit/routes/dc/kv/root-create-test.js
deleted file mode 100644
index f36815359..000000000
--- a/ui/packages/consul-ui/tests/unit/routes/dc/kv/root-create-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'ember-qunit';
-
-module('Unit | Route | dc/kv/root create', function(hooks) {
- setupTest(hooks);
-
- test('it exists', function(assert) {
- let route = this.owner.lookup('route:dc/kv/root-create');
- assert.ok(route);
- });
-});
From be78d764164b924cf91669c3828b788490a7b1b8 Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Wed, 5 Jan 2022 14:52:06 +0000
Subject: [PATCH 047/225] ui: Only allow partition creation with a single
datacenter setup (#11817)
---
.../app/templates/dc/partitions/index.hbs | 10 +++++++++-
ui/packages/consul-ui/app/abilities/partition.js | 14 ++++++++++++--
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/ui/packages/consul-partitions/app/templates/dc/partitions/index.hbs b/ui/packages/consul-partitions/app/templates/dc/partitions/index.hbs
index 824a6ab4f..57609854c 100644
--- a/ui/packages/consul-partitions/app/templates/dc/partitions/index.hbs
+++ b/ui/packages/consul-partitions/app/templates/dc/partitions/index.hbs
@@ -48,7 +48,15 @@ as |route|>
- Create
+{{#if (can 'create partitions')}}
+
+ Create
+
+{{/if}}
{{#if (gt items.length 0)}}
diff --git a/ui/packages/consul-ui/app/abilities/partition.js b/ui/packages/consul-ui/app/abilities/partition.js
index 8756ba3b0..86cc5cefc 100644
--- a/ui/packages/consul-ui/app/abilities/partition.js
+++ b/ui/packages/consul-ui/app/abilities/partition.js
@@ -3,6 +3,7 @@ import { inject as service } from '@ember/service';
export default class PartitionAbility extends BaseAbility {
@service('env') env;
+ @service('repository/dc') dcs;
resource = 'operator';
segmented = false;
@@ -12,7 +13,16 @@ export default class PartitionAbility extends BaseAbility {
}
get canManage() {
- return this.canCreate;
+ // management currently means "can I write", not necessarily just create
+ return this.canWrite;
+ }
+
+ get canCreate() {
+ // we can only currently create a partition if you have only one datacenter
+ if (this.dcs.peekAll().length > 1) {
+ return false;
+ }
+ return super.canCreate;
}
get canDelete() {
@@ -20,7 +30,7 @@ export default class PartitionAbility extends BaseAbility {
}
get canChoose() {
- if(typeof this.dc === 'undefined') {
+ if (typeof this.dc === 'undefined') {
return false;
}
return this.canUse && this.dc.Primary;
From 45b5742973224aa5f06f4e7a4d1fc208984e2ccf Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Wed, 5 Jan 2022 16:56:26 +0000
Subject: [PATCH 048/225] ui: Add selective no-console eslint rule (#11938)
---
ui/packages/consul-ui/.dev.eslintrc.js | 8 --------
ui/packages/consul-ui/.eslintrc.js | 1 +
ui/packages/consul-ui/app/locations/fsm-with-optional.js | 2 +-
.../auth-providers/oauth2-code-with-url-provider.js | 7 +++----
ui/packages/consul-ui/package.json | 1 -
5 files changed, 5 insertions(+), 14 deletions(-)
delete mode 100644 ui/packages/consul-ui/.dev.eslintrc.js
diff --git a/ui/packages/consul-ui/.dev.eslintrc.js b/ui/packages/consul-ui/.dev.eslintrc.js
deleted file mode 100644
index 0cf0f31ed..000000000
--- a/ui/packages/consul-ui/.dev.eslintrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-module.exports = {
- extends: ['./.eslintrc.js'],
- rules: {
- 'no-console': 'warn',
- 'no-unused-vars': ['error', { args: 'none' }],
- 'ember/routes-segments-snake-case': 'warn',
- },
-};
diff --git a/ui/packages/consul-ui/.eslintrc.js b/ui/packages/consul-ui/.eslintrc.js
index 0daee7958..994b78a24 100644
--- a/ui/packages/consul-ui/.eslintrc.js
+++ b/ui/packages/consul-ui/.eslintrc.js
@@ -14,6 +14,7 @@ module.exports = {
browser: true,
},
rules: {
+ 'no-console': ['error', {allow: ['error', 'info']}],
'no-unused-vars': ['error', { args: 'none' }],
'ember/no-new-mixins': ['warn'],
'ember/no-jquery': 'warn',
diff --git a/ui/packages/consul-ui/app/locations/fsm-with-optional.js b/ui/packages/consul-ui/app/locations/fsm-with-optional.js
index 19ed18da3..1e4feb839 100644
--- a/ui/packages/consul-ui/app/locations/fsm-with-optional.js
+++ b/ui/packages/consul-ui/app/locations/fsm-with-optional.js
@@ -240,7 +240,7 @@ export default class FSMWithOptionalLocation {
*/
transitionTo(url) {
if (this.router.currentRouteName.startsWith('docs') && url.startsWith('console://')) {
- console.log(`location.transitionTo: ${url.substr(10)}`);
+ console.info(`location.transitionTo: ${url.substr(10)}`);
return true;
}
const previousOptional = Object.entries(this.optionalParams());
diff --git a/ui/packages/consul-ui/app/services/auth-providers/oauth2-code-with-url-provider.js b/ui/packages/consul-ui/app/services/auth-providers/oauth2-code-with-url-provider.js
index f7a4cf7ca..69aa83f74 100644
--- a/ui/packages/consul-ui/app/services/auth-providers/oauth2-code-with-url-provider.js
+++ b/ui/packages/consul-ui/app/services/auth-providers/oauth2-code-with-url-provider.js
@@ -2,7 +2,6 @@ import OAuth2CodeProvider from 'torii/providers/oauth2-code';
import { runInDebug } from '@ember/debug';
export default class OAuth2CodeWithURLProvider extends OAuth2CodeProvider {
-
name = 'oidc-with-url';
buildUrl() {
@@ -23,7 +22,9 @@ export default class OAuth2CodeWithURLProvider extends OAuth2CodeProvider {
authorizationCode: decodeURIComponent(authData[responseType]),
provider: name,
};
- runInDebug(_ => console.log('Retrieved the following creds from the OAuth Provider', creds))
+ runInDebug(_ =>
+ console.info('Retrieved the following creds from the OAuth Provider', creds)
+ );
return creds;
});
}
@@ -34,6 +35,4 @@ export default class OAuth2CodeWithURLProvider extends OAuth2CodeProvider {
return popup.close();
}
}
-
}
-
diff --git a/ui/packages/consul-ui/package.json b/ui/packages/consul-ui/package.json
index 0eb5ff1e8..5c4035202 100644
--- a/ui/packages/consul-ui/package.json
+++ b/ui/packages/consul-ui/package.json
@@ -16,7 +16,6 @@
"lint": "FORCE_COLOR=1 npm-run-all --aggregate-output --continue-on-error --parallel lint:*",
"lint:hbs": "ember-template-lint .",
"lint:js": "eslint .",
- "_lint:dev:js": "eslint -c .dev.eslintrc.js --fix ./*.js ./.*.js app config lib server tests",
"format": "npm-run-all format:*",
"format:js": "prettier --write \"{app,config,lib,server,vendor,tests}/**/*.js\" ./*.js ./.*.js",
"format:sass": "prettier --write \"app/**/*.scss\"",
From dc18933cc2136e498959c10c0acc8d2792ffc319 Mon Sep 17 00:00:00 2001
From: Mathew Estafanous <56979977+Mathew-Estafanous@users.noreply.github.com>
Date: Wed, 5 Jan 2022 12:11:03 -0500
Subject: [PATCH 049/225] Ensure consistency with error-handling across all
handlers. (#11599)
---
agent/acl_endpoint.go | 107 +++++++++++++++++------------------
agent/acl_endpoint_test.go | 7 +--
agent/agent_endpoint.go | 104 +++++++++++-----------------------
agent/agent_endpoint_test.go | 9 +--
agent/http.go | 20 ++++++-
5 files changed, 107 insertions(+), 140 deletions(-)
diff --git a/agent/acl_endpoint.go b/agent/acl_endpoint.go
index 08ddfb496..ef07e2a01 100644
--- a/agent/acl_endpoint.go
+++ b/agent/acl_endpoint.go
@@ -16,23 +16,22 @@ type aclBootstrapResponse struct {
structs.ACLToken
}
+var aclDisabled = UnauthorizedError{Reason: "ACL support disabled"}
+
// checkACLDisabled will return a standard response if ACLs are disabled. This
// returns true if they are disabled and we should not continue.
-func (s *HTTPHandlers) checkACLDisabled(resp http.ResponseWriter, _req *http.Request) bool {
+func (s *HTTPHandlers) checkACLDisabled() bool {
if s.agent.config.ACLsEnabled {
return false
}
-
- resp.WriteHeader(http.StatusUnauthorized)
- fmt.Fprint(resp, "ACL support disabled")
return true
}
// ACLBootstrap is used to perform a one-time ACL bootstrap operation on
// a cluster to get the first management token.
func (s *HTTPHandlers) ACLBootstrap(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
args := structs.DCSpecificRequest{
@@ -42,9 +41,7 @@ func (s *HTTPHandlers) ACLBootstrap(resp http.ResponseWriter, req *http.Request)
err := s.agent.RPC("ACL.BootstrapTokens", &args, &out)
if err != nil {
if strings.Contains(err.Error(), structs.ACLBootstrapNotAllowedErr.Error()) {
- resp.WriteHeader(http.StatusForbidden)
- fmt.Fprint(resp, acl.PermissionDeniedError{Cause: err.Error()}.Error())
- return nil, nil
+ return nil, acl.PermissionDeniedError{Cause: err.Error()}
} else {
return nil, err
}
@@ -53,8 +50,8 @@ func (s *HTTPHandlers) ACLBootstrap(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) ACLReplicationStatus(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
// Note that we do not forward to the ACL DC here. This is a query for
@@ -74,8 +71,8 @@ func (s *HTTPHandlers) ACLReplicationStatus(resp http.ResponseWriter, req *http.
}
func (s *HTTPHandlers) ACLPolicyList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var args structs.ACLPolicyListRequest
@@ -105,8 +102,8 @@ func (s *HTTPHandlers) ACLPolicyList(resp http.ResponseWriter, req *http.Request
}
func (s *HTTPHandlers) ACLPolicyCRUD(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var fn func(resp http.ResponseWriter, req *http.Request, policyID string) (interface{}, error)
@@ -166,8 +163,8 @@ func (s *HTTPHandlers) ACLPolicyRead(resp http.ResponseWriter, req *http.Request
}
func (s *HTTPHandlers) ACLPolicyReadByName(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
policyName := strings.TrimPrefix(req.URL.Path, "/v1/acl/policy/name/")
@@ -183,8 +180,8 @@ func (s *HTTPHandlers) ACLPolicyReadByID(resp http.ResponseWriter, req *http.Req
}
func (s *HTTPHandlers) ACLPolicyCreate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
return s.aclPolicyWriteInternal(resp, req, "", true)
@@ -248,8 +245,8 @@ func (s *HTTPHandlers) ACLPolicyDelete(resp http.ResponseWriter, req *http.Reque
}
func (s *HTTPHandlers) ACLTokenList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
args := &structs.ACLTokenListRequest{
@@ -285,8 +282,8 @@ func (s *HTTPHandlers) ACLTokenList(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) ACLTokenCRUD(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var fn func(resp http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error)
@@ -318,8 +315,8 @@ func (s *HTTPHandlers) ACLTokenCRUD(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) ACLTokenSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
args := structs.ACLTokenGetRequest{
@@ -351,8 +348,8 @@ func (s *HTTPHandlers) ACLTokenSelf(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) ACLTokenCreate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
return s.aclTokenSetInternal(req, "", true)
@@ -442,8 +439,8 @@ func (s *HTTPHandlers) ACLTokenDelete(resp http.ResponseWriter, req *http.Reques
}
func (s *HTTPHandlers) ACLTokenClone(resp http.ResponseWriter, req *http.Request, tokenID string) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
args := structs.ACLTokenSetRequest{
@@ -471,8 +468,8 @@ func (s *HTTPHandlers) ACLTokenClone(resp http.ResponseWriter, req *http.Request
}
func (s *HTTPHandlers) ACLRoleList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var args structs.ACLRoleListRequest
@@ -504,8 +501,8 @@ func (s *HTTPHandlers) ACLRoleList(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) ACLRoleCRUD(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var fn func(resp http.ResponseWriter, req *http.Request, roleID string) (interface{}, error)
@@ -533,8 +530,8 @@ func (s *HTTPHandlers) ACLRoleCRUD(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) ACLRoleReadByName(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
roleName := strings.TrimPrefix(req.URL.Path, "/v1/acl/role/name/")
@@ -581,8 +578,8 @@ func (s *HTTPHandlers) ACLRoleRead(resp http.ResponseWriter, req *http.Request,
}
func (s *HTTPHandlers) ACLRoleCreate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
return s.ACLRoleWrite(resp, req, "")
@@ -634,8 +631,8 @@ func (s *HTTPHandlers) ACLRoleDelete(resp http.ResponseWriter, req *http.Request
}
func (s *HTTPHandlers) ACLBindingRuleList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var args structs.ACLBindingRuleListRequest
@@ -668,8 +665,8 @@ func (s *HTTPHandlers) ACLBindingRuleList(resp http.ResponseWriter, req *http.Re
}
func (s *HTTPHandlers) ACLBindingRuleCRUD(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var fn func(resp http.ResponseWriter, req *http.Request, bindingRuleID string) (interface{}, error)
@@ -728,8 +725,8 @@ func (s *HTTPHandlers) ACLBindingRuleRead(resp http.ResponseWriter, req *http.Re
}
func (s *HTTPHandlers) ACLBindingRuleCreate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
return s.ACLBindingRuleWrite(resp, req, "")
@@ -781,8 +778,8 @@ func (s *HTTPHandlers) ACLBindingRuleDelete(resp http.ResponseWriter, req *http.
}
func (s *HTTPHandlers) ACLAuthMethodList(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var args structs.ACLAuthMethodListRequest
@@ -812,8 +809,8 @@ func (s *HTTPHandlers) ACLAuthMethodList(resp http.ResponseWriter, req *http.Req
}
func (s *HTTPHandlers) ACLAuthMethodCRUD(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
var fn func(resp http.ResponseWriter, req *http.Request, methodName string) (interface{}, error)
@@ -872,8 +869,8 @@ func (s *HTTPHandlers) ACLAuthMethodRead(resp http.ResponseWriter, req *http.Req
}
func (s *HTTPHandlers) ACLAuthMethodCreate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
return s.ACLAuthMethodWrite(resp, req, "")
@@ -928,8 +925,8 @@ func (s *HTTPHandlers) ACLAuthMethodDelete(resp http.ResponseWriter, req *http.R
}
func (s *HTTPHandlers) ACLLogin(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
args := &structs.ACLLoginRequest{
@@ -954,8 +951,8 @@ func (s *HTTPHandlers) ACLLogin(resp http.ResponseWriter, req *http.Request) (in
}
func (s *HTTPHandlers) ACLLogout(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
args := structs.ACLLogoutRequest{
@@ -1014,8 +1011,8 @@ func (s *HTTPHandlers) ACLAuthorize(resp http.ResponseWriter, req *http.Request)
// policy.
const maxRequests = 64
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, aclDisabled
}
request := structs.RemoteACLAuthorizationRequest{
diff --git a/agent/acl_endpoint_test.go b/agent/acl_endpoint_test.go
index bd8929aab..ca5239061 100644
--- a/agent/acl_endpoint_test.go
+++ b/agent/acl_endpoint_test.go
@@ -70,10 +70,8 @@ func TestACL_Disabled_Response(t *testing.T) {
req, _ := http.NewRequest("PUT", "/should/not/care", nil)
resp := httptest.NewRecorder()
obj, err := tt.fn(resp, req)
- require.NoError(t, err)
require.Nil(t, obj)
- require.Equal(t, http.StatusUnauthorized, resp.Code)
- require.Contains(t, resp.Body.String(), "ACL support disabled")
+ require.ErrorIs(t, err, UnauthorizedError{Reason: "ACL support disabled"})
})
}
}
@@ -119,9 +117,6 @@ func TestACL_Bootstrap(t *testing.T) {
if tt.token && err != nil {
t.Fatalf("err: %v", err)
}
- if got, want := resp.Code, tt.code; got != want {
- t.Fatalf("got %d want %d", got, want)
- }
if tt.token {
wrap, ok := out.(*aclBootstrapResponse)
if !ok {
diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go
index 297f96cbf..2de8c53c4 100644
--- a/agent/agent_endpoint.go
+++ b/agent/agent_endpoint.go
@@ -155,9 +155,11 @@ func (s *HTTPHandlers) AgentMetrics(resp http.ResponseWriter, req *http.Request)
}
if enablePrometheusOutput(req) {
if s.agent.config.Telemetry.PrometheusOpts.Expiration < 1 {
- resp.WriteHeader(http.StatusUnsupportedMediaType)
- fmt.Fprint(resp, "Prometheus is not enabled since its retention time is not positive")
- return nil, nil
+ return nil, CodeWithPayloadError{
+ StatusCode: http.StatusUnsupportedMediaType,
+ Reason: "Prometheus is not enabled since its retention time is not positive",
+ ContentType: "text/plain",
+ }
}
handlerOptions := promhttp.HandlerOpts{
ErrorLog: s.agent.logger.StandardLogger(&hclog.StandardLoggerOptions{
@@ -423,11 +425,7 @@ func (s *HTTPHandlers) AgentService(resp http.ResponseWriter, req *http.Request)
svcState := s.agent.State.ServiceState(sid)
if svcState == nil {
- resp.WriteHeader(http.StatusNotFound)
- fmt.Fprintf(resp,
- "Unknown service ID %q. Ensure that the service ID is passed, not the service name.",
- sid.String())
- return "", nil, nil
+ return "", nil, NotFoundError{Reason: fmt.Sprintf("unknown service ID: %s", sid.String())}
}
svc := svcState.Service
@@ -557,9 +555,7 @@ func (s *HTTPHandlers) AgentMembers(resp http.ResponseWriter, req *http.Request)
// key are ok, otherwise the argument doesn't apply to
// the WAN.
default:
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, "Cannot provide a segment with wan=true")
- return nil, nil
+ return nil, BadRequestError{Reason: "Cannot provide a segment with wan=true"}
}
}
@@ -735,16 +731,16 @@ func (s *HTTPHandlers) AgentRegisterCheck(resp http.ResponseWriter, req *http.Re
}
if err := decodeBody(req.Body, &args); err != nil {
- return nil, BadRequestError{fmt.Sprintf("Request decode failed: %v", err)}
+ return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)}
}
// Verify the check has a name.
if args.Name == "" {
- return nil, BadRequestError{"Missing check name"}
+ return nil, BadRequestError{Reason: "Missing check name"}
}
if args.Status != "" && !structs.ValidStatus(args.Status) {
- return nil, BadRequestError{"Bad check status"}
+ return nil, BadRequestError{Reason: "Bad check status"}
}
authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &args.EnterpriseMeta, nil)
@@ -763,15 +759,15 @@ func (s *HTTPHandlers) AgentRegisterCheck(resp http.ResponseWriter, req *http.Re
chkType := args.CheckType()
err = chkType.Validate()
if err != nil {
- return nil, BadRequestError{fmt.Sprintf("Invalid check: %v", err)}
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid check: %v", err)}
}
// Store the type of check based on the definition
health.Type = chkType.Type()
if health.ServiceID != "" {
- cid := health.CompoundServiceID()
// fixup the service name so that vetCheckRegister requires the right ACLs
+ cid := health.CompoundServiceID()
service := s.agent.State.Service(cid)
if service != nil {
health.ServiceName = service.Service
@@ -881,9 +877,7 @@ type checkUpdate struct {
func (s *HTTPHandlers) AgentCheckUpdate(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
var update checkUpdate
if err := decodeBody(req.Body, &update); err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprintf(resp, "Request decode failed: %v", err)
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)}
}
switch update.Status {
@@ -891,9 +885,7 @@ func (s *HTTPHandlers) AgentCheckUpdate(resp http.ResponseWriter, req *http.Requ
case api.HealthWarning:
case api.HealthCritical:
default:
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprintf(resp, "Invalid check status: '%s'", update.Status)
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid check status: '%s'", update.Status)}
}
ID, err := getPathSuffixUnescaped(req.URL.Path, "/v1/agent/check/update/")
@@ -1121,24 +1113,18 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http.
}
if err := decodeBody(req.Body, &args); err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprintf(resp, "Request decode failed: %v", err)
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Request decode failed: %v", err)}
}
// Verify the service has a name.
if args.Name == "" {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, "Missing service name")
- return nil, nil
+ return nil, BadRequestError{Reason: "Missing service name"}
}
// Check the service address here and in the catalog RPC endpoint
// since service registration isn't synchronous.
if ipaddr.IsAny(args.Address) {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprintf(resp, "Invalid service address")
- return nil, nil
+ return nil, BadRequestError{Reason: "Invalid service address"}
}
var token string
@@ -1157,37 +1143,27 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http.
ns := args.NodeService()
if ns.Weights != nil {
if err := structs.ValidateWeights(ns.Weights); err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, fmt.Errorf("Invalid Weights: %v", err))
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid Weights: %v", err)}
}
}
if err := structs.ValidateServiceMetadata(ns.Kind, ns.Meta, false); err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, fmt.Errorf("Invalid Service Meta: %v", err))
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid Service Meta: %v", err)}
}
// Run validation. This is the same validation that would happen on
// the catalog endpoint so it helps ensure the sync will work properly.
if err := ns.Validate(); err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, err.Error())
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Validation failed: %v", err.Error())}
}
// Verify the check type.
chkTypes, err := args.CheckTypes()
if err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, fmt.Errorf("Invalid check: %v", err))
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid check: %v", err)}
}
for _, check := range chkTypes {
if check.Status != "" && !structs.ValidStatus(check.Status) {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, "Status for checks must 'passing', 'warning', 'critical'")
- return nil, nil
+ return nil, BadRequestError{Reason: "Status for checks must 'passing', 'warning', 'critical'"}
}
}
@@ -1221,9 +1197,7 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http.
}
if sidecar != nil {
if err := sidecar.Validate(); err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, err.Error())
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Failed Validation: %v", err.Error())}
}
// Make sure we are allowed to register the sidecar using the token
// specified (might be specific to sidecar or the same one as the overall
@@ -1324,25 +1298,19 @@ func (s *HTTPHandlers) AgentServiceMaintenance(resp http.ResponseWriter, req *ht
sid := structs.NewServiceID(serviceID, nil)
if sid.ID == "" {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, "Missing service ID")
- return nil, nil
+ return nil, BadRequestError{Reason: "Missing service ID"}
}
// Ensure we have some action
params := req.URL.Query()
if _, ok := params["enable"]; !ok {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, "Missing value for enable")
- return nil, nil
+ return nil, BadRequestError{Reason: "Missing value for enable"}
}
raw := params.Get("enable")
enable, err := strconv.ParseBool(raw)
if err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprintf(resp, "Invalid value for enable: %q", raw)
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid value for enable: %q", raw)}
}
// Get the provided token, if any, and vet against any ACL policies.
@@ -1371,15 +1339,11 @@ func (s *HTTPHandlers) AgentServiceMaintenance(resp http.ResponseWriter, req *ht
if enable {
reason := params.Get("reason")
if err = s.agent.EnableServiceMaintenance(sid, reason, token); err != nil {
- resp.WriteHeader(http.StatusNotFound)
- fmt.Fprint(resp, err.Error())
- return nil, nil
+ return nil, NotFoundError{Reason: err.Error()}
}
} else {
if err = s.agent.DisableServiceMaintenance(sid); err != nil {
- resp.WriteHeader(http.StatusNotFound)
- fmt.Fprint(resp, err.Error())
- return nil, nil
+ return nil, NotFoundError{Reason: err.Error()}
}
}
s.syncChanges()
@@ -1390,17 +1354,13 @@ func (s *HTTPHandlers) AgentNodeMaintenance(resp http.ResponseWriter, req *http.
// Ensure we have some action
params := req.URL.Query()
if _, ok := params["enable"]; !ok {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprint(resp, "Missing value for enable")
- return nil, nil
+ return nil, BadRequestError{Reason: "Missing value for enable"}
}
raw := params.Get("enable")
enable, err := strconv.ParseBool(raw)
if err != nil {
- resp.WriteHeader(http.StatusBadRequest)
- fmt.Fprintf(resp, "Invalid value for enable: %q", raw)
- return nil, nil
+ return nil, BadRequestError{Reason: fmt.Sprintf("Invalid value for enable: %q", raw)}
}
// Get the provided token, if any, and vet against any ACL policies.
@@ -1507,8 +1467,8 @@ func (s *HTTPHandlers) AgentMonitor(resp http.ResponseWriter, req *http.Request)
}
func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) (interface{}, error) {
- if s.checkACLDisabled(resp, req) {
- return nil, nil
+ if s.checkACLDisabled() {
+ return nil, UnauthorizedError{Reason: "ACL support disabled"}
}
// Fetch the ACL token, if any, and enforce agent policy.
diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go
index a240aebed..7f4273269 100644
--- a/agent/agent_endpoint_test.go
+++ b/agent/agent_endpoint_test.go
@@ -660,9 +660,9 @@ func TestAgent_Service(t *testing.T) {
wantResp: &updatedResponse,
},
{
- name: "err: non-existent proxy",
- url: "/v1/agent/service/nope",
- wantCode: 404,
+ name: "err: non-existent proxy",
+ url: "/v1/agent/service/nope",
+ wantErr: "unknown service ID: nope",
},
{
name: "err: bad ACL for service",
@@ -3784,9 +3784,6 @@ func testAgent_RegisterService_InvalidAddress(t *testing.T, extraHCL string) {
if got, want := resp.Code, 400; got != want {
t.Fatalf("got code %d want %d", got, want)
}
- if got, want := resp.Body.String(), "Invalid service address"; got != want {
- t.Fatalf("got body %q want %q", got, want)
- }
})
}
}
diff --git a/agent/http.go b/agent/http.go
index ddc0dffc8..5fc84ea11 100644
--- a/agent/http.go
+++ b/agent/http.go
@@ -69,6 +69,15 @@ func (e NotFoundError) Error() string {
return e.Reason
}
+// UnauthorizedError should be returned by a handler when the request lacks valid authorization.
+type UnauthorizedError struct {
+ Reason string
+}
+
+func (e UnauthorizedError) Error() string {
+ return e.Reason
+}
+
// CodeWithPayloadError allow returning non HTTP 200
// Error codes while not returning PlainText payload
type CodeWithPayloadError struct {
@@ -241,7 +250,8 @@ func (s *HTTPHandlers) handler(enableDebug bool) http.Handler {
// If enableDebug is not set, and ACLs are disabled, write
// an unauthorized response
- if !enableDebug && s.checkACLDisabled(resp, req) {
+ if !enableDebug && s.checkACLDisabled() {
+ resp.WriteHeader(http.StatusUnauthorized)
return
}
@@ -423,6 +433,11 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc
return ok
}
+ isUnauthorized := func(err error) bool {
+ _, ok := err.(UnauthorizedError)
+ return ok
+ }
+
isTooManyRequests := func(err error) bool {
// Sadness net/rpc can't do nice typed errors so this is all we got
return err.Error() == consul.ErrRateLimited.Error()
@@ -467,6 +482,9 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc
case isNotFound(err):
resp.WriteHeader(http.StatusNotFound)
fmt.Fprint(resp, err.Error())
+ case isUnauthorized(err):
+ resp.WriteHeader(http.StatusUnauthorized)
+ fmt.Fprint(resp, err.Error())
case isTooManyRequests(err):
resp.WriteHeader(http.StatusTooManyRequests)
fmt.Fprint(resp, err.Error())
From 5f6bf369af51557540bfd2d46367cc90675969ce Mon Sep 17 00:00:00 2001
From: Dhia Ayachi
Date: Wed, 5 Jan 2022 12:17:47 -0500
Subject: [PATCH 050/225] reset `coalesceTimer` to nil as soon as the event is
consumed (#11924)
* reset `coalesceTimer` to nil as soon as the event is consumed
* add change log
* refactor to add relevant test.
* fix linter
* Apply suggestions from code review
Co-authored-by: Freddy
* remove non needed check
Co-authored-by: Freddy
---
.changelog/11924.txt | 3 +
agent/proxycfg/manager.go | 22 ++---
agent/proxycfg/manager_test.go | 141 ++++++++++++++++++++++++++++++++-
agent/proxycfg/state.go | 13 ++-
4 files changed, 160 insertions(+), 19 deletions(-)
create mode 100644 .changelog/11924.txt
diff --git a/.changelog/11924.txt b/.changelog/11924.txt
new file mode 100644
index 000000000..d76445017
--- /dev/null
+++ b/.changelog/11924.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+xds: fix a deadlock when the snapshot channel already have a snapshot to be consumed.
+```
diff --git a/agent/proxycfg/manager.go b/agent/proxycfg/manager.go
index 083291c13..d5d102b1e 100644
--- a/agent/proxycfg/manager.go
+++ b/agent/proxycfg/manager.go
@@ -127,7 +127,7 @@ func (m *Manager) Run() error {
defer m.State.StopNotify(stateCh)
for {
- m.syncState()
+ m.syncState(m.notifyBroadcast)
// Wait for a state change
_, ok := <-stateCh
@@ -140,7 +140,7 @@ func (m *Manager) Run() error {
// syncState is called whenever the local state notifies a change. It holds the
// lock while finding any new or updated proxies and removing deleted ones.
-func (m *Manager) syncState() {
+func (m *Manager) syncState(notifyBroadcast func(ch <-chan ConfigSnapshot)) {
m.mu.Lock()
defer m.mu.Unlock()
@@ -160,7 +160,7 @@ func (m *Manager) syncState() {
// know that so we'd need to set it here if not during registration of the
// proxy service. Sidecar Service in the interim can do that, but we should
// validate more generally that that is always true.
- err := m.ensureProxyServiceLocked(svc)
+ err := m.ensureProxyServiceLocked(svc, notifyBroadcast)
if err != nil {
m.Logger.Error("failed to watch proxy service",
"service", sid.String(),
@@ -179,7 +179,7 @@ func (m *Manager) syncState() {
}
// ensureProxyServiceLocked adds or changes the proxy to our state.
-func (m *Manager) ensureProxyServiceLocked(ns *structs.NodeService) error {
+func (m *Manager) ensureProxyServiceLocked(ns *structs.NodeService, notifyBroadcast func(ch <-chan ConfigSnapshot)) error {
sid := ns.CompoundServiceID()
// Retrieve the token used to register the service, or fallback to the
@@ -227,16 +227,18 @@ func (m *Manager) ensureProxyServiceLocked(ns *structs.NodeService) error {
m.proxies[sid] = state
// Start a goroutine that will wait for changes and broadcast them to watchers.
- go func(ch <-chan ConfigSnapshot) {
- // Run until ch is closed
- for snap := range ch {
- m.notify(&snap)
- }
- }(ch)
+ go notifyBroadcast(ch)
return nil
}
+func (m *Manager) notifyBroadcast(ch <-chan ConfigSnapshot) {
+ // Run until ch is closed
+ for snap := range ch {
+ m.notify(&snap)
+ }
+}
+
// removeProxyService is called when a service deregisters and frees all
// resources for that service.
func (m *Manager) removeProxyServiceLocked(proxyID structs.ServiceID) {
diff --git a/agent/proxycfg/manager_test.go b/agent/proxycfg/manager_test.go
index 9e659b5f0..cdb271ee3 100644
--- a/agent/proxycfg/manager_test.go
+++ b/agent/proxycfg/manager_test.go
@@ -598,7 +598,146 @@ func TestManager_SyncState_DefaultToken(t *testing.T) {
err = state.AddServiceWithChecks(srv, nil, "")
require.NoError(t, err)
- m.syncState()
+ m.syncState(m.notifyBroadcast)
require.Equal(t, "default-token", m.proxies[srv.CompoundServiceID()].serviceInstance.token)
}
+
+func TestManager_SyncState_No_Notify(t *testing.T) {
+ types := NewTestCacheTypes(t)
+ c := TestCacheWithTypes(t, types)
+ logger := testutil.Logger(t)
+ tokens := new(token.Store)
+ tokens.UpdateUserToken("default-token", token.TokenSourceConfig)
+
+ state := local.NewState(local.Config{}, logger, tokens)
+ state.TriggerSyncChanges = func() {}
+
+ m, err := NewManager(ManagerConfig{
+ Cache: c,
+ Health: &health.Client{Cache: c, CacheName: cachetype.HealthServicesName},
+ State: state,
+ Tokens: tokens,
+ Source: &structs.QuerySource{Datacenter: "dc1"},
+ Logger: logger,
+ })
+ require.NoError(t, err)
+ defer m.Close()
+
+ srv := &structs.NodeService{
+ Kind: structs.ServiceKindConnectProxy,
+ ID: "web-sidecar-proxy",
+ Service: "web-sidecar-proxy",
+ Port: 9999,
+ Meta: map[string]string{},
+ Proxy: structs.ConnectProxyConfig{
+ DestinationServiceID: "web",
+ DestinationServiceName: "web",
+ LocalServiceAddress: "127.0.0.1",
+ LocalServicePort: 8080,
+ Config: map[string]interface{}{
+ "foo": "bar",
+ },
+ },
+ }
+
+ err = state.AddServiceWithChecks(srv, nil, "")
+ require.NoError(t, err)
+
+ readEvent := make(chan bool, 1)
+ snapSent := make(chan bool, 1)
+
+ m.syncState(func(ch <-chan ConfigSnapshot) {
+ for {
+ <-readEvent
+ snap := <-ch
+ m.notify(&snap)
+ snapSent <- true
+ }
+ })
+
+ // Get the relevant notification Channel, should only have 1
+ notifyCH := m.proxies[srv.CompoundServiceID()].ch
+
+ // update the leaf certs
+ roots, issuedCert := TestCerts(t)
+ notifyCH <- cache.UpdateEvent{
+ CorrelationID: leafWatchID,
+ Result: issuedCert,
+ Err: nil,
+ }
+ // at this point the snapshot should not be valid and not be sent
+ after := time.After(200 * time.Millisecond)
+ select {
+ case <-snapSent:
+ t.Fatal("snap should not be valid")
+ case <-after:
+
+ }
+
+ // update the root certs
+ notifyCH <- cache.UpdateEvent{
+ CorrelationID: rootsWatchID,
+ Result: roots,
+ Err: nil,
+ }
+
+ // at this point the snapshot should not be valid and not be sent
+ after = time.After(200 * time.Millisecond)
+ select {
+ case <-snapSent:
+ t.Fatal("snap should not be valid")
+ case <-after:
+
+ }
+
+ // prepare to read a snapshot update as the next update should make the snapshot valid
+ readEvent <- true
+
+ // update the intentions
+ notifyCH <- cache.UpdateEvent{
+ CorrelationID: intentionsWatchID,
+ Result: &structs.IndexedIntentionMatches{},
+ Err: nil,
+ }
+
+ // at this point we have a valid snapshot
+ after = time.After(500 * time.Millisecond)
+ select {
+ case <-snapSent:
+ case <-after:
+ t.Fatal("snap should be valid")
+
+ }
+
+ // send two snapshots back to back without reading them to overflow the snapshot channel and get to the default use case
+ for i := 0; i < 2; i++ {
+ time.Sleep(250 * time.Millisecond)
+ notifyCH <- cache.UpdateEvent{
+ CorrelationID: leafWatchID,
+ Result: issuedCert,
+ Err: nil,
+ }
+ }
+
+ // make sure that we are not receiving any snapshot and wait for the snapshots to be processed
+ after = time.After(500 * time.Millisecond)
+ select {
+ case <-snapSent:
+ t.Fatal("snap should not be sent")
+ case <-after:
+ }
+
+ // now make sure that both snapshots got propagated
+ for i := 0; i < 2; i++ {
+
+ readEvent <- true
+ after = time.After(500 * time.Millisecond)
+ select {
+ case <-snapSent:
+ case <-after:
+ t.Fatal("snap should be valid")
+
+ }
+ }
+}
diff --git a/agent/proxycfg/state.go b/agent/proxycfg/state.go
index 0b535d0e4..586bc3938 100644
--- a/agent/proxycfg/state.go
+++ b/agent/proxycfg/state.go
@@ -294,6 +294,8 @@ func (s *state) run(ctx context.Context, snap *ConfigSnapshot) {
}
case <-sendCh:
+ // Allow the next change to trigger a send
+ coalesceTimer = nil
// Make a deep copy of snap so we don't mutate any of the embedded structs
// etc on future updates.
snapCopy, err := snap.Clone()
@@ -307,9 +309,6 @@ func (s *state) run(ctx context.Context, snap *ConfigSnapshot) {
case s.snapCh <- *snapCopy:
s.logger.Trace("Delivered new snapshot to proxy config watchers")
- // Allow the next change to trigger a send
- coalesceTimer = nil
-
// Skip rest of loop - there is nothing to send since nothing changed on
// this iteration
continue
@@ -320,11 +319,9 @@ func (s *state) run(ctx context.Context, snap *ConfigSnapshot) {
s.logger.Trace("Failed to deliver new snapshot to proxy config watchers")
// Reset the timer to retry later. This is to ensure we attempt to redeliver the updated snapshot shortly.
- if coalesceTimer == nil {
- coalesceTimer = time.AfterFunc(coalesceTimeout, func() {
- sendCh <- struct{}{}
- })
- }
+ coalesceTimer = time.AfterFunc(coalesceTimeout, func() {
+ sendCh <- struct{}{}
+ })
// Do not reset coalesceTimer since we just queued a timer-based refresh
continue
From 407b0b89634e13447364b66dfb8d84ed35d82cf2 Mon Sep 17 00:00:00 2001
From: "Chris S. Kim"
Date: Wed, 5 Jan 2022 12:24:44 -0500
Subject: [PATCH 051/225] Fix test for ENT (#11941)
---
agent/local/state_test.go | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/agent/local/state_test.go b/agent/local/state_test.go
index 62ebd4040..f2c51a281 100644
--- a/agent/local/state_test.go
+++ b/agent/local/state_test.go
@@ -2149,12 +2149,14 @@ func TestState_RemoveServiceErrorMessages(t *testing.T) {
require.NoError(err)
// Attempt to remove service that doesn't exist
- err = state.RemoveService(structs.NewServiceID("db", nil))
- require.Contains(err.Error(), `Unknown service ID "db"`)
+ sid := structs.NewServiceID("db", nil)
+ err = state.RemoveService(sid)
+ require.Contains(err.Error(), fmt.Sprintf(`Unknown service ID %q`, sid))
// Attempt to remove service by name (which isn't valid)
- err = state.RemoveService(structs.NewServiceID("web-name", nil))
- require.Contains(err.Error(), `Unknown service ID "web-name"`)
+ sid2 := structs.NewServiceID("web-name", nil)
+ err = state.RemoveService(sid2)
+ require.Contains(err.Error(), fmt.Sprintf(`Unknown service ID %q`, sid2))
// Attempt to remove service by id (valid)
err = state.RemoveService(structs.NewServiceID("web-id", nil))
From ea2ae4b6375cc088cf05c6fda0d6f03d71b6b689 Mon Sep 17 00:00:00 2001
From: trujillo-adam
Date: Wed, 5 Jan 2022 12:01:10 -0800
Subject: [PATCH 052/225] tweaks to the language used in the requirements
section
---
.../config-entries/exported-services.mdx | 78 ++++++++++---------
1 file changed, 40 insertions(+), 38 deletions(-)
diff --git a/website/content/docs/connect/config-entries/exported-services.mdx b/website/content/docs/connect/config-entries/exported-services.mdx
index 3965f657a..def7a2040 100644
--- a/website/content/docs/connect/config-entries/exported-services.mdx
+++ b/website/content/docs/connect/config-entries/exported-services.mdx
@@ -10,29 +10,28 @@ description: >-
-This topic describes the `exported-services` configuration entry type. The `exported-services` configuration entry enables Consul to export service instances to other admin partitions from a single file. This enables your services to be networked across admin partitions. See [Admin Partitions](/docs/enterprise/admin-partitions) for additional information.
+This topic describes the `exported-services` configuration entry type. The `exported-services` configuration entry enables Consul to export service instances to other admin partitions from a single file. This enables your services to be networked across admin partitions. See [Admin Partitions](/docs/enterprise/admin-partitions) for additional information.
-> **v1.11.0+:** This config entry is supported in Consul Enterprise versions 1.11.0+.
## Introduction
-You can configure Consul to export services contained in an admin partition to one or more additional partitions by declaring the `exported-services` configuration entry in the `kind` field. This enables you to route traffic between services in different clusters that share a single set of Consul servers.
+You can configure Consul to export services contained in an admin partition to one or more additional partitions by declaring the `exported-services` configuration entry in the `kind` field. This enables you to route traffic between services in different clusters that share a single set of Consul servers.
You can configure the settings defined in the `exported-services` configuration entry to apply to all namespaces and federated datacenters.
## Requirements
-* A Consul Enterprise binary
-* A partition that corresponds to the configuration entry. As in, the exported services config entry for partition "frontend" requires that the "frontend" partition exists
-
+- A Consul Enterprise binary
+- A corresponding partition that the configuration entry can export to. For example, the `exported-services` configuration entry for a partition named `frontend` requires an existing `frontend` partition.
## Usage
1. Verify that your datacenter meets the conditions specified in the [Requirements](#requirements).
1. Specify the `exported-services` configuration in the agent configuration file (see [`config_entries`](/docs/agent/options#config_entries)) as described in [Configuration](#configuration).
1. Apply the configuration using one of the following methods:
- * Kubernetes CRD: Refer to the [Custom Resource Definitions](/docs/k8s/crds) documentation for details.
- * Issue the `consul config write` command: Refer to the [Consul Config Write](/commands/config/write) documentation for details.
+ - Kubernetes CRD: Refer to the [Custom Resource Definitions](/docs/k8s/crds) documentation for details.
+ - Issue the `consul config write` command: Refer to the [Consul Config Write](/commands/config/write) documentation for details.
## Configuration
@@ -48,15 +47,16 @@ Name = ""
Services = [
{
Name = ""
- Namespace = ""
+ Namespace = ""
Consumers = [
{
Partition = ""
- },
+ },
]
}
]
```
+
@@ -65,13 +65,14 @@ apiVersion: consul.hashicorp.com/v1alpha1
Kind: ExportedServices
metadata:
name:
-spec:
+spec:
services:
- - name:
- namespace:
- consumers:
- - partition:
+ - name:
+ namespace:
+ consumers:
+ - partition:
```
+
@@ -91,6 +92,7 @@ spec:
}
]
```
+
@@ -98,31 +100,31 @@ spec:
The following table describes the parameters associated with the `exported-services` configuration entry.
-| Parameter | Description | Required | Default |
-| --- | --- | --- | --- |
-| `Kind` | String value that enables the configuration entry. The value should always be `exported-services` (HCL and JSON) or `ExportedServices` (YAML) | Required | None |
-| `Partition` | String value that specifies the name of the partition that contains the services you want to export. | Required | None |
-| `Name` | String value that specifies the name of the partition that contains the services you want to export. | Required | None |
-| `Services` | List of objects that specify which services to export. See [`Services`](#services) for details. | Required | None|
-| `Meta` | Object that defines a map of the max 64 key/value pairs. | Optional | None |
+| Parameter | Description | Required | Default |
+| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- |
+| `Kind` | String value that enables the configuration entry. The value should always be `exported-services` (HCL and JSON) or `ExportedServices` (YAML) | Required | None |
+| `Partition` | String value that specifies the name of the partition that contains the services you want to export. | Required | None |
+| `Name` | String value that specifies the name of the partition that contains the services you want to export. | Required | None |
+| `Services` | List of objects that specify which services to export. See [`Services`](#services) for details. | Required | None |
+| `Meta` | Object that defines a map of the max 64 key/value pairs. | Optional | None |
### Services
The `Services` parameter contains one or more lists of parameters that specify which services to export, which namespaces the services reside, and the destination partition for the exported services. Each list in the `Services` block must contain the following parameters:
-* `Name`: Specifies the name of the service to export. You can use a asterisk wildcard (`*`) to include all services in the namespace.
-* `Namespace`: Specifies the namespace containing the services to export. You can use a asterisk wildcard (`*`) to include all namespaces in the partition.
-* `Consumers`: Specifies one ore more objects that identify a destination partition for the exported services.
+- `Name`: Specifies the name of the service to export. You can use a asterisk wildcard (`*`) to include all services in the namespace.
+- `Namespace`: Specifies the namespace containing the services to export. You can use a asterisk wildcard (`*`) to include all namespaces in the partition.
+- `Consumers`: Specifies one ore more objects that identify a destination partition for the exported services.
## Example
-The following example configures the agent to export the `billing` service from the `default` namespace of the `finance` admin partition to the `frontend` and `backend` partitions. Additionally, all services in all namespaces within the `finance` partition will be exported to the `monitoring` partition.
+The following example configures the agent to export the `billing` service from the `default` namespace of the `finance` admin partition to the `frontend` and `backend` partitions. Additionally, all services in all namespaces within the `finance` partition will be exported to the `monitoring` partition.
```hcl
-Kind = "exported-services"
+Kind = "exported-services"
Partition = "finance"
Name = "finance"
@@ -157,19 +159,19 @@ Services = [
```yaml
apiVersion: consul.hashicorp.com/v1alpha1
Kind: ExportedServices
-metadata:
+metadata:
name: finance
spec:
services:
- - name: mesh-gateway
- namespace: default
- consumers:
- - partition: default
- - name: billing
- namespace: default
- consumers:
- - partition: frontend
- - partition: backend
+ - name: mesh-gateway
+ namespace: default
+ consumers:
+ - partition: default
+ - name: billing
+ namespace: default
+ consumers:
+ - partition: frontend
+ - partition: backend
```
@@ -215,8 +217,8 @@ When an exported service has been imported to another partition, you can use the
$ curl 'localhost:8500/v1/health/connect/billing?partition=finance'
```
-An ACL token with `service:write` permissions is required for the partition from which the query is made. If the call in the previous example is made from a service named `web` in a partition named `frontend`, then the request will require a token with `write` permissions to `web` in the `frontend` partition.
+An ACL token with `service:write` permissions is required for the partition from which the query is made. If the call in the previous example is made from a service named `web` in a partition named `frontend`, then the request will require a token with `write` permissions to `web` in the `frontend` partition.
-Exports are available to all services in the consumer partition. In the previous example, any service with `write` permissions for the `frontend` partition will be able to read exports.
+Exports are available to all services in the consumer partition. In the previous example, any service with `write` permissions for the `frontend` partition will be able to read exports.
See [Health HTTP Endpoint](/api-docs/health) for additional information.
From f7f5aca0588fb45b5ff37630d2ef71bdaa97de06 Mon Sep 17 00:00:00 2001
From: "Chris S. Kim"
Date: Wed, 5 Jan 2022 15:18:08 -0500
Subject: [PATCH 053/225] Fix test for ENT (#11946)
---
agent/agent_endpoint_test.go | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go
index 7f4273269..5d7bed8ba 100644
--- a/agent/agent_endpoint_test.go
+++ b/agent/agent_endpoint_test.go
@@ -662,7 +662,7 @@ func TestAgent_Service(t *testing.T) {
{
name: "err: non-existent proxy",
url: "/v1/agent/service/nope",
- wantErr: "unknown service ID: nope",
+ wantErr: fmt.Sprintf("unknown service ID: %s", structs.NewServiceID("nope", nil)),
},
{
name: "err: bad ACL for service",
@@ -4748,7 +4748,8 @@ func TestAgent_ServiceMaintenance_BadRequest(t *testing.T) {
resp := httptest.NewRecorder()
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, 404, resp.Code)
- require.Contains(t, resp.Body.String(), `Unknown service ID "_nope_"`)
+ sid := structs.NewServiceID("_nope_", nil)
+ require.Contains(t, resp.Body.String(), fmt.Sprintf(`Unknown service ID %q`, sid))
})
}
From affe97e22d46263352fcf046560f6b884c1d4549 Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Thu, 23 Dec 2021 16:30:36 -0500
Subject: [PATCH 054/225] config: correctly capture all errors.
Some calls to multierror.Append were not using the existing b.err, which meant we
were losing all previous errors.
---
agent/config/builder.go | 10 +++++-----
agent/config/builder_test.go | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/agent/config/builder.go b/agent/config/builder.go
index 7f3ab5e4e..987a04fbb 100644
--- a/agent/config/builder.go
+++ b/agent/config/builder.go
@@ -1631,7 +1631,7 @@ func (b *builder) serviceVal(v *ServiceDefinition) *structs.ServiceDefinition {
meta := make(map[string]string)
if err := structs.ValidateServiceMetadata(kind, v.Meta, false); err != nil {
- b.err = multierror.Append(fmt.Errorf("invalid meta for service %s: %v", stringVal(v.Name), err))
+ b.err = multierror.Append(b.err, fmt.Errorf("invalid meta for service %s: %v", stringVal(v.Name), err))
} else {
meta = v.Meta
}
@@ -1646,13 +1646,13 @@ func (b *builder) serviceVal(v *ServiceDefinition) *structs.ServiceDefinition {
}
if err := structs.ValidateWeights(serviceWeights); err != nil {
- b.err = multierror.Append(fmt.Errorf("Invalid weight definition for service %s: %s", stringVal(v.Name), err))
+ b.err = multierror.Append(b.err, fmt.Errorf("Invalid weight definition for service %s: %s", stringVal(v.Name), err))
}
if (v.Port != nil || v.Address != nil) && (v.SocketPath != nil) {
- b.err = multierror.Append(
+ b.err = multierror.Append(b.err,
fmt.Errorf("service %s cannot have both socket path %s and address/port",
- stringVal(v.Name), stringVal(v.SocketPath)), b.err)
+ stringVal(v.Name), stringVal(v.SocketPath)))
}
return &structs.ServiceDefinition{
@@ -1890,7 +1890,7 @@ func (b *builder) durationValWithDefault(name string, v *string, defaultVal time
}
d, err := time.ParseDuration(*v)
if err != nil {
- b.err = multierror.Append(fmt.Errorf("%s: invalid duration: %q: %s", name, *v, err))
+ b.err = multierror.Append(b.err, fmt.Errorf("%s: invalid duration: %q: %s", name, *v, err))
}
return d
}
diff --git a/agent/config/builder_test.go b/agent/config/builder_test.go
index 5901431a0..80ad7b368 100644
--- a/agent/config/builder_test.go
+++ b/agent/config/builder_test.go
@@ -291,3 +291,39 @@ func TestLoad_EmptyClientAddr(t *testing.T) {
})
}
}
+
+func TestBuilder_DurationVal_InvalidDuration(t *testing.T) {
+ b := builder{}
+ badDuration1 := "not-a-duration"
+ badDuration2 := "also-not"
+ b.durationVal("field1", &badDuration1)
+ b.durationVal("field1", &badDuration2)
+
+ require.Error(t, b.err)
+ require.Contains(t, b.err.Error(), "2 errors")
+ require.Contains(t, b.err.Error(), badDuration1)
+ require.Contains(t, b.err.Error(), badDuration2)
+}
+
+func TestBuilder_ServiceVal_MultiError(t *testing.T) {
+ b := builder{}
+ b.serviceVal(&ServiceDefinition{
+ Meta: map[string]string{"": "empty-key"},
+ Port: intPtr(12345),
+ SocketPath: strPtr("/var/run/socket.sock"),
+ Checks: []CheckDefinition{
+ {Interval: strPtr("bad-interval")},
+ },
+ Weights: &ServiceWeights{Passing: intPtr(-1)},
+ })
+ require.Error(t, b.err)
+ require.Contains(t, b.err.Error(), "4 errors")
+ require.Contains(t, b.err.Error(), "bad-interval")
+ require.Contains(t, b.err.Error(), "Key cannot be blank")
+ require.Contains(t, b.err.Error(), "Invalid weight")
+ require.Contains(t, b.err.Error(), "cannot have both socket path")
+}
+
+func intPtr(v int) *int {
+ return &v
+}
From fd084c15c3918ce279708db44e31f2730558e648 Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Thu, 23 Dec 2021 16:34:54 -0500
Subject: [PATCH 055/225] cli: use file mode 0600 when saving a snapshot
So that other users on the machine can not access the snapshot data.
---
command/snapshot/save/snapshot_save.go | 7 ++++---
command/snapshot/save/snapshot_save_test.go | 4 ++++
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/command/snapshot/save/snapshot_save.go b/command/snapshot/save/snapshot_save.go
index 699cf5f1d..e43dcb612 100644
--- a/command/snapshot/save/snapshot_save.go
+++ b/command/snapshot/save/snapshot_save.go
@@ -5,11 +5,12 @@ import (
"fmt"
"os"
+ "github.com/mitchellh/cli"
+ "github.com/rboyer/safeio"
+
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/command/flags"
"github.com/hashicorp/consul/snapshot"
- "github.com/mitchellh/cli"
- "github.com/rboyer/safeio"
)
func New(ui cli.Ui) *cmd {
@@ -71,7 +72,7 @@ func (c *cmd) Run(args []string) int {
// Save the file first.
unverifiedFile := file + ".unverified"
- if _, err := safeio.WriteToFile(snap, unverifiedFile, 0666); err != nil {
+ if _, err := safeio.WriteToFile(snap, unverifiedFile, 0600); err != nil {
c.UI.Error(fmt.Sprintf("Error writing unverified snapshot file: %s", err))
return 1
}
diff --git a/command/snapshot/save/snapshot_save_test.go b/command/snapshot/save/snapshot_save_test.go
index 79df0dfc6..10e8abcfe 100644
--- a/command/snapshot/save/snapshot_save_test.go
+++ b/command/snapshot/save/snapshot_save_test.go
@@ -94,6 +94,10 @@ func TestSnapshotSaveCommand(t *testing.T) {
t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String())
}
+ fi, err := os.Stat(file)
+ require.NoError(t, err)
+ require.Equal(t, fi.Mode(), os.FileMode(0600))
+
f, err := os.Open(file)
if err != nil {
t.Fatalf("err: %v", err)
From 4983c2770370150189e1fec81ab7c9da3454d126 Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Thu, 23 Dec 2021 16:56:30 -0500
Subject: [PATCH 056/225] snapshot: return the error from replyFn
The only function passed to SnapshotRPC today always returns a nil error, so there's no
way to exercise this bug in practice. This change is being made for correctness so that
it doesn't become a problem in the future, if we ever pass a different function to
SnapshotRPC.
---
agent/consul/client.go | 2 +-
agent/consul/server.go | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/agent/consul/client.go b/agent/consul/client.go
index ac64d704a..999f98663 100644
--- a/agent/consul/client.go
+++ b/agent/consul/client.go
@@ -347,7 +347,7 @@ func (c *Client) SnapshotRPC(args *structs.SnapshotRequest, in io.Reader, out io
// Let the caller peek at the reply.
if replyFn != nil {
if err := replyFn(&reply); err != nil {
- return nil
+ return err
}
}
diff --git a/agent/consul/server.go b/agent/consul/server.go
index 91082a7d6..e076af721 100644
--- a/agent/consul/server.go
+++ b/agent/consul/server.go
@@ -1347,7 +1347,7 @@ func (s *Server) SnapshotRPC(args *structs.SnapshotRequest, in io.Reader, out io
// Let the caller peek at the reply.
if replyFn != nil {
if err := replyFn(&reply); err != nil {
- return nil
+ return err
}
}
From f91fcb31d280864e5f85c6eb18fa8d69ef02ce6a Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Wed, 5 Jan 2022 17:26:59 -0500
Subject: [PATCH 057/225] changelog
---
.changelog/11918.txt | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 .changelog/11918.txt
diff --git a/.changelog/11918.txt b/.changelog/11918.txt
new file mode 100644
index 000000000..276a77eef
--- /dev/null
+++ b/.changelog/11918.txt
@@ -0,0 +1,6 @@
+```release-note:bug
+config: include all config errors in the error message, previously some could be hidden.
+```
+```release-note:bug
+snapshot: the `snapshot save` command now saves the snapshot with read permission for only the current user.
+```
From f1841e36c97fa8b9e31ac67c93c82459a1573253 Mon Sep 17 00:00:00 2001
From: David Yu
Date: Wed, 5 Jan 2022 21:35:28 -0800
Subject: [PATCH 058/225] docs: Fix indentation for gossipEncryption when using
Vault secrets backend
---
website/content/docs/k8s/installation/vault/gossip.mdx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/website/content/docs/k8s/installation/vault/gossip.mdx b/website/content/docs/k8s/installation/vault/gossip.mdx
index cea8d6923..4e1422d58 100644
--- a/website/content/docs/k8s/installation/vault/gossip.mdx
+++ b/website/content/docs/k8s/installation/vault/gossip.mdx
@@ -76,9 +76,9 @@ global:
enabled: true
consulServerRole: consul-server
consulClientRole: consul-client
- gossipEncryption:
- secretName: secret/data/consul/gossip
- secretKey: key
+ gossipEncryption:
+ secretName: secret/data/consul/gossip
+ secretKey: key
```
Note that `global.gossipEncryption.secretName` is the path of the secret in Vault.
From 09688bdc3827805748d0951fef67f426e975bae4 Mon Sep 17 00:00:00 2001
From: Dhia Ayachi
Date: Thu, 6 Jan 2022 14:09:13 -0500
Subject: [PATCH 059/225] upgrade raft to v1.3.3 (#11958)
* upgrade raft to v1.3.3
* add change log
* reword the changelog
Co-authored-by: FFMMM
Co-authored-by: FFMMM
---
.changelog/11958.txt | 3 +++
go.mod | 2 +-
go.sum | 4 ++--
3 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 .changelog/11958.txt
diff --git a/.changelog/11958.txt b/.changelog/11958.txt
new file mode 100644
index 000000000..80780dcf2
--- /dev/null
+++ b/.changelog/11958.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+Upgrade to raft `1.3.3` which fixes a bug where a read replica node can trigger a raft election and become a leader.
+```
diff --git a/go.mod b/go.mod
index 386a5928e..26decc628 100644
--- a/go.mod
+++ b/go.mod
@@ -52,7 +52,7 @@ require (
github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038
github.com/hashicorp/memberlist v0.3.0
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69
- github.com/hashicorp/raft v1.3.2
+ github.com/hashicorp/raft v1.3.3
github.com/hashicorp/raft-autopilot v0.1.5
github.com/hashicorp/raft-boltdb v0.0.0-20211202195631-7d34b9fb3f42 // indirect
github.com/hashicorp/raft-boltdb/v2 v2.2.0
diff --git a/go.sum b/go.sum
index 58d66cff8..72542c796 100644
--- a/go.sum
+++ b/go.sum
@@ -289,8 +289,8 @@ github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mo
github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
-github.com/hashicorp/raft v1.3.2 h1:j2tqHqFnDdWCepLxzuo3b6WzS2krIweBrvEoqBbWMTo=
-github.com/hashicorp/raft v1.3.2/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
+github.com/hashicorp/raft v1.3.3 h1:Xr6DSHC5cIM8kzxu+IgoT/+MeNeUNeWin3ie6nlSrMg=
+github.com/hashicorp/raft v1.3.3/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
github.com/hashicorp/raft-autopilot v0.1.5 h1:onEfMH5uHVdXQqtas36zXUHEZxLdsJVu/nXHLcLdL1I=
github.com/hashicorp/raft-autopilot v0.1.5/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw=
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=
From 7e0b8354a570efe6020f0e3801abf6a27897bb5c Mon Sep 17 00:00:00 2001
From: Dhia Ayachi
Date: Thu, 6 Jan 2022 14:33:06 -0500
Subject: [PATCH 060/225] clone the service under lock to avoid a data race
(#11940)
* clone the service under lock to avoid a data race
* add change log
* create a struct and copy the pointer to mutate it to avoid a data race
* fix failing test
* revert added space
* add comments, to clarify the data race.
---
.changelog/11940.txt | 3 +++
agent/local/state.go | 23 +++++++++++++++--------
agent/local/state_test.go | 6 ++++++
3 files changed, 24 insertions(+), 8 deletions(-)
create mode 100644 .changelog/11940.txt
diff --git a/.changelog/11940.txt b/.changelog/11940.txt
new file mode 100644
index 000000000..22278079f
--- /dev/null
+++ b/.changelog/11940.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+ Mutate `NodeService` struct properly to avoid a data race.
+```
diff --git a/agent/local/state.go b/agent/local/state.go
index 03db0badb..d8ad529f7 100644
--- a/agent/local/state.go
+++ b/agent/local/state.go
@@ -1082,27 +1082,34 @@ func (l *State) updateSyncState() error {
continue
}
+ // to avoid a data race with the service struct,
+ // We copy the Service struct, mutate it and replace the pointer
+ svc := *ls.Service
+
// If our definition is different, we need to update it. Make a
// copy so that we don't retain a pointer to any actual state
// store info for in-memory RPCs.
- if ls.Service.EnableTagOverride {
- ls.Service.Tags = make([]string, len(rs.Tags))
- copy(ls.Service.Tags, rs.Tags)
+ if svc.EnableTagOverride {
+ svc.Tags = make([]string, len(rs.Tags))
+ copy(svc.Tags, rs.Tags)
}
// Merge any tagged addresses with the consul- prefix (set by the server)
// back into the local state.
- if !reflect.DeepEqual(ls.Service.TaggedAddresses, rs.TaggedAddresses) {
- if ls.Service.TaggedAddresses == nil {
- ls.Service.TaggedAddresses = make(map[string]structs.ServiceAddress)
+ if !reflect.DeepEqual(svc.TaggedAddresses, rs.TaggedAddresses) {
+ if svc.TaggedAddresses == nil {
+ svc.TaggedAddresses = make(map[string]structs.ServiceAddress)
}
for k, v := range rs.TaggedAddresses {
if strings.HasPrefix(k, structs.MetaKeyReservedPrefix) {
- ls.Service.TaggedAddresses[k] = v
+ svc.TaggedAddresses[k] = v
}
}
}
- ls.InSync = ls.Service.IsSame(rs)
+ ls.InSync = svc.IsSame(rs)
+
+ // replace the service pointer to the new mutated struct
+ ls.Service = &svc
}
// Check which checks need syncing
diff --git a/agent/local/state_test.go b/agent/local/state_test.go
index f2c51a281..679adba84 100644
--- a/agent/local/state_test.go
+++ b/agent/local/state_test.go
@@ -415,6 +415,12 @@ func TestAgentAntiEntropy_Services_ConnectProxy(t *testing.T) {
// All the services should match
for id, serv := range services.NodeServices.Services {
serv.CreateIndex, serv.ModifyIndex = 0, 0
+ if serv.TaggedAddresses != nil {
+ serviceVIP := serv.TaggedAddresses[structs.TaggedAddressVirtualIP].Address
+ assert.NotEmpty(serviceVIP)
+ vips[serviceVIP] = struct{}{}
+ }
+ serv.TaggedAddresses = nil
switch id {
case "mysql-proxy":
assert.Equal(srv1, serv)
From b13fb553acff77f009982e2b6bf6350314e81b7b Mon Sep 17 00:00:00 2001
From: Blake Covarrubias
Date: Thu, 6 Jan 2022 12:38:37 -0800
Subject: [PATCH 061/225] api: Return 404 when deregistering a non-existent
check (#11950)
Update the `/agent/check/deregister/` API endpoint to return a 404
HTTP response code when an attempt is made to de-register a check ID
that does not exist on the agent.
This brings the behavior of /agent/check/deregister/ in line with the
behavior of /agent/service/deregister/ which was changed in #10632 to
similarly return a 404 when de-registering non-existent services.
Fixes #5821
---
.changelog/11950.txt | 3 +++
agent/acl.go | 4 +++-
agent/agent_endpoint_test.go | 33 +++++++++++++++++++++++++++------
3 files changed, 33 insertions(+), 7 deletions(-)
create mode 100644 .changelog/11950.txt
diff --git a/.changelog/11950.txt b/.changelog/11950.txt
new file mode 100644
index 000000000..6e9147674
--- /dev/null
+++ b/.changelog/11950.txt
@@ -0,0 +1,3 @@
+```release-note:improvement
+api: Return 404 when de-registering a non-existent check
+```
diff --git a/agent/acl.go b/agent/acl.go
index ae7efdde1..fa2259cfd 100644
--- a/agent/acl.go
+++ b/agent/acl.go
@@ -149,7 +149,9 @@ func (a *Agent) vetCheckUpdateWithAuthorizer(authz acl.Authorizer, checkID struc
}
}
} else {
- return fmt.Errorf("Unknown check ID %q. Ensure that the check ID is passed, not the check name.", checkID.String())
+ return NotFoundError{Reason: fmt.Sprintf(
+ "Unknown check ID %q. Ensure that the check ID is passed, not the check name.",
+ checkID.String())}
}
return nil
diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go
index 5d7bed8ba..6e5025dd2 100644
--- a/agent/agent_endpoint_test.go
+++ b/agent/agent_endpoint_test.go
@@ -2889,12 +2889,19 @@ func TestAgent_DeregisterCheck(t *testing.T) {
t.Fatalf("err: %v", err)
}
- req, _ := http.NewRequest("PUT", "/v1/agent/check/deregister/test", nil)
- resp := httptest.NewRecorder()
- a.srv.h.ServeHTTP(resp, req)
- if http.StatusOK != resp.Code {
- t.Fatalf("expected 200 but got %v", resp.Code)
- }
+ t.Run("remove registered check", func(t *testing.T) {
+ req, _ := http.NewRequest("PUT", "/v1/agent/check/deregister/test", nil)
+ resp := httptest.NewRecorder()
+ a.srv.h.ServeHTTP(resp, req)
+ require.Equal(t, http.StatusOK, resp.Code)
+ })
+
+ t.Run("remove non-existent check", func(t *testing.T) {
+ req, _ := http.NewRequest("PUT", "/v1/agent/check/deregister/test", nil)
+ resp := httptest.NewRecorder()
+ a.srv.h.ServeHTTP(resp, req)
+ require.Equal(t, http.StatusNotFound, resp.Code)
+ })
// Ensure we have a check mapping
requireCheckMissing(t, a, "test")
@@ -2928,6 +2935,20 @@ func TestAgent_DeregisterCheckACLDeny(t *testing.T) {
a.srv.h.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
})
+
+ t.Run("non-existent check without token", func(t *testing.T) {
+ req, _ := http.NewRequest("PUT", "/v1/agent/check/deregister/_nope_", nil)
+ resp := httptest.NewRecorder()
+ a.srv.h.ServeHTTP(resp, req)
+ require.Equal(t, http.StatusNotFound, resp.Code)
+ })
+
+ t.Run("non-existent check with token", func(t *testing.T) {
+ req, _ := http.NewRequest("PUT", "/v1/agent/check/deregister/_nope_?token=root", nil)
+ resp := httptest.NewRecorder()
+ a.srv.h.ServeHTTP(resp, req)
+ require.Equal(t, http.StatusNotFound, resp.Code)
+ })
}
func TestAgent_PassCheck(t *testing.T) {
From c9735476a7ab748346f8da95d005beb3cdc3802d Mon Sep 17 00:00:00 2001
From: "Chris S. Kim"
Date: Thu, 6 Jan 2022 16:07:09 -0500
Subject: [PATCH 062/225] Fix Windows logging to files (#11960)
---
.changelog/11960.txt | 3 +++
logging/logger.go | 24 +++++++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
create mode 100644 .changelog/11960.txt
diff --git a/.changelog/11960.txt b/.changelog/11960.txt
new file mode 100644
index 000000000..aac5bd422
--- /dev/null
+++ b/.changelog/11960.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+windows: Fixes a bug with empty log files when Consul is run as a Windows Service
+```
\ No newline at end of file
diff --git a/logging/logger.go b/logging/logger.go
index dfc05785c..9d6cff74f 100644
--- a/logging/logger.go
+++ b/logging/logger.go
@@ -27,16 +27,16 @@ type Config struct {
// SyslogFacility is the destination for syslog forwarding.
SyslogFacility string
- //LogFilePath is the path to write the logs to the user specified file.
+ // LogFilePath is the path to write the logs to the user specified file.
LogFilePath string
- //LogRotateDuration is the user specified time to rotate logs
+ // LogRotateDuration is the user specified time to rotate logs
LogRotateDuration time.Duration
- //LogRotateBytes is the user specified byte limit to rotate logs
+ // LogRotateBytes is the user specified byte limit to rotate logs
LogRotateBytes int
- //LogRotateMaxFiles is the maximum number of past archived log files to keep
+ // LogRotateMaxFiles is the maximum number of past archived log files to keep
LogRotateMaxFiles int
}
@@ -45,6 +45,17 @@ const defaultRotateDuration = 24 * time.Hour
type LogSetupErrorFn func(string)
+// noErrorWriter is a wrapper to suppress errors when writing to w.
+type noErrorWriter struct {
+ w io.Writer
+}
+
+func (w noErrorWriter) Write(p []byte) (n int, err error) {
+ _, _ = w.w.Write(p)
+ // We purposely return n == len(p) as if write was successful
+ return len(p), nil
+}
+
// Setup logging from Config, and return an hclog Logger.
//
// Logs may be written to out, and optionally to syslog, and a file.
@@ -55,7 +66,10 @@ func Setup(config Config, out io.Writer) (hclog.InterceptLogger, error) {
allowedLogLevels)
}
- writers := []io.Writer{out}
+ // If out is os.Stdout and Consul is being run as a Windows Service, writes will
+ // fail silently, which may inadvertently prevent writes to other writers.
+ // noErrorWriter is used as a wrapper to suppress any errors when writing to out.
+ writers := []io.Writer{noErrorWriter{w: out}}
if config.EnableSyslog {
retries := 12
From 048d9b69ba441bd90ce7f85290902d223c15c06d Mon Sep 17 00:00:00 2001
From: Blake Covarrubias
Date: Thu, 6 Jan 2022 13:03:31 -0800
Subject: [PATCH 063/225] docs: Redirect mesh-gateway page to new location
The mesh gateway docs at /docs/connect/gateways/mesh-gateway were
moved in #11859 to a new location in order to accommodate the addition
of separate instructions for using gateways with admin partitions.
This commit redirects the old mesh gateway page to its new location at
/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters.
---
website/redirects.next.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/website/redirects.next.js b/website/redirects.next.js
index c2de7c5df..525ab5077 100644
--- a/website/redirects.next.js
+++ b/website/redirects.next.js
@@ -114,7 +114,14 @@ module.exports = [
{ source: '/configuration', destination: '/', permanent: true },
{
source: '/docs/connect/mesh(_|-)gateway',
- destination: '/docs/connect/gateways/mesh-gateway',
+ destination:
+ '/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters',
+ permanent: true,
+ },
+ {
+ source: '/docs/connect/gateways/mesh-gateway',
+ destination:
+ '/docs/connect/gateways/mesh-gateway/service-to-service-traffic-datacenters',
permanent: true,
},
{
From 9ec7e07db4389c9b13e4c7c161c33a6300adb56a Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Tue, 23 Nov 2021 12:49:43 -0500
Subject: [PATCH 064/225] ca: use the new leaf signing lookup func in leader
metrics
---
agent/consul/leader_metrics.go | 22 ++++------------------
1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/agent/consul/leader_metrics.go b/agent/consul/leader_metrics.go
index 7151adb74..244d3fd5d 100644
--- a/agent/consul/leader_metrics.go
+++ b/agent/consul/leader_metrics.go
@@ -13,7 +13,6 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/consul/agent/connect"
- "github.com/hashicorp/consul/agent/connect/ca"
"github.com/hashicorp/consul/logging"
)
@@ -55,27 +54,14 @@ func getRootCAExpiry(s *Server) (time.Duration, error) {
}
func signingCAExpiryMonitor(s *Server) CertExpirationMonitor {
- isPrimary := s.config.Datacenter == s.config.PrimaryDatacenter
- if isPrimary {
- return CertExpirationMonitor{
- Key: metricsKeyMeshActiveSigningCAExpiry,
- Logger: s.logger.Named(logging.Connect),
- Query: func() (time.Duration, error) {
- provider, _ := s.caManager.getCAProvider()
-
- if _, ok := provider.(ca.PrimaryUsesIntermediate); ok {
- return getActiveIntermediateExpiry(s)
- }
- return getRootCAExpiry(s)
- },
- }
- }
-
return CertExpirationMonitor{
Key: metricsKeyMeshActiveSigningCAExpiry,
Logger: s.logger.Named(logging.Connect),
Query: func() (time.Duration, error) {
- return getActiveIntermediateExpiry(s)
+ if s.caManager.isIntermediateUsedToSignLeaf() {
+ return getActiveIntermediateExpiry(s)
+ }
+ return getRootCAExpiry(s)
},
}
}
From 92a054cfa6328c065d1457e3550bb84b1432307a Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Tue, 23 Nov 2021 13:16:40 -0500
Subject: [PATCH 065/225] ca: cleanup a test
Fix the name to match the function it is testing
Remove unused code
Fix the signature, instead of returning (error, string) which should be (string, error)
accept a testing.T to emit errors.
Handle the error from encode.
---
agent/consul/leader_connect_ca_test.go | 35 ++++++++++----------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/agent/consul/leader_connect_ca_test.go b/agent/consul/leader_connect_ca_test.go
index fc2150eea..ba1a2677d 100644
--- a/agent/consul/leader_connect_ca_test.go
+++ b/agent/consul/leader_connect_ca_test.go
@@ -400,7 +400,7 @@ func TestCAManager_UpdateConfigWhileRenewIntermediate(t *testing.T) {
require.EqualValues(t, caStateInitialized, manager.state)
}
-func TestCAManager_SignLeafWithExpiredCert(t *testing.T) {
+func TestCAManager_SignCertificate_WithExpiredCert(t *testing.T) {
if testing.Short() {
t.Skip("too slow for testing.Short")
}
@@ -423,7 +423,6 @@ func TestCAManager_SignLeafWithExpiredCert(t *testing.T) {
}
for _, arg := range args {
-
t.Run(arg.testName, func(t *testing.T) {
// No parallel execution because we change globals
// Set the interval and drift buffer low for renewing the cert.
@@ -443,10 +442,8 @@ func TestCAManager_SignLeafWithExpiredCert(t *testing.T) {
delegate := NewMockCAServerDelegate(t, conf)
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
- err, rootPEM := generatePem(arg.notBeforeRoot, arg.notAfterRoot)
- require.NoError(t, err)
- err, intermediatePEM := generatePem(arg.notBeforeIntermediate, arg.notAfterIntermediate)
- require.NoError(t, err)
+ rootPEM := generateCertPEM(t, arg.notBeforeRoot, arg.notAfterRoot)
+ intermediatePEM := generateCertPEM(t, arg.notBeforeIntermediate, arg.notAfterIntermediate)
manager.providerShim = &mockCAProvider{
callbackCh: delegate.callbackCh,
rootPEM: rootPEM,
@@ -462,7 +459,7 @@ func TestCAManager_SignLeafWithExpiredCert(t *testing.T) {
// Call RenewIntermediate and then confirm the RPCs and provider calls
// happen in the expected order.
- _, err = manager.SignCertificate(&x509.CertificateRequest{}, &connect.SpiffeIDAgent{})
+ _, err := manager.SignCertificate(&x509.CertificateRequest{}, &connect.SpiffeIDAgent{})
if arg.isError {
require.Error(t, err)
@@ -474,7 +471,8 @@ func TestCAManager_SignLeafWithExpiredCert(t *testing.T) {
}
}
-func generatePem(notBefore time.Time, notAfter time.Time) (error, string) {
+func generateCertPEM(t *testing.T, notBefore time.Time, notAfter time.Time) string {
+ t.Helper()
ca := &x509.Certificate{
SerialNumber: big.NewInt(2019),
Subject: pkix.Name{
@@ -493,25 +491,18 @@ func generatePem(notBefore time.Time, notAfter time.Time) (error, string) {
BasicConstraintsValid: true,
}
caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
- if err != nil {
- return err, ""
- }
+ require.NoError(t, err, "failed to generate key")
+
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
- if err != nil {
- return err, ""
- }
+ require.NoError(t, err, "failed to create cert")
+
caPEM := new(bytes.Buffer)
- pem.Encode(caPEM, &pem.Block{
+ err = pem.Encode(caPEM, &pem.Block{
Type: "CERTIFICATE",
Bytes: caBytes,
})
-
- caPrivKeyPEM := new(bytes.Buffer)
- pem.Encode(caPrivKeyPEM, &pem.Block{
- Type: "RSA PRIVATE KEY",
- Bytes: x509.MarshalPKCS1PrivateKey(caPrivKey),
- })
- return err, caPEM.String()
+ require.NoError(t, err, "failed to encode")
+ return caPEM.String()
}
func TestCADelegateWithState_GenerateCASignRequest(t *testing.T) {
From b66d259c1af33b4dc88c7a69f1e9bdd6cc2cb9d0 Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Wed, 24 Nov 2021 18:45:03 -0500
Subject: [PATCH 066/225] ca: only generate a single private key for the whole
test case
Using tracing and cpu profiling I found that the majority of the time in
these test cases is spent generating a private key. We really don't need
separate private keys, so we can generate only one and use it for all
cases.
With this change the test runs much faster.
---
agent/consul/leader_connect_ca_test.go | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/agent/consul/leader_connect_ca_test.go b/agent/consul/leader_connect_ca_test.go
index ba1a2677d..869459cb7 100644
--- a/agent/consul/leader_connect_ca_test.go
+++ b/agent/consul/leader_connect_ca_test.go
@@ -422,6 +422,9 @@ func TestCAManager_SignCertificate_WithExpiredCert(t *testing.T) {
{"root in the future", time.Now().AddDate(0, 0, 1), time.Now().AddDate(0, 0, 2), time.Now().AddDate(0, 0, -1), time.Now().AddDate(0, 0, 2), false, ""},
}
+ caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
+ require.NoError(t, err, "failed to generate key")
+
for _, arg := range args {
t.Run(arg.testName, func(t *testing.T) {
// No parallel execution because we change globals
@@ -439,11 +442,13 @@ func TestCAManager_SignCertificate_WithExpiredCert(t *testing.T) {
conf.ConnectEnabled = true
conf.PrimaryDatacenter = "dc1"
conf.Datacenter = "dc2"
+
+ rootPEM := generateCertPEM(t, caPrivKey, arg.notBeforeRoot, arg.notAfterRoot)
+ intermediatePEM := generateCertPEM(t, caPrivKey, arg.notBeforeIntermediate, arg.notAfterIntermediate)
+
delegate := NewMockCAServerDelegate(t, conf)
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
- rootPEM := generateCertPEM(t, arg.notBeforeRoot, arg.notAfterRoot)
- intermediatePEM := generateCertPEM(t, arg.notBeforeIntermediate, arg.notAfterIntermediate)
manager.providerShim = &mockCAProvider{
callbackCh: delegate.callbackCh,
rootPEM: rootPEM,
@@ -471,7 +476,7 @@ func TestCAManager_SignCertificate_WithExpiredCert(t *testing.T) {
}
}
-func generateCertPEM(t *testing.T, notBefore time.Time, notAfter time.Time) string {
+func generateCertPEM(t *testing.T, caPrivKey *rsa.PrivateKey, notBefore time.Time, notAfter time.Time) string {
t.Helper()
ca := &x509.Certificate{
SerialNumber: big.NewInt(2019),
@@ -490,8 +495,6 @@ func generateCertPEM(t *testing.T, notBefore time.Time, notAfter time.Time) stri
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
- caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
- require.NoError(t, err, "failed to generate key")
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
require.NoError(t, err, "failed to create cert")
From 1f66120c20694fff1e8d1be8442faaeda50b5adf Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Thu, 25 Nov 2021 12:19:10 -0500
Subject: [PATCH 067/225] ca: remove redundant append of an intermediate cert
Immediately above this line we are already appending the full list of
intermediates. The `provider.ActiveIntermediate` MUST be in this list of
intermediates because it must be available to all the other non-leader
Servers. If it was not in this list of intermediates then any proxy
that received data from a non-leader would have the wrong certs.
This is being removed now because we are planning on changing the
`Provider.ActiveIntermediate` interface, and removing these extra calls ahead of
time helps make that change easier.
---
agent/consul/leader_connect_ca.go | 5 -----
1 file changed, 5 deletions(-)
diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go
index 82956bed2..3087fb84a 100644
--- a/agent/consul/leader_connect_ca.go
+++ b/agent/consul/leader_connect_ca.go
@@ -1498,11 +1498,6 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne
pem = pem + ca.EnsureTrailingNewline(p)
}
- // Append our local CA's intermediate if there is one.
- if inter != root {
- pem = pem + ca.EnsureTrailingNewline(inter)
- }
-
modIdx, err := c.delegate.ApplyCALeafRequest()
if err != nil {
return nil, err
From 1f670c22f5bfc3c3e03d8a5a768e073814c0a5e9 Mon Sep 17 00:00:00 2001
From: Daniel Nephin
Date: Tue, 23 Nov 2021 14:15:08 -0500
Subject: [PATCH 068/225] ca: remove one call to provider.ActiveRoot
ActiveRoot should not be called from the secondary DC, because there
should not be a requirement to run the same Vault instance in a
secondary DC. SignIntermediate is called in a secondary DC, so it should
not call ActiveRoot
We would also like to change the interface of ActiveRoot so that we can
support using an intermediate cert as the primary CA in Consul. In
preparation for making that change I am reducing the number of calls to
ActiveRoot, so that there are fewer code paths to modify when the
interface changes.
This change required a change to the mockCAServerDelegate we use in
tests. It was returning the RootCert for SignIntermediate, but that is
not an accurate fake of production. In production this would also be a
separate cert.
---
agent/consul/leader_connect_ca.go | 22 ++++++++--------------
agent/consul/leader_connect_ca_test.go | 24 +++++++++++++++---------
2 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go
index 3087fb84a..0a6b0b47a 100644
--- a/agent/consul/leader_connect_ca.go
+++ b/agent/consul/leader_connect_ca.go
@@ -1463,28 +1463,22 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne
connect.HackSANExtensionForCSR(csr)
- root, err := provider.ActiveRoot()
- if err != nil {
- return nil, err
- }
// Check if the root expired before using it to sign.
- err = c.checkExpired(root)
+ // TODO: we store NotBefore and NotAfter on this struct, so we could avoid
+ // parsing the cert here.
+ err = c.checkExpired(caRoot.RootCert)
if err != nil {
return nil, fmt.Errorf("root expired: %w", err)
}
- inter, err := provider.ActiveIntermediate()
- if err != nil {
- return nil, err
- }
- // Check if the intermediate expired before using it to sign.
- err = c.checkExpired(inter)
- if err != nil {
- return nil, fmt.Errorf("intermediate expired: %w", err)
+ if c.isIntermediateUsedToSignLeaf() && len(caRoot.IntermediateCerts) > 0 {
+ inter := caRoot.IntermediateCerts[len(caRoot.IntermediateCerts)-1]
+ if err := c.checkExpired(inter); err != nil {
+ return nil, fmt.Errorf("intermediate expired: %w", err)
+ }
}
// All seems to be in order, actually sign it.
-
pem, err := provider.Sign(csr)
if err == ca.ErrRateLimited {
return nil, ErrRateLimited
diff --git a/agent/consul/leader_connect_ca_test.go b/agent/consul/leader_connect_ca_test.go
index 869459cb7..5e5e1de59 100644
--- a/agent/consul/leader_connect_ca_test.go
+++ b/agent/consul/leader_connect_ca_test.go
@@ -12,6 +12,7 @@ import (
"fmt"
"math/big"
"net/rpc"
+ "net/url"
"testing"
"time"
@@ -131,11 +132,12 @@ func verifyLeafCert(t *testing.T, root *structs.CARoot, leafCertPEM string) {
}
type mockCAServerDelegate struct {
- t *testing.T
- config *Config
- store *state.Store
- primaryRoot *structs.CARoot
- callbackCh chan string
+ t *testing.T
+ config *Config
+ store *state.Store
+ primaryRoot *structs.CARoot
+ secondaryIntermediate string
+ callbackCh chan string
}
func NewMockCAServerDelegate(t *testing.T, config *Config) *mockCAServerDelegate {
@@ -198,7 +200,7 @@ func (m *mockCAServerDelegate) forwardDC(method, dc string, args interface{}, re
roots.ActiveRootID = m.primaryRoot.ID
case "ConnectCA.SignIntermediate":
r := reply.(*string)
- *r = m.primaryRoot.RootCert
+ *r = m.secondaryIntermediate
default:
return fmt.Errorf("received call to unsupported method %q", method)
}
@@ -305,13 +307,14 @@ func initTestManager(t *testing.T, manager *CAManager, delegate *mockCAServerDel
}
func TestCAManager_Initialize(t *testing.T) {
-
conf := DefaultConfig()
conf.ConnectEnabled = true
conf.PrimaryDatacenter = "dc1"
conf.Datacenter = "dc2"
delegate := NewMockCAServerDelegate(t, conf)
+ delegate.secondaryIntermediate = delegate.primaryRoot.RootCert
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
+
manager.providerShim = &mockCAProvider{
callbackCh: delegate.callbackCh,
rootPEM: delegate.primaryRoot.RootCert,
@@ -356,6 +359,7 @@ func TestCAManager_UpdateConfigWhileRenewIntermediate(t *testing.T) {
conf.PrimaryDatacenter = "dc1"
conf.Datacenter = "dc2"
delegate := NewMockCAServerDelegate(t, conf)
+ delegate.secondaryIntermediate = delegate.primaryRoot.RootCert
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
manager.providerShim = &mockCAProvider{
callbackCh: delegate.callbackCh,
@@ -447,6 +451,8 @@ func TestCAManager_SignCertificate_WithExpiredCert(t *testing.T) {
intermediatePEM := generateCertPEM(t, caPrivKey, arg.notBeforeIntermediate, arg.notAfterIntermediate)
delegate := NewMockCAServerDelegate(t, conf)
+ delegate.primaryRoot.RootCert = rootPEM
+ delegate.secondaryIntermediate = intermediatePEM
manager := NewCAManager(delegate, nil, testutil.Logger(t), conf)
manager.providerShim = &mockCAProvider{
@@ -458,14 +464,13 @@ func TestCAManager_SignCertificate_WithExpiredCert(t *testing.T) {
// Simulate Wait half the TTL for the cert to need renewing.
manager.timeNow = func() time.Time {
- return time.Now().Add(500 * time.Millisecond)
+ return time.Now().UTC().Add(500 * time.Millisecond)
}
// Call RenewIntermediate and then confirm the RPCs and provider calls
// happen in the expected order.
_, err := manager.SignCertificate(&x509.CertificateRequest{}, &connect.SpiffeIDAgent{})
-
if arg.isError {
require.Error(t, err)
require.Contains(t, err.Error(), arg.errorMsg)
@@ -494,6 +499,7 @@ func generateCertPEM(t *testing.T, caPrivKey *rsa.PrivateKey, notBefore time.Tim
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
+ URIs: []*url.URL{connect.SpiffeIDAgent{Host: "foo"}.URI()},
}
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
From a08f2927fdcea91ffe4763b10781854741253d3e Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Fri, 7 Jan 2022 16:15:22 +0000
Subject: [PATCH 069/225] ui: Fix dark borders on certain visualizations
(#11959)
---
.changelog/11959.txt | 3 +++
.../app/components/consul/discovery-chain/skin.scss | 10 ++++++++--
.../app/components/topology-metrics/card/index.scss | 5 ++++-
.../app/components/topology-metrics/skin.scss | 5 ++++-
4 files changed, 19 insertions(+), 4 deletions(-)
create mode 100644 .changelog/11959.txt
diff --git a/.changelog/11959.txt b/.changelog/11959.txt
new file mode 100644
index 000000000..592a83667
--- /dev/null
+++ b/.changelog/11959.txt
@@ -0,0 +1,3 @@
+```release-note:bug
+ui: Fixes a visual issue with some border colors
+```
diff --git a/ui/packages/consul-ui/app/components/consul/discovery-chain/skin.scss b/ui/packages/consul-ui/app/components/consul/discovery-chain/skin.scss
index 30055d3aa..03c367537 100644
--- a/ui/packages/consul-ui/app/components/consul/discovery-chain/skin.scss
+++ b/ui/packages/consul-ui/app/components/consul/discovery-chain/skin.scss
@@ -37,7 +37,10 @@
}
%chain-group {
border-radius: var(--decor-radius-100);
- border: 1px solid rgb(var(--tone-gray-200));
+ border: 1px solid;
+ /* TODO: If this color is combined with the above */
+ /* border property then the compressor removes the color */
+ border-color: rgb(var(--tone-gray-200));
background-color: rgb(var(--tone-gray-100));
pointer-events: none;
@@ -102,7 +105,10 @@
background-color: rgb(var(--tone-gray-000));
border-radius: var(--decor-radius-full);
- border: 2px solid rgb(var(--tone-gray-400));
+ border: 2px solid;
+ /* TODO: If this color is combined with the above */
+ /* border property then the compressor removes the color */
+ border-color: rgb(var(--tone-gray-400));
}
%discovery-chain circle {
stroke-width: 2;
diff --git a/ui/packages/consul-ui/app/components/topology-metrics/card/index.scss b/ui/packages/consul-ui/app/components/topology-metrics/card/index.scss
index 7a08492ca..72d5c4ee1 100644
--- a/ui/packages/consul-ui/app/components/topology-metrics/card/index.scss
+++ b/ui/packages/consul-ui/app/components/topology-metrics/card/index.scss
@@ -9,7 +9,10 @@
overflow: hidden;
background-color: rgb(var(--tone-gray-000));
border-radius: var(--decor-radius-100);
- border: 1px solid rgb(var(--tone-gray-200));
+ border: 1px solid;
+ /* TODO: If this color is combined with the above */
+ /* border property then the compressor removes the color */
+ border-color: rgb(var(--tone-gray-200));
p {
padding: 12px 12px 0 12px;
font-size: var(--typo-size-500);
diff --git a/ui/packages/consul-ui/app/components/topology-metrics/skin.scss b/ui/packages/consul-ui/app/components/topology-metrics/skin.scss
index 8b6fc0fda..026db0f67 100644
--- a/ui/packages/consul-ui/app/components/topology-metrics/skin.scss
+++ b/ui/packages/consul-ui/app/components/topology-metrics/skin.scss
@@ -6,8 +6,11 @@
#downstream-container,
#metrics-container,
#upstream-container {
- border: 1px solid rgb(var(--tone-gray-200));
border-radius: var(--decor-radius-100);
+ border: 1px solid;
+ /* TODO: If this color is combined with the above */
+ /* border property then the compressor removes the color */
+ border-color: rgb(var(--tone-gray-200));
}
#downstream-container,
#upstream-container {
From 86e885fc5b81c6246faa90eac4d467cc57058371 Mon Sep 17 00:00:00 2001
From: John Cowen
Date: Fri, 7 Jan 2022 19:08:25 +0000
Subject: [PATCH 070/225] ui: Upgrade AuthDialog (#11913)
- Move AuthDialog to use a Glimmer Component plus native named blocks/slots.
- Unravel the Auth* contextual components, there wasn't a lot of point having them as contextual components and now the AuthDialog (non-view-specific state machine component) can be used entirely separately from the view-specific components (AuthForm and AuthProfile).
- Move all the ACL related components that are in the main app chrome/navigation (our HashicorpConsul component) in our consul-acls sub package/module (which will eventually be loaded on demand only when ACLs are enabled)
---
.../components/consul/acl/selector/index.hbs | 79 +++
.../consul/token/selector/index.hbs | 158 +++++
.../components/consul/token/selector/index.js | 20 +
.../consul-ui/app/abilities/authenticate.js | 8 -
.../app/components/auth-dialog/README.mdx | 82 ++-
.../app/components/auth-dialog/index.hbs | 24 +-
.../app/components/auth-dialog/index.js | 79 +--
.../app/components/auth-profile/README.mdx | 19 +-
.../app/components/auth-profile/index.hbs | 7 +-
.../app/components/auth-profile/index.js | 5 -
.../app/components/auth-profile/index.scss | 19 +
.../app/components/hashicorp-consul/index.hbs | 610 +++++++-----------
.../app/components/hashicorp-consul/index.js | 22 -
.../app/components/menu-panel/layout.scss | 3 -
.../app/components/menu-panel/skin.scss | 14 -
.../consul-ui/app/styles/components.scss | 1 +
.../consul-ui/app/styles/typography.scss | 1 -
.../components/auth-dialog-test.js | 26 -
18 files changed, 614 insertions(+), 563 deletions(-)
create mode 100644 ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs
create mode 100644 ui/packages/consul-acls/app/components/consul/token/selector/index.hbs
create mode 100644 ui/packages/consul-acls/app/components/consul/token/selector/index.js
delete mode 100644 ui/packages/consul-ui/app/abilities/authenticate.js
delete mode 100644 ui/packages/consul-ui/app/components/auth-profile/index.js
create mode 100644 ui/packages/consul-ui/app/components/auth-profile/index.scss
delete mode 100644 ui/packages/consul-ui/tests/integration/components/auth-dialog-test.js
diff --git a/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs b/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs
new file mode 100644
index 000000000..f5e6bae34
--- /dev/null
+++ b/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs
@@ -0,0 +1,79 @@
+
- {{#if (eq type 'logout')}}
- {{#if (eq status 'success') }}
- You are now logged out.
- {{else}}
- There was an error logging out.
- {{/if}}
- {{else if (eq type 'authorize')}}
- {{#if (eq status 'success') }}
- You are now logged in.
- {{else}}
- There was an error, please check your SecretID/Token
- {{/if}}
+
+
+
+ {{capitalize status}}!
+
+
+
+
+ {{#if (eq type 'logout')}}
+ {{#if (eq status 'success') }}
+ You are now logged out.
{{else}}
- {{#if (or (eq type 'use') (eq flash.model 'token'))}}
-
- {{else if (eq flash.model 'intention')}}
-
- {{else if (eq flash.model 'role')}}
-
- {{else if (eq flash.model 'policy')}}
-
- {{/if}}
+ There was an error logging out.
{{/if}}
-
-
-
+ {{else if (eq type 'authorize')}}
+ {{#if (eq status 'success') }}
+ You are now logged in.
+ {{else}}
+ There was an error, please check your SecretID/Token
+ {{/if}}
+ {{else}}
+ {{#if (or (eq type 'use') (eq flash.model 'token'))}}
+
+ {{else if (eq flash.model 'intention')}}
+
+ {{else if (eq flash.model 'role')}}
+
+ {{else if (eq flash.model 'policy')}}
+
+ {{/if}}
+ {{/if}}
+
- The following list shows individual HTTP paths exposed through Envoy for external services like Prometheus. Read more about this in our documentation.
+ The following list shows individual HTTP paths exposed through Envoy for external services like Prometheus. Read more about this in our documentation.
-
-
+ {{! TODO: Looks like we can get this straight from item.Proxy.Mode }}
+ {{! the less we need `proxy` and `meta` the better }}
+ {{#if (eq meta.ServiceProxy.Mode 'transparent')}}
+
+
+