The client utils will now run a new playbook to ensure that the local archive directory is created early in the deployment process. This change will allow us to build toward a swift-less deployment. All of the client calls, save one, has been moved to use tripleo-common which will assist us to better manage, and migrate from swift storage to a local archive. > As a product of this change all of the "webhook" calls have been removed. which was deprecated as part of the Zaqar and Mistral work. These calls were removed because several swift calls were tied into them, and because mistral is no longer part of the stack, and has been gone for a few cycles, we can safely remove these calls which do nothing. Depends-On: Ibe9b2ffe94cdf493fc84366979d1d78b8528ea1b Change-Id: I7531612a49527f8a21df415c648acb41ac7a0b10 Signed-off-by: Kevin Carter <kecarter@redhat.com>
203 lines
7.0 KiB
Python
203 lines
7.0 KiB
Python
# Copyright 2019 Red Hat, 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 json
|
|
import logging
|
|
import os
|
|
import re
|
|
import yaml
|
|
|
|
from osc_lib.i18n import _
|
|
|
|
from tripleo_common import constants as tripleo_common_constants
|
|
from tripleo_common.utils import swift as swiftutils
|
|
from tripleoclient import constants
|
|
from tripleoclient import utils as oooutils
|
|
|
|
|
|
LOG = logging.getLogger(__name__ + ".utils")
|
|
|
|
|
|
def export_passwords(swift, stack, excludes=True):
|
|
# Export the passwords from swift
|
|
obj = 'plan-environment.yaml'
|
|
container = stack
|
|
content = swiftutils.get_object_string(
|
|
swift,
|
|
container=container,
|
|
object_name=obj
|
|
)
|
|
data = yaml.safe_load(content)
|
|
# The "passwords" key in plan-environment.yaml are generated passwords,
|
|
# they are not necessarily the actual password values used during the
|
|
# deployment.
|
|
generated_passwords = data["passwords"]
|
|
# parameter_defaults will contain any user defined password values
|
|
parameters = data["parameter_defaults"]
|
|
|
|
passwords = {}
|
|
|
|
# For each password, check if it's excluded, then check if there's a user
|
|
# defined value from parameter_defaults, and if not use the value from the
|
|
# generated passwords.
|
|
def exclude_password(password):
|
|
for pattern in constants.EXPORT_PASSWORD_EXCLUDE_PATTERNS:
|
|
return re.match(pattern, password, re.I)
|
|
|
|
for password in tripleo_common_constants.PASSWORD_PARAMETER_NAMES:
|
|
if exclude_password(password):
|
|
continue
|
|
if password in parameters:
|
|
passwords[password] = parameters[password]
|
|
elif password in generated_passwords:
|
|
passwords[password] = generated_passwords[password]
|
|
else:
|
|
LOG.warning("No password value found for %s", password)
|
|
|
|
return passwords
|
|
|
|
|
|
def export_stack(heat, stack, should_filter=False,
|
|
config_download_dir=constants.DEFAULT_WORK_DIR):
|
|
|
|
# data to export
|
|
# parameter: Parameter to be exported
|
|
# file: IF file specified it is taken as source instead of heat
|
|
# output.File is relative to <config-download-dir>/stack.
|
|
# filter: in case only specific settings should be
|
|
# exported from parameter data.
|
|
export_data = {
|
|
"EndpointMap": {
|
|
"parameter": "EndpointMapOverride",
|
|
},
|
|
"HostsEntry": {
|
|
"parameter": "ExtraHostFileEntries",
|
|
},
|
|
"GlobalConfig": {
|
|
"parameter": "GlobalConfigExtraMapData",
|
|
},
|
|
"AllNodesConfig": {
|
|
"file": "group_vars/overcloud.json",
|
|
"parameter": "AllNodesExtraMapData",
|
|
"filter": ["oslo_messaging_notify_short_bootstrap_node_name",
|
|
"oslo_messaging_notify_node_names",
|
|
"oslo_messaging_rpc_node_names",
|
|
"memcached_node_ips",
|
|
"ovn_dbs_vip",
|
|
"redis_vip"]},
|
|
}
|
|
|
|
data = {}
|
|
heat_stack = oooutils.get_stack(heat, stack)
|
|
|
|
for export_key, export_param in export_data.items():
|
|
param = export_param["parameter"]
|
|
if "file" in export_param:
|
|
# get file data
|
|
file = os.path.join(config_download_dir,
|
|
stack,
|
|
export_param["file"])
|
|
with open(file, 'r') as ff:
|
|
try:
|
|
export_data = json.load(ff)
|
|
except Exception as e:
|
|
LOG.error(
|
|
_('Could not read file %s') % file)
|
|
LOG.error(e)
|
|
|
|
else:
|
|
# get stack data
|
|
export_data = oooutils.get_stack_output_item(
|
|
heat_stack, export_key)
|
|
|
|
if export_data:
|
|
# When we export information from a cell controller stack
|
|
# we don't want to filter.
|
|
if "filter" in export_param and should_filter:
|
|
for filter_key in export_param["filter"]:
|
|
if filter_key in export_data:
|
|
element = {filter_key: export_data[filter_key]}
|
|
data.setdefault(param, {}).update(element)
|
|
else:
|
|
data[param] = export_data
|
|
|
|
else:
|
|
raise Exception(
|
|
"No data returned to export %s from." % param)
|
|
|
|
return data
|
|
|
|
|
|
def export_storage_ips(stack, config_download_dir=constants.DEFAULT_WORK_DIR):
|
|
inventory_file = "ceph-ansible/inventory.yml"
|
|
file = os.path.join(config_download_dir, stack, inventory_file)
|
|
with open(file, 'r') as ff:
|
|
try:
|
|
inventory_data = yaml.safe_load(ff)
|
|
except Exception as e:
|
|
LOG.error(
|
|
_('Could not read file %s') % file)
|
|
LOG.error(e)
|
|
mon_ips = []
|
|
for mon_role in inventory_data['mons']['children'].keys():
|
|
for hostname in inventory_data[mon_role]['hosts']:
|
|
ip = inventory_data[mon_role]['hosts'][hostname]['storage_ip']
|
|
mon_ips.append(ip)
|
|
|
|
return mon_ips
|
|
|
|
|
|
def export_ceph(stack, cephx,
|
|
config_download_dir=constants.DEFAULT_WORK_DIR,
|
|
mon_ips=[]):
|
|
# Return a map of ceph data for a list item in CephExternalMultiConfig
|
|
# by parsing files within the config_download_dir of a certain stack
|
|
|
|
if len(mon_ips) == 0:
|
|
mon_ips = export_storage_ips(stack, config_download_dir)
|
|
|
|
# Use ceph-ansible group_vars/all.yml to get remaining values
|
|
ceph_ansible_all = "ceph-ansible/group_vars/all.yml"
|
|
file = os.path.join(config_download_dir, stack, ceph_ansible_all)
|
|
with open(file, 'r') as ff:
|
|
try:
|
|
ceph_data = yaml.safe_load(ff)
|
|
except Exception as e:
|
|
LOG.error(
|
|
_('Could not read file %s') % file)
|
|
LOG.error(e)
|
|
|
|
for key in ceph_data['keys']:
|
|
if key['name'] == 'client.' + str(cephx):
|
|
cephx_keys = [key]
|
|
|
|
ceph_conf_overrides = {}
|
|
ceph_conf_overrides['client'] = {}
|
|
ceph_conf_overrides['client']['keyring'] = '/etc/ceph/' \
|
|
+ ceph_data['cluster'] \
|
|
+ '.client.' + cephx \
|
|
+ '.keyring'
|
|
# Combine extracted data into one map to return
|
|
data = {}
|
|
data['external_cluster_mon_ips'] = str(','.join(mon_ips))
|
|
data['keys'] = cephx_keys
|
|
data['ceph_conf_overrides'] = ceph_conf_overrides
|
|
data['cluster'] = ceph_data['cluster']
|
|
data['fsid'] = ceph_data['fsid']
|
|
data['dashboard_enabled'] = False
|
|
|
|
return data
|