summaryrefslogtreecommitdiffstats
path: root/kernel/security/integrity/Kconfig
blob: 73c457bf5a4aea01eb56b36613ee69f929428765 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#
config INTEGRITY
	bool "Integrity subsystem"
	depends on SECURITY
	default y
	help
	  This option enables the integrity subsystem, which is comprised
	  of a number of different components including the Integrity
	  Measurement Architecture (IMA), Extended Verification Module
	  (EVM), IMA-appraisal extension, digital signature verification
	  extension and audit measurement log support.

	  Each of these components can be enabled/disabled separately.
	  Refer to the individual components for additional details.

if INTEGRITY

config INTEGRITY_SIGNATURE
	bool "Digital signature verification using multiple keyrings"
	depends on KEYS
	default n
	select SIGNATURE
	help
	  This option enables digital signature verification support
	  using multiple keyrings. It defines separate keyrings for each
	  of the different use cases - evm, ima, and modules.
	  Different keyrings improves search performance, but also allow
	  to "lock" certain keyring to prevent adding new keys.
	  This is useful for evm and module keyrings, when keys are
	  usually only added from initramfs.

config INTEGRITY_ASYMMETRIC_KEYS
	bool "Enable asymmetric keys support"
	depends on INTEGRITY_SIGNATURE
	default n
        select ASYMMETRIC_KEY_TYPE
        select ASYMMETRIC_PUBLIC_KEY_SUBTYPE
        select PUBLIC_KEY_ALGO_RSA
        select X509_CERTIFICATE_PARSER
	help
	  This option enables digital signature verification using
	  asymmetric keys.

config INTEGRITY_AUDIT
	bool "Enables integrity auditing support "
	depends on AUDIT
	default y
	help
	  In addition to enabling integrity auditing support, this
	  option adds a kernel parameter 'integrity_audit', which
	  controls the level of integrity auditing messages.
	  0 - basic integrity auditing messages (default)
	  1 - additional integrity auditing messages

	  Additional informational integrity auditing messages would
	  be enabled by specifying 'integrity_audit=1' on the kernel
	  command line.

source security/integrity/ima/Kconfig
source security/integrity/evm/Kconfig

endif   # if INTEGRITY
Comment.Hashbang */ .highlight .cm { color: #75715e } /* Comment.Multiline */ .highlight .cp { color: #75715e } /* Comment.Preproc */ .highlight .cpf { color: #75715e } /* Comment.PreprocFile */ .highlight .c1 { color: #75715e } /* Comment.Single */ .highlight .cs { color: #75715e } /* Comment.Special */ .highlight .gd { color: #f92672 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gi { color: #a6e22e } /* Generic.Inserted */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #75715e } /* Generic.Subheading */ .highlight .kc { color: #66d9ef } /* Keyword.Constant */ .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ .highlight .kn { color: #f92672 } /* Keyword.Namespace */ .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ .highlight .kt { color: #66d9ef } /* Keyword.Type */ .highlight .ld { color: #e6db74 } /* Literal.Date */ .highlight .m { color: #ae81ff } /* Literal.Number */ .highlight .s { color: #e6db74 } /* Literal.String */ .highlight .na { color: #a6e22e } /* Name.Attribute */ .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ .highlight .nc { color: #a6e22e } /* Name.Class */ .highlight .no { color: #66d9ef } /* Name.Constant */ .highlight .nd { color: #a6e22e } /* Name.Decorator */ .highlight .ni { color: #f8f8f2 } /* Name.Entity */ .highlight .ne { color: #a6e22e } /* Name.Exception */ .highlight .nf { color: #a6e22e } /* Name.Function */ .highlight .nl { color: #f8f8f2 } /* Name.Label */ .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ .highlight .nx { color: #a6e22e } /* Name.Other */ .highlight .py { color: #f8f8f2 } /* Name.Property */ .highlight .nt { color: #f92672 } /* Name.Tag */ .highlight .nv { color: #f8f8f2 } /* Name.Variable */ .highlight .ow { color: #f92672 } /* Operator.Word */ .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ .highlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
#!/usr/bin/python
#
# Copyright (c) 2015 All rights reserved
# This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
import ConfigParser
import os
import re
import shutil
import subprocess

from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
import functest.utils.openstack_utils as os_utils


IMAGE_ID_ALT = None
FLAVOR_ID_ALT = None
REPO_PATH = CONST.dir_repo_functest
GLANCE_IMAGE_PATH = os.path.join(CONST.dir_functest_data,
                                 CONST.openstack_image_file_name)
TEMPEST_TEST_LIST_DIR = CONST.dir_tempest_cases
TEMPEST_RESULTS_DIR = os.path.join(CONST.dir_results,
                                   'tempest')
TEMPEST_CUSTOM = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
                              'test_list.txt')
TEMPEST_BLACKLIST = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
                                 'blacklist.txt')
TEMPEST_DEFCORE = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
                               'defcore_req.txt')
TEMPEST_RAW_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_raw_list.txt')
TEMPEST_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_list.txt')
REFSTACK_RESULTS_DIR = os.path.join(CONST.dir_results,
                                    'refstack')

CI_INSTALLER_TYPE = CONST.INSTALLER_TYPE
CI_INSTALLER_IP = CONST.INSTALLER_IP

""" logging configuration """
logger = ft_logger.Logger("Tempest").getLogger()


def create_tempest_resources(use_custom_images=False,
                             use_custom_flavors=False):
    keystone_client = os_utils.get_keystone_client()

    logger.debug("Creating tenant and user for Tempest suite")
    tenant_id = os_utils.create_tenant(
        keystone_client,
        CONST.tempest_identity_tenant_name,
        CONST.tempest_identity_tenant_description)
    if not tenant_id:
        logger.error("Failed to create %s tenant"
                     % CONST.tempest_identity_tenant_name)

    user_id = os_utils.create_user(keystone_client,
                                   CONST.tempest_identity_user_name,
                                   CONST.tempest_identity_user_password,
                                   None, tenant_id)
    if not user_id:
        logger.error("Failed to create %s user" %
                     CONST.tempest_identity_user_name)

    logger.debug("Creating private network for Tempest suite")
    network_dic = os_utils.create_shared_network_full(
        CONST.tempest_private_net_name,
        CONST.tempest_private_subnet_name,
        CONST.tempest_router_name,
        CONST.tempest_private_subnet_cidr)
    if network_dic is None:
        raise Exception('Failed to create private network')

    image_id = ""
    image_id_alt = ""
    flavor_id = ""
    flavor_id_alt = ""

    if CONST.tempest_use_custom_images or use_custom_images:
        # adding alternative image should be trivial should we need it
        logger.debug("Creating image for Tempest suite")
        _, image_id = os_utils.get_or_create_image(
            CONST.openstack_image_name, GLANCE_IMAGE_PATH,
            CONST.openstack_image_disk_format)
        if image_id is None:
            raise Exception('Failed to create image')

    if use_custom_images:
        logger.debug("Creating 2nd image for Tempest suite")
        _, image_id_alt = os_utils.get_or_create_image(
            CONST.openstack_image_name_alt, GLANCE_IMAGE_PATH,
            CONST.openstack_image_disk_format)
        if image_id_alt is None:
            raise Exception('Failed to create image')

    if CONST.tempest_use_custom_flavors or use_custom_flavors:
        # adding alternative flavor should be trivial should we need it
        logger.debug("Creating flavor for Tempest suite")
        _, flavor_id = os_utils.get_or_create_flavor(
            CONST.openstack_flavor_name,
            CONST.openstack_flavor_ram,
            CONST.openstack_flavor_disk,
            CONST.openstack_flavor_vcpus)
        if flavor_id is None:
            raise Exception('Failed to create flavor')

    if use_custom_flavors:
        logger.debug("Creating 2nd flavor for tempest_defcore")
        _, flavor_id_alt = os_utils.get_or_create_flavor(
            CONST.openstack_flavor_name_alt,
            CONST.openstack_flavor_ram,
            CONST.openstack_flavor_disk,
            CONST.openstack_flavor_vcpus)
        if flavor_id_alt is None:
            raise Exception('Failed to create flavor')

    img_flavor_dict = {}
    img_flavor_dict['image_id'] = image_id
    img_flavor_dict['image_id_alt'] = image_id_alt
    img_flavor_dict['flavor_id'] = flavor_id
    img_flavor_dict['flavor_id_alt'] = flavor_id_alt

    return img_flavor_dict


