Merge "Add gradle tests for oss/jenkins/pipelines"
diff --git a/ceph/client/container.yml b/ceph/client/container.yml
new file mode 100644
index 0000000..d200a1d
--- /dev/null
+++ b/ceph/client/container.yml
@@ -0,0 +1,5 @@
+classes:
+- service.ceph.client.container
+parameters:
+  _param:
+    ceph_client_prefix_dir: /srv/volumes/ceph
diff --git a/ceph/monitoring/cluster_stats.yml b/ceph/monitoring/cluster_stats.yml
new file mode 100644
index 0000000..8e2138c
--- /dev/null
+++ b/ceph/monitoring/cluster_stats.yml
@@ -0,0 +1,2 @@
+classes:
+- service.ceph.monitoring.cluster_stats
diff --git a/ceph/monitoring/node_stats.yml b/ceph/monitoring/node_stats.yml
new file mode 100644
index 0000000..7e00533
--- /dev/null
+++ b/ceph/monitoring/node_stats.yml
@@ -0,0 +1,2 @@
+classes:
+- service.ceph.monitoring.node_stats
diff --git a/cinder/control/backend/ceph.yml b/cinder/control/backend/ceph.yml
index 1026f68..3b036d4 100644
--- a/cinder/control/backend/ceph.yml
+++ b/cinder/control/backend/ceph.yml
@@ -11,3 +11,4 @@
           user: ${_param:cinder_storage_user}
           secret_uuid: ${_param:cinder_storage_secret_uuid}
           client_cinder_key: ${_param:cinder_storage_client_key}
+          host: ceph
diff --git a/cinder/volume/backend/ceph.yml b/cinder/volume/backend/ceph.yml
index 6560add..945f2f9 100644
--- a/cinder/volume/backend/ceph.yml
+++ b/cinder/volume/backend/ceph.yml
@@ -1,7 +1,7 @@
 parameters:
   cinder:
     volume:
-      message_queue: 
+      message_queue:
         ha_queues: true
       enabled: true
       notification: true
@@ -15,3 +15,4 @@
           user: ${_param:cinder_storage_user}
           secret_uuid: ${_param:cinder_storage_secret_uuid}
           client_cinder_key: ${_param:cinder_storage_client_key}
+          host: ceph
diff --git a/docker/swarm/stack/dashboard.yml b/docker/swarm/stack/dashboard.yml
index 2ee123b..62a3e14 100644
--- a/docker/swarm/stack/dashboard.yml
+++ b/docker/swarm/stack/dashboard.yml
@@ -1,3 +1,5 @@
+classes:
+- service.grafana.support
 parameters:
   _param:
     docker_grafana_replicas: 1
diff --git a/docker/swarm/stack/decapod.yml b/docker/swarm/stack/decapod.yml
index 90f16d9..bd86062 100644
--- a/docker/swarm/stack/decapod.yml
+++ b/docker/swarm/stack/decapod.yml
@@ -6,7 +6,7 @@
     docker_image_db: docker-prod-local.artifactory.mirantis.com/mirantis/ceph/decapod/db:${_param:decapod_version}
     docker_image_api: docker-prod-local.artifactory.mirantis.com/mirantis/ceph/decapod/api:${_param:decapod_version}
     docker_image_controller: docker-prod-local.artifactory.mirantis.com/mirantis/ceph/decapod/controller:latest
-    docker_image_frontend: docker-prod-local.artifactory.mirantis.com/mirantis/ceph/decapod/controller:${_param:decapod_version}
+    docker_image_frontend: docker-prod-local.artifactory.mirantis.com/mirantis/ceph/decapod/frontend:${_param:decapod_version}
   docker:
     client:
       stack:
diff --git a/docker/swarm/stack/influxdb.yml b/docker/swarm/stack/influxdb.yml
new file mode 100644
index 0000000..f9b1f58
--- /dev/null
+++ b/docker/swarm/stack/influxdb.yml
@@ -0,0 +1,30 @@
+classes:
+- system.influxdb.server.container
+- system.influxdb.server.tmpfs_wal
+- system.telegraf.agent.remote.input.influxdb
+parameters:
+  _param:
+    docker_influxdb_replicas: 1
+    docker_influxdb_dir: /srv/volumes/influxdb
+  docker:
+    client:
+      stack:
+        influxdb:
+          service:
+            server:
+              deploy:
+                replicas: ${_param:docker_influxdb_replicas}
+                restart_policy:
+                  condition: any
+              environment:
+                INFLUXDB_CONFIG_PATH: /etc/influxdb/influxdb.conf
+                INFLUXDB_DATA_DIR: /var/lib/influxdb/data
+                INFLUXDB_META_DIR: /var/lib/influxdb/meta
+                INFLUXDB_DATA_WAL_DIR: /tmp/wal
+              image: ${_param:docker_influxdb_image}
+              ports:
+              - 15016:8086
+              volumes:
+              - ${influxdb:server:prefix_dir}/etc/influxdb:/etc/influxdb
+              - ${_param:docker_influxdb_dir}:/var/lib/influxdb
+              - ${influxdb:server:data:wal_dir}:/tmp/wal
diff --git a/docker/swarm/stack/janitor_monkey.yml b/docker/swarm/stack/janitor_monkey.yml
index 426a75c..95095e4 100644
--- a/docker/swarm/stack/janitor_monkey.yml
+++ b/docker/swarm/stack/janitor_monkey.yml
@@ -19,6 +19,9 @@
     janitor_monkey_openstack:
       project_domain_name: default
       project_name: admin
+      username: ""
+      password: ""
+      auth_url: ""
   docker:
     client:
       stack:
diff --git a/docker/swarm/stack/jenkins/master.yml b/docker/swarm/stack/jenkins/master.yml
index 54b0093..bc01e92 100644
--- a/docker/swarm/stack/jenkins/master.yml
+++ b/docker/swarm/stack/jenkins/master.yml
@@ -1,6 +1,8 @@
 parameters:
   _param:
-    docker_image_jenkins: tcpcloud/jenkins:2.63
+    docker_image_jenkins: tcpcloud/jenkins:2.71
+    jenkins_master_extra_opts: ""
+    jenkins_master_executors_num: 4
   docker:
     client:
       stack:
@@ -8,8 +10,8 @@
           service:
             master:
               environment:
-                JAVA_OPTS: "-Djenkins.install.runSetupWizard=false -Dhudson.DNSMultiCast.disabled=true -Dhudson.udp=-1 -Dhudson.footerURL=https://www.mirantis.com"
-                JENKINS_NUM_EXECUTORS: 4
+                JAVA_OPTS: " -server -XX:+AlwaysPreTouch -Xloggc:$JENKINS_HOME/gc-%t.log -XX:NumberOfGCLogFiles=5 -XX:+UseGCLogFileRotation -XX:GCLogFileSize=20m -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCCause -XX:+PrintTenuringDistribution -XX:+PrintReferenceGC -XX:+PrintAdaptiveSizePolicy -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:+ParallelRefProcEnabled -XX:+UseStringDeduplication -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:+UnlockDiagnosticVMOptions -XX:G1SummarizeRSetStatsPeriod=1 -Djenkins.install.runSetupWizard=false -Dhudson.DNSMultiCast.disabled=true -Dhudson.udp=-1 -Dhudson.footerURL=https://www.mirantis.com ${_param:jenkins_master_extra_opts}"
+                JENKINS_NUM_EXECUTORS: ${_param:jenkins_master_executors_num}
               deploy:
                 restart_policy:
                   condition: any
diff --git a/docker/swarm/stack/monitoring/init.yml b/docker/swarm/stack/monitoring/init.yml
index e5d11e1..97b9ac3 100644
--- a/docker/swarm/stack/monitoring/init.yml
+++ b/docker/swarm/stack/monitoring/init.yml
@@ -3,7 +3,7 @@
 - system.prometheus.pushgateway.container
 - system.prometheus.remote_storage_adapter.container
 - system.prometheus.server.container
-- system.telegraf.agent.remote
+- system.docker.swarm.stack.monitoring.remote_agent
 parameters:
   docker:
     client:
@@ -36,23 +36,6 @@
                 influxdb_db: ${_param:prometheus_influxdb_db}
                 influxdb_username: ${_param:prometheus_influxdb_username}
                 influxdb_password: ${_param:prometheus_influxdb_password}
-            remote_agent:
-              networks:
-                - monitoring
-              deploy:
-                replicas: 1
-                labels:
-                  com.mirantis.monitoring: "remote_agent"
-                restart_policy:
-                  condition: any
-              labels:
-                com.mirantis.monitoring: "remote_agent"
-              image: ${_param:docker_image_remote_agent}
-              ports:
-                - 15014:${telegraf:remote_agent:output:prometheus_client:bind:port}
-              volumes:
-                - ${telegraf:remote_agent:dir:config}:/etc/telegraf
-                - ${telegraf:remote_agent:dir:config_d}:/etc/telegraf/telegraf.d
             alertmanager:
               networks:
                 - monitoring
diff --git a/docker/swarm/stack/monitoring/remote_agent/ceph.yml b/docker/swarm/stack/monitoring/remote_agent/ceph.yml
new file mode 100644
index 0000000..6085eeb
--- /dev/null
+++ b/docker/swarm/stack/monitoring/remote_agent/ceph.yml
@@ -0,0 +1,12 @@
+classes:
+- system.ceph.client.container
+- system.ceph.monitoring.cluster_stats
+parameters:
+  docker:
+    client:
+      stack:
+        monitoring:
+          service:
+            remote_agent:
+              volumes:
+                - ${ceph:client:prefix_dir}/etc/ceph:/etc/ceph
diff --git a/docker/swarm/stack/monitoring/remote_agent/init.yml b/docker/swarm/stack/monitoring/remote_agent/init.yml
new file mode 100644
index 0000000..9e9455e
--- /dev/null
+++ b/docker/swarm/stack/monitoring/remote_agent/init.yml
@@ -0,0 +1,25 @@
+classes:
+- system.telegraf.agent.remote
+parameters:
+  docker:
+    client:
+      stack:
+        monitoring:
+          service:
+            remote_agent:
+              networks:
+                - monitoring
+              deploy:
+                replicas: 1
+                labels:
+                  com.mirantis.monitoring: "remote_agent"
+                restart_policy:
+                  condition: any
+              labels:
+                com.mirantis.monitoring: "remote_agent"
+              image: ${_param:docker_image_remote_agent}
+              ports:
+                - 15014:${telegraf:remote_agent:output:prometheus_client:bind:port}
+              volumes:
+                - ${telegraf:remote_agent:dir:config}:/etc/telegraf
+                - ${telegraf:remote_agent:dir:config_d}:/etc/telegraf/telegraf.d
diff --git a/docker/swarm/stack/security_monkey.yml b/docker/swarm/stack/security_monkey.yml
index 2d06a42..a2249c6 100644
--- a/docker/swarm/stack/security_monkey.yml
+++ b/docker/swarm/stack/security_monkey.yml
@@ -14,6 +14,7 @@
     security_monkey_api_port: ${_param:haproxy_security_monkey_bind_port}
     security_monkey_nginx_port: ${_param:haproxy_security_monkey_bind_port}
     devops_portal_sm_wtf_csrf_enabled: False
+    security_monkey_sync_interval: 15
     security_monkey_openstack:
       os_account_id: mcp_cloud
       os_account_name: mcp_cloud
@@ -49,6 +50,7 @@
             OS_PROJECT_NAME: ${_param:security_monkey_openstack:project_name}
             USER_DOMAIN_NAME: ${_param:security_monkey_openstack:user_domain_name}
             SM_WTF_CSRF_ENABLED: ${_param:devops_portal_sm_wtf_csrf_enabled}
