```
Some checks failed
Build Helm Chart / helm-package (push) Failing after 30s

Rename artemis-broker to artemis-broker-primary

This commit renames and refactors the Helm chart for the
artemis-broker. The original files in the artemis-broker
directory are renamed and moved to artemis-broker-primary.
The purpose of this change is to enable a clear
distinction between the primary broker configuration and any
backup or alternative configurations.

Additionally, the configuration has been updated to support
enhancements in TLS setup, metrics services, and users,
allowing for a more robust and flexible deployment.
This change introduces new templates and scripts needed
for managing various aspects of the broker's functions,
including improved user authentication and logging. No
breaking changes were introduced, but users must update
their references to the chart paths as they now point to
the new directory structure.
```
This commit is contained in:
Marko Oldenburg 2025-03-18 08:30:01 +01:00
parent 568b4d1422
commit b2d45ee0c4
60 changed files with 2002 additions and 0 deletions

3
artemis-broker-primary/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
values.test
tls/broker*
tls/client*

View File

@ -0,0 +1,14 @@
apiVersion: v2
name: artemis-broker
version: 7.12.3-test2
description: An unified Helm Chart that deploys an Artemis MQ Broker with optional SSL support and Optional Disk Persistence. Clustered setups are also supported.
type: application
keywords:
- activemq
- artemismq
- amq-broker
- ssl-endpoint
- amq-cluster
home: https://access.redhat.com/products/red-hat-amq/
sources:
- https://git.cooltux.net/marko/amq-broker-helm

View File

@ -0,0 +1,49 @@
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
## CUSTOMCONFIG
# syntax is role = list of users
# ADMIN ROLE MAPPING
{{- $admins := list -}}
{{- $admins = printf "%s" $.Values.admin.user | append $admins -}}
{{- range $currentUser := $.Values.users }}
{{- if has ($.Values.admin.role) $currentUser.roles }}
{{- $admins = printf "%s" (toString $currentUser.name) | append $admins -}}
{{- end }}
{{- end }}
{{ $.Values.admin.role }} = {{ $admins | join "," }}
{{- $declared_roles := list }}
{{- range .Values.users }}
{{- range .roles }}
{{- if and (not (has (toString .) $declared_roles)) (not (eq (toString .) ($.Values.admin.role))) }}
{{- $declared_roles = printf "%s" (toString .) | append $declared_roles }}
{{- end }}
{{- end }}
{{- end }}
# ADDITIONAL ROLE MAPPING
{{- range $current_role := $declared_roles }}
{{- $users_in_role := list -}}
{{- range $currentUser := $.Values.users }}
{{- if has $current_role $currentUser.roles }}
{{- $users_in_role = printf "%s" (toString $currentUser.name) | append $users_in_role -}}
{{- end }}
{{- end }}
{{ $current_role }} = {{ $users_in_role | join "," }}
{{- end }}

View File

@ -0,0 +1,28 @@
{{- if .Values.security.createSecret }}
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
## CUSTOMCONFIG
# ADMIN USER
{{ .Values.admin.user }} = {{ .Values.admin.password }}
# ADDITIONAL USERS
{{- range .Values.users }}
{{ .name }} = {{ .password }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,43 @@
{{- $jolokia_ssl := and (.Values.parameters.tls_enabled) (.Values.parameters.jolokia_passthrough) }}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<broker xmlns="http://activemq.apache.org/schema">
<jaas-security domain="activemq"/>
<!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
This is to avoid situations where you could have spaces or special characters on this URI -->
<server configuration="file:${HOME}/${AMQ_NAME}/etc//broker.xml"/>
<!-- The web server is only bound to localhost by default -->
{{- if $jolokia_ssl }}
<web bind="https://0.0.0.0:8161" path="web" keyStorePath="{{ .Values.tls.secret_mount_path }}/{{ .Values.tls.keystore }}" keyStorePassword="{{ .Values.tls.keystore_password }}">
{{- else }}
<web bind="http://0.0.0.0:8161" path="web">
{{- end }}
<app url="redhat-branding" war="redhat-branding.war"/>
<app url="artemis-plugin" war="artemis-plugin.war"/>
<app url="console" war="hawtio.war"/>
<app url="metrics" war="metrics.war"/>
</web>
</broker>

View File

@ -0,0 +1,258 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Licensed to the Apache Software Foundation (ASF) under oneor more contributor license agreements. See the NOTICE filedistributed with this work for additional informationregarding copyright ownership. The ASF licenses this fileto you under the Apache License, Version 2.0 (the"License"); you may not use this file except in compliancewith the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing,software distributed under the License is distributed on an"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANYKIND, either express or implied. See the License for thespecific language governing permissions and limitationsunder the License.-->
<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xsi:schemaLocation="urn:activemq:core ">
<name>${AMQ_NAME}</name>
{{- if and .Values.application.persistent (or .Values.clustered .Values.ha_ap) }}
<persistence-enabled>true</persistence-enabled>
<!-- this could be ASYNCIO, MAPPED, NIO ASYNCIO: Linux Libaio MAPPED: mmap files NIO: Plain Java Files -->
<journal-type>{{ .Values.application.journal_type }}</journal-type>
<paging-directory>${AMQ_DATA_DIR}/paging</paging-directory>
<bindings-directory>${AMQ_DATA_DIR}/bindings</bindings-directory>
<journal-directory>${AMQ_DATA_DIR}/journal</journal-directory>
<large-messages-directory>${AMQ_DATA_DIR}/large-messages</large-messages-directory>
{{- else }}
<persistence-enabled>false</persistence-enabled>
<!-- this could be ASYNCIO, MAPPED, NIO ASYNCIO: Linux Libaio MAPPED: mmap files NIO: Plain Java Files -->
<journal-type>NIO</journal-type>
<paging-directory>./data/paging</paging-directory>
<bindings-directory>./data/bindings</bindings-directory>
<journal-directory>./data/journal</journal-directory>
<large-messages-directory>./data/large-messages</large-messages-directory>
{{- end }}
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-file-size>10M</journal-file-size>
<!-- This value was determined through a calculation. Your system could perform 0.26 writes per millisecond on the current journal configuration. That translates as a sync write every 3800000 nanoseconds. Note: If you specify 0 the system will perform writes directly to the disk. We recommend this to be 0 if you are using journalType=MAPPED and ournal-datasync=false. -->
<journal-buffer-timeout>9524000</journal-buffer-timeout>
<!-- When using ASYNCIO, this will determine the writing queue depth for libaio. -->
<journal-max-io>4096</journal-max-io>
<!-- You can verify the network health of a particular NIC by specifying the <network-check-NIC> element. <network-check-NIC>theNicName</network-check-NIC> -->
<!-- Use this to use an HTTP server to validate the network <network-check-URL-list>http://www.apache.org</network-check-URL-list> -->
<!-- <network-check-period>10000</network-check-period> -->
<!-- <network-check-timeout>1000</network-check-timeout> -->
<!-- this is a comma separated list, no spaces, just DNS or IPs it should accept IPV6 Warning: Make sure you understand your network topology as this is meant to validate if your network is valid. Using IPs that could eventually disappear or be partially visible may defeat the purpose. You can use a list of multiple IPs, and if any successful ping will make the server OK to continue running -->
<!-- <network-check-list>10.0.0.1</network-check-list> -->
<!-- use this to customize the ping used for ipv4 addresses -->
<!-- <network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command> -->
<!-- use this to customize the ping used for ipv6 addresses -->
<!-- <network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command> -->
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols that won't support flow control. -->
<max-disk-usage>90</max-disk-usage>
<!-- should the broker detect dead locks and other issues -->
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<!-- the system will enter into page mode once you hit this limit. This is an estimate in bytes of how much the messages are using in memory The system will use half of the available memory (-Xmx) by default for the global-max-size. You may specify a different value here if you need to customize it to your needs. <global-max-size>${AMQ_STORAGE_USAGE_LIMIT}</global-max-size> -->
<acceptors>
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
<!-- amqpCredits: The number of credits sent to AMQP producers -->
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
<!-- Acceptor for every supported protocol -->
{{- if .Values.parameters.tls_enabled }}
{{- range .Values.service.acceptors }}
{{- $extra_args := list -}}
{{- range .acceptor_params }}
{{- $extra_args = printf "%s=%s" (toString .key) (toString .value) | append $extra_args }}
{{- end }}
{{- if or (.use_tls) (eq (.use_tls | toString) "<nil>") }}
<acceptor name="{{ .name }}">tcp://${BROKER_IP}:{{ .port }}?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols={{ default $.Values.parameters.amq_protocols .amq_protocols }};useEpoll=true;amqpCredits=1000;amqpLowCredits=300;anycastPrefix=${AMQ_ANYCAST_PREFIX};multicastPrefix=${AMQ_MULTICAST_PREFIX};connectionsAllowed={{ .max_connections }};sslEnabled=true;keyStorePath=${AMQ_KEYSTORE_TRUSTSTORE_DIR}/{{ $.Values.tls.keystore }};keyStorePassword=${AMQ_KEYSTORE_PASSWORD};trustStorePath=${AMQ_KEYSTORE_TRUSTSTORE_DIR}/{{ $.Values.tls.truststore }};trustStorePassword=${AMQ_TRUSTSTORE_PASSWORD};sslProvider={{ $.Values.parameters.ssl_provider }};{{ $extra_args | join ";" }}</acceptor>
{{- else }}
<acceptor name="{{ .name }}">tcp://${BROKER_IP}:{{ .port }}?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols={{ default $.Values.parameters.amq_protocols .amq_protocols }};useEpoll=true;amqpCredits=1000;amqpLowCredits=300;anycastPrefix=${AMQ_ANYCAST_PREFIX};multicastPrefix=${AMQ_MULTICAST_PREFIX};{{ $extra_args | join ";" }}</acceptor>
{{- end }}
{{- end }}
{{- else }}
{{- range .Values.service.acceptors }}
{{- $extra_args := list -}}
{{- range .acceptor_params }}
{{- $extra_args = printf "%s=%s" (toString .key) (toString .value) | append $extra_args }}
{{- end }}
<acceptor name="{{ .name }}">tcp://${BROKER_IP}:{{ .port }}?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols={{ default $.Values.parameters.amq_protocols .amq_protocols }};useEpoll=true;amqpCredits=1000;amqpLowCredits=300;anycastPrefix=${AMQ_ANYCAST_PREFIX};multicastPrefix=${AMQ_MULTICAST_PREFIX};{{ $extra_args | join ";" }}</acceptor>
{{- end }}
{{- end }}
</acceptors>
<security-enabled>{{ .Values.security.enabled }}</security-enabled>
<security-settings>
{{- range .Values.queues.addresses }}
<security-setting match="{{ .name }}">
{{- range .permissions }}
<permission type="{{ .grant }}" roles="{{- range $i, $el := .roles }}{{if $i}},{{end}}{{$el}}{{- end -}}" />
{{- end }}
</security-setting>
{{- end }}
<security-setting match="#">
<permission type="createNonDurableQueue" roles="${AMQ_ROLE}" />
<permission type="deleteNonDurableQueue" roles="${AMQ_ROLE}" />
<permission type="createDurableQueue" roles="${AMQ_ROLE}" />
<permission type="deleteDurableQueue" roles="${AMQ_ROLE}" />
<permission type="createAddress" roles="${AMQ_ROLE}" />
<permission type="deleteAddress" roles="${AMQ_ROLE}" />
<permission type="consume" roles="${AMQ_ROLE}" />
<permission type="browse" roles="${AMQ_ROLE}" />
<permission type="send" roles="${AMQ_ROLE}" />
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="${AMQ_ROLE}" />
</security-setting>
</security-settings>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<max-delivery-attempts>{{ .Values.queues.defaults.maxDeliveryAttempts }}</max-delivery-attempts>
<redelivery-delay>{{ .Values.queues.defaults.redeliveryDelay }}</redelivery-delay>
<redelivery-delay-multiplier>{{ .Values.queues.defaults.redeliveryDelayMultiplier }}</redelivery-delay-multiplier>
<max-redelivery-delay>{{ .Values.queues.defaults.maxRedeliveryDelay }}</max-redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>{{ .Values.queues.defaults.maxSizeBytes }}</max-size-bytes>
<message-counter-history-day-limit>{{ .Values.queues.defaults.messageCounterHistoryDayLimit }}</message-counter-history-day-limit>
<address-full-policy>{{ .Values.queues.defaults.addressFullPolicy }}</address-full-policy>
{{- if .Values.parameters.amq_force_addresses_cleanup }}
<config-delete-addresses>FORCE</config-delete-addresses>
<config-delete-queues>FORCE</config-delete-queues>
{{- end }}
</address-setting>
{{- range .Values.queues.addresses }}
<address-setting match="{{ .name }}">
{{- if .dlq_address }}
<dead-letter-address>{{ .dlq_address }}</dead-letter-address>
{{- end }}
{{- if .expiry_address }}
<expiry-address>{{ .expiry_address }}</expiry-address>
{{- end }}
<max-delivery-attempts>{{ default $.Values.queues.defaults.maxDeliveryAttempts .maxDeliveryAttempts }}</max-delivery-attempts>
<redelivery-delay>{{ default $.Values.queues.defaults.redeliveryDelay .redeliveryDelay }}</redelivery-delay>
<redelivery-delay-multiplier>{{ default $.Values.queues.defaults.redeliveryDelayMultiplier .redeliveryDelayMultiplier }}</redelivery-delay-multiplier>
<max-redelivery-delay>{{ default $.Values.queues.defaults.maxRedeliveryDelay .maxRedeliveryDelay }}</max-redelivery-delay>
<max-size-bytes>{{ default $.Values.queues.defaults.maxSizeBytes .maxSizeBytes }}</max-size-bytes>
<message-counter-history-day-limit>{{ default $.Values.queues.defaults.messageCounterHistoryDayLimit .messageCounterHistoryDayLimit }}</message-counter-history-day-limit>
<address-full-policy>{{ default $.Values.queues.defaults.addressFullPolicy .addressFullPolicy }}</address-full-policy>
</address-setting>
{{- end }}
</address-settings>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
{{- range .Values.queues.addresses }}
<address name="{{ .name }}">
{{- $isMulticast := "" }}
{{- if ( .type ) }}{{- if eq .type "multicast" }}
{{- $isMulticast = print "true" }}
{{- end }}{{- end }}
{{- if $isMulticast }}
<multicast/>
{{- else }}
<anycast>
<queue name="{{ .name }}" />
</anycast>
{{- end }}
</address>
{{- if .dlq_address }}
<address name="{{ .dlq_address }}">
<anycast>
<queue name="{{ .dlq_address }}" />
</anycast>
</address>
{{- end }}
{{- if .expiry_address }}
<address name="{{ .expiry_address }}">
<anycast>
<queue name="{{ .expiry_address }}" />
</anycast>
</address>
{{- end }}
{{- end }}
</addresses>
{{- if .Values.metrics.enabled }}
<metrics>
<jvm-memory>{{ .Values.metrics.jvm_memory }}</jvm-memory>
<jvm-gc>{{ .Values.metrics.jvm_gc }}</jvm-gc>
<jvm-threads>{{ .Values.metrics.jvm_threads }}</jvm-threads>
<plugin class-name="com.redhat.amq.broker.core.server.metrics.plugins.ArtemisPrometheusMetricsPlugin"/>
</metrics>
{{- end }}
{{- if .Values.clustered }}
{{- if .Values.cluster.ha_ap_mode }}
<connectors>
<connector name="{{ .Values.ha_ap.connector.ref }}">tcp://${BROKER_IP}:{{ .Values.ha_ap.connector.port }}</connector>
<connector name="{{ .Values.ha_ap.connector.static.ref }}">tcp://{{ .Values.ha_ap.connector.static.ref }}-svc:{{ .Values.ha_ap.connector.static.port }}</connector>
</connectors>
<cluster-connections>
<cluster-connection name="my-cluster">
<connector-ref>{{ .Values.ha_ap.connector.ref }}</connector-ref>
<static-connectors>
<connector-ref>{{ .Values.ha_ap.connector.static.ref }}</connector-ref>
</static-connectors>
</cluster-connection>
</cluster-connections>
<ha-policy>
<shared-store>
{{- if eq .Values.ha_ap.mode "primary" }}
<primary>
<failover-on-shutdown>true</failover-on-shutdown>
</primary>
{{- else }}
<backup>
<failover-on-shutdown>true</failover-on-shutdown>
</backup>
{{- end }}
</shared-store>
</ha-policy>
{{- else }}
<connectors>
<connector name="{{ .Values.cluster.connector.ref }}">tcp://${BROKER_IP}:{{ .Values.cluster.connector.port }}</connector>
</connectors>
<discovery-groups>
<discovery-group name="my-discovery-group">
<jgroups-file>{{ .Values.cluster.jgroupsCfg }}</jgroups-file>
<jgroups-channel>activemq_broadcast_channel</jgroups-channel>
<refresh-timeout>{{ .Values.cluster.refreshTimeout }}</refresh-timeout>
</discovery-group>
</discovery-groups>
<broadcast-groups>
<broadcast-group name="my-broadcast-group">
<jgroups-file>{{ .Values.cluster.jgroupsCfg }}</jgroups-file>
<jgroups-channel>activemq_broadcast_channel</jgroups-channel>
<connector-ref>{{ .Values.cluster.connector.ref }}</connector-ref>
</broadcast-group>
</broadcast-groups>
<cluster-connections>
<cluster-connection name="my-cluster">
<connector-ref>{{ .Values.cluster.connector.ref }}</connector-ref>
<retry-interval>1000</retry-interval>
<retry-interval-multiplier>2</retry-interval-multiplier>
<max-retry-interval>32000</max-retry-interval>
<initial-connect-attempts>20</initial-connect-attempts>
<reconnect-attempts>10</reconnect-attempts>
<use-duplicate-detection>true</use-duplicate-detection>
<message-load-balancing>ON_DEMAND</message-load-balancing>
<max-hops>1</max-hops>
<discovery-group-ref discovery-group-name="my-discovery-group"/>
</cluster-connection>
</cluster-connections>
{{- end }}
{{- end }}
</core>
</configuration>

View File

@ -0,0 +1,34 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:org:jgroups"
xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd">
<TCP bind_addr="${jgroups.bind_addr:site_local}"
bind_port="${jgroups.bind_port:{{ .Values.ping_service.jgroups.bind_port }}}"
external_addr="${jgroups.external_addr}"
external_port="${jgroups.external_port}"
thread_pool.min_threads="0"
thread_pool.max_threads="200"
thread_pool.keep_alive_time="30000"/>
<RED/>
<dns.DNS_PING
dns_query="{{ tpl .Values.ping_service.name . }}"
dns_record_type="${DNS_RECORD_TYPE:A}"
/>
<MERGE3 min_interval="10000"
max_interval="30000" />
<FD_SOCK2/>
<FD_ALL3 timeout="40000" interval="5000" />
<VERIFY_SUSPECT2 timeout="1500" />
<pbcast.NAKACK2 use_mcast_xmit="false" />
<UNICAST3 />
<pbcast.STABLE desired_avg_gossip="50000"
max_bytes="4M"/>
<pbcast.GMS print_local_addr="true" join_timeout="2000"/>
<UFC max_credits="2M"
min_threshold="0.4"/>
<MFC max_credits="2M"
min_threshold="0.4"/>
<FRAG2 frag_size="60K" />
</config>

View File

@ -0,0 +1,23 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
activemq {
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule requisite
reload=true
org.apache.activemq.jaas.properties.user="{{ .Values.security.jaasUsers.key }}"
org.apache.activemq.jaas.properties.role="artemis-roles.properties";
};

View File

@ -0,0 +1,37 @@
#!/bin/bash
set -e
INSTANCE_DIR=$1
declare -a CONFIG_FILES=("bootstrap.xml" "broker.xml" "logging.properties")
function swapVars() {
# Requires bash v4+
declare -A SUBSTITUTIONS
while read -r SUBVAR
do
SUBSTITUTIONS[$SUBVAR]=1
done < <( awk '{
while( match($0, /\$\{[a-zA-Z_0-9][a-zA-Z_0-9]*\}/) ) {
print substr($0, RSTART, RLENGTH)
sub(/\$\{[a-zA-Z_0-9][a-zA-Z_0-9]*\}/, "matched", $0)
}
}' $1 )
echo "Found placeholder variables: \"${!SUBSTITUTIONS[@]}\". Customizing configuration.."
for var in "${!SUBSTITUTIONS[@]}"; do
sed -i "s#$var#$(eval echo \"$var\")#g" $1
done
}
for config_file in ${CONFIG_FILES[@]};
do
# Swap env vars into configuration file
if [[ -e $INSTANCE_DIR/etc/$config_file ]]; then
echo "Patching Custom Configuration file '$config_file'"
swapVars $INSTANCE_DIR/etc/$config_file
fi
done

View File

@ -0,0 +1,75 @@
#!/bin/sh
export BROKER_IP=`hostname -f`
instanceDir="${HOME}/${AMQ_NAME}"
ENDPOINT_NAME="${HEADLESS_ENDPOINT}"
if [ "$HEADLESS_SVC_NAME" ]; then
ENDPOINT_NAME=$HEADLESS_SVC_NAME
fi
endpointsUrl="https://${KUBERNETES_SERVICE_HOST:-kubernetes.default.svc}:${KUBERNETES_SERVICE_PORT:-443}/api/v1/namespaces/${POD_NAMESPACE}/"
endpointsAuth="Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
function waitForJolokia() {
while : ;
do
sleep 5
curl -s -o /dev/null -G -k http://${AMQ_USER}:${AMQ_PASSWORD}@${BROKER_IP}:8161/console/jolokia
if [ $? -eq 0 ]; then
break
fi
done
}
endpointsCode=$(curl -s -o /dev/null -w "%{http_code}" -G -k -H "${endpointsAuth}" ${endpointsUrl})
if [ $endpointsCode -ne 200 ]; then
echo "Can't find endpoints with ips status <${endpointsCode}>"
exit 1
fi
ENDPOINTS=$(curl -s -X GET -G -k -H "${endpointsAuth}" ${endpointsUrl}"endpoints/${ENDPOINT_NAME}")
echo $ENDPOINTS
count=0
while [ 1 ]; do
ip=$(echo $ENDPOINTS | python -c "import sys, json; print json.load(sys.stdin)['subsets'][0]['addresses'][${count}]['ip']")
if [ $? -ne 0 ]; then
echo "Can't find ip to scale down to tried ${count} ips"
exit
fi
echo "got ip ${ip} broker ip is ${BROKER_IP}"
if [ "$ip" != "$BROKER_IP" ]; then
break
fi
count=$(( count + 1 ))
done
source /opt/amq/bin/launch.sh nostart
SCALE_TO_BROKER_IP=$ip
# Add connector to the pod to scale down to
connector="<connector name=\"scaledownconnector\">tcp:\/\/${SCALE_TO_BROKER_IP}:61616<\/connector>"
sed -i "/<\/connectors>/ s/.*/${connector}\n&/" ${instanceDir}/etc/broker.xml
# Remove the acceptors
#sed -i -ne "/<acceptors>/ {p; " -e ":a; n; /<\/acceptors>/ {p; b}; ba}; p" ${instanceDir}/etc/broker.xml
acceptor="<acceptor name=\"artemis\">tcp:\/\/${BROKER_IP}:61616?protocols=CORE<\/acceptor>"
sed -i -ne "/<acceptors>/ {p; i $acceptor" -e ":a; n; /<\/acceptors>/ {p; b}; ba}; p" ${instanceDir}/etc/broker.xml
#start the broker and issue the scaledown command to drain the messages.
${instanceDir}/bin/artemis-service start
if [ "$AMQ_DATA_DIR_LOGGING" = "true" ]; then
tail -n 100 -f ${AMQ_DATA_DIR}/log/artemis.log &
else
tail -n 100 -f ${AMQ_NAME}/log/artemis.log &
fi
waitForJolokia
curl -s -o /dev/null -G -k http://${AMQ_USER}:${AMQ_PASSWORD}@${BROKER_IP}:8161/console/jolokia/exec/org.apache.activemq.artemis:broker=%22${AMQ_NAME}%22/scaleDown/scaledownconnector

View File

@ -0,0 +1,444 @@
#!/bin/bash
if [ "${SCRIPT_DEBUG}" = "true" ] ; then
set -x
echo "Script debugging is enabled, allowing bash commands and their arguments to be printed as they are executed"
fi
export BROKER_IP=`hostname -I`
CONFIG_TEMPLATES=/config_templates
#GC Option conflicts with the one already configured.
echo "Removing provided -XX:+UseParallelOldGC in favour of artemis.profile provided option"
JAVA_OPTS=$(echo $JAVA_OPTS | sed -e "s/-XX:+UseParallelOldGC/ /")
PLATFORM=`uname -m`
echo "Platform is ${PLATFORM}"
if [ "${PLATFORM}" = "s390x" ] ; then
#GC Option found to be a problem on s390x
echo "Removing -XX:+UseG1GC as per recommendation to use default GC"
JAVA_OPTS=$(echo $JAVA_OPTS | sed -e "s/-XX:+UseG1GC/ /")
#JDK11 related warnings removal
echo "Adding -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true as per ENTMQBR-1932"
JAVA_OPTS="-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true ${JAVA_OPTS}"
fi
JAVA_OPTS="-Djava.net.preferIPv4Stack=true ${JAVA_OPTS}"
if [ "$AMQ_ENABLE_JOLOKIA_AGENT" = "true" ]; then
echo "Define jolokia jvm agent options"
if [ -z ${AMQ_JOLOKIA_AGENT_OPTS} ]; then
if [ -f "/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt" ]; then
AMQ_JOLOKIA_AGENT_OPTS='realm=activemq,caCert=/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt,clientPrincipal.1=cn=system:master-proxy,clientPrincipal.2=cn=hawtio-online.hawtio.svc,clientPrincipal.3=cn=fuse-console.fuse.svc'
else
AMQ_JOLOKIA_AGENT_OPTS='realm=activemq,clientPrincipal.1=cn=system:master-proxy,clientPrincipal.2=cn=hawtio-online.hawtio.svc,clientPrincipal.3=cn=fuse-console.fuse.svc'
fi
fi
export AB_JOLOKIA_USER=$AMQ_JOLOKIA_AGENT_USER
export AB_JOLOKIA_PASSWORD_RANDOM=false
export AB_JOLOKIA_PASSWORD=$AMQ_JOLOKIA_AGENT_PASSWORD
export AB_JOLOKIA_OPTS="${AMQ_JOLOKIA_AGENT_OPTS}"
JOLOKIA_OPTS="$(/opt/jolokia/jolokia-opts)"
echo "JOLOKIA_OPTS: $JOLOKIA_OPTS"
fi
function sslPartial() {
[ -n "$AMQ_KEYSTORE_TRUSTSTORE_DIR" -o -n "$AMQ_KEYSTORE" -o -n "$AMQ_TRUSTSTORE" -o -n "$AMQ_KEYSTORE_PASSWORD" -o -n "$AMQ_TRUSTSTORE_PASSWORD" ]
}
function sslEnabled() {
[ -n "$AMQ_KEYSTORE_TRUSTSTORE_DIR" -a -n "$AMQ_KEYSTORE" -a -n "$AMQ_TRUSTSTORE" -a -n "$AMQ_KEYSTORE_PASSWORD" -a -n "$AMQ_TRUSTSTORE_PASSWORD" ]
}
# Finds the environment variable and returns its value if found.
# Otherwise returns the default value if provided.
#
# Arguments:
# $1 env variable name to check
# $2 default value if environemnt variable was not set
function find_env() {
var=${!1}
echo "${var:-$2}"
}
function configureUserAuthentication() {
if [ -n "${AMQ_USER}" -a -n "${AMQ_PASSWORD}" ] ; then
AMQ_ARGS="$AMQ_ARGS --user $AMQ_USER --password $AMQ_PASSWORD "
else
echo "Required variable missing: both AMQ_USER and AMQ_PASSWORD are required."
exit 1
fi
if [ "$AMQ_REQUIRE_LOGIN" = "true" ]; then
AMQ_ARGS="$AMQ_ARGS --require-login"
else
AMQ_ARGS="$AMQ_ARGS --allow-anonymous"
fi
}
function configureLogging() {
instanceDir=$1
if [ "$AMQ_DATA_DIR_LOGGING" = "true" ]; then
echo "Configuring logging directory to be ${AMQ_DATA_DIR}/log"
sed -i 's@${artemis.instance}@'"$AMQ_DATA_DIR"'@' ${instanceDir}/etc/logging.properties
fi
}
function configureNetworking() {
if [ "$AMQ_CLUSTERED" = "true" ]; then
echo "Broker will be clustered"
AMQ_ARGS="$AMQ_ARGS --clustered --cluster-user $AMQ_CLUSTER_USER --cluster-password $AMQ_CLUSTER_PASSWORD --host $BROKER_IP"
ACCEPTOR_IP=$BROKER_IP
else
AMQ_ARGS="$AMQ_ARGS --host 0.0.0.0"
ACCEPTOR_IP="0.0.0.0"
fi
}
function configureRedistributionDelay() {
instanceDir=$1
echo "Setting redistribution-delay to zero."
sed -i "s/<address-setting match=\"#\">/&\n <redistribution-delay>0<\/redistribution-delay>/g" ${instanceDir}/etc/broker.xml
}
function configureSSL() {
sslDir=$(find_env "AMQ_KEYSTORE_TRUSTSTORE_DIR" "")
keyStoreFile=$(find_env "AMQ_KEYSTORE" "")
trustStoreFile=$(find_env "AMQ_TRUSTSTORE" "")
if sslEnabled ; then
keyStorePassword=$(find_env "AMQ_KEYSTORE_PASSWORD" "")
trustStorePassword=$(find_env "AMQ_TRUSTSTORE_PASSWORD" "")
keyStorePath="$sslDir/$keyStoreFile"
trustStorePath="$sslDir/$trustStoreFile"
AMQ_ARGS="$AMQ_ARGS --ssl-key $keyStorePath"
AMQ_ARGS="$AMQ_ARGS --ssl-key-password $keyStorePassword"
AMQ_ARGS="$AMQ_ARGS --ssl-trust $trustStorePath"
AMQ_ARGS="$AMQ_ARGS --ssl-trust-password $trustStorePassword"
elif sslPartial ; then
log_warning "Partial ssl configuration, the ssl context WILL NOT be configured."
fi
}
function updateAcceptorsForSSL() {
instanceDir=$1
if sslEnabled ; then
echo "keystore filepath: $keyStorePath"
IFS=',' read -a protocols <<< $(find_env "AMQ_TRANSPORTS" "openwire,amqp,stomp,mqtt,hornetq")
connectionsAllowed=$(find_env "AMQ_MAX_CONNECTIONS" "1000")
sslProvider=$(find_env "AMQ_SSL_PROVIDER" "")
if [ -z "${sslProvider}" ] ; then
SSL_OPS="sslEnabled=true;keyStorePath=${keyStorePath};keyStorePassword=${keyStorePassword}"
else
SSL_OPS="sslEnabled=true;keyStorePath=${keyStorePath};keyStorePassword=${keyStorePassword};sslProvider=${sslProvider}"
fi
if [ "${#protocols[@]}" -ne "0" ]; then
acceptors=""
for protocol in ${protocols[@]}; do
case "${protocol}" in
"openwire")
acceptors="${acceptors} <acceptor name=\"artemis-ssl\">tcp://${ACCEPTOR_IP}:61617?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;connectionsAllowed=${connectionsAllowed};${SSL_OPS}</acceptor>\n"
;;
"mqtt")
acceptors="${acceptors} <acceptor name=\"mqtt-ssl\">tcp://${ACCEPTOR_IP}:8883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true;connectionsAllowed=${connectionsAllowed};${SSL_OPS}</acceptor>\n"
;;
"amqp")
acceptors="${acceptors} <acceptor name=\"amqp-ssl\">tcp://${ACCEPTOR_IP}:5671?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpMinCredits=300;connectionsAllowed=${connectionsAllowed};${SSL_OPS}</acceptor>\n"
;;
"stomp")
acceptors="${acceptors} <acceptor name=\"stomp-ssl\">tcp://${ACCEPTOR_IP}:61612?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;connectionsAllowed=${connectionsAllowed};${SSL_OPS}</acceptor>\n"
;;
esac
done
fi
safeAcceptors=$(echo "${acceptors}" | sed 's/\//\\\//g')
sed -i "/<\/acceptors>/ s/.*/${safeAcceptors}\n&/" ${instanceDir}/etc/broker.xml
fi
}
function updateAcceptorsForPrefixing() {
instanceDir=$1
if [ -n "$AMQ_MULTICAST_PREFIX" ]; then
echo "Setting multicastPrefix to ${AMQ_MULTICAST_PREFIX}"
sed -i "s/:61616?/&multicastPrefix=${AMQ_MULTICAST_PREFIX};/g" ${instanceDir}/etc/broker.xml
sed -i "s/:61617?/&multicastPrefix=${AMQ_MULTICAST_PREFIX};/g" ${instanceDir}/etc/broker.xml
fi
if [ -n "$AMQ_ANYCAST_PREFIX" ]; then
echo "Setting anycastPrefix to ${AMQ_ANYCAST_PREFIX}"
sed -i "s/:61616?/&anycastPrefix=${AMQ_ANYCAST_PREFIX};/g" ${instanceDir}/etc/broker.xml
sed -i "s/:61617?/&anycastPrefix=${AMQ_ANYCAST_PREFIX};/g" ${instanceDir}/etc/broker.xml
fi
}
function appendAcceptorsFromEnv() {
instanceDir=$1
if [ -n "$AMQ_ACCEPTORS" ]; then
echo "Using acceptors from environment and removing existing entries"
sed -i "/acceptor name=/d" ${instanceDir}/etc/broker.xml
acceptorsFromEnv=$(find_env "AMQ_ACCEPTORS" "")
# As AMQ_ACCEPTORS was introduced from the operator, the operator makes a safe string for here
safeAcceptorsFromEnv=$(echo "${acceptorsFromEnv}")
sed -i "/<\/acceptors>/ s/.*/${safeAcceptorsFromEnv}\n&/g" ${instanceDir}/etc/broker.xml
sed -i "s/ACCEPTOR_IP/${ACCEPTOR_IP}/g" ${instanceDir}/etc/broker.xml
fi
}
function appendConnectorsFromEnv() {
instanceDir=$1
if [ -n "$AMQ_CONNECTORS" ]; then
echo "Appending connectors from environment"
connectorsFromEnv=$(find_env "AMQ_CONNECTORS" "")
# As AMQ_CONNECTORS was introduced from the operator, the operator makes a safe string for here
safeConnectorsFromEnv=$(echo "${connectorsFromEnv}")
endConnectorsCount=`grep -c '</connectors>' ${instanceDir}/etc/broker.xml`
if [ ${endConnectorsCount} -ne 0 ]; then
sed -i "/<\/connectors>/ s/.*/\t\t${safeConnectorsFromEnv}\n&/" ${instanceDir}/etc/broker.xml
else
sed -i "/<\/acceptors>/ s/.*/&\n\t<connectors>\n\t\t${safeConnectorsFromEnv}\n\t<\/connectors>\n/" ${instanceDir}/etc/broker.xml
fi
fi
}
function appendJournalType() {
instanceDir=$1
if [ -n "$AMQ_JOURNAL_TYPE" ]; then
echo "Setting journal type to ${AMQ_JOURNAL_TYPE}"
if [[ $(removeWhiteSpace ${AMQ_JOURNAL_TYPE}) != *"nio"* ]]; then
AMQ_ARGS="$AMQ_ARGS --aio"
fi
if [[ $(removeWhiteSpace ${AMQ_JOURNAL_TYPE}) != *"aio"* ]]; then
AMQ_ARGS="$AMQ_ARGS --nio"
fi
fi
}
function modifyDiscovery() {
discoverygroup=""
discoverygroup="${discoverygroup} <discovery-group name=\"my-discovery-group\">"
discoverygroup="${discoverygroup} <jgroups-file>jgroups-ping.xml</jgroups-file>"
discoverygroup="${discoverygroup} <jgroups-channel>activemq_broadcast_channel</jgroups-channel>"
discoverygroup="${discoverygroup} <refresh-timeout>10000</refresh-timeout>"
discoverygroup="${discoverygroup} </discovery-group> "
sed -i -ne "/<discovery-groups>/ {p; i $discoverygroup" -e ":a; n; /<\/discovery-groups>/ {p; b}; ba}; p" ${instanceDir}/etc/broker.xml
#generate jgroups-ping.xml
echo "Generating jgroups-ping.xml, current dir is: $PWD, AMQHOME: $AMQ_HOME"
if [ -z "${PING_SVC_NAME+x}" ]; then
echo "PING_SERVICE is not set"
PING_SVC_NAME=ping
fi
if [ -z "${APPLICATION_NAME+x}" ]; then
echo "APPLICATION_NAME is not set"
sed -i -e "s/\${APPLICATION_NAME}-\${PING_SVC_NAME}/${PING_SVC_NAME}/" $AMQ_HOME/conf/jgroups-ping.xml
else
echo "APPLICATION_NAME is set"
sed -i -e "s/\${APPLICATION_NAME}-\${PING_SVC_NAME}/${APPLICATION_NAME}-${PING_SVC_NAME}/" $AMQ_HOME/conf/jgroups-ping.xml
fi
broadcastgroup=""
broadcastgroup="${broadcastgroup} <broadcast-group name=\"my-broadcast-group\">"
broadcastgroup="${broadcastgroup} <jgroups-file>jgroups-ping.xml</jgroups-file>"
broadcastgroup="${broadcastgroup} <jgroups-channel>activemq_broadcast_channel</jgroups-channel>"
broadcastgroup="${broadcastgroup} <connector-ref>artemis</connector-ref>"
broadcastgroup="${broadcastgroup} </broadcast-group> "
sed -i -ne "/<broadcast-groups>/ {p; i $broadcastgroup" -e ":a; n; /<\/broadcast-groups>/ {p; b}; ba}; p" ${instanceDir}/etc/broker.xml
clusterconnections=""
clusterconnections="${clusterconnections} <cluster-connection name=\"my-cluster\">"
clusterconnections="${clusterconnections} <connector-ref>artemis</connector-ref>"
clusterconnections="${clusterconnections} <retry-interval>1000</retry-interval>"
clusterconnections="${clusterconnections} <retry-interval-multiplier>2</retry-interval-multiplier>"
clusterconnections="${clusterconnections} <max-retry-interval>32000</max-retry-interval>"
clusterconnections="${clusterconnections} <initial-connect-attempts>20</initial-connect-attempts>"
clusterconnections="${clusterconnections} <reconnect-attempts>10</reconnect-attempts>"
clusterconnections="${clusterconnections} <use-duplicate-detection>true</use-duplicate-detection>"
clusterconnections="${clusterconnections} <message-load-balancing>ON_DEMAND</message-load-balancing>"
clusterconnections="${clusterconnections} <max-hops>1</max-hops>"
clusterconnections="${clusterconnections} <discovery-group-ref discovery-group-name=\"my-discovery-group\"/>"
clusterconnections="${clusterconnections} </cluster-connection> "
sed -i -ne "/<cluster-connections>/ {p; i $clusterconnections" -e ":a; n; /<\/cluster-connections>/ {p; b}; ba}; p" ${instanceDir}/etc/broker.xml
}
function configureJAVA_ARGSMemory() {
instanceDir=$1
echo "Removing hardcoded -Xms -Xmx from artemis.profile in favour of JAVA_OPTS in log above"
sed -i "s/\-Xms[0-9]*[mMgG] \-Xmx[0-9]*[mMgG] \-Dhawtio/\ -Dhawtio/g" ${instanceDir}/etc/artemis.profile
}
function configureJolokiaJVMAgent() {
instanceDir=$1
if [ "$AMQ_ENABLE_JOLOKIA_AGENT" = "true" ]; then
echo "Configure jolokia jvm agent"
echo "JOLOKIA_OPTS: $JOLOKIA_OPTS"
echo '' >> ${instanceDir}/etc/artemis.profile
echo "if [ \"\$1\" = \"run\" ]; then JAVA_ARGS=\"\$JAVA_ARGS $JOLOKIA_OPTS\"; fi" >> ${instanceDir}/etc/artemis.profile
echo '' >> ${instanceDir}/etc/artemis.profile
fi
}
function injectMetricsPlugin() {
instanceDir=$1
echo "Adding artemis metrics plugin"
sed -i "s/^\([[:blank:]]*\)<\\/core>/\1\1<metrics-plugin class-name=\"org.apache.activemq.artemis.core.server.metrics.plugins.ArtemisPrometheusMetricsPlugin\"\\/>\\n\1<\\/core>/" $instanceDir/etc/broker.xml
if ! grep -q 'metrics' $instanceDir/etc/bootstrap.xml; then
sed -i 's~</binding>~<app url="metrics" war="metrics.war"/></binding>~' $instanceDir/etc/bootstrap.xml
fi
}
function checkBeforeRun() {
instanceDir=$1
if [ "$AMQ_ENABLE_METRICS_PLUGIN" = "true" ]; then
pluginStr="com.redhat.amq.broker.core.server.metrics.plugins.ArtemisPrometheusMetricsPlugin"
grep -q "$pluginStr" ${instanceDir}/etc/broker.xml
result=$?
if [[ $result == 0 ]]; then
echo "The Prometheus plugin already configured."
else
echo "Need to inject Prometheus plugin"
injectMetricsPlugin ${instanceDir}
fi
fi
if [[ "${JAVA_ARGS_APPEND}" == *"-Dlog4j2.configurationFile"* ]]; then
echo "There is a custom logger configuration defined in JAVA_ARGS_APPEND: ${JAVA_ARGS_APPEND}"
else
echo "Using default logging configuration(console only)"
defaultLoggingConfigFile=${instanceDir}/etc/log4j2.properties
sed -i "s/rootLogger = INFO, console, log_file/rootLogger = INFO, console/g" $defaultLoggingConfigFile
fi
}
function configure() {
instanceDir=$1
export CONTAINER_ID=$HOSTNAME
if [ ! -d ${instanceDir} -o "$AMQ_RESET_CONFIG" = "true" -o ! -f ${instanceDir}/bin/artemis ]; then
AMQ_ARGS="--silent --role $AMQ_ROLE --name $AMQ_NAME --http-host $BROKER_IP --java-options=-Djava.net.preferIPv4Stack=true "
configureUserAuthentication
if [ -n "$AMQ_DATA_DIR" ]; then
AMQ_ARGS="$AMQ_ARGS --data ${AMQ_DATA_DIR}"
fi
if [ -n "$AMQ_QUEUES" ]; then
AMQ_ARGS="$AMQ_ARGS --queues $(removeWhiteSpace $AMQ_QUEUES)"
fi
if [ -n "$AMQ_ADDRESSES" ]; then
AMQ_ARGS="$AMQ_ARGS --addresses $(removeWhiteSpace $AMQ_ADDRESSES)"
fi
if [ -n "$AMQ_ACCEPTORS" ]; then
AMQ_ARGS="$AMQ_ARGS --no-amqp-acceptor --no-hornetq-acceptor --no-mqtt-acceptor --no-stomp-acceptor"
else
if [ -n "$AMQ_TRANSPORTS" ]; then
if [[ $(removeWhiteSpace ${AMQ_TRANSPORTS}) != *"hornetq"* ]]; then
AMQ_ARGS="$AMQ_ARGS --no-hornetq-acceptor"
fi
if [[ $(removeWhiteSpace ${AMQ_TRANSPORTS}) != *"amqp"* ]]; then
AMQ_ARGS="$AMQ_ARGS --no-amqp-acceptor"
fi
if [[ $(removeWhiteSpace ${AMQ_TRANSPORTS}) != *"mqtt"* ]]; then
AMQ_ARGS="$AMQ_ARGS --no-mqtt-acceptor"
fi
if [[ $(removeWhiteSpace ${AMQ_TRANSPORTS}) != *"stomp"* ]]; then
AMQ_ARGS="$AMQ_ARGS --no-stomp-acceptor"
fi
fi
fi
if [ -n "$GLOBAL_MAX_SIZE" ]; then
AMQ_ARGS="$AMQ_ARGS --global-max-size $(removeWhiteSpace $GLOBAL_MAX_SIZE)"
fi
if [ "$AMQ_RESET_CONFIG" = "true" ]; then
AMQ_ARGS="$AMQ_ARGS --force"
fi
if [ "$AMQ_EXTRA_ARGS" ]; then
AMQ_ARGS="$AMQ_ARGS $AMQ_EXTRA_ARGS"
fi
configureNetworking
configureSSL
appendJournalType ${instanceDir}
# mask sensitive values
PRINT_ARGS="${AMQ_ARGS/--password $AMQ_PASSWORD/--password XXXXX}"
PRINT_ARGS="${PRINT_ARGS/--user $AMQ_USER/--user XXXXX}"
PRINT_ARGS="${PRINT_ARGS/--cluster-user $AMQ_CLUSTER_USER/--cluster-user XXXXX}"
PRINT_ARGS="${PRINT_ARGS/--cluster-password $AMQ_CLUSTER_PASSWORD/--cluster-password XXXXX}"
PRINT_ARGS="${PRINT_ARGS/--ssl-key-password $AMQ_KEYSTORE_PASSWORD/--ssl-key-password XXXXX}"
PRINT_ARGS="${PRINT_ARGS/--ssl-trust-password $AMQ_TRUSTSTORE_PASSWORD/--ssl-trust-password XXXXX}"
if [ "$AMQ_CONSOLE_ARGS" ]; then
AMQ_ARGS="$AMQ_ARGS $AMQ_CONSOLE_ARGS"
keypat='(.*)(--ssl-key-password).([[:alnum:]]*)(.*)'
[[ "$AMQ_CONSOLE_ARGS" =~ $keypat ]]
CONSOLE_ARGS_NO_KEYPASS="${BASH_REMATCH[1]} ${BASH_REMATCH[2]} XXXXX ${BASH_REMATCH[4]}"
trustpat='(.*)(--ssl-trust-password).([[:alnum:]]*)(.*)'
[[ "$CONSOLE_ARGS_NO_KEYPASS" =~ $trustpat ]]
CONSOLE_ARGS_NO_TRUSTPASS="${BASH_REMATCH[1]} ${BASH_REMATCH[2]} XXXXX ${BASH_REMATCH[4]}"
PRINT_ARGS="${PRINT_ARGS} ${CONSOLE_ARGS_NO_TRUSTPASS}"
fi
echo "Creating Broker with args $PRINT_ARGS"
$AMQ_HOME/bin/artemis create ${instanceDir} $AMQ_ARGS --java-options "$JAVA_OPTS"
if [ "$AMQ_CLUSTERED" = "true" ]; then
modifyDiscovery
configureRedistributionDelay ${instanceDir}
fi
$AMQ_HOME/bin/configure_jolokia_access.sh ${instanceDir}/etc/jolokia-access.xml
if [ "$AMQ_KEYSTORE_TRUSTSTORE_DIR" ]; then
echo "Updating acceptors for SSL"
updateAcceptorsForSSL ${instanceDir}
fi
updateAcceptorsForPrefixing ${instanceDir}
appendAcceptorsFromEnv ${instanceDir}
appendConnectorsFromEnv ${instanceDir}
configureLogging ${instanceDir}
configureJAVA_ARGSMemory ${instanceDir}
configureJolokiaJVMAgent ${instanceDir}
if [ "$AMQ_ENABLE_METRICS_PLUGIN" = "true" ]; then
echo "Enable artemis metrics plugin"
injectMetricsPlugin ${instanceDir}
fi
$AMQ_HOME/bin/configure_s2i_files.sh ${instanceDir}
$AMQ_HOME/bin/configure_custom_config.sh ${instanceDir}
fi
}
function removeWhiteSpace() {
echo $*|tr -s ''| tr -d [[:space:]]
}
function runServer() {
echo "Configuring Broker"
instanceDir="${HOME}/${AMQ_NAME}"
configure $instanceDir
if [ "$1" != "nostart" ]; then
echo "Running Broker in ${instanceDir}"
checkBeforeRun ${instanceDir}
exec ${instanceDir}/bin/artemis run
fi
}
runServer $1

View File

@ -0,0 +1,132 @@
{{- define "drainer.pod" -}}
alpha.image.policy.openshift.io/resolve-names: "*"
statefulsets.kubernetes.io/drainer-pod-template: |
{
"metadata": {
"labels": {
"app": "{{ .Values.application.name }}-amq-drainer"
}
},
"spec": {
"serviceAccount": "{{ tpl .Values.templates.service_account .}}",
"serviceAccountName": "{{ tpl .Values.templates.service_account .}}",
"terminationGracePeriodSeconds": 5,
"containers": [
{
"env": [
{
"name": "APPLICATION_NAME",
"value": "{{ .Values.application.name }}"
},
{
"name": "HEADLESS_ENDPOINT",
"value": "{{ tpl .Values.templates.service . }}"
},
{
"name": "PING_SVC_NAME",
"value": "{{ tpl .Values.ping_service.name . }}"
},
{
"name": "AMQ_EXTRA_ARGS",
"value": "--no-autotune"
},
{
"name": "AMQ_USER",
"valueFrom": {
"secretKeyRef": {
"name": "{{ tpl .Values.templates.app_secret . }}",
"key": "AMQ_USER"
}
}
},
{
"name": "AMQ_PASSWORD",
"valueFrom": {
"secretKeyRef": {
"name": "{{ tpl .Values.templates.app_secret . }}",
"key": "AMQ_PASSWORD"
}
}
},
{
"name": "AMQ_ROLE",
"value": "{{ .Values.admin.role }}"
},
{
"name": "AMQ_NAME",
"value": "{{ .Values.parameters.amq_broker_name }}"
},
{
"name": "AMQ_TRANSPORTS",
"value": "{{ .Values.parameters.amq_protocols }}"
},
{
"name": "AMQ_GLOBAL_MAX_SIZE",
"value": "{{ .Values.parameters.amq_global_max_size }}"
},
{
"name": "AMQ_ALLOW_ANONYMOUS",
"value": "{{ .Values.parameters.allow_anonymous }}"
},
{
"name": "AMQ_DATA_DIR",
"value": "{{ .Values.parameters.amq_data_dir }}"
},
{
"name": "AMQ_DATA_DIR_LOGGING",
"value": "{{ .Values.parameters.amq_data_dir_logging }}"
},
{
"name": "AMQ_CLUSTERED",
"value": "{{ .Values.parameters.amq_clustered }}"
},
{
"name": "AMQ_REPLICAS",
"value": "{{ .Values.application.replicas }}"
},
{
"name": "AMQ_CLUSTER_USER",
"valueFrom": {
"secretKeyRef": {
"name": "{{ tpl .Values.templates.app_secret .}}",
"key": "AMQ_CLUSTER_USER"
}
}
},
{
"name": "AMQ_CLUSTER_PASSWORD",
"valueFrom": {
"secretKeyRef": {
"name": "{{ tpl .Values.templates.app_secret .}}",
"key": "AMQ_CLUSTER_PASSWORD"
}
}
},
{
"name": "POD_NAMESPACE",
"valueFrom": {
"fieldRef": {
"fieldPath": "metadata.namespace"
}
}
},
{
"name": "OPENSHIFT_DNS_PING_SERVICE_PORT",
"value": "{{ .Values.ping_service.jgroups.bind_port }}"
}
],
"image": "{{ tpl .Values.templates.broker_image .}}",
"name": "{{ .Values.application.name }}-amq-drainer-pod",
"command": ["/bin/sh", "-c", "echo \"Starting the drainer\" ; /opt/amq/bin/drain.sh; echo \"Drain completed! Exit code $?\""],
"volumeMounts": [
{
"name": "{{ tpl .Values.templates.pvc_name . }}",
"mountPath": "{{ .Values.parameters.amq_data_dir }}"
}
]
}
]
}
}
{{- end -}}

View File

@ -0,0 +1,183 @@
{{- define "amq.pod" -}}
{{- if eq .Values.platform "kubernetes" -}}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 2 -}}
{{- end }}
imagePullSecrets:
- name: {{ .Values.application.pullSecretName }}
{{- end }}
containers:
- env:
{{- if .Values.clustered }}
- name: APPLICATION_NAME
value: "{{ .Values.application.name }}"
- name: PING_SVC_NAME
value: "{{ tpl .Values.ping_service.name . }}"
- name: AMQ_CLUSTERED
value: "{{ .Values.clustered }}"
- name: AMQ_REPLICAS
value: "{{ .Values.application.replicas }}"
- name: AMQ_CLUSTER_USER
valueFrom:
secretKeyRef:
name: {{ tpl .Values.templates.app_secret . }}
key: AMQ_CLUSTER_USER
- name: AMQ_CLUSTER_PASSWORD
valueFrom:
secretKeyRef:
name: {{ tpl .Values.templates.app_secret . }}
key: AMQ_CLUSTER_PASSWORD
- name: OPENSHIFT_DNS_PING_SERVICE_PORT
value: "{{ .Values.ping_service.jgroups.bind_port }}"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- end }}
- name: AMQ_USER
valueFrom:
secretKeyRef:
name: {{ tpl .Values.templates.app_secret . }}
key: AMQ_USER
- name: AMQ_PASSWORD
valueFrom:
secretKeyRef:
name: {{ tpl .Values.templates.app_secret . }}
key: AMQ_PASSWORD
- name: AMQ_ROLE
value: "{{ .Values.admin.role }}"
- name: AMQ_NAME
value: "{{ .Values.parameters.amq_broker_name }}"
- name: AMQ_TRANSPORTS
value: "{{ .Values.parameters.amq_protocols }}"
{{- if .Values.parameters.tls_enabled }}
- name: AB_JOLOKIA_HTTPS
value: "{{ .Values.parameters.jolokia_passthrough }}"
- name: AMQ_KEYSTORE_TRUSTSTORE_DIR
value: {{ .Values.tls.secret_mount_path }}
- name: AMQ_TRUSTSTORE
value: {{ .Values.tls.truststore }}
- name: AMQ_TRUSTSTORE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ tpl .Values.templates.app_certificates . }}
key: AMQ_TRUSTSTORE_PASSWORD
- name: AMQ_KEYSTORE
value: {{ .Values.tls.keystore }}
- name: AMQ_KEYSTORE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ tpl .Values.templates.app_certificates . }}
key: AMQ_KEYSTORE_PASSWORD
- name: AMQ_SSL_PROVIDER
value: {{ tpl .Values.parameters.ssl_provider . }}
{{- end }}
- name: AMQ_GLOBAL_MAX_SIZE
value: "{{ .Values.parameters.amq_global_max_size }}"
- name: AMQ_REQUIRE_LOGIN
value: "{{ .Values.parameters.amq_require_login }}"
{{- if .Values.application.persistent }}
- name: AMQ_DATA_DIR
value: "{{ .Values.parameters.amq_data_dir }}"
{{- end }}
- name: AMQ_EXTRA_ARGS
value: {{ if .Values.parameters.amq_extra_args }} "{{ .Values.parameters.amq_extra_args }}" {{ else }} "" {{ end }}
- name: AMQ_ANYCAST_PREFIX
value: {{ if .Values.parameters.amq_anycast_prefix }} "{{ .Values.parameters.amq_anycast_prefix }}" {{ else }} "jms.queue." {{ end }}
- name: AMQ_MULTICAST_PREFIX
value: {{ if .Values.parameters.amq_multicast_prefix }} "{{ .Values.parameters.amq_multicast_prefix }}" {{ else }} "jms.topic." {{ end }}
- name: AMQ_ENABLE_METRICS_PLUGIN
value: {{ .Values.metrics.enabled | quote }}
- name: AMQ_JOURNAL_TYPE
value: "{{ .Values.parameters.amq_journal_type }}"
image: {{ tpl .Values.templates.broker_image . }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 4 -}}
{{- end }}
imagePullPolicy: {{ .Values.application.pullPolicy }}
readinessProbe:
exec:
command:
- "/bin/bash"
- "-c"
- "/opt/amq/bin/readinessProbe.sh"
name: {{ tpl .Values.templates.deployment . }}
ports:
{{- range .Values.service.acceptors }}
- containerPort: {{ .port }}
name: {{ .name }}
protocol: {{ .protocol }}
{{- end }}
{{- range .Values.service.console }}
- containerPort: {{ .port }}
name: {{ .name }}
protocol: {{ .protocol }}
{{- end }}
volumeMounts:
{{- if .Values.application.persistent }}
- name: {{ tpl .Values.templates.pvc_name . }}
mountPath: {{ .Values.parameters.amq_data_dir }}
{{- end }}
- name: broker-config-script-custom
mountPath: /opt/amq/bin/configure_custom_config.sh
subPath: configure_custom_config.sh
readOnly: true
- name: broker-config-script-custom
mountPath: /opt/amq/bin/launch.sh
subPath: launch.sh
readOnly: true
{{- if .Values.clustered }}
- name: broker-config-script-custom
mountPath: /opt/amq/bin/drain.sh
subPath: drain.sh
readOnly: true
{{- end }}
- name: broker-config-volume
mountPath: "/opt/amq/conf"
readOnly: true
{{- if .Values.parameters.tls_enabled }}
- mountPath: {{ .Values.tls.secret_mount_path }}
name: broker-secret-volume
readOnly: true
{{- end }}
terminationGracePeriodSeconds: 60
volumes:
{{- if .Values.parameters.tls_enabled }}
- name: broker-secret-volume
secret:
secretName: {{ tpl .Values.templates.app_certificates . }}
{{- end }}
- name: broker-config-script-custom
configMap:
name: {{ tpl .Values.templates.override_cm . }}
items:
- key: configure_custom_config.sh
path: configure_custom_config.sh
- key: launch.sh
path: launch.sh
{{- if .Values.clustered }}
- key: drain.sh
path: drain.sh
{{- end }}
defaultMode: 0550
- name: broker-config-volume
projected:
sources:
- configMap:
name: {{ tpl .Values.templates.config_cm . }}
{{- range .Values.security.secrets }}
- secret:
name: {{ . }}
{{- end }}
{{- if and (eq .Values.kind "Deployment") (.Values.application.persistent) }}
- name: {{ tpl .Values.templates.pvc_name . }}
persistentVolumeClaim:
{{- if eq .Values.ha_ap.mode "primary" }}
claimName: {{ tpl .Values.templates.pvc_name . }}
{{- else }}
claimName: {{ .Values.ha_ap.connector.static.ref }}-persistent-volume
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,14 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ tpl .Values.templates.override_cm . }}
data:
{{- (.Files.Glob "scripts-override/**.sh").AsConfig | nindent 2 }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ tpl .Values.templates.config_cm . }}
data:
{{ tpl (.Files.Glob "conf/**").AsConfig . | nindent 2 }}

View File

@ -0,0 +1,35 @@
{{- if eq .Values.kind "Deployment" }}
{{- if and .Values.clustered (not .Values.cluster.ha_ap_mode) }}
{{- fail ".Values.kind is set to Deployment but this is unsupported in a clustered environment. Use a StatefulSet" }}
{{- else }}
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
application: {{ .Values.application.name }}
name: {{ tpl .Values.templates.deployment . }}
{{- if .Values.clustered }}
annotations:
{{- include "drainer.pod" . | nindent 6 }}
{{- end }}
spec:
replicas: 1
revisionHistoryLimit: 2
selector:
matchLabels:
application: {{ .Values.application.name }}
strategy:
type: Recreate
template:
metadata:
# trigger deployments on config map changes
annotations:
configmap/checksum: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
labels:
application: {{ .Values.application.name }}
deployment: {{ tpl .Values.templates.deployment . }}
name: {{ tpl .Values.templates.deployment . }}
spec:
{{- include "amq.pod" . | nindent 6 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,64 @@
{{- if eq .Values.platform "kubernetes" }}
{{- $route_name := tpl .Values.templates.route . }}
{{- $svc_name := tpl .Values.templates.service . }}
{{- if .Values.parameters.tls_enabled }}
{{- if not .Values.clustered }}
{{- if .Values.ingress.passthrough.enabled }}
{{- range .Values.service.acceptors }}
{{- $nm := toString .name }}
{{- if eq $nm $.Values.ingress.passthrough.service }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "{{ $route_name }}-passthrough"
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: {{ $.Values.ingress.className }}
rules:
- host: "{{ $route_name }}-passthrough.{{ $.Values.ingress.domain }}"
http:
paths:
- path: "{{ $.Values.ingress.passthrough.path }}"
pathType: Prefix
backend:
service:
name: {{ $svc_name }}
port:
number: {{ .port }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.ingress.console.enabled }}
{{- range .Values.service.console }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "{{ $route_name }}-console"
spec:
{{- if $.Values.ingress.console.tls }}
tls:
- hosts:
- "{{ $route_name }}-console.{{ $.Values.ingress.domain }}"
secretName: {{ $.Values.ingress.console.tlsSecretName }}
{{- end }}
rules:
- host: "{{ $route_name }}-console.{{ $.Values.ingress.domain }}"
http:
paths:
- path: "{{ $.Values.ingress.console.path }}"
pathType: Prefix
backend:
service:
name: {{ $svc_name }}
port:
number: {{ .port }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,26 @@
{{- if .Values.nodeport.enabled }}
{{- $np_svc := .Values.nodeport }}
{{- range .Values.service.acceptors }}
{{- if eq .name $np_svc.service }}
---
apiVersion: v1
kind: Service
metadata:
labels:
application: {{ $.Values.application.name }}
name: {{ $.Values.application.name }}-nodeport-svc
spec:
ports:
- name: {{ quote .name }}
port: {{ .port }}
protocol: {{ quote .protocol }}
targetPort: {{ .port }}
nodePort: {{ $np_svc.port }}
publishNotReadyAddresses: true
selector:
application: {{ $.Values.application.name }}
sessionAffinity: None
type: NodePort
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,13 @@
{{- if and (eq .Values.kind "Deployment") (eq .Values.ha_ap.mode "primary") (.Values.application.persistent) }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ tpl .Values.templates.pvc_name . }}
spec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: {{ .Values.application.volume_capacity }}
storageClassName: "{{ .Values.application.storageclass }}"
{{- end }}

View File

@ -0,0 +1,56 @@
{{- if .Values.clustered }}
{{- $service_account := tpl .Values.templates.service_account . }}
{{- $role := tpl .Values.templates.k8s_role . }}
{{- $rolebinding := tpl .Values.templates.k8s_rolebinding . }}
{{- with $app := .Values.application.name }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $service_account }}
labels:
app: {{ $app }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $role }}
labels:
app: {{ $app }}
rules:
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $rolebinding }}
labels:
app: {{ $app }}
subjects:
- kind: ServiceAccount
name: {{ $service_account }}
roleRef:
kind: Role
name: {{ $role }}
apiGroup: rbac.authorization.k8s.io
{{- end }}
{{- end }}

View File

@ -0,0 +1,65 @@
{{- if eq .Values.platform "openshift" }}
{{- $svc_name := tpl .Values.templates.service . }}
{{- $app_name := tpl .Values.application.name . }}
{{- $route_name := tpl .Values.templates.route . }}
{{- $jolokia_ssl := and (.Values.parameters.tls_enabled) (.Values.parameters.jolokia_passthrough) }}
{{- range .Values.service.console }}
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
application: {{ $app_name }}
name: {{ $route_name }}-console
spec:
{{- if $.Values.parameters.append_ns }}
host: {{ $route_name }}.{{ $.Release.Namespace }}.{{ $.Values.parameters.openshift_appdomain }}
{{- else }}
host: {{ $route_name }}.{{ $.Values.parameters.openshift_appdomain }}
{{- end }}
to:
kind: Service
name: {{ $svc_name }}
port:
targetPort: {{ .port }}
tls:
{{- if $jolokia_ssl }}
termination: passthrough
{{- else }}
termination: edge
{{- end }}
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
{{- end }}
{{- if not .Values.clustered }}
{{- if .Values.passthrough_route.enabled }}
{{- range .Values.service.acceptors }}
{{- $nm := toString .name }}
{{- if eq $nm $.Values.passthrough_route.service }}
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
labels:
application: {{ $app_name }}
name: {{ $route_name }}-passthrough
spec:
{{- if $.Values.parameters.append_ns }}
host: {{ $.Values.passthrough_route.hostname }}.{{ $.Release.Namespace }}.{{ $.Values.parameters.openshift_appdomain }}
{{- else }}
host: {{ $.Values.passthrough_route.hostname }}.{{ $.Values.parameters.openshift_appdomain }}
{{- end }}
to:
kind: Service
name: {{ $svc_name }}
port:
targetPort: {{ .port }}
tls:
termination: passthrough
insecureEdgeTerminationPolicy: Redirect
wildcardPolicy: None
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,42 @@
{{- if .Values.security.createSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ tpl .Values.templates.app_secret .}}
type: Opaque
data:
AMQ_USER: {{ b64enc .Values.admin.user }}
AMQ_PASSWORD: {{ b64enc .Values.admin.password }}
{{- if .Values.clustered }}
AMQ_CLUSTER_USER: {{ b64enc .Values.admin.cluster_user }}
AMQ_CLUSTER_PASSWORD: {{ b64enc .Values.admin.cluster_password }}
{{- end }}
{{- end }}
{{- if .Values.parameters.tls_enabled }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ tpl .Values.templates.app_certificates . }}
type: Opaque
data:
AMQ_KEYSTORE_PASSWORD: {{ b64enc .Values.tls.keystore_password }}
AMQ_TRUSTSTORE_PASSWORD: {{ b64enc .Values.tls.truststore_password }}
{{- range tuple .Values.tls.keystore .Values.tls.truststore }}
{{ . }}: |-
{{ ( printf "%s%s" "tls/" . | $.Files.Get ) | b64enc }}
{{- end }}
{{- end }}
{{- if and (eq .Values.platform "kubernetes") (.Values.ingress.console.tls) }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.ingress.console.tlsSecretName }}
data:
tls.crt: |-
{{ ( printf "%s%s" "tls/" .Values.ingress.console.cert | $.Files.Get) | b64enc }}
tls.key: |-
{{ ( printf "%s%s" "tls/" .Values.ingress.console.key | $.Files.Get) | b64enc }}
type: kubernetes.io/tls
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if .Values.metrics.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ .Values.application.name }}-monitor
labels:
prometheus: prometheus-app
spec:
selector:
matchLabels:
application: {{ .Values.application.name }}
endpoints:
- targetPort: {{ .Values.metrics.servicemonitor.port }}
path: /metrics/
interval: {{ .Values.metrics.servicemonitor.interval }}
{{- end }}

View File

@ -0,0 +1,57 @@
{{- $application_name := .Values.application.name }}
{{- $svc_name := tpl .Values.templates.service . }}
{{- $dc_name := tpl .Values.templates.deployment . }}
---
apiVersion: v1
kind: Service
metadata:
annotations:
{{- if eq .Values.kind "StatefulSet" }}
description: The broker's headless, non load balanced service
{{- else }}
description: AMQ Broker Service
{{- end }}
labels:
application: {{ $application_name }}
app: {{ $application_name }}
name: {{ $svc_name }}
spec:
{{- if eq .Values.kind "StatefulSet" }}
clusterIP: None
{{- end }}
type: ClusterIP
publishNotReadyAddresses: true
ports:
{{- range .Values.service.acceptors }}
- port: {{ .port }}
name: {{ .name }}
protocol: {{ .protocol }}
targetPort: {{ .port }}
{{- end }}
{{- range .Values.service.console }}
- port: {{ .port }}
name: {{ .name }}
protocol: {{ .protocol }}
targetPort: {{ .port }}
{{- end }}
selector:
deployment: {{ $dc_name }}
{{- if .Values.clustered }}
---
apiVersion: v1
kind: Service
metadata:
annotations:
description: The JGroups ping port for clustering.
service.alpha.kubernetes.io/tolerate-unready-endpoints: 'true'
labels:
application: {{ $application_name }}
name: {{ tpl .Values.ping_service.name . }}
spec:
clusterIP: None
ports:
- targetPort: {{ .Values.ping_service.port }}
port: {{ .Values.ping_service.port }}
selector:
deployment: {{ $dc_name }}
{{- end }}

View File

@ -0,0 +1,50 @@
{{- if eq .Values.kind "StatefulSet" }}
{{- $svc_name := tpl .Values.templates.service . }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
application: {{ .Values.application.name }}
name: {{ tpl .Values.templates.deployment . }}
{{- if .Values.clustered }}
annotations:
{{- include "drainer.pod" . | nindent 6 }}
{{- end }}
spec:
revisionHistoryLimit: 2
selector:
matchLabels:
application: {{ .Values.application.name }}
{{- if .Values.clustered }}
podManagementPolicy: OrderedReady
replicas: {{ .Values.application.replicas }}
{{- else }}
replicas: 1
{{- end }}
serviceName: {{ $svc_name }}
template:
metadata:
# trigger deployments on config map changes
annotations:
configmap/checksum: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
labels:
application: {{ .Values.application.name }}
deployment: {{ tpl .Values.templates.deployment . }}
app: {{ .Values.application.name }}
name: {{ tpl .Values.templates.deployment . }}
spec:
{{- include "amq.pod" . | nindent 6 }}
{{- if .Values.application.persistent }}
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ tpl .Values.templates.pvc_name . }}
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: {{ .Values.application.volume_capacity }}
storageClassName: "{{ .Values.application.storageclass }}"
{{- end }}
{{- end }}

View File

@ -0,0 +1 @@
PLACEHOLDER

View File

@ -0,0 +1 @@
PLACEHOLDER

View File

@ -0,0 +1 @@
PLACEHOLDER

View File

@ -0,0 +1 @@
PLACEHOLDER

View File

@ -0,0 +1,237 @@
# Deploy broker as Deployment or StatefulSet
# if clustered is True, then only StatefulSet is supported
kind: Deployment
clustered: false # only with StatefulSet
# Platform type.
platform: kubernetes
application:
name: broker1 # set broker1 is this for primary deployment else set to broker2
amq_broker_version: 55ae4e28b100534d63c34ab86f69230d274c999d46d1493f26fe3e75ba7a0cec # 7.12.3
amq_broker_image: registry.redhat.io/amq7/amq-broker-rhel8
pullPolicy: IfNotPresent
persistent: true
journal_type: ASYNCIO # more information see broker.xml
volume_capacity: "1G"
replicas: 1
storageclass: default
# this is used if platform type is set as "kubernetes"
pullSecretName: redhat-pullsecret
service:
console:
- name: jolokia
description: "The Jolokia Management Console Service"
protocol: TCP
port: 8161
acceptors:
- name: multiplex
description: "Multiplexed protocol endpoint (CORE+All the others)"
protocol: TCP
# when tls is enabled, all acceptors are tls-protected.
# this behaviour can be overridden by marking the acceptor as non-tls
#use_tls: false
port: 61616
# if needed, override the protocols here.
# default values are specified in the "parameters" section below
#amq_protocols: "CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE"
# also, additional properties for a single acceptor can be set here
#acceptor_params:
# - key: supportAdvisory
# value: false
# - key: suppressInternalManagementObjects
# value: false
ping_service:
name: "{{ .Values.application.name }}-ping-svc"
port: 8888
jgroups:
bind_port: 7800
nodeport:
port: 30003
service: multiplex
enabled: true
passthrough_route:
hostname: multiplex-amq
enabled: false
service: multiplex
# only relevant for deployment on kubernetes
ingress:
# the ingress rule domain
domain: kubernetes.local
# passthrough ingress rule: only relevant for TLS enabled brokers
passthrough:
path: "/"
service: multiplex
enabled: true
# jolokia console ingress rule. optional tls certificates can be configured here
console:
path: "/"
service: jolokia
enabled: true
tls: false
tlsSecretName: "amq-console-ingress-certs"
cert: ingress_console.crt
key: ingress_console.key
tls:
secret_mount_path: "/etc/amq-secret-volume"
keystore: keystore.ks
truststore: keystore.ts
keystore_password: kspwd
truststore_password: tspwd
parameters:
tls_enabled: false
jolokia_passthrough: false
append_ns: false
openshift_appdomain: apps.cluster.local
amq_protocols: "openwire,amq,stomp,mqtt,hornetq,core"
amq_broker_name: "broker"
amq_global_max_size: "200 mb"
amq_require_login: False
amq_extra_args: ""
amq_anycast_prefix: "jmx.queue."
amq_multicast_prefix: "jmx.topic."
amq_journal_type: "nio"
ssl_provider: "jdk" # alternative is openssl
amq_data_dir: "/opt/amq/data"
amq_force_addresses_cleanup: True # if true remove all queues that are not declared here upon chart update
cluster:
ha_ap_mode: false # Primary-Backup Mode / only with 2 Deployments
jgroupsCfg: "jgroups-ping.xml"
refreshTimeout: 10000
connector:
ref: multiplex
port: 61616
ha_ap:
mode: primary
refreshTimeout: 10000
connector:
ref: artemis
port: 61616
static:
ref: broker2 # set broker2 is this for primary deployment else set to broker1
port: 61616
templates:
service: "{{ .Values.application.name }}-svc"
service_account: "{{ .Values.application.name }}-sa"
k8s_role: "{{ .Values.application.name }}-role"
k8s_rolebinding: "{{ .Values.application.name }}-rolebinding"
deployment: "{{ .Values.application.name }}-dc"
route: "{{ .Values.application.name }}-route"
broker_image: "{{ .Values.application.amq_broker_image }}:{{ .Values.application.amq_broker_version }}"
override_cm: "{{ .Values.application.name }}-override-cm"
config_cm: "{{ .Values.application.name }}-config-cm"
app_secret: "{{ .Values.application.name }}-secret"
app_certificates: "{{ .Values.application.name }}-certificates"
pvc_name: "{{ .Values.application.name }}-persistent-volume"
admin:
user: admin
password: password
cluster_user: cadmin
cluster_password: cpassword
role: "admin"
security:
enabled: true
# Names of additional secrets to mount into configuration folder.
secrets: []
createSecret: true
jaasUsers:
# Secret key entry name for Username password properties file. Override when files is provided by existing Secret.
key: artemis-users.properties
# Add more users to this configuration
# Any users that gets assigned the .admin.role
# role name becomes an additional administrator
users: []
# - name: demouser
# password: "demo"
# roles:
# - user
# - name: anotheruser
# password: "demo1"
# roles:
# - user
#
queues:
defaults:
maxDeliveryAttempts: 3
redeliveryDelayMultiplier: 1
redeliveryDelay: 5000
maxRedeliveryDelay: 50000
maxSizeBytes: "100 mb"
addressFullPolicy: "PAGE"
messageCounterHistoryDayLimit: 10
addresses: []
# - name: QUEUE_1
# type: anycast # for queues, choose 'multicast' for topics
# dlq_address: QUEUE_1_DLQ
# expiry_address:
# maxDeliveryAttempts:
# redeliveryDelayMultiplier:
# redeliveryDelay:
# maxRedeliveryDelay:
# maxSizeBytes:
# messageCounterHistoryDayLimit:
# addressFullPolicy:
# permissions:
# - grant: consume
# roles:
# - admin
# - user
# - grant: browse
# roles:
# - admin
# - user
# - grant: send
# roles:
# - admin
# - user
# - grant: manage
# roles:
# - admin
# #- grant: createNonDurableQueue # uncomment this when declaring topics (with type: multicast)
# # roles:
# # - admin
# # - user
# Add Metrics and Prometheus ServiceMonitor for collecting metrics
metrics:
enabled: false
jvm_memory: true
jvm_gc: false
jvm_threads: false
servicemonitor:
port: 8161
interval: 20s
# k8s resources
resources: {}
# limits:
# cpu: 1000m
# memory: 2000Mi
# requests:
# cpu: 200m
# memory: 1000Mi
#
# k8s affinity
affinity: {}
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: disktype
# operator: In
# values:
# - ssd