resource_registry) which represent nested stacks
for each service that should get installed on the {{role.name}} role.
type: comma_delimited_list
- {% if role.ServicesDefault %}
- default: {{role.ServicesDefault}}
- {% endif %}
+ default: {{role.ServicesDefault|default([])}}
{{role.name}}Count:
description: Number of {{role.name}} nodes to deploy
type: number
- {% if role.CountDefault %}
- default: {{role.CountDefault}}
- {% endif %}
+ default: {{role.CountDefault|default(0)}}
{{role.name}}HostnameFormat:
type: string
and %stackname% is replaced with the stack name e.g overcloud
{% if role.HostnameFormatDefault %}
default: "{{role.HostnameFormatDefault}}"
+ {% else %}
+ default: "%stackname%-{{role.name.lower()}}-%index%"
{% endif %}
{{role.name}}RemovalPolicies:
List of resources to be removed from {{role.name}} ResourceGroup when
doing an update which requires removal of specific resources.
Example format ComputeRemovalPolicies: [{'resource_list': ['0']}]
+
+{% if role.name != 'Compute' %}
+ {{role.name}}SchedulerHints:
+{% else %}
+ NovaComputeSchedulerHints:
+{% endif %}
+ type: json
+ description: Optional scheduler hints to pass to nova
+ default: {}
{% endfor %}
# Identifiers to trigger tasks on nodes
EnabledServices: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
ServiceHostnameList: {get_attr: [{{role.name}}, hostname]}
+ NetworkHostnameMap:
+ # Note (shardy) this somewhat complex yaql may be replaced
+ # with a map_deep_merge function in ocata. It merges the
+ # list of maps, but appends to colliding lists so we can
+ # create a map of lists for all nodes for each network
+ yaql:
+ expression: dict($.data.where($ != null).flatten().selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
+ data:
+ - {get_attr: [{{role.name}}, hostname_map]}
{{role.name}}:
type: OS::Heat::ResourceGroup
params:
'%stackname%': {get_param: 'OS::stack_name'}
NodeIndex: '%index%'
+ {% if role.name != 'Compute' %}
+ {{role.name}}SchedulerHints: {get_param: {{role.name}}SchedulerHints}
+ {% else %}
+ NovaComputeSchedulerHints: {get_param: NovaComputeSchedulerHints}
+ {% endif %}
ServiceConfigSettings:
map_merge:
- get_attr: [{{role.name}}ServiceChain, role_data, config_settings]
{% for r in roles %}
- get_attr: [{{r.name}}ServiceChain, role_data, global_config_settings]
{% endfor %}
+ # This next step combines two yaql passes:
+ # - The inner one does a deep merge on the service_config_settings for all roles
+ # - The outer one filters the map based on the services enabled for the role
+ # then merges the result into one map.
+ - yaql:
+ expression: let(root => $) -> $.data.map.items().where($[0] in $root.data.services).select($[1]).reduce($1.mergeWith($2), {})
+ data:
+ map:
+ yaql:
+ expression: $.data.where($ != null).reduce($1.mergeWith($2), {})
+ data:
+ {% for r in roles %}
+ - get_attr: [{{r.name}}ServiceChain, role_data, service_config_settings]
+ {% endfor %}
+ services: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
ServiceNames: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
MonitoringSubscriptions: {get_attr: [{{role.name}}ServiceChain, role_data, monitoring_subscriptions]}
- LoggingSources: {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
- LoggingGroups: {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
{% endfor %}
allNodesConfig:
- ','
{% for role in roles %}
- {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
+{% endfor %}
+ logging_groups:
+ yaql:
+ expression: >
+ $.data.groups.flatten()
+ data:
+ groups:
+{% for role in roles %}
+ - {get_attr: [{{role.name}}ServiceChain, role_data, logging_groups]}
+{% endfor %}
+ logging_sources:
+ yaql:
+ expression: >
+ $.data.sources.flatten()
+ data:
+ sources:
+{% for role in roles %}
+ - {get_attr: [{{role.name}}ServiceChain, role_data, logging_sources]}
{% endfor %}
controller_ips: {get_attr: [Controller, ip_address]}
controller_names: {get_attr: [Controller, hostname]}
l:
{% for role in roles %}
- {get_attr: [{{role.name}}IpListMap, service_hostnames]}
+{% endfor %}
+ short_service_node_names:
+ yaql:
+ expression: dict($.data.l.where($ != null).selectMany($.items()).groupBy($[0], $[1], [$[0], $[1].flatten()]))
+ data:
+ l:
+{% for role in roles %}
+ - {get_attr: [{{role.name}}IpListMap, short_service_hostnames]}
{% endfor %}
# FIXME(shardy): These require further work to move into service_ips
memcache_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, MemcachedNetwork]}]}
- keystone_public_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystonePublicApiNetwork]}]}
- keystone_admin_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_attr: [ServiceNetMap, service_net_map, KeystoneAdminApiNetwork]}]}
NetVipMap: {get_attr: [VipMap, net_ip_map]}
RedisVirtualIP: {get_attr: [RedisVirtualIP, ip_address]}
ServiceNetMap: {get_attr: [ServiceNetMap, service_net_map_lower]}
UpdateWorkflow:
type: OS::TripleO::Tasks::UpdateWorkflow
+ depends_on:
+{% for role in roles %}
+ - {{role.name}}AllNodesDeployment
+{% endfor %}
properties:
servers:
{% for role in roles %}
The content that should be appended to your /etc/hosts if you want to get
hostname-based access to the deployed nodes (useful for testing without
setting up a DNS).
- value: {get_attr: [allNodesConfig, hosts_entries]}
+ value:
+ list_join:
+ - "\n"
+ - - {get_attr: [allNodesConfig, hosts_entries]}
+ -
+ - str_replace:
+ template: IP HOST
+ params:
+ IP: {get_attr: [VipMap, net_ip_map, external]}
+ HOST: {get_param: CloudName}
+ - str_replace:
+ template: IP HOST
+ params:
+ IP: {get_attr: [VipMap, net_ip_map, ctlplane]}
+ HOST: {get_param: CloudNameCtlplane}
+ - str_replace:
+ template: IP HOST
+ params:
+ IP: {get_attr: [VipMap, net_ip_map, internal_api]}
+ HOST: {get_param: CloudNameInternal}
+ - str_replace:
+ template: IP HOST
+ params:
+ IP: {get_attr: [VipMap, net_ip_map, storage]}
+ HOST: {get_param: CloudNameStorage}
+ - str_replace:
+ template: IP HOST
+ params:
+ IP: {get_attr: [VipMap, net_ip_map, storage_mgmt]}
+ HOST: {get_param: CloudNameStorageManagement}
EnabledServices:
description: The services enabled on each role
value:
- Controller: {get_attr: [ControllerServiceChain, role_data, service_names]}
- Compute: {get_attr: [ComputeServiceChain, role_data, service_names]}
- BlockStorage: {get_attr: [BlockStorageServiceChain, role_data, service_names]}
- ObjectStorage: {get_attr: [ObjectStorageServiceChain, role_data, service_names]}
- CephStorage: {get_attr: [CephStorageServiceChain, role_data, service_names]}
+{% for role in roles %}
+ {{role.name}}: {get_attr: [{{role.name}}ServiceChain, role_data, service_names]}
+{% endfor %}