+            SECURITY_MONKEY_SYNC_INTERVAL: ${_param:security_monkey_sync_interval}
             SQLALCHEMY_DATABASE_URI: postgresql://${_param:secmonkey_db_user}:${_param:secmonkey_db_user_password}@${_param:secmonkey_db_host}:${_param:haproxy_postgresql_bind_port}/${_param:security_monkey_db}
             SQLALCHEMY_POOL_RECYCLE: 14400
           service:
diff --git a/glance/client/image/octavia.yml b/glance/client/image/octavia.yml
index de81f7f..582f1bc 100644
--- a/glance/client/image/octavia.yml
+++ b/glance/client/image/octavia.yml
@@ -2,7 +2,7 @@
 - system.glance.client
 parameters:
   _param:
-    amphora_image_url: "https://artifactory.mirantis.com/binary-prod-local/mirantis/openstack/octavia/images/ocata/amphora-x64-haproxy.qcow2"
+    amphora_image_url: "https://artifactory.mirantis.com/binary-prod-local/mirantis/openstack/octavia/images/${_param:openstack_version}/amphora-x64-haproxy.qcow2"
     amphora_image_name:  "amphora-x64-haproxy"
   glance:
     client:
diff --git a/glusterfs/client/volume/influxdb.yml b/glusterfs/client/volume/influxdb.yml
new file mode 100644
index 0000000..4edcf4b
--- /dev/null
+++ b/glusterfs/client/volume/influxdb.yml
@@ -0,0 +1,13 @@
+parameters:
+  _param:
+    influxdb_glusterfs_service_host: ${_param:glusterfs_service_host}
+    glusterfs_node01_address: ${_param:cluster_node01_address}
+    glusterfs_node02_address: ${_param:cluster_node02_address}
+    glusterfs_node03_address: ${_param:cluster_node03_address}
+  glusterfs:
+    client:
+      volumes:
+        influxdb:
+          path: /srv/volumes/influxdb
+          server: ${_param:influxdb_glusterfs_service_host}
+          opts: "defaults,backup-volfile-servers=${_param:glusterfs_node01_address}:${_param:glusterfs_node02_address}:${_param:glusterfs_node03_address}"
diff --git a/glusterfs/client/volume/privatebin.yml b/glusterfs/client/volume/privatebin.yml
index c096096..163d5f9 100644
--- a/glusterfs/client/volume/privatebin.yml
+++ b/glusterfs/client/volume/privatebin.yml
@@ -8,6 +8,6 @@
     client:
       volumes:
         privatebin:
-          path: /srv/volume/privatebin
+          path: /srv/volumes/privatebin
           server: ${_param:privatebin_glusterfs_service_host}
           opts: "defaults,backup-volfile-servers=${_param:glusterfs_node01_address}:${_param:glusterfs_node02_address}:${_param:glusterfs_node03_address}"
diff --git a/glusterfs/server/volume/influxdb.yml b/glusterfs/server/volume/influxdb.yml
new file mode 100644
index 0000000..7f2d894
--- /dev/null
+++ b/glusterfs/server/volume/influxdb.yml
@@ -0,0 +1,17 @@
+parameters:
+  glusterfs:
+    server:
+      volumes:
+        influxdb:
+          storage: /srv/glusterfs/influxdb
+          replica: 3
+          bricks:
+            - ${_param:cluster_node01_address}:/srv/glusterfs/influxdb
+            - ${_param:cluster_node02_address}:/srv/glusterfs/influxdb
+            - ${_param:cluster_node03_address}:/srv/glusterfs/influxdb
+          options:
+            cluster.readdir-optimize: On
+            nfs.disable: On
+            network.remote-dio: On
+            diagnostics.client-log-level: WARNING
+            diagnostics.brick-log-level: WARNING
diff --git a/horizon/server/cluster.yml b/horizon/server/cluster.yml
index 8ee48a3..a68ab12 100644
--- a/horizon/server/cluster.yml
+++ b/horizon/server/cluster.yml
@@ -10,6 +10,8 @@
   horizon:
     server:
       branding: ${_param:horizon_site_branding}
+      bind:
+        port: 8078
       plugin: {}
       session:
         engine: "cache"
diff --git a/influxdb/client/database/ceilometer.yml b/influxdb/client/database/ceilometer.yml
new file mode 100644
index 0000000..52aebae
--- /dev/null
+++ b/influxdb/client/database/ceilometer.yml
@@ -0,0 +1,25 @@
+parameters:
+  _param:
+    influxdb_ceilometer_rp_duration: 30d
+  influxdb:
+    client:
+      database:
+        ceilometer:
+          enabled: true
+          name: ceilometer
+          retention_policy:
+            - name: ceilometer_default
+              is_default: true
+              duration: ${_param:influxdb_ceilometer_rp_duration}
+              replication: 1
+      user:
+        ceilometer:
+          enabled: true
+          name: ceilometer
+          password: ${_param:ceilometer_influxdb_password}
+      grant:
+        ceilometer_all:
+          enabled: true
+          user: ceilometer
+          database: ceilometer
+          privilege: all
diff --git a/influxdb/client/database/stacklight.yml b/influxdb/client/database/stacklight.yml
new file mode 100644
index 0000000..d07d0b8
--- /dev/null
+++ b/influxdb/client/database/stacklight.yml
@@ -0,0 +1,25 @@
+parameters:
+  _param:
+    influxdb_stacklight_rp_duration: 30d
+  influxdb:
+    client:
+      database:
+        lma:
+          enabled: true
+          name: lma
+          retention_policy:
+          - name: lma_default
+            is_default: true
+            duration: ${_param:influxdb_stacklight_password}
+            replication: 1
+      user:
+        lma:
+          enabled: true
+          name: lma
+          password: ${_param:influxdb_stacklight_password}
+      grant:
+        lma_all:
+          enabled: true
+          user: lma
+          database: lma
+          privilege: all
diff --git a/influxdb/client/init.yml b/influxdb/client/init.yml
new file mode 100644
index 0000000..8c66f1b
--- /dev/null
+++ b/influxdb/client/init.yml
@@ -0,0 +1,13 @@
+classes:
+- service.influxdb.client
+parameters:
+  _param:
+    influxdb_client_port: 8086
+  influxdb:
+    client:
+      server:
+        protocol: http
+        host: ${_param:influxdb_client_host}
+        port: ${_param:influxdb_client_port}
+        user: root
+        password: ${_param:influxdb_client_password}
diff --git a/influxdb/server/container.yml b/influxdb/server/container.yml
new file mode 100644
index 0000000..d7e7df7
--- /dev/null
+++ b/influxdb/server/container.yml
@@ -0,0 +1,19 @@
+classes:
+- service.influxdb.server.container
+parameters:
+  influxdb:
+    server:
+      enabled: true
+      prefix_dir: /srv/volumes/local/influxdb
+      http:
+        enabled: true
+        bind:
+          port: 8086
+      admin:
+        enabled: true
+        bind:
+          port: 8083
+        user:
+          enabled: true
+          name: 'root'
+          password: ${_param:influxdb_admin_password}
diff --git a/jenkins/client/approved_scripts.yml b/jenkins/client/approved_scripts.yml
index f9e01b8..367a800 100644
--- a/jenkins/client/approved_scripts.yml
+++ b/jenkins/client/approved_scripts.yml
@@ -17,9 +17,12 @@
         - method hudson.model.Item getName
         - method hudson.model.ItemGroup getItem java.lang.String
         - method hudson.model.ItemGroup getItems
+        - method hudson.model.Job getBuildByNumber int
         - method hudson.model.Job getBuilds
         - method hudson.model.Job getLastBuild
         - method hudson.model.Run getEnvironment
+        - method hudson.model.Run getId
+        - method hudson.model.Run getNumber
         - method hudson.model.Run getResult
         - method hudson.model.Run getTimeInMillis
         - method hudson.model.Run isBuilding
@@ -30,6 +33,7 @@
         - method java.lang.AutoCloseable close
         - method java.lang.Class isInstance java.lang.Object
         - method java.lang.Iterable iterator
+        - method java.lang.Throwable printStackTrace
         - method java.net.HttpURLConnection getResponseCode
         - method java.net.HttpURLConnection setRequestMethod java.lang.String
         - method java.net.URI getHost
@@ -41,32 +45,51 @@
         - method java.net.URLConnection setDoOutput boolean
         - method java.net.URLConnection setRequestProperty java.lang.String java.lang.String
         - method java.util.Collection remove java.lang.Object
+        - method java.util.Collection stream
         - method java.util.LinkedHashMap$LinkedHashIterator hasNext
         - method java.util.List subList int int
         - method java.util.Map remove java.lang.Object
         - method java.util.Map size
         - method java.util.regex.MatchResult group int
+        - method java.util.regex.MatchResult groupCount
+        - method java.util.regex.Matcher find
         - method java.util.regex.Matcher matches
         - method java.util.regex.Pattern matcher java.lang.CharSequence
+        - method java.util.stream.Stream collect java.util.stream.Collector
+        - method jenkins.model.Jenkins getItemByFullName java.lang.String
         - method jenkins.model.Jenkins getPluginManager
         - method org.jenkinsci.plugins.workflow.job.WorkflowRun doStop
+        - method org.jenkinsci.plugins.workflow.job.WorkflowRun finish hudson.model.Result java.lang.Throwable
+        - method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment
         - method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper build
+        - new groovy.json.JsonBuilder
         - new groovy.json.JsonBuilder java.lang.Object
         - new groovy.json.JsonSlurperClassic
         - new java.io.File java.lang.String
+        - new java.io.IOException java.lang.String
         - new java.io.OutputStreamWriter java.io.OutputStream
         - new java.lang.Exception java.lang.String
         - new java.lang.InterruptedException
+        - new java.lang.RuntimeException java.lang.String
+        - new java.lang.StringBuilder
+        - new java.lang.StringBuilder int
         - new java.net.URI java.lang.String
+        - new java.util.ArrayList
         - new java.util.Date
+        - new java.util.HashMap
         - staticField groovy.io.FileType FILES
         - staticMethod com.cloudbees.plugins.credentials.CredentialsProvider lookupCredentials java.lang.Class hudson.model.ItemGroup
+        - staticMethod java.lang.Integer valueOf int
         - staticMethod java.lang.Integer valueOf java.lang.String
+        - staticMethod java.lang.Math min int int
         - staticMethod java.lang.String format java.lang.String java.lang.Object[]
+        - staticMethod java.lang.String valueOf int
         - staticMethod java.lang.System exit int
         - staticMethod java.lang.System getProperty java.lang.String
         - staticMethod java.lang.System getenv java.lang.String
+        - staticMethod java.util.regex.Pattern compile java.lang.String
         - staticMethod java.util.regex.Pattern quote java.lang.String
+        - staticMethod java.util.stream.Collectors joining java.lang.CharSequence
         - staticMethod jenkins.model.Jenkins getInstance
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods collect java.util.Map groovy.lang.Closure
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods eachFile java.io.File groovy.io.FileType groovy.lang.Closure
@@ -75,36 +98,24 @@
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods get java.util.Map java.lang.Object java.lang.Object
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.lang.Iterable int
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.lang.String int
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.util.List groovy.lang.Range
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getBytes java.io.File
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getText java.io.InputStream
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods hasProperty java.lang.Object java.lang.String
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods iterator java.lang.Object
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods iterator java.lang.Object[]
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods leftShift java.lang.StringBuffer java.lang.Object
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods plus java.util.List java.lang.Iterable
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods plus java.util.List java.lang.Object
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods plus java.util.List java.util.Collection
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods println java.lang.Object java.lang.Object
         - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods putAt java.lang.Object java.lang.String java.lang.Object
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods sort java.util.Collection
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods split java.lang.String
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods takeRight java.util.List int
         - staticMethod org.codehaus.groovy.runtime.EncodingGroovyMethods encodeBase64 byte[]
         - staticMethod org.codehaus.groovy.runtime.ScriptBytecodeAdapter bitwiseNegate java.lang.Object
-        - method java.util.Collection stream
-        - staticMethod java.util.stream.Collectors joining java.lang.CharSequence
-        - method java.util.stream.Stream collect java.util.stream.Collector
-        - staticMethod java.util.regex.Pattern compile java.lang.String
-        - method java.util.regex.Matcher find
-        - method hudson.model.Run getId
-        - method java.util.regex.MatchResult groupCount
-        - method java.lang.Throwable printStackTrace
-        - method hudson.model.Run getNumber
-        - staticMethod java.lang.String valueOf int
-        - method jenkins.model.Jenkins getItemByFullName java.lang.String
-        - new java.util.ArrayList
-        - new java.util.HashMap
-        - staticMethod java.lang.Math min int int
-        - method hudson.model.Job getBuildByNumber int
-        - new java.io.IOException java.lang.String
-        - method org.jenkinsci.plugins.workflow.job.WorkflowRun finish hudson.model.Result java.lang.Throwable
-        - new groovy.json.JsonBuilder
-        - new java.lang.RuntimeException java.lang.String
-        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods takeRight java.util.List int
-        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.util.List groovy.lang.Range
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods toBoolean java.lang.Boolean
+        - staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.lang.Object java.lang.String
+        - method java.io.File listFiles
+        - method java.lang.String concat java.lang.String
diff --git a/jenkins/client/job/deploy/lab/init.yml b/jenkins/client/job/deploy/lab/init.yml
index e700325..6b0d5ab 100644
--- a/jenkins/client/job/deploy/lab/init.yml
+++ b/jenkins/client/job/deploy/lab/init.yml
@@ -4,6 +4,7 @@
   - system.jenkins.client.job.deploy.lab.mk.cleanup
   - system.jenkins.client.job.deploy.lab.mk.cloud
   - system.jenkins.client.job.deploy.lab.cicd
+  - system.jenkins.client.job.deploy.lab.test-cicd
   - system.jenkins.client.job.deploy.lab.demo
 
 parameters:
diff --git a/jenkins/client/job/deploy/lab/mk/cloud.yml b/jenkins/client/job/deploy/lab/mk/cloud.yml
index 4e4080b..81e2121 100644
--- a/jenkins/client/job/deploy/lab/mk/cloud.yml
+++ b/jenkins/client/job/deploy/lab/mk/cloud.yml
@@ -1,41 +1,57 @@
 parameters:
   _param:
     jenkins_cloud_deploy_pipelines:
-      - stack_name: k8s_calico
+      # Identity AAA
+      - stack_name: aaa_ha_freeipa
+        stack_type: heat
+        stack_install: core,aaa
+        stack_test: ""
+        job_timer: ""
+        extra_formulas: ""
+      - stack_name: k8s_ha_calico
         stack_type: aws
         stack_install: core,k8s,calico
+        stack_test: ""
         job_timer: "H H * * *"
-#      - stack_name: ceph_ha
-#        stack_type: heat
-#        stack_install: core
-#        job_timer: ""
+      - stack_name: ceph_ha
+        stack_type: heat
+        stack_install: core,ceph
+        stack_test: "ceph"
+        job_timer: ""
 #      - stack_name: drivetrain_ha
 #        stack_type: heat
 #        stack_install: core
+#        stack_test: ""
 #        job_timer: ""
 #      - stack_name: drivetrain_ha_clusters
 #        stack_type: heat
 #        stack_install: core
+#        stack_test: ""
 #        job_timer: ""
       - stack_name: k8s_aio_calico
         stack_type: heat
         stack_install: core,k8s,calico
+        stack_test: ""
         job_timer: ""
       - stack_name: k8s_aio_contrail
         stack_type: heat
         stack_install: core,k8s,contrail
+        stack_test: ""
         job_timer: ""
       - stack_name: k8s_ha_calico
         stack_type: heat
         stack_install: core,k8s,calico
-        job_timer: ""
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
       - stack_name: k8s_ha_contrail
         stack_type: heat
         stack_install: core,k8s,contrail
-        job_timer: ""
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
       - stack_name: os_aio_contrail
         stack_type: heat
         stack_install: core,openstack,contrail
+        stack_test: ""
         job_timer: ""
       - stack_name: os_aio_ovs
         stack_type: heat
@@ -44,23 +60,28 @@
       - stack_name: os_ha_contrail
         stack_type: heat
         stack_install: core,openstack,contrail
-        job_timer: ""
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
       - stack_name: os_ha_ovs
         stack_type: heat
         stack_install: core,openstack,ovs
-        job_timer: ""
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
       - stack_name: stacklight_k8s_calico
         stack_type: heat
-        stack_install: core,k8s,calico,sl-legacy
-        job_timer: ""
+        stack_install: core,k8s,calico,stacklight
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
       - stack_name: stacklight_os_contrail
         stack_type: heat
-        stack_install: core,openstack,contrail,sl-legacy
-        job_timer: ""
+        stack_install: core,openstack,contrail,stacklight
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
       - stack_name: stacklight_os_ovs
         stack_type: heat
-        stack_install: core,openstack,ovs,sl-legacy
-        job_timer: ""
+        stack_install: core,openstack,ovs,stacklight
+        stack_test: ""
+        job_timer: "H H(0-6) * * *"
   jenkins:
     client:
       job_template:
@@ -103,7 +124,7 @@
                 default: "{{stack_install}}"
               STACK_TEST:
                 type: string
-                default: ""
+                default: "{{stack_test}}"
               STACK_DELETE:
                 type: boolean
                 default: 'true'
@@ -192,15 +213,15 @@
                 default: "public"
 
               # k8s setttings
-              K8S_API_SERVER:
+              TEST_K8S_API_SERVER:
                 type: string
                 default: "http://127.0.0.1:8080"
-              K8S_CONFORMANCE_IMAGE:
+              TEST_K8S_CONFORMANCE_IMAGE:
                 type: string
                 default: "docker-dev-virtual.docker.mirantis.net/mirantis/kubernetes/k8s-conformance:v1.5.1-3_1482332392819"
 
               # openstack settings
-              TEMPEST_IMAGE:
+              TEST_TEMPEST_IMAGE:
                 type: string
                 default: "sandbox-docker-prod-local.docker.mirantis.net/mirantis/rally_tempest:0.1"
 
diff --git a/jenkins/client/job/deploy/lab/mk/init.yml b/jenkins/client/job/deploy/lab/mk/init.yml
index dde1fb0..b25fd03 100644
--- a/jenkins/client/job/deploy/lab/mk/init.yml
+++ b/jenkins/client/job/deploy/lab/mk/init.yml
@@ -77,6 +77,10 @@
               SALT_MASTER_URL:
                 type: string
                 default: ""
+              SALT_OVERRIDES:
+                type: text
+                default: ""
+                description: "YAML with overrides for Salt deployment"
 
               # openstack api
               OPENSTACK_API_URL:
@@ -108,17 +112,30 @@
                 default: "default"
 
               # k8s setttings
-              K8S_API_SERVER:
+              TEST_K8S_API_SERVER:
                 type: string
                 default: "http://127.0.0.1:8080"
-              K8S_CONFORMANCE_IMAGE:
+              TEST_K8S_CONFORMANCE_IMAGE:
                 type: string
                 default: "docker-dev-virtual.docker.mirantis.net/mirantis/kubernetes/k8s-conformance:v1.5.1-3_1482332392819"
 
               # Tempest settings
-              TEMPEST_IMAGE_LINK:
+              TEST_TEMPEST_IMAGE:
                 type: string
+                description: "Tempest image link"
                 default: "sandbox-docker-prod-local.docker.mirantis.net/mirantis/rally_tempest:0.1"
+              TEST_TEMPEST_TARGET:
+                type: string
+                description: "Node to run tests"
+                default: ""
+              TEST_DOCKER_INSTALL:
+                type: boolean
+                description: "Install docker on the target if true"
+                default: "true"
+              TEST_TEMPEST_PATTERN:
+                type: string
+                description: "Run tests matched to pattern only"
+                default: ""
 
               ASK_ON_ERROR:
                 type: boolean
diff --git a/jenkins/client/job/deploy/lab/mk/virtual.yml b/jenkins/client/job/deploy/lab/mk/virtual.yml
index 243fbf0..31b035f 100644
--- a/jenkins/client/job/deploy/lab/mk/virtual.yml
+++ b/jenkins/client/job/deploy/lab/mk/virtual.yml
@@ -7,83 +7,89 @@
       - lab: virtual_mk20_advanced
         install: core,openstack
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       - lab: virtual_mk20_basic
         install: core,openstack
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       # mk22
       - lab: virtual_mk22_advanced
         install: core,openstack
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       - lab: virtual_mk22_basic
         install: core,openstack
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       # mcp05
       - lab: virtual_mcp05_dvr
         install: core,openstack,dvr
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       - lab: virtual_mcp05_ovs
         install: core,openstack,ovs
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       # mcp10
       - lab: virtual_mcp10_contrail
         install: core,openstack,contrail
         stack_type: heat
-        test: openstack
+        test: ""
         timer: "H H(0-6) * * *"
         extra_formulas: ""
       - lab: virtual_mcp10_dvr
         install: core,openstack,dvr
         stack_type: heat
-        test: openstack
+        test: ""
         timer: "H H(0-6) * * *"
         extra_formulas: ""
       - lab: virtual_mcp10_ovs
         install: core,openstack,ovs
         stack_type: heat
-        test: openstack
+        test: ""
         timer: "H H(0-6) * * *"
         extra_formulas: ""
       # mcp11
       - lab: virtual_mcp11_contrail
         install: core,openstack,contrail
         stack_type: heat
-        test: openstack
+        test: ""
         extra_formulas: ""
         timer: ""
       - lab: virtual_mcp11_dvr
         install: core,openstack,dvr
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       - lab: virtual_mcp11_ovs
         install: core,openstack,ovs
         stack_type: heat
-        test: openstack
+        test: ""
         timer: ""
         extra_formulas: ""
       - lab: virtual_mcp11_ironic_small
         install: core,openstack
         stack_type: heat
-        test: openstack
+        test: ""
+        timer: ""
+        extra_formulas: ""
+      - lab: virtual_mcp11_aio
+        install: core,openstack
+        stack_type: heat
+        test: ""
         timer: ""
         extra_formulas: ""
       - lab: virtual_mcp11_k8s_calico
@@ -101,13 +107,13 @@
       - lab: virtual_mcp11_contrail_nfv
         install: core,openstack,contrail
         stack_type: heat
-        test: openstack
+        test: ""
         timer: "H H(0-6) * * *"
         extra_formulas: ""
       - lab: virtual_mcp11_ovs_dpdk
         install: core,openstack,ovs
         stack_type: heat
-        test: openstack
+        test: ""
         timer: "H H(0-6) * * *"
         extra_formulas: ""
       # Identity AAA