def get_verifier_id():
    """
    Returns verifer id for current Tempest
    """
    cmd = ("rally verify list-verifiers | awk '/" +
           CONST.tempest_deployment_name +
           "/ {print $2}'")
    p = subprocess.Popen(cmd, shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    deployment_uuid = p.stdout.readline().rstrip()
    if deployment_uuid == "":
        logger.error("Tempest verifier not found.")
        raise Exception('Error with command:%s' % cmd)
    return deployment_uuid


def get_verifier_deployment_id():
    """
    Returns deployment id for active Rally deployment
    """
    cmd = ("rally deployment list | awk '/" +
           CONST.rally_deployment_name +
           "/ {print $2}'")
    p = subprocess.Popen(cmd, shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    deployment_uuid = p.stdout.readline().rstrip()
    if deployment_uuid == "":
        logger.error("Rally deployment not found.")
        raise Exception('Error with command:%s' % cmd)
    return deployment_uuid


def get_verifier_repo_dir(verifier_id):
    """
    Returns installed verfier repo directory for Tempest
    """
    if not verifier_id:
        verifier_id = get_verifier_id()

    return os.path.join(CONST.dir_rally_inst,
                        'verification',
                        'verifier-{}'.format(verifier_id),
                        'repo')


def get_verifier_deployment_dir(verifier_id, deployment_id):
    """
    Returns Rally deployment directory for current verifier
    """
    if not verifier_id:
        verifier_id = get_verifier_id()

    if not deployment_id:
        deployment_id = get_verifier_deployment_id()

    return os.path.join(CONST.dir_rally_inst,
                        'verification',
                        'verifier-{}'.format(verifier_id),
                        'for-deployment-{}'.format(deployment_id))


def get_repo_tag(repo):
    """
    Returns last tag of current branch
    """
    cmd = ("git -C {0} describe --abbrev=0 HEAD".format(repo))
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    tag = p.stdout.readline().rstrip()

    return str(tag)


def backup_tempest_config(conf_file):
    """
    Copy config file to tempest results directory
    """
    if not os.path.exists(TEMPEST_RESULTS_DIR):
        os.makedirs(TEMPEST_RESULTS_DIR)

    shutil.copyfile(conf_file,
                    os.path.join(TEMPEST_RESULTS_DIR, 'tempest.conf'))


def configure_tempest(deployment_dir, IMAGE_ID=None, FLAVOR_ID=None,
                      MODE=None):
    """
    Calls rally verify and updates the generated tempest.conf with
    given parameters
    """
    conf_file = configure_verifier(deployment_dir)
    configure_tempest_update_params(conf_file,
                                    IMAGE_ID, FLAVOR_ID)
    if MODE == 'feature_multisite':
        configure_tempest_multisite_params(conf_file)


def configure_tempest_defcore(deployment_dir, img_flavor_dict):
    """
    Add/update needed parameters into tempest.conf file
    """
    conf_file = configure_verifier(deployment_dir)
    configure_tempest_update_params(conf_file,
                                    img_flavor_dict.get("image_id"),
                                    img_flavor_dict.get("flavor_id"))

    logger.debug("Updating selected tempest.conf parameters for defcore...")
    config = ConfigParser.RawConfigParser()
    config.read(conf_file)
    config.set('compute', 'image_ref', img_flavor_dict.get("image_id"))
    config.set('compute', 'image_ref_alt',
               img_flavor_dict['image_id_alt'])
    config.set('compute', 'flavor_ref', img_flavor_dict.get("flavor_id"))
    config.set('compute', 'flavor_ref_alt',
               img_flavor_dict['flavor_id_alt'])

    with open(conf_file, 'wb') as config_file:
        config.write(config_file)

    confpath = os.path.join(CONST.dir_functest_test,
                            CONST.refstack_tempest_conf_path)
    shutil.copyfile(conf_file, confpath)


def configure_tempest_update_params(tempest_conf_file,
                                    IMAGE_ID=None, FLAVOR_ID=None):
    """
    Add/update needed parameters into tempest.conf file
    """
    logger.debug("Updating selected tempest.conf parameters...")
    config = ConfigParser.RawConfigParser()
    config.read(tempest_conf_file)
    config.set(
        'compute',
        'fixed_network_name',
        CONST.tempest_private_net_name)
    config.set('compute', 'volume_device_name',
               CONST.tempest_volume_device_name)
    if CONST.tempest_use_custom_images:
        if IMAGE_ID is not None:
            config.set('compute', 'image_ref', IMAGE_ID)
        if IMAGE_ID_ALT is not None:
            config.set('compute', 'image_ref_alt', IMAGE_ID_ALT)
    if CONST.tempest_use_custom_flavors:
        if FLAVOR_ID is not None:
            config.set('compute', 'flavor_ref', FLAVOR_ID)
        if FLAVOR_ID_ALT is not None:
            config.set('compute', 'flavor_ref_alt', FLAVOR_ID_ALT)
    config.set('identity', 'tenant_name', CONST.tempest_identity_tenant_name)
    config.set('identity', 'username', CONST.tempest_identity_user_name)
    config.set('identity', 'password', CONST.tempest_identity_user_password)
    config.set(
        'validation', 'ssh_timeout', CONST.tempest_validation_ssh_timeout)
    config.set('object-storage', 'operator_role',
               CONST.tempest_object_storage_operator_role)

    if CONST.OS_ENDPOINT_TYPE is not None:
        services_list = ['compute',
                         'volume',
                         'image',
                         'network',
                         'data-processing',
                         'object-storage',
                         'orchestration']
        sections = config.sections()
        for service in services_list:
            if service not in sections:
                config.add_section(service)
            config.set(service, 'endpoint_type',
                       CONST.OS_ENDPOINT_TYPE)

    with open(tempest_conf_file, 'wb') as config_file:
        config.write(config_file)

    backup_tempest_config(tempest_conf_file)


def configure_verifier(deployment_dir):
    """
    Execute rally verify configure-verifier, which generates tempest.conf
    """
    tempest_conf_file = os.path.join(deployment_dir, "tempest.conf")
    if os.path.isfile(tempest_conf_file):
        logger.debug("Verifier is already configured.")
        logger.debug("Reconfiguring the current verifier...")
        cmd = "rally verify configure-verifier --reconfigure"
    else:
        logger.info("Configuring the verifier...")
        cmd = "rally verify configure-verifier"
    ft_utils.execute_command(cmd)

    logger.debug("Looking for tempest.conf file...")
    if not os.path.isfile(tempest_conf_file):
        logger.error("Tempest configuration file %s NOT found."
                     % tempest_conf_file)
        raise Exception("Tempest configuration file %s NOT found."
                        % tempest_conf_file)
    else:
        return tempest_conf_file


def configure_tempest_multisite_params(tempest_conf_file):
    """
    Add/update multisite parameters into tempest.conf file generated by Rally
    """
    logger.debug("Updating multisite tempest.conf parameters...")
    config = ConfigParser.RawConfigParser()
    config.read(tempest_conf_file)

    config.set('service_available', 'kingbird', 'true')
    # cmd = ("openstack endpoint show kingbird | grep publicurl |"
    #       "awk '{print $4}' | awk -F '/' '{print $4}'")
    # kingbird_api_version = os.popen(cmd).read()
    kingbird_api_version = os_utils.get_endpoint(service_type='multisite')

    if CI_INSTALLER_TYPE == 'fuel':
        # For MOS based setup, the service is accessible
        # via bind host
        kingbird_conf_path = "/etc/kingbird/kingbird.conf"
        installer_type = CI_INSTALLER_TYPE
        installer_ip = CI_INSTALLER_IP
        installer_username = CONST.__getattribute__(
            'multisite_{}_installer_username'.format(installer_type))
        installer_password = CONST.__getattribute__(
            'multisite_{}_installer_password'.format(installer_type))

        ssh_options = ("-o UserKnownHostsFile=/dev/null -o "
                       "StrictHostKeyChecking=no")

        # Get the controller IP from the fuel node
        cmd = 'sshpass -p %s ssh 2>/dev/null %s %s@%s \
                \'fuel node --env 1| grep controller | grep "True\|  1" \
                | awk -F\| "{print \$5}"\'' % (installer_password,
                                               ssh_options,
                                               installer_username,
                                               installer_ip)
        multisite_controller_ip = "".join(os.popen(cmd).read().split())

        # Login to controller and get bind host details
        cmd = 'sshpass -p %s ssh 2>/dev/null  %s %s@%s "ssh %s \\" \
            grep -e "^bind_" %s  \\""' % (installer_password,
                                          ssh_options,
                                          installer_username,
                                          installer_ip,
                                          multisite_controller_ip,
                                          kingbird_conf_path)
        bind_details = os.popen(cmd).read()
        bind_details = "".join(bind_details.split())
        # Extract port number from the bind details
        bind_port = re.findall(r"\D(\d{4})", bind_details)[0]
        # Extract ip address from the bind details
        bind_host = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}",
                               bind_details)[0]
        kingbird_endpoint_url = "http://%s:%s/" % (bind_host, bind_port)
    else:
        # cmd = "openstack endpoint show kingbird | grep publicurl |\
        #       awk '{print $4}' | awk -F '/' '{print $3}'"
        # kingbird_endpoint_url = os.popen(cmd).read()
        kingbird_endpoint_url = os_utils.get_endpoint(service_type='kingbird')

    try:
        config.add_section("kingbird")
    except Exception:
        logger.info('kingbird section exist')

    # set the domain id
    config.set('auth', 'admin_domain_name', 'default')

    config.set('kingbird', 'endpoint_type', 'publicURL')
    config.set('kingbird', 'TIME_TO_SYNC', '120')
    config.set('kingbird', 'endpoint_url', kingbird_endpoint_url)
    config.set('kingbird', 'api_version', kingbird_api_version)
    with open(tempest_conf_file, 'wb') as config_file:
        config.write(config_file)

    backup_tempest_config(tempest_conf_file)


def install_verifier_ext(path):
    """
    Install extension to active verifier
    """
    logger.info("Installing verifier from existing repo...")
    tag = get_repo_tag(path)
    cmd = ("rally verify add-verifier-ext --source {0} "
           "--version {1}"
           .format(path, tag))
    error_msg = ("Problem while adding verifier extension from %s" % path)
    ft_utils.execute_command_raise(cmd, error_msg=error_msg)