add unit tests for deployment module

Change-Id: I198bb9bc5428bf32c2560210f5ad06c538aaa072
This commit is contained in:
graceyu08
2014-08-13 15:35:39 -07:00
parent 19bc03d333
commit f0124ca7b1
26 changed files with 993 additions and 384 deletions

View File

@@ -18,7 +18,7 @@
from compass.actions import util
from compass.db.api import adapter_holder as adapter_db
from compass.db.api import cluster as cluster_db
from compass.db.api import host as host_db
from compass.db.api import machine as machine_db
from compass.db.api import user as user_db
from compass.deployment.deploy_manager import DeployManager
from compass.deployment.utils import constants as const
@@ -77,22 +77,43 @@ def redeploy(cluster_id, hosts_id_list, username=None):
user)
deploy_manager = DeployManager(adapter_info, cluster_info, hosts_info)
#deploy_manager.prepare_for_deploy()
# deploy_manager.prepare_for_deploy()
deploy_manager.redeploy()
ActionHelper.update_state(cluster_id, hosts_id_list, user)
def poweron(host_id):
"""Power on a list of hosts."""
pass
class ServerPowerMgmt(object):
"""Power management for bare-metal machines by IPMI command."""
@staticmethod
def poweron(machine_id, user):
"""Power on the specified machine."""
pass
@staticmethod
def poweroff(machine_id, user):
pass
@staticmethod
def reset(machine_id, user):
pass
def poweroff(host_id):
pass
class HostPowerMgmt(object):
"""Power management for hosts installed OS by OS installer. OS installer
will poweron/poweroff/reset host.
"""
@staticmethod
def poweron(host_id, user):
"""Power on the specified host."""
pass
@staticmethod
def poweroff(host_id, user):
pass
def reset(host_id):
pass
@staticmethod
def reset(host_id, user):
pass
class ActionHelper(object):
@@ -103,7 +124,11 @@ class ActionHelper(object):
{
"id": 1,
"name": "xxx",
"roles": ['xxx', 'yyy', ...],
"flavor": {
"flavor_name": "xxx",
"roles": ['xxx', 'yyy', ...],
"template": "xxx.tmpl"
},
"metadata": {
"os_config": {
...
@@ -128,30 +153,44 @@ class ActionHelper(object):
metadata = cluster_db.get_cluster_metadata(user, cluster_id)
adapter_info.update(metadata)
roles_info = adapter_info[const.ROLES]
roles_info = adapter_info[const.FLAVOR][const.ROLES]
roles_list = [role[const.NAME] for role in roles_info]
adapter_info[const.ROLES] = roles_list
adapter_info[const.FLAVOR][const.ROLES] = roles_list
return adapter_info
@staticmethod
def _get_role_names(roles):
return [role[const.NAME] for role in roles]
@staticmethod
def get_cluster_info(cluster_id, user):
"""Get cluster information.Return a dictionary as below,
{
"cluster": {
"id": 1,
"adapter_id": 1,
"os_version": "CentOS-6.5-x86_64",
"name": "cluster_01",
"os_config": {..},
"package_config": {...},
"deployed_os_config": {},
"deployed_package_config": {},
"owner": "xxx"
"id": 1,
"adapter_id": 1,
"os_version": "CentOS-6.5-x86_64",
"name": "cluster_01",
"flavor": {
"flavor_name": "zzz",
"template": "xx.tmpl",
"roles": [...]
}
"os_config": {..},
"package_config": {...},
"deployed_os_config": {},
"deployed_package_config": {},
"owner": "xxx"
}
"""
cluster_info = cluster_db.get_cluster(user, cluster_id)
# convert roles retrieved from db into a list of role names
roles_info = cluster_info[const.FLAVOR][const.ROLES]
cluster_info[const.FLAVOR][const.ROLES] = \
ActionHelper._get_role_names(roles_info)
# get cluster config info
cluster_config = cluster_db.get_cluster_config(user, cluster_id)
cluster_info.update(cluster_config)
@@ -166,10 +205,11 @@ class ActionHelper(object):
"""Get hosts information. Return a dictionary as below,
{
"hosts": {
1($clusterhost_id/host_id): {
1($host_id): {
"reinstall_os": True,
"mac": "xxx",
"name": "xxx",
"roles": [xxx, yyy]
},
"networks": {
"eth0": {
@@ -192,10 +232,13 @@ class ActionHelper(object):
}
"""
hosts_info = {}
for clusterhost_id in hosts_id_list:
info = cluster_db.get_clusterhost(user, clusterhost_id)
config = cluster_db.get_clusterhost_config(user, clusterhost_id)
# Delete 'id' from temp
for host_id in hosts_id_list:
info = cluster_db.get_cluster_host(user, cluster_id, host_id)
info[const.ROLES] = ActionHelper._get_role_names(info[const.ROLES])
config = cluster_db.get_cluster_host_config(user,
cluster_id,
host_id)
info.update(config)
networks = info[const.NETWORKS]
@@ -216,7 +259,7 @@ class ActionHelper(object):
info[const.NETWORKS] = networks_dict
hosts_info[clusterhost_id] = info
hosts_info[host_id] = info
return hosts_info
@@ -230,18 +273,24 @@ class ActionHelper(object):
**cluster_config)
hosts_id_list = deployed_config[const.HOSTS].keys()
for clusterhost_id in hosts_id_list:
config = deployed_config[const.HOSTS][clusterhost_id]
cluster_db.update_clusterhost_deployed_config(user,
clusterhost_id,
**config)
for host_id in hosts_id_list:
config = deployed_config[const.HOSTS][host_id]
cluster_db.update_cluster_host_deployed_config(user,
cluster_id,
host_id,
**config)
@staticmethod
def update_state(cluster_id, clusterhost_id_list, user):
def update_state(cluster_id, host_id_list, user):
# update cluster state
cluster_db.update_cluster_state(user, cluster_id, state='INSTALLING')
# update all clusterhosts state
for clusterhost_id in clusterhost_id_list:
cluster_db.update_clusterhost_state(user, clusterhost_id,
state='INSTALLING')
for host_id in host_id_list:
cluster_db.update_cluster_host_state(user, cluster_id, host_id,
state='INSTALLING')
@staticmethod
def get_machine_IPMI(machine_id, user):
machine_info = machine_db.get_machine(user, machine_id)
return machine_info[const.IPMI_CREDS]

View File

@@ -90,11 +90,8 @@ class DeployManager(object):
self.os_installer.set_package_installer_config(pk_instl_confs)
# start to deploy OS
try:
os_deploy_config = self.os_installer.deploy()
deploy_config = os_deploy_config
except Exception as ex:
logging.error(ex.message)
os_deploy_config = self.os_installer.deploy()
deploy_config = os_deploy_config
if self.pk_installer:
logging.info('DeployManager][deploy]get package installer %s',

View File

@@ -22,7 +22,6 @@ import logging
from compass.deployment.utils import constants as const
from compass.utils import util
class BaseConfigManager(object):
@@ -33,37 +32,23 @@ class BaseConfigManager(object):
self.hosts_info = hosts_info
def get_cluster_id(self):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return None
return self.cluster_info[const.ID]
return self.__get_cluster_item(const.ID)
def get_clustername(self):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return None
return self.cluster_info[const.NAME]
return self.__get_cluster_item(const.NAME)
def get_os_version(self):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return None
return self.cluster_info[const.OS_VERSION]
return self.__get_cluster_item(const.OS_VERSION)
def get_cluster_baseinfo(self):
"""Get cluster base information, including cluster_id, os_version,
and cluster_name.
"""
if not self.cluster_info:
logging.info("cluster config is None or {}")
return None
attr_names = [const.ID, const.NAME, const.OS_VERSION]
base_info = {}
for name in attr_names:
base_info[name] = self.cluster_info[name]
base_info[name] = self.__get_cluster_item(name)
return base_info
@@ -74,19 +59,26 @@ class BaseConfigManager(object):
return self.hosts_info.keys()
def get_cluster_os_config(self):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return {}
def get_cluster_flavor_info(self):
return self.__get_cluster_item(const.FLAVOR, {})
return deepcopy(self.cluster_info[const.OS_CONFIG])
def get_cluster_flavor_name(self):
flavor_info = self.get_cluster_flavor_info()
return flavor_info.setdefault(const.FLAVOR_NAME, None)
def get_cluster_flavor_roles(self):
flavor_info = self.get_cluster_flavor_info()
return flavor_info.setdefault(const.ROLES, [])
def get_cluster_flavor_template(self):
flavor_info = self.get_cluster_flavor_info()
return flavor_info.setdefault(const.TMPL, None)
def get_cluster_os_config(self):
return deepcopy(self.__get_cluster_item(const.OS_CONFIG, {}))
def get_cluster_package_config(self):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return {}
return deepcopy(self.cluster_info[const.PK_CONFIG])
return deepcopy(self.__get_cluster_item(const.PK_CONFIG, {}))
def get_cluster_network_mapping(self):
package_config = self.get_cluster_package_config()
@@ -97,41 +89,20 @@ class BaseConfigManager(object):
mapping = package_config.setdefault(const.NETWORK_MAPPING, {})
logging.info("Network mapping in the config is '%s'!", mapping)
return deepcopy(mapping)
return mapping
def get_cluster_deployed_os_config(self):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return {}
config = self.cluster_info.setdefault(const.DEPLOYED_OS_CONFIG, {})
return config
return deepcopy(self.__get_cluster_item(const.DEPLOYED_OS_CONFIG, {}))
def get_cluster_deployed_package_config(self):
return deepcopy(self.__get_cluster_item(const.DEPLOYED_PK_CONFIG, {}))
def __get_cluster_item(self, item, default_value=None):
if not self.cluster_info:
logging.info("cluster config is None or {}")
return {}
return None
config = self.cluster_info.setdefault(const.DEPLOYED_PK_CONFIG, {})
return config
def get_cluster_os_vars_dict(self):
deployed_config = self.get_cluster_deployed_os_config()
return self.__get_deployed_config_item(deployed_config,
const.TMPL_VARS_DICT)
def get_cluster_package_vars_dict(self):
deployed_config = self.get_cluster_deployed_package_config()
return self.__get_deployed_config_item(deployed_config,
const.TMPL_VARS_DICT)
def __get_deployed_config_item(deployed_config, item):
if not deployed_config:
logging.info("Deploy config is {}")
return {}
value = deployed_config.setdefault(item, {})
return deepcopy(value)
return self.cluster_info.setdefault(item, default_value)
def get_cluster_roles_mapping(self):
if not self.cluster_info:
@@ -159,6 +130,13 @@ class BaseConfigManager(object):
return self.hosts_info[host_id]
def __get_host_item(self, host_id, item, default_value=None):
host_info = self._get_host_info(host_id)
if not host_info:
return {}
return deepcopy(host_info.setdefault(item, default_value))
def get_host_baseinfo(self, host_id):
"""Get host base information."""
host_info = self._get_host_info(host_id)
@@ -180,11 +158,7 @@ class BaseConfigManager(object):
return base_info
def get_host_fullname(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return None
return host_info.setdefault(const.NAME, None)
return self.__get_host_item(host_id, const.NAME, None)
def get_host_dns(self, host_id):
host_info = self._get_host_info(host_id)
@@ -199,60 +173,32 @@ class BaseConfigManager(object):
return host_info[const.DNS]
def get_host_mac_address(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return None
return host_info.setdefault(const.MAC_ADDR, None)
return self.__get_host_item(host_id, const.MAC_ADDR, None)
def get_hostname(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return None
return host_info.setdefault(const.HOSTNAME, None)
return self.__get_host_item(host_id, const.HOSTNAME, None)
def get_host_networks(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return {}
return deepcopy(host_info.setdefault(const.NETWORKS, {}))
return self.__get_host_item(host_id, const.NETWORKS, {})
def get_host_interfaces(self, host_id):
networks = self.get_host_networks(host_id)
if not networks:
return []
nic_names = networks.keys()
return nic_names
return networks.keys()
def get_host_interface_config(self, host_id, interface):
networks = self.get_host_networks(host_id)
if not networks:
return {}
return deepcopy(networks.setdefault(interface, {}))
return networks.setdefault(interface, {})
def get_host_interface_ip(self, host_id, interface):
interface_config = self._get_host_interface_config(host_id, interface)
if not interface_config:
return None
return interface_config.setdefault(const.IP_ADDR, None)
def get_host_interface_netmask(self, host_id, interface):
interface_config = self.get_host_interface_config(host_id, interface)
if not interface_config:
return None
return interface_config.setdefault(const.NETMASK, None)
def get_host_interface_subnet(self, host_id, interface):
nic_config = self.get_host_interface_config(host_id, interface)
if not nic_config:
return None
return nic_config.setdefault(const.SUBNET, None)
def is_interface_promiscuous(self, host_id, interface):
@@ -270,11 +216,7 @@ class BaseConfigManager(object):
return nic_config[const.MGMT_NIC_FLAG]
def get_host_os_config(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return {}
return deepcopy(host_info.setdefault(const.OS_CONFIG, {}))
return self.__get_host_item(host_id, const.OS_CONFIG, {})
def get_host_domain(self, host_id):
os_config = self.get_host_os_config(host_id)
@@ -298,114 +240,82 @@ class BaseConfigManager(object):
return network_mapping
def get_host_package_config(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return {}
return deepcopy(host_info.setdefault(const.PK_CONFIG, {}))
return self.__get_host_item(host_id, const.PK_CONFIG, {})
def get_host_deployed_os_config(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return {}
return host_info.setdefault(const.DEPLOYED_OS_CONFIG, {})
def get_host_os_vars_dict(self, host_id):
deployed_config = self.get_host_deployed_os_config(host_id)
return self.__get_deployed_config_item(deployed_config,
const.TMPL_VARS_DICT)
def get_host_completed_os_config(self, host_id):
deployed_config = self.get_host_deployed_os_config(host_id)
config = self.__get_deployed_config_item(deployed_config,
const.COMPLETED_OS_CONFIG)
if not config:
config = self.get_cluster_os_config()
util.merge_dict(config, self.get_host_os_config(host_id))
deployed_config[const.COMPLETED_OS_CONFIG] = config
return config
def get_host_deployed_package_config(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return {}
return host_info.setdefault(const.DEPLOYED_PK_CONFIG, {})
def get_host_package_vars_dict(self, host_id):
deployed_config = self.get_host_deployed_package_config(host_id)
return self.__get_deployed_config_item(deployed_config,
const.TMPL_VARS_DICT)
def get_host_roles(self, host_id):
config = self.get_host_package_config(host_id)
if not config:
return []
return deepcopy(config.setdefault(const.ROLES, []))
return self.__get_host_item(host_id, const.ROLES, [])
def get_host_roles_mapping(self, host_id):
roles_mapping = {}
deployed_pk_config = self.get_host_deployed_package_config(host_id)
deployed_pk_config = self.get_host_package_config(host_id)
if const.ROLES_MAPPING not in deployed_pk_config:
roles_mapping = self._get_host_roles_mapping_helper(host_id)
deployed_pk_config[const.ROLES_MAPPING] = roles_mapping
else:
roles_mapping = deployed_pk_config[const.ROLES_MAPPING]
return roles_mapping
return deepcopy(roles_mapping)
def get_host_ipmi_info(self, host_id):
ipmi_info = self.__get_host_item(host_id, const.IPMI, {})
if not ipmi_info:
return (None, None, None)
ipmi_ip = ipmi_info[const.IP_ADDR]
ipmi_user = ipmi_info[const.IPMI_CREDS][const.USERNAME]
ipmi_pass = ipmi_info[const.IPMI_CREDS][const.PASSWORD]
return (ipmi_ip, ipmi_user, ipmi_pass)
def __get_adapter_item(self, item, default_value=None):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
return deepcopy(self.adapter_info.setdefault(item, default_value))
def get_adapter_name(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
return self.adapter_info.setdefault(const.NAME, None)
return self.__get_adapter_item(const.NAME, None)
def get_dist_system_name(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
return self.adapter_info.setdefault(const.NAME, None)
def get_adapter_roles(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return []
roles = self.adapter_info.setdefault(const.ROLES, [])
return deepcopy(roles)
return self.__get_adapter_item(const.NAME, None)
def get_os_installer_settings(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
return self.adapter_info[const.OS_INSTALLER][const.INSTALLER_SETTINGS]
installer_info = self.__get_adapter_item(const.OS_INSTALLER, {})
return installer_info.setdefault(const.INSTALLER_SETTINGS, {})
def get_pk_installer_settings(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
return self.adapter_info[const.PK_INSTALLER][const.INSTALLER_SETTINGS]
installer_info = self.__get_adapter_item(const.PK_INSTALLER, {})
return installer_info.setdefault(const.INSTALLER_SETTINGS, {})
def get_os_config_metadata(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
return self.adapter_info[const.METADATA][const.OS_CONFIG]
metadata = self.__get_adapter_item(const.METADATA, {})
return metadata.setdefault(const.OS_CONFIG, {})
def get_pk_config_meatadata(self):
if not self.adapter_info:
logging.info("Adapter Info is None!")
return None
metadata = self.__get_adapter_item(const.METADATA, {})
return metadata.setdefault(const.PK_CONFIG, {})
return self.adapter_info[const.METADATA][const.PK_CONFIG]
def get_adapter_all_flavors(self):
return self.__get_adapter_item(const.FLAVORS, [])
def get_adapter_flavor(self, flavor_name):
flavors = self.__get_adapter_item(const.FLAVORS, [])
for flavor in flavors:
if flavor[const.FLAVOR_NAME] == flavor_name:
return flavor
return None
def _get_cluster_roles_mapping_helper(self):
"""The ouput format will be as below, for example:

View File

@@ -24,6 +24,8 @@ import logging
import os
import simplejson as json
from compass.deployment.installers.config_manager import BaseConfigManager
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
@@ -135,8 +137,9 @@ class BaseInstaller(object):
mod_file, path, descr = imp.find_module(name, [path])
if mod_file:
mod = imp.load_module(name, mod_file, path, descr)
return getattr(mod, mod.NAME)(adapter_info, cluster_info,
hosts_info)
config_manager = BaseConfigManager(adapter_info, cluster_info,
hosts_info)
return getattr(mod, mod.NAME)(config_manager)
except ImportError as exc:
logging.error('No such module found: %s', name)

View File

@@ -19,11 +19,11 @@ import os
import shutil
import xmlrpclib
from compass.deployment.installers.config_manager import BaseConfigManager
from compass.deployment.installers.installer import OSInstaller
from compass.deployment.utils import constants as const
from compass.utils import setting_wrapper as compass_setting
from compass.utils import util
from copy import deepcopy
NAME = 'CobblerInstaller'
@@ -45,12 +45,10 @@ class CobblerInstaller(OSInstaller):
POWER_USER = 'power_user'
POWER_PASS = 'power_pass'
def __init__(self, adapter_info, cluster_info, hosts_info):
def __init__(self, config_manager):
super(CobblerInstaller, self).__init__()
self.config_manager = CobblerConfigManager(adapter_info,
cluster_info,
hosts_info)
self.config_manager = config_manager
installer_settings = self.config_manager.get_os_installer_settings()
try:
username = installer_settings[self.CREDENTIALS][self.USERNAME]
@@ -137,22 +135,17 @@ class CobblerInstaller(OSInstaller):
# set host deploy config
temp = {}
temp = self.config_manager.get_host_deployed_os_config(host_id)
temp[const.TMPL_VARS_DICT] = vars_dict
temp.update(vars_dict[const.HOST])
host_config = {const.DEPLOYED_OS_CONFIG: temp}
hosts_deploy_config[host_id] = host_config
# set cluster deploy config
cluster_deconfig = self.config_manager.get_cluster_deployed_os_config()
cluster_deconfig[const.TMPL_VARS_DICT] = global_vars_dict
# sync to cobbler and trigger installtion.
self._sync()
return {
const.CLUSTER: {
const.ID: self.config_manager.get_cluster_id(),
const.DEPLOYED_OS_CONFIG: cluster_deconfig
const.DEPLOYED_OS_CONFIG: global_vars_dict[const.CLUSTER]
},
const.HOSTS: hosts_deploy_config
}
@@ -304,7 +297,7 @@ class CobblerInstaller(OSInstaller):
vars_dict = {}
if global_vars_dict:
# Set cluster template vars_dict from cluster os_config.
util.merge_dict(vars_dict, global_vars_dict)
vars_dict.update(deepcopy(global_vars_dict[const.CLUSTER]))
if self.PROFILE in kwargs:
profile = kwargs[self.PROFILE]
@@ -333,7 +326,7 @@ class CobblerInstaller(OSInstaller):
vars_dict = self.get_tmpl_vars_from_metadata(os_config_metadata,
cluster_os_config)
return vars_dict
return {const.CLUSTER: vars_dict}
def _check_and_set_system_impi(self, host_id, sys_id):
if not sys_id:
@@ -385,30 +378,3 @@ class CobblerInstaller(OSInstaller):
self.remote.power_system(sys_id, self.token, power='reboot')
logging.info("Host with ID=%d starts to reboot!" % host_id)
class CobblerConfigManager(BaseConfigManager):
def __init__(self, adapter_info, cluster_info, hosts_info):
super(CobblerConfigManager, self).__init__(adapter_info,
cluster_info,
hosts_info)
def get_host_ipmi_info(self, host_id):
host_info = self._get_host_info(host_id)
if not host_info:
return None
if self.IPMI not in host_info:
return None
ipmi_info = host_info[const.IPMI]
if not ipmi_info:
raise Exception('Cannot find IPMI information!')
ipmi_ip = ipmi_info[const.IP_ADDR]
ipmi_user = ipmi_info[const.IPMI_CREDS][const.USERNAME]
ipmi_pass = ipmi_info[const.IPMI_CREDS][const.PASSWORD]
return (ipmi_ip, ipmi_user, ipmi_pass)

View File

@@ -16,11 +16,11 @@ __author__ = "Grace Yu (grace.yu@huawei.com)"
"""package installer: chef plugin."""
from copy import deepcopy
import logging
import os
import shutil
from compass.deployment.installers.config_manager import BaseConfigManager
from compass.deployment.installers.installer import PKInstaller
from compass.deployment.utils import constants as const
from compass.utils import setting_wrapper as compass_setting
@@ -32,21 +32,26 @@ NAME = 'ChefInstaller'
class ChefInstaller(PKInstaller):
"""chef package installer."""
ENV_TMPL_NAME = 'env.tmpl'
NODE_TMPL_DIR = 'node'
ENV_TMPL_DIR = 'environments'
NODE_TMPL_DIR = 'nodes'
DATABAG_TMPL_DIR = 'databags'
COMMON_NODE_TMPL_NAME = 'node.tmpl'
def __init__(self, adapter_info, cluster_info, hosts_info):
# keywords in package installer settings of adapter info
DATABAGS = "databags"
CHEFSERVER_URL = "chef_url"
KEY_DIR = "key_dir"
CLIENT = "client_name"
def __init__(self, config_manager):
super(ChefInstaller, self).__init__()
self.config_manager = ChefConfigManager(adapter_info, cluster_info,
hosts_info)
self.config_manager = config_manager
adapter_name = self.config_manager.get_dist_system_name()
self.tmpl_dir = ChefInstaller.get_tmpl_path(adapter_name)
self.installer_url = self.config_manager.get_chef_url()
key, client = self.config_manager.get_chef_credentials()
installer_settings = self.config_manager.get_pk_installer_settings()
self.installer_url = self.get_chef_url(installer_settings)
key, client = self.get_chef_credentials(installer_settings)
self.chef_api = self._get_chef_api(key, client)
logging.debug('%s instance created', self)
@@ -215,8 +220,11 @@ class ChefInstaller(PKInstaller):
def _get_env_attributes(self, vars_dict):
"""Get environment attributes from env templates."""
env_tmpl = os.path.join(self.tmpl_dir, self.ENV_TMPL_NAME)
env_attri = self.get_config_from_template(env_tmpl, vars_dict)
env_tmpl_fname = self.config_manager.get_cluster_flavor_template()
env_tmpl_path = os.path.join(
os.path.join(self.tmpl_dir, self.ENV_TMPL_DIR), env_tmpl_fname
)
env_attri = self.get_config_from_template(env_tmpl_path, vars_dict)
return env_attri
def get_environment(self, env_name):
@@ -255,7 +263,7 @@ class ChefInstaller(PKInstaller):
:param dict vars_dict: The dictionary used to get attributes from
templates.
"""
databag_names = self.config_manager.get_chef_databag_names()
databag_names = self.get_chef_databag_names()
if not databag_names:
return
@@ -288,7 +296,7 @@ class ChefInstaller(PKInstaller):
vars_dict = {}
if global_vars_dict:
temp = global_vars_dict[const.CLUSTER][const.DEPLOYED_PK_CONFIG]
vars_dict[const.DEPLOYED_PK_CONFIG] = temp
vars_dict[const.DEPLOYED_PK_CONFIG] = deepcopy(temp)
host_baseinfo = self.config_manager.get_host_baseinfo(host_id)
util.merge_dict(vars_dict, host_baseinfo)
@@ -298,7 +306,8 @@ class ChefInstaller(PKInstaller):
# Get host template variables and merge to vars_dict
metadata = self.config_manager.get_pk_config_meatadata()
host_dict = self.get_tmpl_vars_from_metadata(metadata, pk_config)
util.merge_dict(vars_dict[const.DEPLOYED_PK_CONFIG], host_dict)
#util.merge_dict(vars_dict[const.DEPLOYED_PK_CONFIG], host_dict)
vars_dict[const.DEPLOYED_PK_CONFIG].update(host_dict)
# Set role_mapping for host
mapping = self.config_manager.get_host_roles_mapping(host_id)
@@ -308,14 +317,17 @@ class ChefInstaller(PKInstaller):
def _get_cluster_tmpl_vars(self):
vars_dict = {}
# set cluster basic information to vars_dict
cluster_baseinfo = self.config_manager.get_cluster_baseinfo()
util.merge_dict(vars_dict, cluster_baseinfo)
# get and set template variables from cluster package config.
pk_metadata = self.config_manager.get_pk_config_meatadata()
pk_config = self.config_manager.get_cluster_package_config()
meta_dict = self.get_tmpl_vars_from_metadata(pk_metadata, pk_config)
vars_dict[const.DEPLOYED_PK_CONFIG] = meta_dict
# get and set roles_mapping to vars_dict
mapping = self.config_manager.get_cluster_roles_mapping()
vars_dict[const.DEPLOYED_PK_CONFIG][const.ROLES_MAPPING] = mapping
@@ -327,7 +339,11 @@ class ChefInstaller(PKInstaller):
{
"cluster": {
"id": 1,
"deployed_package_config": {...}
"deployed_package_config": {
"roles_mapping": {...},
"service_credentials": {...},
....
}
},
"hosts": {
1($clusterhost_id): {
@@ -338,7 +354,6 @@ class ChefInstaller(PKInstaller):
}
"""
adapter_name = self.config_manager.get_adapter_name()
cluster_id = self.config_manager.get_cluster_id()
cluster_name = self.config_manager.get_clustername()
env_name = self.get_env_name(adapter_name, cluster_name)
@@ -362,23 +377,22 @@ class ChefInstaller(PKInstaller):
self.update_node(node, roles, vars_dict)
# set each host deployed config
tmp = self.config_manager.get_host_deployed_package_config(host_id)
tmp[const.TMPL_VARS_DICT] = vars_dict
tmp = {}
host_config = {}
host_config[const.DEPLOYED_PK_CONFIG] = tmp
hosts_deployed_configs[host_id] = host_config
tmp.update(vars_dict[const.HOST][const.DEPLOYED_PK_CONFIG])
host_config = {
host_id: {const.DEPLOYED_PK_CONFIG: tmp}
}
hosts_deployed_configs.update(host_config)
# set cluster deployed config
cl_config = self.config_manager.get_cluster_deployed_package_config()
cl_config[const.TMPL_VARS_DICT] = global_vars_dict
cl_config = {}
cl_config.update(global_vars_dict)
return {
const.CLUSTER: {
const.ID: cluster_id,
const.DEPLOYED_PK_CONFIG: cl_config
},
const.HOSTS: hosts_deployed_configs
}
output = {}
output.update(cl_config)
output.update({const.HOSTS: hosts_deployed_configs})
return output
def generate_installer_config(self):
"""Render chef config file (client.rb) by OS installing right after
@@ -452,38 +466,34 @@ class ChefInstaller(PKInstaller):
"""reinstall host."""
pass
def get_chef_url(self, installer_settings=None):
settings = installer_settings
if settings is None:
settings = self.config_manager.get_pk_installer_settings()
class ChefConfigManager(BaseConfigManager):
TMPL_DIR = 'tmpl_dir'
DATABAGS = "databags"
CHEFSERVER_URL = "chef_url"
KEY_DIR = "key_dir"
CLIENT = "client_name"
def __init__(self, adapter_info, cluster_info, hosts_info):
super(ChefConfigManager, self).__init__(adapter_info,
cluster_info,
hosts_info)
def get_chef_url(self):
pk_installer_settings = self.get_pk_installer_settings()
if self.CHEFSERVER_URL not in pk_installer_settings:
if self.CHEFSERVER_URL not in settings:
raise KeyError("'%s' must be set in package settings!",
self.CHEFSERVER_URL)
return pk_installer_settings[self.CHEFSERVER_URL]
return settings[self.CHEFSERVER_URL]
def get_chef_credentials(self):
installer_settings = self.get_pk_installer_settings()
key_dir = installer_settings.setdefault(self.KEY_DIR, None)
client = installer_settings.setdefault(self.CLIENT, None)
def get_chef_credentials(self, installer_settings=None):
settings = installer_settings
if settings is None:
settings = self.config_manager.get_pk_installer_settings()
key_dir = settings.setdefault(self.KEY_DIR, None)
client = settings.setdefault(self.CLIENT, None)
return (key_dir, client)
def get_chef_databag_names(self):
pk_installer_settings = self.get_pk_installer_settings()
if self.DATABAGS not in pk_installer_settings:
def get_chef_databag_names(self, installer_settings=None):
settings = installer_settings
if settings is None:
settings = self.config_manager.get_pk_installer_settings()
if self.DATABAGS not in settings:
logging.info("No databags is set!")
return None
return pk_installer_settings[self.DATABAGS]
return settings[self.DATABAGS]

View File

@@ -30,6 +30,10 @@ USERNAME = 'username'
# Adapter info related keywords
DIST_SYS_NAME = 'distributed_system_name'
FLAVOR = 'flavor'
FLAVORS = 'flavors'
FLAVOR_NAME = 'flavor_name'
TMPL = 'template'
INSTALLER_SETTINGS = 'settings'
METADATA = 'metadata'
OS_INSTALLER = 'os_installer'

View File

@@ -43,16 +43,20 @@ class TestDeployAction(unittest2.TestCase):
mock_get_adapter.return_value = {
"id": 1,
"name": "test_adapter",
"roles": [
{
"name": "test-role-1",
"display_name": "test role 1"
},
{
"name": "test-role-2",
"display_name": "test role 2"
}
],
"flavor": {
"flavor_name": "test_flavor",
"template": "test_tmpl.tmpl",
"roles": [
{
"name": "test-role-1",
"display_name": "test role 1"
},
{
"name": "test-role-2",
"display_name": "test role 2"
}
]
},
"os_installer": {
"name": "test_os_installer",
"settings": {
@@ -73,7 +77,11 @@ class TestDeployAction(unittest2.TestCase):
expected_output = {
"id": 1,
"name": "test_adapter",
"roles": ["test-role-1", "test-role-2"],
"flavor": {
"flavor_name": "test_flavor",
"template": "test_tmpl.tmpl",
"roles": ["test-role-1", "test-role-2"]
},
"os_installer": {
"name": "test_os_installer",
"settings": {
@@ -93,22 +101,32 @@ class TestDeployAction(unittest2.TestCase):
self.maxDiff = None
self.assertDictEqual(expected_output, output)
@patch('compass.db.api.cluster.get_clusterhost_config')
@patch('compass.db.api.cluster.get_clusterhost')
def test_get_hosts_info(self, mock_get_clusterhost,
mock_get_clusterhost_config):
mock_get_clusterhost_config.return_value = {
@patch('compass.db.api.cluster.get_cluster_host_config')
@patch('compass.db.api.cluster.get_cluster_host')
def test_get_hosts_info(self, mock_get_cluster_host,
mock_get_cluster_host_config):
mock_get_cluster_host_config.return_value = {
"os_config": {},
"package_config": {},
"deployed_os_config": {},
"deployed_package_config": {}
}
mock_get_clusterhost.return_value = {
mock_get_cluster_host.return_value = {
"id": 1,
"host_id": 10,
"name": "test",
"mac": "00:89:23:a1:e9:10",
"hostname": "server01",
"roles": [
{
"name": "test-role-1",
"display_name": "test role 1"
},
{
"name": "test-role-2",
"display_name": "test role 2"
}
],
"networks": [
{
"interface": "eth0",
@@ -127,6 +145,7 @@ class TestDeployAction(unittest2.TestCase):
"name": "test",
"mac": "00:89:23:a1:e9:10",
"hostname": "server01",
"roles": ["test-role-1", "test-role-2"],
"networks": {
"eth0": {
"ip": "127.0.0.1",

View File

@@ -28,6 +28,7 @@ import unittest2
os.environ['COMPASS_IGNORE_SETTING'] = 'true'
from compass.deployment.installers.config_manager import BaseConfigManager
from compass.deployment.installers.os_installers.cobbler.cobbler \
import CobblerInstaller
from compass.tests.deployment.test_data import config_data
@@ -98,12 +99,15 @@ class TestCobblerInstaller(unittest2.TestCase):
del self.test_cobbler
def _get_cobbler_installer(self):
adapter_info = deepcopy(config_data.adapter_test_config)
cluster_info = deepcopy(config_data.cluster_test_config)
adapter_info = config_data.adapter_test_config
cluster_info = config_data.cluster_test_config
hosts_info = deepcopy(config_data.hosts_test_config)
# In config_data, only hosts with ID 1 and 2 needs to install OS.
del hosts_info[3]
config_manager = BaseConfigManager(adapter_info, cluster_info,
hosts_info)
CobblerInstaller._get_cobbler_server = Mock()
CobblerInstaller._get_cobbler_server.return_value = "mock_server"
CobblerInstaller._get_token = Mock()
@@ -112,7 +116,7 @@ class TestCobblerInstaller(unittest2.TestCase):
CobblerInstaller.get_tmpl_path = Mock()
test_tmpl_dir = os.path.join(config_data.test_tmpl_dir, 'cobbler')
CobblerInstaller.get_tmpl_path.return_value = test_tmpl_dir
return CobblerInstaller(adapter_info, cluster_info, hosts_info)
return CobblerInstaller(config_manager)
def test_get_host_tmpl_vars_dict(self):
host_id = 1
@@ -171,3 +175,149 @@ class TestCobblerInstaller(unittest2.TestCase):
host_id, self.expected_host_vars_dict)
self.maxDiff = None
self.assertEqual(expected_system_config, output)
def test_deploy(self):
profile = 'Ubuntu-12.04-x86_64'
self.test_cobbler._get_profile_from_server = Mock()
self.test_cobbler._get_profile_from_server.return_value = profile
self.test_cobbler.update_host_config_to_cobbler = Mock()
self.test_cobbler._sync = Mock()
expected_output = {
"cluster": {
"id": 1,
"deployed_os_config": {
"language": "EN",
"timezone": "UTC",
"gateway": "12.234.32.1",
"http_proxy": "http://127.0.0.1:3128",
"https_proxy": "",
"ntp_server": "127.0.0.1",
"nameservers": ["127.0.0.1"],
"search_path": ["1.ods.com", "ods.com"],
"partition": {
"/var": {
"vol_percentage": 20,
"vol_size": 20
},
"/home": {
"vol_percentage": 40,
"vol_size": 50
}
},
"server_credentials": {
"username": "root",
"password": "huawei"
}
}
},
"hosts": {
1: {
"deployed_os_config": {
"mac": "00:0c:29:3e:60:e9",
"name": "server01.test",
"hostname": "server01",
"profile": "Ubuntu-12.04-x86_64",
"reinstall_os": True,
"dns": "server01.test.ods.com",
"networks": {
"vnet0": {
"ip": "12.234.32.100",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"vnet1": {
"ip": "172.16.1.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
},
"language": "EN",
"timezone": "UTC",
"gateway": "10.145.88.1",
"http_proxy": "http://127.0.0.1:3128",
"https_proxy": "",
"ntp_server": "127.0.0.1",
"nameservers": ["127.0.0.1"],
"search_path": ["1.ods.com", "ods.com"],
"partition": {
"/var": {
"vol_percentage": 30,
"vol_size": 30
},
"/home": {
"vol_percentage": 40,
"vol_size": 50
},
"/test": {
"vol_percentage": 10,
"vol_size": 10
}
},
"server_credentials": {
"username": "root",
"password": "huawei"
}
}
},
2: {
"deployed_os_config": {
"mac": "00:0c:29:3e:60:a1",
"name": "server02.test",
"hostname": "server02",
"profile": "Ubuntu-12.04-x86_64",
"reinstall_os": True,
"dns": "server02.test.ods.com",
"networks": {
"eth0": {
"ip": "12.234.32.101",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"eth1": {
"ip": "172.16.1.2",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
},
"language": "EN",
"timezone": "UTC",
"gateway": "12.234.32.1",
"http_proxy": "http://127.0.0.1:3128",
"https_proxy": "",
"ntp_server": "127.0.0.1",
"nameservers": ["127.0.0.1"],
"search_path": ["1.ods.com", "ods.com"],
"partition": {
"/var": {
"vol_percentage": 20,
"vol_size": 20
},
"/home": {
"vol_percentage": 40,
"vol_size": 50
},
"/test": {
"vol_percentage": 20,
"vol_size": 10
}
},
"server_credentials": {
"username": "root",
"password": "huawei"
}
}
}
}
}
output = self.test_cobbler.deploy()
self.maxDiff = None
self.assertDictEqual(expected_output, output)

View File

@@ -20,7 +20,6 @@ __author__ = "Grace Yu (grace.yu@huawei.com)"
"""Test Chef installer module.
"""
from copy import deepcopy
from mock import Mock
import os
import unittest2
@@ -28,6 +27,7 @@ import unittest2
os.environ['COMPASS_IGNORE_SETTING'] = 'true'
from compass.deployment.installers.config_manager import BaseConfigManager
from compass.tests.deployment.test_data import config_data
from compass.utils import setting_wrapper as compass_setting
reload(compass_setting)
@@ -47,9 +47,12 @@ class TestChefInstaller(unittest2.TestCase):
super(TestChefInstaller, self).tearDown()
def _get_chef_installer(self):
adapter_info = deepcopy(config_data.adapter_test_config)
cluster_info = deepcopy(config_data.cluster_test_config)
hosts_info = deepcopy(config_data.hosts_test_config)
adapter_info = config_data.adapter_test_config
cluster_info = config_data.cluster_test_config
hosts_info = config_data.hosts_test_config
config_manager = BaseConfigManager(adapter_info, cluster_info,
hosts_info)
ChefInstaller.get_tmpl_path = Mock()
test_tmpl_dir = os.path.join(os.path.join(config_data.test_tmpl_dir,
@@ -59,7 +62,7 @@ class TestChefInstaller(unittest2.TestCase):
ChefInstaller._get_chef_api = Mock()
ChefInstaller._get_chef_api.return_value = 'mock_server'
chef_installer = ChefInstaller(adapter_info, cluster_info, hosts_info)
chef_installer = ChefInstaller(config_manager)
return chef_installer
def test_get_tmpl_vars(self):
@@ -178,7 +181,7 @@ class TestChefInstaller(unittest2.TestCase):
}
}
databag_dir = os.path.join(self.test_chef.get_tmpl_path(), 'databags')
databags = self.test_chef.config_manager.get_chef_databag_names()
databags = self.test_chef.get_chef_databag_names()
for bag in databags:
tmpl_path = os.path.join(databag_dir, '.'.join((bag, 'tmpl')))
output = self.test_chef._get_databagitem_attributes(tmpl_path,
@@ -195,3 +198,218 @@ class TestChefInstaller(unittest2.TestCase):
self.test_chef._clean_log('/tmp', fullname)
self.assertFalse(os.path.exists(test_log_dir))
def test_deploy(self):
expected_output = {
"cluster": {
"id": 1,
"name": "test",
"os_name": "Ubuntu-12.04-x86_64",
"deployed_package_config": {
"service_credentials": {
"mq": {
"username": "guest",
"password": "test"
}
},
"roles_mapping": {
"os_controller": {
"management": {
"interface": "vnet0",
"ip": "12.234.32.100",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "vnet1",
"ip": "172.16.1.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
},
"os_compute": {
"management": {
"interface": "eth0",
"ip": "12.234.32.101",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.2",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
},
"os_network": {
"management": {
"interface": "eth0",
"ip": "12.234.32.103",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.3",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
},
"public": {
"interface": "eth2",
"ip": "10.0.0.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": True,
"subnet": "10.0.0.0/24"
}
}
}
}
},
"hosts": {
1: {
"deployed_package_config": {
"roles_mapping": {
"os_controller": {
"management": {
"interface": "vnet0",
"ip": "12.234.32.100",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "vnet1",
"ip": "172.16.1.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
}
},
"service_credentials": {
"mq": {
"username": "guest",
"password": "test"
}
}
}
},
2: {
"deployed_package_config": {
"roles_mapping": {
"os_compute": {
"management": {
"interface": "eth0",
"ip": "12.234.32.101",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.2",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
}
},
"service_credentials": {
"mq": {
"username": "guest",
"password": "test"
}
}
}
},
3: {
"deployed_package_config": {
"roles_mapping": {
"os_network": {
"management": {
"interface": "eth0",
"ip": "12.234.32.103",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.3",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
},
"public": {
"interface": "eth2",
"ip": "10.0.0.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": True,
"subnet": "10.0.0.0/24"
}
},
"os_compute": {
"management": {
"interface": "eth0",
"ip": "12.234.32.103",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.3",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
},
"public": {
"interface": "eth2",
"ip": "10.0.0.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": True,
"subnet": "10.0.0.0/24"
}
}
},
"service_credentials": {
"mq": {
"username": "guest",
"password": "test"
}
}
}
}
}
}
self.test_chef.update_environment = Mock()
self.test_chef.update_databags = Mock()
self.test_chef.get_node = Mock()
self.test_chef.update_node = Mock()
output = self.test_chef.deploy()
self.maxDiff = None
self.assertDictEqual(expected_output, output)

View File

@@ -11,3 +11,159 @@
# 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.
"""Test config_manager module."""
import os
import unittest2
os.environ['COMPASS_IGNORE_SETTING'] = 'true'
from compass.deployment.installers.config_manager import BaseConfigManager
from compass.tests.deployment.test_data import config_data
from compass.utils import setting_wrapper as compass_setting
reload(compass_setting)
class TestConfigManager(unittest2.TestCase):
"""Test ConfigManager methods."""
def setUp(self):
super(TestConfigManager, self).setUp()
adapter_test_info = config_data.adapter_test_config
cluster_test_info = config_data.cluster_test_config
hosts_test_info = config_data.hosts_test_config
self.test_config_manager = BaseConfigManager(adapter_test_info,
cluster_test_info,
hosts_test_info)
def tearDown(self):
super(TestConfigManager, self).tearDown()
del self.test_config_manager
def test_get_cluster_roles_mapping(self):
expected_output = {
"os_controller": {
"management": {
"interface": "vnet0",
"ip": "12.234.32.100",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "vnet1",
"ip": "172.16.1.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
},
"os_compute": {
"management": {
"interface": "eth0",
"ip": "12.234.32.101",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.2",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
}
},
"os_network": {
"management": {
"interface": "eth0",
"ip": "12.234.32.103",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.3",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
},
"public": {
"interface": "eth2",
"ip": "10.0.0.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": True,
"subnet": "10.0.0.0/24"
}
}
}
self.maxDiff = None
output = self.test_config_manager.get_cluster_roles_mapping()
self.assertEqual(expected_output, output)
def test_get_host_role_mapping(self):
expected_output = {
"os_network": {
"management": {
"interface": "eth0",
"ip": "12.234.32.103",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.3",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
},
"public": {
"interface": "eth2",
"ip": "10.0.0.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": True,
"subnet": "10.0.0.0/24"
}
},
"os_compute": {
"management": {
"interface": "eth0",
"ip": "12.234.32.103",
"netmask": "255.255.255.0",
"is_mgmt": True,
"is_promiscuous": False,
"subnet": "12.234.32.0/24"
},
"tenant": {
"interface": "eth1",
"ip": "172.16.1.3",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": False,
"subnet": "172.16.1.0/24"
},
"public": {
"interface": "eth2",
"ip": "10.0.0.1",
"netmask": "255.255.255.0",
"is_mgmt": False,
"is_promiscuous": True,
"subnet": "10.0.0.0/24"
}
}
}
self.maxDiff = None
output = self.test_config_manager.get_host_roles_mapping(3)
self.assertEqual(expected_output, output)

View File

@@ -11,3 +11,39 @@
# 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.
"""Test base installer functionalities."""
import os
import unittest2
os.environ['COMPASS_IGNORE_SETTING'] = 'true'
from compass.deployment.installers.installer import BaseInstaller
from compass.tests.deployment.test_data import config_data
from compass.utils import setting_wrapper as compass_setting
reload(compass_setting)
class TestBaseInstaller(unittest2.TestCase):
"""Test base installer."""
def setUp(self):
super(TestBaseInstaller, self).setUp()
self.test_installer = BaseInstaller()
def tearDown(self):
super(TestBaseInstaller, self).tearDown()
del self.test_installer
def test_get_tmpl_vars_from_metadata(self):
test_cases = config_data.metadata_test_cases
for case in test_cases:
metadata = case["metadata"]
config = case["config"]
expected_output = case["expected_output"]
output = self.test_installer.get_tmpl_vars_from_metadata(metadata,
config)
self.maxDiff = None
self.assertDictEqual(expected_output, output)

View File

@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA2aiAT//LE2EIB4n/Y0MM8eiwcExy6xO0HEdwUMHuCHXM9g01
U4T9KWRHJ4kGDS8yUwgRXrz4BIVVYuHqs05t4TsU4VzsoQvtat0u6N7Ccs0GoyvQ
DkcVFWaAetnHGGEG7Yw3Epc553pwDhfajFKjziX2SW28XLFZhzxigciSPDccB0lS
IhbsdEZbAX9/ByPZ79HHnwexO0aSAIYhsXkKMSJ8ZlkcbXAY69UGTN+Hr9ScUDZg
W7VYn+MgQXDj+lv2pwbG7wI1GwywQCzCC07OZeiMCTVLSUOU+V8+i92R7b+Zdrtj
iBra6AR8k514CbSJmGWvHUCqPm2xY3pZzCTnUQIDAQABAoIBAQCYe+TQptpFTFAM
wA/MIZg7DZI2SkikCdy/hwjXetVg1e5uXliCl4OocNksiGFV8T+nTdqlbWuv9x0X
tj/vuD1gcjyxmaEpPirpF+WaPR0qwhopTDNpHUFXCcVuy40gtjDdUMLwYkOtuGgy
Z2Gztt2NOakuThONOK4JATPdyn8wcPyF9/z96fKSysqu2v2syD5Ql4XaXwLv47vR
bd/jgFZ3Fh8TbhWU8ss5qOKZMy9jK2VuLQRbheMGKaBA4YrTQHFmWWZpTrqW1ixR
eEPuMvD1q7P+8ynnNWsFJnUIB8l1RTuw8TKGPeXvzb2YbvOqwHwTSoA/Qwx9XIuf
ZdBSEErxAoGBAPAWsI9fO6C6uBrPW47Yui8OaDcXd+knF/DpJx8Xc243LDe/g/FA
eLczpw8dy2DOnMhWi7DGlzQL6GpBUuHTxpJmdiYxUbA7kYQucfZpdS9z6dGjkaOH
+RelZxLtifJSccKwPw3L8LsC8zzaXEPGA/gSrbMal1hr5aByy4cO6zf9AoGBAOgV
QpT+75EJ4MlABTDEQZroKPHPeoT7DGa6l5da9t9rIUXrfeK2fYzibS6fjHOFsAQN
R5+3aEZx6GXXKKd3uHcQ5K8RFd7I2bbDRRVRpLkFDJ6DuxRz1KfbVF1XJFO+FPGw
RcBL6qB2X6F6Gb5x0p7fOSNtQdcl0nJqfRPrprrlAoGBAN/7CvR2T9Z+20qHsE7v
eaJ0ulzLFB77TaZ+nPSwmAt2hVXs4VasYvHmyi+cCCRkHHf55ZAhdOYlRcn67yum
ulXSKN8wm5jhubuq6L6NW7nNVZEyG6iILaYVtLc/y7W5nE+YxPpGDGsrMWjP/cts
bD9+jXXNlOv0nOC2t5FkJaSxAoGAUwKvsv1QkO8YkMMuWBgKYy7g3kTYzNHCyMe6
yu9FV/pIh2rItxuQ4qBmbwOwR+2sXHanhLAkQvYhKrP/nY7L0wKe2SNiUDJE9QL5
JbvzEB6HOfdiJdmcWYGwtkYh/zYA5cWn3TUKMeTFJcu3g4/QxvSOymYc46hqknQW
Uta55yUCgYA7oJXdFyYkk68EWcleGC0EvB29Z0bnPg+SF4rWVI7sZRY2SihMTxkC
nYQtcEkNdxMP3HbrPmr8+VAMayzm2NdIp0zyhQx0z/bQ0UjsGXLFDg7xwc7fL22r
zUCV2oB+T/43vyM/jNaiRO1JDNdEZM97CS/SjmdA1CB1dEWSQTITrw==
-----END RSA PRIVATE KEY-----

View File

@@ -15,17 +15,31 @@
__author__ = "Grace Yu (grace.yu@huawei.com)"
import os
os.environ['COMPASS_IGNORE_SETTING'] = 'true'
from compass.utils import setting_wrapper as compass_setting
reload(compass_setting)
curr_dir = os.path.dirname(os.path.realpath(__file__))
test_tmpl_dir = os.path.join(curr_dir, 'templates')
test_client_key = os.path.join(curr_dir, 'client.pem')
test_chef_url = compass_setting.TEST_CHEF_URL
test_client_key = compass_setting.TEST_CLIENT_KEY_PATH
test_client = compass_setting.TEST_CLIENT_NAME
adapter_test_config = {
"name": "openstack_icehouse",
"distributed_system_name": "openstack_icehouse",
"roles": ["os-controller", "os-compute-worker", "os-network"],
"flavors": [
{
"falvor_name": "test_flavor",
"roles": ["os-controller", "os-compute-worker", "os-network"],
"template": "multinodes.tmpl"
}
],
"os_installer": {
"name": "cobbler",
"settings": {
@@ -170,6 +184,11 @@ cluster_test_config = {
"id": 1,
"os_name": "Ubuntu-12.04-x86_64",
"name": "test",
"flavor": {
"falvor_name": "test_flavor",
"roles": ["os-controller", "os-compute-worker", "os-network"],
"template": "multinodes.tmpl"
},
"os_config": {
"general": {
"language": "EN",
@@ -221,6 +240,7 @@ hosts_test_config = {
"mac": "00:0c:29:3e:60:e9",
"name": "server01.test",
"hostname": "server01",
"roles": ["os-controller"],
"networks": {
"vnet0": {
"ip": "12.234.32.100",
@@ -256,8 +276,7 @@ hosts_test_config = {
"network_mapping": {
"management": "vnet0",
"tenant": "vnet1"
},
"roles": ["os-controller"]
}
}
},
2: {
@@ -266,6 +285,7 @@ hosts_test_config = {
"mac": "00:0c:29:3e:60:a1",
"name": "server02.test",
"hostname": "server02",
"roles": ["os-compute"],
"networks": {
"eth0": {
"ip": "12.234.32.101",
@@ -296,15 +316,15 @@ hosts_test_config = {
}
},
"package_config": {
"roles": ["os-compute"]
}
},
3: {
"host_id": 10,
"reinstall_os": False,
"mac_address": "00:0c:29:3e:60:a2",
"mac": "00:0c:29:3e:60:a2",
"name": "server03.test",
"hostname": "server03",
"roles": ["os-network", "os-compute"],
"networks": {
"eth0": {
"ip": "12.234.32.103",
@@ -352,7 +372,95 @@ hosts_test_config = {
}
},
"package_config": {
"roles": ["os-network"]
}
}
}
metadata_test_cases = [
{
"metadata": {
"general": {
"_self": {},
"language": {
"_self": {"mapping_to": "lan"}
},
"timezone": {
"_self": {"mapping_to": "timezone"}
}
}
},
"config": {
"general": {
"language": "EN",
"timezone": "UTC"
}
},
"expected_output": {
"lan": "EN",
"timezone": "UTC"
}
},
{
"metadata": {
"security": {
"_self": {"mapping_to": "security"},
"$credentials": {
"_self": {},
"$service": {
"username": {
"_self": {"mapping_to": "user"}
},
"password": {
"_self": {"mapping_to": "pass"}
}
}
}
},
"test": {
"_self": {"mapping_to": "test_section"},
"item1": {
"_self": {"mapping_to": "itema"}
},
"item2": {
"_self": {"mapping_to": "itemb"}
}
}
},
"config": {
"security": {
"service_credentials": {
"glance": {"username": "glance", "password": "glance"},
"identity": {"username": "keystone",
"password": "keystone"},
"dash": {"username": "dash", "password": "dash"}
},
"db_credentials": {
"mysql": {"username": "root", "password": "root"},
"rabbit_mq": {"username": "guest", "password": "guest"}
}
},
"test": {
"item1": "a",
"item2": "b"
}
},
"expected_output": {
"security": {
"service_credentials": {
"glance": {"user": "glance", "pass": "glance"},
"identity": {"user": "keystone", "pass": "keystone"},
"dash": {"user": "dash", "pass": "dash"}
},
"db_credentials": {
"mysql": {"user": "root", "pass": "root"},
"rabbit_mq": {"user": "guest", "pass": "guest"}
}
},
"test_section": {
"itema": "a",
"itemb": "b"
}
}
}
]

View File

@@ -20,7 +20,6 @@ __author__ = "Grace Yu (grace.yu@huawei.com)"
"""Test Chef installer functionalities regarding to chef server side.
"""
from copy import deepcopy
from mock import Mock
import os
import unittest2
@@ -33,6 +32,7 @@ from compass.utils import setting_wrapper as compass_setting
reload(compass_setting)
from compass.deployment.installers.config_manager import BaseConfigManager
from compass.deployment.installers.pk_installers.chef_installer.chef_installer\
import ChefInstaller
@@ -49,7 +49,7 @@ class TestChefInstaller(unittest2.TestCase):
def tearDown(self):
import chef
super(TestChefInstaller, self).tearDown()
databag_names = self.test_chef.config_manager.get_chef_databag_names()
databag_names = self.test_chef.get_chef_databag_names()
del self.test_chef
for obj in self.objects:
try:
@@ -65,16 +65,20 @@ class TestChefInstaller(unittest2.TestCase):
def _get_testchefapi(self):
import chef
url = 'https://api.opscode.com/organizations/compasscheftest'
return chef.ChefAPI(url, config_data.test_client_key, 'graceyu')
return chef.ChefAPI(config_data.test_chef_url,
config_data.test_client_key,
config_data.test_client)
def _register(self, obj):
self.objects.append(obj)
def _get_chef_installer(self):
adapter_info = deepcopy(config_data.adapter_test_config)
cluster_info = deepcopy(config_data.cluster_test_config)
hosts_info = deepcopy(config_data.hosts_test_config)
adapter_info = config_data.adapter_test_config
cluster_info = config_data.cluster_test_config
hosts_info = config_data.hosts_test_config
config_manager = BaseConfigManager(adapter_info, cluster_info,
hosts_info)
ChefInstaller.get_tmpl_path = Mock()
test_tmpl_dir = os.path.join(os.path.join(config_data.test_tmpl_dir,
@@ -84,7 +88,7 @@ class TestChefInstaller(unittest2.TestCase):
ChefInstaller._get_chef_api = Mock()
ChefInstaller._get_chef_api.return_value = self.chef_test_api
chef_installer = ChefInstaller(adapter_info, cluster_info, hosts_info)
chef_installer = ChefInstaller(config_manager)
return chef_installer
def test_update_node(self):
@@ -231,7 +235,7 @@ class TestChefInstaller(unittest2.TestCase):
}
}
self.test_chef.update_databags(vars_dict)
databag_names = self.test_chef.config_manager.get_chef_databag_names()
databag_names = self.test_chef.get_chef_databag_names()
for name in databag_names:
test_databag = chef.DataBag(name, self.chef_test_api)

View File

@@ -71,6 +71,12 @@ PACKAGE_FIELD_DIR = '/etc/compass/package_field'
ADAPTER_ROLE_DIR = '/etc/compass/role'
VALIDATOR_DIR = '/etc/compass/validator'
TMPL_DIR = '/etc/compass/templates'
# For test chef server. please replace these config info with your own.
TEST_CHEF_URL = "https://api.opscode.com/organizations/compasscheftest"
TEST_CLIENT_KEY_PATH = "/etc/compass/client.pem"
TEST_CLIENT_NAME = "graceyu"
if (
'COMPASS_IGNORE_SETTING' in os.environ and
os.environ['COMPASS_IGNORE_SETTING']