You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
11 KiB
253 lines
11 KiB
{%- set _networks = [] -%} |
|
{%- for network in networks -%} |
|
{%- set _networks = _networks.append(network.name) -%} |
|
{%- endfor -%} |
|
heat_template_version: rocky |
|
description: 'All Nodes Config for Puppet' |
|
|
|
parameters: |
|
{%- for network in networks if network.vip|default(false) %} |
|
cloud_name_{{network.name_lower}}: |
|
type: string |
|
{%- endfor %} |
|
cloud_name_ctlplane: |
|
type: string |
|
enabled_services: |
|
type: comma_delimited_list |
|
controller_ips: |
|
type: comma_delimited_list |
|
service_ips: |
|
type: json |
|
service_node_names: |
|
type: json |
|
short_service_node_names: |
|
type: json |
|
short_service_bootstrap_node: |
|
type: json |
|
service_bootstrap_node_ip: |
|
type: json |
|
controller_names: |
|
type: comma_delimited_list |
|
cellv2_discovery_hosts: |
|
type: comma_delimited_list |
|
NetVipMap: |
|
type: json |
|
RedisVirtualIP: |
|
type: string |
|
default: '' |
|
ServiceNetMap: |
|
type: json |
|
DeployIdentifier: |
|
type: string |
|
default: '' |
|
description: > |
|
Setting this to a unique value will re-run any deployment tasks which |
|
perform configuration on a Heat stack-update. |
|
UpdateIdentifier: |
|
type: string |
|
default: '' |
|
description: > |
|
Setting to a previously unused value during stack-update will trigger |
|
package update on all nodes |
|
StackAction: |
|
type: string |
|
description: > |
|
Heat action on performed top-level stack. Note StackUpdateType is |
|
set to UPGRADE when a major-version upgrade is in progress. |
|
constraints: |
|
- allowed_values: ['CREATE', 'UPDATE'] |
|
StackUpdateType: |
|
type: string |
|
description: > |
|
Type of update, to differentiate between UPGRADE and UPDATE cases |
|
when StackAction is UPDATE (both are the same stack action). |
|
constraints: |
|
- allowed_values: ['', 'UPGRADE', 'FASTFORWARDUPGRADE'] |
|
default: '' |
|
EnableInternalTLS: |
|
type: boolean |
|
default: false |
|
AllNodesExtraMapData: |
|
type: json |
|
default: {} |
|
description: Map of extra data (hieradata) to set on each node. |
|
|
|
{%- for network in networks %} |
|
{{network.name}}NetName: |
|
default: {{network.name_lower}} |
|
description: The name of the {{network.name_lower}} network. |
|
type: string |
|
{%- endfor %} |
|
ContainerCli: |
|
type: string |
|
default: 'docker' |
|
description: CLI tool used to manage containers. |
|
constraints: |
|
- allowed_values: ['docker', 'podman'] |
|
|
|
resources: |
|
|
|
allNodesConfigValue: |
|
type: OS::Heat::Value |
|
properties: |
|
value: |
|
yaql: |
|
expression: $.data.all_nodes_extra_map_data.mergeWith($.data.all_nodes) |
|
data: |
|
all_nodes_extra_map_data: {get_param: AllNodesExtraMapData} |
|
all_nodes: |
|
map_merge: |
|
- enabled_services: |
|
yaql: |
|
expression: $.data.distinct() |
|
data: {get_param: enabled_services} |
|
# This writes out a mapping of service_name_enabled: 'true' |
|
# For any services not enabled, hiera foo_enabled will |
|
# return nil, as it's undefined |
|
- map_merge: |
|
repeat: |
|
template: |
|
# Note this must be string 'true' due to |
|
# https://bugs.launchpad.net/heat/+bug/1617203 |
|
SERVICE_enabled: 'true' |
|
for_each: |
|
SERVICE: {get_param: enabled_services} |
|
# Dynamically generate per-service network data |
|
# This works as follows (outer->inner functions) |
|
# yaql - filters services where no mapping exists in ServiceNetMap |
|
# map_replace: substitute e.g heat_api_network with network name from ServiceNetMap |
|
# map_merge/repeat: generate a per-service mapping |
|
- yaql: |
|
# This filters any entries where the value hasn't been substituted for |
|
# a list, e.g it's still $service_network. This happens when there is |
|
# no network defined for the service in the ServiceNetMap, which is OK |
|
# as not all services have to be bound to a network, so we filter them |
|
expression: dict($.data.map.items().where(isString($[1]) and not $[1].endsWith("_network"))) |
|
data: |
|
map: |
|
map_replace: |
|
- map_merge: |
|
repeat: |
|
template: |
|
SERVICE_network: SERVICE_network |
|
for_each: |
|
SERVICE: {get_param: enabled_services} |
|
- values: {get_param: ServiceNetMap} |
|
# Keystone doesn't provide separate entries for the public |
|
# and admin endpoints, so we need to add them here manually |
|
# like we do in the vip-config below |
|
- keystone_admin_api_network: {get_param: [ServiceNetMap, keystone_admin_api_network]} |
|
keystone_public_api_network: {get_param: [ServiceNetMap, keystone_public_api_network]} |
|
# provides a mapping of service_name_ips to a list of IPs |
|
- {get_param: service_ips} |
|
- {get_param: service_node_names} |
|
- {get_param: short_service_node_names} |
|
- {get_param: short_service_bootstrap_node} |
|
- {get_param: service_bootstrap_node_ip} |
|
- controller_node_ips: |
|
list_join: |
|
- ',' |
|
- {get_param: controller_ips} |
|
controller_node_names: |
|
list_join: |
|
- ',' |
|
- {get_param: controller_names} |
|
- cellv2_discovery_hosts: |
|
list_join: |
|
- ',' |
|
- {get_param: cellv2_discovery_hosts} |
|
deploy_identifier: {get_param: DeployIdentifier} |
|
stack_action: {get_param: StackAction} |
|
stack_update_type: {get_param: StackUpdateType} |
|
container_cli: {get_param: ContainerCli} |
|
|
|
allNodesConfigImpl: |
|
type: OS::Heat::StructuredConfig |
|
properties: |
|
group: hiera |
|
config: |
|
datafiles: |
|
bootstrap_node: |
|
bootstrap_nodeid: {get_input: bootstrap_nodeid} |
|
all_nodes: {get_attr: [allNodesConfigValue, value]} |
|
vip_data: |
|
map_merge: |
|
# Dynamically generate per-service VIP data based on enabled_services |
|
# This works as follows (outer->inner functions) |
|
# yaql - filters services where no mapping exists in ServiceNetMap |
|
# map_replace: substitute e.g internal_api with the IP from NetVipMap |
|
# map_replace: substitute e.g heat_api_network with network name from ServiceNetMap |
|
# map_merge/repeat: generate a per-service mapping |
|
- yaql: |
|
# This filters any entries where the value hasn't been substituted for |
|
# a list, e.g it's still $service_network. This happens when there is |
|
# no network defined for the service in the ServiceNetMap, which is OK |
|
# as not all services have to be bound to a network, so we filter them |
|
expression: dict($.data.map.items().where(isString($[1]) and not $[1].endsWith("_network"))) |
|
data: |
|
map: |
|
map_replace: |
|
- map_replace: |
|
- map_merge: |
|
repeat: |
|
template: |
|
SERVICE_vip: SERVICE_network |
|
for_each: |
|
SERVICE: {get_param: enabled_services} |
|
- values: {get_param: ServiceNetMap} |
|
- values: {get_param: NetVipMap} |
|
- keystone_admin_api_vip: |
|
get_param: [NetVipMap, {get_param: [ServiceNetMap, keystone_admin_api_network]}] |
|
keystone_public_api_vip: |
|
get_param: [NetVipMap, {get_param: [ServiceNetMap, keystone_public_api_network]}] |
|
{%- if 'External' in _networks %} |
|
public_virtual_ip: {get_param: [NetVipMap, {get_param: ExternalNetName}]} |
|
{%- else %} |
|
public_virtual_ip: {get_param: [NetVipMap, ctlplane]} |
|
{%- endif %} |
|
controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} |
|
{%- if 'InternalApi' in _networks %} |
|
# the internal_api_virtual_ip is needed for contrail only |
|
internal_api_virtual_ip: {get_param: [NetVipMap, {get_param: InternalApiNetName}]} |
|
{%- endif %} |
|
network_virtual_ips: |
|
{%- for network in networks if network.vip|default(false) %} |
|
# External virtual ip is currently being handled separately as public_virtual_ip. |
|
# Likewise, optional StorageNFS virtual ip is handled separately as ganesha_vip. |
|
{%- if network.name != 'External' and network.name != 'StorageNFS' %} |
|
{{network.name_lower}}: |
|
ip_address: {get_param: [NetVipMap, {get_param: {{network.name}}NetName}]} |
|
index: {{loop.index}} |
|
{%- endif %} |
|
{%- endfor %} |
|
redis_vip: {get_param: RedisVirtualIP} |
|
{%- for network in networks if network.name == 'StorageNFS' %} |
|
ganesha_vip: {get_param: [NetVipMap, {get_param: StorageNFSNetName}]} |
|
{%- endfor %} |
|
# public_virtual_ip and controller_virtual_ip are needed in |
|
# both HAproxy & keepalived. |
|
{%- if 'External' in _networks %} |
|
tripleo::haproxy::public_virtual_ip: {get_param: [NetVipMap, {get_param: ExternalNetName}]} |
|
tripleo::keepalived::public_virtual_ip: {get_param: [NetVipMap, {get_param: ExternalNetName}]} |
|
{%- else %} |
|
tripleo::haproxy::public_virtual_ip: {get_param: [NetVipMap, ctlplane]} |
|
tripleo::keepalived::public_virtual_ip: {get_param: [NetVipMap, ctlplane]} |
|
{%- endif %} |
|
tripleo::haproxy::controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} |
|
tripleo::keepalived::controller_virtual_ip: {get_param: [NetVipMap, ctlplane]} |
|
tripleo::keepalived::redis_virtual_ip: {get_param: RedisVirtualIP} |
|
tripleo::redis_notification::haproxy_monitor_ip: {get_param: [NetVipMap, ctlplane]} |
|
{%- for network in networks if network.vip|default(false) %} |
|
cloud_name_{{network.name_lower}}: {get_param: cloud_name_{{network.name_lower}}} |
|
{%- endfor %} |
|
cloud_name_ctlplane: {get_param: cloud_name_ctlplane} |
|
enable_internal_tls: {get_param: EnableInternalTLS} |
|
|
|
outputs: |
|
config_id: |
|
description: The ID of the allNodesConfigImpl resource. |
|
value: |
|
{get_resource: allNodesConfigImpl} |
|
all_nodes_config: |
|
description: The all_nodes hieradata config |
|
value: {get_attr: [allNodesConfigValue, value]}
|
|
|