diff --git a/jenkins/client/job/deploy/lab/test-cicd.yml b/jenkins/client/job/deploy/lab/test-cicd.yml
new file mode 100644
index 0000000..0205223
--- /dev/null
+++ b/jenkins/client/job/deploy/lab/test-cicd.yml
@@ -0,0 +1,111 @@
+parameters:
+  jenkins:
+    client:
+      job_template:
+        deploy_heat_test_cicd:
+          name: deploy-heat-{{name}}
+          jobs:
+            - name: test-cicd-lab-dev
+              lab: cicd_lab_dev
+          template:
+            type: workflow-scm
+            concurrent: true
+            display_name: "Deploy {{name}} heat stack"
+            scm:
+              type: git
+              url: "${_param:jenkins_gerrit_url}/mk/mk-pipelines"
+              credentials: "gerrit"
+              script: cicd-lab-pipeline.groovy
+            param:
+              # heat
+              HEAT_TEMPLATE_URL:
+                type: string
+                default: "${_param:jenkins_gerrit_url}/mk/heat-templates"
+              HEAT_TEMPLATE_CREDENTIALS:
+                type: string
+                default: "gerrit"
+              HEAT_TEMPLATE_BRANCH:
+                type: string
+                default: "master"
+              HEAT_STACK_NAME:
+                type: string
+                description: Heat stack name. Will be generated if missing.
+              HEAT_STACK_TEMPLATE:
+                type: string
+                default: "{{lab}}"
+              HEAT_STACK_ENVIRONMENT:
+                type: string
+                default: "devcloud"
+              HEAT_STACK_ZONE:
+                type: string
+                default: "mcp-oss"
+              HEAT_STACK_PUBLIC_NET:
+                type: string
+                default: "public"
+              HEAT_STACK_DELETE:
+                type: boolean
+                default: 'true'
+                description: "Delete heat stack at the end of job"
+              HEAT_STACK_REUSE:
+                type: boolean
+                default: 'false'
+                description: "Reuse existing stack and only orchestrate deployment"
+
+              # salt master
+              SALT_MASTER_CREDENTIALS:
+                type: string
+                default: "salt-qa-credentials"
+              SSH_PUBLIC_KEY:
+                type: string
+                description: "User's public SSH key to be able to login when stack is deployed"
+
+              # openstack api
+              OPENSTACK_API_URL:
+                type: string
+                default: "https://cloud-cz.bud.mirantis.net:5000"
+              OPENSTACK_API_CREDENTIALS:
+                type: string
+                default: "openstack-devcloud-credentials"
+              OPENSTACK_API_PROJECT:
+                type: string
+                default: "mcp-oss"
+              OPENSTACK_API_CLIENT:
+                type: string
+                default: ""
+              OPENSTACK_API_VERSION:
+                type: string
+                default: "3"
+              OPENSTACK_API_PROJECT_DOMAIN:
+                type: string
+                default: "default"
+              OPENSTACK_API_USER_DOMAIN_ID:
+                type: string
+                default: "default"
+              OPENSTACK_API_PROJECT_ID:
+                type: string
+                default: ""
+              OPENSTACK_API_USER_DOMAIN:
+                type: string
+                default: "default"
+
+              # devops-portal-tests
+              DEVOPS_PORTAL_TESTS_URL:
+                type: string
+                default: "${_param:jenkins_gerrit_url}/oss/devops-portal-tests"
+              DEVOPS_PORTAL_TESTS_CREDENTIALS:
+                type: string
+                default: "gerrit"
+              DEVOPS_PORTAL_TESTS_BRANCH:
+                type: string
+                default: "master"
+              DEVOPS_PORTAL_TESTS_RUN_LOCAL:
+                type: boolean
+                default: 'true'
+                description: "Run on swarm master node"
+              DEVOPS_PORTAL_TESTS_CONFIG:
+                type: string
+                description: "Path to the service-configuration file in json-format"
+              DEVOPS_PORTAL_TESTS_MARK:
+                type: string
+                default: "ALL"
+                description: "Mark specific tests to run: healthcheck, functional (default = all)"
diff --git a/jenkins/client/job/deploy/update/init.yml b/jenkins/client/job/deploy/update/init.yml
index 2f78072..8816a66 100644
--- a/jenkins/client/job/deploy/update/init.yml
+++ b/jenkins/client/job/deploy/update/init.yml
@@ -4,6 +4,7 @@
   - system.jenkins.client.job.deploy.update.saltenv
   - system.jenkins.client.job.deploy.update.upgrade
   - system.jenkins.client.job.deploy.update.upgrade_compute
+  - system.jenkins.client.job.deploy.update.upgrade_ovs_gateway
   - system.jenkins.client.job.deploy.update.upgrade_opencontrail
   - system.jenkins.client.job.deploy.update.restore_mysql
   - system.jenkins.client.job.deploy.update.restore_cassandra
diff --git a/jenkins/client/job/deploy/update/upgrade_opencontrail.yml b/jenkins/client/job/deploy/update/upgrade_opencontrail.yml
index 7f9e5c2..b5d1e77 100644
--- a/jenkins/client/job/deploy/update/upgrade_opencontrail.yml
+++ b/jenkins/client/job/deploy/update/upgrade_opencontrail.yml
@@ -43,3 +43,15 @@
               type: string
               default: '1'
               description: Number of selected nodes to live apply compute upgrade.
+            STAGE_CONTROLLERS_ROLLBACK:
+              type: boolean
+              default: 'false'
+              description: "Run rollback on Opencontrail controllers"
+            STAGE_ANALYTICS_ROLLBACK:
+              type: boolean
+              default: 'false'
+              description: "Run rollback on Opencontrail analytics"
+            STAGE_COMPUTES_ROLLBACK:
+              type: boolean
+              default: 'false'
+              description: "Run rollback on Opencontrail compute nodes"
diff --git a/jenkins/client/job/deploy/update/upgrade_ovs_gateway.yml b/jenkins/client/job/deploy/update/upgrade_ovs_gateway.yml
new file mode 100644
index 0000000..3d12796
--- /dev/null
+++ b/jenkins/client/job/deploy/update/upgrade_ovs_gateway.yml
@@ -0,0 +1,36 @@
+#
+# Jobs to update packages on given Salt master environment
+#
+parameters:
+  _param:
+    jenkins_salt_api_url: "http://${_param:salt_master_host}:6969"
+  jenkins:
+    client:
+      job:
+        deploy-upgrade-ovs-gateway:
+          type: workflow-scm
+          concurrent: true
+          display_name: "Deploy - upgrade OVS gateway"
+          scm:
+            type: git
+            url: "${_param:jenkins_gerrit_url}/mk/mk-pipelines"
+            credentials: "gerrit"
+            script: ovs-gateway-upgrade.groovy
+          param:
+            SALT_MASTER_URL:
+              type: string
+              default: "${_param:jenkins_salt_api_url}"
+            SALT_MASTER_CREDENTIALS:
+              type: string
+              default: "salt"
+            TARGET_SERVERS:
+              type: string
+              default: "gtw*"
+              description: Salt compound target to match nodes to be updated [*, G@osfamily:debian].
+            TARGET_SUBSET_TEST:
+              type: string
+              description: Number of nodes to list package updates, empty string means all targetted nodes.
+            TARGET_SUBSET_LIVE:
+              type: string
+              default: '1'
+              description: Number of selected nodes to live apply upgrade.
diff --git a/jenkins/client/job/docker/init.yml b/jenkins/client/job/docker/init.yml
index 1a2e4d9..99e230b 100644
--- a/jenkins/client/job/docker/init.yml
+++ b/jenkins/client/job/docker/init.yml
@@ -23,8 +23,8 @@
               tags: "2.32"
               dockerfile: "Dockerfile"
             - name: jenkins
-              branch: "2.52"
-              tags: "2.52 latest"
+              branch: "2.71"
+              tags: "2.71 latest"
               dockerfile: "Dockerfile"
             - name: phpldapadmin
               branch: "master"
diff --git a/jenkins/client/job/docker/oss/init.yml b/jenkins/client/job/docker/oss/init.yml
index 9e36046..1157bd3 100644
--- a/jenkins/client/job/docker/oss/init.yml
+++ b/jenkins/client/job/docker/oss/init.yml
@@ -1,4 +1,6 @@
-parameters:
+classes:
   - system.jenkins.client.job.docker.oss.cis-collectors
   - system.jenkins.client.job.docker.oss.devops-portal
+  - system.jenkins.client.job.docker.oss.janitor-monkey-codebase
+  - system.jenkins.client.job.docker.oss.janitor-monkey-docker
   - system.jenkins.client.job.docker.oss.rundeck
diff --git a/jenkins/client/job/docker/oss/janitor-monkey-codebase.yml b/jenkins/client/job/docker/oss/janitor-monkey-codebase.yml
new file mode 100644
index 0000000..95a45f1
--- /dev/null
+++ b/jenkins/client/job/docker/oss/janitor-monkey-codebase.yml
@@ -0,0 +1,73 @@
+parameters:
+  jenkins:
+    client:
+      job:
+        docker-build-images-janitor-monkey-codebase:
+          name: docker-build-images-janitor-monkey-codebase
+          discard:
+            build:
+              keep_num: 25
+            artifact:
+              keep_num: 25
+          type: workflow-scm
+          concurrent: true
+          scm:
+            type: git
+            url: "${_param:jenkins_gerrit_url}/oss/jenkins/pipelines"
+            credentials: "gerrit"
+            script: docker-build-image-pipeline.groovy
+          trigger:
+            gerrit:
+              project:
+                "oss/SimianArmy":
+                  branches:
+                    - devel
+              skip_vote:
+                - successful
+                - failed
+                - unstable
+                - not_built
+              event:
+                patchset:
+                  - created:
+                      excludeDrafts: false
+                      excludeNoCodeChange: false
+                change:
+                  - merged
+                comment:
+                  - addedContains:
+                      commentAddedCommentContains: 'rebuild'
+          param:
+            IMAGE_NAME:
+              type: string
+              default: "janitor-monkey"
+            IMAGE_TAGS:
+              type: string
+              default: ""
+            CREDENTIALS_ID:
+              type: string
+              default: "gerrit"
+            DOCKER_REGISTRY:
+              type: string
+              default: "docker-dev-virtual.docker.mirantis.net"
+            PROJECT_NAMESPACE:
+              type: string
+              default: "oss"
+            DOCKERFILE_PATH:
+              type: string
+              default: "Dockerfile"
+            CONTEXT_PATH:
+              type: string
+              default: "."
+            CUSTOM_GERRIT_PROJECT:
+              type: string
+              default: oss/docker-janitor-monkey
+            CUSTOM_GERRIT_BRANCH:
+              type: string
+              default: master
+            CI_BUILD_ARG_JANITOR_MONKEY_REPO:
+              type: string
+              default: ""
+            CI_BUILD_ARG_JANITOR_MONKEY_REF:
+              type: string
+              default: ""
diff --git a/jenkins/client/job/docker/oss/janitor-monkey-docker.yml b/jenkins/client/job/docker/oss/janitor-monkey-docker.yml
new file mode 100644
index 0000000..083d086
--- /dev/null
+++ b/jenkins/client/job/docker/oss/janitor-monkey-docker.yml
@@ -0,0 +1,67 @@
+parameters:
+  jenkins:
+    client:
+      job:
+        docker-build-images-janitor-monkey-docker:
+          name: docker-build-images-janitor-monkey-docker
+          discard:
+            build:
+              keep_num: 25
+            artifact:
+              keep_num: 25
+          type: workflow-scm
+          concurrent: true
+          scm:
+            type: git
+            url: "${_param:jenkins_gerrit_url}/oss/jenkins/pipelines"
+            credentials: "gerrit"
+            script: docker-build-image-pipeline.groovy
+          trigger:
+            gerrit:
+              project:
+                "oss/docker-janitor-monkey":
+                  branches:
+                    - master
+              skip_vote:
+                - successful
+                - failed
+                - unstable
+                - not_built
+              event:
+                patchset:
+                  - created:
+                      excludeDrafts: false
+                      excludeNoCodeChange: false
+                change:
+                  - merged
+                comment:
+                  - addedContains:
+                      commentAddedCommentContains: 'rebuild'
+          param:
+            IMAGE_NAME:
+              type: string
+              default: "janitor-monkey"
+            IMAGE_TAGS:
+              type: string
+              default: ""
+            CREDENTIALS_ID:
+              type: string
+              default: "gerrit"
+            DOCKER_REGISTRY:
+              type: string
+              default: "docker-dev-virtual.docker.mirantis.net"
+            PROJECT_NAMESPACE:
+              type: string
+              default: "oss"
+            DOCKERFILE_PATH:
+              type: string
+              default: "Dockerfile"
+            CONTEXT_PATH:
+              type: string
+              default: "."
+            CI_BUILD_ARG_JANITOR_MONKEY_REPO:
+              type: string
+              default: ""
+            CI_BUILD_ARG_JANITOR_MONKEY_REF:
+              type: string
+              default: ""
\ No newline at end of file
diff --git a/jenkins/client/job/gating.yml b/jenkins/client/job/gating.yml
index d0f2149..6886b06 100644
--- a/jenkins/client/job/gating.yml
+++ b/jenkins/client/job/gating.yml
@@ -38,6 +38,7 @@
             quiet_period: 60
             trigger:
               gerrit:
+                silent_start_mode: true
                 project:
                   '{{regex}}':
                     compare_type: REG_EXP
diff --git a/jenkins/client/job/opencontrail/build/dpdk-extra.yml b/jenkins/client/job/opencontrail/build/dpdk-extra.yml
index 5b128a2..156cedb 100644
--- a/jenkins/client/job/opencontrail/build/dpdk-extra.yml
+++ b/jenkins/client/job/opencontrail/build/dpdk-extra.yml
@@ -9,22 +9,38 @@
               dist: trusty
               branch_name: kilo
               branch_real_name: kilo
+              aptly_repo: ubuntu-trusty-kilo
+              binary: "all"
             - os: ubuntu
               dist: trusty
               branch_name: liberty
               branch_real_name: liberty-multiqueue
+              aptly_repo: ubuntu-trusty-liberty
+              binary: "all"
             - os: ubuntu
               dist: trusty
               branch_name: mitaka
               branch_real_name: mitaka
+              aptly_repo: ubuntu-trusty-mitaka
+              binary: "all"
             - os: ubuntu
               dist: xenial
               branch_name: mitaka
               branch_real_name: mitaka
+              aptly_repo: ubuntu-xenial-mitaka
+              binary: "all"
             - os: ubuntu
               dist: xenial
               branch_name: newton
               branch_real_name: newton
+              aptly_repo: ubuntu-xenial-newton
+              binary: "all"
+            - os: ubuntu
+              dist: xenial
+              branch_name: dpdk1702
+              branch_real_name: mitaka_dpdk_17_02
+              aptly_repo: ubuntu-xenial-oc40-dpdk1702
+              binary: "contrail-dpdk-kernel-modules-dkms"
           template:
             discard:
              build:
@@ -39,19 +55,6 @@
               credentials: "gerrit"
               script: build-extra-dpdk-pipeline.groovy
             quiet_period: 120
-            trigger:
-              gerrit:
-                project:
-                  contrail/contrail-dpdk-extra-packages:
-                    branches:
-                      - "{{branch_real_name}}"
-                message:
-                  build_successful: "Build successful"
-                  build_unstable: "Build unstable"
-                  build_failure: "Build failed"
-                event:
-                  ref:
-                    - updated
             param:
               SOURCE_URL:
                 type: string
@@ -80,4 +83,4 @@
               BINARY_PACKAGES:
                 description: "binary packages to create"
                 type: string
-                default: "all"
+                default: "{{binary}}"
diff --git a/jenkins/client/job/opencontrail/build/generic.yml b/jenkins/client/job/opencontrail/build/generic.yml
index 27e3117..9643254 100644
--- a/jenkins/client/job/opencontrail/build/generic.yml
+++ b/jenkins/client/job/opencontrail/build/generic.yml
@@ -13,66 +13,91 @@
               branch: R3.0.3.x
               ppa: mirantis-opencontrail/opencontrail-3.0.3
               upload_source_package: false
+              dpdk: contrail_dpdk_2_1
             - buildname: oc31
               os: ubuntu
               dist: trusty
               branch: R3.1
               ppa: mirantis-opencontrail/opencontrail-3.1
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc31
               os: ubuntu
               dist: xenial
               branch: R3.1
               ppa: mirantis-opencontrail/opencontrail-3.1
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc311
               os: ubuntu
               dist: trusty
               branch: R3.1.1.x
               ppa: mirantis-opencontrail/opencontrail-3.1.1
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc311
               os: ubuntu
               dist: xenial
               branch: R3.1.1.x
               ppa: mirantis-opencontrail/opencontrail-3.1.1
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc32
               os: ubuntu
               dist: trusty
               branch: R3.2
               ppa: mirantis-opencontrail/opencontrail-3.2
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc32
               os: ubuntu
               dist: xenial
               branch: R3.2
               ppa: mirantis-opencontrail/opencontrail-3.2
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc323
               os: ubuntu
               dist: trusty
               branch: R3.2.3.x
               ppa: mirantis-opencontrail/opencontrail-3.2.3
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc323
               os: ubuntu
               dist: xenial
               branch: R3.2.3.x
               ppa: mirantis-opencontrail/opencontrail-3.2.3
               upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc40
               os: ubuntu
               dist: trusty
               branch: R4.0
               ppa: mirantis-opencontrail/opencontrail-4.0
-              upload_source_package: false
+              upload_source_package: true
+              dpdk: contrail_dpdk_2_1
             - buildname: oc40
               os: ubuntu
               dist: xenial
               branch: R4.0
               ppa: mirantis-opencontrail/opencontrail-4.0
+              upload_source_package: true
+              dpdk: contrail_dpdk_2_1
+            - buildname: oc40-dpdk1702
+              os: ubuntu
+              dist: trusty
+              branch: R4.0
+              ppa: mirantis-opencontrail/opencontrail-4.0-dpdk-17-02
               upload_source_package: false
+              dpdk: contrail_dpdk_17_02
+            - buildname: oc40-dpdk1702
+              os: ubuntu
+              dist: xenial
+              branch: R4.0
+              ppa: mirantis-opencontrail/opencontrail-4.0-dpdk-17-02
+              upload_source_package: false
+              dpdk: contrail_dpdk_17_02
             - buildname: oc666
               os: ubuntu
               dist: trusty
@@ -120,10 +145,9 @@
                 type: boolean
                 default: 'false'
                 description: "Don't cleanup on failure"
-              DEBUG_DPDK:
-                type: boolean
-                default: 'false'
-                description: "CONFIG_RTE_LIBRTE_ETHDEV_DEBUG enabled or disabled"
+              DPDK_BRANCH:
+                type: string
+                default: "{{dpdk}}"
               OS:
                 type: string
                 default: "{{os}}"
diff --git a/jenkins/client/job/opencontrail/init.yml b/jenkins/client/job/opencontrail/init.yml
index dad3c3a..4b42d50 100644
--- a/jenkins/client/job/opencontrail/init.yml
+++ b/jenkins/client/job/opencontrail/init.yml
@@ -5,7 +5,7 @@
   _param:
     contrail_branches: "R3.0.2.x,R3.0.3.x,R3.1,R3.1.1.x,R3.2,R3.2.3.x,R4.0,master"
     contrail_kubernetes_branches: "master,release-1.2"
-    contrail_dpdk_extra_branches: "mitaka,kilo,liberty-multiqueue,newton"
+    contrail_dpdk_extra_branches: "mitaka,mitaka_dpdk_17_02,mitaka_dpdk_17_05,kilo,liberty-multiqueue,newton"
     contrail_ceilometer_plugin_branches: "master,R4.0"
     contrail_kubernetes_branches: "master,origin-1.1,origin-1.1.3,release-1.1,release-1.2"
     contrail_dpdk_branches: "master,R3.0.2.x,R3.0.3.x,R3.1,R3.1.1.x,R3.2,R3.2.3.x,R4.0,contrail_dpdk_17_02,contrail_dpdk_17_05,contrail_dpdk_1_7,contrail_dpdk_2_0,contrail_dpdk_2_1"
diff --git a/jenkins/client/job/salt-formulas/tests.yml b/jenkins/client/job/salt-formulas/tests.yml
index 15eff13..c25cc49 100644
--- a/jenkins/client/job/salt-formulas/tests.yml
+++ b/jenkins/client/job/salt-formulas/tests.yml
@@ -158,3 +158,5 @@
               KITCHEN_TESTS_PARALLEL:
                 type: boolean
                 default: 'false'
+              CUSTOM_KITCHEN_ENVS:
+                type: text
diff --git a/jenkins/client/job/salt-models/generate-auto.yml b/jenkins/client/job/salt-models/generate-auto.yml
deleted file mode 100644
index 79e4ba3..0000000
--- a/jenkins/client/job/salt-models/generate-auto.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-parameters:
-  jenkins:
-    client:
-      job_template:
-        generate-salt-model-auto:
-          name: generate-salt-model-{{cookiecutter_template}}
-          param:
-            cookiecutter_template:
-            - separated-products-auto
-          template:
-            type: workflow-scm
-            concurrent: true
-            display_name: "Generate reclass cluster {{cookiecutter_template}} automatically"
-            scm:
-              type: git
-              url: "${_param:jenkins_gerrit_url}/mk/mk-pipelines"
-              credentials: "jenkins-mk"
-              script: generate-cookiecutter-products-auto.groovy
-            param:
-              COOKIECUTTER_TEMPLATE_URL:
-                type: string
-                default: "https://gerrit.mcp.mirantis.net/p/mk/cookiecutter-templates.git"
-              COOKIECUTTER_TEMPLATE_CREDENTIALS:
-                type: string
-                default: github-credentials
-              COOKIECUTTER_TEMPLATE_BRANCH:
-                type: string
-                default: master
-              COOKIECUTTER_TEMPLATE_PATH:
-                type: string
-                default: "./"
-              COOKIECUTTER_TEMPLATE_CONTEXT:
-                type: text
-              RECLASS_MODEL_URL:
-                type: string
-              RECLASS_MODEL_CREDENTIALS:
-                type: string
-                default: gerrit
-              RECLASS_MODEL_BRANCH:
-                type: string
-                default: master
-              EMAIL_ADDRESS:
-                type: string
-                default: ""
\ No newline at end of file
diff --git a/jenkins/client/job/salt-models/generate.yml b/jenkins/client/job/salt-models/generate.yml
index 587b3c4..491cfee 100644
--- a/jenkins/client/job/salt-models/generate.yml
+++ b/jenkins/client/job/salt-models/generate.yml
@@ -17,12 +17,13 @@
               credentials: "jenkins-mk"
               script: generate-cookiecutter-products.groovy
             param:
+              # Cookiecutter
               COOKIECUTTER_TEMPLATE_URL:
                 type: string
-                default: "https://gerrit.mcp.mirantis.net/p/mk/cookiecutter-templates.git"
+                default: "${_param:jenkins_gerrit_url}/mk/cookiecutter-templates.git"
               COOKIECUTTER_TEMPLATE_CREDENTIALS:
                 type: string
-                default: github-credentials
+                default: gerrit
               COOKIECUTTER_TEMPLATE_BRANCH:
                 type: string
                 default: master
@@ -31,17 +32,11 @@
                 default: "./"
               COOKIECUTTER_TEMPLATE_CONTEXT:
                 type: text
-              RECLASS_MODEL_URL:
+
+              # Other
+              SHARED_RECLASS_URL:
                 type: string
-              RECLASS_MODEL_CREDENTIALS:
-                type: string
-                default: gerrit
-              RECLASS_MODEL_BRANCH:
-                type: string
-                default: master
-              COMMIT_CHANGES:
-                type: boolean
-                default: false
+                default: "${_param:jenkins_gerrit_url}/salt-models/reclass-system.git"
               EMAIL_ADDRESS:
                 type: string
               TEST_MODEL:
diff --git a/jenkins/client/job/salt-models/init.yml b/jenkins/client/job/salt-models/init.yml
index 9da1a34..7e5039a 100644
--- a/jenkins/client/job/salt-models/init.yml
+++ b/jenkins/client/job/salt-models/init.yml
@@ -2,7 +2,6 @@
   - system.jenkins.client.job.salt-models.git-mirrors
   - system.jenkins.client.job.salt-models.tests
   - system.jenkins.client.job.salt-models.generate
-  - system.jenkins.client.job.salt-models.generate-auto
 parameters:
   _param:
     salt_formulas_branches: master
diff --git a/jenkins/client/job/salt-models/tests.yml b/jenkins/client/job/salt-models/tests.yml
index 7c2b369..8c04aba 100644
--- a/jenkins/client/job/salt-models/tests.yml
+++ b/jenkins/client/job/salt-models/tests.yml
@@ -41,7 +41,7 @@
                 default: "gerrit"
               PARALLEL_NODE_GROUP_SIZE:
                 type: string
-                default: "1"
+                default: "5"
               # Salt master setup extra formulas
               EXTRA_FORMULAS:
                 type: string
@@ -58,6 +58,9 @@
               SYSTEM_GIT_REF:
                 type: string
                 default: ""
+              CONFIG_NODE_NAME_PATTERN:
+                type: string
+                default: "{{config_node_name}}"
         test_system_reclass:
           name: test-salt-model-{{name}}
           template:
@@ -122,7 +125,7 @@
                 default: "1"
               EXTRA_FORMULAS:
                 type: string
-                default: "xtrabackup"
+                default: "xtrabackup docker haproxy aptly keepalived gerrit jenkins openldap maas"
       job:
         test-salt-model-node:
           name: test-salt-model-node
diff --git a/keystone/client/service/octavia.yml b/keystone/client/service/octavia.yml
index 4e14217..0382345 100644
--- a/keystone/client/service/octavia.yml
+++ b/keystone/client/service/octavia.yml
@@ -36,3 +36,4 @@
             host: ${_param:keystone_service_host}
             port: 5000
             region_name: ${_param:openstack_region}
+            use_keystoneauth: true
diff --git a/linux/system/repo/docker.yml b/linux/system/repo/docker.yml
index 6eae575..c527aa8 100644
--- a/linux/system/repo/docker.yml
+++ b/linux/system/repo/docker.yml
@@ -6,4 +6,4 @@
           source: "deb https://apt.dockerproject.org/repo ubuntu-${_param:linux_system_codename} main"
           architectures: amd64
           key_id: 58118E89F3A912897C070ADBF76221572C52609D
-          key_server: hkp://p80.pool.sks-keyservers.net:80
+          key_server: keyserver.ubuntu.com
diff --git a/model_manager/server/delivery.yml b/model_manager/server/delivery.yml
new file mode 100644
index 0000000..c7c5dce
--- /dev/null
+++ b/model_manager/server/delivery.yml
@@ -0,0 +1,6 @@
+classes:
+- service.model_manager.server.delivery
+- service.redis.server.local
+- system.nginx.server.single
+- system.nginx.server.site.model_manager
+
diff --git a/model_manager/server/integration.yml b/model_manager/server/integration.yml
new file mode 100644
index 0000000..0d723a8
--- /dev/null
+++ b/model_manager/server/integration.yml
@@ -0,0 +1,6 @@
+classes:
+- service.model_manager.server.integration
+- service.redis.server.local
+- system.nginx.server.single
+- system.nginx.server.site.model_manager
+
diff --git a/model_manager/server/single.yml b/model_manager/server/single.yml
new file mode 100644
index 0000000..2bc7f0d
--- /dev/null
+++ b/model_manager/server/single.yml
@@ -0,0 +1,4 @@
+classes:
+- system.model_manager.server.integration
+- system.model_manager.server.delivery
+
diff --git a/neutron/client/service/octavia.yml b/neutron/client/service/octavia.yml
index e818f76..90a4a4e 100644
--- a/neutron/client/service/octavia.yml
+++ b/neutron/client/service/octavia.yml
@@ -1,6 +1,8 @@
 classes:
 - service.neutron.client
 parameters:
+  _param:
+    octavia_hm_bind_ip: '192.168.0.12'
   neutron:
     client:
       server:
@@ -19,7 +21,7 @@
               port:
                 octavia-health-manager-listen-port:
                   fixed_ips:
-                    - ip_address: '192.168.0.12'
+                    - ip_address: ${_param:octavia_hm_bind_ip}
                   device_owner: Octavia:health-mgr
                   binding_host_id: ${_param:openstack_gateway_node01_hostname}
                   security_groups:
diff --git a/neutron/control/opencontrail/single.yml b/neutron/control/opencontrail/single.yml
new file mode 100644
index 0000000..0c2841b
--- /dev/null
+++ b/neutron/control/opencontrail/single.yml
@@ -0,0 +1,39 @@
+classes:
+- service.neutron.control.single
+parameters:
+  mysql:
+    server:
+      database:
+        neutron:
+          encoding: utf8
+          users:
+          - name: neutron
+            password: ${_param:mysql_neutron_password}
+            host: '%'
+            rights: all
+          - name: neutron
+            password: ${_param:mysql_neutron_password}
+            host: ${_param:cluster_local_address}
+            rights: all
+  neutron:
+    server:
+      dns_domain: ${_param:cluster_domain}
+      database:
+        host: ${_param:openstack_database_address}
+      identity:
+        region: ${_param:openstack_region}
+        host: ${_param:openstack_control_address}
+      message_queue:
+        members:
+          - host: ${_param:openstack_message_queue_node01_address}
+      compute:
+        host: ${_param:openstack_control_address}
+        region: ${_param:openstack_region}
+      backend:
+        engine: contrail
+        host: ${_param:opencontrail_control_address}
+        port: 8082
+        user: admin
+        password: ${_param:keystone_admin_password}
+        tenant: admin
+        token: ${_param:keystone_service_token}
\ No newline at end of file
diff --git a/nginx/server/proxy/model_manager_web.yml b/nginx/server/proxy/model_manager_web.yml
new file mode 100644
index 0000000..a71fe41
--- /dev/null
+++ b/nginx/server/proxy/model_manager_web.yml
@@ -0,0 +1,37 @@
+parameters:
+  _param:
+    nginx_proxy_model_manager_web_host: ${_param:cluster_public_host}
+    nginx_proxy_model_manager_web_proxy_host: ${_param:cluster_vip_address}
+    nginx_proxy_model_manager_web_buffer_size:
+      number: 4
+      size: 256
+  nginx:
+    server:
+      enabled: true
+      site:
+        nginx_proxy_model_manager_web:
+          enabled: true
+          type: nginx_proxy
+          name: model_manager_web
+          proxy:
+            host: ${_param:nginx_proxy_model_manager_web_proxy_host}
+            port: 80
+            size: 10000m
+            timeout: 43200
+            protocol: http
+            websocket: true
+            request_buffer: false
+            buffer:
+              ${_param:nginx_proxy_model_manager_web_buffer_size}
+          host:
+            name: ${_param:nginx_proxy_model_manager_web_host}
+            port: 443
+            protocol: https
+          ssl: ${_param:nginx_proxy_ssl}
+        nginx_ssl_redirect_model_manager_web:
+          enabled: true
+          type: nginx_redirect
+          name: model_manager_web_redirect
+          host:
+            name: ${_param:nginx_proxy_model_manager_web_host}
+            port: 80
diff --git a/nginx/server/site/model_manager.yml b/nginx/server/site/model_manager.yml
new file mode 100644
index 0000000..150d785
--- /dev/null
+++ b/nginx/server/site/model_manager.yml
@@ -0,0 +1,13 @@
+parameters:
+  nginx:
+    server:
+      enabled: true
+      site:
+        model_manager_dashboard:
+          enabled: true
+          type: model_manager
+          name: dashboard
+          host:
+            name: ${_param:single_address}
+            port: 80
+
diff --git a/nova/client/service/octavia.yml b/nova/client/service/octavia.yml
index 817297f..e0b6557 100644
--- a/nova/client/service/octavia.yml
+++ b/nova/client/service/octavia.yml
@@ -1,9 +1,12 @@
+classes:
+- service.nova.client
 parameters:
+  _param:
+    octavia_ssh_key_path: "/etc/octavia/.ssh/octavia_ssh_key.pub"
   nova:
     client:
-      enabled: true
       server:
-        octavia_identity:
+        admin_identity:
           endpoint_type: internalURL
           flavor:
             m1.amphora:
@@ -11,3 +14,8 @@
               ram: 1024
               disk: 2
               vcpus: 1
+        octavia_identity:
+          endpoint_type: internalURL
+          keypair:
+            octavia_ssh_key:
+              pub_file: ${_param:octavia_ssh_key_path}
diff --git a/openssh/server/team/members/ashestakov.yml b/openssh/server/team/members/ashestakov.yml
new file mode 100644
index 0000000..c3eae16
--- /dev/null
+++ b/openssh/server/team/members/ashestakov.yml
@@ -0,0 +1,20 @@
+parameters:
+  linux:
+    system:
+      user:
+        ashestakov:
+          enabled: true
+          name: ashestakov
+          sudo: true
+          full_name: Andrey Shestakov
+          home: /home/ashestakov
+          email: ashestakov@mirantis.com
+  openssh:
+    server:
+      enabled: true
+      user:
+        ashestakov:
+          enabled: true
+          public_keys:
+            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQClIwlkr2nH8tCa2VnDgYpsVccJ4pX44mEdjt4oYqSdvEzXKaLhkC2vRzZ/DJo+1GjHC1cy6oPq26bo186MZ2/6PBh2gyVR5rRWyOFoNocAUaaEnBxu8TtNewIzrZ9k+telbmzz/PcoXkELLsHjrTPPxGlpI6qmk3WL/vJlXumvlZlv/FUbI8RlMxTuOK3TF5AQBGd3+1UkF+qFcAFGAAVFO0Td69MMQcsIhLCzJ68d7YM60+3z37At0x/URNlRwgf5Wt8NLPUQwo1dCDCK4GSZtqAHzj7IKVyk77twiN0SLQR12eTqUkyEjm6zR6QpZ6mpIbAjRVVFV5W55WTZXpIz
+          user: ${linux:system:user:ashestakov}
diff --git a/openssh/server/team/members/rsafonov.yml b/openssh/server/team/members/rsafonov.yml
index 7e6f206..5569975 100644
--- a/openssh/server/team/members/rsafonov.yml
+++ b/openssh/server/team/members/rsafonov.yml
@@ -21,5 +21,5 @@
           user: ${linux:system:user:rsafonov}
   public_keys:
     rsafonov:
-      - key: ssh-rsa ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaVDVMjNUXR+SP4xjH4vX9zfqzYHosQRO4MlVxE8uJPIIQdF1+iPWtggLrsRDZTSQ0JNzCYGXPv8fK6iKBQ/cX5KgMnVPQmFn4Q+Ip/oWotkbVZtR1F0ZVw01KNBYE0LMXrV9dxhX6qUFCO0IV9inbOZ+6zhYOLPddG2WVc8htz8XH7xdWqGbU1GBwyEoRFjITZ9GAYMRNrSjlzPsoBVkQwGKNtvh8uCFZasfAMr2mV1XVFcJlK52T6bNqIXOYPmRc9mSoQoD0UHRRYwlWAZHzW+2e8SABT+NRT1Cc/BoioRC2SBKj9tsZgy9nhq5O0EfuvWVL3ZCM6+RviNxkEL7Z
+      - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaVDVMjNUXR+SP4xjH4vX9zfqzYHosQRO4MlVxE8uJPIIQdF1+iPWtggLrsRDZTSQ0JNzCYGXPv8fK6iKBQ/cX5KgMnVPQmFn4Q+Ip/oWotkbVZtR1F0ZVw01KNBYE0LMXrV9dxhX6qUFCO0IV9inbOZ+6zhYOLPddG2WVc8htz8XH7xdWqGbU1GBwyEoRFjITZ9GAYMRNrSjlzPsoBVkQwGKNtvh8uCFZasfAMr2mV1XVFcJlK52T6bNqIXOYPmRc9mSoQoD0UHRRYwlWAZHzW+2e8SABT+NRT1Cc/BoioRC2SBKj9tsZgy9nhq5O0EfuvWVL3ZCM6+RviNxkEL7Z roman@roman
 
diff --git a/openssh/server/team/members/rsatek.yml b/openssh/server/team/members/rsatek.yml
new file mode 100644
index 0000000..7968ee7
--- /dev/null
+++ b/openssh/server/team/members/rsatek.yml
@@ -0,0 +1,20 @@
+parameters:
+  linux:
+    system:
+      user:
+        rsatek:
+          enabled: true
+          name: rsatek
+          sudo: true
+          full_name: Rudolf Satek
+          home: /home/rsatek
+          email: rsatek@mirantis.com
+  openssh:
+    server:
+      enabled: true
+      user:
+        rsatek:
+          enabled: true
+          public_keys:
+            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC63DK9CdBB2WNHcbgzReBlcVY7YDvVKBJI4P5O8N3lg/T+01ROL99/6k8drFYFJjdeXJaMkCg7UM17yIyouDijBHB9G9AM7jkefBZrGDF7QaWJeGvpxB9W3BQnhotCeuP363CNBup+oUfPwXVnkE5iGuLJAGS8SENpVZpZsF0gXAUuVtvl5D8h1wIqQtFveJSV6qJkjVIudZYJfOMDBfiyS5nEwKmboP5jFtrm3e64HpxDhm2J5irNtzw3hOO8cq2ssnZ0ZAHFf2FfnPAzZ2L0Z1MpZcEPdzBonsdO8/cfxdbov9hW4iLmpJF80KxgPyHU0R304uyfnsfkC164l0Rx rsatek@Rudolfs-MacBook-Pro.local
+            user: ${linux:system:user:rsatek}
diff --git a/openssh/server/team/members/tkukral.yml b/openssh/server/team/members/tkukral.yml
index cba6ef6..e53ce2d 100644
--- a/openssh/server/team/members/tkukral.yml
+++ b/openssh/server/team/members/tkukral.yml
@@ -16,5 +16,6 @@
         tkukral:
           enabled: true
           public_keys:
-            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRM6WquKic6i6v/JbNR2XuMqCCYqlfyGU1K7XHK7tWFordRLz2/o4S76sZULBTXR0rLHtynvHM4QHlloE1/XJnd0BtI/3y8aY0OkXyu6PHvTC8Az8SyGj2XAcaiPlaT2f+oTJHoPc9rxLhMMD7OTwias6QeVKB3UrT0OaHfy2wWCF7t8cQeofi2ldEHKeCsC1jrT1vaVuoThQgZ00h0rNk4COPZEW34FXdmdJFUmZcUIDMa71HtYgnn4gmE8sUiJ/j6ardvPaycCDT9j1GW1Yu6UVLBWOoMMCb04bDJiidlvY1fQqbM/G4cR4ZPHFZ0RQiM2+wnRaB5RCmBVgNT0Tj tkukral
-          user: ${linux:system:user:tkukral}
\ No newline at end of file
+            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRM6WquKic6i6v/JbNR2XuMqCCYqlfyGU1K7XHK7tWFordRLz2/o4S76sZULBTXR0rLHtynvHM4QHlloE1/XJnd0BtI/3y8aY0OkXyu6PHvTC8Az8SyGj2XAcaiPlaT2f+oTJHoPc9rxLhMMD7OTwias6QeVKB3UrT0OaHfy2wWCF7t8cQeofi2ldEHKeCsC1jrT1vaVuoThQgZ00h0rNk4COPZEW34FXdmdJFUmZcUIDMa71HtYgnn4gmE8sUiJ/j6ardvPaycCDT9j1GW1Yu6UVLBWOoMMCb04bDJiidlvY1fQqbM/G4cR4ZPHFZ0RQiM2+wnRaB5RCmBVgNT0Tj
+            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDIcEZKBvsDAVOeUyucpTXH7nubNjXxlQSMf6oXmcXW5EFzQ7bcBjUJIC2/w4NV2v+/qbbvax1BiI5wU3TWM+LKx6VyhexwrnGQ4p9xprbAIiYaDAbT4KsSOyFnItmbD3qo5JzYruF/jxpus2fV/rBjfsgENHSDSL7ZNO5XLRhdfdcjGrReYf6MU+Py90mOxIcafJQ0nI2PkZ4JURtiJmd/lBp+QJH+6JpQ4Fjm1C0stJFLZfyn0r9YtMXs7j3LK5QaypbZO63NvBKp/1GhZUbC48Cb19SqIoBfQl8JroT93PFzhcQaXd/iXbbBg1WPhEJLAaJEJ7aHGVN+93YHoukP+AFobrpCES3LPFrwbRXpjZNCbKtQCMS1oZHLNBrIsa6uuvAhd9ni3Q/iJq4O6uZ8g0gW69+VI3FT7l3adBCBlOQUVvN51k2k3Q18oeFZAuVPoH49gUDXgxaUHjA5nE0hgPd6KaZkh5UGs/8jyvDLRLVRCUGYfVZcXlMAa5uc1SaUGR3XZgciUlY9DWAGTS8mA4ZnD6mXdnQmjDqhaI2S9jFmuO1Z4YAlHCs+qqMmnFBwbIZuIJaTgl9blr2pi8g6SVQGOE8eA9SDZYTH2EM741ZgVxBPTC/QjMcRtERWNTzfK+R6nZgsdozi9w8MMlmLgvjhney+YuhPhBI2YUwafV2wngqcz7qKP35Jx4E0AeI/Z6z2duuP4JHtaswkR7Zwk4/ebRm1DGIvImh4UxucumEMpXrNOyPZqyJwOb1GM7U5w/kfGSU10y6Y2/db23eYvIb2c1aIbKcGI+Db+1UuED9KcmI9JuYnxqzQZe66T56s+jOi0zyjQDlx9gu2ib/ORE+XVuKqvqii/WF4dTK42YgzTY1RX4wag4mNOEhY4hX+VA6eEFLruqIE+zQ9L+vjf4w2jqpC2CTtY+UtgAbkpZWn9/00CqS9EAh3cmYVgL8se+mfo9iQkcOrHoJ/hN9wyWOK8yQXACMtm/zdFyMtCzhWeSvz03SPz4o1L5QcS3VG+FF6XE5jb0KCWH2C0U6ufgKhpna+LXmG1nXGtay7KqUkQeIwOXq2nq2xehPwgfM25xIPHJ+t1dQMstXrR/h0Bs9lHM7V7mTcgA4MtuYM1mwUpuK9QYantvWE7aq1KtFwFBaP/4swtSoxWsotIDv9GxJhWRJ8aUJIAbsN2znMlbtsIDGTMlWLW3pbpr+1ANAZx6YiQOSCkDDzk4eaFMhlGaa+4sBVfIU0QwnO9swOjQMQH+3/qaeGl9LOZEf87kwFKnQDpMEdDl4vmpsSwzcyGT8AIFl/ybrrl///v3cvCZe1lDJZxPag6KT4BOwycoWTKfL5ll06v+JzW67XqkQT
+          user: ${linux:system:user:tkukral}
diff --git a/openssh/server/team/members/vnogin.yml b/openssh/server/team/members/vnogin.yml
new file mode 100644
index 0000000..e8c1df9
--- /dev/null
+++ b/openssh/server/team/members/vnogin.yml
@@ -0,0 +1,20 @@
+parameters:
+  linux:
+    system:
+      user:
+        vnogin:
+          enabled: true
+          name: vnogin
+          sudo: true
+          full_name: Vitaliy Nogin
+          home: /home/vnogin
+          email: vnogin@mirantis.com
+  openssh:
+    server:
+      enabled: true
+      user:
+        vnogin:
+          enabled: true
+          public_keys:
+            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiuKuC+aACWPhwTg1liOOGMAvL3zSMcgU2ZfjN6NMLMyekJqD7sr9NwJkeXEt6wr1YSelfYDcUjdu2ZyQHzfQ8CaNrTAlrNYUc+UlUqqydbO1d89j/MMn8fUAuFBu1vLMOqfNW8nPRmy327blmvSxBq2Oz9wSf/z/3lB4TVJKGwB61ciQn08FwFAitCN9cdfBthjRJXrhs/7kt0/An8O0p43LNa1aQ5QeaxLUAqMZa3VxkAaEwFzm/E/Vg4SPEJLijfCWYPozkZttoS2ud0HAJR87jya/BaCrtSAOqX55cLzWGABlvDWFprwo/59aJw7WlE8Y2bgxhtnFRdaHuIk7T vnogin@MacBook-Pro-Vitalii.local
+          user: ${linux:system:user:vnogin}
diff --git a/openssh/server/team/members/vsaienko.yml b/openssh/server/team/members/vsaienko.yml
new file mode 100644
index 0000000..bd532f6
--- /dev/null
+++ b/openssh/server/team/members/vsaienko.yml
@@ -0,0 +1,20 @@
+parameters:
+  linux:
+    system:
+      user:
+        vsaienko:
+          enabled: true
+          name: vsaienko
+          sudo: true
+          full_name: Vasyl Saienko
+          home: /home/vsaienko
+          email: vsaienko@mirantis.com
+  openssh:
+    server:
+      enabled: true
+      user:
+        vsaienko:
+          enabled: true
+          public_keys:
+            - key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPagYDP2Dt5cGMC/HYlv+5AVYx/v9yRiOSJuQb/XqU35PLW5CVroSAaEA33IIAOjyte8DRrmi4UxErX00V7+F9Dwebt0qkEX35FE91E+BM2L3S2Zcuuh4gHDDp5khsHSTHdgiFpMhRREFesuG6P7ekQ6gCBzKK4R+TTLVTKWYn1/TXQIvMUAO+umGykHQ2T6memO2eGivnSSNkKCGOjODquyP3JMmt9Dk7bP5RR6kRLSD9HknFCIFds2fkcdbOhZMv+XIqwOVAWhRPksafOMktmaHNyy3k6IcMPJroH6H4P/GsQmrPL8IXpDP01vTdeQYM47YqPC14L3T74u71YJGF vsaienko@mirantis.com
+          user: ${linux:system:user:vsaienko}
diff --git a/openssh/server/team/oscore_devops.yml b/openssh/server/team/oscore_devops.yml
new file mode 100644
index 0000000..2ba780a
--- /dev/null
+++ b/openssh/server/team/oscore_devops.yml
@@ -0,0 +1,5 @@
+classes:
+- system.linux.system.sudo
+- system.openssh.server.team.members.vsaienko
+- system.openssh.server.team.members.vnogin
+- system.openssh.server.team.members.ashestakov
diff --git a/prometheus/server/target/dns.yml b/prometheus/server/target/dns.yml
index ed6602d..e2745f1 100644
--- a/prometheus/server/target/dns.yml
+++ b/prometheus/server/target/dns.yml
@@ -25,3 +25,8 @@
               - 'tasks.monitoring_remote_agent'
               type: A
               port: ${telegraf:remote_agent:output:prometheus_client:bind:port}
+            - name: 'remote_storage_adapter'
+              domain:
+              - 'tasks.monitoring_remote_storage_adapter'
+              type: A
+              port: ${prometheus:remote_storage_adapter:bind:port}
diff --git a/rabbitmq/server/vhost/openstack.yml b/rabbitmq/server/vhost/openstack.yml
index 962bc0a..4320919 100644
--- a/rabbitmq/server/vhost/openstack.yml
+++ b/rabbitmq/server/vhost/openstack.yml
@@ -1,4 +1,7 @@
 parameters:
+  _param:
+    # Ceilometer samples are persisted up to 3 hours by default
+    rabbitmq_ceilometer_ttl: 10800000
   rabbitmq:
     server:
       host:
@@ -15,6 +18,10 @@
           user: openstack
           password: ${_param:rabbitmq_openstack_password}
           policies:
+          - name: Ceilometer
+            pattern: '^metering.sample$'
+            definition: '{"ha-mode": "all", "message-ttl": ${_param:rabbitmq_ceilometer_ttl}}'
+            priority: 10
           - name: HA
             pattern: '^(?!amq\.).*'
             definition: '{"ha-mode": "all", "message-ttl": 120000}'
diff --git a/reclass/storage/system/cicd_manager_cluster.yml b/reclass/storage/system/cicd_manager_cluster.yml
new file mode 100644
index 0000000..898e657
--- /dev/null
+++ b/reclass/storage/system/cicd_manager_cluster.yml
@@ -0,0 +1,29 @@
+parameters:
+  _param:
+    cicd_control_node02_hostname: cid01
+    cicd_control_node03_hostname: cid02
+  reclass:
+    storage:
+      node:
+        cicd_control_node02:
+          name: ${_param:cicd_control_node02_hostname}
+          domain: ${_param:cluster_domain}
+          classes:
+          - cluster.${_param:cluster_name}.cicd.control.manager
+          params:
+            salt_master_host: ${_param:reclass_config_master}
+            linux_system_codename: xenial
+            single_address: ${_param:cicd_control_node02_address}
+            keepalived_vip_priority: 102
+            cicd_database_id: 2
+        cicd_control_node03:
+          name: ${_param:cicd_control_node03_hostname}
+          domain: ${_param:cluster_domain}
+          classes:
+          - cluster.${_param:cluster_name}.cicd.control.manager
+          params:
+            salt_master_host: ${_param:reclass_config_master}
+            linux_system_codename: xenial
+            single_address: ${_param:cicd_control_node03_address}
+            keepalived_vip_priority: 101
+            cicd_database_id: 3
diff --git a/reclass/storage/system/openstack_control_single.yml b/reclass/storage/system/openstack_control_single.yml
new file mode 100644
index 0000000..016ab96
--- /dev/null
+++ b/reclass/storage/system/openstack_control_single.yml
@@ -0,0 +1,15 @@
+parameters:
+  _param:
+    openstack_control_node01_hostname: ctl01
+  reclass:
+    storage:
+      node:
+        openstack_control_node01:
+          name: ${_param:openstack_control_node01_hostname}
+          domain: ${_param:cluster_domain}
+          classes:
+          - cluster.${_param:cluster_name}.openstack.control
+          params:
+            salt_master_host: ${_param:reclass_config_master}
+            linux_system_codename: xenial
+            single_address: ${_param:openstack_control_node01_address}
diff --git a/reclass/storage/system/openstack_gateway_single_octavia.yml b/reclass/storage/system/openstack_gateway_single_octavia.yml
index 264b3f1..2a5b952 100644
--- a/reclass/storage/system/openstack_gateway_single_octavia.yml
+++ b/reclass/storage/system/openstack_gateway_single_octavia.yml
@@ -4,4 +4,4 @@
       node:
         openstack_gateway_node01:
           classes:
-          - system.octavia.manager.single
+          - cluster.${_param:cluster_name}.openstack.octavia_manager
diff --git a/salt/master/formula/git/foundation.yml b/salt/master/formula/git/foundation.yml
index 7e21699..dbc7d19 100644
--- a/salt/master/formula/git/foundation.yml
+++ b/salt/master/formula/git/foundation.yml
@@ -54,3 +54,7 @@
               source: git
               address: '${_param:salt_master_environment_repository}/salt-formula-openldap.git'
               revision: ${_param:salt_master_environment_revision}
+            powerdns:
+              source: git
+              address: '${_param:salt_master_environment_repository}/salt-formula-powerdns.git'
+              revision: ${_param:salt_master_environment_revision}
diff --git a/salt/master/formula/pkg/foundation.yml b/salt/master/formula/pkg/foundation.yml
index 3eed5e9..3111419 100644
--- a/salt/master/formula/pkg/foundation.yml
+++ b/salt/master/formula/pkg/foundation.yml
@@ -28,6 +28,9 @@
             openldap:
               source: pkg
               name: salt-formula-openldap
+            powerdns:
+              source: pkg
+              name: salt-formula-powerdns
             lldp:
               source: pkg
               name: salt-formula-lldp
diff --git a/salt/minion/ca/octavia_ca.yml b/salt/minion/ca/octavia_ca.yml
new file mode 100644
index 0000000..ac66bec
--- /dev/null
+++ b/salt/minion/ca/octavia_ca.yml
@@ -0,0 +1,29 @@
+parameters:
+  _param:
+    octavia_ca_common_name: Octavia CA
+    octavia_ca_country: cz
+    octavia_ca_locality: Prague
+    octavia_ca_organization: Mirantis
+    octavia_ca_days_valid_authority: 3650
+    octavia_ca_days_valid_certificate: 365
+  salt:
+    minion:
+      ca:
+        octavia_ca:
+          common_name: ${_param:octavia_ca_common_name}
+          country: ${_param:octavia_ca_country}
+          locality: ${_param:octavia_ca_locality}
+          organization: ${_param:octavia_ca_organization}
+          signing_policy:
+            cert_server:
+              type: v3_edge_cert_server
+              minions: '*'
+            cert_client:
+              type: v3_edge_cert_client
+              minions: '*'
+            cert_open:
+              type: v3_edge_cert_open
+              minions: '*'
+          days_valid:
+            authority: ${_param:octavia_ca_days_valid_authority}
+            certificate: ${_param:octavia_ca_days_valid_certificate}
diff --git a/salt/minion/cert/octavia_amp_client.yml b/salt/minion/cert/octavia_amp_client.yml
new file mode 100644
index 0000000..5219450
--- /dev/null
+++ b/salt/minion/cert/octavia_amp_client.yml
@@ -0,0 +1,21 @@
+parameters:
+  _param:
+    octavia_ca_hostname: ${linux:system:name}
+    octavia_ca_host: ${_param:octavia_ca_hostname}.${_param:cluster_domain}
+    octavia_ca_authority: octavia_ca
+  salt:
+    minion:
+      cert:
+        octavia_amp_client:
+          host: ${_param:octavia_ca_host}
+          authority: ${_param:octavia_ca_authority}
+          common_name: octavia_amp_client
+          signing_policy: cert_open
+          key_usage: "digitalSignature,nonRepudiation,keyEncipherment"
+          ca_file: ${octavia:manager:certificates:ca_certificate}
+          ca_key_file: ${octavia:manager:certificates:ca_private_key}
+          key_file: ${octavia:manager:haproxy_amphora:client_cert_key}
+          cert_file: ${octavia:manager:haproxy_amphora:client_cert}
+          all_file: ${octavia:manager:haproxy_amphora:client_cert_all}
+          user: octavia
+          group: octavia
diff --git a/salt/minion/cert/rabbitmq_server.yml b/salt/minion/cert/rabbitmq_server.yml
new file mode 100644
index 0000000..59972fe
--- /dev/null
+++ b/salt/minion/cert/rabbitmq_server.yml
@@ -0,0 +1,22 @@
+parameters:
+
+  _param:
+    salt_minion_ca_host: cfg01.${_param:cluster_domain}
+    salt_minion_ca_authority: salt_master_ca
+
+  salt:
+    minion:
+        cert:
+          rabbitmq_server:
+            host: ${_param:salt_minion_ca_host}
+            authority: ${_param:salt_minion_ca_authority}
+            common_name: rabbitmq_server
+            signing_policy: cert_open
+            alternative_names: IP:127.0.0.1,IP:${_param:cluster_local_address},DNS:${linux:system:name},DNS:${linux:network:fqdn}
+            key_usage: "digitalSignature,nonRepudiation,keyEncipherment"
+            key_file: ${rabbitmq:server:ssl:key_file}
+            cert_file: ${rabbitmq:server:ssl:cert_file}
+            all_file: ${rabbitmq:server:ssl:all_file}
+            ca_file: ${rabbitmq:server:ssl:ca_file}
+            user: rabbitmq
+            group: rabbitmq
\ No newline at end of file
diff --git a/sensu/server/cluster.yml b/sensu/server/cluster.yml
index 28eb78b..5c8fe85 100644
--- a/sensu/server/cluster.yml
+++ b/sensu/server/cluster.yml
@@ -11,6 +11,15 @@
     rabbitmq_cold_password: password
     rabbitmq_monitor_password: password
     sensu_message_queue_host: ${_param:cluster_vip_address}
+    cluster_redis_port: 6379
+  sensu:
+   server:
+     bind:
+       address: ${_param:single_address}
+     database:
+       engine: redis
+       host: ${_param:cluster_vip_address}
+       port: ${_param:cluster_redis_port}
   rabbitmq:
     cluster:
       name: 'monitoring'
diff --git a/telegraf/agent/init.yml b/telegraf/agent/init.yml
index ca7e2b0..64ef566 100644
--- a/telegraf/agent/init.yml
+++ b/telegraf/agent/init.yml
@@ -1,13 +1,5 @@
 classes:
 - service.telegraf.agent
 - system.telegraf.agent.input.http_listener
+- system.telegraf.agent.output.prometheus_client
 - system.telegraf.sudo
-parameters:
-  telegraf:
-    agent:
-      output:
-        prometheus_client:
-          bind:
-            address: 0.0.0.0
-            port: 9126
-          engine: prometheus
diff --git a/telegraf/agent/output/prometheus.yml b/telegraf/agent/output/prometheus.yml
deleted file mode 100644
index 952bc13..0000000
--- a/telegraf/agent/output/prometheus.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-parameters:
-  _param:
-    telegraf_agent_prometheus_port: 9126
-  telegraf:
-    agent:
-      output:
-        prometheus_client:
-          bind:
-            address: 0.0.0.0
-            port: ${_param: telegraf_agent_prometheus_port}
-          engine: prometheus
diff --git a/telegraf/agent/output/prometheus_client.yml b/telegraf/agent/output/prometheus_client.yml
new file mode 100644
index 0000000..bad5ebd
--- /dev/null
+++ b/telegraf/agent/output/prometheus_client.yml
@@ -0,0 +1,2 @@
+classes:
+- service.telegraf.agent.output.prometheus_client
diff --git a/telegraf/agent/remote/input/influxdb.yml b/telegraf/agent/remote/input/influxdb.yml
new file mode 100644
index 0000000..9b28476
--- /dev/null
+++ b/telegraf/agent/remote/input/influxdb.yml
@@ -0,0 +1,12 @@
+parameters:
+  _param:
+    telegraf_remote_agent_influxdb_port: 15016
+    telegraf_remote_agent_influxdb_protocol: http
+  telegraf:
+    remote_agent:
+      input:
+        influxdb:
+          servers:
+          - url: "${_param:telegraf_remote_agent_influxdb_protocol}://${_param:telegraf_remote_agent_influxdb_address}:${_param:telegraf_remote_agent_influxdb_port}/debug/vars"
+          tags:
+            host: ${_param:telegraf_remote_agent_influxdb_address}