diff --git a/.changelog/10559.txt b/.changelog/10559.txt new file mode 100644 index 0000000000..9e755940f9 --- /dev/null +++ b/.changelog/10559.txt @@ -0,0 +1,3 @@ +```release-note:bug +api: Fix default values used for optional fields in autopilot configuration update (POST to `/v1/operator/autopilot/configuration`) [[GH-10558](https://github.com/hashicorp/consul/issues/10558)] +``` diff --git a/agent/operator_endpoint.go b/agent/operator_endpoint.go index f8f2f4fcc6..644fe7fba6 100644 --- a/agent/operator_endpoint.go +++ b/agent/operator_endpoint.go @@ -217,7 +217,7 @@ func (s *HTTPHandlers) OperatorAutopilotConfiguration(resp http.ResponseWriter, s.parseDC(req, &args.Datacenter) s.parseToken(req, &args.Token) - var conf api.AutopilotConfiguration + conf := api.NewAutopilotConfiguration() if err := decodeBody(req.Body, &conf); err != nil { return nil, BadRequestError{Reason: fmt.Sprintf("Error parsing autopilot config: %v", err)} } diff --git a/agent/operator_endpoint_test.go b/agent/operator_endpoint_test.go index ae22e97057..37f893b441 100644 --- a/agent/operator_endpoint_test.go +++ b/agent/operator_endpoint_test.go @@ -435,7 +435,21 @@ func TestOperator_AutopilotSetConfiguration(t *testing.T) { a := NewTestAgent(t, "") defer a.Shutdown() + // Provide a non-default value only for CleanupDeadServers. + // Expect all other fields to be updated with default values + // (except CreateIndex and ModifyIndex). body := bytes.NewBuffer([]byte(`{"CleanupDeadServers": false}`)) + expected := structs.AutopilotConfig{ + CleanupDeadServers: false, // only non-default value + LastContactThreshold: 200 * time.Millisecond, + MaxTrailingLogs: 250, + MinQuorum: 0, + ServerStabilizationTime: 10 * time.Second, + RedundancyZoneTag: "", + DisableUpgradeMigration: false, + UpgradeVersionTag: "", + } + req, _ := http.NewRequest("PUT", "/v1/operator/autopilot/configuration", body) resp := httptest.NewRecorder() if _, err := a.srv.OperatorAutopilotConfiguration(resp, req); err != nil { @@ -453,9 +467,11 @@ func TestOperator_AutopilotSetConfiguration(t *testing.T) { if err := a.RPC("Operator.AutopilotGetConfiguration", &args, &reply); err != nil { t.Fatalf("err: %v", err) } - if reply.CleanupDeadServers { - t.Fatalf("bad: %#v", reply) - } + + // For equality comparison check, ignore CreateIndex and ModifyIndex + expected.CreateIndex = reply.CreateIndex + expected.ModifyIndex = reply.ModifyIndex + require.Equal(t, expected, reply) } func TestOperator_AutopilotCASConfiguration(t *testing.T) { diff --git a/api/operator_autopilot.go b/api/operator_autopilot.go index 8175f5133a..d713ee1cc3 100644 --- a/api/operator_autopilot.go +++ b/api/operator_autopilot.go @@ -58,6 +58,23 @@ type AutopilotConfiguration struct { ModifyIndex uint64 } +// Defines default values for the AutopilotConfiguration type, consistent with +// https://www.consul.io/api-docs/operator/autopilot#parameters-1 +func NewAutopilotConfiguration() AutopilotConfiguration { + cfg := AutopilotConfiguration{ + CleanupDeadServers: true, + LastContactThreshold: NewReadableDuration(200 * time.Millisecond), + MaxTrailingLogs: 250, + MinQuorum: 0, + ServerStabilizationTime: NewReadableDuration(10 * time.Second), + RedundancyZoneTag: "", + DisableUpgradeMigration: false, + UpgradeVersionTag: "", + } + + return cfg +} + // ServerHealth is the health (from the leader's point of view) of a server. type ServerHealth struct { // ID is the raft ID of the server. diff --git a/website/content/docs/k8s/helm.mdx b/website/content/docs/k8s/helm.mdx index cfc9f7bb5c..1b2295833e 100644 --- a/website/content/docs/k8s/helm.mdx +++ b/website/content/docs/k8s/helm.mdx @@ -18,6 +18,8 @@ and consider if they're appropriate for your deployment. the consul-helm repo's values.yaml file --> +### global + - `global` ((#v-global)) - Holds values that affect multiple components of the chart. - `enabled` ((#v-global-enabled)) (`boolean: true`) - The main enabled/disabled setting. If true, servers, @@ -40,10 +42,10 @@ and consider if they're appropriate for your deployment. Examples: ```yaml - # Consul 1.5.0 - image: "consul:1.5.0" - # Consul Enterprise 1.5.0 - image: "hashicorp/consul-enterprise:1.5.0-ent" + # Consul 1.10.0 + image: "consul:1.10.0" + # Consul Enterprise 1.10.0 + image: "hashicorp/consul-enterprise:1.10.0-ent" ``` - `imagePullSecrets` ((#v-global-imagepullsecrets)) (`array`) - Array of objects containing image pull secret names that will be applied to each service account. @@ -252,6 +254,8 @@ and consider if they're appropriate for your deployment. - `enabled` ((#v-global-openshift-enabled)) (`boolean: false`) - If true, the Helm chart will create necessary configuration for running its components on OpenShift. +### server + - `server` ((#v-server)) - Server, when enabled, configures a server cluster to run. This should be disabled if you plan on connecting to a Consul cluster external to the Kube cluster. @@ -519,6 +523,8 @@ and consider if they're appropriate for your deployment. feature, in case kubernetes cluster is behind egress http proxies. Additionally, it could be used to configure custom consul parameters. +### externalServers + - `externalServers` ((#v-externalservers)) - Configuration for Consul servers when the servers are running outside of Kubernetes. When running external servers, configuring these values is recommended if setting `global.tls.enableAutoEncrypt` to true (requires consul-k8s >= 0.13.0) @@ -561,6 +567,8 @@ and consider if they're appropriate for your deployment. -o jsonpath="{.clusters[?(@.name=='')].cluster.server}" ``` +### client + - `client` ((#v-client)) - Values that configure running a Consul client on Kubernetes nodes. - `enabled` ((#v-client-enabled)) (`boolean: global.enabled`) - If true, the chart will install all @@ -792,6 +800,8 @@ and consider if they're appropriate for your deployment. ... ``` +### dns + - `dns` ((#v-dns)) - Configuration for DNS configuration within the Kubernetes cluster. This creates a service that routes to all agents (client or server) for serving DNS requests. This DOES NOT automatically configure kube-dns @@ -817,6 +827,8 @@ and consider if they're appropriate for your deployment. This should be a multi-line string mapping directly to a Kubernetes ServiceSpec object. +### ui + - `ui` ((#v-ui)) - Values that configure the Consul UI. - `enabled` ((#v-ui-enabled)) (`boolean: global.enabled`) - If true, the UI will be enabled. This will @@ -878,7 +890,7 @@ and consider if they're appropriate for your deployment. ```yaml tls: - hosts: - - chart-example.local + - chart-example.local secretName: testsecret-tls ``` @@ -903,6 +915,8 @@ and consider if they're appropriate for your deployment. - `baseURL` ((#v-ui-metrics-baseurl)) (`string: http://prometheus-server`) - baseURL is the URL of the prometheus server, usually the service URL. This value is only used if `ui.enabled` is set to true. +### syncCatalog + - `syncCatalog` ((#v-synccatalog)) - Configure the catalog sync process to sync K8S with Consul services. This can run bidirectional (default) or unidirectionally (Consul to K8S or K8S to Consul only). @@ -1076,6 +1090,8 @@ and consider if they're appropriate for your deployment. anotherLabelKey: another-label-value ``` +### connectInject + - `connectInject` ((#v-connectinject)) - Configures the automatic Connect sidecar injector. - `enabled` ((#v-connectinject-enabled)) (`boolean: false`) - True if you want to enable connect injection. Set to "-" to inherit from @@ -1090,7 +1106,7 @@ and consider if they're appropriate for your deployment. to explicitly opt-out of injection. - `transparentProxy` ((#v-connectinject-transparentproxy)) - Configures Transparent Proxy for Consul Service mesh services. - Using this feature requires Consul 1.10.0+ and consul-k8s 0.26.0+. + Using this feature requires Consul 1.10.0-beta1+ and consul-k8s 0.26.0-beta1+. - `defaultEnabled` ((#v-connectinject-transparentproxy-defaultenabled)) (`boolean: true`) - If true, then all Consul Service mesh will run with transparent proxy enabled by default, i.e. we enforce that all traffic within the pod will go through the proxy. @@ -1110,17 +1126,18 @@ and consider if they're appropriate for your deployment. add prometheus annotations to connect-injected pods. It will also add a listener on the Envoy sidecar to expose metrics. The exposed metrics will depend on whether metrics merging is enabled: - - If metrics merging is enabled: - the Consul sidecar will run a merged metrics server - combining Envoy sidecar and Connect service metrics, - i.e. if your service exposes its own Prometheus metrics. - - If metrics merging is disabled: - the listener will just expose Envoy sidecar metrics. - This will inherit from `global.metrics.enabled`. + + - If metrics merging is enabled: + the Consul sidecar will run a merged metrics server + combining Envoy sidecar and Connect service metrics, + i.e. if your service exposes its own Prometheus metrics. + - If metrics merging is disabled: + the listener will just expose Envoy sidecar metrics. + This will inherit from `global.metrics.enabled`. - `defaultEnableMerging` ((#v-connectinject-metrics-defaultenablemerging)) (`boolean: false`) - Configures the Consul sidecar to run a merged metrics server to combine and serve both Envoy and Connect service metrics. - This feature is available only in Consul v1.10-alpha or greater. + This feature is available only in Consul v1.10.0 or greater. - `defaultMergedMetricsPort` ((#v-connectinject-metrics-defaultmergedmetricsport)) (`integer: 20100`) - Configures the port at which the Consul sidecar will listen on to return combined metrics. This port only needs to be changed if it conflicts with @@ -1129,14 +1146,14 @@ and consider if they're appropriate for your deployment. - `defaultPrometheusScrapePort` ((#v-connectinject-metrics-defaultprometheusscrapeport)) (`integer: 20200`) - Configures the port Prometheus will scrape metrics from, by configuring the Pod annotation `prometheus.io/port` and the corresponding listener in the Envoy sidecar. - NOTE: This is *not* the port that your application exposes metrics on. + NOTE: This is _not_ the port that your application exposes metrics on. That can be configured with the `consul.hashicorp.com/service-metrics-port` annotation. - `defaultPrometheusScrapePath` ((#v-connectinject-metrics-defaultprometheusscrapepath)) (`string: /metrics`) - Configures the path Prometheus will scrape metrics from, by configuring the pod annotation `prometheus.io/path` and the corresponding handler in the Envoy sidecar. - NOTE: This is *not* the path that your application exposes metrics on. + NOTE: This is _not_ the path that your application exposes metrics on. That can be configured with the `consul.hashicorp.com/service-metrics-path` annotation. @@ -1293,6 +1310,8 @@ and consider if they're appropriate for your deployment. - `initContainer` ((#v-connectinject-initcontainer)) (`map`) - Resource settings for the Connect injected init container. +### controller + - `controller` ((#v-controller)) - Controller handles config entry custom resources. Requires consul >= 1.8.4. ServiceIntentions require consul 1.9+. @@ -1331,6 +1350,7 @@ and consider if they're appropriate for your deployment. `global.acls.manageSystemACLs`). If running Consul OSS, requires permissions: + ```hcl operator = "write" service_prefix "" { @@ -1338,12 +1358,15 @@ and consider if they're appropriate for your deployment. intentions = "write" } ``` + If running Consul Enterprise, talk to your account manager for assistance. - `secretName` ((#v-controller-acltoken-secretname)) (`string: null`) - The name of the Kubernetes secret. - `secretKey` ((#v-controller-acltoken-secretkey)) (`string: null`) - The key of the Kubernetes secret. +### meshGateway + - `meshGateway` ((#v-meshgateway)) - Mesh Gateways enable Consul Connect to work across Consul datacenters. - `enabled` ((#v-meshgateway-enabled)) (`boolean: false`) - If mesh gateways are enabled, a Deployment will be created that runs @@ -1469,6 +1492,8 @@ and consider if they're appropriate for your deployment. 'annotation-key': annotation-value ``` +### ingressGateways + - `ingressGateways` ((#v-ingressgateways)) - Configuration options for ingress gateways. Default values for all ingress gateways are defined in `ingressGateways.defaults`. Any of these values may be overridden in `ingressGateways.gateways` for a @@ -1562,6 +1587,8 @@ and consider if they're appropriate for your deployment. - `name` ((#v-ingressgateways-gateways-name)) (`string: ingress-gateway`) +### terminatingGateways + - `terminatingGateways` ((#v-terminatinggateways)) - Configuration options for terminating gateways. Default values for all terminating gateways are defined in `terminatingGateways.defaults`. Any of these values may be overridden in `terminatingGateways.gateways` for a @@ -1643,11 +1670,15 @@ and consider if they're appropriate for your deployment. - `name` ((#v-terminatinggateways-gateways-name)) (`string: terminating-gateway`) +### prometheus + - `prometheus` ((#v-prometheus)) - Configures a demo Prometheus installation. - `enabled` ((#v-prometheus-enabled)) (`boolean: false`) - When true, the Helm chart will install a demo Prometheus server instance alongside Consul. +### tests + - `tests` ((#v-tests)) - Control whether a test Pod manifest is generated when running helm template. When using helm install, the test Pod is not submitted to the cluster so this is only useful when running helm template.