Switch overcloud to software-config
This migrates the overcloud to using OS::Heat::StructuredConfig and OS::Heat::StructuredDeployment. With those tools, we can decouple servers from software configuration and begin to deprecate features in tripleo_heat_merge. Change-Id: Ice85f0711e90d0fabf1d1bc4698201c4d6758508
This commit is contained in:
parent
a830cea3b1
commit
be5af1a35e
4
Makefile
4
Makefile
@ -11,8 +11,8 @@ overcloud_source_deps = nova-compute-instance.yaml
|
||||
|
||||
all: $(generated_templates)
|
||||
|
||||
overcloud.yaml: overcloud-source.yaml block-storage.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml $(overcloud_source_deps)
|
||||
python ./tripleo_heat_merge/merge.py --scale NovaCompute=$${COMPUTESCALE:-'1'} --scale SwiftStorage=$${SWIFTSTORAGESCALE='0'} --scale BlockStorage=$${BLOCKSTORAGESCALE='0'} overcloud-source.yaml block-storage.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml > $@.tmp
|
||||
overcloud.yaml: overcloud-source.yaml block-storage.yaml swift-deploy.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml nova-compute-config.yaml $(overcloud_source_deps)
|
||||
python ./tripleo_heat_merge/merge.py --scale NovaCompute=$${COMPUTESCALE:-'1'} --scale SwiftStorage=$${SWIFTSTORAGESCALE='0'} --scale BlockStorage=$${BLOCKSTORAGESCALE='0'} overcloud-source.yaml block-storage.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml swift-deploy.yaml nova-compute-config.yaml > $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
overcloud-with-block-storage-nfs.yaml: overcloud-source.yaml block-storage-nfs.yaml nfs-server-source.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml $(overcloud_source_deps)
|
||||
|
@ -15,30 +15,6 @@ Parameters:
|
||||
Type: String
|
||||
Default: True
|
||||
Resources:
|
||||
BlockStorageAccessPolicy:
|
||||
Type: OS::Heat::AccessPolicy
|
||||
Properties:
|
||||
AllowedResources:
|
||||
- BlockStorage0
|
||||
- BlockStorage0Config
|
||||
BlockStorageUser:
|
||||
Type: AWS::IAM::User
|
||||
Properties:
|
||||
Policies: [ { Ref: BlockStorageAccessPolicy } ]
|
||||
BlockStorage0Key:
|
||||
Type: AWS::IAM::AccessKey
|
||||
Properties:
|
||||
UserName:
|
||||
Ref: BlockStorageUser
|
||||
BlockStorage0CompletionCondition:
|
||||
Type: AWS::CloudFormation::WaitCondition
|
||||
DependsOn: controller0Config
|
||||
Properties:
|
||||
Handle: {Ref: BlockStorage0CompletionHandle}
|
||||
Count: '1'
|
||||
Timeout: '1800'
|
||||
BlockStorage0CompletionHandle:
|
||||
Type: AWS::CloudFormation::WaitConditionHandle
|
||||
BlockStorage0:
|
||||
Type: OS::Nova::Server
|
||||
Properties:
|
||||
@ -46,60 +22,64 @@ Resources:
|
||||
{Ref: BlockStorageImage}
|
||||
flavor: {Ref: OvercloudBlockStorageFlavor}
|
||||
key_name: {Ref: KeyName}
|
||||
Metadata:
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: BlockStorage0Key
|
||||
secret_access_key:
|
||||
Fn::GetAtt: [ BlockStorage0Key, SecretAccessKey ]
|
||||
stack_name: {Ref: 'AWS::StackName'}
|
||||
path: BlockStorage0Config.Metadata
|
||||
OpenStack::ImageBuilder::Elements: [ cinder ]
|
||||
BlockStorage0Config:
|
||||
Type: AWS::AutoScaling::LaunchConfiguration
|
||||
BlockStorage0Deployment:
|
||||
Type: OS::Heat::StructuredDeployment
|
||||
Properties:
|
||||
InstanceType: '0'
|
||||
ImageId: '0'
|
||||
Metadata:
|
||||
completion-handle:
|
||||
Ref: BlockStorage0CompletionHandle
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: BlockStorage0Key
|
||||
secret_access_key:
|
||||
Fn::GetAtt: [ BlockStorage0Key, SecretAccessKey ]
|
||||
stack_name: {Ref: 'AWS::StackName'}
|
||||
path: BlockStorage0Config.Metadata
|
||||
admin-password: {Ref: AdminPassword}
|
||||
keystone:
|
||||
host: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
cinder:
|
||||
db: {"Fn::Join": ['', ['mysql://cinder:unset@', {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } , '/cinder']]}
|
||||
volume_size_mb: '5000'
|
||||
service-password:
|
||||
Ref: CinderPassword
|
||||
iscsi-helper:
|
||||
Ref: CinderISCSIHelper
|
||||
admin-password: {Ref: AdminPassword}
|
||||
rabbit:
|
||||
host: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
username: {Ref: RabbitUserName}
|
||||
password: {Ref: RabbitPassword}
|
||||
interfaces:
|
||||
control: {Ref: NeutronPublicInterface}
|
||||
neutron:
|
||||
ovs:
|
||||
local_ip:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- BlockStorage0
|
||||
- networks
|
||||
tenant_network_type: {Ref: NeutronNetworkType}
|
||||
enable_tunneling: {Ref: NeutronEnableTunnelling}
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
server: {Ref: BlockStorage0}
|
||||
config: {Ref: BlockStorageConfig}
|
||||
input_values:
|
||||
controller_host: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
cinder_dsn: {"Fn::Join": ['', ['mysql://cinder:unset@', {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } , '/cinder']]}
|
||||
neutron_local_ip: {"Fn::Select": [0, "Fn::Select": [ctlplane, [{"Fn::GetAtt": [BlockStorage0 , networks]}]]]}
|
||||
BlockStorageConfig:
|
||||
Type: OS::Heat::StructuredConfig
|
||||
Properties:
|
||||
config:
|
||||
admin-password: {Ref: AdminPassword}
|
||||
keystone:
|
||||
host: {get_input: controller_host}
|
||||
cinder:
|
||||
db: {get_input: cinder_dsn}
|
||||
volume_size_mb: '5000'
|
||||
service-password:
|
||||
Ref: CinderPassword
|
||||
iscsi-helper:
|
||||
Ref: CinderISCSIHelper
|
||||
admin-password: {Ref: AdminPassword}
|
||||
rabbit:
|
||||
host: {get_input: controller_host}
|
||||
username: {Ref: RabbitUserName}
|
||||
password: {Ref: RabbitPassword}
|
||||
interfaces:
|
||||
control: {Ref: NeutronPublicInterface}
|
||||
neutron:
|
||||
ovs:
|
||||
local_ip: {get_input: neutron_local_ip}
|
||||
tenant_network_type: {Ref: NeutronNetworkType}
|
||||
enable_tunneling: {Ref: NeutronEnableTunnelling}
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
config:
|
||||
keystone:
|
||||
host: {get_input: controller_host}
|
||||
cinder:
|
||||
db: {get_input: cinder_dsn}
|
||||
volume_size_mb: '5000'
|
||||
service-password:
|
||||
Ref: CinderPassword
|
||||
iscsi-helper:
|
||||
Ref: CinderISCSIHelper
|
||||
admin-password: {Ref: AdminPassword}
|
||||
rabbit:
|
||||
host: {get_input: controller_host}
|
||||
username: {Ref: RabbitUserName}
|
||||
password: {Ref: RabbitPassword}
|
||||
interfaces:
|
||||
control: {Ref: NeutronPublicInterface}
|
||||
neutron:
|
||||
ovs:
|
||||
local_ip: { get_input: neutron_local_ip }
|
||||
tenant_network_type: {Ref: NeutronNetworkType}
|
||||
enable_tunneling: {Ref: NeutronEnableTunnelling}
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
|
47
nova-compute-config.yaml
Normal file
47
nova-compute-config.yaml
Normal file
@ -0,0 +1,47 @@
|
||||
Resources:
|
||||
NovaComputeConfig:
|
||||
Type: OS::Heat::StructuredConfig
|
||||
Properties:
|
||||
config:
|
||||
nova:
|
||||
compute_driver: { get_input: nova_compute_driver }
|
||||
compute_libvirt_type: { get_input: nova_compute_libvirt_type }
|
||||
db: {get_input: nova_dsn}
|
||||
host: {get_input: nova_api_host}
|
||||
service-password: {get_input: nova_password}
|
||||
ceilometer:
|
||||
db: {get_input: ceilometer_dsn}
|
||||
metering_secret: {get_input: ceilometer_metering_secret}
|
||||
service-password: {get_input: ceilometer_password}
|
||||
compute_agent: {get_input: ceilometer_compute_agent}
|
||||
glance:
|
||||
host: {get_input: glance_host}
|
||||
hosts: {get_input: static_hosts}
|
||||
keystone:
|
||||
host: {get_input: keystone_host}
|
||||
neutron:
|
||||
flat-networks: {get_input: neutron_flat_networks}
|
||||
host: {get_input: neutron_host}
|
||||
ovs_db: {get_input: neutron_dsn}
|
||||
ovs:
|
||||
local_ip: {get_input: neutron_local_ip}
|
||||
tenant_network_type: {get_input: neutron_tenant_network_type}
|
||||
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}
|
||||
service-password: {get_input: neutron_password}
|
||||
admin-password: {get_input: admin_password}
|
||||
rabbit:
|
||||
host: {get_input: rabbit_host}
|
||||
username: {get_input: rabbit_user_name}
|
||||
password: {get_input: rabbit_password}
|
||||
live-update:
|
||||
host: {get_input: live_update_host}
|
||||
username: {get_input: live_update_username}
|
||||
password: {get_input: live_update_password}
|
||||
tenant-name: {get_input: live_update_tenant_name}
|
||||
base_image_id: {get_input: nova_image}
|
||||
live_update_image_id: {get_input: live_update_compute_image}
|
||||
completion-signal: {get_input: deploy_signal_id}
|
@ -114,28 +114,6 @@ Parameters:
|
||||
Description: The image ID for live-updates to the overcloud compute nodes.
|
||||
Default: ''
|
||||
Resources:
|
||||
ComputeAccessPolicy:
|
||||
Type: OS::Heat::AccessPolicy
|
||||
Properties:
|
||||
AllowedResources: [ NovaCompute0 ]
|
||||
ComputeUser:
|
||||
Type: AWS::IAM::User
|
||||
Properties:
|
||||
Policies: [ { Ref: ComputeAccessPolicy } ]
|
||||
NovaCompute0Key:
|
||||
Type: AWS::IAM::AccessKey
|
||||
Properties:
|
||||
UserName:
|
||||
Ref: ComputeUser
|
||||
NovaCompute0CompletionCondition:
|
||||
Type: AWS::CloudFormation::WaitCondition
|
||||
DependsOn: controller0Config
|
||||
Properties:
|
||||
Handle: {Ref: NovaCompute0CompletionHandle}
|
||||
Count: '1'
|
||||
Timeout: '1800'
|
||||
NovaCompute0CompletionHandle:
|
||||
Type: AWS::CloudFormation::WaitConditionHandle
|
||||
NovaCompute0:
|
||||
Type: OS::Nova::Server
|
||||
Properties:
|
||||
@ -145,79 +123,43 @@ Resources:
|
||||
Ref: ImageUpdatePolicy
|
||||
flavor: {Ref: OvercloudComputeFlavor}
|
||||
key_name: {Ref: KeyName}
|
||||
Metadata:
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: NovaCompute0Key
|
||||
secret_access_key:
|
||||
Fn::GetAtt: [ NovaCompute0Key, SecretAccessKey ]
|
||||
stack_name: {Ref: 'AWS::StackName'}
|
||||
path: NovaCompute0Config.Metadata
|
||||
OpenStack::ImageBuilder::Elements: [ nova-compute ]
|
||||
NovaCompute0Config:
|
||||
Type: AWS::AutoScaling::LaunchConfiguration
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
NovaCompute0Deploy:
|
||||
Type: OS::Heat::StructuredDeployment
|
||||
Properties:
|
||||
InstanceType: '0'
|
||||
ImageId: '0'
|
||||
Metadata:
|
||||
completion-handle:
|
||||
Ref: NovaCompute0CompletionHandle
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: NovaCompute0Key
|
||||
secret_access_key:
|
||||
Fn::GetAtt: [ NovaCompute0Key, SecretAccessKey ]
|
||||
stack_name: {Ref: 'AWS::StackName'}
|
||||
path: NovaCompute0Config.Metadata
|
||||
nova:
|
||||
compute_driver: {Ref: NovaComputeDriver}
|
||||
compute_libvirt_type: {Ref: NovaComputeLibvirtType}
|
||||
db: {Ref: NovaDSN}
|
||||
host: {Ref: NovaApiHost}
|
||||
service-password:
|
||||
Ref: NovaPassword
|
||||
ceilometer:
|
||||
db: {Ref: CeilometerDSN}
|
||||
metering_secret: {Ref: CeilometerMeteringSecret}
|
||||
service-password: {Ref: CeilometerPassword}
|
||||
compute_agent: {Ref: CeilometerComputeAgent}
|
||||
glance:
|
||||
host: {Ref: GlanceHost}
|
||||
hosts: {Ref: StaticHosts}
|
||||
keystone:
|
||||
host: {Ref: KeystoneHost}
|
||||
neutron:
|
||||
flat-networks: {Ref: NeutronFlatNetworks}
|
||||
host: {Ref: NeutronHost}
|
||||
ovs_db: {Ref: NeutronDSN}
|
||||
ovs:
|
||||
local_ip:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- NovaCompute0
|
||||
- networks
|
||||
tenant_network_type: {Ref: NeutronNetworkType}
|
||||
network_vlan_ranges: {Ref: NeutronNetworkVLANRanges}
|
||||
bridge_mappings: {Ref: NeutronBridgeMappings}
|
||||
enable_tunneling: {Ref: NeutronEnableTunnelling}
|
||||
physical_bridge: {Ref: NeutronPhysicalBridge}
|
||||
public_interface: {Ref: NeutronPublicInterface}
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
admin-password: {Ref: AdminPassword}
|
||||
rabbit:
|
||||
host: {Ref: RabbitHost}
|
||||
username: {Ref: RabbitUserName}
|
||||
password: {Ref: RabbitPassword}
|
||||
live-update:
|
||||
host: {Ref: LiveUpdateHost}
|
||||
username: {Ref: LiveUpdateUserName}
|
||||
password: {Ref: LiveUpdatePassword}
|
||||
tenant-name: {Ref: LiveUpdateTenantName}
|
||||
base_image_id: {Ref: NovaImage}
|
||||
config: {Ref: NovaComputeConfig}
|
||||
server: {Ref: NovaCompute0}
|
||||
input_values:
|
||||
nova_compute_driver: {Ref: NovaComputeDriver}
|
||||
nova_compute_libvirt_type: {Ref: NovaComputeLibvirtType}
|
||||
nova_dsn: {Ref: NovaDSN}
|
||||
nova_api_host: {Ref: NovaApiHost}
|
||||
nova_password: {Ref: NovaPassword}
|
||||
ceilometer_dsn: {Ref: CeilometerDSN}
|
||||
ceilometer_metering_secret: {Ref: CeilometerMeteringSecret}
|
||||
ceilometer_password: {Ref: CeilometerPassword}
|
||||
ceilometer_compute_agent: {Ref: CeilometerComputeAgent}
|
||||
glance_host: {Ref: GlanceHost}
|
||||
static_hosts: {Ref: StaticHosts}
|
||||
keystone_host: {Ref: KeystoneHost}
|
||||
neutron_flat_networks: {Ref: NeutronFlatNetworks}
|
||||
neutron_host: {Ref: NeutronHost}
|
||||
neutron_dsn: {Ref: NeutronDSN}
|
||||
neutron_local_ip: {"Fn::Select": [ 0, "Fn::Select": [ ctlplane, { "Fn::GetAtt": [ NovaCompute0, networks ]}]]}
|
||||
neutron_tenant_network_type: {Ref: NeutronNetworkType}
|
||||
neutron_network_vlan_ranges: {Ref: NeutronNetworkVLANRanges}
|
||||
neutron_bridge_mappings: {Ref: NeutronBridgeMappings}
|
||||
neutron_enable_tunneling: {Ref: NeutronEnableTunnelling}
|
||||
neutron_physical_bridge: {Ref: NeutronPhysicalBridge}
|
||||
neutron_public_interface: {Ref: NeutronPublicInterface}
|
||||
neutron_password: {Ref: NeutronPassword}
|
||||
admin_password: {Ref: AdminPassword}
|
||||
rabbit_host: {Ref: RabbitHost}
|
||||
rabbit_username: {Ref: RabbitUserName}
|
||||
rabbit_password: {Ref: RabbitPassword}
|
||||
live_update_host: {Ref: LiveUpdateHost}
|
||||
live_update_username: {Ref: LiveUpdateUserName}
|
||||
live_update_password: {Ref: LiveUpdatePassword}
|
||||
live_update_tenant_name: {Ref: LiveUpdateTenantName}
|
||||
nova_image: {Ref: NovaImage}
|
||||
live_update_image_id: {Ref: LiveUpdateComputeImage}
|
||||
|
@ -181,53 +181,10 @@ Resources:
|
||||
length: 20
|
||||
salt:
|
||||
Ref: RabbitCookieSalt
|
||||
AccessPolicy:
|
||||
Properties:
|
||||
AllowedResources:
|
||||
- controller0
|
||||
- controller0Config
|
||||
Type: OS::Heat::AccessPolicy
|
||||
ComputeAccessPolicy:
|
||||
Properties:
|
||||
AllowedResources:
|
||||
- NovaCompute0
|
||||
- NovaCompute0Config
|
||||
Type: OS::Heat::AccessPolicy
|
||||
controller0Key:
|
||||
Properties:
|
||||
UserName:
|
||||
Ref: User
|
||||
Type: AWS::IAM::AccessKey
|
||||
controller0CompletionCondition:
|
||||
Type: AWS::CloudFormation::WaitCondition
|
||||
DependsOn: controller0Config
|
||||
Properties:
|
||||
Handle: {Ref: controller0CompletionHandle}
|
||||
Count: '1'
|
||||
Timeout: '1800'
|
||||
controller0CompletionHandle:
|
||||
Type: OS::Heat::UpdateWaitConditionHandle
|
||||
NovaCompute0Key:
|
||||
Type: FileInclude
|
||||
Path: nova-compute-instance.yaml
|
||||
SubKey: Resources.NovaCompute0Key
|
||||
NovaCompute0CompletionCondition:
|
||||
Type: FileInclude
|
||||
Path: nova-compute-instance.yaml
|
||||
SubKey: Resources.NovaCompute0CompletionCondition
|
||||
NovaCompute0CompletionHandle:
|
||||
Type: FileInclude
|
||||
Path: nova-compute-instance.yaml
|
||||
SubKey: Resources.NovaCompute0CompletionHandle
|
||||
ComputeUser:
|
||||
Properties:
|
||||
Policies:
|
||||
- Ref: ComputeAccessPolicy
|
||||
Type: AWS::IAM::User
|
||||
NovaCompute0Config:
|
||||
Type: FileInclude
|
||||
Path: nova-compute-instance.yaml
|
||||
SubKey: Resources.NovaCompute0Config
|
||||
SubKey: Resources.NovaCompute0Deploy
|
||||
Parameters:
|
||||
NovaApiHost: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
KeystoneHost: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
@ -293,220 +250,110 @@ Resources:
|
||||
Type: FileInclude
|
||||
Path: nova-compute-instance.yaml
|
||||
SubKey: Resources.NovaCompute0
|
||||
User:
|
||||
controllerConfig:
|
||||
Type: OS::Heat::StructuredConfig
|
||||
Properties:
|
||||
Policies:
|
||||
- Ref: AccessPolicy
|
||||
Type: AWS::IAM::User
|
||||
controller0Config:
|
||||
Type: AWS::AutoScaling::LaunchConfiguration
|
||||
Properties:
|
||||
ImageId: '0'
|
||||
InstanceType: '0'
|
||||
Metadata:
|
||||
OpenStack::Heat::Stack: {}
|
||||
OpenStack::ImageBuilder::Elements:
|
||||
- boot-stack
|
||||
- heat-cfntools
|
||||
- heat-localip
|
||||
- neutron-network-node
|
||||
admin-password:
|
||||
Ref: AdminPassword
|
||||
admin-token:
|
||||
Ref: AdminToken
|
||||
bootstack:
|
||||
public_interface_ip:
|
||||
Ref: NeutronPublicInterfaceIP
|
||||
cinder:
|
||||
db: mysql://cinder:unset@localhost/cinder
|
||||
volume_size_mb: '5000'
|
||||
service-password:
|
||||
Ref: CinderPassword
|
||||
iscsi-helper:
|
||||
Ref: CinderISCSIHelper
|
||||
completion-handle:
|
||||
Ref: controller0CompletionHandle
|
||||
controller-address:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
db-password: unset
|
||||
glance:
|
||||
backend: swift
|
||||
db: mysql://glance:unset@localhost/glance
|
||||
host:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
service-password:
|
||||
Ref: GlancePassword
|
||||
swift-store-user: service:glance
|
||||
swift-store-key:
|
||||
Ref: GlancePassword
|
||||
notifier-strategy:
|
||||
Ref: GlanceNotifierStrategy
|
||||
log-file:
|
||||
Ref: GlanceLogFile
|
||||
heat:
|
||||
admin_password:
|
||||
Ref: HeatPassword
|
||||
admin_tenant_name: service
|
||||
admin_user: heat
|
||||
auth_encryption_key: unset___________
|
||||
db: mysql://heat:unset@localhost/heat
|
||||
stack_domain_admin_password: {Ref: HeatStackDomainAdminPassword}
|
||||
watch_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
- ':8003'
|
||||
metadata_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
- ':8000'
|
||||
waitcondition_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
- ':8000/v1/waitcondition'
|
||||
hosts:
|
||||
Fn::Join:
|
||||
- ' '
|
||||
- - Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
- {Ref: CloudName}
|
||||
keystone:
|
||||
db: mysql://keystone:unset@localhost/keystone
|
||||
host:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
mysql:
|
||||
innodb_buffer_pool_size: {Ref: MysqlInnodbBufferPoolSize}
|
||||
neutron:
|
||||
flat-networks: {Ref: NeutronFlatNetworks}
|
||||
host:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
metadata_proxy_shared_secret: unset
|
||||
ovs:
|
||||
enable_tunneling: 'True'
|
||||
local_ip:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
bridge_mappings: {Ref: NeutronBridgeMappings}
|
||||
public_interface:
|
||||
Ref: NeutronPublicInterface
|
||||
public_interface_raw_device:
|
||||
Ref: NeutronPublicInterfaceRawDevice
|
||||
public_interface_route:
|
||||
Ref: NeutronPublicInterfaceDefaultRoute
|
||||
physical_bridge: br-ex
|
||||
tenant_network_type: gre
|
||||
ovs_db: mysql://neutron:unset@localhost/ovs_neutron?charset=utf8
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
ceilometer:
|
||||
db: mysql://ceilometer:unset@localhost/ceilometer
|
||||
metering_secret: {Ref: CeilometerMeteringSecret}
|
||||
service-password:
|
||||
Ref: CeilometerPassword
|
||||
nova:
|
||||
compute_driver: libvirt.LibvirtDriver
|
||||
db: mysql://nova:unset@localhost/nova
|
||||
default_floating_pool:
|
||||
ext-net
|
||||
host:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
metadata-proxy: true
|
||||
service-password:
|
||||
Ref: NovaPassword
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: controller0Key
|
||||
path: controller0Config.Metadata
|
||||
secret_access_key:
|
||||
config:
|
||||
completion-signal: {get_input: deploy_signal_id}
|
||||
admin-password:
|
||||
Ref: AdminPassword
|
||||
admin-token:
|
||||
Ref: AdminToken
|
||||
bootstack:
|
||||
public_interface_ip:
|
||||
Ref: NeutronPublicInterfaceIP
|
||||
cinder:
|
||||
db: mysql://cinder:unset@localhost/cinder
|
||||
volume_size_mb: '5000'
|
||||
service-password:
|
||||
Ref: CinderPassword
|
||||
iscsi-helper:
|
||||
Ref: CinderISCSIHelper
|
||||
controller-address:
|
||||
get_input: controller_host
|
||||
db-password: unset
|
||||
glance:
|
||||
backend: swift
|
||||
db: mysql://glance:unset@localhost/glance
|
||||
host:
|
||||
get_input: controller_host
|
||||
service-password:
|
||||
Ref: GlancePassword
|
||||
swift-store-user: service:glance
|
||||
swift-store-key:
|
||||
Ref: GlancePassword
|
||||
notifier-strategy:
|
||||
Ref: GlanceNotifierStrategy
|
||||
log-file:
|
||||
Ref: GlanceLogFile
|
||||
heat:
|
||||
admin_password:
|
||||
Ref: HeatPassword
|
||||
admin_tenant_name: service
|
||||
admin_user: heat
|
||||
auth_encryption_key: unset___________
|
||||
db: mysql://heat:unset@localhost/heat
|
||||
stack_domain_admin_password: {Ref: 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}
|
||||
hosts: {get_input: hosts}
|
||||
keystone:
|
||||
db: mysql://keystone:unset@localhost/keystone
|
||||
host:
|
||||
get_input: controller_host
|
||||
mysql:
|
||||
innodb_buffer_pool_size: {Ref: MysqlInnodbBufferPoolSize}
|
||||
neutron:
|
||||
flat-networks: {Ref: NeutronFlatNetworks}
|
||||
host:
|
||||
get_input: controller_host
|
||||
metadata_proxy_shared_secret: unset
|
||||
ovs:
|
||||
enable_tunneling: 'True'
|
||||
local_ip:
|
||||
get_input: controller_host
|
||||
bridge_mappings: {Ref: NeutronBridgeMappings}
|
||||
public_interface:
|
||||
Ref: NeutronPublicInterface
|
||||
public_interface_raw_device:
|
||||
Ref: NeutronPublicInterfaceRawDevice
|
||||
public_interface_route:
|
||||
Ref: NeutronPublicInterfaceDefaultRoute
|
||||
physical_bridge: br-ex
|
||||
tenant_network_type: gre
|
||||
ovs_db: mysql://neutron:unset@localhost/ovs_neutron?charset=utf8
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
ceilometer:
|
||||
db: mysql://ceilometer:unset@localhost/ceilometer
|
||||
metering_secret: {Ref: CeilometerMeteringSecret}
|
||||
service-password:
|
||||
Ref: CeilometerPassword
|
||||
nova:
|
||||
compute_driver: libvirt.LibvirtDriver
|
||||
db: mysql://nova:unset@localhost/nova
|
||||
default_floating_pool:
|
||||
ext-net
|
||||
host:
|
||||
get_input: controller_host
|
||||
metadata-proxy: true
|
||||
service-password:
|
||||
Ref: NovaPassword
|
||||
rabbit:
|
||||
host:
|
||||
get_input: controller_host
|
||||
username:
|
||||
Ref: RabbitUserName
|
||||
password:
|
||||
Ref: RabbitPassword
|
||||
cookie:
|
||||
Fn::GetAtt:
|
||||
- controller0Key
|
||||
- SecretAccessKey
|
||||
stack_name:
|
||||
Ref: AWS::StackName
|
||||
rabbit:
|
||||
host:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
username:
|
||||
Ref: RabbitUserName
|
||||
password:
|
||||
Ref: RabbitPassword
|
||||
cookie:
|
||||
Fn::GetAtt:
|
||||
- RabbitCookie
|
||||
- value
|
||||
ntp:
|
||||
servers:
|
||||
- {server: {Ref: NtpServer}, fudge: "stratum 0"}
|
||||
- RabbitCookie
|
||||
- value
|
||||
ntp:
|
||||
servers:
|
||||
- {server: {Ref: NtpServer}, fudge: "stratum 0"}
|
||||
controller0:
|
||||
Type: OS::Nova::Server
|
||||
Properties:
|
||||
@ -518,18 +365,53 @@ Resources:
|
||||
Ref: OvercloudControlFlavor
|
||||
key_name:
|
||||
Ref: KeyName
|
||||
Metadata:
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: controller0Key
|
||||
path: controller0Config.Metadata
|
||||
secret_access_key:
|
||||
Fn::GetAtt:
|
||||
- controller0Key
|
||||
- SecretAccessKey
|
||||
stack_name:
|
||||
Ref: AWS::StackName
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
controller0Deployment:
|
||||
Type: OS::Heat::StructuredDeployment
|
||||
Properties:
|
||||
config: {Ref: controllerConfig}
|
||||
server: {Ref: controller0}
|
||||
input_values:
|
||||
controller_host:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
heat.watch_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {"Fn::Select": [ 0, "Fn::Select": [ ctlplane, { "Fn::GetAtt": [ controller0, networks ]}]]}
|
||||
- ':8003'
|
||||
heat.metadata_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {"Fn::Select": [ 0, "Fn::Select": [ ctlplane, { "Fn::GetAtt": [ controller0, networks ]}]]}
|
||||
- ':8000'
|
||||
heat.waitcondition_server_url:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'http://'
|
||||
- {"Fn::Select": [ 0, "Fn::Select": [ ctlplane, { "Fn::GetAtt": [ controller0, networks ]}]]}
|
||||
- ':8000/v1/waitcondition'
|
||||
hosts:
|
||||
Fn::Join:
|
||||
- ' '
|
||||
- - {"Fn::Select": [ 0, "Fn::Select": [ ctlplane, { "Fn::GetAtt": [ controller0, networks ]}]]}
|
||||
- {Ref: CloudName}
|
||||
controller0SSLDeployment:
|
||||
Type: OS::Heat::StructuredDeployment
|
||||
Properties:
|
||||
config: {Ref: SSLConfig}
|
||||
server: {Ref: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
ssl_certificate: {Ref: SSLCertificate}
|
||||
ssl_key: {Ref: SSLKey}
|
||||
Outputs:
|
||||
KeystoneURL:
|
||||
Description: URL for the Overcloud Keystone service
|
||||
|
@ -11,33 +11,34 @@ Parameters:
|
||||
Type: String
|
||||
NoEcho: true
|
||||
Resources:
|
||||
controller0Config:
|
||||
Type: AWS::AutoScaling::LaunchConfiguration
|
||||
Metadata:
|
||||
stunnel:
|
||||
cert:
|
||||
Ref: SSLCertificate
|
||||
key:
|
||||
Ref: SSLKey
|
||||
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
|
||||
SSLConfig:
|
||||
Type: OS::Heat::StructuredConfig
|
||||
Properties:
|
||||
config:
|
||||
stunnel:
|
||||
cert:
|
||||
get_input: ssl_certificate
|
||||
key:
|
||||
get_input: ssl_key
|
||||
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
|
||||
|
45
swift-deploy.yaml
Normal file
45
swift-deploy.yaml
Normal file
@ -0,0 +1,45 @@
|
||||
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
|
||||
NoEcho: true
|
||||
SwiftPassword:
|
||||
Default: unset
|
||||
Description: The password for the swift service account, used by the swift proxy services.
|
||||
Type: String
|
||||
NoEcho: true
|
||||
Resources:
|
||||
controller0Swift:
|
||||
Type: OS::Heat::StructuredDeployment
|
||||
Properties:
|
||||
config: {Ref: SwiftConfig}
|
||||
server: {Ref: controller0}
|
||||
signal_transport: NO_SIGNAL
|
||||
input_values:
|
||||
swift_hash_suffix: {Ref: SwiftHashSuffix}
|
||||
swift_password: {Ref: SwiftPassword}
|
||||
swift_devices:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- - Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
- ':%PORT%/d1'
|
||||
- Fn::Join:
|
||||
- ', '
|
||||
- Merge::Map:
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- SwiftStorage0
|
||||
- networks
|
||||
- ':%PORT%/d1'
|
@ -1,52 +1,16 @@
|
||||
Description: 'Swift-common: OpenStack object storage common configurations'
|
||||
Parameters:
|
||||
SwiftHashSuffix:
|
||||
Default: unset
|
||||
Description: A random string to be used as a salt when hashing to determine mappings in the ring.
|
||||
Type: String
|
||||
NoEcho: true
|
||||
SwiftPassword:
|
||||
Default: unset
|
||||
Description: The password for the swift service account, used by the swift proxy services.
|
||||
Type: String
|
||||
NoEcho: true
|
||||
Resources:
|
||||
controller0Config:
|
||||
Type: AWS::AutoScaling::LaunchConfiguration
|
||||
Metadata:
|
||||
swift:
|
||||
devices:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- - Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
- ':%PORT%/d1'
|
||||
- Fn::Join:
|
||||
- ', '
|
||||
- Merge::Map:
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- SwiftStorage0
|
||||
- networks
|
||||
- ':%PORT%/d1'
|
||||
hash:
|
||||
Ref: SwiftHashSuffix
|
||||
part-power: 10
|
||||
replicas: 1
|
||||
service-password:
|
||||
Ref: SwiftPassword
|
||||
SwiftConfig:
|
||||
Type: OS::Heat::StructuredConfig
|
||||
Properties:
|
||||
config:
|
||||
swift:
|
||||
devices: { get_input: swift_devices }
|
||||
hash: { get_input: swift_hash_suffix }
|
||||
part-power: 10
|
||||
replicas: 1
|
||||
service-password: { get_input: swift_password }
|
||||
neutron:
|
||||
enable_tunnelling: {Ref: NeutronEnableTunnelling}
|
||||
tenant_network_type: {Ref: NeutronNetworkType}
|
||||
ovs:
|
||||
local_ip: { get_input: neutron_local_ip }
|
||||
|
@ -15,30 +15,6 @@ Parameters:
|
||||
Type: String
|
||||
Default: True
|
||||
Resources:
|
||||
SwiftStorageAccessPolicy:
|
||||
Type: OS::Heat::AccessPolicy
|
||||
Properties:
|
||||
AllowedResources:
|
||||
- SwiftStorage0
|
||||
- SwiftStorage0Config
|
||||
SwiftStorageUser:
|
||||
Type: AWS::IAM::User
|
||||
Properties:
|
||||
Policies: [ { Ref: SwiftStorageAccessPolicy } ]
|
||||
SwiftStorage0Key:
|
||||
Type: AWS::IAM::AccessKey
|
||||
Properties:
|
||||
UserName:
|
||||
Ref: SwiftStorageUser
|
||||
SwiftStorage0CompletionCondition:
|
||||
Type: AWS::CloudFormation::WaitCondition
|
||||
DependsOn: controller0Config
|
||||
Properties:
|
||||
Handle: {Ref: SwiftStorage0CompletionHandle}
|
||||
Count: '1'
|
||||
Timeout: '1800'
|
||||
SwiftStorage0CompletionHandle:
|
||||
Type: AWS::CloudFormation::WaitConditionHandle
|
||||
SwiftStorage0:
|
||||
Type: OS::Nova::Server
|
||||
Properties:
|
||||
@ -46,80 +22,33 @@ Resources:
|
||||
{Ref: SwiftStorageImage}
|
||||
flavor: {Ref: OvercloudSwiftStorageFlavor}
|
||||
key_name: {Ref: KeyName}
|
||||
Metadata:
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: SwiftStorage0Key
|
||||
secret_access_key:
|
||||
Fn::GetAtt: [ SwiftStorage0Key, SecretAccessKey ]
|
||||
stack_name: {Ref: 'AWS::StackName'}
|
||||
path: SwiftStorage0Config.Metadata
|
||||
OpenStack::ImageBuilder::Elements: [ swift ]
|
||||
SwiftStorage0Config:
|
||||
Type: AWS::AutoScaling::LaunchConfiguration
|
||||
SwiftStorage0Deploy:
|
||||
Type: OS::Heat::StructuredDeployment
|
||||
Properties:
|
||||
InstanceType: '0'
|
||||
ImageId: '0'
|
||||
Metadata:
|
||||
completion-handle:
|
||||
Ref: SwiftStorage0CompletionHandle
|
||||
os-collect-config:
|
||||
cfn:
|
||||
access_key_id:
|
||||
Ref: SwiftStorage0Key
|
||||
secret_access_key:
|
||||
Fn::GetAtt: [ SwiftStorage0Key, SecretAccessKey ]
|
||||
stack_name: {Ref: 'AWS::StackName'}
|
||||
path: SwiftStorage0Config.Metadata
|
||||
admin-password: {Ref: AdminPassword}
|
||||
neutron:
|
||||
ovs:
|
||||
local_ip:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- ctlplane
|
||||
- Fn::GetAtt:
|
||||
- SwiftStorage0
|
||||
- networks
|
||||
tenant_network_type: {Ref: NeutronNetworkType}
|
||||
enable_tunneling: {Ref: NeutronEnableTunnelling}
|
||||
service-password:
|
||||
Ref: NeutronPassword
|
||||
swift:
|
||||
devices:
|
||||
server: {Ref: SwiftStorage0}
|
||||
config: {Ref: SwiftConfig}
|
||||
input_values:
|
||||
neutron_local_ip: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [SwiftStorage0, networks]} ]} ] }
|
||||
swift_devices:
|
||||
Fn::Join:
|
||||
- ', '
|
||||
- - Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- controller0
|
||||
- networks
|
||||
- {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] }
|
||||
- ':%PORT%/d1'
|
||||
- Fn::Join:
|
||||
- ', '
|
||||
- Merge::Map:
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
Merge::Map:
|
||||
SwiftStorage0:
|
||||
Fn::Join:
|
||||
- ''
|
||||
- - 'r1z1-'
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 0
|
||||
- Fn::Select:
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- SwiftStorage0
|
||||
- networks
|
||||
- ':%PORT%/d1'
|
||||
hash:
|
||||
Ref: SwiftHashSuffix
|
||||
part-power: 10
|
||||
replicas: 1
|
||||
service-password:
|
||||
Ref: SwiftPassword
|
||||
- 'ctlplane'
|
||||
- Fn::GetAtt:
|
||||
- SwiftStorage0
|
||||
- networks
|
||||
- ':%PORT%/d1'
|
||||
|
@ -292,7 +292,11 @@ def merge(templates, master_role=None, slave_roles=None,
|
||||
errors.append('Role %s metadata key %s conflicts.' %
|
||||
(role, m))
|
||||
continue
|
||||
end_template['Resources'][role]['Metadata'][m] = mbody
|
||||
role_res = end_template['Resources'][role]
|
||||
if role_res['Type'] == 'OS::Heat::StructuredConfig':
|
||||
end_template['Resources'][role]['Properties']['config'][m] = mbody
|
||||
else:
|
||||
end_template['Resources'][role]['Metadata'][m] = mbody
|
||||
continue
|
||||
if 'Resources' not in end_template:
|
||||
end_template['Resources'] = {}
|
||||
@ -315,6 +319,8 @@ def merge(templates, master_role=None, slave_roles=None,
|
||||
include_content = resolve_params(include_content,
|
||||
replace_param,
|
||||
replace_value)
|
||||
if 'Resources' not in end_template:
|
||||
end_template['Resources'] = {}
|
||||
end_template['Resources'][r] = include_content
|
||||
else:
|
||||
if r in end_template.get('Resources', {}):
|
||||
|
Loading…
x
Reference in New Issue
Block a user