Merge "Migrate cfg01 node to cloud"
diff --git a/jobs/pipelines/deploy-cicd-and-run-tests.groovy b/jobs/pipelines/deploy-cicd-and-run-tests.groovy
index 567ddc6..bf447eb 100644
--- a/jobs/pipelines/deploy-cicd-and-run-tests.groovy
+++ b/jobs/pipelines/deploy-cicd-and-run-tests.groovy
@@ -38,6 +38,11 @@
             } else {
                 throw new Exception("Unknow env_manager: '${env_manager}'")
             }
+
+            if (fileExists("jenkins_agent_description.txt")) {
+                def String jenkins_agent_description = readFile("jenkins_agent_description.txt")
+                currentBuild.description += "${jenkins_agent_description}"
+            }
         }
 
         stage("Install core infrastructure and deploy CICD nodes") {
@@ -135,36 +140,10 @@
             }
         }
 
-        if (fileExists("jenkins_agent_description.txt")) {
-            def String jenkins_agent_description = readFile("jenkins_agent_description.txt")
-            currentBuild.description += "${jenkins_agent_description}"
-
-            // if there is a separated foundation node on $jenkins_slave_node_name,
-            // then archive artifacts also on that node
-            if (jenkins_slave_node_name != env.NODE_NAME) {
-                node ("${jenkins_slave_node_name}") {
-                    stage("Archive all xml reports from node ${jenkins_slave_node_name}") {
-                        archiveArtifacts artifacts: "**/*.xml,**/*.ini,**/*.log,**/*.tar.gz"
-                    }
-                    if ("${env.REPORT_TO_TESTRAIL}" != "false") {
-                        stage("report results to testrail") {
-                            common.printMsg("Running on: " + node_with_reports, "blue")
-                            shared.swarm_testrail_report(steps, node_with_reports)
-                    }
-                        stage("Store TestRail reports to job description from ${jenkins_slave_node_name}") {
-                            if (fileExists("description.txt")) {
-                                def String description  = readFile("description.txt")
-                                currentBuild.description += "${description}"
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
         stage("Archive all xml reports") {
             archiveArtifacts artifacts: "**/*.xml,**/*.ini,**/*.log,**/*.tar.gz"
         }
+
         if ("${env.REPORT_TO_TESTRAIL}" != "false") {
             stage("report results to testrail from jenkins master") {
                 common.printMsg("Running on: " + node_with_reports, "blue")
@@ -182,6 +161,31 @@
                 }
             }
         }
+
+        if (fileExists("jenkins_agent_description.txt")) {
+            // if there is a separated foundation node on $jenkins_slave_node_name,
+            // then archive artifacts also on that node
+            if (jenkins_slave_node_name != env.NODE_NAME) {
+                node ("${jenkins_slave_node_name}") {
+                    stage("Archive all xml reports from node ${jenkins_slave_node_name}") {
+                        archiveArtifacts artifacts: "**/*.xml,**/*.ini,**/*.log,**/*.tar.gz"
+                    }
+                    if ("${env.REPORT_TO_TESTRAIL}" != "false") {
+                        stage("report results to testrail") {
+                            common.printMsg("Running on: " + node_with_reports, "blue")
+                            shared.swarm_testrail_report(steps, node_with_reports)
+                        }
+                        stage("Store TestRail reports to job description from ${jenkins_slave_node_name}") {
+                            if (fileExists("description.txt")) {
+                                def String description  = readFile("description.txt")
+                                currentBuild.description += "${description}"
+                            }
+                        }
+                    }
+                } // node
+            }
+        }
+
     } // try
   } // node
 
diff --git a/jobs/pipelines/swarm-testrail-report.groovy b/jobs/pipelines/swarm-testrail-report.groovy
index 38a7968..e754936 100644
--- a/jobs/pipelines/swarm-testrail-report.groovy
+++ b/jobs/pipelines/swarm-testrail-report.groovy
@@ -33,6 +33,7 @@
     }
     dir("${PARENT_WORKSPACE}") {
         def description = ''
+        def exception_message = ''
         try {
 
             if (env.TCP_QA_REFS) {
@@ -47,7 +48,6 @@
             def testrail_name_template = ''
             def reporter_extra_options = []
 
-            def report_result = ''
             def report_url = ''
 
             //  deployment_report_name = "deployment_${ENV_NAME}.xml"
@@ -83,14 +83,15 @@
                       "--testrail-case-custom-fields {\\\"custom_qa_team\\\":\\\"9\\\"}",
                       "--testrail-case-section-name \'All\'",
                     ]
-                    report_result = shared.upload_results_to_testrail(deployment_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(deployment_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
@@ -104,14 +105,15 @@
                       "--testrail-case-custom-fields {\\\"custom_qa_team\\\":\\\"9\\\"}",
                       "--testrail-case-section-name \'All\'",
                     ]
-                    report_result = shared.upload_results_to_testrail(tcpqa_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(tcpqa_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
@@ -120,14 +122,15 @@
                     testSuiteName = env.TEMPEST_TEST_SUITE_NAME
                     methodname = "{classname}.{methodname}"
                     testrail_name_template = "{title}"
-                    report_result = shared.upload_results_to_testrail(tempest_report_name, testSuiteName, methodname, testrail_name_template)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(tempest_report_name, testSuiteName, methodname, testrail_name_template)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
@@ -146,14 +149,15 @@
                       "--testrail-case-custom-fields {\\\"custom_qa_team\\\":\\\"9\\\"}",
                       "--testrail-case-section-name \'Conformance\'",
                     ]
-                    report_result = shared.upload_results_to_testrail(k8s_conformance_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(k8s_conformance_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
@@ -168,14 +172,15 @@
                       "--testrail-case-custom-fields {\\\"custom_qa_team\\\":\\\"9\\\"}",
                       "--testrail-case-section-name \'Conformance\'",
                     ]
-                    report_result = shared.upload_results_to_testrail(k8s_conformance_virtlet_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(k8s_conformance_virtlet_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
@@ -184,14 +189,15 @@
                     testSuiteName = "LMA2.0_Automated"
                     methodname = "{methodname}"
                     testrail_name_template = "{title}"
-                    report_result = shared.upload_results_to_testrail(stacklight_report_name, testSuiteName, methodname, testrail_name_template)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(stacklight_report_name, testSuiteName, methodname, testrail_name_template)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
@@ -206,17 +212,23 @@
                       "--testrail-case-custom-fields {\\\"custom_qa_team\\\":\\\"9\\\"}",
                       "--testrail-case-section-name \'All\'",
                     ]
-                    report_result = shared.upload_results_to_testrail(cvp_sanity_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
-                    common.printMsg(report_result, "blue")
-                    report_url = report_result.split("\n").each {
+                    ret = shared.upload_results_to_testrail(cvp_sanity_report_name, testSuiteName, methodname, testrail_name_template, reporter_extra_options)
+                    common.printMsg(ret.stdout, "blue")
+                    report_url = ret.stdout.split("\n").each {
                         if (it.contains("[TestRun URL]")) {
                             common.printMsg("Found report URL: " + it.trim().split().last(), "blue")
                             description += "<a href=" + it.trim().split().last() + ">${testSuiteName}</a><br>"
                         }
                     }
+                    exception_message += ret.exception
                 }
             }
 
+            // Check if there were any exceptions during reporting
+            if (exception_message) {
+                throw new Exception(exception_message)
+            }
+
         } catch (e) {
             common.printMsg("Job is failed", "purple")
             throw e
diff --git a/src/com/mirantis/system_qa/SharedPipeline.groovy b/src/com/mirantis/system_qa/SharedPipeline.groovy
index 300aad5..1380668 100644
--- a/src/com/mirantis/system_qa/SharedPipeline.groovy
+++ b/src/com/mirantis/system_qa/SharedPipeline.groovy
@@ -705,7 +705,16 @@
              passwordVariable: 'TESTRAIL_PASSWORD',
              usernameVariable: 'TESTRAIL_USER']
   ]) {
-    return run_cmd_stdout(script)
+    def ret = [:]
+    ret.stdout = ''
+    ret.exception = ''
+    try {
+        ret.stdout = run_cmd_stdout(script)
+    } catch (Exception ex) {
+        ret.exception = ("""\
+##### Report to '${testSuiteName}' failed: #####\n""" + ex.message + "\n\n")
+    }
+    return ret
   }
 }
 
diff --git a/tcp_tests/templates/heat-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml b/tcp_tests/templates/heat-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml
index 40b5867..1afcf67 100644
--- a/tcp_tests/templates/heat-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml
+++ b/tcp_tests/templates/heat-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml
@@ -144,6 +144,7 @@
   maas_deploy_address: ==IPV4_NET_ADMIN_PREFIX==.15
   maas_deploy_range_end: ==IPV4_NET_ADMIN_PREFIX==.199
   maas_deploy_range_start: ==IPV4_NET_ADMIN_PREFIX==.180
+  maas_enabled: 'False'
   maas_deploy_vlan: '0'
   maas_fabric_name: deploy-fabric0
   maas_hostname: cfg01
diff --git a/tcp_tests/templates/heat-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml b/tcp_tests/templates/heat-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml
index 48d8f1d..4f50b5d 100644
--- a/tcp_tests/templates/heat-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml
+++ b/tcp_tests/templates/heat-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml
@@ -83,6 +83,7 @@
   kubernetes_ingressnginx_controller_replicas: 2
   local_repositories: 'False'
   maas_deploy_address: ==IPV4_NET_ADMIN_PREFIX==.15
+  maas_enabled: 'False'
   maas_deploy_range_end: ==IPV4_NET_ADMIN_PREFIX==.199
   maas_deploy_range_start: ==IPV4_NET_ADMIN_PREFIX==.180
   maas_deploy_vlan: '0'
diff --git a/tcp_tests/templates/heat-cicd-pike-contrail41-sl/underlay.hot b/tcp_tests/templates/heat-cicd-pike-contrail41-sl/underlay.hot
index bca1c84..54f31e1 100644
--- a/tcp_tests/templates/heat-cicd-pike-contrail41-sl/underlay.hot
+++ b/tcp_tests/templates/heat-cicd-pike-contrail41-sl/underlay.hot
@@ -779,7 +779,7 @@
       mcp_version: { get_param: mcp_version }
       instance_domain: {get_param: instance_domain}
       instance_name: prx01
-      instance_flavor: {get_param: cid_flavor}
+      instance_flavor: {get_param: prx_flavor}
       underlay_userdata: { get_file: ./underlay-userdata.yaml }
       control_net_static_ip:
         list_join:
@@ -796,6 +796,30 @@
 
       instance_config_host: { get_attr: [cfg01_node, instance_address] }
 
+  prx02_virtual:
+    type: MCP::SingleInstance
+    depends_on: [control_cluster]
+    properties:
+      env_name: { get_param: env_name }
+      mcp_version: { get_param: mcp_version }
+      instance_domain: {get_param: instance_domain}
+      instance_name: prx02
+      instance_flavor: {get_param: prx_flavor}
+      underlay_userdata: { get_file: ./underlay-userdata.yaml }
+      control_net_static_ip:
+        list_join:
+        - '.'
+        - [ { get_attr: [subnets, control_net_prefix] }, '82' ]
+      tenant_net_static_ip:
+        list_join:
+        - '.'
+        - [ { get_attr: [subnets, tenant_net_prefix] }, '82' ]
+      external_net_static_ip:
+        list_join:
+        - '.'
+        - [ { get_attr: [subnets, external_net_prefix] }, '82' ]
+
+      instance_config_host: { get_attr: [cfg01_node, instance_address] }
   cmp001_virtual:
     type: MCP::Compute
     depends_on: [cfg01_node]
diff --git a/tcp_tests/templates/heat-cicd-pike-dvr-sl/underlay.hot b/tcp_tests/templates/heat-cicd-pike-dvr-sl/underlay.hot
index df23b9d..543bcd8 100644
--- a/tcp_tests/templates/heat-cicd-pike-dvr-sl/underlay.hot
+++ b/tcp_tests/templates/heat-cicd-pike-dvr-sl/underlay.hot
@@ -973,7 +973,6 @@
       instance02_name: mdb02
       instance03_name: mdb03
       instance_flavor: {get_param: mdb_flavor}
-      network: { get_attr: [subnets, network] }
       underlay_userdata: { get_file: ./underlay-userdata.yaml }
       instance01_control_net_static_ip:
         list_join:
diff --git a/tcp_tests/templates/heat-cicd-queens-dvr-sl/underlay.hot b/tcp_tests/templates/heat-cicd-queens-dvr-sl/underlay.hot
index 6020707..7c415b7 100644
--- a/tcp_tests/templates/heat-cicd-queens-dvr-sl/underlay.hot
+++ b/tcp_tests/templates/heat-cicd-queens-dvr-sl/underlay.hot
@@ -973,7 +973,6 @@
       instance02_name: mdb02
       instance03_name: mdb03
       instance_flavor: {get_param: mdb_flavor}
-      network: { get_attr: [subnets, network] }
       underlay_userdata: { get_file: ./underlay-userdata.yaml }
       instance01_control_net_static_ip:
         list_join:
diff --git a/tcp_tests/tests/system/test_cvp_pipelines.py b/tcp_tests/tests/system/test_cvp_pipelines.py
index 830320d..a21d2c2 100644
--- a/tcp_tests/tests/system/test_cvp_pipelines.py
+++ b/tcp_tests/tests/system/test_cvp_pipelines.py
@@ -125,7 +125,7 @@
             maas_minion_id = salt.get_single_pillar(
                 tgt='I@maas:cluster or I@maas:region',
                 pillar="__reclass__:nodename")
-            ntp_skipped_nodes = 'ntp_skipped_nodes={0}'.format(maas_minion_id)
+            ntp_skipped_nodes = '{0}'.format(maas_minion_id)
         except LookupError:
             ntp_skipped_nodes = ''
 
@@ -142,7 +142,7 @@
                   - skipped_packages='{0}'
                   - skipped_modules='xunitmerge,setuptools'
                   - skipped_services='docker,containerd'
-                  - skipped_nodes='{1}'"""
+                  - ntp_skipped_nodes='{1}'"""
                 .format(skipped_packages, ntp_skipped_nodes)),
         }
 
diff --git a/tcp_tests/utils/get_param_heat_template.py b/tcp_tests/utils/get_param_heat_template.py
index 9b8b236..09a2450 100755
--- a/tcp_tests/utils/get_param_heat_template.py
+++ b/tcp_tests/utils/get_param_heat_template.py
@@ -48,7 +48,8 @@
 parameter_name = sys.argv[1]
 parameter_value = env['parameter_defaults'].get(parameter_name)
 if parameter_value is None:
-    parameter_value = template['parameters'].get(parameter_name)
+    parameter_template = template['parameters'].get(parameter_name, {})
+    parameter_value = parameter_template.get('default')
     if parameter_value is None:
         raise Exception("Parameter '{0}' not found in env file '{1}' "
                         "and temlate file '{2}'"