Merge branch 'main' of github.com:hashicorp/consul
This commit is contained in:
commit
5447e0ecb2
34
api/acl.go
34
api/acl.go
|
@ -552,7 +552,7 @@ func (a *ACL) Update(acl *ACLEntry, q *WriteOptions) (*WriteMeta, error) {
|
|||
//
|
||||
// Deprecated: Use TokenDelete instead.
|
||||
func (a *ACL) Destroy(id string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := a.c.newRequest("PUT", "/v1/acl/destroy/"+id)
|
||||
r := a.c.newRequest("PUT", "/v1/acl/destroy/"+url.PathEscape(id))
|
||||
r.setWriteOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -571,7 +571,7 @@ func (a *ACL) Destroy(id string, q *WriteOptions) (*WriteMeta, error) {
|
|||
//
|
||||
// Deprecated: Use TokenClone instead.
|
||||
func (a *ACL) Clone(id string, q *WriteOptions) (string, *WriteMeta, error) {
|
||||
r := a.c.newRequest("PUT", "/v1/acl/clone/"+id)
|
||||
r := a.c.newRequest("PUT", "/v1/acl/clone/"+url.PathEscape(id))
|
||||
r.setWriteOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -594,7 +594,7 @@ func (a *ACL) Clone(id string, q *WriteOptions) (string, *WriteMeta, error) {
|
|||
//
|
||||
// Deprecated: Use TokenRead instead.
|
||||
func (a *ACL) Info(id string, q *QueryOptions) (*ACLEntry, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/acl/info/"+id)
|
||||
r := a.c.newRequest("GET", "/v1/acl/info/"+url.PathEscape(id))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -696,7 +696,7 @@ func (a *ACL) TokenUpdate(token *ACLToken, q *WriteOptions) (*ACLToken, *WriteMe
|
|||
if token.AccessorID == "" {
|
||||
return nil, nil, fmt.Errorf("Must specify an AccessorID for Token Updating")
|
||||
}
|
||||
r := a.c.newRequest("PUT", "/v1/acl/token/"+token.AccessorID)
|
||||
r := a.c.newRequest("PUT", "/v1/acl/token/"+url.PathEscape(token.AccessorID))
|
||||
r.setWriteOptions(q)
|
||||
r.obj = token
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
|
@ -725,7 +725,7 @@ func (a *ACL) TokenClone(tokenID string, description string, q *WriteOptions) (*
|
|||
return nil, nil, fmt.Errorf("Must specify a tokenID for Token Cloning")
|
||||
}
|
||||
|
||||
r := a.c.newRequest("PUT", "/v1/acl/token/"+tokenID+"/clone")
|
||||
r := a.c.newRequest("PUT", "/v1/acl/token/"+url.PathEscape(tokenID)+"/clone")
|
||||
r.setWriteOptions(q)
|
||||
r.obj = struct{ Description string }{description}
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
|
@ -748,7 +748,7 @@ func (a *ACL) TokenClone(tokenID string, description string, q *WriteOptions) (*
|
|||
// TokenDelete removes a single ACL token. The tokenID parameter must be a valid
|
||||
// Accessor ID of an existing token.
|
||||
func (a *ACL) TokenDelete(tokenID string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/token/"+tokenID)
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/token/"+url.PathEscape(tokenID))
|
||||
r.setWriteOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -766,7 +766,7 @@ func (a *ACL) TokenDelete(tokenID string, q *WriteOptions) (*WriteMeta, error) {
|
|||
// TokenRead retrieves the full token details. The tokenID parameter must be a valid
|
||||
// Accessor ID of an existing token.
|
||||
func (a *ACL) TokenRead(tokenID string, q *QueryOptions) (*ACLToken, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/acl/token/"+tokenID)
|
||||
r := a.c.newRequest("GET", "/v1/acl/token/"+url.PathEscape(tokenID))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -871,7 +871,7 @@ func (a *ACL) PolicyUpdate(policy *ACLPolicy, q *WriteOptions) (*ACLPolicy, *Wri
|
|||
return nil, nil, fmt.Errorf("Must specify an ID in Policy Update")
|
||||
}
|
||||
|
||||
r := a.c.newRequest("PUT", "/v1/acl/policy/"+policy.ID)
|
||||
r := a.c.newRequest("PUT", "/v1/acl/policy/"+url.PathEscape(policy.ID))
|
||||
r.setWriteOptions(q)
|
||||
r.obj = policy
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
|
@ -893,7 +893,7 @@ func (a *ACL) PolicyUpdate(policy *ACLPolicy, q *WriteOptions) (*ACLPolicy, *Wri
|
|||
|
||||
// PolicyDelete deletes a policy given its ID.
|
||||
func (a *ACL) PolicyDelete(policyID string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/policy/"+policyID)
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/policy/"+url.PathEscape(policyID))
|
||||
r.setWriteOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -910,7 +910,7 @@ func (a *ACL) PolicyDelete(policyID string, q *WriteOptions) (*WriteMeta, error)
|
|||
|
||||
// PolicyRead retrieves the policy details including the rule set.
|
||||
func (a *ACL) PolicyRead(policyID string, q *QueryOptions) (*ACLPolicy, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/acl/policy/"+policyID)
|
||||
r := a.c.newRequest("GET", "/v1/acl/policy/"+url.PathEscape(policyID))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -1021,7 +1021,7 @@ func (a *ACL) RulesTranslate(rules io.Reader) (string, error) {
|
|||
// Deprecated: Support for the legacy syntax translation will be removed
|
||||
// when legacy ACL support is removed.
|
||||
func (a *ACL) RulesTranslateToken(tokenID string) (string, error) {
|
||||
r := a.c.newRequest("GET", "/v1/acl/rules/translate/"+tokenID)
|
||||
r := a.c.newRequest("GET", "/v1/acl/rules/translate/"+url.PathEscape(tokenID))
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -1076,7 +1076,7 @@ func (a *ACL) RoleUpdate(role *ACLRole, q *WriteOptions) (*ACLRole, *WriteMeta,
|
|||
return nil, nil, fmt.Errorf("Must specify an ID in Role Update")
|
||||
}
|
||||
|
||||
r := a.c.newRequest("PUT", "/v1/acl/role/"+role.ID)
|
||||
r := a.c.newRequest("PUT", "/v1/acl/role/"+url.PathEscape(role.ID))
|
||||
r.setWriteOptions(q)
|
||||
r.obj = role
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
|
@ -1098,7 +1098,7 @@ func (a *ACL) RoleUpdate(role *ACLRole, q *WriteOptions) (*ACLRole, *WriteMeta,
|
|||
|
||||
// RoleDelete deletes a role given its ID.
|
||||
func (a *ACL) RoleDelete(roleID string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/role/"+roleID)
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/role/"+url.PathEscape(roleID))
|
||||
r.setWriteOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -1115,7 +1115,7 @@ func (a *ACL) RoleDelete(roleID string, q *WriteOptions) (*WriteMeta, error) {
|
|||
|
||||
// RoleRead retrieves the role details (by ID). Returns nil if not found.
|
||||
func (a *ACL) RoleRead(roleID string, q *QueryOptions) (*ACLRole, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/acl/role/"+roleID)
|
||||
r := a.c.newRequest("GET", "/v1/acl/role/"+url.PathEscape(roleID))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -1365,7 +1365,7 @@ func (a *ACL) BindingRuleUpdate(rule *ACLBindingRule, q *WriteOptions) (*ACLBind
|
|||
return nil, nil, fmt.Errorf("Must specify an ID in Binding Rule Update")
|
||||
}
|
||||
|
||||
r := a.c.newRequest("PUT", "/v1/acl/binding-rule/"+rule.ID)
|
||||
r := a.c.newRequest("PUT", "/v1/acl/binding-rule/"+url.PathEscape(rule.ID))
|
||||
r.setWriteOptions(q)
|
||||
r.obj = rule
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
|
@ -1387,7 +1387,7 @@ func (a *ACL) BindingRuleUpdate(rule *ACLBindingRule, q *WriteOptions) (*ACLBind
|
|||
|
||||
// BindingRuleDelete deletes a binding rule given its ID.
|
||||
func (a *ACL) BindingRuleDelete(bindingRuleID string, q *WriteOptions) (*WriteMeta, error) {
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/binding-rule/"+bindingRuleID)
|
||||
r := a.c.newRequest("DELETE", "/v1/acl/binding-rule/"+url.PathEscape(bindingRuleID))
|
||||
r.setWriteOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -1404,7 +1404,7 @@ func (a *ACL) BindingRuleDelete(bindingRuleID string, q *WriteOptions) (*WriteMe
|
|||
|
||||
// BindingRuleRead retrieves the binding rule details. Returns nil if not found.
|
||||
func (a *ACL) BindingRuleRead(bindingRuleID string, q *QueryOptions) (*ACLBindingRule, *QueryMeta, error) {
|
||||
r := a.c.newRequest("GET", "/v1/acl/binding-rule/"+bindingRuleID)
|
||||
r := a.c.newRequest("GET", "/v1/acl/binding-rule/"+url.PathEscape(bindingRuleID))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := a.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
|
|
@ -2,6 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
@ -254,9 +255,9 @@ func (c *Catalog) ConnectMultipleTags(service string, tags []string, q *QueryOpt
|
|||
}
|
||||
|
||||
func (c *Catalog) service(service string, tags []string, q *QueryOptions, connect bool) ([]*CatalogService, *QueryMeta, error) {
|
||||
path := "/v1/catalog/service/" + service
|
||||
path := "/v1/catalog/service/" + url.PathEscape(service)
|
||||
if connect {
|
||||
path = "/v1/catalog/connect/" + service
|
||||
path = "/v1/catalog/connect/" + url.PathEscape(service)
|
||||
}
|
||||
r := c.c.newRequest("GET", path)
|
||||
r.setQueryOptions(q)
|
||||
|
@ -287,7 +288,7 @@ func (c *Catalog) service(service string, tags []string, q *QueryOptions, connec
|
|||
|
||||
// Node is used to query for service information about a single node
|
||||
func (c *Catalog) Node(node string, q *QueryOptions) (*CatalogNode, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/node/"+node)
|
||||
r := c.c.newRequest("GET", "/v1/catalog/node/"+url.PathEscape(node))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -314,7 +315,7 @@ func (c *Catalog) Node(node string, q *QueryOptions) (*CatalogNode, *QueryMeta,
|
|||
// a map of service ids to services. This different structure allows for using the wildcard specifier
|
||||
// '*' for the Namespace in the QueryOptions.
|
||||
func (c *Catalog) NodeServiceList(node string, q *QueryOptions) (*CatalogNodeServiceList, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/node-services/"+node)
|
||||
r := c.c.newRequest("GET", "/v1/catalog/node-services/"+url.PathEscape(node))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -338,7 +339,7 @@ func (c *Catalog) NodeServiceList(node string, q *QueryOptions) (*CatalogNodeSer
|
|||
|
||||
// GatewayServices is used to query the services associated with an ingress gateway or terminating gateway.
|
||||
func (c *Catalog) GatewayServices(gateway string, q *QueryOptions) ([]*GatewayService, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/catalog/gateway-services/"+gateway)
|
||||
r := c.c.newRequest("GET", "/v1/catalog/gateway-services/"+url.PathEscape(gateway))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -378,7 +379,7 @@ func (conf *ConfigEntries) Get(kind string, name string, q *QueryOptions) (Confi
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s/%s", kind, name))
|
||||
r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s/%s", url.PathEscape(kind), url.PathEscape(name)))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := conf.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -405,7 +406,7 @@ func (conf *ConfigEntries) List(kind string, q *QueryOptions) ([]ConfigEntry, *Q
|
|||
return nil, nil, fmt.Errorf("The kind parameter must not be empty")
|
||||
}
|
||||
|
||||
r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s", kind))
|
||||
r := conf.c.newRequest("GET", fmt.Sprintf("/v1/config/%s", url.PathEscape(kind)))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := conf.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
@ -485,7 +486,7 @@ func (conf *ConfigEntries) delete(kind, name string, params map[string]string, w
|
|||
return false, nil, fmt.Errorf("Both kind and name parameters must not be empty")
|
||||
}
|
||||
|
||||
r := conf.c.newRequest("DELETE", fmt.Sprintf("/v1/config/%s/%s", kind, name))
|
||||
r := conf.c.newRequest("DELETE", fmt.Sprintf("/v1/config/%s/%s", url.PathEscape(kind), url.PathEscape(name)))
|
||||
r.setWriteOptions(w)
|
||||
for param, value := range params {
|
||||
r.params.Set(param, value)
|
||||
|
|
|
@ -2,6 +2,7 @@ package api
|
|||
|
||||
import (
|
||||
"github.com/hashicorp/serf/coordinate"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// CoordinateEntry represents a node and its associated network coordinate.
|
||||
|
@ -96,7 +97,7 @@ func (c *Coordinate) Update(coord *CoordinateEntry, q *WriteOptions) (*WriteMeta
|
|||
|
||||
// Node is used to return the coordinates of a single node in the LAN pool.
|
||||
func (c *Coordinate) Node(node string, q *QueryOptions) ([]*CoordinateEntry, *QueryMeta, error) {
|
||||
r := c.c.newRequest("GET", "/v1/coordinate/node/"+node)
|
||||
r := c.c.newRequest("GET", "/v1/coordinate/node/"+url.PathEscape(node))
|
||||
r.setQueryOptions(q)
|
||||
rtt, resp, err := c.c.doRequest(r)
|
||||
if err != nil {
|
||||
|
|
|
@ -3,6 +3,7 @@ package api
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -26,7 +27,7 @@ func (d *DiscoveryChain) Get(name string, opts *DiscoveryChainOptions, q *QueryO
|
|||
method = "POST"
|
||||
}
|
||||
|
||||
r := d.c.newRequest(method, fmt.Sprintf("/v1/discovery-chain/%s", name))
|
||||
r := d.c.newRequest(method, fmt.Sprintf("/v1/discovery-chain/%s", url.PathEscape(name)))
|
||||
r.setQueryOptions(q)
|
||||
|
||||
if opts != nil {
|
||||
|
|
|
@ -66,6 +66,8 @@ service named `prometheus-server` so each Consul agent can reach it on
|
|||
|
||||
A full configuration to enable Prometheus is given below.
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
```hcl
|
||||
ui_config {
|
||||
enabled = true
|
||||
|
@ -76,6 +78,24 @@ ui_config {
|
|||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"ui_config": [
|
||||
{
|
||||
"enabled": true,
|
||||
"metrics_provider": "prometheus",
|
||||
"metrics_proxy": [
|
||||
{
|
||||
"base_url": "http://prometheus-server"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
Similarly, to configure the UI on Kubernetes, use this [reference](/docs/k8s/connect/observability/metrics).
|
||||
|
||||
## Configuring Dashboard URLs
|
||||
|
@ -95,30 +115,41 @@ to the relevant information.
|
|||
|
||||
An example with Grafana is shown below.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="HCL">
|
||||
<CodeTabs tabs={[ "HCL", "JSON", "YAML (Kubernetes)" ]}>
|
||||
|
||||
<CodeBlockConfig>
|
||||
|
||||
```hcl
|
||||
ui_config {
|
||||
enabled = true
|
||||
dashboard_url_templates {
|
||||
service = "https://grafana.example.com/d/lDlaj-NGz/
|
||||
service-overview?orgId=1&var-service={{Service.Name}}&
|
||||
var-namespace={{Service.Namespace}}&
|
||||
var-partition={{Service.Partition}}&var-dc={{Datacenter}}"
|
||||
service = "https://grafana.example.com/d/lDlaj-NGz/service-overview?orgId=1&var-service={{Service.Name}}&var-namespace={{Service.Namespace}}&var-partition={{Service.Partition}}&var-dc={{Datacenter}}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-> **Note**: the URL is wrapped over multiple lines to make it easier to read
|
||||
without horizontal scrolling in the example above however this needs to be a
|
||||
normal single-line string value in an HCL configuration file.
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Kubernetes YAML">
|
||||
<CodeBlockConfig>
|
||||
|
||||
On Kubernetes, Consul Server configuration is set in your Helm config via the
|
||||
[`server.extraConfig`](/docs/k8s/helm#v-server-extraconfig) key as JSON:
|
||||
```json
|
||||
{
|
||||
"ui_config": [
|
||||
{
|
||||
"dashboard_url_templates": [
|
||||
{
|
||||
"service": "https://grafana.example.com/d/lDlaj-NGz/service-overview?orgId=1\u0026var-service={{Service.Name}}\u0026var-namespace={{Service.Namespace}}\u0026var-partition={{Service.Partition}}\u0026var-dc={{Datacenter}}"
|
||||
}
|
||||
],
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
<CodeBlockConfig>
|
||||
|
||||
```yaml
|
||||
# The UI is enabled by default so this stanza is not required.
|
||||
|
@ -135,10 +166,14 @@ server:
|
|||
}
|
||||
```
|
||||
|
||||
-> **Note**: The `{{` characters in the URL must be escaped using `{{ "{{" }}` so that Helm doesn't try to template them.
|
||||
</CodeBlockConfig>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</CodeTabs>
|
||||
|
||||
~> **Note**: On Kubernetes, Consul Server configuration is set in your Helm
|
||||
config via the [`server.extraConfig`](/docs/k8s/helm#v-server-extraconfig) key as JSON.
|
||||
The `{{` characters in the URL must be escaped using `{{ "{{" }}` so that Helm
|
||||
doesn't try to template them.
|
||||
|
||||
![Consul UI Service Dashboard Link](/img/ui-dashboard-url-template.png)
|
||||
|
||||
|
@ -171,6 +206,8 @@ un-authenticated workloads on the network**.
|
|||
With ACLs enabled, the proxy endpoint requires a valid token with read access
|
||||
to all nodes and services (across all namespaces in Enterprise):
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
```hcl
|
||||
# Consul OSS
|
||||
service_prefix "" {
|
||||
|
@ -191,6 +228,8 @@ namespace_prefix "" {
|
|||
}
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
It's typical for most authenticated users to have this level of access in Consul
|
||||
as it's required for viewing the catalog or discovering services. If you use a
|
||||
[Single Sign-On integration](/docs/security/acl/auth-methods/oidc) (Consul
|
||||
|
@ -235,6 +274,8 @@ visible to Consul operators in the configuration file while UI users can query
|
|||
the metrics they need without separately obtaining a token for that provider or
|
||||
having a token exposed to them that they might be able to use elsewhere.
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
```hcl
|
||||
ui_config {
|
||||
enabled = true
|
||||
|
@ -251,6 +292,30 @@ ui_config {
|
|||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"ui_config": [
|
||||
{
|
||||
"enabled": true,
|
||||
"metrics_provider": "example-apm",
|
||||
"metrics_proxy": [
|
||||
{
|
||||
"add_headers": [
|
||||
{
|
||||
"name": "Authorization",
|
||||
"value": "Bearer \u003ctoken\u003e"
|
||||
}
|
||||
],
|
||||
"base_url": "https://example-apm.com/api/v1/metrics"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Custom Metrics Providers
|
||||
|
||||
Consul 1.9.0 includes a built-in provider for fetching metrics from
|
||||
|
@ -266,6 +331,8 @@ feedback on [GitHub](https://github.com/hashicorp/consul) or
|
|||
|
||||
The template for a complete provider JavaScript file is given below.
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
```JavaScript
|
||||
(function () {
|
||||
var provider = {
|
||||
|
@ -472,6 +539,8 @@ The template for a complete provider JavaScript file is given below.
|
|||
}());
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
Additionally, the built in [Prometheus
|
||||
provider code](https://github.com/hashicorp/consul/blob/main/ui/packages/consul-ui/vendor/metrics-providers/prometheus.js)
|
||||
can be used as a reference.
|
||||
|
@ -484,6 +553,8 @@ named `example-provider`, which is defined in
|
|||
have been specified in the call to `consul.registerMetricsProvider` as in the
|
||||
code listing in the last section.
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
```hcl
|
||||
ui_config {
|
||||
enabled = true
|
||||
|
@ -497,6 +568,19 @@ ui_config {
|
|||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"ui_config": {
|
||||
"enabled": true,
|
||||
"metrics_provider": "example-provider",
|
||||
"metrics_provide_files": ["/usr/local/bin/example-metrics-provider.js"],
|
||||
"metrics_provider_options_json": "{\"foo\":\"bar\"}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
More than one JavaScript file may be specified in
|
||||
[`metrics_provider_files`](/docs/agent/options#ui_config_metrics_provider_files)
|
||||
and all we be served allowing flexibility if needed to include dependencies.
|
||||
|
|
|
@ -82,7 +82,8 @@ Your Consul configuration must meet the following requirements to use admin part
|
|||
|
||||
One of the primary use cases for admin partitions is for enabling a service mesh across multiple Kubernetes clusters. The following requirements must be met to create admin partitions on Kubernetes:
|
||||
|
||||
* Two or more Kubernetes clusters. Consul servers must be deployed to a single cluster. The other clusters should run Consul clients.
|
||||
* If you are deploying Consul servers on Kubernetes, then ensure that the Consul servers are deployed within the same Kubernetes cluster. Consul servers may be deployed external to Kubernetes and configured using the `externalServers` stanza.
|
||||
* Consul clients deployed on the same Kubernetes cluster as the Consul Servers must use the `default` partition. If the clients are required to run on a non-default partition, then the clients must be deployed in a separate Kubernetes cluster.
|
||||
* A Consul Enterprise license must be installed on each Kubernetes cluster.
|
||||
* The helm chart for consul-k8s v0.39.0 or greater.
|
||||
* Consul 1.11.1-ent or greater.
|
||||
|
|
|
@ -7,7 +7,7 @@ page_title: 1.10.0
|
|||
|
||||
## Release Highlights
|
||||
|
||||
- **Transparent Proxy:** Simplifies deploying applications into the service mesh by using iptables to redirect traffic from applications running in virtual machines or Kubernetes through the Envoy proxy.
|
||||
- **Transparent Proxy:** Simplifies deploying applications into the service mesh by using iptables to redirect traffic from applications running in virtual machines or Kubernetes through the Envoy proxy. [`consul connect redirect-traffic`](/commands/connect/redirect-traffic) now provides a CLI interface for applying traffic redirection `iptables` rules to redirect traffic through an inbound and outbound listener on the Envoy sidecar. More information on how to utilize Transparent Proxy for Consul on Kubernetes could be found on [Transparent Proxy](/docs/connect/transparent-proxy).
|
||||
|
||||
- **Support for xDS v3 and Incremental xDS:** Consul 1.10 will default to using xDS version 3 and Incremental xDS for all supported Envoy proxy versions bootstrapped by the Consul 1.10 CLI. This is driven by the fact that xDS v2 was deprecated in Envoy 1.15 and disabled in Envoy 1.17. Envoy proxies bootstrapped with older Consul CLI binaries will continue to use the xDS v2 state-of-the-world API.
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
layout: docs
|
||||
page_title: 1.11.0
|
||||
---
|
||||
|
||||
# Consul 1.11.0
|
||||
|
||||
## Release Highlights
|
||||
|
||||
- **Admin Partitions (Enterprise):** Consul 1.11.0 Enteprise introduces a new entity for defining administrative and networking boundaries within a Consul deployment. This feature also enables servers to communicate with clients over a specific gossip segment created for each partition. This release also enables cross partition communication between services across partitions, using Mesh Gateways. For more information refer to the [Admin Partitions](/docs/enterprise/admin-partitions) documentation.
|
||||
|
||||
- **Virtual IPs for services deployed with Consul Service Mesh:** Consul will now generate a unique virtual IP for each service deployed within Consul Service Mesh, allowing transparent proxy to route to services within a data center that exist in different clusters or outside the service mesh.
|
||||
|
||||
- **Replace [boltdb](https://github.com/boltdb/bolt) with [etcd-io/bbolt](https://github.com/etcd-io/bbolt) for raft log store:** Consul now leverages `etcd-io/bbolt` as the default implementation of `boltdb` instead of `boltdb/bolt`. This change also exposes a configuration to allow for disabling boltdb freelist syncing. In addition, Consul now emits metrics for the raft boltdb store to provide insights into boltdb performance.
|
||||
|
||||
- **TLS Certificates for Ingress Gateways via an SDS source:**: Ingress Gateways can now be configured to retrieve TLS certificates from an external SDS Service and load the TLS certificates for Ingress listeners. This configuration is set using the `ingress-gateway` configuration entry via the [SDS](/docs/connect/config-entries/ingress-gateway#sds) stanza within the Ingress Gateway TLS configuration.
|
||||
|
||||
- **Vault Auth Method support for Connect CA Vault Provider:** Consul now supports configuring the Connect CA Vault provider to use auth methods for authentication to Vault. Consul supports using any non-deprecated auth method that is available in Vault v1.8.5, including AppRole, AliCloud, AWS, Azure, Cloud Foundry, GitHub, Google Cloud, JWT/OIDC, Kerberos, Kubernetes, LDAP, Oracle Cloud Infrastructure, Okta, Radius, TLS Certificates, and Username & Password. The Vault Auth Method for Connect CA Provider is utilized by default for the [Vault Secrets Backend](/docs/k8s/installation/vault) feature on Consul on Kubernetes. Utilizing a Vault Auth method would no longer require a Vault token to be managed or provisioned ahead of time to be used for authentication to Vault.
|
||||
|
||||
## What's Changed
|
||||
|
||||
- The legacy ACL system that was deprecated in Consul 1.4.0 has been removed. Before upgrading you should verify that all tokens and policies have been migrated to the newer ACL system. See the [Migrate Legacy ACL Tokens Learn Guide](https://learn.hashicorp.com/tutorials/consul/access-control-token-migration) for more information.
|
||||
|
||||
- The `agent_master` ACL token has been renamed to `agent_recovery` ACL token. In addition, the `consul acl set-agent-token master` command has been replaced with `consul acl set-agent-token recovery`. See [ACL Agent Recovery Token](/docs/security/acl/acl-system#acl-agent-recovery-token) and [Consul ACL Set Agent Token](/commands/acl/set-agent-token) for more information.
|
||||
|
||||
- Drops support for Envoy versions 1.15.x and 1.16.x
|
||||
|
||||
For more detailed information, please refer to the [upgrade details page](/docs/upgrading/upgrade-specific#consul-1-11-0) and the [1.11.0 changelog](https://github.com/hashicorp/consul/releases/tag/v1.11.0).
|
|
@ -1067,12 +1067,16 @@
|
|||
"title": "Release Notes",
|
||||
"routes": [
|
||||
{
|
||||
"title": "1.9.0",
|
||||
"path": "release-notes/1-9-0"
|
||||
"title": "1.11.0",
|
||||
"path": "release-notes/1-11-0"
|
||||
},
|
||||
{
|
||||
"title": "1.10.0",
|
||||
"path": "release-notes/1-10-0"
|
||||
},
|
||||
{
|
||||
"title": "1.9.0",
|
||||
"path": "release-notes/1-9-0"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue