Add new group collecting mechanism
diff --git a/cvp_checks/global_config.yaml b/cvp_checks/global_config.yaml
index 4de94ce..4faa46d 100644
--- a/cvp_checks/global_config.yaml
+++ b/cvp_checks/global_config.yaml
@@ -17,7 +17,7 @@
 # How many seconds to wait for salt-minion to respond
 salt_timeout: 1
 
-# List of nodes (full fqdn) to skip in all tests
+# List of nodes (full fqdn) to skip in ALL tests
 # Use as env variable as
 # export skipped_nodes=mtr01.local,log02.local
 # TEMPORARY: please do not comment this setting.
@@ -29,6 +29,11 @@
 # TEMPORARY: please do not comment this setting.
 skipped_groups: [""]
 
+# Groups can be defined using pillars.
+# Uncomment this section to enable this.
+# Otherwise groups will be discovered automaticaly
+#groups: {cmp: 'nova:compute'}
+
 # mtu test setting
 # this test may skip groups (see example)
 test_mtu:
diff --git a/cvp_checks/tests/test_default_gateway.py b/cvp_checks/tests/test_default_gateway.py
index b6c74c2..cac5328 100644
--- a/cvp_checks/tests/test_default_gateway.py
+++ b/cvp_checks/tests/test_default_gateway.py
@@ -6,13 +6,11 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_check_default_gateways(local_salt_client, group):
-    if "skipped" in group:
-        pytest.skip("skipped in config")
     netstat_info = local_salt_client.cmd(
-        group, 'cmd.run', ['ip r | sed -n 1p'], expr_form='pcre')
+        "L@"+','.join(utils.node_groups[group]), 'cmd.run', ['ip r | sed -n 1p'], expr_form='compound')
 
     gateways = {}
     nodes = netstat_info.keys()
diff --git a/cvp_checks/tests/test_mtu.py b/cvp_checks/tests/test_mtu.py
index 8d76cef..53d9dba 100644
--- a/cvp_checks/tests/test_mtu.py
+++ b/cvp_checks/tests/test_mtu.py
@@ -6,18 +6,16 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_mtu(local_salt_client, group):
     testname = os.path.basename(__file__).split('.')[0]
-    if "skipped" in group:
-        pytest.skip("skipped in config")
     config = utils.get_configuration()
     skipped_ifaces = config.get(testname)["skipped_ifaces"] or \
         ["bonding_masters", "lo", "veth", "tap", "cali"]
     total = {}
     network_info = local_salt_client.cmd(
-        group, 'cmd.run', ['ls /sys/class/net/'], expr_form='pcre')
+        "L@"+','.join(utils.node_groups[group]), 'cmd.run', ['ls /sys/class/net/'], expr_form='compound')
 
     kvm_nodes = local_salt_client.cmd(
         'salt:control', 'test.ping', expr_form='pillar').keys()
diff --git a/cvp_checks/tests/test_packet_checker.py b/cvp_checks/tests/test_packet_checker.py
index 2556bcf..d85e87e 100644
--- a/cvp_checks/tests/test_packet_checker.py
+++ b/cvp_checks/tests/test_packet_checker.py
@@ -6,12 +6,10 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_check_package_versions(local_salt_client, group):
-    if "skipped" in group:
-        pytest.skip("skipped in config")
-    output = local_salt_client.cmd(group, 'lowpkg.list_pkgs', expr_form='pcre')
+    output = local_salt_client.cmd("L@"+','.join(utils.node_groups[group]), 'lowpkg.list_pkgs', expr_form='compound')
 
     if len(output.keys()) < 2:
         pytest.skip("Nothing to compare - only 1 node")
@@ -44,18 +42,16 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_check_module_versions(local_salt_client, group):
-    if "skipped" in group:
-        pytest.skip("skipped in config")
     pre_check = local_salt_client.cmd(
-        group, 'cmd.run', ['dpkg -l | grep "python-pip "'], expr_form='pcre')
+        "L@"+','.join(utils.node_groups[group]), 'cmd.run', ['dpkg -l | grep "python-pip "'], expr_form='compound')
     if pre_check.values().count('') > 0:
         pytest.skip("pip is not installed on one or more nodes")
     if len(pre_check.keys()) < 2:
         pytest.skip("Nothing to compare - only 1 node")
-    output = local_salt_client.cmd(group, 'pip.freeze', expr_form='pcre')
+    output = local_salt_client.cmd("L@"+','.join(utils.node_groups[group]), 'pip.freeze', expr_form='compound')
 
     nodes = []
     pkts_data = []
