Merge "Do not lockout service users on auth failures"
diff --git a/defaults/openstack/init.yml b/defaults/openstack/init.yml
index aefcf5e..66b357d 100644
--- a/defaults/openstack/init.yml
+++ b/defaults/openstack/init.yml
@@ -16,12 +16,15 @@
     openstack_service_user_enabled: True
     openstack_telemetry_redis_db: '0'
     openstack_telemetry_redis_sentinel_mastername: 'master_1'
+    openstack_upgrade_enabled: False
     # SSL
     ceilometer_agent_ssl_enabled: False
     openstack_mysql_x509_enabled: False
     # for non-ssl use 5672 / for ssl 5671
     openstack_rabbitmq_port: 5672
     openstack_rabbitmq_x509_enabled: False
+    # RabbitMQ
+    rabbitmq_upgrade_enabled: ${_param:openstack_upgrade_enabled}
     # Openstack memcache
     openstack_memcached_server_bind_address: 0.0.0.0
     openstack_memcache_security_enabled: False
@@ -30,7 +33,6 @@
     openstack_memcached_proto_udp_enabled: False
     openstack_version: queens
     openstack_old_version: ${_param:openstack_version}
-    openstack_upgrade_enabled: False
     # Security compliance user options
     openstack_service_user_options:
       ignore_change_password_upon_first_use: True
diff --git a/docker/swarm/stack/jenkins/slave01.yml b/docker/swarm/stack/jenkins/slave01.yml
index a9643ac..4791fe3 100644
--- a/docker/swarm/stack/jenkins/slave01.yml
+++ b/docker/swarm/stack/jenkins/slave01.yml
@@ -28,6 +28,7 @@
               image: ${_param:docker_image_jenkins_slave}
               volumes:
                 - /etc/ssl/certs/java/cacerts:/etc/ssl/certs/java/cacerts:ro
+                - /dev/urandom:/dev/random:ro
                 - /var/run/docker.sock:/var/run/docker.sock
                 - /usr/bin/docker:/usr/bin/docker:ro
                 - /var/lib/jenkins:/var/lib/jenkins
diff --git a/docker/swarm/stack/jenkins/slave02.yml b/docker/swarm/stack/jenkins/slave02.yml
index fb3e6cc..58b5a23 100644
--- a/docker/swarm/stack/jenkins/slave02.yml
+++ b/docker/swarm/stack/jenkins/slave02.yml
@@ -28,6 +28,7 @@
               image: ${_param:docker_image_jenkins_slave}
               volumes:
                 - /etc/ssl/certs/java/cacerts:/etc/ssl/certs/java/cacerts:ro
+                - /dev/urandom:/dev/random:ro
                 - /var/run/docker.sock:/var/run/docker.sock
                 - /usr/bin/docker:/usr/bin/docker:ro
                 - /var/lib/jenkins:/var/lib/jenkins
diff --git a/docker/swarm/stack/jenkins/slave03.yml b/docker/swarm/stack/jenkins/slave03.yml
index b10dc66..cc2acbd 100644
--- a/docker/swarm/stack/jenkins/slave03.yml
+++ b/docker/swarm/stack/jenkins/slave03.yml
@@ -28,6 +28,7 @@
               image: ${_param:docker_image_jenkins_slave}
               volumes:
                 - /etc/ssl/certs/java/cacerts:/etc/ssl/certs/java/cacerts:ro
+                - /dev/urandom:/dev/random:ro
                 - /var/run/docker.sock:/var/run/docker.sock
                 - /usr/bin/docker:/usr/bin/docker:ro
                 - /var/lib/jenkins:/var/lib/jenkins
diff --git a/fluentd/label/notifications/audit.yml b/fluentd/label/notifications/audit.yml
new file mode 100644
index 0000000..6449e1e
--- /dev/null
+++ b/fluentd/label/notifications/audit.yml
@@ -0,0 +1,51 @@
+parameters:
+  _param:
+    elasticsearch_port: 9200
+  fluentd:
+    agent:
+      config:
+        label:
+          audit_messages:
+            filter:
+              get_payload_values:
+                tag: audit
+                type: record_transformer
+                enable_ruby: true
+                record:
+                  - name: Logger
+                    value: ${fluentd:dollar}{ record.dig("publisher_id") }
+                  - name: Severity
+                    value: ${fluentd:dollar}{ {'TRACE'=>7,'DEBUG'=>7,'INFO'=>6,'AUDIT'=>6,'WARNING'=>4,'ERROR'=>3,'CRITICAL'=>2}[record['priority']].to_i }
+                  - name: Timestamp
+                    value: ${fluentd:dollar}{ DateTime.strptime(record.dig("payload", "eventTime"), "%Y-%m-%dT%H:%M:%S.%N%z").strftime("%Y-%m-%dT%H:%M:%S.%3NZ") }
+                  - name: notification_type
+                    value: ${fluentd:dollar}{ record.dig("event_type") }
+                  - name: severity_label
+                    value: ${fluentd:dollar}{ record.dig("priority") }
+                  - name: environment_label
+                    value: ${_param:cluster_domain}
+
+                  - name: action
+                    value: ${fluentd:dollar}{ record.dig("payload", "action") }
+                  - name: event_type
+                    value: ${fluentd:dollar}{ record.dig("payload", "eventType") }
+                  - name: outcome
+                    value: ${fluentd:dollar}{ record.dig("payload", "outcome") }
+              pack_payload_to_json:
+                tag: audit
+                require:
+                  - get_payload_values
+                type: record_transformer
+                enable_ruby: true
+                remove_keys: '["payload", "timestamp", "publisher_id", "priority"]'
+                record:
+                  - name: Payload
+                    value: ${fluentd:dollar}{ record["payload"].to_json }
+            match:
+              audit_output:
+                tag: audit
+                type: elasticsearch
+                host: ${_param:stacklight_log_address}
+                port: ${_param:elasticsearch_port}
+                es_index_name: audit
+                tag_key: Type
diff --git a/fluentd/label/notifications/init.yml b/fluentd/label/notifications/init.yml
new file mode 100644
index 0000000..e4e57f8
--- /dev/null
+++ b/fluentd/label/notifications/init.yml
@@ -0,0 +1,4 @@
+classes:
+- system.fluentd.label.notifications.input_rabbitmq
+- system.fluentd.label.notifications.notifications
+- system.fluentd.label.notifications.audit
diff --git a/fluentd/label/notifications/input_rabbitmq.yml b/fluentd/label/notifications/input_rabbitmq.yml
new file mode 100644
index 0000000..3d7edef
--- /dev/null
+++ b/fluentd/label/notifications/input_rabbitmq.yml
@@ -0,0 +1,107 @@
+parameters:
+  _param:
+    stacklight_notification_topic: stacklight_notifications
+  fluentd:
+    agent:
+      config:
+        label:
+          rabbitmq_notifications:
+            input:
+              tail_rabbitmq_info:
+                tag: raw_notifications
+                type: rabbitmq
+                host: ${_param:openstack_message_queue_address}
+                user: openstack
+                pass: ${_param:rabbitmq_openstack_password}
+                vhost: /openstack
+                queue: ${_param:stacklight_notification_topic}.info
+                routing_key: ${_param:stacklight_notification_topic}.info
+                parser:
+                  type: json
+              tail_rabbitmq_warn:
+                tag: raw_notifications
+                type: rabbitmq
+                host: ${_param:openstack_message_queue_address}
+                user: openstack
+                pass: ${_param:rabbitmq_openstack_password}
+                vhost: /openstack
+                queue: ${_param:stacklight_notification_topic}.warn
+                routing_key: ${_param:stacklight_notification_topic}.warn
+                parser:
+                  type: json
+              tail_rabbitmq_error:
+                tag: raw_notifications
+                type: rabbitmq
+                host: ${_param:openstack_message_queue_address}
+                user: openstack
+                pass: ${_param:rabbitmq_openstack_password}
+                vhost: /openstack
+                queue: ${_param:stacklight_notification_topic}.error
+                routing_key: ${_param:stacklight_notification_topic}.error
+                parser:
+                  type: json
+            filter:
+              parse_json:
+                tag: raw_notifications
+                type: parser
+                key_name: oslo.message
+                reserve_data: false
+                hash_value_field: parsed
+                parser:
+                  type: json
+              remove_context:
+                tag: raw_notifications
+                require:
+                  - parse_json
+                type: record_transformer
+                enable_ruby: true
+                remove_keys: _dummy_1
+                record:
+                  - name: _dummy_1
+                    value: ${fluentd:dollar}{record['parsed'].delete_if { |k,_| k.include?('_context_') }; nil}
+              pack_parsed_to_json:
+                tag: raw_notifications
+                require:
+                  - remove_context
+                type: record_transformer
+                enable_ruby: true
+                record:
+                  - name: parsed
+                    value: ${fluentd:dollar}{record["parsed"].to_json}
+              unpack_on_top_level:
+                tag: raw_notifications
+                require:
+                  - pack_parsed_to_json
+                type: parser
+                key_name: parsed
+                reserve_data: false
+                parser:
+                  type: json
+              detect_audit_notification:
+                tag: raw_notifications
+                require:
+                  - unpack_on_top_level
+                type: record_transformer
+                enable_ruby: true
+                record:
+                  - name: notification_type
+                    value: '${fluentd:dollar}{ record["payload"]["eventType"] && record["payload"]["eventTime"] ? "audit" : "notification" }'
+            match:
+              rewrite_message_tag:
+                tag: raw_notifications
+                type: rewrite_tag_filter
+                rule:
+                  - name: notification_type
+                    regexp: 'audit'
+                    result: audit
+                  - name: notification_type
+                    regexp: '/.+/'
+                    result: notification
+              forward_notification:
+                tag: notification
+                type: relabel
+                label: notification_messages
+              forward_audit:
+                tag: audit
+                type: relabel
+                label: audit_messages
diff --git a/fluentd/label/notifications/notifications.yml b/fluentd/label/notifications/notifications.yml
new file mode 100644
index 0000000..5556d6e
--- /dev/null
+++ b/fluentd/label/notifications/notifications.yml
@@ -0,0 +1,124 @@
+parameters:
+  _param:
+    elasticsearch_port: 9200
+  fluentd:
+    agent:
+      config:
+        label:
+          notification_messages:
+            filter:
+              parse_publuisher_host:
+                tag: notification
+                type: parser
+                key_name: publisher_id
+                reserve_data: true
+                parser:
+                  type: regexp
+                  format: (?<publisher>\w+).(?<hostname>\w+)
+              save_hostname:
+                tag: notification
+                require:
+                  - parse_publuisher_host
+                type: record_transformer
+                enable_ruby: true
+                record:
+                  - name: Hostname
+                    value: ${fluentd:dollar}{ record["hostname"] }
+              parse_source:
+                tag: notification
+                require:
+                  - save_hostname
+                type: parser
+                key_name: event_type
+                reserve_data: true
+                parser:
+                  type: regexp
+                  format: (?<event_type_logger>\w+).+
+              map_logger:
+                tag: notification
+                require:
+                  - parse_source
+                type: record_transformer
+                enable_ruby: true
+                remove_keys: event_type_logger
+                record:
+                  - name: Logger
+                    value: ${fluentd:dollar}{ {'volume'=>'cinder', 'snapshot'=>'cinder', 'image'=>'glance', 'orchestration'=>'heat', 'identity'=>'keystone', 'compute'=>'nova', 'compute_task'=>'nova', 'scheduler'=>'nova', 'keypair'=>'nova', 'floatingip' =>'neutron', 'security_group' =>'neutron', 'security_group_rule' =>'neutron', 'network' =>'neutron', 'port' =>'neutron', 'router' =>'neutron', 'subnet' =>'neutron', 'sahara' =>'sahara'}[record["event_type_logger"]] }
+              get_payload_values:
+                tag: notification
+                require:
+                  - map_logger
+                type: record_transformer
+                enable_ruby: true
+                record:
+                  - name: Timestamp
+                    value: ${fluentd:dollar}{ DateTime.strptime(record['timestamp'], '%Y-%m-%d %H:%M:%S.%N').strftime('%Y-%m-%dT%H:%M:%S.%3NZ') }
+                  - name: severity_label
+                    value: ${fluentd:dollar}{ record["priority"] }
+                  - name: Severity
+                    value: ${fluentd:dollar}{ {'TRACE'=>7,'DEBUG'=>7,'INFO'=>6,'AUDIT'=>6,'WARNING'=>4,'ERROR'=>3,'CRITICAL'=>2}[record['priority']].to_i }
+                  - name: Hostname
+                    value: '${fluentd:dollar}{ record["payload"].has_key?("host") ? record["payload"]["host"] : record["Hostname"] }'
+                  - name: environment_label
+                    value: ${_param:cluster_domain}
+
+                  - name: tenant_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "tenant_id") }
+                  - name: user_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "user_id") }
+                  - name: display_name
+                    value: ${fluentd:dollar}{ record.dig("payload", "display_name") }
+                  - name: vcpus
+                    value: ${fluentd:dollar}{ record.dig("payload", "vcpus") }
+                  - name: availability_zone
+                    value: ${fluentd:dollar}{ record.dig("payload", "availability_zone") }
+                  - name: instance_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "instance_id") }
+                  - name: instance_type
+                    value: ${fluentd:dollar}{ record.dig("payload", "instance_type") }
+                  - name: image_name
+                    value: ${fluentd:dollar}{ record.dig("payload", "image_name") }
+                  - name: memory_mb
+                    value: ${fluentd:dollar}{ record.dig("payload", "memory_mb") }
+                  - name: disk_gb
+                    value: ${fluentd:dollar}{ record.dig("payload", "disk_gb") }
+                  - name: state
+                    value: ${fluentd:dollar}{ record.dig("payload", "state") }
+                  - name: old_state
+                    value: ${fluentd:dollar}{ record.dig("payload", "old_state") }
+                  - name: old_task_state
+                    value: ${fluentd:dollar}{ record.dig("payload", "old_task_state") }
+                  - name: new_task_state
+                    value: ${fluentd:dollar}{ record.dig("payload", "new_task_state") }
+                  - name: network_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "network_id") }
+                  - name: subnet_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "subnet_id") }
+                  - name: port_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "port_id") }
+                  - name: volume_id
+                    value: ${fluentd:dollar}{ record.dig("payload", "volume_id") }
+                  - name: size
+                    value: ${fluentd:dollar}{ record.dig("payload", "size") }
+                  - name: status
+                    value: ${fluentd:dollar}{ record.dig("payload", "status") }
+                  - name: replication_status
+                    value: ${fluentd:dollar}{ record.dig("payload", "replication_status") }
+              pack_payload_to_json:
+                tag: notification
+                require:
+                  - get_payload_values
+                type: record_transformer
+                enable_ruby: true
+                remove_keys: '["timestamp", "publisher_id", "priority", "notification_type", "payload"]'
+                record:
+                  - name: Payload
+                    value: ${fluentd:dollar}{ record["payload"].to_json }
+            match:
+              notifications_output:
+                tag: notification
+                type: elasticsearch
+                host: ${_param:stacklight_log_address}
+                port: ${_param:elasticsearch_port}
+                es_index_name: notification
+                tag_key: Type
diff --git a/haproxy/proxy/listen/keycloak.yml b/haproxy/proxy/listen/keycloak.yml
index 89a9670..73697a3 100644
--- a/haproxy/proxy/listen/keycloak.yml
+++ b/haproxy/proxy/listen/keycloak.yml
@@ -1,7 +1,7 @@
 parameters:
   _param:
     haproxy_keycloak_bind_host: ${_param:haproxy_bind_address}
