diff options
33 files changed, 1258 insertions, 216 deletions
diff --git a/block-storage.yaml b/block-storage.yaml index 16363b59..da5f9edc 100644 --- a/block-storage.yaml +++ b/block-storage.yaml @@ -22,6 +22,7 @@ Resources: {Ref: BlockStorageImage} flavor: {Ref: OvercloudBlockStorageFlavor} key_name: {Ref: KeyName} + user_data_format: SOFTWARE_CONFIG BlockStorage0Deployment: Type: OS::Heat::StructuredDeployment Properties: @@ -30,7 +31,8 @@ Resources: 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]}]]]} + neutron_local_ip: {"Fn::Select": [0, "Fn::Select": [ctlplane, {"Fn::GetAtt": [BlockStorage0 , networks]}]]} + signal_transport: NO_SIGNAL BlockStorageConfig: Type: OS::Heat::StructuredConfig Properties: diff --git a/examples/launchconfig1.yaml b/examples/launchconfig1.yaml index 9127eab9..70ea2463 100644 --- a/examples/launchconfig1.yaml +++ b/examples/launchconfig1.yaml @@ -1,3 +1,4 @@ +HeatTemplateFormatVersion: '2012-12-12' Parameters: A: Type: String diff --git a/examples/launchconfig1_hot.yaml b/examples/launchconfig1_hot.yaml new file mode 100644 index 00000000..1354f469 --- /dev/null +++ b/examples/launchconfig1_hot.yaml @@ -0,0 +1,24 @@ +heat_template_version: 2013-05-23 +parameters: + A: + type: string + default: test1 + B: + type: string + default: test2 + resource1Image: + type: string + default: resource1 +resources: + notcomputeConfigBase: + type: AWS::AutoScaling::LaunchConfiguration + metadata: + OpenStack::Role: notcomputeConfig + a: {get_param: A} + b: {get_param: B} + resource1: + type: OS::Nova::Server + properties: + flavor: test_flavor + image: {get_param: resource1Image} + key_name: test_key diff --git a/examples/launchconfig2.yaml b/examples/launchconfig2.yaml index 1681637b..3ced0cc4 100644 --- a/examples/launchconfig2.yaml +++ b/examples/launchconfig2.yaml @@ -1,3 +1,4 @@ +HeatTemplateFormatVersion: '2012-12-12' Parameters: C: Type: String diff --git a/examples/launchconfig2_hot.yaml b/examples/launchconfig2_hot.yaml new file mode 100644 index 00000000..3bd5549d --- /dev/null +++ b/examples/launchconfig2_hot.yaml @@ -0,0 +1,20 @@ +heat_template_version: 2013-05-23 +parameters: + C: + type: string + default: test3 + resource2Image: + type: string + default: resource2 +resources: + notcomputeConfigMixin: + type: AWS::AutoScaling::LaunchConfiguration + metadata: + OpenStack::Role: notcomputeConfig + c: {get_param: C} + resource2: + type: OS::Nova::Server + properties: + flavor: test_flavor + image: {get_param: resource2Image} + key_name: test_key diff --git a/examples/launchconfig_result_hot.yaml b/examples/launchconfig_result_hot.yaml new file mode 100644 index 00000000..e3019f20 --- /dev/null +++ b/examples/launchconfig_result_hot.yaml @@ -0,0 +1,43 @@ +description: examples/launchconfig1_hot.yaml,examples/launchconfig2_hot.yaml +heat_template_version: '2013-05-23' +parameters: + A: + default: test1 + type: string + B: + default: test2 + type: string + C: + default: test3 + type: string + resource1Image: + default: resource1 + type: string + resource2Image: + default: resource2 + type: string +resources: + notcomputeConfig: + metadata: + OpenStack::Role: notcomputeConfig + a: + get_param: A + b: + get_param: B + c: + get_param: C + type: AWS::AutoScaling::LaunchConfiguration + resource1: + properties: + flavor: test_flavor + image: + get_param: resource1Image + key_name: test_key + type: OS::Nova::Server + resource2: + properties: + flavor: test_flavor + image: + get_param: resource2Image + key_name: test_key + type: OS::Nova::Server diff --git a/examples/lib_hot.yaml b/examples/lib_hot.yaml new file mode 100644 index 00000000..b5af05e4 --- /dev/null +++ b/examples/lib_hot.yaml @@ -0,0 +1,13 @@ +parameters: + ImportantValue: + default: a_default + type: string + BImage: + type: string +resources: + GenericB: + type: OS::Nova::Server + properties: + image: {get_param: BImage} + metadata: + my_meta: {get_param: ImportantValue} diff --git a/examples/scale1.yaml b/examples/scale1.yaml index bbe618da..6acb6049 100644 --- a/examples/scale1.yaml +++ b/examples/scale1.yaml @@ -1,3 +1,4 @@ +HeatTemplateFormatVersion: '2012-12-12' Resources: ComputeUser: Type: AWS::IAM::User diff --git a/examples/scale1_hot.yaml b/examples/scale1_hot.yaml new file mode 100644 index 00000000..5597bbbf --- /dev/null +++ b/examples/scale1_hot.yaml @@ -0,0 +1,32 @@ +heat_template_version: 2013-05-23 +resources: + ComputeUser: + type: AWS::IAM::User + properties: + Policies: [ { get_param: ComputeAccessPolicy } ] + GlobalAccessPolicy: + type: OS::Heat::AccessPolicy + NovaCompute0Key: + type: FileInclude + Path: examples/scale2_hot.yaml + SubKey: resources.NovaCompute0Key + NovaCompute0CompletionCondition: + type: FileInclude + Path: examples/scale2_hot.yaml + SubKey: resources.NovaCompute0CompletionCondition + NovaCompute0CompletionHandle: + type: FileInclude + Path: examples/scale2_hot.yaml + SubKey: resources.NovaCompute0CompletionHandle + NovaCompute0Config: + type: FileInclude + Path: examples/scale2_hot.yaml + SubKey: resources.NovaCompute0Config + parameters: + ComputeImage: "123" + RabbitUserName: "guest" + RabbitPassword: "guest" + NovaCompute0: + type: FileInclude + Path: examples/scale2_hot.yaml + SubKey: resources.NovaCompute0 diff --git a/examples/scale2_hot.yaml b/examples/scale2_hot.yaml new file mode 100644 index 00000000..8800a6c8 --- /dev/null +++ b/examples/scale2_hot.yaml @@ -0,0 +1,69 @@ +heat_template_version: 2013-05-23 +parameters: + ComputeImage: + type: string + RabbitUserName: + type: string + RabbitPassword: + type: string + hidden: true +resources: + ComputeAccessPolicy: + type: OS::Heat::AccessPolicy + properties: + AllowedResources: [ NovaCompute0 ] + NovaCompute0Key: + type: AWS::IAM::AccessKey + properties: + UserName: + get_param: ComputeUser + NovaCompute0CompletionCondition: + type: AWS::CloudFormation::WaitCondition + depends_on: notcompute + properties: + Handle: {get_resource: NovaCompute0CompletionHandle} + Count: '1' + Timeout: '1800' + NovaCompute0CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute0: + type: OS::Nova::Server + properties: + image: + get_param: ComputeImage + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + secret_access_key: + get_attr: [ NovaCompute0Key, SecretAccessKey ] + stack_name: {get_param: 'AWS::StackName'} + path: NovaCompute0Config.Metadata + NovaCompute0Config: + type: AWS::AutoScaling::LaunchConfiguration + metadata: + completion-handle: + get_resource: NovaCompute0CompletionHandle + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + secret_access_key: + get_attr: [ NovaCompute0Key, SecretAccessKey ] + stack_name: {get_param: 'AWS::StackName'} + path: NovaCompute0Config.Metadata + neutron: + ovs: + local_ip: + Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute0 + - networks + rabbit: + username: {get_param: RabbitUserName} + password: {get_param: RabbitPassword} + diff --git a/examples/scale_map.yaml b/examples/scale_map.yaml index 7c79ad57..08bcbf7c 100644 --- a/examples/scale_map.yaml +++ b/examples/scale_map.yaml @@ -1,3 +1,4 @@ +HeatTemplateFormatVersion: '2012-12-12' Resources: ComputeUser: Type: AWS::IAM::User diff --git a/examples/scale_map2_hot.yaml b/examples/scale_map2_hot.yaml new file mode 100644 index 00000000..b2b6dfbb --- /dev/null +++ b/examples/scale_map2_hot.yaml @@ -0,0 +1,54 @@ +heat_template_version: 2013-05-23 +parameters: + AllHosts: + type: string + ComputeImage: + type: string +resources: + ComputeAccessPolicy: + type: OS::Heat::AccessPolicy + properties: + AllowedResources: [ NovaCompute0 ] + NovaCompute0Key: + type: AWS::IAM::AccessKey + properties: + UserName: + get_param: ComputeUser + NovaCompute0CompletionCondition: + type: AWS::CloudFormation::WaitCondition + depends_on: notcompute + properties: + Handle: {get_resource: NovaCompute0CompletionHandle} + Count: '1' + Timeout: '1800' + NovaCompute0CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute0: + type: OS::Nova::Server + properties: + image: + get_param: ComputeImage + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + secret_access_key: + get_attr: [ NovaCompute0Key, SecretAccessKey ] + stack_name: {get_param: 'AWS::StackName'} + path: NovaCompute0Config.Metadata + NovaCompute0Config: + type: AWS::AutoScaling::LaunchConfiguration + metadata: + completion-handle: + get_resource: NovaCompute0CompletionHandle + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + secret_access_key: + get_attr: [ NovaCompute0Key, SecretAccessKey ] + stack_name: {get_param: 'AWS::StackName'} + path: NovaCompute0Config.Metadata + hosts: + get_param: AllHosts diff --git a/examples/scale_map_hot.yaml b/examples/scale_map_hot.yaml new file mode 100644 index 00000000..282d49bb --- /dev/null +++ b/examples/scale_map_hot.yaml @@ -0,0 +1,56 @@ +heat_template_version: 2013-05-23 +resources: + ComputeUser: + type: AWS::IAM::User + properties: + Policies: [ { get_param: ComputeAccessPolicy } ] + GlobalAccessPolicy: + type: OS::Heat::AccessPolicy + NovaCompute0Key: + type: FileInclude + Path: examples/scale_map2_hot.yaml + SubKey: resources.NovaCompute0Key + NovaCompute0CompletionCondition: + type: FileInclude + Path: examples/scale_map2_hot.yaml + SubKey: resources.NovaCompute0CompletionCondition + NovaCompute0CompletionHandle: + type: FileInclude + Path: examples/scale_map2_hot.yaml + SubKey: resources.NovaCompute0CompletionHandle + NovaCompute0Config: + type: FileInclude + Path: examples/scale_map2_hot.yaml + SubKey: resources.NovaCompute0Config + parameters: + AllHosts: + list_join: + - "\n" + - Merge::Map: + NovaCompute0: + list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute0 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - list_join: + - '.' + - - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - 'local' + NovaCompute0: + type: FileInclude + Path: examples/scale_map2_hot.yaml + SubKey: resources.NovaCompute0 diff --git a/examples/scale_map_result_hot.yaml b/examples/scale_map_result_hot.yaml new file mode 100644 index 00000000..5976e54e --- /dev/null +++ b/examples/scale_map_result_hot.yaml @@ -0,0 +1,367 @@ +description: examples/scale_map_hot.yaml +heat_template_version: '2013-05-23' +resources: + ComputeUser: + properties: + Policies: + - get_param: ComputeAccessPolicy + type: AWS::IAM::User + GlobalAccessPolicy: + type: OS::Heat::AccessPolicy + NovaCompute0: + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + path: NovaCompute0Config.Metadata + secret_access_key: + get_attr: + - NovaCompute0Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + properties: + image: + get_param: ComputeImage + type: OS::Nova::Server + NovaCompute0CompletionCondition: + depends_on: notcompute + properties: + Count: '1' + Handle: + get_resource: NovaCompute0CompletionHandle + Timeout: '1800' + type: AWS::CloudFormation::WaitCondition + NovaCompute0CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute0Config: + metadata: + completion-handle: + get_resource: NovaCompute0CompletionHandle + hosts: + list_join: + - ' + + ' + - - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute0 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - local + - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute1 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute1 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute1 + - show + - local + - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute2 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute2 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute2 + - show + - local + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + path: NovaCompute0Config.Metadata + secret_access_key: + get_attr: + - NovaCompute0Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + type: AWS::AutoScaling::LaunchConfiguration + NovaCompute0Key: + properties: + UserName: + get_param: ComputeUser + type: AWS::IAM::AccessKey + NovaCompute1: + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute1Key + path: NovaCompute1Config.Metadata + secret_access_key: + get_attr: + - NovaCompute1Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + properties: + image: + get_param: ComputeImage + type: OS::Nova::Server + NovaCompute1CompletionCondition: + depends_on: notcompute + properties: + Count: '1' + Handle: + get_resource: NovaCompute1CompletionHandle + Timeout: '1800' + type: AWS::CloudFormation::WaitCondition + NovaCompute1CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute1Config: + metadata: + completion-handle: + get_resource: NovaCompute1CompletionHandle + hosts: + list_join: + - ' + + ' + - - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute0 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - local + - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute1 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute1 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute1 + - show + - local + - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute2 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute2 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute2 + - show + - local + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute1Key + path: NovaCompute1Config.Metadata + secret_access_key: + get_attr: + - NovaCompute1Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + type: AWS::AutoScaling::LaunchConfiguration + NovaCompute1Key: + properties: + UserName: + get_param: ComputeUser + type: AWS::IAM::AccessKey + NovaCompute2: + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute2Key + path: NovaCompute2Config.Metadata + secret_access_key: + get_attr: + - NovaCompute2Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + properties: + image: + get_param: ComputeImage + type: OS::Nova::Server + NovaCompute2CompletionCondition: + depends_on: notcompute + properties: + Count: '1' + Handle: + get_resource: NovaCompute2CompletionHandle + Timeout: '1800' + type: AWS::CloudFormation::WaitCondition + NovaCompute2CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute2Config: + metadata: + completion-handle: + get_resource: NovaCompute2CompletionHandle + hosts: + list_join: + - ' + + ' + - - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute0 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute0 + - show + - local + - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute1 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute1 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute1 + - show + - local + - list_join: + - ' ' + - - Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute2 + - networks + - Fn::Select: + - name + - get_attr: + - NovaCompute2 + - show + - list_join: + - . + - - Fn::Select: + - name + - get_attr: + - NovaCompute2 + - show + - local + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute2Key + path: NovaCompute2Config.Metadata + secret_access_key: + get_attr: + - NovaCompute2Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + type: AWS::AutoScaling::LaunchConfiguration + NovaCompute2Key: + properties: + UserName: + get_param: ComputeUser + type: AWS::IAM::AccessKey diff --git a/examples/scale_result_hot.yaml b/examples/scale_result_hot.yaml new file mode 100644 index 00000000..17c05147 --- /dev/null +++ b/examples/scale_result_hot.yaml @@ -0,0 +1,193 @@ +description: examples/scale1_hot.yaml +heat_template_version: '2013-05-23' +resources: + ComputeUser: + properties: + Policies: + - get_param: ComputeAccessPolicy + type: AWS::IAM::User + GlobalAccessPolicy: + type: OS::Heat::AccessPolicy + NovaCompute0: + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + path: NovaCompute0Config.Metadata + secret_access_key: + get_attr: + - NovaCompute0Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + properties: + image: + get_param: ComputeImage + type: OS::Nova::Server + NovaCompute0CompletionCondition: + depends_on: notcompute + properties: + Count: '1' + Handle: + get_resource: NovaCompute0CompletionHandle + Timeout: '1800' + type: AWS::CloudFormation::WaitCondition + NovaCompute0CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute0Config: + metadata: + completion-handle: + get_resource: NovaCompute0CompletionHandle + neutron: + ovs: + local_ip: + Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute0 + - networks + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute0Key + path: NovaCompute0Config.Metadata + secret_access_key: + get_attr: + - NovaCompute0Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + rabbit: + password: guest + username: guest + type: AWS::AutoScaling::LaunchConfiguration + NovaCompute0Key: + properties: + UserName: + get_param: ComputeUser + type: AWS::IAM::AccessKey + NovaCompute1: + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute1Key + path: NovaCompute1Config.Metadata + secret_access_key: + get_attr: + - NovaCompute1Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + properties: + image: + get_param: ComputeImage + type: OS::Nova::Server + NovaCompute1CompletionCondition: + depends_on: notcompute + properties: + Count: '1' + Handle: + get_resource: NovaCompute1CompletionHandle + Timeout: '1800' + type: AWS::CloudFormation::WaitCondition + NovaCompute1CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute1Config: + metadata: + completion-handle: + get_resource: NovaCompute1CompletionHandle + neutron: + ovs: + local_ip: + Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute1 + - networks + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute1Key + path: NovaCompute1Config.Metadata + secret_access_key: + get_attr: + - NovaCompute1Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + rabbit: + password: guest + username: guest + type: AWS::AutoScaling::LaunchConfiguration + NovaCompute1Key: + properties: + UserName: + get_param: ComputeUser + type: AWS::IAM::AccessKey + NovaCompute2: + metadata: + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute2Key + path: NovaCompute2Config.Metadata + secret_access_key: + get_attr: + - NovaCompute2Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + properties: + image: + get_param: ComputeImage + type: OS::Nova::Server + NovaCompute2CompletionCondition: + depends_on: notcompute + properties: + Count: '1' + Handle: + get_resource: NovaCompute2CompletionHandle + Timeout: '1800' + type: AWS::CloudFormation::WaitCondition + NovaCompute2CompletionHandle: + type: AWS::CloudFormation::WaitConditionHandle + NovaCompute2Config: + metadata: + completion-handle: + get_resource: NovaCompute2CompletionHandle + neutron: + ovs: + local_ip: + Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - get_attr: + - NovaCompute2 + - networks + os-collect-config: + cfn: + access_key_id: + get_resource: NovaCompute2Key + path: NovaCompute2Config.Metadata + secret_access_key: + get_attr: + - NovaCompute2Key + - SecretAccessKey + stack_name: + get_param: AWS::StackName + rabbit: + password: guest + username: guest + type: AWS::AutoScaling::LaunchConfiguration + NovaCompute2Key: + properties: + UserName: + get_param: ComputeUser + type: AWS::IAM::AccessKey diff --git a/examples/source.yaml b/examples/source.yaml index 89707a7b..88f0bde7 100644 --- a/examples/source.yaml +++ b/examples/source.yaml @@ -1,7 +1,8 @@ +HeatTemplateFormatVersion: '2012-12-12' Parameters: SourceImage: - Type: String - Default: my_image + Type: String + Default: my_image Resources: A: Type: OS::Nova::Server diff --git a/examples/source2_hot.yaml b/examples/source2_hot.yaml new file mode 100644 index 00000000..e3861a6c --- /dev/null +++ b/examples/source2_hot.yaml @@ -0,0 +1,4 @@ +__include__: + path: examples/lib_hot.yaml + params: + ImportantValue: Foo diff --git a/examples/source2_lib_result_hot.yaml b/examples/source2_lib_result_hot.yaml new file mode 100644 index 00000000..3f891e47 --- /dev/null +++ b/examples/source2_lib_result_hot.yaml @@ -0,0 +1,16 @@ +description: examples/source2_hot.yaml +heat_template_version: '2013-05-23' +parameters: + BImage: + type: string + ImportantValue: + default: a_default + type: string +resources: + GenericB: + metadata: + my_meta: Foo + properties: + image: + get_param: BImage + type: OS::Nova::Server diff --git a/examples/source_hot.yaml b/examples/source_hot.yaml new file mode 100644 index 00000000..e8dd59a3 --- /dev/null +++ b/examples/source_hot.yaml @@ -0,0 +1,16 @@ +heat_template_version: 2013-05-23 +parameters: + SourceImage: + type: string + default: my_image +resources: + A: + type: OS::Nova::Server + properties: + image: {get_param: SourceImage} + B: + type: FileInclude + Path: examples/lib_hot.yaml + SubKey: resources.GenericB + parameters: + ImportantValue: {list_join: [ '', ['one', 'two', 'three']]} diff --git a/examples/source_include_subkey.yaml b/examples/source_include_subkey.yaml index be344cd8..37591d80 100644 --- a/examples/source_include_subkey.yaml +++ b/examples/source_include_subkey.yaml @@ -1,3 +1,4 @@ +HeatTemplateFormatVersion: '2012-12-12' Parameters: Foo: Type: String diff --git a/examples/source_include_subkey_hot.yaml b/examples/source_include_subkey_hot.yaml new file mode 100644 index 00000000..b330efe6 --- /dev/null +++ b/examples/source_include_subkey_hot.yaml @@ -0,0 +1,11 @@ +heat_template_version: 2013-05-23 +parameters: + Foo: + type: string +resources: + __include__: + path: examples/lib_hot.yaml + subkey: resources + params: + BImage: + get_param: Foo diff --git a/examples/source_include_subkey_result_hot.yaml b/examples/source_include_subkey_result_hot.yaml new file mode 100644 index 00000000..f8853c23 --- /dev/null +++ b/examples/source_include_subkey_result_hot.yaml @@ -0,0 +1,14 @@ +description: examples/source_include_subkey_hot.yaml +heat_template_version: '2013-05-23' +parameters: + Foo: + type: string +resources: + GenericB: + metadata: + my_meta: + get_param: ImportantValue + properties: + image: + get_param: Foo + type: OS::Nova::Server diff --git a/examples/source_lib_result.yaml b/examples/source_lib_result.yaml index ceb8a321..5844c813 100644 --- a/examples/source_lib_result.yaml +++ b/examples/source_lib_result.yaml @@ -1,9 +1,9 @@ Description: examples/source.yaml HeatTemplateFormatVersion: '2012-12-12' Parameters: - Default: my_image - SourceImage: null - Type: String + SourceImage: + Default: my_image + Type: String Resources: A: Properties: diff --git a/examples/source_lib_result_hot.yaml b/examples/source_lib_result_hot.yaml new file mode 100644 index 00000000..4c07da0c --- /dev/null +++ b/examples/source_lib_result_hot.yaml @@ -0,0 +1,24 @@ +description: examples/source_hot.yaml +heat_template_version: '2013-05-23' +parameters: + SourceImage: + default: my_image + type: string +resources: + A: + properties: + image: + get_param: SourceImage + type: OS::Nova::Server + B: + metadata: + my_meta: + list_join: + - '' + - - one + - two + - three + properties: + image: + get_param: BImage + type: OS::Nova::Server diff --git a/nova-compute-config.yaml b/nova-compute-config.yaml index 6c6f7dc8..c4264430 100644 --- a/nova-compute-config.yaml +++ b/nova-compute-config.yaml @@ -21,6 +21,8 @@ Resources: readonly_user_password: {get_input: snmpd_readonly_user_password} glance: host: {get_input: glance_host} + port: {get_input: glance_port} + protocol: {get_input: glance_protocol} keystone: host: {get_input: keystone_host} neutron: diff --git a/nova-compute-group.yaml b/nova-compute-group.yaml deleted file mode 100644 index 6a586433..00000000 --- a/nova-compute-group.yaml +++ /dev/null @@ -1,67 +0,0 @@ -HeatTemplateFormatVersion: '2012-12-12' -Description: 'Group of Nova Computes' -Parameters: - KeyName: - Description: Name of an existing EC2 KeyPair to enable SSH access to the instances - Type: String - Default: default - InstanceType: - Description: Use this flavor - Type: String - Default: baremetal - NovaImage: - Type: String - Default: overcloud-compute - KeystoneHost: - Type: String - ServicePassword: - Description: admin_password for setting up auth in nova. - Type: String - NoEcho: true - NeutronHost: - Type: String - RabbitHost: - Type: String - RabbitUserName: - Type: String - RabbitPassword: - Type: String - NoEcho: true - NovaInterfaces: - Type: String - Default: eth0 - NovaComputeDriver: - Type: String - Default: libvirt.LibvirtDriver - NovaApiHost: - Type: String - GlanceHost: - Type: String - NovaComputeTemplate: - Type: String - Default: https://raw.github.com/openstack/tripleo-heat-templates/master/nova-compute-instance.yaml - NovaDSN: - Type: String - NeutronDSN: - Type: String -Resources: - NovaCompute0: - Type: AWS::CloudFormation::Stack - Properties: - Parameters: - NovaImage: {Ref: NovaImage} - InstanceType: {Ref: InstanceType} - KeyName: {Ref: KeyName} - KeystoneHost: {Ref: KeystoneHost} - ServicePassword: {Ref: ServicePassword} - NeutronHost: {Ref: NeutronHost} - RabbitHost: {Ref: RabbitHost} - RabbitUserName: {Ref: RabbitUserName} - RabbitPassword: {Ref: RabbitPassword} - NovaInterfaces: {Ref: NovaInterfaces} - NovaComputeDriver: {Ref: NovaComputeDriver} - NovaApiHost: {Ref: NovaApiHost} - GlanceHost: {Ref: GlanceHost} - NovaDSN: {Ref: NovaDSN} - NeutronDSN: {Ref: NeutronDSN} - TemplateURL: {Ref: NovaComputeTemplate} diff --git a/nova-compute-instance.yaml b/nova-compute-instance.yaml index baa20e29..baf781df 100644 --- a/nova-compute-instance.yaml +++ b/nova-compute-instance.yaml @@ -181,7 +181,7 @@ Resources: - network: ctlplane user_data_format: SOFTWARE_CONFIG NovaCompute0Deploy: - DependsOn: [controller0Deployment] + DependsOn: [controller0AllNodes] Type: OS::Heat::StructuredDeployment Properties: signal_transport: NO_SIGNAL @@ -225,11 +225,13 @@ Resources: live_update_image_id: {Ref: LiveUpdateComputeImage} ntp_server: {Ref: NtpServer} NovaCompute0AllNodesDeploy: + DependsOn: [NovaCompute0Passthrough] Type: OS::Heat::StructuredDeployment Properties: config: {Ref: AllNodesConfig} server: {Ref: NovaCompute0} NovaCompute0Passthrough: + DependsOn: [NovaCompute0Deploy] Type: OS::Heat::StructuredDeployment Properties: config: {Ref: NovaComputePassthrough} diff --git a/overcloud-source.yaml b/overcloud-source.yaml index 7cce21a3..b8216cd9 100644 --- a/overcloud-source.yaml +++ b/overcloud-source.yaml @@ -252,6 +252,23 @@ Parameters: Default: [] Description: Should be used for arbitrary ips. Type: Json + 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. KeystoneCACertificate: Default: '' Description: Keystone self-signed certificate authority certificate. @@ -277,13 +294,20 @@ Resources: Type: OS::Heat::RandomString Properties: length: 10 + PublicVirtualIP: + Type: OS::Neutron::Port + Properties: + name: public_virtual_ip + network: {Ref: PublicVirtualNetwork} + fixed_ips: + Ref: PublicVirtualFixedIPs RabbitCookie: Type: OS::Heat::RandomString Properties: length: 20 salt: Ref: RabbitCookieSalt - NovaCompute0Config: + NovaCompute0Deploy: Type: FileInclude Path: nova-compute-instance.yaml SubKey: Resources.NovaCompute0Deploy @@ -313,12 +337,10 @@ Resources: Parameters: AllNodesConfig: {Ref: allNodesConfig} NovaCompute0Passthrough: - Type: OS::Heat::StructuredDeployment - Properties: - config: {Ref: NovaComputePassthrough} - server: {Ref: NovaCompute0} - signal_transport: NO_SIGNAL - input_values: + Type: FileInclude + Path: nova-compute-instance.yaml + SubKey: Resources.NovaCompute0Passthrough + Parameters: passthrough_config: {Ref: ExtraConfig} NovaCompute0: Type: FileInclude @@ -360,6 +382,17 @@ Resources: Ref: CinderISCSIHelper controller-address: get_input: controller_host + corosync: + bindnetaddr: {get_input: controller_host} + mcastport: 5577 + nodes: + Merge::Map: + controller0: + ip: {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } + pacemaker: + stonith_enabled : false + recheck_interval : 5 + quorum_policy : ignore db-password: unset glance: registry: @@ -367,7 +400,7 @@ Resources: backend: swift db: mysql://glance:unset@localhost/glance host: - get_input: controller_host + get_input: controller_virtual_ip port: Ref: GlancePort protocol: @@ -392,10 +425,17 @@ Resources: 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: + caches: + memcached: + nodes: + Merge::Map: + controller0: + {"Fn::Select": [ name, {"Fn::GetAtt": [controller0, show]} ] } keystone: db: mysql://keystone:unset@localhost/keystone host: - get_input: controller_host + get_input: controller_virtual_ip ca_certificate: {Ref: KeystoneCACertificate} signing_key: {Ref: KeystoneSigningKey} signing_certificate: {Ref: KeystoneSigningCertificate} @@ -464,15 +504,44 @@ Resources: ntp: servers: - {server: {Ref: NtpServer}, fudge: "stratum 0"} + virtual_interfaces: + instances: + - vrrp_instance_name: VI_CONTROL + virtual_router_id: 51 + keepalive_interface: + Ref: ControlVirtualInterface + priority: 101 + virtual_ips: + - ip: {'Fn::Select': [ip_address, 'Fn::Select': [0, 'Fn::GetAtt': [ControlVirtualIP, fixed_ips]]]} + interface: + Ref: ControlVirtualInterface + - vrrp_instance_name: VI_PUBLIC + virtual_router_id: 52 + keepalive_interface: + Ref: PublicVirtualInterface + priority: 101 + virtual_ips: + - ip: {'Fn::Select': [ip_address, 'Fn::Select': [0, 'Fn::GetAtt': [PublicVirtualIP, fixed_ips]]]} + interface: + Ref: PublicVirtualInterface + vrrp_sync_groups: + - name: VG1 + members: + - VI_CONTROL + - VI_PUBLIC keepalived: keepalive_interface: - Ref: NeutronPublicInterface + Ref: PublicVirtualInterface priority: 101 virtual_ips: - ip: {'Fn::Select': [ip_address, 'Fn::Select': [0, 'Fn::GetAtt': [ControlVirtualIP, fixed_ips]]]} interface: Ref: ControlVirtualInterface + - + ip: {'Fn::Select': [ip_address, 'Fn::Select': [0, 'Fn::GetAtt': [PublicVirtualIP, fixed_ips]]]} + interface: + Ref: PublicVirtualInterface haproxy: nodes: Merge::Map: @@ -484,34 +553,50 @@ Resources: services: - name: keystone_admin port: 35357 + net_binds: &public_binds + - ip: {'Fn::Select': [ip_address, 'Fn::Select': [0, 'Fn::GetAtt': [ControlVirtualIP, fixed_ips]]]} + - ip: {'Fn::Select': [ip_address, 'Fn::Select': [0, 'Fn::GetAtt': [PublicVirtualIP, fixed_ips]]]} - name: keystone_public port: 5000 + net_binds: *public_binds - name: horizon port: 80 + net_binds: *public_binds - name: neutron port: 9696 + net_binds: *public_binds - name: cinder port: 8776 + net_binds: *public_binds - name: glance_api port: 9292 + net_binds: *public_binds - name: glance_registry port: 9191 + net_binds: *public_binds - name: heat_api port: 8004 + net_binds: *public_binds - name: heat_cloudwatch port: 8003 + net_binds: *public_binds - name: heat_cfn port: 8000 + net_binds: *public_binds - name: nova_ec2 port: 8773 - name: nova_osapi port: 8774 + net_binds: *public_binds - name: nova_metadata port: 8775 + net_binds: *public_binds - name: ceilometer port: 8777 + net_binds: *public_binds - name: swift_proxy_server port: 8080 + net_binds: *public_binds controllerPassthrough: Type: OS::Heat::StructuredConfig Properties: @@ -531,7 +616,8 @@ Resources: networks: - network: ctlplane user_data_format: SOFTWARE_CONFIG - controller0AllNodesConfig: + controller0AllNodes: + DependsOn: [controller0Deployment,controller0SSLDeployment,controller0Swift,controller0Passthrough] Type: OS::Heat::StructuredDeployment Properties: config: {Ref: allNodesConfig} @@ -652,6 +738,14 @@ Resources: server: {Ref: controller0} signal_transport: NO_SIGNAL input_values: + controller_host: + Fn::Select: + - 0 + - Fn::Select: + - ctlplane + - Fn::GetAtt: + - controller0 + - networks ssl_certificate: {Ref: SSLCertificate} ssl_key: {Ref: SSLKey} ssl_ca_certificate: {Ref: SSLCACertificate} diff --git a/ssl-source.yaml b/ssl-source.yaml index 38d6d7ec..e64eca51 100644 --- a/ssl-source.yaml +++ b/ssl-source.yaml @@ -31,24 +31,40 @@ Resources: - name: 'ec2' accept: 13773 connect: 8773 + connect_host: + get_input: controller_host - name: 'image' accept: 13292 connect: 9292 + connect_host: + get_input: controller_host - name: 'identity' accept: 13000 connect: 5000 + connect_host: + get_input: controller_host - name: 'network' accept: 13696 connect: 9696 + connect_host: + get_input: controller_host - name: 'compute' accept: 13774 connect: 8774 + connect_host: + get_input: controller_host - name: 'swift-proxy' accept: 13080 connect: 8080 + connect_host: + get_input: controller_host - name: 'cinder' accept: 13776 connect: 8776 + connect_host: + get_input: controller_host - name: 'ceilometer' accept: 13777 connect: 8777 + connect_host: + get_input: controller_host diff --git a/swift-deploy.yaml b/swift-deploy.yaml index 3fe8eced..e5b83de4 100644 --- a/swift-deploy.yaml +++ b/swift-deploy.yaml @@ -23,45 +23,33 @@ Resources: 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' + - Merge::Map: + controller0: + Fn::Join: + - '' + - - 'r1z1-' + - {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } + - ':%PORT%/d1' + SwiftStorage0: + Fn::Join: + - '' + - - 'r1z1-' + - Fn::Select: + - 0 + - Fn::Select: + - 'ctlplane' + - Fn::GetAtt: + - SwiftStorage0 + - networks + - ':%PORT%/d1' swift_proxy_memcache: Fn::Join: - - ', ' - - - Fn::Join: - - '' - - - {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } - - ':11211' - - Fn::Join: - - ', ' - - Merge::Map: - SwiftStorage0: - Fn::Join: - - '' - - - Fn::Select: - - 0 - - Fn::Select: - - 'ctlplane' - - Fn::GetAtt: - - SwiftStorage0 - - networks - - ':11211' - + - ',' + - Merge::Map: + controller0: + Fn::Join: + - ', ' + - - Fn::Join: + - '' + - - {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } + - ':11211' diff --git a/swift-storage-source.yaml b/swift-storage-source.yaml index d9df5728..cbbecf10 100644 --- a/swift-storage-source.yaml +++ b/swift-storage-source.yaml @@ -49,44 +49,33 @@ Resources: 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' + - Merge::Map: + controller0: + Fn::Join: + - '' + - - 'r1z1-' + - {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } + - ':%PORT%/d1' + SwiftStorage0: + Fn::Join: + - '' + - - 'r1z1-' + - Fn::Select: + - 0 + - Fn::Select: + - 'ctlplane' + - Fn::GetAtt: + - SwiftStorage0 + - networks + - ':%PORT%/d1' swift_proxy_memcache: Fn::Join: - - ', ' - - - Fn::Join: - - '' - - - {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } - - ':11211' - - Fn::Join: - - ', ' - - Merge::Map: - SwiftStorage0: - Fn::Join: - - '' - - - Fn::Select: - - 0 - - Fn::Select: - - 'ctlplane' - - Fn::GetAtt: - - SwiftStorage0 - - networks - - ':11211' + - ',' + - Merge::Map: + controller0: + Fn::Join: + - ', ' + - - Fn::Join: + - '' + - - {"Fn::Select": [ 0, {"Fn::Select": [ "ctlplane", {"Fn::GetAtt": [controller0, networks]} ]} ] } + - ':11211' diff --git a/test_merge.bash b/test_merge.bash index 19d75377..d076f50a 100755 --- a/test_merge.bash +++ b/test_merge.bash @@ -30,6 +30,12 @@ run_test "python $merge_py examples/source_include_subkey.yaml" examples/source_ 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 echo trap - EXIT exit $fail diff --git a/tripleo_heat_merge/merge.py b/tripleo_heat_merge/merge.py index 127a0e03..077bcb1c 100644 --- a/tripleo_heat_merge/merge.py +++ b/tripleo_heat_merge/merge.py @@ -4,6 +4,47 @@ 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. @@ -137,7 +178,7 @@ def translate_role(role, master_role, slave_roles): return r def resolve_params(item, param, value): - if item == {'Ref': param}: + if item in ({lang.get_param: param}, {lang.get_resource: param}): return value if isinstance(item, dict): copy_item = dict(item) @@ -219,7 +260,15 @@ def main(argv=None): 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, @@ -237,76 +286,75 @@ def merge(templates, master_role=None, slave_roles=None, scaling=None, change_image_params=None): scaling = scaling or {} errors = [] - end_template={'HeatTemplateFormatVersion': '2012-12-12', - 'Description': []} + 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['Description'].append(template.get('Description', + end_template[lang.description].append(template.get(lang.description, template_path)) - new_parameters = template.get('Parameters', {}) + new_parameters = template.get(lang.parameters, {}) for p, pbody in sorted(new_parameters.items()): - if p in end_template.get('Parameters', {}): - if pbody != end_template['Parameters'][p]: + 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 'Parameters' not in end_template: - end_template['Parameters'] = {} - end_template['Parameters'][p] = pbody + if lang.parameters not in end_template: + end_template[lang.parameters] = {} + end_template[lang.parameters][p] = pbody - new_outputs = template.get('Outputs', {}) + new_outputs = template.get(lang.outputs, {}) for o, obody in sorted(new_outputs.items()): - if o in end_template.get('Outputs', {}): - if pbody != end_template['Outputs'][p]: + 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 'Outputs' not in end_template: - end_template['Outputs'] = {} - end_template['Outputs'][o] = obody + if lang.outputs not in end_template: + end_template[lang.outputs] = {} + end_template[lang.outputs][o] = obody - new_resources = template.get('Resources', {}) + new_resources = template.get(lang.resources, {}) for r, rbody in sorted(new_resources.items()): - if rbody['Type'] in MERGABLE_TYPES: + if rbody[lang.type] in MERGABLE_TYPES: if change_image_params: - if 'image' in MERGABLE_TYPES[rbody['Type']]: - image_key = MERGABLE_TYPES[rbody['Type']]['image'] + 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['Parameters'][rbody['Properties'][image_key]['Ref']] - del end_template['Parameters'][rbody['Properties'][image_key]['Ref']] - role = rbody.get('Metadata', {}).get('OpenStack::Role', r) + 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]] + 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('Resources', {}): - new_metadata = rbody.get('Metadata', {}) + 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['Resources'][role].get('Metadata', {}): + if m in end_template[lang.resources][role].get(lang.metadata, {}): if m == 'OpenStack::ImageBuilder::Elements': - end_template['Resources'][role]['Metadata'][m].extend(mbody) + end_template[lang.resources][role][lang.metadata][m].extend(mbody) continue - if mbody != end_template['Resources'][role]['Metadata'][m]: + 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['Resources'][role] - if role_res['Type'] == 'OS::Heat::StructuredConfig': - end_template['Resources'][role]['Properties']['config'][m] = mbody + 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['Resources'][role]['Metadata'][m] = mbody + end_template[lang.resources][role][lang.metadata][m] = mbody continue - if 'Resources' not in end_template: - end_template['Resources'] = {} - end_template['Resources'][role] = rbody + 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['Type']]: + if 'image' in MERGABLE_TYPES[rbody[lang.type]]: ikey = '%sImage' % (role) - end_template['Resources'][role]['Properties'][image_key] = {'Ref': ikey} - end_template['Parameters'][ikey] = ikey_val - elif rbody['Type'] == 'FileInclude': + 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: @@ -314,23 +362,23 @@ def merge(templates, master_role=None, slave_roles=None, 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('Parameters', + for replace_param, replace_value in iter(rbody.get(lang.parameters, {}).items()): 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 + 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('Resources', {}): - if rbody != end_template['Resources'][r]: + 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 'Resources' not in end_template: - end_template['Resources'] = {} - end_template['Resources'][r] = rbody + 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) @@ -339,13 +387,13 @@ def merge(templates, master_role=None, slave_roles=None, if isinstance(item, dict): copy_item = dict(item) for k, v in sorted(copy_item.items()): - if k == 'Ref' and v == old: + if k == lang.get_resource and v == old: item[k] = new continue - if k == 'DependsOn' and v == old: + if k == lang.depends_on and v == old: item[k] = new continue - if k == 'Fn::GetAtt' and isinstance(v, list) and v[0] == old: + 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 @@ -367,7 +415,7 @@ def merge(templates, master_role=None, slave_roles=None, if errors: for e in errors: sys.stderr.write("ERROR: %s\n" % e) - end_template['Description'] = ','.join(end_template['Description']) + end_template[lang.description] = ','.join(end_template[lang.description]) return yaml.safe_dump(end_template, default_flow_style=False) if __name__ == "__main__": |