243 lines
8.8 KiB
Python
243 lines
8.8 KiB
Python
# Copyright 2016 Red Hat, Inc.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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 copy
|
|
import logging
|
|
|
|
from heatclient import exc as heat_exc
|
|
from swiftclient import exceptions as swiftexceptions
|
|
|
|
from tripleo_common import constants
|
|
from tripleo_common.utils import nodes
|
|
from tripleo_common.utils import parameters as param_utils
|
|
from tripleo_common.utils import plan as plan_utils
|
|
from tripleo_common.utils import template as template_utils
|
|
from tripleo_common.utils import stack as stack_utils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def get_flattened_parameters(swift, heat,
|
|
container=constants.DEFAULT_CONTAINER_NAME):
|
|
cached = plan_utils.cache_get(
|
|
swift, container, "tripleo.parameters.get")
|
|
|
|
if cached is not None:
|
|
return cached
|
|
|
|
processed_data = template_utils.process_templates(
|
|
swift, heat, container=container
|
|
)
|
|
|
|
# respect previously user set param values
|
|
try:
|
|
env = plan_utils.get_env(swift, container)
|
|
except swiftexceptions.ClientException as err:
|
|
err_msg = ("Error retrieving environment for plan %s: %s" % (
|
|
container, err))
|
|
LOG.exception(err_msg)
|
|
raise RuntimeError(err_msg)
|
|
|
|
processed_data = stack_utils.validate_stack_and_flatten_parameters(
|
|
heat, processed_data, env)
|
|
|
|
plan_utils.cache_set(swift, container,
|
|
"tripleo.parameters.get", processed_data)
|
|
|
|
return processed_data
|
|
|
|
|
|
def update_parameters(swift, heat, parameters,
|
|
container=constants.DEFAULT_CONTAINER_NAME,
|
|
parameter_key=constants.DEFAULT_PLAN_ENV_KEY,
|
|
validate=True):
|
|
try:
|
|
env = plan_utils.get_env(swift, container)
|
|
except swiftexceptions.ClientException as err:
|
|
err_msg = ("Error retrieving environment for plan %s: %s" % (
|
|
container, err))
|
|
LOG.exception(err_msg)
|
|
raise RuntimeError(err_msg)
|
|
|
|
saved_env = copy.deepcopy(env)
|
|
try:
|
|
plan_utils.update_in_env(swift, env, parameter_key, parameters)
|
|
except swiftexceptions.ClientException as err:
|
|
err_msg = ("Error updating environment for plan %s: %s" % (
|
|
container, err))
|
|
LOG.exception(err_msg)
|
|
raise RuntimeError(err_msg)
|
|
|
|
processed_data = template_utils.process_templates(
|
|
swift, heat, container=container
|
|
)
|
|
|
|
env = plan_utils.get_env(swift, container)
|
|
|
|
if not validate:
|
|
return env
|
|
|
|
try:
|
|
processed_data = stack_utils.validate_stack_and_flatten_parameters(
|
|
heat, processed_data, env)
|
|
|
|
plan_utils.cache_set(swift, container,
|
|
"tripleo.parameters.get", processed_data)
|
|
except heat_exc.HTTPException as err:
|
|
LOG.debug("Validation failed rebuilding saved env")
|
|
|
|
# There has been an error validating we must reprocess the
|
|
# templates with the saved working env
|
|
plan_utils.put_env(swift, saved_env)
|
|
template_utils.process_custom_roles(swift, heat, container)
|
|
|
|
err_msg = ("Error validating environment for plan %s: %s" % (
|
|
container, err))
|
|
LOG.exception(err_msg)
|
|
raise RuntimeError(err_msg)
|
|
return processed_data
|
|
|
|
|
|
def reset_parameters(swift, container=constants.DEFAULT_CONTAINER_NAME,
|
|
key=constants.DEFAULT_PLAN_ENV_KEY):
|
|
try:
|
|
env = plan_utils.get_env(swift, container)
|
|
except swiftexceptions.ClientException as err:
|
|
err_msg = ("Error retrieving environment for plan %s: %s" % (
|
|
container, err))
|
|
LOG.exception(err_msg)
|
|
raise RuntimeError(err_msg)
|
|
|
|
try:
|
|
plan_utils.update_in_env(swift, env, key, None, delete_key=True)
|
|
except swiftexceptions.ClientException as err:
|
|
err_msg = ("Error updating environment for plan %s: %s" % (
|
|
container, err))
|
|
LOG.exception(err_msg)
|
|
raise RuntimeError(err_msg)
|
|
|
|
plan_utils.cache_delete(swift, container, "tripleo.parameters.get")
|
|
return env
|
|
|
|
|
|
def update_role_parameters(swift, heat, ironic, nova, role,
|
|
container=constants.DEFAULT_CONTAINER_NAME):
|
|
parameters = param_utils.set_count_and_flavor_params(role, ironic, nova)
|
|
return update_parameters(swift, heat, parameters, container)
|
|
|
|
|
|
def generate_fencing_parameters(ironic, compute, nodes_json, delay,
|
|
ipmi_level, ipmi_cipher, ipmi_lanplus):
|
|
hostmap = nodes.generate_hostmap(ironic, compute)
|
|
fence_params = {"EnableFencing": True, "FencingConfig": {}}
|
|
devices = []
|
|
nodes_json = nodes.convert_nodes_json_mac_to_ports(nodes_json)
|
|
|
|
for node in nodes_json:
|
|
node_data = {}
|
|
params = {}
|
|
if "ports" in node:
|
|
# Not all Ironic drivers present a MAC address, so we only
|
|
# capture it if it's present
|
|
mac_addr = node['ports'][0]['address'].lower()
|
|
node_data["host_mac"] = mac_addr
|
|
|
|
# If the MAC isn't in the hostmap, this node hasn't been
|
|
# provisioned, so no fencing parameters are necessary
|
|
if hostmap and mac_addr not in hostmap:
|
|
continue
|
|
|
|
# Build up fencing parameters based on which Ironic driver this
|
|
# node is using
|
|
try:
|
|
# Deprecated classic drivers (pxe_ipmitool, etc)
|
|
driver_proto = node['pm_type'].split('_')[1]
|
|
except IndexError:
|
|
# New-style hardware types (ipmi, etc)
|
|
driver_proto = node['pm_type']
|
|
|
|
if driver_proto in {'ipmi', 'ipmitool', 'drac', 'idrac', 'ilo',
|
|
'redfish'}:
|
|
if driver_proto == "redfish":
|
|
node_data["agent"] = "fence_redfish"
|
|
params["systems_uri"] = node["pm_system_id"]
|
|
else:
|
|
node_data["agent"] = "fence_ipmilan"
|
|
if ipmi_lanplus:
|
|
params["lanplus"] = ipmi_lanplus
|
|
params["ipaddr"] = node["pm_addr"]
|
|
params["passwd"] = node["pm_password"]
|
|
params["login"] = node["pm_user"]
|
|
if hostmap:
|
|
params["pcmk_host_list"] = \
|
|
hostmap[mac_addr]["compute_name"]
|
|
if "pm_port" in node:
|
|
params["ipport"] = node["pm_port"]
|
|
if "redfish_verify_ca" in node:
|
|
if node["redfish_verify_ca"] == "false":
|
|
params["ssl_insecure"] = "true"
|
|
else:
|
|
params["ssl_insecure"] = "false"
|
|
if delay:
|
|
params["delay"] = delay
|
|
if ipmi_cipher:
|
|
params["cipher"] = ipmi_cipher
|
|
if ipmi_level:
|
|
params["privlvl"] = ipmi_level
|
|
elif driver_proto in {'staging-ovirt'}:
|
|
# fence_rhevm
|
|
node_data["agent"] = "fence_rhevm"
|
|
params["ipaddr"] = node["pm_addr"]
|
|
params["passwd"] = node["pm_password"]
|
|
params["login"] = node["pm_user"]
|
|
params["port"] = node["pm_vm_name"]
|
|
params["ssl"] = 1
|
|
params["ssl_insecure"] = 1
|
|
if hostmap:
|
|
params["pcmk_host_list"] = \
|
|
hostmap[mac_addr]["compute_name"]
|
|
if delay:
|
|
params["delay"] = delay
|
|
else:
|
|
error = ("Unable to generate fencing parameters for %s" %
|
|
node["pm_type"])
|
|
raise ValueError(error)
|
|
|
|
node_data["params"] = params
|
|
devices.append(node_data)
|
|
|
|
fence_params["FencingConfig"]["devices"] = devices
|
|
return {"parameter_defaults": fence_params}
|
|
|
|
|
|
def get_network_configs(swift, heat, container, role_name):
|
|
processed_data = template_utils.process_templates(
|
|
swift, heat, container=container
|
|
)
|
|
|
|
# Default temporary value is used when no user input for any
|
|
# interface routes for the role networks to find network config.
|
|
role_networks = processed_data['template'].get('resources', {}).get(
|
|
role_name + 'GroupVars', {}).get('properties', {}).get(
|
|
'value', {}).get('role_networks', [])
|
|
for nw in role_networks:
|
|
rt = nw + 'InterfaceRoutes'
|
|
if rt not in processed_data['environment']['parameter_defaults']:
|
|
processed_data['environment']['parameter_defaults'][rt] = [[]]
|
|
|
|
network_configs = stack_utils.preview_stack_and_network_configs(
|
|
heat, processed_data, container, role_name)
|
|
return network_configs
|