// Module included in the following assemblies:
//
// assembly-cruise-control-concepts.adoc

[id='ref-cruise-control-configuration-{context}']
= Cruise Control configuration

The `config` property in `Kafka.spec.cruiseControl` contains configuration options as keys with values as one of the following JSON types:

* String
* Number
* Boolean

You can specify and configure all the options listed in the "Configurations" section of the {CruiseControlConfigDocs}, apart from those managed directly by Strimzi.
Specifically, you *cannot* modify configuration options with keys equal to or starting with one of the keys mentioned xref:type-CruiseControlSpec-reference[here].

If restricted options are specified, they are ignored and a warning message is printed to the Cluster Operator log file.
All the supported options are passed to Cruise Control.

.An example Cruise Control configuration
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  # ...
  cruiseControl:
    # ...
    config:
      default.goals: >
         com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,
         com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal
      cpu.balance.threshold: 1.1
      metadata.max.age.ms: 300000
      send.buffer.bytes: 131072
    # ...
----

[[cors-configuration]]
[discrete]
== Cross-Origin Resource Sharing configuration

Cross-Origin Resource Sharing (CORS) allows you to specify allowed methods and originating URLs for accessing REST APIs.

By default, CORS is disabled for the Cruise Control REST API.
When enabled, only `GET` requests for read-only access to the Kafka cluster state are allowed.
This means that external applications, which are running in different origins than the Strimzi components, cannot make `POST` requests to the Cruise Control API.
However, those applications can make `GET` requests to access read-only information about the Kafka cluster, such as the current cluster load or the most recent optimization proposal.

.Enabling CORS for Cruise Control

You enable and configure CORS in `Kafka.spec.cruiseControl.config`.
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  # ...
  cruiseControl:
    # ...
    config:
      webserver.http.cors.enabled: true
      webserver.http.cors.origin: "*"
      webserver.http.cors.exposeheaders: "User-Task-ID,Content-Type"
    # ...
----

For more information, see {CruiseControlApiDocs}.

[[capacity-configuration]]
[discrete]
== Capacity configuration

Cruise Control uses _capacity limits_ to determine if optimization goals for resource distribution are being broken.
There are four goals of this type:

* `DiskUsageDistributionGoal`            - Disk utilization distribution
* `CpuUsageDistributionGoal`             - CPU utilization distribution
* `NetworkInboundUsageDistributionGoal`  - Network inbound utilization distribution
* `NetworkOutboundUsageDistributionGoal` - Network outbound utilization distribution

You specify capacity limits for Kafka broker resources in the `brokerCapacity` property in `Kafka.spec.cruiseControl` .
They are enabled by default and you can change their default values.
Capacity limits can be set for the following broker resources:

* `cpuUtilization`  - CPU utilization as a percentage (Default: 100)
* `inboundNetwork`  - Inbound network throughput in byte units per second (Default: 10000KiB/s)
* `outboundNetwork` - Outbound network throughput in byte units per second (Default: 10000KiB/s)

For network throughput, use an integer value with standard Kubernetes byte units (K, M, G) or their bibyte (power of two) equivalents (Ki, Mi, Gi) per second.

NOTE: Disk capacity limits are automatically generated by Strimzi, so we do not need to set them.

[NOTE]
====
In order to guarantee accurate rebalance proposal when using CPU goals, you can set CPU requests equal to CPU limits in `Kafka.spec.kafka.resources`.
That way, all CPU resources are reserved upfront and are always available.
This configuration allows Cruise Control to properly evaluate the CPU utilization when preparing the rebalance proposals based on CPU goals.
====

.An example Cruise Control brokerCapacity configuration using bibyte units
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  # ...
  cruiseControl:
    # ...
    brokerCapacity:
      cpuUtilization: 100
      inboundNetwork: 10000KiB/s
      outboundNetwork: 10000KiB/s
    # ...
----

.Additional resources
For more information, refer to the xref:type-BrokerCapacity-reference[].

[[logging-configuration]]
[discrete]
== Logging configuration

Cruise Control has its own configurable logger:

* `rootLogger.level`

Cruise Control uses the Apache `log4j 2` logger implementation.

Use the `logging` property to configure loggers and logger levels.

You can set the log levels by specifying the logger and level directly (inline) or use a custom (external) ConfigMap.
If a ConfigMap is used, you set `logging.valueFrom.configMapKeyRef.name` property to the name of the ConfigMap containing the external logging configuration. Inside the ConfigMap, the logging configuration is described using `log4j.properties`. Both `logging.valueFrom.configMapKeyRef.name` and `logging.valueFrom.configMapKeyRef.key` properties are mandatory. A ConfigMap using the exact logging configuration specified is created with the custom resource when the Cluster Operator is running, then recreated after each reconciliation. If you do not specify a custom ConfigMap, default logging settings are used. If a specific logger value is not set, upper-level logger settings are inherited for that logger.
Here we see examples of `inline` and `external` logging.

.Inline logging
[source,yaml,subs="+quotes,attributes"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
# ...
spec:
  cruiseControl:
    # ...
    logging:
      type: inline
      loggers:
        rootLogger.level: "INFO"
    # ...
----

.External logging
[source,yaml,subs="+quotes,attributes"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
# ...
spec:
  cruiseControl:
    # ...
    logging:
      type: external
      valueFrom:
        configMapKeyRef:
          name: customConfigMap
          key: cruise-control-log4j.properties
    # ...
----

[[api-security-configuration]]
[discrete]
== Cruise Control REST API security

The Cruise Control REST API is secured with HTTP Basic authentication and SSL to protect the cluster against potentially destructive Cruise Control operations, such as decommissioning Kafka brokers.

We recommend that Cruise Control in Strimzi is **only used with these settings enabled**.
You should not disable the built-in HTTP Basic authentication or SSL settings described below.

* To disable the built-in HTTP Basic authentication, set `webserver.security.enable` to `false`.
* To disable the built-in SSL, set `webserver.ssl.enable` to `false`.

.Example Cruise Control configuration to disable API authorization, authentication, and SSL
[source,yaml,subs="attributes+"]
----
apiVersion: {KafkaApiVersion}
kind: Kafka
metadata:
  name: my-cluster
spec:
  # ...
  cruiseControl:
    config:
      webserver.security.enable: false
      webserver.ssl.enable: false
# ...
----
