You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2021/02/01 07:41:42 UTC

[ignite] branch ignite-ducktape updated: IGNITE-13895: SSL usage in ducktape tests (#8623)

This is an automated email from the ASF dual-hosted git repository.

nizhikov pushed a commit to branch ignite-ducktape
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/ignite-ducktape by this push:
     new c35850e  IGNITE-13895: SSL usage in ducktape tests (#8623)
c35850e is described below

commit c35850e30df5a22ab90877d1dd6aa4b341a72900
Author: Sergei Ryzhov <s....@gmail.com>
AuthorDate: Mon Feb 1 10:41:14 2021 +0300

    IGNITE-13895: SSL usage in ducktape tests (#8623)
---
 modules/ducktests/tests/certs/functions.sh         | 110 +++++++++++++++++++++
 .../utils/__init__.py => certs/mkcerts.sh}         |  24 ++++-
 .../tests/checks/utils/check_parametrized.py       |   9 +-
 modules/ducktests/tests/docker/run_tests.sh        |   2 +
 .../ducktests/tests/ignitetest/services/ignite.py  |   5 +
 .../tests/ignitetest/services/ignite_app.py        |   6 +-
 .../ignitetest/services/utils/control_utility.py   |  40 +++++++-
 .../ignitetest/services/utils/ignite_aware.py      |  26 +++++
 .../utils/ignite_configuration/__init__.py         |   4 +
 .../tests/ignitetest/services/utils/path.py        |   9 ++
 .../{utils => services/utils/ssl}/__init__.py      |   8 --
 .../utils/ssl/connector_configuration.py}          |  17 +++-
 .../ignitetest/services/utils/ssl/ssl_factory.py   |  45 +++++++++
 .../utils/templates/connector_configuration.j2     |  29 ++++++
 .../services/utils/templates/ignite.xml.j2         |  13 +++
 .../services/utils/templates/ssl_factory_macro.j2  |  25 +++++
 .../ignitetest/tests/cellular_affinity_test.py     |  10 +-
 .../tests/ignitetest/tests/client_test.py          |   2 +-
 .../tests/control_utility/baseline_test.py         |  12 +--
 .../ignitetest/tests/control_utility/tx_test.py    |   6 +-
 .../tests/ignitetest/tests/discovery_test.py       |   6 +-
 .../tests/ignitetest/tests/pme_free_switch_test.py |   7 +-
 .../ducktests/tests/ignitetest/tests/ssl_test.py   |  71 +++++++++++++
 .../ducktests/tests/ignitetest/utils/__init__.py   |   4 +-
 modules/ducktests/tests/ignitetest/utils/_mark.py  |  16 +--
 25 files changed, 449 insertions(+), 57 deletions(-)

diff --git a/modules/ducktests/tests/certs/functions.sh b/modules/ducktests/tests/certs/functions.sh
new file mode 100644
index 0000000..ffe07e0
--- /dev/null
+++ b/modules/ducktests/tests/certs/functions.sh
@@ -0,0 +1,110 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+function makeRoot() {
+    ALIAS=$1
+    DNAME=$2
+    PSWD=$3
+
+    if [[ ${ALIAS} == "" ]] || [[ ${DNAME} == "" ]] || [[ ${PSWD} == "" ]]
+    then
+        error "makeRoot: Need ALIAS, DNAME, PSWD"
+    fi
+
+    rm -f "${ALIAS}.jks"
+    rm -f "${ALIAS}.pem"
+
+    keytool -genkeypair -keystore "${ALIAS}.jks" -alias "${ALIAS}" -dname "${DNAME}" -ext bc:c -storepass "${PSWD}" \
+     -keypass "${PSWD}" -noprompt -v
+
+    keytool -keystore "${ALIAS}.jks" -storepass "${PSWD}" -keypass "${PSWD}" -alias "${ALIAS}" -exportcert \
+     -rfc -file "${ALIAS}.pem" -v
+}
+
+function makeCA() {
+    ROOT=$1
+    ALIAS=$2
+    DNAME=$3
+    PSWD=$4
+
+    if [[ "${ROOT}" == "" ]] || [[ "${ALIAS}" == "" ]] || [[ "${DNAME}" == "" ]] || [[ "${PSWD}" == "" ]]
+    then
+        error "makeCA: Need CA, ALIAS, DNAME, PSWD"
+    fi
+
+    rm -f "${ALIAS}.jks"
+    rm -f "${ALIAS}.pem"
+
+    keytool -genkeypair -keystore "${ALIAS}.jks" -alias "${ALIAS}" -dname "${DNAME}" -ext bc:c -storepass "${PSWD}" \
+     -keypass "${PSWD}" -noprompt -v
+
+    keytool -storepass "${PSWD}" -keypass "${PSWD}" -keystore "${ALIAS}.jks" -certreq -alias "${ALIAS}" \
+      | keytool -storepass "${PSWD}" -keypass "${PSWD}" -keystore "${ROOT}.jks" -gencert -alias "${ROOT}" \
+      -ext BC=0 -rfc -outfile "${ALIAS}.pem" -v
+
+    keytool -keystore "${ALIAS}.jks" -storepass "${PSWD}" -keypass "${PSWD}" -importcert -alias "${ROOT}" \
+    -file "${ROOT}.pem"  -noprompt -v
+    keytool -keystore "${ALIAS}.jks" -storepass "${PSWD}" -keypass "${PSWD}" -importcert -alias "${ALIAS}" \
+    -file "${ALIAS}.pem" -noprompt -v
+}
+
+function mkCert() {
+    CA=$1
+    ALIAS=$2
+    DNAME=$3
+    PSWD=$4
+
+    if [[ ${CA} == "" ]] || [[ ${ALIAS} == "" ]] || [[ ${DNAME} == "" ]] || [[ ${PSWD} == "" ]]
+    then
+        error "mkCert: Need CA, ALIAS, DNAME, PSWD"
+    fi
+
+    rm -f "${ALIAS}.jks"
+    rm -f "${ALIAS}.pem"
+    rm -f "${ALIAS}.csr"
+
+    keytool -genkeypair -keystore "${ALIAS}.jks" -alias "${ALIAS}" -dname "${DNAME}" -keyalg RSA -keysize 2048 \
+     -keypass "${PSWD}" -storepass "${PSWD}" -noprompt -v || error
+
+    keytool -storepass "${PSWD}" -keystore "${ALIAS}.jks" -certreq -alias "${ALIAS}" -file "${ALIAS}.csr" -v || error
+
+    keytool -gencert -infile "${ALIAS}.csr" -keystore "${CA}.jks" -alias "${CA}" -storepass "${PSWD}" -rfc \
+     -outfile "${ALIAS}.pem" -v || error
+
+    keytool -keystore "${ALIAS}.jks" -importcert -alias "${ALIAS}" -storepass "${PSWD}" -file "${ALIAS}.pem" \
+     -noprompt -v || error
+
+    rm -f "${ALIAS}.csr"
+    rm -f "${ALIAS}.pem"
+}
+
+function makeTruststore() {
+    rm -f truststore.jks
+
+    # shellcheck disable=SC2068
+    for cert in $@ ; do
+      keytool -keystore truststore.jks -importcert -alias "${cert}" -storepass 123456 -file "${cert}.pem" \
+       -noprompt -v || error
+
+    done
+}
+
+function error() {
+    # shellcheck disable=SC2145
+    echo "¯\_(ツ)_/¯ Something went wrong: $@"
+    exit 1
+}
diff --git a/modules/ducktests/tests/ignitetest/utils/__init__.py b/modules/ducktests/tests/certs/mkcerts.sh
old mode 100644
new mode 100755
similarity index 67%
copy from modules/ducktests/tests/ignitetest/utils/__init__.py
copy to modules/ducktests/tests/certs/mkcerts.sh
index a400779..222f3d7
--- a/modules/ducktests/tests/ignitetest/utils/__init__.py
+++ b/modules/ducktests/tests/certs/mkcerts.sh
@@ -1,3 +1,5 @@
+#!/usr/bin/env bash
+
 # Licensed to the Apache Software Foundation (ASF) under one or more
 # contributor license agreements.  See the NOTICE file distributed with
 # this work for additional information regarding copyright ownership.
@@ -13,10 +15,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-This module contains convenient utils for test.
-"""
+CERTS_DIR="$(dirname "$0")"
+
+cd "${CERTS_DIR}" || exit 1
+
+source ./functions.sh
+
+PSWD=123456
+
+makeRoot root "CN=Ignite Root" "${PSWD}"
+
+makeCA root ca "CN=Ignite CA" "${PSWD}"
+
+makeTruststore root ca
 
-from ._mark import version_if, ignite_versions, cluster
+mkCert ca server "CN=Ignite Server" "${PSWD}"
+mkCert ca client "CN=Ignite Client" "${PSWD}"
+mkCert ca admin "CN=Ignite Admin" "${PSWD}"
 
-__all__ = ['version_if', 'ignite_versions', 'cluster']
+cd - || exit 1
diff --git a/modules/ducktests/tests/checks/utils/check_parametrized.py b/modules/ducktests/tests/checks/utils/check_parametrized.py
index 5eddb3f..dd87907a 100644
--- a/modules/ducktests/tests/checks/utils/check_parametrized.py
+++ b/modules/ducktests/tests/checks/utils/check_parametrized.py
@@ -23,8 +23,9 @@ from unittest.mock import Mock
 import pytest
 from ducktape.mark import parametrized, parametrize, matrix, ignore
 from ducktape.mark.mark_expander import MarkedFunctionExpander
+from ignitetest.utils import ignite_versions, ignore_if
 
-from ignitetest.utils._mark import IgniteVersionParametrize, ignite_versions, version_if
+from ignitetest.utils._mark import IgniteVersionParametrize
 from ignitetest.utils.version import IgniteVersion, V_2_8_0, V_2_8_1, V_2_7_6, DEV_BRANCH
 
 
@@ -213,13 +214,13 @@ class CheckVersionIf:
         """
         Check common scenarios with @ignite_versions parametrization.
         """
-        @version_if(lambda ver: ver != V_2_8_0, variable_name='ver')
+        @ignore_if(lambda version, globals: version == V_2_8_0, variable_name='ver')
         @ignite_versions(str(DEV_BRANCH), str(V_2_8_0), version_prefix='ver')
         def function_1(ver):
             return IgniteVersion(ver)
 
-        @version_if(lambda ver: ver > V_2_7_6, variable_name='ver_1')
-        @version_if(lambda ver: ver < V_2_8_0, variable_name='ver_2')
+        @ignore_if(lambda ver, globals: ver == V_2_7_6, variable_name='ver_1')
+        @ignore_if(lambda ver, globals: ver >= V_2_8_0, variable_name='ver_2')
         @ignite_versions((str(V_2_8_1), str(V_2_8_0)), (str(V_2_8_0), str(V_2_7_6)), version_prefix='ver')
         def function_2(ver_1, ver_2):
             return IgniteVersion(ver_1), IgniteVersion(ver_2)
diff --git a/modules/ducktests/tests/docker/run_tests.sh b/modules/ducktests/tests/docker/run_tests.sh
index 5facd8a..6ff723c 100755
--- a/modules/ducktests/tests/docker/run_tests.sh
+++ b/modules/ducktests/tests/docker/run_tests.sh
@@ -167,5 +167,7 @@ if [[ -n "$MAX_PARALLEL" ]]; then
   DUCKTAPE_OPTIONS="$DUCKTAPE_OPTIONS --max-parallel $MAX_PARALLEL"
 fi
 
+"$SCRIPT_DIR"/../certs/mkcerts.sh
+
 "$SCRIPT_DIR"/ducker-ignite test "$TC_PATHS" "$DUCKTAPE_OPTIONS" \
   || die "ducker-ignite test failed"
diff --git a/modules/ducktests/tests/ignitetest/services/ignite.py b/modules/ducktests/tests/ignitetest/services/ignite.py
index 483ef2c..059b249 100644
--- a/modules/ducktests/tests/ignitetest/services/ignite.py
+++ b/modules/ducktests/tests/ignitetest/services/ignite.py
@@ -24,6 +24,7 @@ from datetime import datetime
 from ducktape.cluster.remoteaccount import RemoteCommandError
 
 from ignitetest.services.utils.ignite_aware import IgniteAwareService
+from ignitetest.services.utils.ssl.ssl_factory import DEFAULT_SERVER_KEYSTORE
 
 
 class IgniteService(IgniteAwareService):
@@ -61,6 +62,10 @@ class IgniteService(IgniteAwareService):
         except (RemoteCommandError, ValueError):
             return []
 
+    def update_config_with_globals(self):
+        if self.globals.get("use_ssl", False):
+            self._update_ssl_config_with_globals("server", DEFAULT_SERVER_KEYSTORE)
+
 
 def node_failed_event_pattern(failed_node_id=None):
     """Failed node pattern in log."""
diff --git a/modules/ducktests/tests/ignitetest/services/ignite_app.py b/modules/ducktests/tests/ignitetest/services/ignite_app.py
index 277724b..7414afc 100644
--- a/modules/ducktests/tests/ignitetest/services/ignite_app.py
+++ b/modules/ducktests/tests/ignitetest/services/ignite_app.py
@@ -16,7 +16,6 @@
 """
 This module contains the base class to build Ignite aware application written on java.
 """
-
 import re
 
 # pylint: disable=W0622
@@ -24,6 +23,7 @@ from ducktape.errors import TimeoutError
 
 from ignitetest.services.ignite_execution_exception import IgniteExecutionException
 from ignitetest.services.utils.ignite_aware import IgniteAwareService
+from ignitetest.services.utils.ssl.ssl_factory import DEFAULT_CLIENT_KEYSTORE
 
 
 class IgniteApplicationService(IgniteAwareService):
@@ -107,3 +107,7 @@ class IgniteApplicationService(IgniteAwareService):
                 res.append(re.search("%s(.*)%s" % (name + "->", "<-"), line).group(1))
 
         return res
+
+    def update_config_with_globals(self):
+        if self.globals.get("use_ssl", False):
+            self._update_ssl_config_with_globals("client", DEFAULT_CLIENT_KEYSTORE)
diff --git a/modules/ducktests/tests/ignitetest/services/utils/control_utility.py b/modules/ducktests/tests/ignitetest/services/utils/control_utility.py
index 9b1a9ea..9f04b96 100644
--- a/modules/ducktests/tests/ignitetest/services/utils/control_utility.py
+++ b/modules/ducktests/tests/ignitetest/services/utils/control_utility.py
@@ -16,7 +16,7 @@
 """
 This module contains control utility wrapper.
 """
-
+import os
 import random
 import re
 import time
@@ -24,6 +24,8 @@ from typing import NamedTuple
 
 from ducktape.cluster.remoteaccount import RemoteCommandError
 
+from ignitetest.services.utils.ssl.ssl_factory import DEFAULT_PASSWORD, DEFAULT_TRUSTSTORE, DEFAULT_ADMIN_KEYSTORE
+
 
 class ControlUtility:
     """
@@ -31,9 +33,34 @@ class ControlUtility:
     """
     BASE_COMMAND = "control.sh"
 
-    def __init__(self, cluster, text_context):
+    # pylint: disable=R0913
+    def __init__(self, cluster,
+                 key_store_jks: str = None, key_store_password: str = DEFAULT_PASSWORD,
+                 trust_store_jks: str = DEFAULT_TRUSTSTORE, trust_store_password: str = DEFAULT_PASSWORD):
         self._cluster = cluster
-        self.logger = text_context.logger
+        self.logger = cluster.context.logger
+
+        if cluster.context.globals.get("use_ssl", False):
+            admin_dict = cluster.globals.get("admin", dict())
+
+            self.key_store_path = admin_dict.get("key_store_path",
+                                                 self.jks_path(admin_dict.get('key_store_jks', DEFAULT_ADMIN_KEYSTORE)))
+            self.key_store_password = admin_dict.get('key_store_password', DEFAULT_PASSWORD)
+            self.trust_store_path = admin_dict.get("trust_store_path",
+                                                   self.jks_path(admin_dict.get('trust_store_jks', DEFAULT_TRUSTSTORE)))
+            self.trust_store_password = admin_dict.get('trust_store_password', DEFAULT_PASSWORD)
+
+        elif key_store_jks is not None:
+            self.key_store_path = self.jks_path(key_store_jks)
+            self.key_store_password = key_store_password
+            self.trust_store_path = self.jks_path(trust_store_jks)
+            self.trust_store_password = trust_store_password
+
+    def jks_path(self, jks_name: str):
+        """
+        :return Path to jks file.
+        """
+        return os.path.join(self._cluster.certificate_dir, jks_name)
 
     def baseline(self):
         """
@@ -264,7 +291,12 @@ class ControlUtility:
         return output
 
     def __form_cmd(self, node, cmd):
-        return self._cluster.script(f"{self.BASE_COMMAND} --host {node.account.externally_routable_ip} {cmd}")
+        ssl = ""
+        if hasattr(self, 'key_store_path'):
+            ssl = f" --keystore {self.key_store_path} --keystore-password {self.key_store_password} " \
+                  f"--truststore {self.trust_store_path} --truststore-password {self.trust_store_password}"
+
+        return self._cluster.script(f"{self.BASE_COMMAND} --host {node.account.externally_routable_ip} {cmd} {ssl}")
 
     @staticmethod
     def __parse_output(raw_output):
diff --git a/modules/ducktests/tests/ignitetest/services/utils/ignite_aware.py b/modules/ducktests/tests/ignitetest/services/utils/ignite_aware.py
index d1a3a38..bc275ce 100644
--- a/modules/ducktests/tests/ignitetest/services/utils/ignite_aware.py
+++ b/modules/ducktests/tests/ignitetest/services/utils/ignite_aware.py
@@ -38,6 +38,10 @@ from ignitetest.utils.enum import constructible
 
 
 # pylint: disable=too-many-public-methods
+from ignitetest.services.utils.ssl.connector_configuration import ConnectorConfiguration
+from ignitetest.services.utils.ssl.ssl_factory import SslContextFactory
+
+
 class IgniteAwareService(BackgroundThreadService, IgnitePathAware, metaclass=ABCMeta):
     """
     The base class to build services aware of Ignite.
@@ -88,12 +92,19 @@ class IgniteAwareService(BackgroundThreadService, IgnitePathAware, metaclass=ABC
         """
         Starts in async way.
         """
+        self.update_config_with_globals()
         super().start(**kwargs)
 
     def start(self, **kwargs):
         self.start_async(**kwargs)
         self.await_started()
 
+    @abstractmethod
+    def update_config_with_globals(self):
+        """
+        Update configuration with global parameters.
+        """
+
     def await_started(self):
         """
         Awaits start finished.
@@ -404,3 +415,18 @@ class IgniteAwareService(BackgroundThreadService, IgnitePathAware, metaclass=ABC
             rotated_log = os.path.join(self.log_dir, f"console.log.{cnt}")
             self.logger.debug(f"rotating {node.log_file} to {rotated_log} on {node.name}")
             node.account.ssh(f"mv {node.log_file} {rotated_log}")
+
+    def _update_ssl_config_with_globals(self, dict_name: str, default_jks: str):
+        """
+        Update ssl configuration.
+        """
+        _dict = self.globals.get(dict_name)
+
+        if _dict is not None:
+            ssl_context_factory = SslContextFactory(self.install_root, **_dict)
+        else:
+            ssl_context_factory = SslContextFactory(self.install_root, default_jks)
+
+        self.config = self.config._replace(ssl_context_factory=ssl_context_factory)
+        self.config = self.config._replace(connector_configuration=ConnectorConfiguration(
+            ssl_enabled=True, ssl_context_factory=ssl_context_factory))
diff --git a/modules/ducktests/tests/ignitetest/services/utils/ignite_configuration/__init__.py b/modules/ducktests/tests/ignitetest/services/utils/ignite_configuration/__init__.py
index fbf3cd6..7799288 100644
--- a/modules/ducktests/tests/ignitetest/services/utils/ignite_configuration/__init__.py
+++ b/modules/ducktests/tests/ignitetest/services/utils/ignite_configuration/__init__.py
@@ -20,8 +20,10 @@ This module contains IgniteConfiguration classes and utilities.
 from typing import NamedTuple
 
 from ignitetest.services.utils.ignite_configuration.communication import CommunicationSpi, TcpCommunicationSpi
+from ignitetest.services.utils.ssl.connector_configuration import ConnectorConfiguration
 from ignitetest.services.utils.ignite_configuration.data_storage import DataStorageConfiguration
 from ignitetest.services.utils.ignite_configuration.discovery import DiscoverySpi, TcpDiscoverySpi
+from ignitetest.services.utils.ssl.ssl_factory import SslContextFactory
 from ignitetest.utils.version import IgniteVersion, DEV_BRANCH
 
 
@@ -41,6 +43,8 @@ class IgniteConfiguration(NamedTuple):
     data_storage: DataStorageConfiguration = None
     caches: list = []
     local_host: str = None
+    ssl_context_factory: SslContextFactory = None
+    connector_configuration: ConnectorConfiguration = None
 
 
 class IgniteClientConfiguration(IgniteConfiguration):
diff --git a/modules/ducktests/tests/ignitetest/services/utils/path.py b/modules/ducktests/tests/ignitetest/services/utils/path.py
index 9cab69d..7747568 100644
--- a/modules/ducktests/tests/ignitetest/services/utils/path.py
+++ b/modules/ducktests/tests/ignitetest/services/utils/path.py
@@ -21,6 +21,7 @@ import os
 from abc import abstractmethod, ABCMeta
 
 from ignitetest.services.utils.config_template import IgniteLoggerConfigTemplate
+from ignitetest.utils.version import DEV_BRANCH
 
 
 def get_home_dir(install_root, project, version):
@@ -165,6 +166,14 @@ class IgnitePathAware(PathAware, metaclass=ABCMeta):
     def log_config_file(self):
         return os.path.join(self.persistent_root, "ignite-log4j.xml")
 
+    @property
+    def certificate_dir(self):
+        """
+        :return: path to the certificate directory.
+        """
+        return os.path.join(get_home_dir(self.install_root, self.project, DEV_BRANCH),
+                            "modules", "ducktests", "tests", "certs")
+
     def script(self, script_name):
         """
         :param script_name: name of Ignite script
diff --git a/modules/ducktests/tests/ignitetest/utils/__init__.py b/modules/ducktests/tests/ignitetest/services/utils/ssl/__init__.py
similarity index 82%
copy from modules/ducktests/tests/ignitetest/utils/__init__.py
copy to modules/ducktests/tests/ignitetest/services/utils/ssl/__init__.py
index a400779..ec20143 100644
--- a/modules/ducktests/tests/ignitetest/utils/__init__.py
+++ b/modules/ducktests/tests/ignitetest/services/utils/ssl/__init__.py
@@ -12,11 +12,3 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-"""
-This module contains convenient utils for test.
-"""
-
-from ._mark import version_if, ignite_versions, cluster
-
-__all__ = ['version_if', 'ignite_versions', 'cluster']
diff --git a/modules/ducktests/tests/ignitetest/utils/__init__.py b/modules/ducktests/tests/ignitetest/services/utils/ssl/connector_configuration.py
similarity index 63%
copy from modules/ducktests/tests/ignitetest/utils/__init__.py
copy to modules/ducktests/tests/ignitetest/services/utils/ssl/connector_configuration.py
index a400779..4d75b78 100644
--- a/modules/ducktests/tests/ignitetest/utils/__init__.py
+++ b/modules/ducktests/tests/ignitetest/services/utils/ssl/connector_configuration.py
@@ -11,12 +11,21 @@
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
-# limitations under the License.
+# limitations under the License
 
 """
-This module contains convenient utils for test.
+This module contains classes and utilities for Ignite ConnectorConfiguration.
 """
 
-from ._mark import version_if, ignite_versions, cluster
+from typing import NamedTuple
 
-__all__ = ['version_if', 'ignite_versions', 'cluster']
+from ignitetest.services.utils.ssl.ssl_factory import SslContextFactory
+
+
+class ConnectorConfiguration(NamedTuple):
+    """
+    Ignite ConnectorConfiguration.
+    Used to connect from ControlUtility (control.sh).
+    """
+    ssl_enabled: bool = False
+    ssl_context_factory: SslContextFactory = None
diff --git a/modules/ducktests/tests/ignitetest/services/utils/ssl/ssl_factory.py b/modules/ducktests/tests/ignitetest/services/utils/ssl/ssl_factory.py
new file mode 100644
index 0000000..51468aa
--- /dev/null
+++ b/modules/ducktests/tests/ignitetest/services/utils/ssl/ssl_factory.py
@@ -0,0 +1,45 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+
+"""
+This module contains classes and utilities for SslContextFactory.
+"""
+import os
+
+DEFAULT_PASSWORD = "123456"
+DEFAULT_SERVER_KEYSTORE = "server.jks"
+DEFAULT_CLIENT_KEYSTORE = "client.jks"
+DEFAULT_ADMIN_KEYSTORE = "admin.jks"
+DEFAULT_TRUSTSTORE = "truststore.jks"
+
+
+class SslContextFactory:
+    """
+    Ignite SslContextFactory.
+    """
+
+    # pylint: disable=R0913
+    def __init__(self, root_dir: str = "/opt",
+                 key_store_jks: str = DEFAULT_SERVER_KEYSTORE, key_store_password: str = DEFAULT_PASSWORD,
+                 trust_store_jks: str = DEFAULT_TRUSTSTORE, trust_store_password: str = DEFAULT_PASSWORD,
+                 key_store_path: str = None, trust_store_path: str = None):
+        certificate_dir = os.path.join(root_dir, "ignite-dev", "modules", "ducktests", "tests", "certs")
+
+        self.key_store_path = key_store_path if key_store_path is not None \
+            else os.path.join(certificate_dir, key_store_jks)
+        self.key_store_password = key_store_password
+        self.trust_store_path = trust_store_path if trust_store_path is not None \
+            else os.path.join(certificate_dir, trust_store_jks)
+        self.trust_store_password = trust_store_password
diff --git a/modules/ducktests/tests/ignitetest/services/utils/templates/connector_configuration.j2 b/modules/ducktests/tests/ignitetest/services/utils/templates/connector_configuration.j2
new file mode 100644
index 0000000..7a43f99
--- /dev/null
+++ b/modules/ducktests/tests/ignitetest/services/utils/templates/connector_configuration.j2
@@ -0,0 +1,29 @@
+{#
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+#}
+
+{% import 'ssl_factory_macro.j2' as ssl_factory_util %}
+
+{% macro connector_configuration(config) %}
+        <bean class="org.apache.ignite.configuration.ConnectorConfiguration">
+                <property name="sslEnabled" value="{{ config.ssl_enabled }}"/>
+                {% if config.ssl_enabled %}
+                <property name="sslFactory">
+                    {{ ssl_factory_util.ssl_factory(config.ssl_context_factory) }}
+                </property>
+                {% endif %}
+        </bean>
+{% endmacro %}
diff --git a/modules/ducktests/tests/ignitetest/services/utils/templates/ignite.xml.j2 b/modules/ducktests/tests/ignitetest/services/utils/templates/ignite.xml.j2
index cfed0a7..8bbff0f 100644
--- a/modules/ducktests/tests/ignitetest/services/utils/templates/ignite.xml.j2
+++ b/modules/ducktests/tests/ignitetest/services/utils/templates/ignite.xml.j2
@@ -22,6 +22,8 @@
 {% import 'cache_macro.j2' as cache_utils %}
 {% import 'datastorage_macro.j2' as datastorage_utils %}
 {% import 'misc_macro.j2' as misc_utils %}
+{% import 'ssl_factory_macro.j2' as ssl_factory_util %}
+{% import 'connector_configuration.j2' as connector_configuration_util %}
 
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -57,5 +59,16 @@
         {% if config.properties %}
             {{ config.properties }}
         {% endif %}
+
+        {% if config.ssl_context_factory %}
+            <property name="sslContextFactory">
+                {{ ssl_factory_util.ssl_factory(config.ssl_context_factory) }}
+            </property>
+        {% endif %}
+        {% if config.connector_configuration %}
+            <property name="connectorConfiguration">
+                {{ connector_configuration_util.connector_configuration(config.connector_configuration) }}
+            </property>
+        {% endif %}
     </bean>
 </beans>
diff --git a/modules/ducktests/tests/ignitetest/services/utils/templates/ssl_factory_macro.j2 b/modules/ducktests/tests/ignitetest/services/utils/templates/ssl_factory_macro.j2
new file mode 100644
index 0000000..2f8878c
--- /dev/null
+++ b/modules/ducktests/tests/ignitetest/services/utils/templates/ssl_factory_macro.j2
@@ -0,0 +1,25 @@
+{#
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+#}
+
+{% macro ssl_factory(factory) %}
+<bean class="org.apache.ignite.ssl.SslContextFactory">
+    <property name="keyStoreFilePath" value="{{ factory.key_store_path }}"/>
+    <property name="keyStorePassword" value="{{ factory.key_store_password }}"/>
+    <property name="trustStoreFilePath" value="{{ factory.trust_store_path }}"/>
+    <property name="trustStorePassword" value="{{ factory.trust_store_password }}"/>
+</bean>
+{% endmacro %}
diff --git a/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py b/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py
index e6541fa..a8aa393 100644
--- a/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py
+++ b/modules/ducktests/tests/ignitetest/tests/cellular_affinity_test.py
@@ -29,7 +29,7 @@ from ignitetest.services.utils.ignite_configuration import IgniteConfiguration,
 from ignitetest.services.utils.ignite_configuration.discovery import from_ignite_cluster, from_zookeeper_cluster, \
     TcpDiscoverySpi
 from ignitetest.services.zk.zookeeper import ZookeeperSettings, ZookeeperService
-from ignitetest.utils import ignite_versions, version_if, cluster
+from ignitetest.utils import ignite_versions, cluster, ignore_if
 from ignitetest.utils.enum import constructible
 from ignitetest.utils.ignite_test import IgniteTest
 from ignitetest.utils.version import DEV_BRANCH, IgniteVersion, LATEST_2_8
@@ -104,7 +104,7 @@ class CellularAffinity(IgniteTest):
             cacheName=CellularAffinity.CACHE_NAME)
 
     @cluster(num_nodes=NODES_PER_CELL * 3 + 1)
-    @version_if(lambda version: version >= DEV_BRANCH)
+    @ignore_if(lambda version, globals: version < DEV_BRANCH)
     @ignite_versions(str(DEV_BRANCH))
     def test_distribution(self, ignite_version):
         """
@@ -121,7 +121,7 @@ class CellularAffinity(IgniteTest):
         for cell in [cell1, cell2, cell3]:
             cell.await_started()
 
-        ControlUtility(cell1, self.test_context).activate()
+        ControlUtility(cell1).activate()
 
         checker = IgniteApplicationService(
             self.test_context,
@@ -203,8 +203,8 @@ class CellularAffinity(IgniteTest):
         for streamer in streamers:
             streamer.await_started()
 
-        ControlUtility(cell0, self.test_context).disable_baseline_auto_adjust()  # baseline set.
-        ControlUtility(cell0, self.test_context).activate()
+        ControlUtility(cell0).disable_baseline_auto_adjust()  # baseline set.
+        ControlUtility(cell0).activate()
 
         for loader in loaders:
             loader.await_event("ALL_TRANSACTIONS_PREPARED", 180, from_the_beginning=True)
diff --git a/modules/ducktests/tests/ignitetest/tests/client_test.py b/modules/ducktests/tests/ignitetest/tests/client_test.py
index 28b1213..fa5cf44 100644
--- a/modules/ducktests/tests/ignitetest/tests/client_test.py
+++ b/modules/ducktests/tests/ignitetest/tests/client_test.py
@@ -91,7 +91,7 @@ class ClientTest(IgniteTest):
 
         ignite = IgniteService(self.test_context, server_cfg, num_nodes=servers_count)
 
-        control_utility = ControlUtility(ignite, self.test_context)
+        control_utility = ControlUtility(ignite)
 
         client_cfg = server_cfg._replace(client_mode=True)
 
diff --git a/modules/ducktests/tests/ignitetest/tests/control_utility/baseline_test.py b/modules/ducktests/tests/ignitetest/tests/control_utility/baseline_test.py
index 8951006..281c91f 100644
--- a/modules/ducktests/tests/ignitetest/tests/control_utility/baseline_test.py
+++ b/modules/ducktests/tests/ignitetest/tests/control_utility/baseline_test.py
@@ -24,7 +24,7 @@ from ignitetest.services.utils.control_utility import ControlUtility, ControlUti
 from ignitetest.services.utils.ignite_configuration import IgniteConfiguration, DataStorageConfiguration
 from ignitetest.services.utils.ignite_configuration.data_storage import DataRegionConfiguration
 from ignitetest.services.utils.ignite_configuration.discovery import from_ignite_cluster
-from ignitetest.utils import version_if, ignite_versions, cluster
+from ignitetest.utils import ignore_if, ignite_versions, cluster
 from ignitetest.utils.ignite_test import IgniteTest
 from ignitetest.utils.version import DEV_BRANCH, LATEST, IgniteVersion, V_2_8_0
 
@@ -45,7 +45,7 @@ class BaselineTests(IgniteTest):
         blt_size = self.NUM_NODES - 2
         servers = self.__start_ignite_nodes(ignite_version, blt_size)
 
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
         control_utility.activate()
 
         # Check baseline of activated cluster.
@@ -81,7 +81,7 @@ class BaselineTests(IgniteTest):
         blt_size = self.NUM_NODES - 1
         servers = self.__start_ignite_nodes(ignite_version, blt_size)
 
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
 
         control_utility.activate()
 
@@ -122,7 +122,7 @@ class BaselineTests(IgniteTest):
         """
         servers = self.__start_ignite_nodes(ignite_version, self.NUM_NODES)
 
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
 
         control_utility.activate()
 
@@ -137,7 +137,7 @@ class BaselineTests(IgniteTest):
         assert state.lower() == 'inactive', 'Unexpected state %s' % state
 
     @cluster(num_nodes=NUM_NODES)
-    @version_if(lambda version: version >= V_2_8_0)
+    @ignore_if(lambda version, globals: version < V_2_8_0)
     @ignite_versions(str(DEV_BRANCH), str(LATEST))
     def test_baseline_autoadjust(self, ignite_version):
         """
@@ -146,7 +146,7 @@ class BaselineTests(IgniteTest):
         blt_size = self.NUM_NODES - 2
         servers = self.__start_ignite_nodes(ignite_version, blt_size)
 
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
         control_utility.activate()
 
         # Add node.
diff --git a/modules/ducktests/tests/ignitetest/tests/control_utility/tx_test.py b/modules/ducktests/tests/ignitetest/tests/control_utility/tx_test.py
index bc059e5..2e962b9 100644
--- a/modules/ducktests/tests/ignitetest/tests/control_utility/tx_test.py
+++ b/modules/ducktests/tests/ignitetest/tests/control_utility/tx_test.py
@@ -52,7 +52,7 @@ class TransactionsTests(IgniteTest):
 
         wait_for_key_locked(long_tx)
 
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
 
         transactions = control_utility.tx()
 
@@ -83,7 +83,7 @@ class TransactionsTests(IgniteTest):
 
         wait_for_key_locked(long_tx_1, long_tx_2)
 
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
 
         # check kill with specific xid.
         transactions = control_utility.tx(label_pattern='TX_1')
@@ -115,7 +115,7 @@ class TransactionsTests(IgniteTest):
                                       wait_for_topology_version=4)
 
         wait_for_key_locked(clients, servers)
-        control_utility = ControlUtility(servers, self.test_context)
+        control_utility = ControlUtility(servers)
 
         start_check = self.monotonic()
         assert len(control_utility.tx(clients=True, label_pattern='LBL_.*')) == client_tx_count
diff --git a/modules/ducktests/tests/ignitetest/tests/discovery_test.py b/modules/ducktests/tests/ignitetest/tests/discovery_test.py
index 6ce08a0..17bfdc4 100644
--- a/modules/ducktests/tests/ignitetest/tests/discovery_test.py
+++ b/modules/ducktests/tests/ignitetest/tests/discovery_test.py
@@ -34,7 +34,7 @@ from ignitetest.services.utils.ignite_configuration.discovery import from_zookee
     TcpDiscoverySpi
 from ignitetest.services.utils.time_utils import epoch_mills
 from ignitetest.services.zk.zookeeper import ZookeeperService, ZookeeperSettings
-from ignitetest.utils import ignite_versions, version_if, cluster
+from ignitetest.utils import ignite_versions, ignore_if, cluster
 from ignitetest.utils.ignite_test import IgniteTest
 from ignitetest.utils.version import DEV_BRANCH, LATEST, LATEST_2_7, V_2_8_0, V_2_9_0, IgniteVersion
 from ignitetest.utils.enum import constructible
@@ -123,7 +123,7 @@ class DiscoveryTest(IgniteTest):
         return self._perform_node_fail_scenario(test_config)
 
     @cluster(num_nodes=MAX_CONTAINERS)
-    @version_if(lambda version: version != V_2_8_0)  # ignite-zookeeper package is broken in 2.8.0
+    @ignore_if(lambda version, globals: version == V_2_8_0)  # ignite-zookeeper package is broken in 2.8.0
     @ignite_versions(str(DEV_BRANCH), str(LATEST))
     @matrix(nodes_to_kill=[1, 2], failure_detection_timeout=[FAILURE_TIMEOUT],
             load_type=[ClusterLoad.NONE, ClusterLoad.ATOMIC, ClusterLoad.TRANSACTIONAL])
@@ -138,7 +138,7 @@ class DiscoveryTest(IgniteTest):
         return self._perform_node_fail_scenario(test_config)
 
     @cluster(num_nodes=MAX_CONTAINERS)
-    @version_if(lambda version: version != V_2_8_0)  # ignite-zookeeper package is broken in 2.8.0
+    @ignore_if(lambda version, globals: version == V_2_8_0)  # ignite-zookeeper package is broken in 2.8.0
     @ignite_versions(str(DEV_BRANCH), str(LATEST))
     @matrix(load_type=[ClusterLoad.NONE, ClusterLoad.ATOMIC, ClusterLoad.TRANSACTIONAL],
             failure_detection_timeout=[FAILURE_TIMEOUT])
diff --git a/modules/ducktests/tests/ignitetest/tests/pme_free_switch_test.py b/modules/ducktests/tests/ignitetest/tests/pme_free_switch_test.py
index 08a43bf..2109490 100644
--- a/modules/ducktests/tests/ignitetest/tests/pme_free_switch_test.py
+++ b/modules/ducktests/tests/ignitetest/tests/pme_free_switch_test.py
@@ -28,7 +28,7 @@ from ignitetest.services.utils.control_utility import ControlUtility
 from ignitetest.services.utils.ignite_configuration import IgniteConfiguration
 from ignitetest.services.utils.ignite_configuration.cache import CacheConfiguration
 from ignitetest.services.utils.ignite_configuration.discovery import from_ignite_cluster
-from ignitetest.utils import ignite_versions, cluster
+from ignitetest.utils import ignite_versions, cluster, ignore_if
 from ignitetest.utils.enum import constructible
 from ignitetest.utils.ignite_test import IgniteTest
 from ignitetest.utils.version import DEV_BRANCH, LATEST_2_7, V_2_8_0, IgniteVersion
@@ -54,6 +54,7 @@ class PmeFreeSwitchTest(IgniteTest):
     EXTRA_CACHES_AMOUNT = 100
 
     @cluster(num_nodes=NUM_NODES + 2)
+    @ignore_if(lambda version, globals: version <= V_2_8_0 or not globals.get("use_ssl"))
     @ignite_versions(str(DEV_BRANCH), str(LATEST_2_7))
     @matrix(load_type=[LoadType.NONE, LoadType.EXTRA_CACHES, LoadType.LONG_TXS])
     def test(self, ignite_version, load_type):
@@ -84,9 +85,9 @@ class PmeFreeSwitchTest(IgniteTest):
         ignites.start()
 
         if IgniteVersion(ignite_version) >= V_2_8_0:
-            ControlUtility(ignites, self.test_context).disable_baseline_auto_adjust()
+            ControlUtility(ignites).disable_baseline_auto_adjust()
 
-        ControlUtility(ignites, self.test_context).activate()
+        ControlUtility(ignites).activate()
 
         client_config = config._replace(client_mode=True,
                                         discovery_spi=from_ignite_cluster(ignites, slice(0, num_nodes - 1)))
diff --git a/modules/ducktests/tests/ignitetest/tests/ssl_test.py b/modules/ducktests/tests/ignitetest/tests/ssl_test.py
new file mode 100644
index 0000000..4df3180
--- /dev/null
+++ b/modules/ducktests/tests/ignitetest/tests/ssl_test.py
@@ -0,0 +1,71 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+This module contains ssl tests.
+"""
+from ignitetest.services.ignite import IgniteService
+from ignitetest.services.ignite_app import IgniteApplicationService
+from ignitetest.services.utils.control_utility import ControlUtility
+from ignitetest.services.utils.ignite_configuration import IgniteConfiguration
+from ignitetest.services.utils.ssl.connector_configuration import ConnectorConfiguration
+from ignitetest.services.utils.ssl.ssl_factory import SslContextFactory
+from ignitetest.utils import ignite_versions, cluster
+from ignitetest.utils.ignite_test import IgniteTest
+from ignitetest.utils.version import IgniteVersion, DEV_BRANCH, LATEST_2_9, LATEST_2_8
+
+
+# pylint: disable=W0223
+class SslTest(IgniteTest):
+    """
+    Ssl test.
+    """
+    @cluster(num_nodes=3)
+    @ignite_versions(str(DEV_BRANCH), str(LATEST_2_9), str(LATEST_2_8))
+    def test_ssl_connection(self, ignite_version):
+        """
+        Test that IgniteService, IgniteApplicationService correctly start and stop with ssl configurations.
+        And check ControlUtility with ssl arguments.
+        """
+        root_dir = self.test_context.globals.get("install_root", "/opt")
+
+        server_ssl = SslContextFactory(root_dir=root_dir)
+
+        server_configuration = IgniteConfiguration(
+            version=IgniteVersion(ignite_version), ssl_context_factory=server_ssl,
+            connector_configuration=ConnectorConfiguration(ssl_enabled=True, ssl_context_factory=server_ssl))
+
+        ignite = IgniteService(self.test_context, server_configuration, num_nodes=2,
+                               startup_timeout_sec=180)
+
+        client_configuration = server_configuration._replace(
+            client_mode=True,
+            ssl_context_factory=SslContextFactory(root_dir, key_store_jks="client.jks"))
+
+        app = IgniteApplicationService(
+            self.test_context,
+            client_configuration,
+            java_class_name="org.apache.ignite.internal.ducktest.tests.smoke_test.SimpleApplication",
+            startup_timeout_sec=180)
+
+        control_utility = ControlUtility(cluster=ignite, key_store_jks="admin.jks")
+
+        ignite.start()
+        app.start()
+
+        control_utility.cluster_state()
+
+        app.stop()
+        ignite.stop()
diff --git a/modules/ducktests/tests/ignitetest/utils/__init__.py b/modules/ducktests/tests/ignitetest/utils/__init__.py
index a400779..6d6da0d 100644
--- a/modules/ducktests/tests/ignitetest/utils/__init__.py
+++ b/modules/ducktests/tests/ignitetest/utils/__init__.py
@@ -17,6 +17,6 @@
 This module contains convenient utils for test.
 """
 
-from ._mark import version_if, ignite_versions, cluster
+from ._mark import ignore_if, ignite_versions, cluster
 
-__all__ = ['version_if', 'ignite_versions', 'cluster']
+__all__ = ['ignore_if', 'ignite_versions', 'cluster']
diff --git a/modules/ducktests/tests/ignitetest/utils/_mark.py b/modules/ducktests/tests/ignitetest/utils/_mark.py
index d6d0bdb..69bb685 100644
--- a/modules/ducktests/tests/ignitetest/utils/_mark.py
+++ b/modules/ducktests/tests/ignitetest/utils/_mark.py
@@ -26,9 +26,9 @@ from ducktape.mark._mark import Ignore, Mark, _inject
 from ignitetest.utils.version import IgniteVersion
 
 
-class VersionIf(Ignore):
+class IgnoreIf(Ignore):
     """
-    Ignore test if version doesn't corresponds to condition.
+    Ignore test if version or global parameters correspond to condition.
     """
     def __init__(self, condition, variable_name):
         super().__init__()
@@ -36,13 +36,13 @@ class VersionIf(Ignore):
         self.variable_name = variable_name
 
     def apply(self, seed_context, context_list):
-        assert len(context_list) > 0, "ignore_if decorator is not being applied to any test cases"
+        assert len(context_list) > 0, "ignore if decorator is not being applied to any test cases"
 
         for ctx in context_list:
             if self.variable_name in ctx.injected_args:
                 version = ctx.injected_args[self.variable_name]
                 assert isinstance(version, str), "'%s'n injected args must be a string" % (self.variable_name,)
-                ctx.ignore = ctx.ignore or not self.condition(IgniteVersion(version))
+                ctx.ignore = ctx.ignore or self.condition(IgniteVersion(version), ctx.globals)
 
         return context_list
 
@@ -192,15 +192,15 @@ def ignite_versions(*args, version_prefix="ignite_version"):
     return parametrizer
 
 
-def version_if(condition, *, variable_name='ignite_version'):
+def ignore_if(condition, *, variable_name='ignite_version'):
     """
-    Mark decorated test method as IGNORE if version doesn't corresponds to condition.
+    Mark decorated test method as IGNORE if version or global parameters correspond to condition.
 
-    :param condition: function(IgniteVersion) -> bool
+    :param condition: function(IgniteVersion, Globals) -> bool
     :param variable_name: version variable name
     """
     def ignorer(func):
-        Mark.mark(func, VersionIf(condition, variable_name))
+        Mark.mark(func, IgnoreIf(condition, variable_name))
         return func
 
     return ignorer