diff --git a/test_set/cvp-spt/utils/__init__.py b/test_set/cvp-spt/utils/__init__.py
new file mode 100644
index 0000000..36cf239
--- /dev/null
+++ b/test_set/cvp-spt/utils/__init__.py
@@ -0,0 +1,111 @@
+import os
+import yaml
+import requests
+import re
+import sys, traceback
+import itertools
+import helpers
+from utils import os_client
+
+
+class salt_remote:
+    def cmd(self, tgt, fun, param=None, expr_form=None, tgt_type=None):
+        config = get_configuration()
+        url = config['SALT_URL']
+        proxies = {"http": None, "https": None}
+        headers = {'Accept': 'application/json'}
+        login_payload = {'username': config['SALT_USERNAME'],
+                         'password': config['SALT_PASSWORD'], 'eauth': 'pam'}
+        accept_key_payload = {'fun': fun, 'tgt': tgt, 'client': 'local',
+                              'expr_form': expr_form, 'tgt_type': tgt_type,
+                              'timeout': config['salt_timeout']}
+        if param:
+            accept_key_payload['arg'] = param
+
+        try:
+            login_request = requests.post(os.path.join(url, 'login'),
+                                          headers=headers, data=login_payload,
+                                          proxies=proxies)
+            if login_request.ok:
+                request = requests.post(url, headers=headers,
+                                        data=accept_key_payload,
+                                        cookies=login_request.cookies,
+                                        proxies=proxies)
+                return request.json()['return'][0]
+        except Exception:
+            print "\033[91m\nConnection to SaltMaster " \
+                  "was not established.\n" \
+                  "Please make sure that you " \
+                  "provided correct credentials.\033[0m\n"
+            traceback.print_exc(file=sys.stdout)
+            sys.exit()
+
+
+def init_salt_client():
+    local = salt_remote()
+    return local
+
+
+def compile_pairs (nodes):
+    result = {}
+    if len(nodes) %2 != 0:
+        nodes.pop(1)
+    pairs = zip(*[iter(nodes)]*2)
+    for pair in pairs:
+        result[pair[0]+'<>'+pair[1]] = pair
+    return result
+
+
+def get_pairs():
+    # TODO
+    # maybe collect cmp from nova service-list
+    config = get_configuration()
+    local_salt_client = init_salt_client()
+    cmp_hosts = config.get('CMP_HOSTS') or []
+    skipped_nodes = config.get('skipped_nodes') or []
+    if skipped_nodes:
+        print "Notice: {0} nodes will be skipped for vm2vm test".format(skipped_nodes)
+    if not cmp_hosts:
+        nodes = local_salt_client.cmd(
+                'I@nova:compute',
+                'test.ping',
+                expr_form='compound')
+        cmp_hosts = [node.split('.')[0] for node in nodes.keys() if node not in skipped_nodes]
+    return compile_pairs(cmp_hosts)
+
+
+def get_hw_pairs():
+    config = get_configuration()
+    local_salt_client = init_salt_client()
+    hw_nodes = config.get('HW_NODES') or []
+    skipped_nodes = config.get('skipped_nodes') or []
+    if skipped_nodes:
+        print "Notice: {0} nodes will be skipped for hw2hw test".format(skipped_nodes)
+    if not hw_nodes:
+        nodes = local_salt_client.cmd(
+                'I@salt:control or I@nova:compute',
+                'test.ping',
+                expr_form='compound')
+        hw_nodes = [node for node in nodes.keys() if node not in skipped_nodes]
+    print local_salt_client.cmd(expr_form='compound', tgt="L@"+','.join(hw_nodes),
+                                fun='pkg.install', param=['iperf'])
+    return compile_pairs(hw_nodes)
+
+def get_configuration():
+    """function returns configuration for environment
+    and for test if it's specified"""
+
+    global_config_file = os.path.join(
+        os.path.dirname(os.path.abspath(__file__)), "../global_config.yaml")
+    with open(global_config_file, 'r') as file:
+        global_config = yaml.load(file)
+    for param in global_config.keys():
+        if param in os.environ.keys():
+            if ',' in os.environ[param]:
+                global_config[param] = []
+                for item in os.environ[param].split(','):
+                    global_config[param].append(item)
+            else:
+                global_config[param] = os.environ[param]
+
+    return global_config
diff --git a/test_set/cvp-spt/utils/helpers.py b/test_set/cvp-spt/utils/helpers.py
new file mode 100644
index 0000000..97a3bae
--- /dev/null
+++ b/test_set/cvp-spt/utils/helpers.py
@@ -0,0 +1,79 @@
+import texttable as tt
+
+class helpers(object):
+    def __init__ (self, local_salt_client):
+        self.local_salt_client = local_salt_client
+
+    def start_iperf_between_hosts(self, global_results, node_i, node_j, ip_i, ip_j, net_name):
+        result = []
+        direct_raw_results = self.start_iperf_client(node_i, ip_j)
+        result.append(direct_raw_results)
+        print "1 forward"
+        forward = "1 thread:\n"
+        forward += direct_raw_results + " Gbits/sec"
+
+        direct_raw_results = self.start_iperf_client(node_i, ip_j, 10)
+        result.append(direct_raw_results)
+        print "10 forward"
+        forward += "\n\n10 thread:\n"
+        forward += direct_raw_results + " Gbits/sec"
+
+        reverse_raw_results = self.start_iperf_client(node_j, ip_i)
+        result.append(reverse_raw_results)
+        print "1 backward"
+        backward = "1 thread:\n"
+        backward += reverse_raw_results + " Gbits/sec"
+
+        reverse_raw_results = self.start_iperf_client(node_j, ip_i, 10)
+        result.append(reverse_raw_results)
+        print "10 backward"
+        backward += "\n\n10 thread:\n"
+        backward += reverse_raw_results + " Gbits/sec"
+        global_results.append([node_i, node_j,
+                               net_name, forward, backward])
+
+        self.kill_iperf_processes(node_i)
+        self.kill_iperf_processes(node_j)
+        return result
+
+    def draw_table_with_results(self, global_results):
+        tab = tt.Texttable()
+        header = [
+            'node name 1',
+            'node name 2',
+            'network',
+            'bandwidth >',
+            'bandwidth <',
+        ]
+        tab.set_cols_align(['l', 'l', 'l', 'l', 'l'])
+        tab.set_cols_width([27, 27, 15, 20, '20'])
+        tab.header(header)
+        for row in global_results:
+            tab.add_row(row)
+        s = tab.draw()
+        print s
+
+    def start_iperf_client(self, minion_name, target_ip, thread_count=None):
+        iperf_command = 'timeout --kill-after=20 19 iperf -c {0}'.format(target_ip)
+        if thread_count:
+            iperf_command += ' -P {0}'.format(thread_count)
+        output = self.local_salt_client.cmd(tgt=minion_name,
+                                            fun='cmd.run',
+                                            param=[iperf_command])
+        # self.kill_iperf_processes(minion_name)
+        try:
+            result = output.values()[0].split('\n')[-1].split(' ')[-2:]
+            if result[1] == 'Mbits/sec':
+                return str(float(result[0])*0.001)
+            if result[1] != 'Gbits/sec':
+                return "0"
+            return result[0]
+        except:
+            print "No iperf result between {} and {} (maybe they don't have connectivity)".format(minion_name, target_ip)
+
+
+    def kill_iperf_processes(self, minion_name):
+        kill_command = "for pid in $(pgrep  iperf); do kill $pid; done"
+        output = self.local_salt_client.cmd(tgt=minion_name,
+                                            fun='cmd.run',
+                                            param=[kill_command])
diff --git a/test_set/cvp-spt/utils/os_client.py b/test_set/cvp-spt/utils/os_client.py
new file mode 100644
index 0000000..fb84265
--- /dev/null
+++ b/test_set/cvp-spt/utils/os_client.py
@@ -0,0 +1,399 @@
+from cinderclient import client as cinder_client
+from glanceclient import client as glance_client
+from keystoneauth1 import identity as keystone_identity
+from keystoneauth1 import session as keystone_session
+from keystoneclient.v3 import client as keystone_client
+from neutronclient.v2_0 import client as neutron_client
+from novaclient import client as novaclient
+
+import os
+import random
+import time
+import utils
+
+class OfficialClientManager(object):
+    """Manager that provides access to the official python clients for
+    calling various OpenStack APIs.
+    """
+
+    CINDERCLIENT_VERSION = 3
+    GLANCECLIENT_VERSION = 2
+    KEYSTONECLIENT_VERSION = 3
+    NEUTRONCLIENT_VERSION = 2
+    NOVACLIENT_VERSION = 2
+    INTERFACE = 'admin'
+    if "OS_ENDPOINT_TYPE" in os.environ.keys():
+        INTERFACE = os.environ["OS_ENDPOINT_TYPE"]
+
+    def __init__(self, username=None, password=None,
+                 tenant_name=None, auth_url=None, endpoint_type="internalURL",
+                 cert=False, domain="Default", **kwargs):
+        self.traceback = ""
+
+        self.client_attr_names = [
+            "auth",
+            "compute",
+            "network",
+            "volume",
+            "image",
+        ]
+        self.username = username
+        self.password = password
+        self.tenant_name = tenant_name
+        self.project_name = tenant_name
+        self.auth_url = auth_url
+        self.endpoint_type = endpoint_type
+        self.cert = cert
+        self.domain = domain
+        self.kwargs = kwargs
+
+        # Lazy clients
+        self._auth = None
+        self._compute = None
+        self._network = None
+        self._volume = None
+        self._image = None
+
+    @classmethod
+    def _get_auth_session(cls, username=None, password=None,
+                          tenant_name=None, auth_url=None, cert=None,
+                          domain='Default'):
+        if None in (username, password, tenant_name):
+            print(username, password, tenant_name)
+            msg = ("Missing required credentials for identity client. "
+                   "username: {username}, password: {password}, "
+                   "tenant_name: {tenant_name}").format(
+                       username=username,
+                       password=password,
+                       tenant_name=tenant_name, )
+            raise msg
+
+        if cert and "https" not in auth_url:
+            auth_url = auth_url.replace("http", "https")
+
+        if cls.KEYSTONECLIENT_VERSION == (2, 0):
+            # auth_url = "{}{}".format(auth_url, "v2.0/")
+            auth = keystone_identity.v2.Password(
+                username=username,
+                password=password,
+                auth_url=auth_url,
+                tenant_name=tenant_name)
+        else:
+            auth_url = "{}{}".format(auth_url, "/v3")
+            auth = keystone_identity.v3.Password(
+                auth_url=auth_url,
+                user_domain_name=domain,
+                username=username,
+                password=password,
+                project_domain_name=domain,
+                project_name=tenant_name)
+
+        auth_session = keystone_session.Session(auth=auth, verify=cert)
+        # auth_session.get_auth_headers()
+        return auth_session
+
+    @classmethod
+    def get_auth_client(cls, username=None, password=None,
+                        tenant_name=None, auth_url=None, cert=None,
+                        domain='Default', **kwargs):
+        session = cls._get_auth_session(
+            username=username,
+            password=password,
+            tenant_name=tenant_name,
+            auth_url=auth_url,
+            cert=cert,
+            domain=domain)
+        keystone = keystone_client.Client(version=cls.KEYSTONECLIENT_VERSION,
+                                          session=session, **kwargs)
+        keystone.management_url = auth_url
+        return keystone
+
+    @classmethod
+    def get_compute_client(cls, username=None, password=None,
+                           tenant_name=None, auth_url=None, cert=None,
+                           domain='Default', **kwargs):
+        session = cls._get_auth_session(
+            username=username, password=password, tenant_name=tenant_name,
+            auth_url=auth_url, cert=cert, domain=domain)
+        service_type = 'compute'
+        compute_client = novaclient.Client(
+            version=cls.NOVACLIENT_VERSION, session=session,
+            service_type=service_type, os_cache=False, **kwargs)
+        return compute_client
+
+    @classmethod
+    def get_network_client(cls, username=None, password=None,
+                           tenant_name=None, auth_url=None, cert=None,
+                           domain='Default', **kwargs):
+        session = cls._get_auth_session(
+            username=username, password=password, tenant_name=tenant_name,
+            auth_url=auth_url, cert=cert, domain=domain)
+        service_type = 'network'
+        return neutron_client.Client(
+            service_type=service_type, session=session, interface=cls.INTERFACE, **kwargs)
+
+    @classmethod
+    def get_volume_client(cls, username=None, password=None,
+                          tenant_name=None, auth_url=None, cert=None,
+                          domain='Default', **kwargs):
+        session = cls._get_auth_session(
+            username=username, password=password, tenant_name=tenant_name,
+            auth_url=auth_url, cert=cert, domain=domain)
+        service_type = 'volume'
+        return cinder_client.Client(
+            version=cls.CINDERCLIENT_VERSION,
+            service_type=service_type,
+            interface=cls.INTERFACE,
+            session=session, **kwargs)
+
+    @classmethod
+    def get_image_client(cls, username=None, password=None,
+                         tenant_name=None, auth_url=None, cert=None,
+                         domain='Default', **kwargs):
+        session = cls._get_auth_session(
+            username=username, password=password, tenant_name=tenant_name,
+            auth_url=auth_url, cert=cert, domain=domain)
+        service_type = 'image'
+        return glance_client.Client(
+            version=cls.GLANCECLIENT_VERSION,
+            service_type=service_type,
+            session=session, interface=cls.INTERFACE,
+            **kwargs)
+
+    @property
+    def auth(self):
+        if self._auth is None:
+            self._auth = self.get_auth_client(
+                self.username, self.password, self.tenant_name, self.auth_url,
+                self.cert, self.domain, endpoint_type=self.endpoint_type
+            )
+        return self._auth
+
+    @property
+    def compute(self):
+        if self._compute is None:
+            self._compute = self.get_compute_client(
+                self.username, self.password, self.tenant_name, self.auth_url,
+                self.cert, self.domain, endpoint_type=self.endpoint_type
+            )
+        return self._compute
+
+    @property
+    def network(self):
+        if self._network is None:
+            self._network = self.get_network_client(
+                self.username, self.password, self.tenant_name, self.auth_url,
+                self.cert, self.domain, endpoint_type=self.endpoint_type
+            )
+        return self._network
+
+    @property
+    def volume(self):
+        if self._volume is None:
+            self._volume = self.get_volume_client(
+                self.username, self.password, self.tenant_name, self.auth_url,
+                self.cert, self.domain, endpoint_type=self.endpoint_type
+            )
+        return self._volume
+
+    @property
+    def image(self):
+        if self._image is None:
+            self._image = self.get_image_client(
+                self.username, self.password, self.tenant_name, self.auth_url,
+                self.cert, self.domain
+            )
+        return self._image
+
+
+class OSCliActions(object):
+    def __init__(self, os_clients):
+        self.os_clients = os_clients
+
+    def get_admin_tenant(self):
+        # TODO Keystone v3 doesnt have tenants attribute
+        return self.os_clients.auth.projects.find(name="admin")
+
+    # TODO: refactor
+    def get_cirros_image(self):
+        images_list = list(self.os_clients.image.images.list(name='TestVM'))
+        if images_list:
+            image = images_list[0]
+        else:
+            image = self.os_clients.image.images.create(
+                name="TestVM",
+                disk_format='qcow2',
+                container_format='bare')
+            with file_cache.get_file(settings.CIRROS_QCOW2_URL) as f:
+                self.os_clients.image.images.upload(image.id, f)
+        return image
+
+    def get_internal_network(self):
+        networks = [
+            net for net in self.os_clients.network.list_networks()["networks"]
+            if net["admin_state_up"] and not net["router:external"] and
+            len(net["subnets"])
+        ]
+        if networks:
+            net = networks[0]
+        else:
+            net = self.create_network_resources()
+        return net
+
+    def get_external_network(self):
+        config = utils.get_configuration()
+        ext_net = config.get('external_network') or ''
+        if not ext_net:
+            networks = [
+                net for net in self.os_clients.network.list_networks()["networks"]
+                if net["admin_state_up"] and net["router:external"] and
+                len(net["subnets"])
+            ]
+            if networks:
+                ext_net = networks[0]
+            else:
+                ext_net = self.create_fake_external_network()
+        return ext_net
+
+    def create_flavor(self, name, ram=256, vcpus=1, disk=2):
+        return self.os_clients.compute.flavors.create(name, ram, vcpus, disk)
+
+    def create_sec_group(self, rulesets=None):
+        if rulesets is None:
+            rulesets = [
+                {
+                    # ssh
+                    'ip_protocol': 'tcp',
+                    'from_port': 22,
+                    'to_port': 22,
+                    'cidr': '0.0.0.0/0',
+                },
+                {
+                    # iperf
+                    'ip_protocol': 'tcp',
+                    'from_port':5001,
+                    'to_port': 5001,
+                    'cidr': '0.0.0.0/0',
+                },
+                {
+                    # ping
+                    'ip_protocol': 'icmp',
+                    'from_port': -1,
+                    'to_port': -1,
+                    'cidr': '0.0.0.0/0',
+                }
+            ]
+        sg_name = "spt-test-secgroup-{}".format(random.randrange(100, 999))
+        sg_desc = sg_name + " SPT"
+        secgroup = self.os_clients.compute.security_groups.create(
+            sg_name, sg_desc)
+        for ruleset in rulesets:
+            self.os_clients.compute.security_group_rules.create(
+                secgroup.id, **ruleset)
+        return secgroup
+
+
+    def wait(predicate, interval=5, timeout=60, timeout_msg="Waiting timed out"):
+        start_time = time.time()
+        if not timeout:
+            return predicate()
+        while not predicate():
+            if start_time + timeout < time.time():
+                raise exceptions.TimeoutError(timeout_msg)
+
+            seconds_to_sleep = max(
+                0,
+                min(interval, start_time + timeout - time.time()))
+            time.sleep(seconds_to_sleep)
+
+        return timeout + start_time - time.time()
+
+    def create_basic_server(self, image=None, flavor=None, net=None,
+                            availability_zone=None, sec_groups=(),
+                            keypair=None,
+                            wait_timeout=3 * 60):
+        os_conn = self.os_clients
+        image = image or self.get_cirros_image()
+        flavor = flavor or self.get_micro_flavor()
+        net = net or self.get_internal_network()
+        kwargs = {}
+        if sec_groups:
+            kwargs['security_groups'] = sec_groups
+        server = os_conn.compute.servers.create(
+            "spt-test-server-{}".format(random.randrange(100, 999)),
+            image, flavor, nics=[{"net-id": net["id"]}],
+            availability_zone=availability_zone, key_name=keypair, **kwargs)
+        # TODO
+        #if wait_timeout:
+        #    self.wait(
+        #        lambda: os_conn.compute.servers.get(server).status == "ACTIVE",
+        #        timeout=wait_timeout,
+        #        timeout_msg=(
+        #            "Create server {!r} failed by timeout. "
+        #            "Please, take a look at OpenStack logs".format(server.id)))
+        return server
+
+    def create_network(self, tenant_id):
+        net_name = "spt-test-net-{}".format(random.randrange(100, 999))
+        net_body = {
+            'network': {
+                'name': net_name,
+                'tenant_id': tenant_id
+            }
+        }
+        net = self.os_clients.network.create_network(net_body)['network']
+        return net
+        #yield net
+        #self.os_clients.network.delete_network(net['id'])
+
+    def create_subnet(self, net, tenant_id, cidr=None):
+        subnet_name = "spt-test-subnet-{}".format(random.randrange(100, 999))
+        subnet_body = {
+            'subnet': {
+                "name": subnet_name,
+                'network_id': net['id'],
+                'ip_version': 4,
+                'cidr': cidr if cidr else '10.1.7.0/24',
+                'tenant_id': tenant_id
+            }
+        }
+        subnet = self.os_clients.network.create_subnet(subnet_body)['subnet']
+        return subnet
+        #yield subnet
+        #self.os_clients.network.delete_subnet(subnet['id'])
+
+    def create_router(self, ext_net, tenant_id):
+        name = 'spt-test-router-{}'.format(random.randrange(100, 999))
+        router_body = {
+            'router': {
+                'name': name,
+                'external_gateway_info': {
+                    'network_id': ext_net['id']
+                },
+                'tenant_id': tenant_id
+            }
+        }
+        router = self.os_clients.network.create_router(router_body)['router']
+        return router
+        #yield router
+        #self.os_clients.network.delete_router(router['id'])
+
+    def create_network_resources(self):
+        tenant_id = self.get_admin_tenant().id
+        ext_net = self.get_external_network()
+        net = self.create_network(tenant_id)
+        subnet = self.create_subnet(net, tenant_id)
+        #router = self.create_router(ext_net, tenant_id)
+        #self.os_clients.network.add_interface_router(
+        #    router['id'], {'subnet_id': subnet['id']})
+
+        private_net_id = net['id']
+        # floating_ip_pool = ext_net['id']
+
+        return net
+        #yield private_net_id, floating_ip_pool
+        #yield private_net_id
+        #
+        #self.os_clients.network.remove_interface_router(
+        #     router['id'], {'subnet_id': subnet['id']})
+        #self.os_clients.network.remove_gateway_router(router['id'])
diff --git a/test_set/cvp-spt/utils/ssh.py b/test_set/cvp-spt/utils/ssh.py
new file mode 100644
index 0000000..66551eb
--- /dev/null
+++ b/test_set/cvp-spt/utils/ssh.py
@@ -0,0 +1,140 @@
+import cStringIO
+import logging
+import select
+import utils
+import paramiko
+
+
+logger = logging.getLogger(__name__)
+
+# Suppress paramiko logging
+logging.getLogger("paramiko").setLevel(logging.WARNING)
+
+
+class SSHTransport(object):
+    def __init__(self, address, username, password=None,
+                 private_key=None, look_for_keys=False, *args, **kwargs):
+
+        self.address = address
+        self.username = username
+        self.password = password
+        if private_key is not None:
+            self.private_key = paramiko.RSAKey.from_private_key(
+                cStringIO.StringIO(private_key))
+        else:
+            self.private_key = None
+
+        self.look_for_keys = look_for_keys
+        self.buf_size = 1024
+        self.channel_timeout = 10.0
+
+    def _get_ssh_connection(self):
+        ssh = paramiko.SSHClient()
+        ssh.set_missing_host_key_policy(
+            paramiko.AutoAddPolicy())
+        ssh.connect(self.address, username=self.username,
+                    password=self.password, pkey=self.private_key,
+                    timeout=self.channel_timeout)
+        logger.debug("Successfully connected to: {0}".format(self.address))
+        return ssh
+
+    def _get_sftp_connection(self):
+        transport = paramiko.Transport((self.address, 22))
+        transport.connect(username=self.username,
+                          password=self.password,
+                          pkey=self.private_key)
+
+        return paramiko.SFTPClient.from_transport(transport)
+
+    def exec_sync(self, cmd):
+        logger.debug("Executing {0} on host {1}".format(cmd, self.address))
+        ssh = self._get_ssh_connection()
+        transport = ssh.get_transport()
+        channel = transport.open_session()
+        channel.fileno()
+        channel.exec_command(cmd)
+        channel.shutdown_write()
+        out_data = []
+        err_data = []
+        poll = select.poll()
+        poll.register(channel, select.POLLIN)
+
+        while True:
+            ready = poll.poll(self.channel_timeout)
+            if not any(ready):
+                continue
+            if not ready[0]:
+                continue
+            out_chunk = err_chunk = None
+            if channel.recv_ready():
+                out_chunk = channel.recv(self.buf_size)
+                out_data += out_chunk,
+            if channel.recv_stderr_ready():
+                err_chunk = channel.recv_stderr(self.buf_size)
+                err_data += err_chunk,
+            if channel.closed and not err_chunk and not out_chunk:
+                break
+        exit_status = channel.recv_exit_status()
+        logger.debug("Command {0} executed with status: {1}"
+                     .format(cmd, exit_status))
+        return (
+            exit_status, ''.join(out_data).strip(), ''.join(err_data).strip())
+
+    def exec_command(self, cmd):
+        exit_status, stdout, stderr = self.exec_sync(cmd)
+        return stdout
+
+    def check_call(self, command, error_info=None, expected=None,
+                   raise_on_err=True):
+        """Execute command and check for return code
+        :type command: str
+        :type error_info: str
+        :type expected: list
+        :type raise_on_err: bool
+        :rtype: ExecResult
+        :raises: DevopsCalledProcessError
+        """
+        if expected is None:
+            expected = [0]
+        ret = self.exec_sync(command)
+        exit_code, stdout_str, stderr_str = ret
+        if exit_code not in expected:
+            message = (
+                "{append}Command '{cmd}' returned exit code {code} while "
+                "expected {expected}\n"
+                "\tSTDOUT:\n"
+                "{stdout}"
+                "\n\tSTDERR:\n"
+                "{stderr}".format(
+                    append=error_info + '\n' if error_info else '',
+                    cmd=command,
+                    code=exit_code,
+                    expected=expected,
+                    stdout=stdout_str,
+                    stderr=stderr_str
+                ))
+            logger.error(message)
+            if raise_on_err:
+                exit()
+        return ret
+
+    def put_file(self, source_path, destination_path):
+        sftp = self._get_sftp_connection()
+        sftp.put(source_path, destination_path)
+        sftp.close()
+
+    def get_file(self, source_path, destination_path):
+        sftp = self._get_sftp_connection()
+        sftp.get(source_path, destination_path)
+        sftp.close()
+
+
+class prepare_iperf(object):
+
+    def __init__(self,fip,user='ubuntu',password='password', private_key=None):
+        transport = SSHTransport(fip, user, password, private_key)
+        config = utils.get_configuration()
+        preparation_cmd = config.get('iperf_prep_string') or ['']
+        transport.exec_command(preparation_cmd)
+        transport.exec_command('sudo apt-get update; sudo apt-get install -y iperf')
+        transport.exec_command('nohup iperf -s > file 2>&1 &') 
