fuel-ccp-tests/fuel_ccp_tests/managers/ccpmanager.py

238 lines
8.6 KiB
Python

# Copyright 2016 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import yaml
from devops.error import DevopsCalledProcessError
from fuel_ccp_tests.helpers import exceptions
from fuel_ccp_tests import settings
from fuel_ccp_tests import logger
LOG = logger.logger
class CCPManager(object):
"""docstring for CCPManager"""
__config = None
__underlay = None
def __init__(self, config, underlay):
self.__config = config
self.__underlay = underlay
super(CCPManager, self).__init__()
def install_ccp(self, use_defaults=True):
"""Base action to deploy k8s by external deployment script"""
LOG.info("Trying to install fuel-ccp on admin node")
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
ccp_repo_url = settings.CCP_REPO
LOG.info("Fetch ccp from github")
cmd = 'git clone {}'.format(ccp_repo_url)
remote.check_call(cmd, verbose=True)
LOG.info('Install fuel-ccp from local path')
cmd = 'pip install --upgrade fuel-ccp/'
with remote.get_sudo(remote):
LOG.debug("*** Run cmd={0}".format(cmd))
result = remote.check_call(cmd, verbose=True)
LOG.debug("*** Result STDOUT:\n{0}".format(result.stdout_str))
LOG.debug("*** Result STDERR:\n{0}".format(result.stderr_str))
@property
def default_params(self):
if hasattr(self, '_default_params'):
return self._default_params.copy()
return None
@default_params.setter
def default_params(self, v):
self._default_params = v.copy()
def init_default_config(self, include_files=None):
self.put_yaml_config(settings.CCP_CLI_PARAMS["config-file"],
settings.CCP_CONF)
self.add_includes(settings.CCP_CLI_PARAMS["config-file"],
include_files)
def add_includes(self, path, files):
def clear_tilda(p):
return p.replace('~/', '')
content = "---\n!include\n{}".format(
'\n'.join(['- ' + clear_tilda(f) for f in files]))
cmd = 'echo "{content}" >> {path}'.format(
path=path, content=content)
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
remote.execute(cmd)
def put_raw_config(self, path, content):
"""Put config content to file on admin node at path
:param path: path to config file
:param config: raw configuration data
"""
cmd = "cat > {path} << EOF\n{content}\nEOF".format(
path=path, content=content)
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
remote.execute(cmd)
def get_raw_config(self, path):
"""Get config content from file at path on admin node
:param path: path to config file
:return: str
"""
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
return remote.open(path).read()
def put_yaml_config(self, path, config):
"""Convert config dict to yaml and put it to admin node at path
:param path: path to config file
:param config: dict with configuration data
"""
content = yaml.dump(config, default_flow_style=False)
cmd = "cat >> {path} << EOF\n{content}\nEOF".format(
path=path, content=content)
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
remote.execute(cmd)
def get_yaml_config(self, path):
"""Get config content from file at path on admin node
:param path: path to config file
:return: dict
"""
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
return yaml.load(remote.open(path))
def __build_param_string(self, params=None):
if params is None:
params = self.default_params
else:
merge = self.default_params.copy()
merge.update(params)
params = merge
return ' '.join(["--{}={}".format(
k, v) if v else "--{}".format(k) for (k, v) in params.items()])
def run(self, cmd, components=None, params=None,
use_cli_params=False, suppress_output=False,
raise_on_err=True, error_info=None,
expected=None):
if suppress_output:
ccp_out_redirect = ("> >(tee ccp.out.log > /dev/null) "
"2> >(tee ccp.err.log >/dev/null)")
else:
ccp_out_redirect = ""
if use_cli_params is True:
params = self.__build_param_string(params)
params = params or ''
if components:
if isinstance(components, str):
components = [components]
components = '-c {}'.format(' '.join(components))
else:
components = ''
cmd = ("ccp -v --debug {params} {cmd} {components}"
" {ccp_out_redirect}").format(
params=params, cmd=cmd, components=components,
ccp_out_redirect=ccp_out_redirect)
else:
cmd = "ccp -v --debug {cmd} {ccp_out_redirect}".format(
cmd=cmd, ccp_out_redirect=ccp_out_redirect)
LOG.info("Running {cmd}".format(cmd=cmd))
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
res = remote.check_call(cmd,
raise_on_err=raise_on_err,
error_info=error_info,
expected=expected,
verbose=True)
return res
def fetch(self,
params=None,
raise_on_err=True,
error_info=None,
expected=None):
# build config file
self.put_yaml_config(settings.CCP_FETCH_CONFIG, params)
return self.run('fetch',
raise_on_err=raise_on_err,
error_info=error_info,
expected=expected)
def build(self, components=None, params=None, suppress_output=True):
try:
self.run('build',
components=components,
params=params, suppress_output=suppress_output)
except DevopsCalledProcessError as e:
LOG.warning(e)
LOG.info("Retry build command")
self.run('build',
components=components,
params=params, suppress_output=suppress_output)
def deploy(self, components=None, params=None, use_cli_params=False):
self.run('deploy',
components=components,
params=params, use_cli_params=use_cli_params)
def dry_deploy(self, export_dir, components=None, params=None):
self.run('deploy --dry-run --export-dir={export_dir}'.format(
export_dir=export_dir),
components=components,
params=params)
def cleanup(self, components=None, params=None):
self.run('cleanup',
components=components,
params=params)
def show_dep(self, components=None, params=None):
self.run('show-dep',
components=components,
params=params)
def update_service(self, service_name, path=None):
if not settings.SERVICE_PATH and not path:
raise exceptions.VariableNotSet('SERVICE_PATH')
path = path or settings.SERVICE_PATH
with self.__underlay.remote(
host=self.__config.k8s.kube_host) as remote:
remote.execute(
'rm -rf ./ccp-repos/fuel-ccp-{}'
.format(service_name))
remote.upload(
path,
"/home/{user}/ccp-repos/fuel-ccp-{service}".format(
user=settings.SSH_LOGIN,
service=service_name))