From c708636581f0a613d615ecb4ce0b44522dac2063 Mon Sep 17 00:00:00 2001 From: Romain Pelisse Date: Wed, 27 Sep 2023 19:35:53 +0200 Subject: [PATCH] add role for cruise control deployment --- roles/amq_streams_cruise_control/README.md | 29 ++ .../defaults/main.yml | 18 + .../handlers/main.yml | 12 + .../meta/argument_specs.yml | 90 +++++ .../amq_streams_cruise_control/meta/main.yml | 29 ++ .../tasks/cruise_control_operation.yml | 28 ++ .../amq_streams_cruise_control/tasks/main.yml | 41 ++ .../templates/cruisecontrol.properties.j2 | 366 ++++++++++++++++++ 8 files changed, 613 insertions(+) create mode 100644 roles/amq_streams_cruise_control/README.md create mode 100644 roles/amq_streams_cruise_control/defaults/main.yml create mode 100644 roles/amq_streams_cruise_control/handlers/main.yml create mode 100644 roles/amq_streams_cruise_control/meta/argument_specs.yml create mode 100644 roles/amq_streams_cruise_control/meta/main.yml create mode 100644 roles/amq_streams_cruise_control/tasks/cruise_control_operation.yml create mode 100644 roles/amq_streams_cruise_control/tasks/main.yml create mode 100644 roles/amq_streams_cruise_control/templates/cruisecontrol.properties.j2 diff --git a/roles/amq_streams_cruise_control/README.md b/roles/amq_streams_cruise_control/README.md new file mode 100644 index 0000000..e3c1c48 --- /dev/null +++ b/roles/amq_streams_cruise_control/README.md @@ -0,0 +1,29 @@ +# Cruise Control Role + +Perform installation and configuration of Cruise Control. + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`amq_streams_cruise_control_home`| Path to folder where Cruise Control has been installed | `/opt/cruise-control/` | +|`amq_streams_cruise_control_service_name`| Name of the systemd service running Cruise Control | `amq_streams_cruise_control` | +|`amq_streams_cruise_control_server_start`| Path to start script for systemd service managing Cruise Control | `{{ amq_streams_cruise_control_home }}/kafka-cruise-control-start.sh` | +|`amq_streams_cruise_control_server_stop`| Path to stop script for systemd service managing Cruise Control | `{{ amq_streams_cruise_control_home }}/kafka-cruise-control-stop.sh` | +|`amq_streams_cruise_control_server_config`| Path to config file for Cruise Control service | `/etc/amq_streams_cruise_control.properties` | +|`amq_streams_cruise_control_config_template`| Path to template defining the systemd service for Cruise Control | `templates/service.conf.j2` | +|`amq_streams_cruise_control_config_properties_template`| Path to template defining the config file for Cruise Control | `templates/cruisecontrol.properties.j2` | +|`amq_streams_cruise_control_user`| User account running the Cruise Control service | `root` | +|`amq_streams_cruise_control_group`| Groupname of the account running the Cruise Control service | `root` | +|`amq_streams_cruise_control_zk_host`| Hostname of the Zookeeper instance used by Cruise Control to communicate with the ensemble | `{{ groups['zookeepers'][0] }}` | +|`amq_streams_cruise_control_broker_host`| Hostname of the Zookeeper instance used by Cruise Control to communicate with the ensemble | `{{ groups['brokers'][0] }}` | +|`amq_streams_cruise_control_host`| Name of the host system running Cruise Control | `localhost` | +|`amq_streams_cruise_control_port`| Port used communicate with Cruise Control | `9090` | +|`amq_streams_cruise_control_api_path`| Context of the HTTP API call to Cruise Control (don't modify unless you know what you are doing) | `kafkacruisecontrol` | +|`amq_streams_cruise_control_operation_exec`| Set to False to display the URL built, but do not execute it (debug) | `True` | + +## License + +Apache License v2.0 or later + +## Author Information + +* [Romain Pelisse](https://github.com/rpelisse) diff --git a/roles/amq_streams_cruise_control/defaults/main.yml b/roles/amq_streams_cruise_control/defaults/main.yml new file mode 100644 index 0000000..3f2d0a7 --- /dev/null +++ b/roles/amq_streams_cruise_control/defaults/main.yml @@ -0,0 +1,18 @@ +--- +amq_streams_cruise_control_home: /opt/cruise-control/ +amq_streams_cruise_control_service_name: amq_streams_cruise_control +amq_streams_cruise_control_server_start: "{{ amq_streams_cruise_control_home }}/kafka-cruise-control-start.sh" +amq_streams_cruise_control_server_stop: "{{ amq_streams_cruise_control_home }}/kafka-cruise-control-stop.sh" +amq_streams_cruise_control_server_config: "/etc/amq_streams_cruise_control.properties" +amq_streams_cruise_control_config_template: 'templates/service.conf.j2' +amq_streams_cruise_control_config_properties_template: 'templates/cruisecontrol.properties.j2' +amq_streams_cruise_control_user: root +amq_streams_cruise_control_group: root +amq_streams_cruise_control_zk_host: "{{ groups['zookeepers'][0] }}" +amq_streams_cruise_control_broker_host: "{{ groups['brokers'][0] }}" +# Cruise Control HTTP API +amq_streams_cruise_control_host: 'localhost' +amq_streams_cruise_control_port: 9090 +amq_streams_cruise_control_api_path: 'kafkacruisecontrol' +# Switch next var to False to display the HTTP request +amq_streams_cruise_control_operation_exec: True diff --git a/roles/amq_streams_cruise_control/handlers/main.yml b/roles/amq_streams_cruise_control/handlers/main.yml new file mode 100644 index 0000000..8bb1f9a --- /dev/null +++ b/roles/amq_streams_cruise_control/handlers/main.yml @@ -0,0 +1,12 @@ +--- +- name: "Restart {{ amq_streams_cruise_control_service_name }}" + ansible.builtin.service: + name: "{{ amq_streams_cruise_control_service_name }}" + state: restarted + become: yes + +- name: "Stop {{ amq_streams_cruise_control_service_name }}" + ansible.builtin.service: + name: "{{ amq_streams_cruise_control_service_name }}" + state: stopped + become: yes diff --git a/roles/amq_streams_cruise_control/meta/argument_specs.yml b/roles/amq_streams_cruise_control/meta/argument_specs.yml new file mode 100644 index 0000000..5d96744 --- /dev/null +++ b/roles/amq_streams_cruise_control/meta/argument_specs.yml @@ -0,0 +1,90 @@ +argument_specs: + main: + options: + # line 2 of defaults/main.yml + amq_streams_cruise_control_home: + default: "/opt/cruise-control/" + description: "Path to folder where Cruise Control has been installed" + type: "str" + + # line 3 of defaults/main.yml + amq_streams_cruise_control_service_name: + default: "amq_streams_cruise_control" + description: "Name of the systemd service running Cruise Control" + type: "str" + + # line 4 of defaults/main.yml + amq_streams_cruise_control_server_start: + default: "{{ amq_streams_cruise_control_home }}/kafka-cruise-control-start.sh" + description: "Path to start script for systemd service managing Cruise Control" + type: "str" + + # line 5 of defaults/main.yml + amq_streams_cruise_control_server_stop: + default: "{{ amq_streams_cruise_control_home }}/kafka-cruise-control-stop.sh" + description: "Path to stop script for systemd service managing Cruise Control" + type: "str" + + # line 6 of defaults/main.yml + amq_streams_cruise_control_server_config: + default: "/etc/amq_streams_cruise_control.properties" + description: "Path to config file for Cruise Control service" + type: "str" + + # line 7 of defaults/main.yml + amq_streams_cruise_control_config_template: + default: "templates/service.conf.j2" + description: "Path to template defining the systemd service for Cruise Control" + type: "str" + + # line 8 of defaults/main.yml + amq_streams_cruise_control_config_properties_template: + default: "templates/cruisecontrol.properties.j2" + description: "Path to template defining the config file for Cruise Control" + type: "str" + + # line 9 of defaults/main.yml + amq_streams_cruise_control_user: + default: "root" + description: "User account running the Cruise Control service" + type: "str" + + # line 10 of defaults/main.yml + amq_streams_cruise_control_group: + default: "root" + description: "Groupname of the account running the Cruise Control service" + type: "str" + + # line 11 of defaults/main.yml + amq_streams_cruise_control_zk_host: + default: "{{ groups['zookeepers'][0] }}" + description: "Hostname of the Zookeeper instance used by Cruise Control to communicate with the ensemble" + type: "str" + + # line 12 of defaults/main.yml + amq_streams_cruise_control_broker_host: + default: "{{ groups['brokers'][0] }}" + description: "Hostname of the Zookeeper instance used by Cruise Control to communicate with the ensemble" + type: "str" + + # line 14 of defaults/main.yml + amq_streams_cruise_control_host: + default: "localhost" + description: "Name of the host system running Cruise Control" + type: "str" + + # line 15 of defaults/main.yml + amq_streams_cruise_control_port: + default: 9090 + description: "Port used communicate with Cruise Control" + type: "int" + + # line 16 of defaults/main.yml + amq_streams_cruise_control_api_path: + default: "kafkacruisecontrol" + description: "Context of the HTTP API call to Cruise Control (don't modify unless you know what you are doing)" + type: "str" + amq_streams_cruise_control_operation_exec: + default: True + description: "Indicate if the request must be executed or just diplayed (for debugging purpose)" + type: "bool" diff --git a/roles/amq_streams_cruise_control/meta/main.yml b/roles/amq_streams_cruise_control/meta/main.yml new file mode 100644 index 0000000..f769839 --- /dev/null +++ b/roles/amq_streams_cruise_control/meta/main.yml @@ -0,0 +1,29 @@ +--- +collections: + - middleware_automation.common + +galaxy_info: + role_name: amq_streams_cruise_control + namespace: middleware_automation + author: Romain Pelisse + description: Install AMQ Streams Zookeeper server + company: Red Hat, Inc. + + license: Apache License 2.0 + + min_ansible_version: "2.12" + + platforms: + - name: EL + versions: + - 8 + + galaxy_tags: + - java + - jboss + - wildfly + - cli + - server + +dependencies: +- { role: amq_streams_common } diff --git a/roles/amq_streams_cruise_control/tasks/cruise_control_operation.yml b/roles/amq_streams_cruise_control/tasks/cruise_control_operation.yml new file mode 100644 index 0000000..d35fa0a --- /dev/null +++ b/roles/amq_streams_cruise_control/tasks/cruise_control_operation.yml @@ -0,0 +1,28 @@ +--- +- name: "Ensure required parameters have been provided" + ansible.builtin.assert: + that: + - amq_streams_cruise_control_host is defined and amq_streams_cruise_control_host | length > 0 + - amq_streams_cruise_control_port is defined and amq_streams_cruise_control_port | string | length > 0 + - operation_name is defined and operation_name | length > 0 + quiet: true + +- name: "Build request" + ansible.builtin.set_fact: + cruise_control_url_request: "http://{{ amq_streams_cruise_control_host }}:{{ amq_streams_cruise_control_port }}/{{ amq_streams_cruise_control_api_path }}/{{ operation_name }}" + +- name: "Use Cruise Control to perform {{ operation_name }} on the cluster" + when: + - amq_streams_cruise_control_operation_exec is defined and amq_streams_cruise_control_operation_exec + block: + - name: "Execute request" + ansible.builtin.uri: + url: "{{ cruise_control_url_request }}" + method: POST + return_content: True + register: operation_result + + rescue: + - name: "Display Cruise Control response to operation request ({{ operation_name }})" + ansible.builtin.debug: + var: operation_result diff --git a/roles/amq_streams_cruise_control/tasks/main.yml b/roles/amq_streams_cruise_control/tasks/main.yml new file mode 100644 index 0000000..acaf83d --- /dev/null +++ b/roles/amq_streams_cruise_control/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: "Ensure required parameter(s) are defined." + ansible.builtin.assert: + that: + - amq_stream_cruise_control_home is defined + quiet: true + +- name: "Ensure Cruise Control artifacts are available." + ansible.builtin.include_role: + name: amq_streams_common + +- name: "Ensure Cruise Control artifacts are available." + ansible.builtin.include_role: + name: amq_streams_common + tasks_from: install.yml + +# TODO deal with FW, if enabled + +- name: "Deploy Cruise Control as a systemd service." + ansible.builtin.include_role: + name: amq_streams_common + tasks_from: systemd.yml + vars: +# service_systemd_workdir: "{{ amq_streams_common_home }}" + server_name: "{{ amq_streams_cruise_control_service_name }}" + server_start: "{{ amq_streams_cruise_control_server_start }}" + server_stop: "{{ amq_streams_cruise_control_server_stop }}" + server_config: "{{ amq_streams_cruise_control_server_config }}" + server_config_template: "{{ amq_streams_cruise_control_config_properties_template }}" +# service_systemd_env_file: "{{ amq_streams_connect_systemd_env_file }}" +# service_systemd_env_file_template: "{{ amq_streams_connect_service_config_template }}" +# server_log_dir: "{{ amq_streams_connect_logs_dir | default(omit) }}" +# server_extra_args: "{{ amq_streams_connect_server_extra_args }}" + server_user: "{{ amq_streams_cruise_control_user }}" + server_group: "{{ amq_streams_cruise_control_group }}" +# server_java_opts: "{{ amq_streams_connect_java_opts | default('') }}" +# server_log4j_opts: "{{ amq_streams_connect_java_log4j_opts | default('') }}" +# server_java_heap_opts: "{{ amq_streams_connect_java_heap_opts | default('') }}" +# server_java_performance_opts: "{{ amq_streams_connect_java_performance_opts | default('') }}" +# server_java_gc_log_opts: "{{ amq_streams_connect_java_java_gc_log_opts | default('') }}" +# server_start_sleep: "{{ amq_streams_connect_zookeeper_session_timeout_ms }}" diff --git a/roles/amq_streams_cruise_control/templates/cruisecontrol.properties.j2 b/roles/amq_streams_cruise_control/templates/cruisecontrol.properties.j2 new file mode 100644 index 0000000..9cf6a6b --- /dev/null +++ b/roles/amq_streams_cruise_control/templates/cruisecontrol.properties.j2 @@ -0,0 +1,366 @@ +# +# Copyright 2017 LinkedIn Corp. Licensed under the BSD 2-Clause License (the "License"). See License in the project root for license information. +# + +# This is an example property file for Kafka Cruise Control. See com.linkedin.kafka.cruisecontrol.config.constants for more details. + +# Configuration for the metadata client. +# ======================================= + +# The Kafka cluster to control. +bootstrap.servers={{ amq_streams_cruise_control_broker_host | default('localhost') }}:{{ amq_streams_broker_listener_port | default('9092') }} + +# The maximum interval in milliseconds between two metadata refreshes. +#metadata.max.age.ms=300000 + +# Client id for the Cruise Control. It is used for the metadata client. +#client.id=kafka-cruise-control + +# The size of TCP send buffer bytes for the metadata client. +#send.buffer.bytes=131072 + +# The size of TCP receive buffer size for the metadata client. +#receive.buffer.bytes=131072 + +# The time to wait before disconnect an idle TCP connection. +#connections.max.idle.ms=540000 + +# The time to wait before reconnect to a given host. +#reconnect.backoff.ms=50 + +# The time to wait for a response from a host after sending a request. +#request.timeout.ms=30000 + +# The time to wait for broker logdir to respond after sending a request. +#logdir.response.timeout.ms=10000 + +# Configurations for the load monitor +# ======================================= + +# The metric sampler class +metric.sampler.class=com.linkedin.kafka.cruisecontrol.monitor.sampling.CruiseControlMetricsReporterSampler + +# True if the sampling process allows CPU capacity estimation of brokers used for CPU utilization estimation. +sampling.allow.cpu.capacity.estimation=true + +# Configurations for CruiseControlMetricsReporterSampler +metric.reporter.topic=__CruiseControlMetrics + +# The sample store class name +sample.store.class=com.linkedin.kafka.cruisecontrol.monitor.sampling.KafkaSampleStore + +# The config for the Kafka sample store to save the partition metric samples +partition.metric.sample.store.topic=__KafkaCruiseControlPartitionMetricSamples + +# The config for the Kafka sample store to save the model training samples +broker.metric.sample.store.topic=__KafkaCruiseControlModelTrainingSamples + +# The replication factor of Kafka metric sample store topic +sample.store.topic.replication.factor=2 + +# The config for the number of Kafka sample store consumer threads +num.sample.loading.threads=8 + +# The partition assignor class for the metric samplers +metric.sampler.partition.assignor.class=com.linkedin.kafka.cruisecontrol.monitor.sampling.DefaultMetricSamplerPartitionAssignor + +# The metric sampling interval in milliseconds +metric.sampling.interval.ms=120000 + +# The partition metrics window size in milliseconds +partition.metrics.window.ms=300000 + +# The number of partition metric windows to keep in memory. Partition-load-history = num.partition.metrics.windows * partition.metrics.window.ms +num.partition.metrics.windows=5 + +# The minimum partition metric samples required for a partition in each window +min.samples.per.partition.metrics.window=1 + +# The broker metrics window size in milliseconds +broker.metrics.window.ms=300000 + +# The number of broker metric windows to keep in memory. Broker-load-history = num.broker.metrics.windows * broker.metrics.window.ms +num.broker.metrics.windows=20 + +# The minimum broker metric samples required for a partition in each window +min.samples.per.broker.metrics.window=1 + +# The configuration for the BrokerCapacityConfigFileResolver (supports JBOD, non-JBOD, and heterogeneous CPU core capacities) +#capacity.config.file={{ amq_stream_cruise_control_home }}/config/capacity.json +capacity.config.file={{ amq_stream_cruise_control_home }}/config/capacityJBOD.json + +# Configurations for the analyzer +# ======================================= + +# The list of goals to optimize the Kafka cluster for with pre-computed proposals -- consider using RackAwareDistributionGoal instead of RackAwareGoal in clusters with partitions whose replication factor > number of racks. The value must be a subset of the "goals" and a superset of the "hard.goals" and "self.healing.goals". +default.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PotentialNwOutGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.TopicReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderBytesInDistributionGoal + +# The list of supported goals +goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.BrokerSetAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PotentialNwOutGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.TopicReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderBytesInDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerDiskUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerEvenRackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PreferredLeaderElectionGoal + +# The list of supported intra-broker goals +intra.broker.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.IntraBrokerDiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.IntraBrokerDiskUsageDistributionGoal + +# The list of supported hard goals -- consider using RackAwareDistributionGoal instead of RackAwareGoal in clusters with partitions whose replication factor > number of racks +hard.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal + +# The minimum percentage of well monitored partitions out of all the partitions +min.valid.partition.ratio=0.95 + +# The balance threshold for CPU +cpu.balance.threshold=1.1 + +# The balance threshold for disk +disk.balance.threshold=1.1 + +# The balance threshold for network inbound utilization +network.inbound.balance.threshold=1.1 + +# The balance threshold for network outbound utilization +network.outbound.balance.threshold=1.1 + +# The balance threshold for the replica count +replica.count.balance.threshold=1.1 + +# The capacity threshold for CPU in percentage +cpu.capacity.threshold=0.7 + +# The capacity threshold for disk in percentage +disk.capacity.threshold=0.8 + +# The capacity threshold for network inbound utilization in percentage +network.inbound.capacity.threshold=0.8 + +# The capacity threshold for network outbound utilization in percentage +network.outbound.capacity.threshold=0.8 + +# The threshold to define the cluster to be in a low CPU utilization state +cpu.low.utilization.threshold=0.0 + +# The threshold to define the cluster to be in a low disk utilization state +disk.low.utilization.threshold=0.0 + +# The threshold to define the cluster to be in a low network inbound utilization state +network.inbound.low.utilization.threshold=0.0 + +# The threshold to define the cluster to be in a low network outbound utilization state +network.outbound.low.utilization.threshold=0.0 + +# The metric anomaly percentile upper threshold +metric.anomaly.percentile.upper.threshold=90.0 + +# The metric anomaly percentile lower threshold +metric.anomaly.percentile.lower.threshold=10.0 + +# How often should the cached proposal be expired and recalculated if necessary +proposal.expiration.ms=60000 + +# The maximum number of replicas that can reside on a broker at any given time. +max.replicas.per.broker=10000 + +# The number of threads to use for proposal candidate precomputing. +num.proposal.precompute.threads=1 + +# the topics that should be excluded from the partition movement. +#topics.excluded.from.partition.movement + +# The impact of having one level higher goal priority on the relative balancedness score. +#goal.balancedness.priority.weight + +# The impact of strictness on the relative balancedness score. +#goal.balancedness.strictness.weight + +# Configurations for the executor +# ======================================= + +# The zookeeper connect of the Kafka cluster +zookeeper.connect={{ amq_streams_cruise_control_zk_host | default('localhost') }}:{{ amq_streams_zookeeper_port | default('2181') }} + +# If true, appropriate zookeeper Client { .. } entry required in jaas file located at $base_dir/config/cruise_control_jaas.conf +zookeeper.security.enabled=false + +# The max number of partitions to move in/out on a given broker at a given time. +num.concurrent.partition.movements.per.broker=10 + +# The upper bound of partitions to move in cluster at a given time +max.num.cluster.partition.movements=1250 + +# The max number of partitions to move between disks within a given broker at a given time. +num.concurrent.intra.broker.partition.movements=2 + +# The max number of leadership movement within the whole cluster at a given time. +num.concurrent.leader.movements=1000 + +# Default replica movement throttle. If not specified, movements unthrottled by default. +# default.replication.throttle= + +# The interval between two execution progress checks. +execution.progress.check.interval.ms=10000 + + +# Configurations for anomaly detector +# ======================================= + +# The goal violation notifier class +anomaly.notifier.class=com.linkedin.kafka.cruisecontrol.detector.notifier.SelfHealingNotifier + +# The metric anomaly finder class +metric.anomaly.finder.class=com.linkedin.kafka.cruisecontrol.detector.KafkaMetricAnomalyFinder + +# The anomaly detection interval +#anomaly.detection.interval.ms=10000 + +# The goal violation to detect -- consider using RackAwareDistributionGoal instead of RackAwareGoal in clusters with partitions whose replication factor > number of racks +anomaly.detection.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal + +# The interested metrics for metric anomaly analyzer. +metric.anomaly.analyzer.metrics=BROKER_PRODUCE_LOCAL_TIME_MS_50TH,BROKER_PRODUCE_LOCAL_TIME_MS_999TH,BROKER_CONSUMER_FETCH_LOCAL_TIME_MS_50TH,BROKER_CONSUMER_FETCH_LOCAL_TIME_MS_999TH,BROKER_FOLLOWER_FETCH_LOCAL_TIME_MS_50TH,BROKER_FOLLOWER_FETCH_LOCAL_TIME_MS_999TH,BROKER_LOG_FLUSH_TIME_MS_50TH,BROKER_LOG_FLUSH_TIME_MS_999TH + +# True if recently demoted brokers are excluded from optimizations during self healing, false otherwise +self.healing.exclude.recently.demoted.brokers=true + +# True if recently removed brokers are excluded from optimizations during self healing, false otherwise +self.healing.exclude.recently.removed.brokers=true + +# The zk path to store failed broker information. +failed.brokers.zk.path=/CruiseControlBrokerList + +# Topic config provider class +topic.config.provider.class=com.linkedin.kafka.cruisecontrol.config.KafkaAdminTopicConfigProvider + +# The cluster configurations for the TopicConfigProvider +cluster.configs.file={{ amq_stream_cruise_control_home }}/config/clusterConfigs.json + +# The maximum time in milliseconds to store the response and access details of a completed kafka monitoring user task. +completed.kafka.monitor.user.task.retention.time.ms=86400000 + +# The maximum time in milliseconds to store the response and access details of a completed cruise control monitoring user task. +completed.cruise.control.monitor.user.task.retention.time.ms=86400000 + +# The maximum time in milliseconds to store the response and access details of a completed kafka admin user task. +completed.kafka.admin.user.task.retention.time.ms=604800000 + +# The maximum time in milliseconds to store the response and access details of a completed cruise control admin user task. +completed.cruise.control.admin.user.task.retention.time.ms=604800000 + +# The fallback maximum time in milliseconds to store the response and access details of a completed user task. +completed.user.task.retention.time.ms=86400000 + +# The maximum time in milliseconds to retain the demotion history of brokers. +demotion.history.retention.time.ms=1209600000 + +# The maximum time in milliseconds to retain the removal history of brokers. +removal.history.retention.time.ms=1209600000 + +# The maximum number of completed kafka monitoring user tasks for which the response and access details will be cached. +max.cached.completed.kafka.monitor.user.tasks=20 + +# The maximum number of completed cruise control monitoring user tasks for which the response and access details will be cached. +max.cached.completed.cruise.control.monitor.user.tasks=20 + +# The maximum number of completed kafka admin user tasks for which the response and access details will be cached. +max.cached.completed.kafka.admin.user.tasks=30 + +# The maximum number of completed cruise control admin user tasks for which the response and access details will be cached. +max.cached.completed.cruise.control.admin.user.tasks=30 + +# The fallback maximum number of completed user tasks of certain type for which the response and access details will be cached. +max.cached.completed.user.tasks=25 + +# The maximum number of user tasks for concurrently running in async endpoints across all users. +max.active.user.tasks=5 + +# Enable self healing for all anomaly detectors, unless the particular anomaly detector is explicitly disabled +self.healing.enabled=false + +# Enable self healing for broker failure detector +#self.healing.broker.failure.enabled=true + +# Enable self healing for goal violation detector +#self.healing.goal.violation.enabled=true + +# Enable self healing for metric anomaly detector +#self.healing.metric.anomaly.enabled=true + +# Enable self healing for disk failure detector +#self.healing.disk.failure.enabled=true + +# Enable self healing for topic anomaly detector +#self.healing.topic.anomaly.enabled=true +#topic.anomaly.finder.class=com.linkedin.kafka.cruisecontrol.detector.TopicReplicationFactorAnomalyFinder + +# Enable self healing for maintenance event detector +#self.healing.maintenance.event.enabled=true + +# The multiplier applied to the threshold of distribution goals used by goal.violation.detector. +#goal.violation.distribution.threshold.multiplier=2.50 + +# configurations for the webserver +# ================================ + +# HTTP listen port +webserver.http.port=9090 + +# HTTP listen address +webserver.http.address=0.0.0.0 + +# Whether CORS support is enabled for API or not +webserver.http.cors.enabled=false + +# Value for Access-Control-Allow-Origin +webserver.http.cors.origin=http://localhost:8080/ + +# Value for Access-Control-Request-Method +webserver.http.cors.allowmethods=OPTIONS,GET,POST + +# Headers that should be exposed to the Browser (Webapp) +# This is a special header that is used by the +# User Tasks subsystem and should be explicitly +# Enabled when CORS mode is used as part of the +# Admin Interface +webserver.http.cors.exposeheaders=User-Task-ID + +# REST API default prefix (dont forget the ending /*) +webserver.api.urlprefix=/kafkacruisecontrol/* + +# Location where the Cruise Control frontend is deployed +webserver.ui.diskpath=./cruise-control-ui/dist/ + +# URL path prefix for UI (dont forget the ending /*) +webserver.ui.urlprefix=/* + +# Time After which request is converted to Async +webserver.request.maxBlockTimeMs=10000 + +# Default Session Expiry Period +webserver.session.maxExpiryTimeMs=60000 + +# Session cookie path +webserver.session.path=/ + +# Server Access Logs +webserver.accesslog.enabled=true + +# Configurations for servlet +# ========================== + +# Enable two-step verification for processing POST requests. +two.step.verification.enabled=false + +# The maximum time in milliseconds to retain the requests in two-step (verification) purgatory. +two.step.purgatory.retention.time.ms=1209600000 + +# The maximum number of requests in two-step (verification) purgatory. +two.step.purgatory.max.requests=25 + +#Enable Vertx API with Swagger +vertx.enabled=false + +{% if amq_streams_cruise_control_zk_security_protocol is defined %}security.protocol={{ amq_streams_cruise_control_zk_security_protocol }} +{% endif %} + +{% if amq_streams_cruise_control_zk_sasl_mechanism is defined %}sasl.mechanism={{ amq_streams_cruise_control_zk_sasl_mechanism }} +{% endif %} + +{% if amq_streams_cruise_control_zk_sasl_jaas_config is defined %}sasl.jaas.config={{ amq_streams_cruise_control_zk_sasl_jaas_config }} +{% endif %}