-    haproxy_keycloak_bind_port: 8080
+    haproxy_keycloak_bind_port: 8086
     haproxy_keycloak_exposed_port: 18086
     haproxy_keycloak_ssl:
       enabled: false
diff --git a/jenkins/client/init.yml b/jenkins/client/init.yml
index d1fa605..dd136ad 100644
--- a/jenkins/client/init.yml
+++ b/jenkins/client/init.yml
@@ -1,8 +1,9 @@
 classes:
-  - service.jenkins.support
-  - service.jenkins.client
-  - system.jenkins.client.approved_scripts
-  - system.jenkins.client.plugins
+- service.jenkins.support
+- service.jenkins.client
+- system.jenkins.client.approved_scripts
+- system.jenkins.client.plugins
+- system.jenkins.client.security.csrf
 parameters:
   _param:
     jenkins_client_user: none
diff --git a/jenkins/client/job/validate.yml b/jenkins/client/job/validate.yml
index 21313b2..467d79c 100644
--- a/jenkins/client/job/validate.yml
+++ b/jenkins/client/job/validate.yml
@@ -115,8 +115,10 @@
               default: "salt"
             EXTRA_PARAMS:
               type: text
-              default: "---"
-              description: YAML context with additional parameters
+              default: |
+                envs:
+                  - tests_set=''
+              description: "YAML context with additional parameters, e.g. skipped_nodes=nal01.local.com,ntw01.local.com or tests_set='tests/test_mtu.py'"
         cvp-func:
           type: workflow-scm
           name: cvp-func
