Merge "Drop deprecated templates/Makefile/merge.py"
This commit is contained in:
commit
a3a6b30d10
49
Makefile
49
Makefile
@ -1,49 +0,0 @@
|
||||
generated_templates = \
|
||||
overcloud.yaml \
|
||||
overcloud-with-block-storage-nfs.yaml \
|
||||
undercloud-vm.yaml \
|
||||
undercloud-bm.yaml \
|
||||
undercloud-vm-ironic.yaml \
|
||||
undercloud-vm-ironic-vlan.yaml
|
||||
|
||||
# Files included in deprecated/overcloud-source.yaml via FileInclude
|
||||
overcloud_source_deps = deprecated/nova-compute-instance.yaml
|
||||
|
||||
all: $(generated_templates)
|
||||
VALIDATE := $(patsubst %,validate-%,$(generated_templates))
|
||||
validate-all: $(VALIDATE)
|
||||
$(VALIDATE):
|
||||
heat template-validate -f $(subst validate-,,$@)
|
||||
|
||||
# You can define in CONTROLEXTRA one or more additional YAML files to further extend the template, some additions could be:
|
||||
# - overcloud-vlan-port.yaml to activate the VLAN auto-assignment from Neutron
|
||||
# - nfs-source.yaml to configure Cinder with NFS
|
||||
overcloud.yaml: deprecated/overcloud-source.yaml deprecated/block-storage.yaml deprecated/swift-deploy.yaml deprecated/swift-source.yaml deprecated/swift-storage-source.yaml deprecated/ssl-source.yaml deprecated/nova-compute-config.yaml $(overcloud_source_deps)
|
||||
python ./tripleo_heat_merge/merge.py --hot --scale NovaCompute=$${COMPUTESCALE:-'1'} --scale controller=$${CONTROLSCALE:-'1'} --scale SwiftStorage=$${SWIFTSTORAGESCALE:-'0'} --scale BlockStorage=$${BLOCKSTORAGESCALE:-'0'} --scale CephStorage=$${CEPHSTORAGESCALE:-'0'} deprecated/overcloud-source.yaml deprecated/block-storage.yaml deprecated/swift-source.yaml deprecated/swift-storage-source.yaml deprecated/ssl-source.yaml deprecated/swift-deploy.yaml deprecated/nova-compute-config.yaml ${CONTROLEXTRA} > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
undercloud-vm.yaml: deprecated/undercloud-source.yaml deprecated/undercloud-vm-nova-config.yaml deprecated/undercloud-vm-nova-deploy.yaml
|
||||
python ./tripleo_heat_merge/merge.py --hot $^ > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
undercloud-bm.yaml: deprecated/undercloud-source.yaml deprecated/undercloud-bm-nova-config.yaml deprecated/undercloud-bm-nova-deploy.yaml
|
||||
python ./tripleo_heat_merge/merge.py --hot $^ > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
undercloud-vm-ironic.yaml: deprecated/undercloud-source.yaml deprecated/undercloud-vm-ironic-config.yaml deprecated/undercloud-vm-ironic-deploy.yaml
|
||||
python ./tripleo_heat_merge/merge.py --hot $^ > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
undercloud-vm-ironic-vlan.yaml: deprecated/undercloud-source.yaml deprecated/undercloud-vm-ironic-config.yaml deprecated/undercloud-vm-ironic-deploy.yaml deprecated/undercloud-vlan-port.yaml
|
||||
python ./tripleo_heat_merge/merge.py --hot $^ > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
check: test
|
||||
|
||||
test:
|
||||
@bash test_merge.bash
|
||||
|
||||
clean:
|
||||
rm -f $(generated_templates)
|
||||
|
||||
.PHONY: clean overcloud.yaml check
|
@ -29,8 +29,6 @@ Directories
|
||||
|
||||
A description of the directory layout in TripleO Heat Templates.
|
||||
|
||||
* deprecated: contains templates that have been deprecated
|
||||
|
||||
* environments: contains heat environment files that can be used with -e
|
||||
on the command like to enable features, etc.
|
||||
|
||||
|
@ -1,92 +0,0 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'Common Block Storage Configuration'
|
||||
parameters:
|
||||
BlockStorageImage:
|
||||
type: string
|
||||
default: overcloud-cinder-volume
|
||||
OvercloudBlockStorageFlavor:
|
||||
description: Flavor for block storage nodes to request when deploying.
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.flavor
|
||||
BlockStorageExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
Controller specific configuration to inject into the cluster. Same
|
||||
structure as ExtraConfig.
|
||||
type: json
|
||||
resources:
|
||||
BlockStorage0:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image:
|
||||
{get_param: BlockStorageImage}
|
||||
flavor: {get_param: OvercloudBlockStorageFlavor}
|
||||
key_name: {get_param: KeyName}
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
BlockStorage0AllNodesDeployment:
|
||||
depends_on: [BlockStorage0Deployment,BlockStorage0PassthroughSpecific]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
signal_transport: {get_param: DefaultSignalTransport}
|
||||
config: {get_resource: allNodesConfig}
|
||||
server: {get_resource: BlockStorage0}
|
||||
BlockStorage0Deployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
server: {get_resource: BlockStorage0}
|
||||
config: {get_resource: BlockStorageConfig}
|
||||
input_values:
|
||||
controller_virtual_ip: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
cinder_dsn: {"Fn::Join": ['', ['mysql://cinder:unset@', {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]} , '/cinder']]}
|
||||
signal_transport: NO_SIGNAL
|
||||
BlockStorage0Passthrough:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: BlockStoragePassthrough}
|
||||
server: {get_resource: BlockStorage0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config: {get_param: ExtraConfig}
|
||||
BlockStorage0PassthroughSpecific:
|
||||
depends_on: [BlockStorage0Passthrough]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: BlockStoragePassthroughSpecific}
|
||||
server: {get_resource: BlockStorage0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config_specific: {get_param: BlockStorageExtraConfig}
|
||||
BlockStorageConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
admin-password: {get_param: AdminPassword}
|
||||
keystone:
|
||||
host: {get_input: controller_virtual_ip}
|
||||
cinder:
|
||||
db: {get_input: cinder_dsn}
|
||||
volume_size_mb:
|
||||
get_param: CinderLVMLoopDeviceSize
|
||||
service-password:
|
||||
get_param: CinderPassword
|
||||
iscsi-helper:
|
||||
get_param: CinderISCSIHelper
|
||||
rabbit:
|
||||
host: {get_input: controller_virtual_ip}
|
||||
username: {get_param: RabbitUserName}
|
||||
password: {get_param: RabbitPassword}
|
||||
glance:
|
||||
host: {get_input: controller_virtual_ip}
|
||||
port: {get_param: GlancePort}
|
||||
BlockStoragePassthrough:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config: {get_input: passthrough_config}
|
||||
BlockStoragePassthroughSpecific:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config: {get_input: passthrough_config_specific}
|
@ -1,36 +0,0 @@
|
||||
resources:
|
||||
controllerNfsServerConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
nfs_server:
|
||||
shares:
|
||||
- name: cinder
|
||||
clients:
|
||||
- machine: 192.0.2.0/24
|
||||
options: rw,async,all_squash,anonuid=0,anongid=0
|
||||
controllerCinderNfsConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
cinder:
|
||||
include_nfs_backend: true
|
||||
nfs_shares:
|
||||
Fn::Join:
|
||||
- ':'
|
||||
- - {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
- /mnt/state/var/lib/nfs/cinder
|
||||
controllerNfsServerDeployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: controllerNfsServerConfig}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
controller0CinderNfsDeployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: controllerCinderNfsConfig}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
@ -1,69 +0,0 @@
|
||||
resources:
|
||||
NovaComputeConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
nova:
|
||||
compute_driver: { get_input: nova_compute_driver }
|
||||
compute_libvirt_type: { get_input: nova_compute_libvirt_type }
|
||||
debug: {get_param: Debug}
|
||||
host: {get_input: nova_api_host}
|
||||
public_ip: {get_input: nova_public_ip}
|
||||
service-password: {get_input: nova_password}
|
||||
ceilometer:
|
||||
debug: {get_param: Debug}
|
||||
metering_secret: {get_input: ceilometer_metering_secret}
|
||||
service-password: {get_input: ceilometer_password}
|
||||
compute_agent: {get_input: ceilometer_compute_agent}
|
||||
snmpd:
|
||||
export_MIB: UCD-SNMP-MIB
|
||||
readonly_user_name: {get_input: snmpd_readonly_user_name}
|
||||
readonly_user_password: {get_input: snmpd_readonly_user_password}
|
||||
glance:
|
||||
debug: {get_param: Debug}
|
||||
host: {get_input: glance_host}
|
||||
port: {get_input: glance_port}
|
||||
protocol: {get_input: glance_protocol}
|
||||
keystone:
|
||||
debug: {get_param: Debug}
|
||||
host: {get_input: keystone_host}
|
||||
neutron:
|
||||
debug: {get_param: Debug}
|
||||
flat-networks: {get_input: neutron_flat_networks}
|
||||
host: {get_input: neutron_host}
|
||||
router_distributed: {get_input: neutron_router_distributed}
|
||||
agent_mode: {get_input: neutron_agent_mode}
|
||||
metadata_proxy_shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
|
||||
mechanism_drivers: {get_input: neutron_mechanism_drivers}
|
||||
allow_automatic_l3agent_failover: {get_input: neutron_allow_l3agent_failover}
|
||||
l3_ha: {get_input: neutron_l3_ha}
|
||||
ovs:
|
||||
local_ip: {get_input: neutron_local_ip}
|
||||
tenant_network_type: {get_input: neutron_tenant_network_type}
|
||||
tunnel_types: {get_input: neutron_tunnel_types}
|
||||
network_vlan_ranges: {get_input: neutron_network_vlan_ranges}
|
||||
bridge_mappings: {get_input: neutron_bridge_mappings}
|
||||
enable_tunneling: {get_input: neutron_enable_tunneling}
|
||||
physical_bridge: {get_input: neutron_physical_bridge}
|
||||
public_interface: {get_input: neutron_public_interface}
|
||||
public_interface_raw_device: {get_input: neutron_public_interface_raw_device}
|
||||
service-password: {get_input: neutron_password}
|
||||
admin-password: {get_input: admin_password}
|
||||
rabbit:
|
||||
host: {get_input: rabbit_host}
|
||||
username: {get_input: rabbit_username}
|
||||
password: {get_input: rabbit_password}
|
||||
ntp:
|
||||
servers:
|
||||
- {server: {get_input: ntp_server}}
|
||||
NovaComputePassthrough:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config: {get_input: passthrough_config}
|
||||
NovaComputePassthroughSpecific:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config: {get_input: passthrough_config_specific}
|
@ -1,273 +0,0 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'Nova Compute'
|
||||
parameters:
|
||||
AdminPassword:
|
||||
default: unset
|
||||
description: The password for the keystone admin account, used for monitoring, querying neutron etc.
|
||||
type: string
|
||||
hidden: true
|
||||
AllNodesConfig:
|
||||
type: string
|
||||
description: OS::Heat::Config to use for all nodes deployment
|
||||
CeilometerComputeAgent:
|
||||
description: Indicates whether the Compute agent is present and expects nova-compute to be configured accordingly
|
||||
type: string
|
||||
default: ''
|
||||
constraints:
|
||||
- allowed_values: ['', Present]
|
||||
CeilometerMeteringSecret:
|
||||
default: unset
|
||||
description: Secret shared by the ceilometer services.
|
||||
type: string
|
||||
hidden: true
|
||||
CeilometerPassword:
|
||||
default: unset
|
||||
description: The password for the ceilometer service account.
|
||||
type: string
|
||||
hidden: true
|
||||
DefaultSignalTransport:
|
||||
default: CFN_SIGNAL
|
||||
description: Transport to use for software-config signals.
|
||||
type: string
|
||||
constraints:
|
||||
- allowed_values: [ CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL ]
|
||||
ExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
Additional configuration to inject into the cluster. The JSON should have
|
||||
the following structure:
|
||||
{"FILEKEY":
|
||||
{"config":
|
||||
[{"section": "SECTIONNAME",
|
||||
"values":
|
||||
[{"option": "OPTIONNAME",
|
||||
"value": "VALUENAME"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
For instance:
|
||||
{"nova":
|
||||
{"config":
|
||||
[{"section": "default",
|
||||
"values":
|
||||
[{"option": "force_config_drive",
|
||||
"value": "always"
|
||||
}
|
||||
]
|
||||
},
|
||||
{"section": "cells",
|
||||
"values":
|
||||
[{"option": "driver",
|
||||
"value": "nova.cells.rpc_driver.CellsRPCDriver"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
type: json
|
||||
GlanceHost:
|
||||
type: string
|
||||
GlancePort:
|
||||
default: 9292
|
||||
description: Glance port.
|
||||
type: string
|
||||
GlanceProtocol:
|
||||
default: http
|
||||
description: Protocol to use when connecting to glance, set to https for SSL.
|
||||
type: string
|
||||
ImageUpdatePolicy:
|
||||
default: 'REBUILD_PRESERVE_EPHEMERAL'
|
||||
description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
|
||||
type: string
|
||||
KeyName:
|
||||
description: Name of an existing EC2 KeyPair to enable SSH access to the instances
|
||||
type: string
|
||||
default: default
|
||||
KeystoneHost:
|
||||
type: string
|
||||
NeutronBridgeMappings:
|
||||
type: string
|
||||
NeutronEnableTunnelling:
|
||||
type: string
|
||||
NeutronFlatNetworks:
|
||||
type: string
|
||||
default: ''
|
||||
description: If set, flat networks to configure in neutron plugins.
|
||||
NeutronHost:
|
||||
type: string
|
||||
NeutronNetworkType:
|
||||
default: 'vxlan'
|
||||
description: The tenant network type for Neutron, either gre or vxlan.
|
||||
type: string
|
||||
NeutronNetworkVLANRanges:
|
||||
type: string
|
||||
NeutronPhysicalBridge:
|
||||
default: ''
|
||||
description: An OVS bridge to create for accessing external networks.
|
||||
type: string
|
||||
NeutronPublicInterface:
|
||||
default: ''
|
||||
description: A port to add to the NeutronPhysicalBridge.
|
||||
type: string
|
||||
NeutronTunnelTypes:
|
||||
default: 'vxlan'
|
||||
description: |
|
||||
The tunnel types for the Neutron tenant network. To specify multiple
|
||||
values, use a comma separated string, like so: 'gre,vxlan'
|
||||
type: string
|
||||
NeutronPublicInterfaceRawDevice:
|
||||
default: ''
|
||||
type: string
|
||||
NeutronDVR:
|
||||
default: 'False'
|
||||
type: string
|
||||
NeutronMechanismDrivers:
|
||||
default: 'openvswitch'
|
||||
description: |
|
||||
The mechanism drivers for the Neutron tenant network. To specify multiple
|
||||
values, use a comma separated string, like so: 'openvswitch,l2_population'
|
||||
type: string
|
||||
NeutronAllowL3AgentFailover:
|
||||
default: 'True'
|
||||
description: Allow automatic l3-agent failover
|
||||
type: string
|
||||
NeutronL3HA:
|
||||
default: 'False'
|
||||
description: Whether to enable l3-agent HA
|
||||
type: string
|
||||
NovaApiHost:
|
||||
type: string
|
||||
NovaComputeDriver:
|
||||
type: string
|
||||
default: libvirt.LibvirtDriver
|
||||
NovaComputeExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
NovaCompute specific configuration to inject into the cluster. Same
|
||||
structure as ExtraConfig.
|
||||
type: json
|
||||
NovaComputeLibvirtType:
|
||||
type: string
|
||||
default: ''
|
||||
NovaImage:
|
||||
type: string
|
||||
default: overcloud-compute
|
||||
NovaPassword:
|
||||
default: unset
|
||||
description: The password for the nova service account, used by nova-api.
|
||||
type: string
|
||||
hidden: true
|
||||
NovaPublicIP:
|
||||
type: string
|
||||
NtpServer:
|
||||
type: string
|
||||
default: ''
|
||||
OvercloudComputeFlavor:
|
||||
description: Use this flavor
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.flavor
|
||||
RabbitHost:
|
||||
type: string
|
||||
RabbitUserName:
|
||||
type: string
|
||||
RabbitPassword:
|
||||
type: string
|
||||
hidden: true
|
||||
SnmpdReadonlyUserName:
|
||||
default: ro_snmp_user
|
||||
description: The user name for SNMPd with readonly rights running on all Overcloud nodes
|
||||
type: string
|
||||
SnmpdReadonlyUserPassword:
|
||||
default: unset
|
||||
description: The user password for SNMPd with readonly rights running on all Overcloud nodes
|
||||
type: string
|
||||
hidden: true
|
||||
resources:
|
||||
NovaCompute0:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image:
|
||||
{get_param: NovaImage}
|
||||
image_update_policy:
|
||||
get_param: ImageUpdatePolicy
|
||||
flavor: {get_param: OvercloudComputeFlavor}
|
||||
key_name: {get_param: KeyName}
|
||||
networks:
|
||||
- network: ctlplane
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
NovaCompute0Deployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
signal_transport: NO_SIGNAL
|
||||
config: {get_resource: NovaComputeConfig}
|
||||
server: {get_resource: NovaCompute0}
|
||||
input_values:
|
||||
nova_compute_driver: {get_param: NovaComputeDriver}
|
||||
nova_compute_libvirt_type: {get_param: NovaComputeLibvirtType}
|
||||
nova_public_ip: {get_param: NovaPublicIP}
|
||||
nova_api_host: {get_param: NovaApiHost}
|
||||
nova_password: {get_param: NovaPassword}
|
||||
ceilometer_metering_secret: {get_param: CeilometerMeteringSecret}
|
||||
ceilometer_password: {get_param: CeilometerPassword}
|
||||
ceilometer_compute_agent: {get_param: CeilometerComputeAgent}
|
||||
snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
|
||||
snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
|
||||
glance_host: {get_param: GlanceHost}
|
||||
glance_port: {get_param: GlancePort}
|
||||
glance_protocol: {get_param: GlanceProtocol}
|
||||
keystone_host: {get_param: KeystoneHost}
|
||||
neutron_flat_networks: {get_param: NeutronFlatNetworks}
|
||||
neutron_host: {get_param: NeutronHost}
|
||||
neutron_local_ip: {get_attr: [NovaCompute0, networks, ctlplane, 0]}
|
||||
neutron_tenant_network_type: {get_param: NeutronNetworkType}
|
||||
neutron_tunnel_types: {get_param: NeutronTunnelTypes}
|
||||
neutron_network_vlan_ranges: {get_param: NeutronNetworkVLANRanges}
|
||||
neutron_bridge_mappings: {get_param: NeutronBridgeMappings}
|
||||
neutron_enable_tunneling: {get_param: NeutronEnableTunnelling}
|
||||
neutron_physical_bridge: {get_param: NeutronPhysicalBridge}
|
||||
neutron_public_interface: {get_param: NeutronPublicInterface}
|
||||
neutron_public_interface_raw_device: {get_param: NeutronPublicInterfaceRawDevice}
|
||||
neutron_password: {get_param: NeutronPassword}
|
||||
neutron_agent_mode: {get_param: NeutronComputeAgentMode}
|
||||
neutron_router_distributed: {get_param: NeutronDVR}
|
||||
neutron_metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret}
|
||||
neutron_mechanism_drivers: {get_param: NeutronMechanismDrivers}
|
||||
neutron_allow_l3agent_failover: {get_param: NeutronAllowL3AgentFailover}
|
||||
neutron_l3_ha: {get_param: NeutronL3HA}
|
||||
admin_password: {get_param: AdminPassword}
|
||||
rabbit_host: {get_param: RabbitHost}
|
||||
rabbit_username: {get_param: RabbitUserName}
|
||||
rabbit_password: {get_param: RabbitPassword}
|
||||
ntp_server: {get_param: NtpServer}
|
||||
NovaCompute0AllNodesDeployment:
|
||||
depends_on:
|
||||
- controller0AllNodesDeployment
|
||||
- NovaCompute0Deployment
|
||||
- NovaCompute0PassthroughSpecific
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
signal_transport: {get_param: DefaultSignalTransport}
|
||||
config: {get_param: AllNodesConfig}
|
||||
server: {get_resource: NovaCompute0}
|
||||
NovaCompute0Passthrough:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: NovaComputePassthrough}
|
||||
server: {get_resource: NovaCompute0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config: {get_param: ExtraConfig}
|
||||
NovaCompute0PassthroughSpecific:
|
||||
depends_on: [NovaCompute0Passthrough]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: NovaComputePassthroughSpecific}
|
||||
server: {get_resource: NovaCompute0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config_specific: {get_param: NovaComputeExtraConfig}
|
@ -1,952 +0,0 @@
|
||||
description: Deprecated. Please migrate to use overcloud-without-mergepy instead.
|
||||
heat_template_version: 2013-05-23
|
||||
parameters:
|
||||
AdminPassword:
|
||||
default: unset
|
||||
description: The password for the keystone admin account, used for monitoring, querying neutron etc.
|
||||
type: string
|
||||
hidden: true
|
||||
AdminToken:
|
||||
default: unset
|
||||
description: The keystone auth secret.
|
||||
type: string
|
||||
hidden: true
|
||||
CeilometerComputeAgent:
|
||||
description: Indicates whether the Compute agent is present and expects nova-compute to be configured accordingly
|
||||
type: string
|
||||
default: ''
|
||||
constraints:
|
||||
- allowed_values: ['', Present]
|
||||
CeilometerMeteringSecret:
|
||||
default: unset
|
||||
description: Secret shared by the ceilometer services.
|
||||
type: string
|
||||
hidden: true
|
||||
CeilometerPassword:
|
||||
default: unset
|
||||
description: The password for the ceilometer service account.
|
||||
type: string
|
||||
hidden: true
|
||||
CinderISCSIHelper:
|
||||
default: tgtadm
|
||||
description: The iSCSI helper to use with cinder.
|
||||
type: string
|
||||
CinderLVMLoopDeviceSize:
|
||||
default: 5000
|
||||
description: The size of the loopback file used by the cinder LVM driver.
|
||||
type: number
|
||||
CinderPassword:
|
||||
default: unset
|
||||
description: The password for the cinder service account, used by cinder-api.
|
||||
type: string
|
||||
hidden: true
|
||||
CloudName:
|
||||
default: ''
|
||||
description: The DNS name of this cloud. E.g. ci-overcloud.tripleo.org
|
||||
type: string
|
||||
ControlFixedIPs:
|
||||
default: []
|
||||
description: Should be used for arbitrary ips.
|
||||
type: json
|
||||
controllerExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
Controller specific configuration to inject into the cluster. Same
|
||||
structure as ExtraConfig.
|
||||
type: json
|
||||
controllerImage:
|
||||
type: string
|
||||
default: overcloud-control
|
||||
constraints:
|
||||
- custom_constraint: glance.image
|
||||
ControlVirtualInterface:
|
||||
default: 'br-ex'
|
||||
description: Interface where virtual ip will be assigned.
|
||||
type: string
|
||||
Debug:
|
||||
default: ''
|
||||
description: Set to True to enable debugging on all services.
|
||||
type: string
|
||||
DefaultSignalTransport:
|
||||
default: CFN_SIGNAL
|
||||
description: Transport to use for software-config signals.
|
||||
type: string
|
||||
constraints:
|
||||
- allowed_values: [ CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL ]
|
||||
ExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
Additional configuration to inject into the cluster. The JSON should have
|
||||
the following structure:
|
||||
{"FILEKEY":
|
||||
{"config":
|
||||
[{"section": "SECTIONNAME",
|
||||
"values":
|
||||
[{"option": "OPTIONNAME",
|
||||
"value": "VALUENAME"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
For instance:
|
||||
{"nova":
|
||||
{"config":
|
||||
[{"section": "default",
|
||||
"values":
|
||||
[{"option": "force_config_drive",
|
||||
"value": "always"
|
||||
}
|
||||
]
|
||||
},
|
||||
{"section": "cells",
|
||||
"values":
|
||||
[{"option": "driver",
|
||||
"value": "nova.cells.rpc_driver.CellsRPCDriver"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
type: json
|
||||
GlanceLogFile:
|
||||
description: The filepath of the file to use for logging messages from Glance.
|
||||
type: string
|
||||
default: ''
|
||||
HorizonPort:
|
||||
type: number
|
||||
default: 80
|
||||
description: Horizon web server port.
|
||||
GlancePassword:
|
||||
default: unset
|
||||
description: The password for the glance service account, used by the glance services.
|
||||
type: string
|
||||
hidden: true
|
||||
GlancePort:
|
||||
default: 9292
|
||||
description: Glance port.
|
||||
type: string
|
||||
GlanceProtocol:
|
||||
default: http
|
||||
description: Protocol to use when connecting to glance, set to https for SSL.
|
||||
type: string
|
||||
GlanceNotifierStrategy:
|
||||
description: Strategy to use for Glance notification queue
|
||||
type: string
|
||||
default: noop
|
||||
HeatPassword:
|
||||
default: unset
|
||||
description: The password for the Heat service account, used by the Heat services.
|
||||
type: string
|
||||
hidden: true
|
||||
HeatStackDomainAdminPassword:
|
||||
description: Password for heat_domain_admin user.
|
||||
type: string
|
||||
default: ''
|
||||
hidden: true
|
||||
HypervisorNeutronPhysicalBridge:
|
||||
default: 'br-ex'
|
||||
description: >
|
||||
An OVS bridge to create on each hypervisor. This defaults to br-ex the
|
||||
same as the control plane nodes, as we have a uniform configuration of
|
||||
the openvswitch agent. Typically should not need to be changed.
|
||||
type: string
|
||||
HypervisorNeutronPublicInterface:
|
||||
default: nic1
|
||||
description: What interface to add to the HypervisorNeutronPhysicalBridge.
|
||||
type: string
|
||||
ImageUpdatePolicy:
|
||||
default: 'REBUILD_PRESERVE_EPHEMERAL'
|
||||
description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
|
||||
type: string
|
||||
KeyName:
|
||||
default: default
|
||||
description: Name of an existing EC2 KeyPair to enable SSH access to the instances
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.keypair
|
||||
KeystoneCACertificate:
|
||||
default: ''
|
||||
description: Keystone self-signed certificate authority certificate.
|
||||
type: string
|
||||
KeystoneSigningCertificate:
|
||||
default: ''
|
||||
description: Keystone certificate for verifying token validity.
|
||||
type: string
|
||||
KeystoneSigningKey:
|
||||
default: ''
|
||||
description: Keystone key for signing tokens.
|
||||
type: string
|
||||
hidden: true
|
||||
KeystoneSSLCertificate:
|
||||
default: ''
|
||||
description: Keystone certificate for verifying token validity.
|
||||
type: string
|
||||
KeystoneSSLCertificateKey:
|
||||
default: ''
|
||||
description: Keystone key for signing tokens.
|
||||
type: string
|
||||
hidden: true
|
||||
MysqlInnodbBufferPoolSize:
|
||||
description: >
|
||||
Specifies the size of the buffer pool in megabytes. Setting to
|
||||
zero should be interpreted as "no value" and will defer to the
|
||||
lower level default.
|
||||
type: number
|
||||
default: 0
|
||||
NeutronBridgeMappings:
|
||||
description: >
|
||||
The OVS logical->physical bridge mappings to use. See the Neutron
|
||||
documentation for details. Defaults to mapping br-ex - the external
|
||||
bridge on hosts - to a physical name 'datacentre' which can be used
|
||||
to create provider networks (and we use this for the default floating
|
||||
network) - if changing this either use different post-install network
|
||||
scripts or be sure to keep 'datacentre' as a mapping network name.
|
||||
type: string
|
||||
default: "datacentre:br-ex"
|
||||
NeutronControlPlaneID:
|
||||
default: ''
|
||||
type: string
|
||||
description: Neutron ID for ctlplane network.
|
||||
NeutronDnsmasqOptions:
|
||||
default: 'dhcp-option-force=26,1400'
|
||||
description: Dnsmasq options for neutron-dhcp-agent. The default value here forces MTU to be set to 1400 to account for the tunnel overhead.
|
||||
type: string
|
||||
NeutronFlatNetworks:
|
||||
type: string
|
||||
default: 'datacentre'
|
||||
description: >
|
||||
If set, flat networks to configure in neutron plugins. Defaults to
|
||||
'datacentre' to permit external network creation.
|
||||
NeutronNetworkType:
|
||||
default: 'vxlan'
|
||||
description: The tenant network type for Neutron, either gre or vxlan.
|
||||
type: string
|
||||
NeutronNetworkVLANRanges:
|
||||
default: 'datacentre'
|
||||
description: >
|
||||
The Neutron ML2 and OpenVSwitch vlan mapping range to support. See the
|
||||
Neutron documentation for permitted values. Defaults to permitting any
|
||||
VLAN on the 'datacentre' physical network (See NeutronBridgeMappings).
|
||||
type: string
|
||||
NeutronPassword:
|
||||
default: unset
|
||||
description: The password for the neutron service account, used by neutron agents.
|
||||
type: string
|
||||
hidden: true
|
||||
NeutronPublicInterface:
|
||||
default: nic1
|
||||
description: What interface to bridge onto br-ex for network nodes.
|
||||
type: string
|
||||
NeutronPublicInterfaceDefaultRoute:
|
||||
default: ''
|
||||
description: A custom default route for the NeutronPublicInterface.
|
||||
type: string
|
||||
NeutronPublicInterfaceIP:
|
||||
default: ''
|
||||
description: A custom IP address to put onto the NeutronPublicInterface.
|
||||
type: string
|
||||
NeutronPublicInterfaceRawDevice:
|
||||
default: ''
|
||||
description: If set, the public interface is a vlan with this device as the raw device.
|
||||
type: string
|
||||
NeutronPublicInterfaceTag:
|
||||
default: ''
|
||||
description: >
|
||||
VLAN tag for creating a public VLAN. The tag will be used to
|
||||
create an access port on the exterior bridge for each control plane node,
|
||||
and that port will be given the IP address returned by neutron from the
|
||||
public network. Set CONTROLEXTRA=overcloud-vlan-port.yaml when compiling
|
||||
overcloud.yaml to include the deployment of VLAN ports to the control
|
||||
plane.
|
||||
type: string
|
||||
NeutronComputeAgentMode:
|
||||
default: 'dvr'
|
||||
description: Agent mode for the neutron-l3-agent on the compute hosts
|
||||
type: string
|
||||
NeutronAgentMode:
|
||||
default: 'dvr_snat'
|
||||
description: Agent mode for the neutron-l3-agent on the controller hosts
|
||||
type: string
|
||||
NeutronDVR:
|
||||
default: 'False'
|
||||
description: Whether to configure Neutron Distributed Virtual Routers
|
||||
type: string
|
||||
NeutronMetadataProxySharedSecret:
|
||||
default: 'unset'
|
||||
description: Shared secret to prevent spoofing
|
||||
type: string
|
||||
NeutronTunnelTypes:
|
||||
default: 'vxlan'
|
||||
description: |
|
||||
The tunnel types for the Neutron tenant network. To specify multiple
|
||||
values, use a comma separated string, like so: 'gre,vxlan'
|
||||
type: string
|
||||
NeutronMechanismDrivers:
|
||||
default: 'openvswitch'
|
||||
description: |
|
||||
The mechanism drivers for the Neutron tenant network. To specify multiple
|
||||
values, use a comma separated string, like so: 'openvswitch,l2_population'
|
||||
type: string
|
||||
NeutronAllowL3AgentFailover:
|
||||
default: 'True'
|
||||
description: Allow automatic l3-agent failover
|
||||
type: string
|
||||
NeutronL3HA:
|
||||
default: 'False'
|
||||
description: Whether to enable l3-agent HA
|
||||
type: string
|
||||
NovaComputeDriver:
|
||||
default: libvirt.LibvirtDriver
|
||||
type: string
|
||||
NovaComputeExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
NovaCompute specific configuration to inject into the cluster. Same
|
||||
structure as ExtraConfig.
|
||||
type: json
|
||||
NovaComputeLibvirtType:
|
||||
default: ''
|
||||
type: string
|
||||
NovaImage:
|
||||
type: string
|
||||
default: overcloud-compute
|
||||
constraints:
|
||||
- custom_constraint: glance.image
|
||||
NovaPassword:
|
||||
default: unset
|
||||
description: The password for the nova service account, used by nova-api.
|
||||
type: string
|
||||
hidden: true
|
||||
NtpServer:
|
||||
type: string
|
||||
default: ''
|
||||
OvercloudComputeFlavor:
|
||||
description: Flavor for compute nodes to request when deploying.
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.flavor
|
||||
OvercloudControlFlavor:
|
||||
description: Flavor for control nodes to request when deploying.
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.flavor
|
||||
PublicVirtualFixedIPs:
|
||||
default: []
|
||||
description: >
|
||||
Control the IP allocation for the PublicVirtualInterface port. E.g.
|
||||
[{'ip_address':'1.2.3.4'}]
|
||||
type: json
|
||||
PublicVirtualInterface:
|
||||
default: 'br-ex'
|
||||
description: >
|
||||
Specifies the interface where the public-facing virtual ip will be assigned.
|
||||
This should be int_public when a VLAN is being used.
|
||||
type: string
|
||||
PublicVirtualNetwork:
|
||||
default: 'ctlplane'
|
||||
type: string
|
||||
description: >
|
||||
Neutron network to allocate public virtual IP port on.
|
||||
RabbitCookieSalt:
|
||||
type: string
|
||||
default: unset
|
||||
description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
|
||||
RabbitPassword:
|
||||
default: guest
|
||||
description: The password for RabbitMQ
|
||||
type: string
|
||||
hidden: true
|
||||
RabbitUserName:
|
||||
default: guest
|
||||
description: The username for RabbitMQ
|
||||
type: string
|
||||
RabbitClientUseSSL:
|
||||
default: false
|
||||
description: >
|
||||
Rabbit client subscriber parameter to specify
|
||||
an SSL connection to the RabbitMQ host.
|
||||
type: string
|
||||
RabbitClientPort:
|
||||
default: 5672
|
||||
description: Set rabbit subscriber port, change this if using SSL
|
||||
type: number
|
||||
SnmpdReadonlyUserName:
|
||||
default: ro_snmp_user
|
||||
description: The user name for SNMPd with readonly rights running on all Overcloud nodes
|
||||
type: string
|
||||
SnmpdReadonlyUserPassword:
|
||||
default: unset
|
||||
description: The user password for SNMPd with readonly rights running on all Overcloud nodes
|
||||
type: string
|
||||
hidden: true
|
||||
resources:
|
||||
ControlVirtualIP:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
name: control_virtual_ip
|
||||
network_id: {get_param: NeutronControlPlaneID}
|
||||
fixed_ips:
|
||||
get_param: ControlFixedIPs
|
||||
replacement_policy: AUTO
|
||||
MysqlClusterUniquePart:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
length: 10
|
||||
MysqlRootPassword:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
length: 10
|
||||
PublicVirtualIP:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
name: public_virtual_ip
|
||||
network: {get_param: PublicVirtualNetwork}
|
||||
fixed_ips:
|
||||
get_param: PublicVirtualFixedIPs
|
||||
replacement_policy: AUTO
|
||||
RabbitCookie:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
length: 20
|
||||
salt:
|
||||
get_param: RabbitCookieSalt
|
||||
NovaCompute0Deployment:
|
||||
type: FileInclude
|
||||
Path: deprecated/nova-compute-instance.yaml
|
||||
SubKey: resources.NovaCompute0Deployment
|
||||
parameters:
|
||||
DefaultSignalTransport:
|
||||
get_param: DefaultSignalTransport
|
||||
NovaApiHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
KeystoneHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
NeutronHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
GlanceHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
RabbitHost: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
NovaPublicIP: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
|
||||
NeutronNetworkType:
|
||||
get_param: NeutronNetworkType
|
||||
NeutronTunnelTypes:
|
||||
get_param: NeutronTunnelTypes
|
||||
NeutronEnableTunnelling: "True"
|
||||
NeutronFlatNetworks:
|
||||
get_param: NeutronFlatNetworks
|
||||
NeutronNetworkVLANRanges:
|
||||
get_param: NeutronNetworkVLANRanges
|
||||
NeutronPhysicalBridge:
|
||||
get_param: HypervisorNeutronPhysicalBridge
|
||||
NeutronPublicInterface:
|
||||
get_param: HypervisorNeutronPublicInterface
|
||||
NeutronBridgeMappings:
|
||||
get_param: NeutronBridgeMappings
|
||||
NeutronDVR:
|
||||
get_param: NeutronDVR
|
||||
NeutronAgentMode:
|
||||
get_param: NeutronComputeAgentMode
|
||||
NeutronPublicInterfaceRawDevice:
|
||||
get_param: NeutronPublicInterfaceRawDevice
|
||||
NeutronMechanismDrivers:
|
||||
get_param: NeutronMechanismDrivers
|
||||
NeutronAllowL3AgentFailover:
|
||||
get_param: NeutronAllowL3AgentFailover
|
||||
NeutronL3HA:
|
||||
get_param: NeutronL3HA
|
||||
NovaCompute0AllNodesDeployment:
|
||||
type: FileInclude
|
||||
Path: deprecated/nova-compute-instance.yaml
|
||||
SubKey: resources.NovaCompute0AllNodesDeployment
|
||||
parameters:
|
||||
AllNodesConfig: {get_resource: allNodesConfig}
|
||||
NovaCompute0:
|
||||
type: FileInclude
|
||||
Path: deprecated/nova-compute-instance.yaml
|
||||
SubKey: resources.NovaCompute0
|
||||
NovaCompute0Passthrough:
|
||||
type: FileInclude
|
||||
Path: deprecated/nova-compute-instance.yaml
|
||||
SubKey: resources.NovaCompute0Passthrough
|
||||
parameters:
|
||||
passthrough_config: {get_param: ExtraConfig}
|
||||
NovaCompute0PassthroughSpecific:
|
||||
type: FileInclude
|
||||
Path: deprecated/nova-compute-instance.yaml
|
||||
SubKey: resources.NovaCompute0PassthroughSpecific
|
||||
parameters:
|
||||
passthrough_config_specific: {get_param: NovaComputeExtraConfig}
|
||||
HeatAuthEncryptionKey:
|
||||
type: OS::Heat::RandomString
|
||||
controllerConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
admin-password:
|
||||
get_param: AdminPassword
|
||||
admin-token:
|
||||
get_param: AdminToken
|
||||
bootstack:
|
||||
public_interface_ip:
|
||||
get_param: NeutronPublicInterfaceIP
|
||||
bootstrap_host:
|
||||
bootstrap_nodeid:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
- get_attr:
|
||||
- controller0
|
||||
- name
|
||||
nodeid: {get_input: bootstack_nodeid}
|
||||
database:
|
||||
host: &database_host
|
||||
{get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
cinder:
|
||||
db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://cinder:unset@
|
||||
- *database_host
|
||||
- /cinder
|
||||
debug: {get_param: Debug}
|
||||
volume_size_mb:
|
||||
get_param: CinderLVMLoopDeviceSize
|
||||
service-password:
|
||||
get_param: CinderPassword
|
||||
iscsi-helper:
|
||||
get_param: CinderISCSIHelper
|
||||
controller-address:
|
||||
get_input: controller_host
|
||||
corosync:
|
||||
bindnetaddr: {get_input: controller_host}
|
||||
mcastport: 5577
|
||||
nodes:
|
||||
Merge::Map:
|
||||
controller0:
|
||||
ip: {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
pacemaker:
|
||||
stonith_enabled : false
|
||||
recheck_interval : 5
|
||||
quorum_policy : ignore
|
||||
db-password: unset
|
||||
glance:
|
||||
registry:
|
||||
host: {get_input: controller_virtual_ip}
|
||||
backend: swift
|
||||
db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://glance:unset@
|
||||
- *database_host
|
||||
- /glance
|
||||
debug: {get_param: Debug}
|
||||
host:
|
||||
get_input: controller_virtual_ip
|
||||
port:
|
||||
get_param: GlancePort
|
||||
protocol:
|
||||
get_param: GlanceProtocol
|
||||
service-password:
|
||||
get_param: GlancePassword
|
||||
swift-store-user: service:glance
|
||||
swift-store-key:
|
||||
get_param: GlancePassword
|
||||
notifier-strategy:
|
||||
get_param: GlanceNotifierStrategy
|
||||
log-file:
|
||||
get_param: GlanceLogFile
|
||||
heat:
|
||||
admin_password:
|
||||
get_param: HeatPassword
|
||||
admin_tenant_name: service
|
||||
admin_user: heat
|
||||
auth_encryption_key:
|
||||
get_resource: HeatAuthEncryptionKey
|
||||
db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://heat:unset@
|
||||
- *database_host
|
||||
- /heat
|
||||
debug: {get_param: Debug}
|
||||
stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
|
||||
watch_server_url: {get_input: heat.watch_server_url}
|
||||
metadata_server_url: {get_input: heat.metadata_server_url}
|
||||
waitcondition_server_url: {get_input: heat.waitcondition_server_url}
|
||||
horizon:
|
||||
port: {get_param: HorizonPort}
|
||||
caches:
|
||||
memcached:
|
||||
nodes:
|
||||
Merge::Map:
|
||||
controller0:
|
||||
{get_attr: [controller0, name]}
|
||||
keystone:
|
||||
db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://keystone:unset@
|
||||
- *database_host
|
||||
- /keystone
|
||||
debug: {get_param: Debug}
|
||||
host:
|
||||
get_input: controller_virtual_ip
|
||||
ca_certificate: {get_param: KeystoneCACertificate}
|
||||
signing_key: {get_param: KeystoneSigningKey}
|
||||
signing_certificate: {get_param: KeystoneSigningCertificate}
|
||||
ssl:
|
||||
certificate: {get_param: KeystoneSSLCertificate}
|
||||
certificate_key: {get_param: KeystoneSSLCertificateKey}
|
||||
mysql:
|
||||
innodb_buffer_pool_size: {get_param: MysqlInnodbBufferPoolSize}
|
||||
local_bind: true
|
||||
root-password: {get_resource: MysqlRootPassword}
|
||||
nodes:
|
||||
Merge::Map:
|
||||
controller0:
|
||||
ip: {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
cluster_name:
|
||||
Fn::Join:
|
||||
- '-'
|
||||
- - 'tripleo'
|
||||
- {get_resource: MysqlClusterUniquePart}
|
||||
neutron:
|
||||
debug: {get_param: Debug}
|
||||
flat-networks: {get_param: NeutronFlatNetworks}
|
||||
host: {get_input: controller_virtual_ip}
|
||||
metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret}
|
||||
agent_mode: {get_param: NeutronAgentMode}
|
||||
router_distributed: {get_param: NeutronDVR}
|
||||
mechanism_drivers: {get_param: NeutronMechanismDrivers}
|
||||
allow_automatic_l3agent_failover: {get_param: NeutronAllowL3AgentFailover}
|
||||
l3_ha: {get_param: NeutronL3HA}
|
||||
ovs:
|
||||
enable_tunneling: 'True'
|
||||
local_ip:
|
||||
get_input: controller_host
|
||||
network_vlan_ranges: {get_param: NeutronNetworkVLANRanges}
|
||||
bridge_mappings: {get_param: NeutronBridgeMappings}
|
||||
public_interface:
|
||||
get_param: NeutronPublicInterface
|
||||
public_interface_raw_device:
|
||||
get_param: NeutronPublicInterfaceRawDevice
|
||||
public_interface_route:
|
||||
get_param: NeutronPublicInterfaceDefaultRoute
|
||||
public_interface_tag:
|
||||
get_param: NeutronPublicInterfaceTag
|
||||
physical_bridge: br-ex
|
||||
tenant_network_type:
|
||||
get_param: NeutronNetworkType
|
||||
tunnel_types:
|
||||
get_param: NeutronTunnelTypes
|
||||
ovs_db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://neutron:unset@
|
||||
- *database_host
|
||||
- /ovs_neutron?charset=utf8
|
||||
service-password:
|
||||
get_param: NeutronPassword
|
||||
dnsmasq-options:
|
||||
get_param: NeutronDnsmasqOptions
|
||||
ceilometer:
|
||||
db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://ceilometer:unset@
|
||||
- *database_host
|
||||
- /ceilometer
|
||||
debug: {get_param: Debug}
|
||||
metering_secret: {get_param: CeilometerMeteringSecret}
|
||||
service-password:
|
||||
get_param: CeilometerPassword
|
||||
snmpd:
|
||||
export_MIB: UCD-SNMP-MIB
|
||||
readonly_user_name:
|
||||
get_param: SnmpdReadonlyUserName
|
||||
readonly_user_password:
|
||||
get_param: SnmpdReadonlyUserPassword
|
||||
nova:
|
||||
compute_driver: libvirt.LibvirtDriver
|
||||
db:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - mysql://nova:unset@
|
||||
- *database_host
|
||||
- /nova
|
||||
default_floating_pool:
|
||||
ext-net
|
||||
host: {get_input: controller_virtual_ip}
|
||||
metadata-proxy: true
|
||||
service-password:
|
||||
get_param: NovaPassword
|
||||
rabbit:
|
||||
host: {get_input: controller_virtual_ip}
|
||||
username:
|
||||
get_param: RabbitUserName
|
||||
password:
|
||||
get_param: RabbitPassword
|
||||
cookie:
|
||||
get_attr:
|
||||
- RabbitCookie
|
||||
- value
|
||||
rabbit_client_use_ssl: {get_param: RabbitClientUseSSL}
|
||||
rabbit_port: {get_param: RabbitClientPort}
|
||||
ntp:
|
||||
servers:
|
||||
- {server: {get_param: NtpServer}}
|
||||
virtual_interfaces:
|
||||
instances:
|
||||
- vrrp_instance_name: VI_CONTROL
|
||||
virtual_router_id: 51
|
||||
keepalive_interface:
|
||||
get_param: ControlVirtualInterface
|
||||
priority: 101
|
||||
virtual_ips:
|
||||
- ip: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
interface:
|
||||
get_param: ControlVirtualInterface
|
||||
- vrrp_instance_name: VI_PUBLIC
|
||||
virtual_router_id: 52
|
||||
keepalive_interface:
|
||||
get_param: PublicVirtualInterface
|
||||
priority: 101
|
||||
virtual_ips:
|
||||
- ip: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
|
||||
interface:
|
||||
get_param: PublicVirtualInterface
|
||||
vrrp_sync_groups:
|
||||
- name: VG1
|
||||
members:
|
||||
- VI_CONTROL
|
||||
- VI_PUBLIC
|
||||
keepalived:
|
||||
keepalive_interface:
|
||||
get_param: PublicVirtualInterface
|
||||
priority: 101
|
||||
virtual_ips:
|
||||
-
|
||||
ip: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
interface:
|
||||
get_param: ControlVirtualInterface
|
||||
-
|
||||
ip: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}
|
||||
interface:
|
||||
get_param: PublicVirtualInterface
|
||||
haproxy:
|
||||
nodes:
|
||||
Merge::Map:
|
||||
controller0:
|
||||
ip: {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
name: {get_attr: [controller0, name]}
|
||||
net_binds:
|
||||
- &control_vip {ip: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}}
|
||||
- &public_vip {ip: {get_attr: [PublicVirtualIP, fixed_ips, 0, ip_address]}}
|
||||
options:
|
||||
- option httpchk GET /
|
||||
services:
|
||||
- name: keystone_admin
|
||||
port: 35357
|
||||
- name: keystone_public
|
||||
port: 5000
|
||||
- name: horizon
|
||||
port: 80
|
||||
- name: neutron
|
||||
port: 9696
|
||||
- name: cinder
|
||||
port: 8776
|
||||
- name: glance_api
|
||||
port: 9292
|
||||
- name: glance_registry
|
||||
port: 9191
|
||||
options: # overwrite options as glace_reg needs auth for http req
|
||||
- name: heat_api
|
||||
port: 8004
|
||||
- name: heat_cloudwatch
|
||||
port: 8003
|
||||
- name: heat_cfn
|
||||
port: 8000
|
||||
- name: mysql
|
||||
port: 3306
|
||||
net_binds:
|
||||
- *control_vip
|
||||
extra_server_params:
|
||||
- backup
|
||||
options:
|
||||
- timeout client 0
|
||||
- timeout server 0
|
||||
- name: nova_ec2
|
||||
port: 8773
|
||||
- name: nova_osapi
|
||||
port: 8774
|
||||
- name: nova_metadata
|
||||
port: 8775
|
||||
- name: nova_novncproxy
|
||||
port: 6080
|
||||
- name: ceilometer
|
||||
port: 8777
|
||||
options: # overwrite options as ceil needs auth for http req
|
||||
- name: swift_proxy_server
|
||||
port: 8080
|
||||
options:
|
||||
- option httpchk GET /info
|
||||
- name: rabbitmq
|
||||
port: 5672
|
||||
net_binds:
|
||||
- *control_vip
|
||||
options:
|
||||
- timeout client 0
|
||||
- timeout server 0
|
||||
- maxconn 1500
|
||||
controllerPassthrough:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config: {get_input: passthrough_config}
|
||||
controllerPassthroughSpecific:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config: {get_input: passthrough_config_specific}
|
||||
controller0:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image:
|
||||
get_param: controllerImage
|
||||
image_update_policy:
|
||||
get_param: ImageUpdatePolicy
|
||||
flavor:
|
||||
get_param: OvercloudControlFlavor
|
||||
key_name:
|
||||
get_param: KeyName
|
||||
networks:
|
||||
- network: ctlplane
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
controller0AllNodesDeployment:
|
||||
depends_on: [controller0Deployment,controller0SSLDeployment,controller0Swift,controller0PassthroughSpecific]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
signal_transport: {get_param: DefaultSignalTransport}
|
||||
config: {get_resource: allNodesConfig}
|
||||
server: {get_resource: controller0}
|
||||
controller0Deployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
signal_transport: NO_SIGNAL
|
||||
config: {get_resource: controllerConfig}
|
||||
server: {get_resource: controller0}
|
||||
input_values:
|
||||
bootstack_nodeid: {get_attr: [controller0, name]}
|
||||
controller_host: {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
controller_virtual_ip:
|
||||
{get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
heat.watch_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
- ':8003'
|
||||
heat.metadata_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
- ':8000'
|
||||
heat.waitcondition_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
- ':8000/v1/waitcondition'
|
||||
allNodesConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
completion-signal: {get_input: deploy_signal_id}
|
||||
hosts:
|
||||
Fn::Join:
|
||||
- "\n"
|
||||
- - Fn::Join:
|
||||
- "\n"
|
||||
- Merge::Map:
|
||||
NovaCompute0:
|
||||
Fn::Join:
|
||||
- ' '
|
||||
- - {get_attr: [NovaCompute0, networks, ctlplane, 0]}
|
||||
- {get_attr: [NovaCompute0, name]}
|
||||
- Fn::Join:
|
||||
- "\n"
|
||||
- Merge::Map:
|
||||
BlockStorage0:
|
||||
Fn::Join:
|
||||
- ' '
|
||||
- - {get_attr: [BlockStorage0, networks, ctlplane, 0]}
|
||||
- {get_attr: [BlockStorage0, name]}
|
||||
- Fn::Join:
|
||||
- "\n"
|
||||
- Merge::Map:
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ' '
|
||||
- - {get_attr: [SwiftStorage0, networks, ctlplane, 0]}
|
||||
- {get_attr: [SwiftStorage0, name]}
|
||||
- Fn::Join:
|
||||
- "\n"
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
Fn::Join:
|
||||
- ' '
|
||||
- - {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
- {get_attr: [controller0, name]}
|
||||
- {get_param: CloudName}
|
||||
rabbit:
|
||||
nodes:
|
||||
Fn::Join:
|
||||
- ','
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
{get_attr: [controller0, name]}
|
||||
sysctl:
|
||||
net.ipv4.tcp_keepalive_time: 5
|
||||
net.ipv4.tcp_keepalive_probes: 5
|
||||
net.ipv4.tcp_keepalive_intvl: 1
|
||||
controller0SSLDeployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: SSLConfig}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
controller_host: {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
ssl_certificate: {get_param: SSLCertificate}
|
||||
ssl_key: {get_param: SSLKey}
|
||||
ssl_ca_certificate: {get_param: SSLCACertificate}
|
||||
controller0Passthrough:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: controllerPassthrough}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config: {get_param: ExtraConfig}
|
||||
controller0PassthroughSpecific:
|
||||
depends_on: [controller0Passthrough]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: controllerPassthroughSpecific}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config_specific: {get_param: controllerExtraConfig}
|
||||
outputs:
|
||||
KeystoneURL:
|
||||
description: URL for the Overcloud Keystone service
|
||||
value:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - http://
|
||||
- {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
- :5000/v2.0/
|
@ -1,39 +0,0 @@
|
||||
outputs:
|
||||
controller0PublicIP:
|
||||
description: Address for registering endpoints in the cloud.
|
||||
value: {get_attr: [controller0_VLANPort, fixed_ips, 0, ip_address]}
|
||||
resources:
|
||||
# Override the main template which can also supply a static route.
|
||||
controller0_99_VLANPort:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: ControllerVLANPortConfig}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
vlan_port:
|
||||
list_join:
|
||||
- '/'
|
||||
- - {get_attr: [controller0_VLANPort, fixed_ips, 0, ip_address]}
|
||||
# This should also be pulled out of the subnet. May need a
|
||||
# neutron fix too - XXX make into a parameter and feed it
|
||||
# in via _overcloud.sh for now.
|
||||
- '24'
|
||||
# Tell the instance to apply the default route.
|
||||
# Reinstate when https://bugs.launchpad.net/heat/+bug/1336656 is
|
||||
# sorted
|
||||
# public_interface_route:
|
||||
# get_attr: [controller0_VLANPort, fixed_ips, 0, subnet, gateway_ip]
|
||||
ControllerVLANPortConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
neutron:
|
||||
ovs:
|
||||
public_interface_tag_ip: {get_input: vlan_port}
|
||||
controller0_VLANPort:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
name: controller0_vlan
|
||||
network: public
|
||||
replacement_policy: AUTO
|
@ -1,54 +0,0 @@
|
||||
description: 'ssl-source: SSL endpoint metadata for openstack'
|
||||
parameters:
|
||||
SSLCACertificate:
|
||||
default: ''
|
||||
description: If set, the contents of an SSL certificate authority file.
|
||||
type: string
|
||||
SSLCertificate:
|
||||
default: ''
|
||||
description: If set, the contents of an SSL certificate .crt file for encrypting SSL endpoints.
|
||||
type: string
|
||||
hidden: true
|
||||
SSLKey:
|
||||
default: ''
|
||||
description: If set, the contents of an SSL certificate .key file for encrypting SSL endpoints.
|
||||
type: string
|
||||
hidden: true
|
||||
resources:
|
||||
SSLConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
ssl:
|
||||
ca_certificate: {get_input: ssl_ca_certificate}
|
||||
stunnel:
|
||||
cert: {get_input: ssl_certificate}
|
||||
key: {get_input: ssl_key}
|
||||
cacert: {get_input: ssl_ca_certificate}
|
||||
connect_host: {get_input: controller_host}
|
||||
ports:
|
||||
- name: 'ec2'
|
||||
accept: 13773
|
||||
connect: 8773
|
||||
- name: 'image'
|
||||
accept: 13292
|
||||
connect: 9292
|
||||
- name: 'identity'
|
||||
accept: 13000
|
||||
connect: 5000
|
||||
- name: 'network'
|
||||
accept: 13696
|
||||
connect: 9696
|
||||
- name: 'compute'
|
||||
accept: 13774
|
||||
connect: 8774
|
||||
- name: 'swift-proxy'
|
||||
accept: 13080
|
||||
connect: 8080
|
||||
- name: 'cinder'
|
||||
accept: 13776
|
||||
connect: 8776
|
||||
- name: 'ceilometer'
|
||||
accept: 13777
|
||||
connect: 8777
|
@ -1,69 +0,0 @@
|
||||
description: 'Swift-proxy: OpenStack object storage proxy'
|
||||
parameters:
|
||||
SwiftHashSuffix:
|
||||
default: unset
|
||||
description: A random string to be used as a salt when hashing to determine mappings in the ring.
|
||||
type: string
|
||||
hidden: true
|
||||
SwiftMountCheck:
|
||||
default: 'false'
|
||||
description: Value of mount_check in Swift account/container/object -server.conf
|
||||
type: boolean
|
||||
SwiftMinPartHours:
|
||||
type: number
|
||||
default: 1
|
||||
description: The minimum time (in hours) before a partition in a ring can be moved following a rebalance.
|
||||
SwiftPartPower:
|
||||
default: 10
|
||||
description: Partition Power to use when building Swift rings
|
||||
type: number
|
||||
SwiftPassword:
|
||||
default: unset
|
||||
description: The password for the swift service account, used by the swift proxy services.
|
||||
type: string
|
||||
hidden: true
|
||||
SwiftReplicas:
|
||||
type: number
|
||||
default: 3
|
||||
description: How many replicas to use in the swift rings.
|
||||
resources:
|
||||
controller0Swift:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: SwiftConfig}
|
||||
server: {get_resource: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
swift_hash_suffix: {get_param: SwiftHashSuffix}
|
||||
swift_mount_check: {get_param: SwiftMountCheck}
|
||||
swift_password: {get_param: SwiftPassword}
|
||||
swift_part_power: {get_param: SwiftPartPower}
|
||||
swift_devices:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
- ':%PORT%/d1'
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- {get_attr: [SwiftStorage0, networks, ctlplane, 0]}
|
||||
- ':%PORT%/d1'
|
||||
swift_proxy_memcache:
|
||||
Fn::Join:
|
||||
- ','
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- - Fn::Join:
|
||||
- ''
|
||||
- - {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
- ':11211'
|
||||
swift_replicas: { get_param: SwiftReplicas}
|
||||
swift_min_part_hours: { get_param: SwiftMinPartHours}
|
@ -1,15 +0,0 @@
|
||||
resources:
|
||||
SwiftConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: os-apply-config
|
||||
config:
|
||||
swift:
|
||||
devices: { get_input: swift_devices }
|
||||
hash: { get_input: swift_hash_suffix }
|
||||
mount-check: { get_input: swift_mount_check }
|
||||
part-power: { get_input: swift_part_power }
|
||||
proxy-memcache: { get_input: swift_proxy_memcache }
|
||||
replicas: {get_input: swift_replicas }
|
||||
min-part-hours: {get_input: swift_min_part_hours }
|
||||
service-password: { get_input: swift_password }
|
@ -1,77 +0,0 @@
|
||||
heat_template_version: 2013-05-23
|
||||
description: 'Common Swift Storage Configuration'
|
||||
parameters:
|
||||
OvercloudSwiftStorageFlavor:
|
||||
description: Flavor for Swift storage nodes to request when deploying.
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.flavor
|
||||
SwiftReplicas:
|
||||
type: number
|
||||
default: 1
|
||||
description: How many replicas to use in the swift rings.
|
||||
SwiftStorageImage:
|
||||
type: string
|
||||
default: overcloud-swift-storage
|
||||
resources:
|
||||
SwiftStorage0:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image: {get_param: SwiftStorageImage}
|
||||
flavor: {get_param: OvercloudSwiftStorageFlavor}
|
||||
key_name: {get_param: KeyName}
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
SwiftKeystoneConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
keystone:
|
||||
host: {get_input: keystone_host}
|
||||
SwiftStorage0Keystone:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
server: {get_resource: SwiftStorage0}
|
||||
config: {get_resource: SwiftKeystoneConfig}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
keystone_host: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
|
||||
SwiftStorage0Deploy:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
server: {get_resource: SwiftStorage0}
|
||||
config: {get_resource: SwiftConfig}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
swift_hash_suffix: {get_param: SwiftHashSuffix}
|
||||
swift_mount_check: {get_param: SwiftMountCheck}
|
||||
swift_password: {get_param: SwiftPassword}
|
||||
swift_part_power: {get_param: SwiftPartPower}
|
||||
swift_devices:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
- ':%PORT%/d1'
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- {get_attr: [SwiftStorage0, networks, ctlplane, 0]}
|
||||
- ':%PORT%/d1'
|
||||
swift_proxy_memcache:
|
||||
Fn::Join:
|
||||
- ','
|
||||
- Merge::Map:
|
||||
controller0:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- - Fn::Join:
|
||||
- ''
|
||||
- - {get_attr: [controller0, networks, ctlplane, 0]}
|
||||
- ':11211'
|
||||
swift_replicas: { get_param: SwiftReplicas}
|
||||
swift_min_part_hours: { get_param: SwiftMinPartHours}
|
@ -1,23 +0,0 @@
|
||||
resources:
|
||||
undercloudNovaConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
nova:
|
||||
compute_hostname: undercloud
|
||||
compute_driver: {get_param: NovaComputeDriver}
|
||||
compute_manager: {get_param: NovaComputeManager}
|
||||
scheduler_host_manager: {get_param: NovaSchedulerHostManager}
|
||||
db: {list_join: ['', ['mysql://nova:', {get_param: NovaPassword}, '@localhost/nova']]}
|
||||
default_ephemeral_format: ext4
|
||||
host: 127.0.0.1
|
||||
metadata-proxy: false
|
||||
tuning:
|
||||
ram_allocation_ratio: 1.0
|
||||
reserved_host_memory_mb: 0
|
||||
baremetal:
|
||||
arch: {get_input: nova_arch}
|
||||
db: {list_join: ['', ['mysql://nova:', {get_param: NovaPassword}, '@localhost/nova_bm']]}
|
||||
power_manager: {get_input: power_manager}
|
||||
pxe_deploy_timeout: {get_input: pxe_deploy_timeout}
|
||||
service-password: {get_input: nova_service_password}
|
@ -1,37 +0,0 @@
|
||||
parameters:
|
||||
NeutronPublicInterface:
|
||||
default: nic1
|
||||
description: What interface to bridge onto br-ex for network nodes.
|
||||
type: string
|
||||
NovaComputeDriver:
|
||||
default: baremetal.driver.BareMetalDriver
|
||||
description: Full class name for the Nova compute driver
|
||||
type: string
|
||||
NovaComputeManager:
|
||||
default: nova.compute.manager.ComputeManager
|
||||
description: Full class name for the Nova compute manager
|
||||
type: string
|
||||
NovaSchedulerHostManager:
|
||||
default: nova.scheduler.host_manager.HostManager
|
||||
description: Full class name for the Nova scheduler host manager
|
||||
type: string
|
||||
PowerManager:
|
||||
default: nova.virt.baremetal.ipmi.IPMI
|
||||
description: Bare metal power manager driver.
|
||||
type: string
|
||||
PxeDeployTimeout:
|
||||
default: 2400
|
||||
description: Timeout for PXE deployment of baremetal nodes
|
||||
type: number
|
||||
resources:
|
||||
undercloudNovaDeployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudNovaConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
nova_arch: {get_param: BaremetalArch}
|
||||
power_manager: {get_param: PowerManager}
|
||||
pxe_deploy_timeout: {get_param: PxeDeployTimeout}
|
||||
nova_service_password: {get_param: NovaPassword}
|
@ -1,412 +0,0 @@
|
||||
description: Deprecated. Use instack-undercloud instead. All-in-one baremetal OpenStack and all dependencies.
|
||||
heat_template_version: 2013-05-23
|
||||
parameters:
|
||||
AdminPassword:
|
||||
default: unset
|
||||
description: The password for the keystone admin account, used for monitoring, querying neutron etc.
|
||||
type: string
|
||||
hidden: true
|
||||
AdminToken:
|
||||
default: unset
|
||||
description: The keystone auth secret.
|
||||
type: string
|
||||
hidden: true
|
||||
BaremetalArch:
|
||||
default: i386
|
||||
description: The architecture to use in Nova-BM - i386 or amd64.
|
||||
type: string
|
||||
CeilometerMeteringSecret:
|
||||
default: unset
|
||||
description: Secret shared by the ceilometer services.
|
||||
type: string
|
||||
hidden: true
|
||||
CeilometerPassword:
|
||||
default: unset
|
||||
description: The password for the ceilometer service account.
|
||||
type: string
|
||||
hidden: true
|
||||
Debug:
|
||||
default: ''
|
||||
description: Set to True to enable debugging on all services.
|
||||
type: string
|
||||
DefaultSignalTransport:
|
||||
default: CFN_SIGNAL
|
||||
description: Transport to use for software-config signals.
|
||||
type: string
|
||||
constraints:
|
||||
- allowed_values: [ CFN_SIGNAL, HEAT_SIGNAL, NO_SIGNAL ]
|
||||
ExtraConfig:
|
||||
default: {}
|
||||
description: |
|
||||
Additional configuration to inject into the cluster. The JSON should have
|
||||
the following structure:
|
||||
{"FILEKEY":
|
||||
{"config:
|
||||
[{"section": "SECTIONNAME",
|
||||
"values":
|
||||
[{"option": "OPTIONNAME",
|
||||
"value": "VALUENAME"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
For instance:
|
||||
{"nova":
|
||||
{"config":
|
||||
[{"section": "default",
|
||||
"values":
|
||||
[{"option": "compute_manager",
|
||||
"value": "ironic.nova.compute.manager.ClusterComputeManager"
|
||||
}
|
||||
]
|
||||
},
|
||||
{"section": "cells",
|
||||
"values":
|
||||
[{"option": "driver",
|
||||
"value": "nova.cells.rpc_driver.CellsRPCDriver"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
type: json
|
||||
Flavor:
|
||||
description: Flavor to request when deploying.
|
||||
type: string
|
||||
constraints:
|
||||
- custom_constraint: nova.flavor
|
||||
GlanceLogFile:
|
||||
description: The filepath of the file to use for logging messages from Glance.
|
||||
type: string
|
||||
default: ''
|
||||
GlancePassword:
|
||||
default: unset
|
||||
description: The password for the glance service account, used by the glance services.
|
||||
type: string
|
||||
hidden: true
|
||||
GlancePort:
|
||||
default: 9292
|
||||
description: Glance port.
|
||||
type: string
|
||||
GlanceProtocol:
|
||||
default: http
|
||||
description: Protocol to use when connecting to glance, set to https for SSL.
|
||||
type: string
|
||||
GlanceNotifierStrategy:
|
||||
description: Strategy to use for Glance notification queue
|
||||
type: string
|
||||
default: noop
|
||||
KeyName:
|
||||
default: default
|
||||
description: Name of an existing EC2 KeyPair to enable SSH access to the instances
|
||||
type: string
|
||||
KeystoneCACertificate:
|
||||
default: ''
|
||||
description: Keystone self-signed certificate authority certificate.
|
||||
type: string
|
||||
KeystoneSigningCertificate:
|
||||
default: ''
|
||||
description: Keystone certificate for verifying token validity.
|
||||
type: string
|
||||
KeystoneSigningKey:
|
||||
default: ''
|
||||
description: Keystone key for signing tokens.
|
||||
type: string
|
||||
hidden: true
|
||||
KeystoneSSLCertificate:
|
||||
default: ''
|
||||
description: Keystone certificate for verifying token validity.
|
||||
type: string
|
||||
KeystoneSSLCertificateKey:
|
||||
default: ''
|
||||
description: Keystone key for signing tokens.
|
||||
type: string
|
||||
hidden: true
|
||||
HeatPassword:
|
||||
default: unset
|
||||
description: The password for the Heat service account, used by the Heat services.
|
||||
type: string
|
||||
hidden: true
|
||||
HeatStackDomainAdminPassword:
|
||||
description: Password for heat_domain_admin user.
|
||||
type: string
|
||||
default: ''
|
||||
hidden: true
|
||||
ImageUpdatePolicy:
|
||||
default: REBUILD_PRESERVE_EPHEMERAL
|
||||
description: What policy to use when reconstructing instances. REBUILD for rebuilds,
|
||||
REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
|
||||
type: string
|
||||
MysqlInnodbBufferPoolSize:
|
||||
description: >
|
||||
Specifies the size of the buffer pool in megabytes. Setting to
|
||||
zero should be interpreted as "no value" and will defer to the
|
||||
lower level default.
|
||||
type: number
|
||||
default: 0
|
||||
NeutronPassword:
|
||||
default: unset
|
||||
description: The password for the neutron service account, used by neutron agents.
|
||||
type: string
|
||||
hidden: true
|
||||
NeutronPublicInterfaceDefaultRoute:
|
||||
default: ''
|
||||
description: A custom default route for the NeutronPublicInterface.
|
||||
type: string
|
||||
NeutronPublicInterfaceIP:
|
||||
default: ''
|
||||
description: >
|
||||
A custom IP address to put onto the NeutronPublicInterface bridge.
|
||||
See also NeutronPublicInterfaceTagIP for adding a VLAN tagging IP.
|
||||
NeutronPublicInterfaceIP is deprecated in the context of deploying
|
||||
underclouds - its only needed for the seed bootstrap process.
|
||||
type: string
|
||||
NeutronPublicInterfaceRawDevice:
|
||||
default: ''
|
||||
description: If set, the public interface is a vlan with this device as the raw device.
|
||||
type: string
|
||||
NeutronPublicInterfaceTag:
|
||||
default: ''
|
||||
description: >
|
||||
VLAN tag for creating a public VLAN. The tag will be used to
|
||||
create an access port on the exterior bridge, and that port will be
|
||||
given the IP address returned by neutron from the public network.
|
||||
type: string
|
||||
NovaPassword:
|
||||
default: unset
|
||||
description: The password for the nova service account, used by nova-api.
|
||||
type: string
|
||||
hidden: true
|
||||
NeutronDVR:
|
||||
default: 'False'
|
||||
type: string
|
||||
NtpServer:
|
||||
type: string
|
||||
default: ''
|
||||
RabbitCookieSalt:
|
||||
type: string
|
||||
default: unset
|
||||
description: Salt for the rabbit cookie, change this to force the randomly generated rabbit cookie to change.
|
||||
RabbitUserName:
|
||||
default: guest
|
||||
description: The username for RabbitMQ
|
||||
type: string
|
||||
RabbitPassword:
|
||||
default: guest
|
||||
description: The password for RabbitMQ
|
||||
type: string
|
||||
hidden: true
|
||||
SnmpdReadonlyUserName:
|
||||
default: ro_snmp_user
|
||||
description: The user name for SNMPd with readonly rights running on all Overcloud nodes
|
||||
type: string
|
||||
SnmpdReadonlyUserPassword:
|
||||
default: unset
|
||||
description: The user password for SNMPd with readonly rights running on all Overcloud nodes
|
||||
type: string
|
||||
hidden: true
|
||||
undercloudImage:
|
||||
default: undercloud
|
||||
type: string
|
||||
resources:
|
||||
RabbitCookie:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
length: 20
|
||||
salt:
|
||||
get_param: RabbitCookieSalt
|
||||
MysqlRootPassword:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
length: 10
|
||||
undercloudConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
completion-signal: {get_input: deploy_signal_id}
|
||||
admin-password:
|
||||
get_param: AdminPassword
|
||||
admin-token:
|
||||
get_param: AdminToken
|
||||
bootstrap_host:
|
||||
bootstrap_nodeid:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Merge::Map:
|
||||
undercloud:
|
||||
- get_attr:
|
||||
- undercloud
|
||||
- name
|
||||
nodeid: {get_input: bootstack_nodeid}
|
||||
bootstack:
|
||||
public_interface_ip:
|
||||
get_param: NeutronPublicInterfaceIP
|
||||
controller-address:
|
||||
get_input: controller_host
|
||||
corosync:
|
||||
bindnetaddr: {get_input: controller_host}
|
||||
mcastport: 5577
|
||||
nodes:
|
||||
Merge::Map:
|
||||
controller0:
|
||||
ip: {get_attr: [undercloud, networks, ctlplane, 0]}
|
||||
pacemaker:
|
||||
stonith_enabled : false
|
||||
recheck_interval : 5
|
||||
quorum_policy : ignore
|
||||
ceilometer:
|
||||
db: {list_join: ['', ['mysql://ceilometer:', {get_param: CeilometerPassword}, '@localhost/ceilometer']]}
|
||||
debug: {get_param: Debug}
|
||||
metering_secret: {get_param: CeilometerMeteringSecret}
|
||||
snmpd_readonly_user_name:
|
||||
get_param: SnmpdReadonlyUserName
|
||||
snmpd_readonly_user_password:
|
||||
get_param: SnmpdReadonlyUserPassword
|
||||
service-password:
|
||||
get_param: CeilometerPassword
|
||||
db-password: unset
|
||||
glance:
|
||||
backend: file
|
||||
db: {list_join: ['', ['mysql://glance:', {get_param: GlancePassword}, '@localhost/glance']]}
|
||||
debug: {get_param: Debug}
|
||||
host: 127.0.0.1
|
||||
port:
|
||||
get_param: GlancePort
|
||||
protocol:
|
||||
get_param: GlanceProtocol
|
||||
service-password:
|
||||
get_param: GlancePassword
|
||||
notifier-strategy:
|
||||
get_param: GlanceNotifierStrategy
|
||||
log-file:
|
||||
get_param: GlanceLogFile
|
||||
heat:
|
||||
admin_password:
|
||||
get_param: HeatPassword
|
||||
admin_tenant_name: service
|
||||
admin_user: heat
|
||||
auth_encryption_key: unset___________
|
||||
db: {list_join: ['', ['mysql://heat:', {get_param: HeatPassword}, '@localhost/heat']]}
|
||||
debug: {get_param: Debug}
|
||||
stack_domain_admin_password: {get_param: HeatStackDomainAdminPassword}
|
||||
watch_server_url: {get_input: heat.watch_server_url}
|
||||
metadata_server_url: {get_input: heat.metadata_server_url}
|
||||
waitcondition_server_url: {get_input: heat.waitcondition_server_url}
|
||||
keystone:
|
||||
db: {list_join: ['', ['mysql://keystone:', {get_param: AdminToken}, '@localhost/keystone']]}
|
||||
debug: {get_param: Debug}
|
||||
host: 127.0.0.1
|
||||
ca_certificate: {get_param: KeystoneCACertificate}
|
||||
signing_key: {get_param: KeystoneSigningKey}
|
||||
signing_certificate: {get_param: KeystoneSigningCertificate}
|
||||
ssl:
|
||||
certificate: {get_param: KeystoneSSLCertificate}
|
||||
certificate_key: {get_param: KeystoneSSLCertificateKey}
|
||||
mysql:
|
||||
innodb_buffer_pool_size: {get_param: MysqlInnodbBufferPoolSize}
|
||||
root-password: {get_resource: MysqlRootPassword}
|
||||
bind_address: 127.0.0.1
|
||||
neutron:
|
||||
debug: {get_param: Debug}
|
||||
host: 127.0.0.1
|
||||
ovs_db: {list_join: ['', ['mysql://neutron:', {get_param: NeutronPassword}, '@localhost/ovs_neutron?charset=utf8']]}
|
||||
ovs:
|
||||
local_ip:
|
||||
get_input: controller_host
|
||||
public_interface:
|
||||
get_param: NeutronPublicInterface
|
||||
public_interface_raw_device:
|
||||
get_param: NeutronPublicInterfaceRawDevice
|
||||
public_interface_route:
|
||||
get_param: NeutronPublicInterfaceDefaultRoute
|
||||
public_interface_tag:
|
||||
get_param: NeutronPublicInterfaceTag
|
||||
physical_bridge: br-ctlplane
|
||||
physical_network: ctlplane
|
||||
network_vlan_ranges: ctlplane
|
||||
bridge_mappings: ctlplane:br-ctlplane
|
||||
tenant_network_type: vlan
|
||||
enable_tunneling: 'False'
|
||||
service-password:
|
||||
get_param: NeutronPassword
|
||||
rabbit:
|
||||
host: 127.0.0.1
|
||||
username:
|
||||
get_param: RabbitUserName
|
||||
password:
|
||||
get_param: RabbitPassword
|
||||
cookie:
|
||||
get_attr:
|
||||
- RabbitCookie
|
||||
- value
|
||||
ntp:
|
||||
servers:
|
||||
- {server: {get_param: NtpServer}}
|
||||
undercloudPassthroughConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config: {get_input: passthrough_config}
|
||||
undercloud:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image:
|
||||
get_param: undercloudImage
|
||||
flavor:
|
||||
get_param: Flavor
|
||||
key_name:
|
||||
get_param: KeyName
|
||||
image_update_policy:
|
||||
get_param: ImageUpdatePolicy
|
||||
networks:
|
||||
- network: ctlplane
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
undercloudDeployment:
|
||||
depends_on: [undercloudPassthroughDeployment]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: {get_param: DefaultSignalTransport}
|
||||
input_values:
|
||||
bootstack_nodeid:
|
||||
get_attr:
|
||||
- undercloud
|
||||
- name
|
||||
controller_host:
|
||||
get_attr:
|
||||
- undercloud
|
||||
- networks
|
||||
- ctlplane
|
||||
- 0
|
||||
heat.watch_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- get_attr: [undercloud, networks, ctlplane, 0]
|
||||
- ':8003'
|
||||
heat.metadata_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {get_attr: [undercloud, networks, ctlplane, 0]}
|
||||
- ':8000'
|
||||
heat.waitcondition_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {get_attr: [undercloud, networks, ctlplane, 0]}
|
||||
- ':8000/v1/waitcondition'
|
||||
undercloudPassthroughDeployment:
|
||||
depends_on: [undercloudNovaDeployment]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudPassthroughConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
passthrough_config: {get_param: ExtraConfig}
|
@ -1,37 +0,0 @@
|
||||
outputs:
|
||||
PublicIP:
|
||||
description: Address for registering endpoints in the cloud.
|
||||
value: {get_attr: [undercloud_VLANPort, fixed_ips, 0, ip_address]}
|
||||
resources:
|
||||
# Override the main template which can also supply a static route.
|
||||
undercloud_99VLANPort:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudVLANPortConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: NO_SIGNAL
|
||||
undercloudVLANPortConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
neutron:
|
||||
ovs:
|
||||
public_interface_tag_ip:
|
||||
Fn::Join:
|
||||
- '/'
|
||||
- - {get_attr: [undercloud_VLANPort, fixed_ips, 0, ip_address]}
|
||||
- '24'
|
||||
# This should also be pulled out of the subnet. May need a
|
||||
# neutron fix too - XXX make into a parameter and feed it
|
||||
# in via _undercloud.sh for now.
|
||||
# Tell the instance to apply the default route.
|
||||
# Reinstate when https://bugs.launchpad.net/heat/+bug/1336656 is
|
||||
# sorted
|
||||
# public_interface_route:
|
||||
# get_attr: [undercloud_VLANPort, fixed_ips, 0, subnet, gateway_ip]
|
||||
undercloud_VLANPort:
|
||||
type: OS::Neutron::Port
|
||||
properties:
|
||||
name: undercloud_vlan
|
||||
network: public
|
||||
replacement_policy: AUTO
|
@ -1,27 +0,0 @@
|
||||
resources:
|
||||
undercloudNovaConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
nova:
|
||||
compute_hostname: undercloud
|
||||
compute_driver: {get_param: NovaComputeDriver}
|
||||
compute_manager: {get_param: NovaComputeManager}
|
||||
scheduler_host_manager: {get_param: NovaSchedulerHostManager}
|
||||
db: {list_join: ['', ['mysql://nova:', {get_param: NovaPassword}, '@localhost/nova']]}
|
||||
debug: {get_param: Debug}
|
||||
default_ephemeral_format: ext4
|
||||
host: 127.0.0.1
|
||||
metadata-proxy: false
|
||||
tuning:
|
||||
ram_allocation_ratio: 1.0
|
||||
reserved_host_memory_mb: 0
|
||||
service-password: {get_input: nova_service_password}
|
||||
undercloudIronicConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
ironic:
|
||||
db: {list_join: ['', ['mysql://ironic:', {get_param: IronicPassword}, '@localhost/ironic']]}
|
||||
service-password: {get_input: ironic_service_password}
|
||||
virtual_power_ssh_key: {get_input: virtual_power_ssh_key}
|
@ -1,44 +0,0 @@
|
||||
parameters:
|
||||
IronicPassword:
|
||||
type: string
|
||||
description: Ironic password for keystone access
|
||||
hidden: true
|
||||
NeutronPublicInterface:
|
||||
default: nic1
|
||||
description: What interface to bridge onto br-ex for network nodes.
|
||||
type: string
|
||||
NovaComputeDriver:
|
||||
default: nova.virt.ironic.driver.IronicDriver
|
||||
description: Full class name for the Nova compute driver
|
||||
type: string
|
||||
NovaComputeManager:
|
||||
default: ironic.nova.compute.manager.ClusteredComputeManager
|
||||
description: Full class name for the Nova compute manager
|
||||
type: string
|
||||
NovaSchedulerHostManager:
|
||||
default: nova.scheduler.ironic_host_manager.IronicHostManager
|
||||
description: Full class name for the Nova scheduler host manager
|
||||
type: string
|
||||
PowerSSHPrivateKey:
|
||||
description: Private key for using to ssh to a virtual power host.
|
||||
type: string
|
||||
hidden: true
|
||||
resources:
|
||||
undercloudNovaDeployment:
|
||||
depends_on: [undercloudIronicDeployment]
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudNovaConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
nova_service_password: {get_param: NovaPassword}
|
||||
undercloudIronicDeployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudIronicConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
ironic_service_password: {get_param: IronicPassword}
|
||||
virtual_power_ssh_key: {get_param: PowerSSHPrivateKey}
|
@ -1,29 +0,0 @@
|
||||
resources:
|
||||
undercloudNovaConfig:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
config:
|
||||
nova:
|
||||
compute_hostname: undercloud
|
||||
compute_driver: {get_param: NovaComputeDriver}
|
||||
compute_manager: {get_param: NovaComputeManager}
|
||||
scheduler_host_manager: {get_param: NovaSchedulerHostManager}
|
||||
db: {list_join: ['', ['mysql://nova:', {get_param: NovaPassword}, '@localhost/nova']]}
|
||||
default_ephemeral_format: ext4
|
||||
host: 127.0.0.1
|
||||
metadata-proxy: false
|
||||
tuning:
|
||||
ram_allocation_ratio: 1.0
|
||||
reserved_host_memory_mb: 0
|
||||
baremetal:
|
||||
arch: {get_input: nova_arch}
|
||||
db: {list_join: ['', ['mysql://nova:', {get_param: NovaPassword}, '@localhost/nova_bm']]}
|
||||
power_manager: {get_input: power_manager}
|
||||
pxe_deploy_timeout: {get_input: pxe_deploy_timeout}
|
||||
virtual_power:
|
||||
user: {get_input: user}
|
||||
ssh_host: {get_input: ssh_host}
|
||||
ssh_key: {get_input: ssh_key}
|
||||
type: virsh
|
||||
service-password: {get_input: nova_service_password}
|
||||
|
@ -1,52 +0,0 @@
|
||||
parameters:
|
||||
NeutronPublicInterface:
|
||||
default: nic1
|
||||
description: What interface to bridge onto br-ex for network nodes.
|
||||
type: string
|
||||
NovaComputeDriver:
|
||||
default: baremetal.driver.BareMetalDriver
|
||||
description: Full class name for the Nova compute driver
|
||||
type: string
|
||||
NovaComputeManager:
|
||||
default: nova.compute.manager.ComputeManager
|
||||
description: Full class name for the Nova compute manager
|
||||
type: string
|
||||
NovaSchedulerHostManager:
|
||||
default: nova.scheduler.host_manager.HostManager
|
||||
description: Full class name for the Nova scheduler host manager
|
||||
type: string
|
||||
PowerManager:
|
||||
default: nova.virt.baremetal.virtual_power_driver.VirtualPowerManager
|
||||
description: Bare metal power manager driver.
|
||||
type: string
|
||||
PowerSSHHost:
|
||||
default: 192.168.122.1
|
||||
description: SSH host to ssh to for power management operations.
|
||||
type: string
|
||||
PowerSSHPrivateKey:
|
||||
description: Private key for using to ssh to a virtual power host.
|
||||
type: string
|
||||
hidden: true
|
||||
PowerUserName:
|
||||
default: stack
|
||||
description: What username to ssh to the virtual power host with.
|
||||
type: string
|
||||
PxeDeployTimeout:
|
||||
default: 2400
|
||||
description: Timeout for PXE deployment of baremetal nodes
|
||||
type: number
|
||||
resources:
|
||||
undercloudNovaDeployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config: {get_resource: undercloudNovaConfig}
|
||||
server: {get_resource: undercloud}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
nova_arch: {get_param: BaremetalArch}
|
||||
power_manager: {get_param: PowerManager}
|
||||
pxe_deploy_timeout: {get_param: PxeDeployTimeout}
|
||||
nova_service_password: {get_param: NovaPassword}
|
||||
user: {get_param: PowerUserName}
|
||||
ssh_host: {get_param: PowerSSHHost}
|
||||
ssh_key: {get_param: PowerSSHPrivateKey}
|
@ -14,10 +14,3 @@ classifier =
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Other
|
||||
Environment :: Console
|
||||
|
||||
[files]
|
||||
packages =
|
||||
tripleo_heat_merge
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
tripleo-heat-merge = tripleo_heat_merge.merge:main
|
||||
|
@ -1,43 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -ue
|
||||
result=""
|
||||
cleanup() {
|
||||
if [ -n "$result" ] ; then
|
||||
rm -f $result
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
run_test() {
|
||||
local cmd=$1
|
||||
local expected=$2
|
||||
result=$(mktemp /tmp/test_merge.XXXXXX)
|
||||
fail=0
|
||||
$cmd --output $result
|
||||
if ! cmp $result $expected ; then
|
||||
diff -u $expected $result || :
|
||||
echo FAIL - $cmd result does not match expected
|
||||
fail=1
|
||||
else
|
||||
echo PASS - $cmd
|
||||
fi
|
||||
cleanup
|
||||
}
|
||||
echo
|
||||
merge_py="./tripleo_heat_merge/merge.py"
|
||||
run_test "python $merge_py examples/source.yaml" examples/source_lib_result.yaml
|
||||
run_test "python $merge_py examples/source2.yaml" examples/source2_lib_result.yaml
|
||||
run_test "python $merge_py examples/source_include_subkey.yaml" examples/source_include_subkey_result.yaml
|
||||
run_test "python $merge_py examples/launchconfig1.yaml examples/launchconfig2.yaml" examples/launchconfig_result.yaml
|
||||
run_test "python $merge_py --scale NovaCompute=3 examples/scale1.yaml" examples/scale_result.yaml
|
||||
run_test "python $merge_py --scale NovaCompute=3 examples/scale_map.yaml" examples/scale_map_result.yaml
|
||||
run_test "python $merge_py --hot examples/source_hot.yaml" examples/source_lib_result_hot.yaml
|
||||
run_test "python $merge_py --hot examples/source2_hot.yaml" examples/source2_lib_result_hot.yaml
|
||||
run_test "python $merge_py --hot examples/source_include_subkey_hot.yaml" examples/source_include_subkey_result_hot.yaml
|
||||
run_test "python $merge_py --hot examples/launchconfig1_hot.yaml examples/launchconfig2_hot.yaml" examples/launchconfig_result_hot.yaml
|
||||
run_test "python $merge_py --hot --scale NovaCompute=3 examples/scale1_hot.yaml" examples/scale_result_hot.yaml
|
||||
run_test "python $merge_py --hot --scale NovaCompute=3 examples/scale_map_hot.yaml" examples/scale_map_result_hot.yaml
|
||||
run_test "python $merge_py --hot --scale NovaCompute=5,1,2 examples/scale_map_hot.yaml" examples/scale_map_result_hot_blacklist.yaml
|
||||
run_test "python $merge_py --hot --scale NovaCompute=3, examples/scale_map_hot.yaml" examples/scale_map_result_hot.yaml
|
||||
echo
|
||||
trap - EXIT
|
||||
exit $fail
|
@ -1,436 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
import argparse
|
||||
|
||||
|
||||
class Cfn(object):
|
||||
|
||||
base_template = {
|
||||
'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Description': []
|
||||
}
|
||||
get_resource = 'Ref'
|
||||
get_param = 'Ref'
|
||||
description = 'Description'
|
||||
parameters = 'Parameters'
|
||||
outputs = 'Outputs'
|
||||
resources = 'Resources'
|
||||
type = 'Type'
|
||||
properties = 'Properties'
|
||||
metadata = 'Metadata'
|
||||
depends_on = 'DependsOn'
|
||||
get_attr = 'Fn::GetAtt'
|
||||
|
||||
|
||||
class Hot(object):
|
||||
|
||||
base_template = {
|
||||
'heat_template_version': '2013-05-23',
|
||||
'description': []
|
||||
}
|
||||
get_resource = 'get_resource'
|
||||
get_param = 'get_param'
|
||||
description = 'description'
|
||||
parameters = 'parameters'
|
||||
outputs = 'outputs'
|
||||
resources = 'resources'
|
||||
type = 'type'
|
||||
properties = 'properties'
|
||||
metadata = 'metadata'
|
||||
depends_on = 'depends_on'
|
||||
get_attr = 'get_attr'
|
||||
|
||||
|
||||
lang = Cfn()
|
||||
|
||||
|
||||
def apply_maps(template):
|
||||
"""Apply Merge::Map within template.
|
||||
|
||||
Any dict {'Merge::Map': {'Foo': 'Bar', 'Baz': 'Quux'}}
|
||||
will resolve to ['Bar', 'Quux'] - that is a dict with key
|
||||
'Merge::Map' is replaced entirely by that dict['Merge::Map'].values().
|
||||
"""
|
||||
if isinstance(template, dict):
|
||||
if 'Merge::Map' in template:
|
||||
return sorted(
|
||||
apply_maps(value) for value in template['Merge::Map'].values()
|
||||
)
|
||||
else:
|
||||
return dict((key, apply_maps(value))
|
||||
for key, value in template.items())
|
||||
elif isinstance(template, list):
|
||||
return [apply_maps(item) for item in template]
|
||||
else:
|
||||
return template
|
||||
|
||||
|
||||
def apply_scaling(template, scaling, in_copies=None):
|
||||
"""Apply a set of scaling operations to template.
|
||||
|
||||
This is a single pass recursive function: for each call we process one
|
||||
dict or list and recurse to handle children containers.
|
||||
|
||||
Values are handled via scale_value.
|
||||
|
||||
Keys in dicts are copied per the scaling rule.
|
||||
Values are either replaced or copied depending on whether the given
|
||||
scaling rule is in in_copies.
|
||||
|
||||
in_copies is reset to None when a dict {'Merge::Map': someobject} is
|
||||
encountered.
|
||||
|
||||
:param scaling: A dict of prefix -> (count, blacklists).
|
||||
"""
|
||||
in_copies = dict(in_copies or {})
|
||||
# Shouldn't be needed but to avoid unexpected side effects/bugs we short
|
||||
# circuit no-ops.
|
||||
if not scaling:
|
||||
return template
|
||||
if isinstance(template, dict):
|
||||
if 'Merge::Map' in template:
|
||||
in_copies = None
|
||||
new_template = {}
|
||||
for key, value in template.items():
|
||||
for prefix, copy_num, new_key in scale_value(
|
||||
key, scaling, in_copies):
|
||||
if prefix:
|
||||
# e.g. Compute0, 1, Compute1Foo
|
||||
in_copies[prefix] = prefix[:-1] + str(copy_num)
|
||||
if isinstance(value, (dict, list)):
|
||||
new_value = apply_scaling(value, scaling, in_copies)
|
||||
new_template[new_key] = new_value
|
||||
else:
|
||||
new_values = list(scale_value(value, scaling, in_copies))
|
||||
# We have nowhere to multiply a non-container value of a
|
||||
# dict, so it may be copied or unchanged but not scaled.
|
||||
assert len(new_values) == 1
|
||||
new_template[new_key] = new_values[0][2]
|
||||
if prefix:
|
||||
del in_copies[prefix]
|
||||
return new_template
|
||||
elif isinstance(template, list):
|
||||
new_template = []
|
||||
for value in template:
|
||||
if isinstance(value, (dict, list)):
|
||||
new_template.append(apply_scaling(value, scaling, in_copies))
|
||||
else:
|
||||
for _, _, new_value in scale_value(value, scaling, in_copies):
|
||||
new_template.append(new_value)
|
||||
return new_template
|
||||
else:
|
||||
raise Exception("apply_scaling called with non-container %r" % template)
|
||||
|
||||
|
||||
def scale_value(value, scaling, in_copies):
|
||||
"""Scale out a value.
|
||||
|
||||
:param value: The value to scale (not a container).
|
||||
:param scaling: The scaling map (prefix-> (copies, blacklist) to use.
|
||||
:param in_copies: What containers we're currently copying.
|
||||
:return: An iterator of the new values for the value as tuples:
|
||||
(prefix, copy_num, value). E.g. Compute0, 1, Compute1Foo
|
||||
prefix and copy_num are only set when:
|
||||
- a prefix in scaling matches value
|
||||
- and that prefix is not in in_copies
|
||||
"""
|
||||
if isinstance(value, (str, unicode)):
|
||||
for prefix, (copies, blacklist) in scaling.items():
|
||||
if not value.startswith(prefix):
|
||||
continue
|
||||
suffix = value[len(prefix):]
|
||||
if prefix in in_copies:
|
||||
# Adjust to the copy number we're on
|
||||
yield None, None, in_copies[prefix] + suffix
|
||||
return
|
||||
else:
|
||||
for n in range(copies):
|
||||
if n not in blacklist:
|
||||
yield prefix, n, prefix[:-1] + str(n) + suffix
|
||||
return
|
||||
yield None, None, value
|
||||
else:
|
||||
yield None, None, value
|
||||
|
||||
|
||||
def parse_scaling(scaling_args):
|
||||
"""Translate a list of scaling requests to a dict prefix:count."""
|
||||
scaling_args = scaling_args or []
|
||||
result = {}
|
||||
for item in scaling_args:
|
||||
key, values = item.split('=')
|
||||
values = values.split(',')
|
||||
value = int(values[0])
|
||||
blacklist = frozenset(int(v) for v in values[1:] if v)
|
||||
result[key + '0'] = value, blacklist
|
||||
return result
|
||||
|
||||
|
||||
def _translate_role(role, master_role, slave_roles):
|
||||
if not master_role:
|
||||
return role
|
||||
if role == master_role:
|
||||
return role
|
||||
if role not in slave_roles:
|
||||
return role
|
||||
return master_role
|
||||
|
||||
def translate_role(role, master_role, slave_roles):
|
||||
r = _translate_role(role, master_role, slave_roles)
|
||||
if not isinstance(r, basestring):
|
||||
raise Exception('%s -> %r' % (role, r))
|
||||
return r
|
||||
|
||||
def resolve_params(item, param, value):
|
||||
if item in ({lang.get_param: param}, {lang.get_resource: param}):
|
||||
return value
|
||||
if isinstance(item, dict):
|
||||
copy_item = dict(item)
|
||||
for k, v in iter(copy_item.items()):
|
||||
item[k] = resolve_params(v, param, value)
|
||||
elif isinstance(item, list):
|
||||
copy_item = list(item)
|
||||
new_item = []
|
||||
for v in copy_item:
|
||||
new_item.append(resolve_params(v, param, value))
|
||||
item = new_item
|
||||
return item
|
||||
|
||||
MERGABLE_TYPES = {'OS::Nova::Server':
|
||||
{'image': 'image'},
|
||||
'AWS::EC2::Instance':
|
||||
{'image': 'ImageId'},
|
||||
'AWS::AutoScaling::LaunchConfiguration':
|
||||
{},
|
||||
}
|
||||
INCLUDED_TEMPLATE_DIR = os.getcwd()
|
||||
|
||||
|
||||
def resolve_includes(template, params=None):
|
||||
new_template = {}
|
||||
if params is None:
|
||||
params = {}
|
||||
for key, value in iter(template.items()):
|
||||
if key == '__include__':
|
||||
new_params = dict(params) # do not propagate up the stack
|
||||
if not isinstance(value, dict):
|
||||
raise ValueError('__include__ must be a mapping')
|
||||
if 'path' not in value:
|
||||
raise ValueError('__include__ must have path')
|
||||
if 'params' in value:
|
||||
if not isinstance(value['params'], dict):
|
||||
raise ValueError('__include__ params must be a mapping')
|
||||
new_params.update(value['params'])
|
||||
with open(value['path']) as include_file:
|
||||
sub_template = yaml.safe_load(include_file.read())
|
||||
if 'subkey' in value:
|
||||
if ((not isinstance(value['subkey'], int)
|
||||
and not isinstance(sub_template, dict))):
|
||||
raise RuntimeError('subkey requires mapping root or'
|
||||
' integer for list root')
|
||||
sub_template = sub_template[value['subkey']]
|
||||
for k, v in iter(new_params.items()):
|
||||
sub_template = resolve_params(sub_template, k, v)
|
||||
new_template.update(resolve_includes(sub_template))
|
||||
else:
|
||||
if isinstance(value, dict):
|
||||
new_template[key] = resolve_includes(value)
|
||||
else:
|
||||
new_template[key] = value
|
||||
return new_template
|
||||
|
||||
def main(argv=None):
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('templates', nargs='+')
|
||||
parser.add_argument('--master-role', nargs='?',
|
||||
help='Translate slave_roles to this')
|
||||
parser.add_argument('--slave-roles', nargs='*',
|
||||
help='Translate all of these to master_role')
|
||||
parser.add_argument('--included-template-dir', nargs='?',
|
||||
default=INCLUDED_TEMPLATE_DIR,
|
||||
help='Path for resolving included templates')
|
||||
parser.add_argument('--output',
|
||||
help='File to write output to. - for stdout',
|
||||
default='-')
|
||||
parser.add_argument('--scale', action="append",
|
||||
help="Names to scale out. Pass Prefix=2 to cause a key Prefix0Foo to "
|
||||
"be copied to Prefix1Foo in the output, and value Prefix0Bar to be"
|
||||
"renamed to Prefix1Bar inside that copy, or copied to Prefix1Bar "
|
||||
"outside of any copy. Pass Prefix=3,1 to cause Prefix1* to be elided"
|
||||
"when scaling Prefix out. Prefix=4,1,2 will likewise elide Prefix1 and"
|
||||
"Prefix2.")
|
||||
parser.add_argument(
|
||||
'--change-image-params', action='store_true', default=False,
|
||||
help="Change parameters in templates to match resource names. This was "
|
||||
" the default at one time but it causes issues when parameter "
|
||||
" names need to remain stable.")
|
||||
parser.add_argument(
|
||||
'--hot', action='store_true', default=False,
|
||||
help="Assume source templates are in the HOT format, and generate a "
|
||||
"HOT template artifact.")
|
||||
args = parser.parse_args(argv)
|
||||
if args.hot:
|
||||
global lang
|
||||
lang = Hot()
|
||||
|
||||
templates = args.templates
|
||||
scaling = parse_scaling(args.scale)
|
||||
merged_template = merge(templates, args.master_role, args.slave_roles,
|
||||
args.included_template_dir, scaling=scaling,
|
||||
change_image_params=args.change_image_params)
|
||||
if args.output == '-':
|
||||
out_file = sys.stdout
|
||||
else:
|
||||
out_file = file(args.output, 'wt')
|
||||
out_file.write(merged_template)
|
||||
|
||||
|
||||
def merge(templates, master_role=None, slave_roles=None,
|
||||
included_template_dir=INCLUDED_TEMPLATE_DIR,
|
||||
scaling=None, change_image_params=None):
|
||||
scaling = scaling or {}
|
||||
errors = []
|
||||
end_template = dict(lang.base_template)
|
||||
resource_changes=[]
|
||||
for template_path in templates:
|
||||
template = yaml.safe_load(open(template_path))
|
||||
# Resolve __include__ tags
|
||||
template = resolve_includes(template)
|
||||
end_template[lang.description].append(template.get(lang.description,
|
||||
template_path))
|
||||
new_parameters = template.get(lang.parameters, {})
|
||||
for p, pbody in sorted(new_parameters.items()):
|
||||
if p in end_template.get(lang.parameters, {}):
|
||||
if pbody != end_template[lang.parameters][p]:
|
||||
errors.append('Parameter %s from %s conflicts.' % (p,
|
||||
template_path))
|
||||
continue
|
||||
if lang.parameters not in end_template:
|
||||
end_template[lang.parameters] = {}
|
||||
end_template[lang.parameters][p] = pbody
|
||||
|
||||
new_outputs = template.get(lang.outputs, {})
|
||||
for o, obody in sorted(new_outputs.items()):
|
||||
if o in end_template.get(lang.outputs, {}):
|
||||
if pbody != end_template[lang.outputs][p]:
|
||||
errors.append('Output %s from %s conflicts.' % (o,
|
||||
template_path))
|
||||
continue
|
||||
if lang.outputs not in end_template:
|
||||
end_template[lang.outputs] = {}
|
||||
end_template[lang.outputs][o] = obody
|
||||
|
||||
new_resources = template.get(lang.resources, {})
|
||||
for r, rbody in sorted(new_resources.items()):
|
||||
if rbody[lang.type] in MERGABLE_TYPES:
|
||||
if change_image_params:
|
||||
if 'image' in MERGABLE_TYPES[rbody[lang.type]]:
|
||||
image_key = MERGABLE_TYPES[rbody[lang.type]]['image']
|
||||
# XXX Assuming ImageId is always a Ref
|
||||
ikey_val = end_template[lang.parameters][rbody[lang.properties][image_key][lang.get_param]]
|
||||
del end_template[lang.parameters][rbody[lang.properties][image_key][lang.get_param]]
|
||||
if 'OpenStack::Role' in rbody.get(lang.metadata, {}):
|
||||
sys.stderr.write("WARNING: OpenStack::Role is deprecated"
|
||||
" and will be removed in a later release\n");
|
||||
role = rbody.get(lang.metadata, {}).get('OpenStack::Role', r)
|
||||
role = translate_role(role, master_role, slave_roles)
|
||||
if role != r:
|
||||
resource_changes.append((r, role))
|
||||
if role in end_template.get(lang.resources, {}):
|
||||
new_metadata = rbody.get(lang.metadata, {})
|
||||
for m, mbody in iter(new_metadata.items()):
|
||||
if m in end_template[lang.resources][role].get(lang.metadata, {}):
|
||||
if m == 'OpenStack::ImageBuilder::Elements':
|
||||
end_template[lang.resources][role][lang.metadata][m].extend(mbody)
|
||||
sys.stderr.write(
|
||||
"WARNING: OpenStack::ImageBuilder::Elements"
|
||||
" is deprecated and will be removed in a"
|
||||
" later release\n");
|
||||
continue
|
||||
if mbody != end_template[lang.resources][role][lang.metadata][m]:
|
||||
errors.append('Role %s metadata key %s conflicts.' %
|
||||
(role, m))
|
||||
continue
|
||||
role_res = end_template[lang.resources][role]
|
||||
if role_res[lang.type] == 'OS::Heat::StructuredConfig':
|
||||
end_template[lang.resources][role][lang.properties]['config'][m] = mbody
|
||||
else:
|
||||
end_template[lang.resources][role][lang.metadata][m] = mbody
|
||||
continue
|
||||
if lang.resources not in end_template:
|
||||
end_template[lang.resources] = {}
|
||||
end_template[lang.resources][role] = rbody
|
||||
if change_image_params:
|
||||
if 'image' in MERGABLE_TYPES[rbody[lang.type]]:
|
||||
ikey = '%sImage' % (role)
|
||||
end_template[lang.resources][role][lang.properties][image_key] = {lang.get_param: ikey}
|
||||
end_template[lang.parameters][ikey] = ikey_val
|
||||
elif rbody[lang.type] == 'FileInclude':
|
||||
# we trust os.path.join to DTRT: if FileInclude path isn't
|
||||
# absolute, join to included_template_dir (./)
|
||||
with open(os.path.join(included_template_dir, rbody['Path'])) as rfile:
|
||||
include_content = yaml.safe_load(rfile.read())
|
||||
subkeys = rbody.get('SubKey','').split('.')
|
||||
while len(subkeys) and subkeys[0]:
|
||||
include_content = include_content[subkeys.pop(0)]
|
||||
for replace_param, replace_value in iter(rbody.get(lang.parameters,
|
||||
{}).items()):
|
||||
include_content = resolve_params(include_content,
|
||||
replace_param,
|
||||
replace_value)
|
||||
if lang.resources not in end_template:
|
||||
end_template[lang.resources] = {}
|
||||
end_template[lang.resources][r] = include_content
|
||||
else:
|
||||
if r in end_template.get(lang.resources, {}):
|
||||
if rbody != end_template[lang.resources][r]:
|
||||
errors.append('Resource %s from %s conflicts' % (r,
|
||||
template_path))
|
||||
continue
|
||||
if lang.resources not in end_template:
|
||||
end_template[lang.resources] = {}
|
||||
end_template[lang.resources][r] = rbody
|
||||
|
||||
end_template = apply_scaling(end_template, scaling)
|
||||
end_template = apply_maps(end_template)
|
||||
|
||||
def fix_ref(item, old, new):
|
||||
if isinstance(item, dict):
|
||||
copy_item = dict(item)
|
||||
for k, v in sorted(copy_item.items()):
|
||||
if k == lang.get_resource and v == old:
|
||||
item[k] = new
|
||||
continue
|
||||
if k == lang.depends_on and v == old:
|
||||
item[k] = new
|
||||
continue
|
||||
if k == lang.get_attr and isinstance(v, list) and v[0] == old:
|
||||
new_list = list(v)
|
||||
new_list[0] = new
|
||||
item[k] = new_list
|
||||
continue
|
||||
if k == 'AllowedResources' and isinstance(v, list) and old in v:
|
||||
while old in v:
|
||||
pos = v.index(old)
|
||||
v[pos] = new
|
||||
continue
|
||||
fix_ref(v, old, new)
|
||||
elif isinstance(item, list):
|
||||
copy_item = list(item)
|
||||
for v in item:
|
||||
fix_ref(v, old, new)
|
||||
|
||||
for change in resource_changes:
|
||||
fix_ref(end_template, change[0], change[1])
|
||||
|
||||
if errors:
|
||||
for e in errors:
|
||||
sys.stderr.write("ERROR: %s\n" % e)
|
||||
end_template[lang.description] = ','.join(end_template[lang.description])
|
||||
return yaml.safe_dump(end_template, default_flow_style=False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue
Block a user