diff --git a/cvp_checks/tests/test_repo_list.py b/cvp_checks/tests/test_repo_list.py
index 07f16d0..c29bb7f 100644
--- a/cvp_checks/tests/test_repo_list.py
+++ b/cvp_checks/tests/test_repo_list.py
@@ -5,13 +5,13 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_list_of_repo_on_nodes(local_salt_client, group):
     if "skipped" in group:
         pytest.skip("skipped in config")
     info_salt = local_salt_client.cmd(
-        group, 'pillar.data', ['linux:system:repo'], expr_form='pcre')
+        "L@"+','.join(utils.node_groups[group]), 'pillar.data', ['linux:system:repo'], expr_form='compound')
 
     raw_actual_info = local_salt_client.cmd(
         group,
diff --git a/cvp_checks/tests/test_services.py b/cvp_checks/tests/test_services.py
index 7f04578..be0bc16 100644
--- a/cvp_checks/tests/test_services.py
+++ b/cvp_checks/tests/test_services.py
@@ -6,12 +6,10 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_check_services(local_salt_client, group):
-    if "skipped" in group:
-        pytest.skip("skipped in config")
-    output = local_salt_client.cmd(group, 'service.get_all', expr_form='pcre')
+    output = local_salt_client.cmd("L@"+','.join(utils.node_groups[group]), 'service.get_all', expr_form='compound')
 
     if len(output.keys()) < 2:
         pytest.skip("Nothing to compare - only 1 node")
diff --git a/cvp_checks/tests/test_single_vip.py b/cvp_checks/tests/test_single_vip.py
index 60d1894..d829a1a 100644
--- a/cvp_checks/tests/test_single_vip.py
+++ b/cvp_checks/tests/test_single_vip.py
@@ -6,12 +6,10 @@
 
 @pytest.mark.parametrize(
     "group",
-    utils.get_groups(os.path.basename(__file__))
+    utils.node_groups.keys()
 )
 def test_single_vip(local_salt_client, group):
-    if "skipped" in group:
-        pytest.skip("skipped in config")
-    local_salt_client.cmd(group, 'saltutil.sync_all', expr_form='pcre')
+    local_salt_client.cmd("L@"+','.join(utils.node_groups[group]), 'saltutil.sync_all', expr_form='compound')
     nodes_list = local_salt_client.cmd(
         group, 'grains.item', ['ipv4'], expr_form='pcre')
 
diff --git a/cvp_checks/utils/__init__.py b/cvp_checks/utils/__init__.py
index 35aa54e..746b5bf 100644
--- a/cvp_checks/utils/__init__.py
+++ b/cvp_checks/utils/__init__.py
@@ -28,6 +28,9 @@
             raise EnvironmentError("401 Not authorized.")
 
 
+node_groups = {}
+
+
 def init_salt_client():
     local = salt_remote()
     return local
@@ -71,37 +74,39 @@
     return nodes
 
 
-def get_groups(test):
+def calculate_groups():
     config = get_configuration()
-    testname = test.split('.')[0]
-    # assume that node name is like <name>.domain
-    # last 1-3 digits of name are index, e.g. 001 in cpu001
-    # name doesn't contain dots
-    active_nodes = get_active_nodes()
-
-    skipped_groups = config.get('skipped_groups') or []
-    if config.get(testname):
-        if 'skipped_groups' in config.get(testname).keys():
-            skipped_groups += config.get(testname)['skipped_groups'] or []
-
-    groups = []
-
-    for node in active_nodes:
-        index = re.search('[0-9]{1,3}$', node.split('.')[0])
-        if index:
-            group_name = node.split('.')[0][:-len(index.group(0))]
-        else:
-            group_name = node
-        if group_name not in groups:
-            if group_name not in skipped_groups:
-                groups.append(group_name)
+    local_salt_client = init_salt_client()
+    nodes_names = set ()
+    expr_form = ''
+    if 'groups' in config.keys():
+        nodes_names.update(config['groups'].keys())
+        expr_form = 'pillar'
+    else:
+        nodes = local_salt_client.cmd('*', 'test.ping')
+        for node in nodes:
+            index = re.search('[0-9]{1,3}$', node.split('.')[0])
+            if index:
+                nodes_names.add(node.split('.')[0][:-len(index.group(0))])
             else:
-                if group_name + " - skipped" not in groups:
-                    groups.append(group_name + " - skipped")
+                nodes_names.add(node)
+        expr_form = 'pcre'
 
-    return groups
-
-
+    for node_name in nodes_names:
+        skipped_groups = config.get('skipped_groups') or []
+        if node_name in skipped_groups:
+            continue
+        if expr_form == 'pcre':
+            nodes = local_salt_client.cmd(node_name,
+                                          'test.ping',
+                                          expr_form=expr_form)
+        else:
+            nodes = local_salt_client.cmd(config['groups'][node_name],
+                                          'test.ping',
+                                          expr_form=expr_form)
+        node_groups[node_name]=[x for x in nodes if x not in config['skipped_nodes']]
+                
+            
 def get_configuration():
     """function returns configuration for environment
     and for test if it's specified"""
@@ -119,3 +124,6 @@
                 global_config[param] = os.environ[param]
 
     return global_config
+
+
+calculate_groups()