@@ -152,7 +154,7 @@
               description: Credentials to the Salt API
             TEST_IMAGE:
               type: string
-              default: "xrally/xrally-openstack:0.10.1"
+              default: "xrally/xrally-openstack:0.11.2"
               description: Docker image to use for running Rally/Tempest
             TARGET_NODE:
               type: string
@@ -212,7 +214,7 @@
               description: Node where container with tempest will be run
             TEST_IMAGE:
               type: string
-              default: "xrally/xrally-openstack:0.10.1"
+              default: "xrally/xrally-openstack:0.11.2"
               description: Docker image to use for running Rally/Tempest
             TARGET_NODES:
               type: string
@@ -250,6 +252,53 @@
               type: string
               default: "https://github.com/Mirantis/cvp-configuration"
               description: URL of repo where testing tools, scenarios, configs are located.
+        cvp-tempest:
+          type: workflow-scm
+          name: cvp-tempest
+          display_name: "CVP - Functional tests (new)"
+          discard:
+            build:
+              keep_num: 20
+            artifact:
+              keep_num: 20
+          concurrent: false
+          scm:
+            type: git
+            url: "${_param:jenkins_gerrit_url}/mk/mk-pipelines"
+            branch: "${_param:jenkins_pipelines_branch}"
+            credentials: "gerrit"
+            script: cvp-tempest.groovy
+          param:
+            PREPARE_RESOURCES:
+              type: boolean
+              default: true
+              description: Prepare resources for Tempest
+            SALT_MASTER_URL:
+              type: string
+              default: "${_param:jenkins_salt_api_url}"
+              description: SALT_MASTER_URL
+            TEMPEST_TEST_PATTERN:
+              type: string
+              default: "set=smoke"
+              description: Use set=smoke, set=full or just test name (regex)
+            TEMPEST_ENDPOINT_TYPE:
+              type: choice
+              choices:
+                - internalURL
+                - adminURL
+                - publicURL
+              description: Openstack endpoint type to use during test run.
+            EXTRA_PARAMS:
+              type: text
+              default:  |
+                ---
+                  DEBUG_MODE: false
+                  GENERATE_CONFIG: true
+                  TARGET_NODE: "I@gerrit:client"
+                  SKIP_LIST_PATH: ""
+                  TEST_IMAGE: "docker-prod-virtual.docker.mirantis.net/mirantis/cicd/ci-tempest:${_param:openstack_version}"
+                  report_prefix: "cvp_"
+              description: YAML context with additional parameters
         cvp-perf:
           type: workflow-scm
           name: cvp-perf
@@ -277,7 +326,7 @@
               description: Path to scenario file in container
             TEST_IMAGE:
               type: string
-              default: "xrally/xrally-openstack:0.10.1"
+              default: "xrally/xrally-openstack:0.11.2"
               description: Docker image to use for running Rally/Tempest
             SALT_MASTER_URL:
               type: string
@@ -363,8 +412,12 @@
               default: "salt"
             EXTRA_PARAMS:
               type: text
-              default: "---"
-              description: YAML context with additional parameters
+              default: |
+                envs:
+                  - tests_set=''
+                  - image_name='Ubuntu'
+                  - networks=10.101.0.0/24
+              description: 'YAML context with additional parameters. Additional params: HW_NODES, CMP_HOSTS, salt_timeout, skipped_nodes, nova_timeout, iperf_prep_string, IMAGE_SIZE_MB'
         cvp-shaker:
           type: workflow-scm
           name: cvp-shaker
@@ -444,3 +497,39 @@
                     SHAKER_EXTERNAL_NET='public'
                   For the more detailed description of the last two categories please refer to the shaker documentation
                   https://pyshaker.readthedocs.io/en/latest/tools.html
+        cvp-rebuild:
+          type: workflow-scm
+          name: cvp-rebuild
+          display_name: "CVP-rebuild job for images"
+          discard:
+            build:
+              keep_num: 20
+            artifact:
+              keep_num: 20
+          concurrent: false
+          scm:
+            type: git
+            url: "${_param:jenkins_gerrit_url}/mk/mk-pipelines"
+            branch: "${_param:jenkins_pipelines_branch}"
+            credentials: "gerrit"
+            script: cvp-rebuild.groovy
+          param:
+            DESTINATION_IMAGE:
+              type: string
+              default: ""
+              description: "Specify address of local registry and name of the image e.g. _cid_vip_:5000/ci-tempest:v1"
+            SALT_MASTER_URL:
+              type: string
+              default: "${_param:jenkins_salt_api_url}"
+              description: Full Salt API address [e.g. https://10.10.10.2:6969]
+            SALT_MASTER_CREDENTIALS:
+              type: string
+              default: "salt"
+            REPO:
+              type: string
+              default: ""
+              description: Specify repo that will be used to rebuild image
+            BRANCH:
+              type: string
+              default: ""
+              description: Branch or version of REPO to checkout
diff --git a/jenkins/client/security/csrf.yml b/jenkins/client/security/csrf.yml
new file mode 100644
index 0000000..0f65db0
--- /dev/null
+++ b/jenkins/client/security/csrf.yml
@@ -0,0 +1,6 @@
+parameters:
+  jenkins:
+    client:
+      security:
+        csrf:
+          enable: True
diff --git a/keepalived/cluster/instance/kdt_kube_api_server_vip.yml b/keepalived/cluster/instance/kdt_kube_api_server_vip.yml
index a26748a..e76b767 100644
--- a/keepalived/cluster/instance/kdt_kube_api_server_vip.yml
+++ b/keepalived/cluster/instance/kdt_kube_api_server_vip.yml
@@ -23,6 +23,6 @@
           address: ${_param:keepalived_kdt_k8s_apiserver_vip_address}
           password: ${_param:keepalived_kdt_k8s_apiserver_vip_password}
           interface: ${_param:keepalived_kdt_k8s_apiserver_vip_interface}
-          virtual_router_id: 70
+          virtual_router_id: 71
           priority: ${_param:keepalived_vip_priority}
           track_script: kdt_vip
diff --git a/kubernetes/control/services/drivetrain/jenkins_slave_multi.yml b/kubernetes/control/services/drivetrain/jenkins_slave_multi.yml
index e710cd2..f1617b4 100644
--- a/kubernetes/control/services/drivetrain/jenkins_slave_multi.yml
+++ b/kubernetes/control/services/drivetrain/jenkins_slave_multi.yml
@@ -41,6 +41,9 @@
                 - name: docker-sock-volume02
                   mount: /var/run/docker.sock
                   read_only: false
+                - name: entropy-volume02
+                  mount: /dev/random
+                  read_only: true
           volume:
             jenkins-slave02:
               type: glusterfs
@@ -50,6 +53,9 @@
             docker-sock-volume02:
               type: hostPath
               path: /var/run/docker.sock
+            entropy-volume02:
+              type: hostPath
+              path: /dev/urandom
         jenkins_slave03:
           create: true
           service: slave03
@@ -87,6 +93,9 @@
               - name: docker-sock-volume03
                 mount: /var/run/docker.sock
                 read_only: false
+              - name: entropy-volume03
+                mount: /dev/random
+                read_only: true
           volume:
             jenkins-slave03:
               type: glusterfs
@@ -96,3 +105,6 @@
             docker-sock-volume03:
               type: hostPath
               path: /var/run/docker.sock
+            entropy-volume03:
+              type: hostPath
+              path: /dev/urandom
diff --git a/kubernetes/control/services/drivetrain/jenkins_slave_single.yml b/kubernetes/control/services/drivetrain/jenkins_slave_single.yml
index 5cdd32b..ee327dd 100644
--- a/kubernetes/control/services/drivetrain/jenkins_slave_single.yml
+++ b/kubernetes/control/services/drivetrain/jenkins_slave_single.yml
@@ -42,6 +42,9 @@
                 - name: docker-sock-volume
                   mount: /var/run/docker.sock
                   read_only: false
+                - name: entropy-volume
+                  mount: /dev/random
+                  read_only: true
           volume:
             jenkins-slave01:
               type: glusterfs
@@ -51,3 +54,6 @@
             docker-sock-volume:
               type: hostPath
               path: /var/run/docker.sock
+            entropy-volume:
+              type: hostPath
+              path: /dev/urandom
diff --git a/rabbitmq/server/cluster.yml b/rabbitmq/server/cluster.yml
index c9de9a8..2971795 100644
--- a/rabbitmq/server/cluster.yml
+++ b/rabbitmq/server/cluster.yml
@@ -1,4 +1,5 @@
 classes:
 - service.rabbitmq.server.cluster
 - service.keepalived.cluster.single
-- service.haproxy.proxy.single
\ No newline at end of file
+- service.haproxy.proxy.single
+- system.rabbitmq.upgrade
diff --git a/rabbitmq/server/single.yml b/rabbitmq/server/single.yml
index 6183f81..9982957 100644
--- a/rabbitmq/server/single.yml
+++ b/rabbitmq/server/single.yml
@@ -1,2 +1,3 @@
 classes:
 - service.rabbitmq.server.single
+- system.rabbitmq.upgrade
diff --git a/rabbitmq/upgrade/init.yml b/rabbitmq/upgrade/init.yml
new file mode 100644
index 0000000..3a75137
--- /dev/null
+++ b/rabbitmq/upgrade/init.yml
@@ -0,0 +1,4 @@
+parameters:
+  rabbitmq:
+    upgrade:
+      enabled: ${_param:rabbitmq_upgrade_enabled}
diff --git a/salt/control/placement/openstack/golden.yml b/salt/control/placement/openstack/golden.yml
index 03abda5..f4ea2bd 100644
--- a/salt/control/placement/openstack/golden.yml
+++ b/salt/control/placement/openstack/golden.yml
@@ -74,6 +74,13 @@
             ${salt:control:size:openstack.dns:image_layout}
           owner: root:root
           path: /usr/share/growlvm/image-layout.yml
+    salt_control_cluster_node_cloud_init_openstack_telemetry:
+      user_data:
+        write_files:
+        - content: |
+            ${salt:control:size:openstack.telemetry:image_layout}
+          owner: root:root
+          path: /usr/share/growlvm/image-layout.yml
   salt:
     control:
       cluster: