f75c430bd0aabe576eaf8f08eaa32a2e2b37235a
[apex.git] / build / opnfv-tripleo-heat-templates.patch
1 From d86b6e5cc493645e01484a1ea6cfff29cce2fa3d Mon Sep 17 00:00:00 2001
2 From: Tim Rozet <tdrozet@gmail.com>
3 Date: Tue, 12 Jan 2016 16:49:57 -0500
4 Subject: [PATCH] Adds current opnfv patch with ODL and ONOS support
5
6 ---
7  environments/onos.yaml                             |   8 +
8  environments/opendaylight-external.yaml            |  25 ++
9  environments/opendaylight.yaml                     |  25 ++
10  environments/opendaylight_l3.yaml                  |   9 +
11  environments/opendaylight_sdnvpn.yaml              |  29 ++
12  environments/opendaylight_sfc.yaml                 |  28 ++
13  network/endpoints/endpoint_map.yaml                |  31 ++
14  overcloud-resource-registry-puppet.yaml            |   3 +
15  overcloud-without-mergepy.yaml                     |  93 +++++
16  puppet/all-nodes-config.yaml                       |  17 +
17  puppet/compute.yaml                                |  35 ++
18  puppet/controller.yaml                             |  93 ++++-
19  puppet/hieradata/common.yaml                       |   1 +
20  puppet/hieradata/controller.yaml                   |   5 +-
21  puppet/manifests/overcloud_compute.pp              |  31 +-
22  puppet/manifests/overcloud_controller.pp           | 128 +++++-
23  puppet/manifests/overcloud_controller_pacemaker.pp | 456 ++++++++++++++-------
24  puppet/manifests/overcloud_opendaylight.pp         |  27 ++
25  puppet/opendaylight-puppet.yaml                    | 223 ++++++++++
26  19 files changed, 1105 insertions(+), 162 deletions(-)
27  create mode 100644 environments/onos.yaml
28  create mode 100644 environments/opendaylight-external.yaml
29  create mode 100644 environments/opendaylight.yaml
30  create mode 100644 environments/opendaylight_l3.yaml
31  create mode 100644 environments/opendaylight_sdnvpn.yaml
32  create mode 100644 environments/opendaylight_sfc.yaml
33  create mode 100644 puppet/manifests/overcloud_opendaylight.pp
34  create mode 100644 puppet/opendaylight-puppet.yaml
35
36 diff --git a/environments/onos.yaml b/environments/onos.yaml
37 new file mode 100644
38 index 0000000..510aca9
39 --- /dev/null
40 +++ b/environments/onos.yaml
41 @@ -0,0 +1,8 @@
42 +parameters:
43 +    #This a bug for odl deployment. Once bug fixed OpenDaylightCount can be remove.
44 +    OpenDaylightCount: 0
45 +    NeutronL3HA: false
46 +    ExtraConfig:
47 +      neutron_service_plugins: ['onos_router']
48 +      neutron_mechanism_drivers: ['onos_ml2']
49 +      neutron_tenant_network_type: vxlan
50 diff --git a/environments/opendaylight-external.yaml b/environments/opendaylight-external.yaml
51 new file mode 100644
52 index 0000000..411df21
53 --- /dev/null
54 +++ b/environments/opendaylight-external.yaml
55 @@ -0,0 +1,25 @@
56 +# Environment file used to enable OpenDaylight
57 +# Currently uses overcloud image that is assumed
58 +# to be virt-customized with ODL RPM already on it
59 +
60 +# These parameters customize the OpenDaylight Node
61 +# The user name and password are for the ODL service
62 +# Defaults are included here for reference
63 +#parameter_defaults:
64 +#  OpenDaylightFlavor: baremetal
65 +#  OpenDaylightHostname: opendaylight-server
66 +#  OpenDaylightImage: overcloud-full
67 +#  OpenDaylightUsername: admin
68 +#  OpenDaylightPassword: admin
69 +
70 +parameters:
71 +    # increase this if you need more ODL nodes
72 +    OpenDaylightCount: 1
73 +    NeutronL3HA: false
74 +    ExtraConfig:
75 +      neutron_mechanism_drivers: ['opendaylight']
76 +      neutron_tenant_network_type: vxlan
77 +      # Enable this if you want OpenDaylight on the contollers
78 +      # reduce OpenDaylightCount to 0 if you don't want any
79 +      # OpenDaylight only nodes
80 +      #opendaylight_install: true
81 diff --git a/environments/opendaylight.yaml b/environments/opendaylight.yaml
82 new file mode 100644
83 index 0000000..c8abf75
84 --- /dev/null
85 +++ b/environments/opendaylight.yaml
86 @@ -0,0 +1,25 @@
87 +# Environment file used to enable OpenDaylight
88 +# Currently uses overcloud image that is assumed
89 +# to be virt-customized with ODL RPM already on it
90 +
91 +# These parameters customize the OpenDaylight Node
92 +# The user name and password are for the ODL service
93 +# Defaults are included here for reference
94 +#parameter_defaults:
95 +#  OpenDaylightFlavor: baremetal
96 +#  OpenDaylightHostname: opendaylight-server
97 +#  OpenDaylightImage: overcloud-full
98 +#  OpenDaylightUsername: admin
99 +#  OpenDaylightPassword: admin
100 +
101 +parameters:
102 +    # increase this if you need more ODL nodes
103 +    # OpenDaylightCount: 1
104 +    NeutronL3HA: false
105 +    ExtraConfig:
106 +      neutron_mechanism_drivers: ['opendaylight']
107 +      neutron_tenant_network_type: vxlan
108 +      # Enable this if you want OpenDaylight on the contollers
109 +      # reduce OpenDaylightCount to 0 if you don't want any
110 +      # OpenDaylight only nodes
111 +      opendaylight_install: true
112 diff --git a/environments/opendaylight_l3.yaml b/environments/opendaylight_l3.yaml
113 new file mode 100644
114 index 0000000..05c0aff
115 --- /dev/null
116 +++ b/environments/opendaylight_l3.yaml
117 @@ -0,0 +1,9 @@
118 +parameters:
119 +    #NeutronEnableL3Agent: false
120 +    NeutronEnableForceMetadata: true
121 +    OpenDaylightEnableL3: "'yes'"
122 +    NeutronServicePlugins: "networking_odl.l3.l3_odl.OpenDaylightL3RouterPlugin"
123 +    ExtraConfig:
124 +      neutron_mechanism_drivers: ['opendaylight']
125 +      neutron_tenant_network_type: vxlan
126 +      opendaylight_install: true
127 diff --git a/environments/opendaylight_sdnvpn.yaml b/environments/opendaylight_sdnvpn.yaml
128 new file mode 100644
129 index 0000000..3a14975
130 --- /dev/null
131 +++ b/environments/opendaylight_sdnvpn.yaml
132 @@ -0,0 +1,29 @@
133 +# Environment file used to enable OpenDaylight
134 +# Currently uses overcloud image that is assumed
135 +# to be virt-customized with ODL RPM already on it
136 +
137 +# These parameters customize the OpenDaylight Node
138 +# The user name and password are for the ODL service
139 +# Defaults are included here for reference
140 +#parameter_defaults:
141 +#  OpenDaylightFlavor: baremetal
142 +#  OpenDaylightHostname: opendaylight-server
143 +#  OpenDaylightImage: overcloud-full
144 +#  OpenDaylightUsername: admin
145 +#  OpenDaylightPassword: admin
146 +
147 +parameters:
148 +    # increase this if you need more ODL nodes
149 +    # OpenDaylightCount: 1
150 +    ControllerEnableSwiftStorage: false
151 +    OpenDaylightFeatures: "odl-ovsdb-openstack,odl-vpnservice-api,odl-vpnservice-impl,odl-vpnservice-impl-rest,odl-vpnservice-impl-ui,odl-vpnservice-core"
152 +    NeutronL3HA: false
153 +    NeutronServicePlugins: "router,qos,networking_bgpvpn.neutron.services.plugin.BGPVPNPlugin"
154 +    ExtraConfig:
155 +      tripleo::ringbuilder::build_ring: False
156 +      neutron_mechanism_drivers: ['opendaylight']
157 +      neutron_tenant_network_type: vxlan
158 +      # Enable this if you want OpenDaylight on the contollers
159 +      # reduce OpenDaylightCount to 0 if you don't want any
160 +      # OpenDaylight only nodes
161 +      opendaylight_install: true
162 diff --git a/environments/opendaylight_sfc.yaml b/environments/opendaylight_sfc.yaml
163 new file mode 100644
164 index 0000000..3dd1e13
165 --- /dev/null
166 +++ b/environments/opendaylight_sfc.yaml
167 @@ -0,0 +1,28 @@
168 +# Environment file used to enable OpenDaylight
169 +# Currently uses overcloud image that is assumed
170 +# to be virt-customized with ODL RPM already on it
171 +
172 +# These parameters customize the OpenDaylight Node
173 +# The user name and password are for the ODL service
174 +# Defaults are included here for reference
175 +#parameter_defaults:
176 +#  OpenDaylightFlavor: baremetal
177 +#  OpenDaylightHostname: opendaylight-server
178 +#  OpenDaylightImage: overcloud-full
179 +#  OpenDaylightUsername: admin
180 +#  OpenDaylightPassword: admin
181 +
182 +parameters:
183 +    # increase this if you need more ODL nodes
184 +    # OpenDaylightCount: 1
185 +    ControllerEnableSwiftStorage: false
186 +    OpenDaylightFeatures: "odl-ovsdb-sfc-rest"
187 +    NeutronL3HA: false
188 +    ExtraConfig:
189 +      tripleo::ringbuilder::build_ring: False
190 +      neutron_mechanism_drivers: ['opendaylight']
191 +      neutron_tenant_network_type: vxlan
192 +      # Enable this if you want OpenDaylight on the contollers
193 +      # reduce OpenDaylightCount to 0 if you don't want any
194 +      # OpenDaylight only nodes
195 +      opendaylight_install: true
196 diff --git a/network/endpoints/endpoint_map.yaml b/network/endpoints/endpoint_map.yaml
197 index 0521401..7caa91b 100644
198 --- a/network/endpoints/endpoint_map.yaml
199 +++ b/network/endpoints/endpoint_map.yaml
200 @@ -4,6 +4,9 @@ description: >
201    A Map of OpenStack Endpoints
202  
203  parameters:
204 +  AodhApiVirtualIP:
205 +    type: string
206 +    default: ''
207    CeilometerApiVirtualIP:
208      type: string
209      default: ''
210 @@ -43,6 +46,9 @@ parameters:
211    EndpointMap:
212      type: json
213      default:
214 +      AodhAdmin: {protocol: 'http', port: '8042', host: 'IP_ADDRESS'}
215 +      AodhInternal: {protocol: 'http', port: '8042', host: 'IP_ADDRESS'}
216 +      AodhPublic: {protocol: 'http', port: '8042', host: 'IP_ADDRESS'}
217        CeilometerAdmin: {protocol: 'http', port: '8777', host: 'IP_ADDRESS'}
218        CeilometerInternal: {protocol: 'http', port: '8777', host: 'IP_ADDRESS'}
219        CeilometerPublic: {protocol: 'http', port: '8777', host: 'IP_ADDRESS'}
220 @@ -83,6 +89,28 @@ parameters:
221  
222  resources:
223  
224 +  AodhInternal:
225 +    type: OS::TripleO::Endpoint
226 +    properties:
227 +      EndpointName: AodhInternal
228 +      EndpointMap: { get_param: EndpointMap }
229 +      CloudName: {get_param: CloudName}
230 +      IP: {get_param: AodhApiVirtualIP}
231 +  AodhPublic:
232 +    type: OS::TripleO::Endpoint
233 +    properties:
234 +      EndpointName: AodhPublic
235 +      EndpointMap: { get_param: EndpointMap }
236 +      CloudName: {get_param: CloudName}
237 +      IP: {get_param: PublicVirtualIP}
238 +  AodhAdmin:
239 +    type: OS::TripleO::Endpoint
240 +    properties:
241 +      EndpointName: AodhAdmin
242 +      EndpointMap: { get_param: EndpointMap }
243 +      CloudName: {get_param: CloudName}
244 +      IP: {get_param: AodhApiVirtualIP}
245 +
246    CeilometerInternal:
247      type: OS::TripleO::Endpoint
248      properties:
249 @@ -407,6 +435,9 @@ resources:
250  outputs:
251    endpoint_map:
252      value:
253 +      AodhInternal: {get_attr: [ AodhInternal, endpoint] }
254 +      AodhPublic: {get_attr: [ AodhPublic, endpoint] }
255 +      AodhAdmin: {get_attr: [ AodhAdmin, endpoint] }
256        CeilometerInternal: {get_attr: [ CeilometerInternal, endpoint] }
257        CeilometerPublic: {get_attr: [ CeilometerPublic, endpoint] }
258        CeilometerAdmin: {get_attr: [ CeilometerAdmin, endpoint] }
259 diff --git a/overcloud-resource-registry-puppet.yaml b/overcloud-resource-registry-puppet.yaml
260 index 4cfed6b..adecc79 100644
261 --- a/overcloud-resource-registry-puppet.yaml
262 +++ b/overcloud-resource-registry-puppet.yaml
263 @@ -27,6 +27,9 @@ resource_registry:
264    # To disable, replace with firstboot/userdata_default.yaml
265    OS::TripleO::NodeAdminUserData: firstboot/userdata_heat_admin.yaml
266  
267 +  # This configures OpenDaylight to drive the network
268 +  OS::TripleO::OpenDaylightNode: puppet/opendaylight-puppet.yaml
269 +
270    # Hooks for operator extra config
271    # NodeUserData == Cloud-init additional user-data, e.g cloud-config
272    # ControllerExtraConfigPre == Controller configuration pre service deployment
273 diff --git a/overcloud-without-mergepy.yaml b/overcloud-without-mergepy.yaml
274 index a532c2f..965ca4c 100644
275 --- a/overcloud-without-mergepy.yaml
276 +++ b/overcloud-without-mergepy.yaml
277 @@ -15,6 +15,11 @@ parameters:
278      description: The password for the keystone admin account, used for monitoring, querying neutron etc.
279      type: string
280      hidden: true
281 +  AodhPassword:
282 +    default: unset
283 +    description: The password for the aodh services
284 +    type: string
285 +    hidden: true
286    CeilometerBackend:
287      default: 'mongodb'
288      description: The ceilometer backend type.
289 @@ -113,6 +118,10 @@ parameters:
290      default: ''
291      type: string
292      description: Neutron ID for ctlplane network.
293 +  NeutronEnableForceMetadata:
294 +    default: 'False'
295 +    description: If True, DHCP always provides metadata route to VM.
296 +    type: string
297    NeutronEnableTunnelling:
298      type: string
299      default: "True"
300 @@ -227,6 +236,31 @@ parameters:
301      default: false
302      description: Should MongoDb journaling be disabled
303      type: boolean
304 +  OpenDaylightPort:
305 +    default: 8081
306 +    description: Set opendaylight service port
307 +    type: number
308 +  OpenDaylightEnableL3:
309 +    description: Knob to enable/disable ODL L3
310 +    type: string
311 +    default: 'no'
312 +  OpenDaylightFeatures:
313 +    description: List of features to install with ODL
314 +    type: comma_delimited_list
315 +    default: "odl-ovsdb-openstack"
316 +  OpenDaylightInstall:
317 +    default: false
318 +    description: Whether to install OpenDaylight on the control nodes.
319 +    type: boolean
320 +  OpenDaylightUsername:
321 +    default: 'admin'
322 +    description: The username for the opendaylight server.
323 +    type: string
324 +  OpenDaylightPassword:
325 +    default: 'admin'
326 +    type: string
327 +    description: The password for the opendaylight server.
328 +    hidden: true
329    PublicVirtualFixedIPs:
330      default: []
331      description: >
332 @@ -575,6 +609,7 @@ parameters:
333      default:
334        NeutronTenantNetwork: tenant
335        CeilometerApiNetwork: internal_api
336 +      AodhApiNetwork: internal_api
337        MongoDbNetwork: internal_api
338        CinderApiNetwork: internal_api
339        CinderIscsiNetwork: storage
340 @@ -664,6 +699,18 @@ parameters:
341        structure as ExtraConfig.
342      type: json
343  
344 +# OpenDaylight specific parameters
345 +  OpenDaylightCount:
346 +    type: number
347 +    default: 0
348 +  OpenDaylightImage:
349 +    default: overcloud-full
350 +    type: string
351 +  OpenDaylightFlavor:
352 +    default: baremetal
353 +    description: Flavor for OpenDaylight node
354 +    type: string
355 +
356    # Hostname format for each role
357    # Note %index% is translated into the index of the node, e.g 0/1/2 etc
358    # and %stackname% is replaced with OS::stack_name in the template below.
359 @@ -688,6 +735,10 @@ parameters:
360      type: string
361      description: Format for CephStorage node hostnames
362      default: '%stackname%-cephstorage-%index%'
363 +  OpenDaylightHostnameFormat:
364 +    type: string
365 +    description: Format for OpenDaylight node hostnames
366 +    default: '%stackname%-opendaylight-%index%'
367  
368    # Identifiers to trigger tasks on nodes
369    UpdateIdentifier:
370 @@ -758,6 +809,7 @@ resources:
371      properties:
372        CloudName: {get_param: CloudName}
373        CeilometerApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
374 +      AodhApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, AodhApiNetwork]}]}
375        CinderApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CinderApiNetwork]}]}
376        GlanceApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
377        GlanceRegistryVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceRegistryNetwork]}]}
378 @@ -770,6 +822,29 @@ resources:
379        SwiftProxyVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}
380        PublicVirtualIP: {get_attr: [VipMap, net_ip_map, external]}
381  
382 +  OpenDaylightNode:
383 +    type: OS::Heat::ResourceGroup
384 +    depends_on: Networks
385 +    properties:
386 +      count: {get_param: OpenDaylightCount}
387 +      removal_policies: {get_param: ComputeRemovalPolicies}
388 +      resource_def:
389 +        type: OS::TripleO::OpenDaylightNode
390 +        properties:
391 +          UpdateIdentifier: {get_param: UpdateIdentifier}
392 +          OpenDaylightFlavor: {get_param: OpenDaylightFlavor}
393 +          OpenDaylightImage: {get_param: OpenDaylightImage}
394 +          OpenDaylightPort: {get_param: OpenDaylightPort}
395 +          OpenDaylightUsername: {get_param: OpenDaylightUsername}
396 +          OpenDaylightFeatures: {get_param: OpenDaylightFeatures}
397 +          OpenDaylightPassword: {get_param: OpenDaylightPassword}
398 +          OpenDaylightEnableL3: {get_param: OpenDaylightEnableL3}
399 +          OpenDaylightHostname:
400 +            str_replace:
401 +              template: {get_param: OpenDaylightHostnameFormat}
402 +              params:
403 +                '%stackname%': {get_param: 'OS::stack_name'}
404 +
405    Controller:
406      type: OS::Heat::ResourceGroup
407      depends_on: Networks
408 @@ -781,6 +856,7 @@ resources:
409          properties:
410            AdminPassword: {get_param: AdminPassword}
411            AdminToken: {get_param: AdminToken}
412 +          AodhPassword: {get_param: AodhPassword}
413            CeilometerBackend: {get_param: CeilometerBackend}
414            CeilometerMeteringSecret: {get_param: CeilometerMeteringSecret}
415            CeilometerPassword: {get_param: CeilometerPassword}
416 @@ -832,6 +908,7 @@ resources:
417            NeutronBridgeMappings: {get_param: NeutronBridgeMappings}
418            NeutronExternalNetworkBridge: {get_param: NeutronExternalNetworkBridge}
419            NeutronEnableTunnelling: {get_param: NeutronEnableTunnelling}
420 +          NeutronEnableForceMetadata: {get_param: NeutronEnableForceMetadata}
421            NeutronNetworkVLANRanges: {get_param: NeutronNetworkVLANRanges}
422            NeutronPublicInterface: {get_param: NeutronPublicInterface}
423            NeutronPublicInterfaceDefaultRoute: {get_param: NeutronPublicInterfaceDefaultRoute}
424 @@ -853,6 +930,12 @@ resources:
425            NovaPassword: {get_param: NovaPassword}
426            NtpServer: {get_param: NtpServer}
427            MongoDbNoJournal: {get_param: MongoDbNoJournal}
428 +          OpenDaylightPort: {get_param: OpenDaylightPort}
429 +          OpenDaylightInstall: {get_param: OpenDaylightInstall}
430 +          OpenDaylightUsername: {get_param: OpenDaylightUsername}
431 +          OpenDaylightFeatures: {get_param: OpenDaylightFeatures}
432 +          OpenDaylightPassword: {get_param: OpenDaylightPassword}
433 +          OpenDaylightEnableL3: {get_param: OpenDaylightEnableL3}
434            PcsdPassword: {get_resource: PcsdPassword}
435            PublicVirtualInterface: {get_param: PublicVirtualInterface}
436            RabbitPassword: {get_param: RabbitPassword}
437 @@ -878,6 +961,7 @@ resources:
438            ServiceNetMap: {get_param: ServiceNetMap}
439            EndpointMap: {get_attr: [EndpointMap, endpoint_map]}
440            CeilometerApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
441 +          AodhApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, AodhApiNetwork]}]}
442            CinderApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CinderApiNetwork]}]}
443            HeatApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
444            GlanceApiVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
445 @@ -948,6 +1032,9 @@ resources:
446            NovaPublicIP: {get_attr: [PublicVirtualIP, ip_address]}
447            NovaPassword: {get_param: NovaPassword}
448            NtpServer: {get_param: NtpServer}
449 +          OpenDaylightPort: {get_param: OpenDaylightPort}
450 +          OpenDaylightUsername: {get_param: OpenDaylightUsername}
451 +          OpenDaylightPassword: {get_param: OpenDaylightPassword}
452            RabbitHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]}
453            RabbitPassword: {get_param: RabbitPassword}
454            RabbitUserName: {get_param: RabbitUserName}
455 @@ -1068,6 +1155,7 @@ resources:
456        compute_hosts: {get_attr: [Compute, hosts_entry]}
457        controller_hosts: {get_attr: [Controller, hosts_entry]}
458        controller_ips: {get_attr: [Controller, ip_address]}
459 +      opendaylight_ip: {get_attr: [OpenDaylightNode, ip_address]}
460        block_storage_hosts: {get_attr: [BlockStorage, hosts_entry]}
461        object_storage_hosts: {get_attr: [ObjectStorage, hosts_entry]}
462        ceph_storage_hosts: {get_attr: [CephStorage, hosts_entry]}
463 @@ -1081,6 +1169,7 @@ resources:
464        heat_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
465        swift_proxy_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}
466        ceilometer_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
467 +      aodh_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, AodhApiNetwork]}]}
468        nova_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
469        nova_metadata_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, NovaMetadataNetwork]}]}
470        glance_api_node_ips: {get_attr: [ControllerIpListMap, net_ip_map, {get_param: [ServiceNetMap, GlanceApiNetwork]}]}
471 @@ -1189,6 +1278,7 @@ resources:
472          nova_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
473          nova_metadata_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, NovaMetadataNetwork]}]}
474          ceilometer_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
475 +        aodh_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, AodhApiNetwork]}]}
476          heat_api_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HeatApiNetwork]}]}
477          horizon_vip: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, HorizonNetwork]}]}
478          redis_vip: {get_attr: [RedisVirtualIP, ip_address]}
479 @@ -1434,6 +1524,9 @@ outputs:
480    PublicVip:
481      description: Controller VIP for public API endpoints
482      value: {get_attr: [PublicVirtualIP, ip_address]}
483 +  AodhInternalVip:
484 +    description: VIP for Aodh API internal endpoint
485 +    value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, AodhApiNetwork]}]}
486    CeilometerInternalVip:
487      description: VIP for Ceilometer API internal endpoint
488      value: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
489 diff --git a/puppet/all-nodes-config.yaml b/puppet/all-nodes-config.yaml
490 index 2bc519b..d649ba0 100644
491 --- a/puppet/all-nodes-config.yaml
492 +++ b/puppet/all-nodes-config.yaml
493 @@ -8,6 +8,8 @@ parameters:
494      type: comma_delimited_list
495    controller_ips:
496      type: comma_delimited_list
497 +  opendaylight_ip:
498 +    type: comma_delimited_list
499    block_storage_hosts:
500      type: comma_delimited_list
501    object_storage_hosts:
502 @@ -34,6 +36,8 @@ parameters:
503      type: comma_delimited_list
504    ceilometer_api_node_ips:
505      type: comma_delimited_list
506 +  aodh_api_node_ips:
507 +    type: comma_delimited_list
508    nova_api_node_ips:
509      type: comma_delimited_list
510    nova_metadata_node_ips:
511 @@ -82,6 +86,10 @@ resources:
512                raw_data: {get_file: hieradata/RedHat.yaml}
513              all_nodes:
514                mapped_data:
515 +                opendaylight_controller_ip:
516 +                  list_join:
517 +                  - ','
518 +                  - {get_param: opendaylight_ip}
519                  controller_node_ips:
520                    list_join:
521                    - ','
522 @@ -166,6 +174,14 @@ resources:
523                          list_join:
524                          - "','"
525                          - {get_param: ceilometer_api_node_ips}
526 +                aodh_api_node_ips:
527 +                  str_replace:
528 +                    template: "['SERVERS_LIST']"
529 +                    params:
530 +                      SERVERS_LIST:
531 +                        list_join:
532 +                        - "','"
533 +                        - {get_param: aodh_api_node_ips}
534                  nova_api_node_ips:
535                    str_replace:
536                      template: "['SERVERS_LIST']"
537 @@ -239,6 +255,7 @@ resources:
538                  neutron::rabbit_hosts: *rabbit_nodes_array
539                  nova::rabbit_hosts: *rabbit_nodes_array
540                  keystone::rabbit_hosts: *rabbit_nodes_array
541 +                aodh::rabbit_hosts: *rabbit_nodes_array
542  
543  outputs:
544    config_id:
545 diff --git a/puppet/compute.yaml b/puppet/compute.yaml
546 index 70c7403..13fd4f6 100644
547 --- a/puppet/compute.yaml
548 +++ b/puppet/compute.yaml
549 @@ -213,6 +213,23 @@ parameters:
550    NtpServer:
551      type: string
552      default: ''
553 +  OpenDaylightPort:
554 +    default: 8081
555 +    description: Set opendaylight service port
556 +    type: number
557 +  OpenDaylightUsername:
558 +    default: 'admin'
559 +    description: The username for the opendaylight server.
560 +    type: string
561 +  OpenDaylightPassword:
562 +    default: 'admin'
563 +    type: string
564 +    description: The password for the opendaylight server.
565 +    hidden: true
566 +  ONOSPort:
567 +    default: 8181
568 +    description: Set onos service port
569 +    type: number
570    RabbitHost:
571      type: string
572      default: ''  # Has to be here because of the ignored empty value bug
573 @@ -320,6 +337,11 @@ resources:
574      properties:
575        ControlPlaneIP: {get_attr: [NovaCompute, networks, ctlplane, 0]}
576  
577 +  ExternalPort:
578 +    type: OS::TripleO::Controller::Ports::ExternalPort
579 +    properties:
580 +      ControlPlaneIP: {get_attr: [NovaCompute, networks, ctlplane, 0]}
581 +
582    NetIpMap:
583      type: OS::TripleO::Network::Ports::NetIpMap
584      properties:
585 @@ -327,6 +349,7 @@ resources:
586        InternalApiIp: {get_attr: [InternalApiPort, ip_address]}
587        StorageIp: {get_attr: [StoragePort, ip_address]}
588        TenantIp: {get_attr: [TenantPort, ip_address]}
589 +      ExternalIp: {get_attr: [ExternalPort, ip_address]}
590  
591    NetworkConfig:
592      type: OS::TripleO::Compute::Net::SoftwareConfig
593 @@ -335,6 +358,7 @@ resources:
594        InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]}
595        StorageIpSubnet: {get_attr: [StoragePort, ip_subnet]}
596        TenantIpSubnet: {get_attr: [TenantPort, ip_subnet]}
597 +      ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]}
598  
599    NetworkDeployment:
600      type: OS::TripleO::SoftwareDeployment
601 @@ -406,6 +430,10 @@ resources:
602                  neutron::rabbit_user: {get_input: rabbit_user}
603                  neutron::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
604                  neutron::rabbit_port: {get_input: rabbit_client_port}
605 +                opendaylight_port: {get_input: opendaylight_port}
606 +                opendaylight_username: {get_input: opendaylight_username}
607 +                opendaylight_password: {get_input: opendaylight_password}
608 +                onos_port: {get_input: onos_port}
609                  neutron_flat_networks: {get_input: neutron_flat_networks}
610                  neutron_host: {get_input: neutron_host}
611                  neutron::agents::ml2::ovs::local_ip: {get_input: neutron_local_ip}
612 @@ -459,6 +487,10 @@ resources:
613          snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
614          snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
615          glance_api_servers: {get_param: [EndpointMap, GlanceInternal, uri]}
616 +        opendaylight_port: {get_param: OpenDaylightPort}
617 +        opendaylight_username: {get_param: OpenDaylightUsername}
618 +        opendaylight_password: {get_param: OpenDaylightPassword}
619 +        onos_port: {get_param: ONOSPort}
620          neutron_flat_networks: {get_param: NeutronFlatNetworks}
621          neutron_host: {get_param: NeutronHost}
622          neutron_local_ip: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronTenantNetwork]}]}
623 @@ -570,6 +602,9 @@ outputs:
624    tenant_ip_address:
625      description: IP address of the server in the tenant network
626      value: {get_attr: [TenantPort, ip_address]}
627 +  external_ip_address:
628 +    description: IP address of the server in the external network
629 +    value: {get_attr: [ExternalPort, ip_address]}
630    hostname:
631      description: Hostname of the server
632      value: {get_attr: [NovaCompute, name]}
633 diff --git a/puppet/controller.yaml b/puppet/controller.yaml
634 index ea0b3af..bd82e93 100644
635 --- a/puppet/controller.yaml
636 +++ b/puppet/controller.yaml
637 @@ -14,6 +14,14 @@ parameters:
638      description: The keystone auth secret and db password.
639      type: string
640      hidden: true
641 +  AodhApiVirtualIP:
642 +    type: string
643 +    default: ''
644 +  AodhPassword:
645 +    default: unset
646 +    description: The password for the aodh services.
647 +    type: string
648 +    hidden: true
649    CeilometerApiVirtualIP:
650      type: string
651      default: ''
652 @@ -357,6 +365,10 @@ parameters:
653      default: 'True'
654      description: Allow automatic l3-agent failover
655      type: string
656 +  NeutronEnableForceMetadata:
657 +    default: 'False'
658 +    description: If True, DHCP always provides metadata route to VM.
659 +    type: string
660    NeutronEnableTunnelling:
661      type: string
662      default: "True"
663 @@ -443,6 +455,35 @@ parameters:
664    NtpServer:
665      type: string
666      default: ''
667 +  OpenDaylightPort:
668 +    default: 8081
669 +    description: Set opendaylight service port
670 +    type: number
671 +  OpenDaylightInstall:
672 +    default: false
673 +    description: Whether to install OpenDaylight on the control nodes.
674 +    type: boolean
675 +  OpenDaylightUsername:
676 +    default: 'admin'
677 +    description: The username for the opendaylight server.
678 +    type: string
679 +  OpenDaylightPassword:
680 +    default: 'admin'
681 +    type: string
682 +    description: The password for the opendaylight server.
683 +    hidden: true
684 +  OpenDaylightEnableL3:
685 +    description: Knob to enable/disable ODL L3
686 +    type: string
687 +    default: 'no'
688 +  OpenDaylightFeatures:
689 +    description: List of features to install with ODL
690 +    type: comma_delimited_list
691 +    default: "odl-ovsdb-openstack"
692 +  ONOSPort:
693 +    default: 8181
694 +    description: Set onos service port
695 +    type: number
696    PcsdPassword:
697      type: string
698      description: The password for the 'pcsd' user.
699 @@ -696,6 +737,7 @@ resources:
700        input_values:
701          bootstack_nodeid: {get_attr: [Controller, name]}
702          neutron_enable_tunneling: {get_param: NeutronEnableTunnelling}
703 +        neutron_enable_force_metadata: {get_param: NeutronEnableForceMetadata}
704          haproxy_log_address: {get_param: HAProxySyslogAddress}
705          heat.watch_server_url:
706            list_join:
707 @@ -774,6 +816,7 @@ resources:
708                - {get_param: MysqlVirtualIP}
709                - '/heat'
710          keystone_ca_certificate: {get_param: KeystoneCACertificate}
711 +        keystone_admin_vip: {get_param: KeystoneAdminApiVirtualIP}
712          keystone_signing_key: {get_param: KeystoneSigningKey}
713          keystone_signing_certificate: {get_param: KeystoneSigningCertificate}
714          keystone_ssl_certificate: {get_param: KeystoneSSLCertificate}
715 @@ -805,6 +848,13 @@ resources:
716              template: tripleo-CLUSTER
717              params:
718                CLUSTER: {get_param: MysqlClusterUniquePart}
719 +        opendaylight_port: {get_param: OpenDaylightPort}
720 +        opendaylight_install: {get_param: OpenDaylightInstall}
721 +        opendaylight_username: {get_param: OpenDaylightUsername}
722 +        opendaylight_password: {get_param: OpenDaylightPassword}
723 +        opendaylight_enable_l3: {get_param: OpenDaylightEnableL3}
724 +        opendaylight_features: {get_param: OpenDaylightFeatures}
725 +        onos_port: {get_param: ONOSPort}
726          neutron_flat_networks: {get_param: NeutronFlatNetworks}
727          neutron_metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret}
728          neutron_agent_mode: {get_param: NeutronAgentMode}
729 @@ -879,6 +929,7 @@ resources:
730          ceilometer_backend: {get_param: CeilometerBackend}
731          ceilometer_metering_secret: {get_param: CeilometerMeteringSecret}
732          ceilometer_password: {get_param: CeilometerPassword}
733 +        aodh_password: {get_param: AodhPassword}
734          ceilometer_coordination_url:
735            list_join:
736              - ''
737 @@ -891,6 +942,12 @@ resources:
738              - - 'mysql://ceilometer:unset@'
739                - {get_param: MysqlVirtualIP}
740                - '/ceilometer'
741 +        ceilometer_public_url: {get_param: [EndpointMap, CeilometerPublic, uri]}
742 +        ceilometer_internal_url: {get_param: [EndpointMap, CeilometerInternal, uri]}
743 +        ceilometer_admin_url: {get_param: [EndpointMap, CeilometerAdmin, uri]}
744 +        aodh_public_url: {get_param: [EndpointMap, AodhPublic, uri]}
745 +        aodh_internal_url: {get_param: [EndpointMap, AodhInternal, uri]}
746 +        aodh_admin_url: {get_param: [EndpointMap, AodhAdmin, uri]}
747          snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
748          snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
749          nova_password: {get_param: NovaPassword}
750 @@ -948,6 +1005,7 @@ resources:
751          neutron_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronApiNetwork]}]}
752          neutron_local_ip: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronTenantNetwork]}]}
753          ceilometer_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, CeilometerApiNetwork]}]}
754 +        aodh_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, AodhApiNetwork]}]}
755          nova_api_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NovaApiNetwork]}]}
756          nova_metadata_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NovaMetadataNetwork]}]}
757          horizon_network: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, HorizonNetwork]}]}
758 @@ -1041,7 +1099,7 @@ resources:
759                  cinder_iscsi_ip_address: {get_input: cinder_iscsi_network}
760                  cinder::database_connection: {get_input: cinder_dsn}
761                  cinder::api::keystone_password: {get_input: cinder_password}
762 -                cinder::api::auth_uri: {get_input: keystone_auth_uri}
763 +                cinder::api::keystone_auth_host: {get_input: keystone_admin_vip}
764                  cinder::api::identity_uri: {get_input: keystone_identity_uri}
765                  cinder::api::bind_host: {get_input: cinder_api_network}
766                  cinder::rabbit_userid: {get_input: rabbit_username}
767 @@ -1136,6 +1194,17 @@ resources:
768                  mysql_bind_host: {get_input: mysql_network}
769                  mysql_virtual_ip: {get_input: mysql_virtual_ip}
770  
771 +                # OpenDaylight
772 +                opendaylight_port: {get_input: opendaylight_port}
773 +                opendaylight_install: {get_input: opendaylight_install}
774 +                opendaylight_username: {get_input: opendaylight_username}
775 +                opendaylight_password: {get_input: opendaylight_password}
776 +                opendaylight_enable_l3: {get_input: opendaylight_enable_l3}
777 +                opendaylight_features: {get_input: opendaylight_features}
778 +
779 +                # ONOS
780 +                onos_port: {get_input: onos_port}
781 +
782                  # Neutron
783                  neutron::bind_host: {get_input: neutron_api_network}
784                  neutron::rabbit_password: {get_input: rabbit_password}
785 @@ -1152,6 +1221,7 @@ resources:
786                  neutron_flat_networks: {get_input: neutron_flat_networks}
787                  neutron::agents::metadata::shared_secret: {get_input: neutron_metadata_proxy_shared_secret}
788                  neutron::agents::metadata::metadata_ip: {get_input: neutron_api_network}
789 +                neutron::agents::dhcp::enable_force_metadata: {get_input: neutron_enable_force_metadata}
790                  neutron_agent_mode: {get_input: neutron_agent_mode}
791                  neutron_router_distributed: {get_input: neutron_router_distributed}
792                  neutron::core_plugin: {get_input: neutron_core_plugin}
793 @@ -1198,6 +1268,27 @@ resources:
794                  snmpd_readonly_user_name: {get_input: snmpd_readonly_user_name}
795                  snmpd_readonly_user_password: {get_input: snmpd_readonly_user_password}
796  
797 +                # Aodh
798 +                aodh::rabbit_userid: {get_input: rabbit_username}
799 +                aodh::rabbit_password: {get_input: rabbit_password}
800 +                aodh::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
801 +                aodh::rabbit_port: {get_input: rabbit_client_port}
802 +                aodh::debug: {get_input: debug}
803 +                aodh::wsgi::apache::ssl: false
804 +                aodh::api::service_name: 'httpd'
805 +                aodh::api::host: {get_input: aodh_api_network}
806 +                aodh::api::keystone_password: {get_input: aodh_password}
807 +                aodh::api::keystone_auth_uri: {get_input: keystone_auth_uri}
808 +                aodh::api::keystone_identity_uri: {get_input: keystone_identity_uri}
809 +                aodh::auth::auth_password: {get_input: aodh_password}
810 +                aodh::keystone::auth::public_url: {get_input: aodh_public_url }
811 +                aodh::keystone::auth::internal_url: {get_input: aodh_internal_url }
812 +                aodh::keystone::auth::admin_url: {get_input: aodh_admin_url }
813 +                aodh::keystone::auth::password: {get_input: aodh_password }
814 +                aodh::keystone::auth::region: {get_input: keystone_region}
815 +                # for a migration path from ceilometer-alarm to aodh, we use the same database & coordination
816 +                aodh::evaluator::coordination_url: {get_input: ceilometer_coordination_url}
817 +
818                  # Nova
819                  nova::rabbit_userid: {get_input: rabbit_username}
820                  nova::rabbit_password: {get_input: rabbit_password}
821 diff --git a/puppet/hieradata/common.yaml b/puppet/hieradata/common.yaml
822 index 030f661..5840016 100644
823 --- a/puppet/hieradata/common.yaml
824 +++ b/puppet/hieradata/common.yaml
825 @@ -6,6 +6,7 @@ ceilometer::agent::auth::auth_region: 'regionOne'
826  # FIXME: Might be better to use 'service' tenant here but this requires
827  # changes in the tripleo-incubator keystone role setup
828  ceilometer::agent::auth::auth_tenant_name: 'admin'
829 +aodh::auth::auth_tenant_name: 'admin'
830  
831  nova::network::neutron::neutron_admin_tenant_name: 'service'
832  nova::network::neutron::neutron_admin_username: 'neutron'
833 diff --git a/puppet/hieradata/controller.yaml b/puppet/hieradata/controller.yaml
834 index 4b7fd81..7dbc2e9 100644
835 --- a/puppet/hieradata/controller.yaml
836 +++ b/puppet/hieradata/controller.yaml
837 @@ -32,6 +32,7 @@ redis::sentinel::notification_script: '/usr/local/bin/redis-notifications.sh'
838  # service tenant
839  nova::api::admin_tenant_name: 'service'
840  glance::api::keystone_tenant: 'service'
841 +aodh::api::keystone_tenant: 'service'
842  glance::registry::keystone_tenant: 'service'
843  neutron::server::auth_tenant: 'service'
844  neutron::agents::metadata::auth_tenant: 'service'
845 @@ -39,6 +40,7 @@ cinder::api::keystone_tenant: 'service'
846  swift::proxy::authtoken::admin_tenant_name: 'service'
847  ceilometer::api::keystone_tenant: 'service'
848  heat::keystone_tenant: 'service'
849 +aodh::keystone::auth::tenant: 'service'
850  
851  # keystone
852  keystone::cron::token_flush::maxdelay: 3600
853 @@ -72,7 +74,7 @@ neutron::agents::dhcp::dnsmasq_config_file: /etc/neutron/dnsmasq-neutron.conf
854  
855  # nova
856  nova::notify_on_state_change: 'vm_and_task_state'
857 -nova::api::default_floating_pool: 'public'
858 +nova::api::default_floating_pool: 'external'
859  nova::api::osapi_v3: true
860  nova::scheduler::filter::ram_allocation_ratio: '1.0'
861  
862 @@ -115,6 +117,7 @@ tripleo::loadbalancer::mysql: true
863  tripleo::loadbalancer::redis: true
864  tripleo::loadbalancer::swift_proxy_server: true
865  tripleo::loadbalancer::ceilometer: true
866 +tripleo::loadbalancer::aodh: true
867  tripleo::loadbalancer::heat_api: true
868  tripleo::loadbalancer::heat_cloudwatch: true
869  tripleo::loadbalancer::heat_cfn: true
870 diff --git a/puppet/manifests/overcloud_compute.pp b/puppet/manifests/overcloud_compute.pp
871 index cd41cc7..110ca1d 100644
872 --- a/puppet/manifests/overcloud_compute.pp
873 +++ b/puppet/manifests/overcloud_compute.pp
874 @@ -75,9 +75,34 @@ class { '::neutron::plugins::ml2':
875    tenant_network_types => [hiera('neutron_tenant_network_type')],
876  }
877  
878 -class { '::neutron::agents::ml2::ovs':
879 -  bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
880 -  tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
881 +if 'opendaylight' in hiera('neutron_mechanism_drivers') {
882 +
883 +  if str2bool(hiera('opendaylight_install', 'false')) {
884 +    $controller_ips = split(hiera('controller_node_ips'), ',')
885 +    $opendaylight_controller_ip = $controller_ips[0]
886 +  } else {
887 +    $opendaylight_controller_ip = hiera('opendaylight_controller_ip')
888 +  }
889 +
890 +  class { 'neutron::plugins::ovs::opendaylight':
891 +      odl_controller_ip => $opendaylight_controller_ip,
892 +      tunnel_ip         => hiera('neutron::agents::ml2::ovs::local_ip'),
893 +      odl_port          => hiera('opendaylight_port'),
894 +      odl_username      => hiera('opendaylight_username'),
895 +      odl_password      => hiera('opendaylight_password'),
896 +  }
897 +
898 +} elsif 'onos_ml2' in hiera('neutron_mechanism_drivers') {
899 +  $controller_ips = split(hiera('controller_node_ips'), ',')
900 +  class {'onos::ovs_computer':
901 +    manager_ip => $controller_ips[0]
902 +  }
903 +
904 +} else {
905 +  class { 'neutron::agents::ml2::ovs':
906 +    bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
907 +    tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
908 +  }
909  }
910  
911  if 'cisco_n1kv' in hiera('neutron_mechanism_drivers') {
912 diff --git a/puppet/manifests/overcloud_controller.pp b/puppet/manifests/overcloud_controller.pp
913 index 1f6c2be..1095758 100644
914 --- a/puppet/manifests/overcloud_controller.pp
915 +++ b/puppet/manifests/overcloud_controller.pp
916 @@ -30,6 +30,21 @@ if hiera('step') >= 1 {
917  
918  if hiera('step') >= 2 {
919  
920 +  if str2bool(hiera('opendaylight_install', 'false')) {
921 +    class {"opendaylight":
922 +      extra_features => any2array(hiera('opendaylight_features', 'odl-ovsdb-openstack')),
923 +      odl_rest_port  => hiera('opendaylight_port'),
924 +      enable_l3      => hiera('opendaylight_enable_l3', 'no'),
925 +    }
926 +  }
927 +  
928 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
929 +    # install onos and config ovs
930 +    class {"onos":
931 +      controllers_ip => $controller_node_ips
932 +    }
933 +  }
934 +
935    if count(hiera('ntp::servers')) > 0 {
936      include ::ntp
937    }
938 @@ -158,6 +173,9 @@ if hiera('step') >= 2 {
939  
940  if hiera('step') >= 3 {
941  
942 +  # Apache
943 +  include ::apache
944 +
945    include ::keystone
946  
947    #TODO: need a cleanup-keystone-tokens.sh solution here
948 @@ -223,9 +241,7 @@ if hiera('step') >= 3 {
949    include ::nova::scheduler
950    include ::nova::scheduler::filter
951  
952 -  include ::neutron
953    include ::neutron::server
954 -  include ::neutron::agents::l3
955    include ::neutron::agents::dhcp
956    include ::neutron::agents::metadata
957  
958 @@ -237,15 +253,101 @@ if hiera('step') >= 3 {
959      require => Package['neutron'],
960    }
961  
962 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
963 +    # config neutron service_plugins to onos driver
964 +    class { '::neutron':
965 +      service_plugins  => [hiera('neutron_service_plugins')]
966 +    }
967 +  } else {
968 +    include ::neutron
969 +    if 'opendaylight' in hiera('neutron_mechanism_drivers') {
970 +      if ! str2bool(hiera('opendaylight_enable_l3', 'no')) {
971 +        include ::neutron::agents::l3
972 +      }
973 +    }
974 +  }
975 +  
976    class { '::neutron::plugins::ml2':
977      flat_networks        => split(hiera('neutron_flat_networks'), ','),
978      tenant_network_types => [hiera('neutron_tenant_network_type')],
979      mechanism_drivers    => [hiera('neutron_mechanism_drivers')],
980    }
981 -  class { '::neutron::agents::ml2::ovs':
982 -    bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
983 -    tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
984 +
985 +  if 'opendaylight' in hiera('neutron_mechanism_drivers') {
986 +    if ! str2bool(hiera('opendaylight_enable_l3', 'no')) {
987 +      Service['neutron-server'] -> Service['neutron-l3']
988 +    }
989 +
990 +    if str2bool(hiera('opendaylight_install', 'false')) {
991 +      $controller_ips = split(hiera('controller_node_ips'), ',')
992 +      $opendaylight_controller_ip = $controller_ips[0]
993 +    } else {
994 +      $opendaylight_controller_ip = hiera('opendaylight_controller_ip')
995 +    }
996 +
997 +    # co-existence hacks for SFC
998 +    if hiera('opendaylight_features', 'odl-ovsdb-openstack') =~ /odl-ovsdb-sfc-rest/ {
999 +      $opendaylight_port = hiera('opendaylight_port')
1000 +      $netvirt_coexist_url = "http://${opendaylight_controller_ip}:${opendaylight_port}/restconf/config/netvirt-providers-config:netvirt-providers-config"
1001 +      $netvirt_post_body = "{'netvirt-providers-config': {'table-offset': 1}}"
1002 +      $sfc_coexist_url = "http://${opendaylight_controller_ip}:${opendaylight_port}/restconf/config/sfc-of-renderer:sfc-of-renderer-config"
1003 +      $sfc_post_body = "{ 'sfc-of-renderer-config' : { 'sfc-of-table-offset' : 150, 'sfc-of-app-egress-table-offset' : 11 }}"
1004 +      $odl_username = hiera('opendaylight_username')
1005 +      $odl_password = hiera('opendaylight_password')
1006 +      exec { 'Coexistence table offsets for netvirt':
1007 +        command   => "curl -o /dev/null --fail --silent -u ${odl_username}:${odl_password} ${netvirt_coexist_url} -i -H 'Content-Type: application/json' --data \'${netvirt_post_body}\' -X PUT",
1008 +        tries     => 5,
1009 +        try_sleep => 30,
1010 +        path      => '/usr/sbin:/usr/bin:/sbin:/bin',
1011 +      } ->
1012 +      # Coexist for SFC
1013 +      exec { 'Coexistence table offsets for sfc':
1014 +        command   => "curl -o /dev/null --fail --silent -u ${odl_username}:${odl_password} ${sfc_coexist_url} -i -H 'Content-Type: application/json' --data \'${sfc_post_body}\' -X PUT",
1015 +        tries     => 5,
1016 +        try_sleep => 30,
1017 +        path      => '/usr/sbin:/usr/bin:/sbin:/bin',
1018 +      }
1019 +    }
1020 +
1021 +    class { 'neutron::plugins::ml2::opendaylight':
1022 +      odl_controller_ip => $opendaylight_controller_ip,
1023 +      odl_username      => hiera('opendaylight_username'),
1024 +      odl_password      => hiera('opendaylight_password'),
1025 +      odl_port          => hiera('opendaylight_port'),
1026 +    }
1027 +
1028 +    if str2bool(hiera('opendaylight_install', 'false')) {
1029 +      class { 'neutron::plugins::ovs::opendaylight':
1030 +        odl_controller_ip => $opendaylight_controller_ip,
1031 +        tunnel_ip         => hiera('neutron::agents::ml2::ovs::local_ip'),
1032 +        odl_port          => hiera('opendaylight_port'),
1033 +        odl_username      => hiera('opendaylight_username'),
1034 +        odl_password      => hiera('opendaylight_password'),
1035 +      }
1036 +    }
1037 +
1038 +  } elsif 'onos_ml2' in hiera('neutron_mechanism_drivers') {
1039 +    #config ml2_conf.ini with onos url address
1040 +    $onos_port = hiera('onos_port')
1041 +    $private_ip = hiera('neutron::agents::ml2::ovs::local_ip')
1042 +
1043 +    neutron_plugin_ml2 {
1044 +      'onos/username':         value => 'admin';
1045 +      'onos/password':         value => 'admin';
1046 +      'onos/url_path':         value => "http://${controller_node_ips[0]}:${onos_port}/onos/vtn";
1047 +    }
1048 +
1049 +  } else {
1050 +
1051 +    class { 'neutron::agents::ml2::ovs':
1052 +      bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
1053 +      tunnel_types => split(hiera('neutron_tunnel_types'), ','),
1054 +    }
1055 +
1056 +    Service['neutron-server'] -> Service['neutron-ovs-agent-service']
1057 +    Service['neutron-server'] -> Service['neutron-l3']
1058    }
1059 +
1060    if 'cisco_n1kv' in hiera('neutron_mechanism_drivers') {
1061      include ::neutron::plugins::ml2::cisco::nexus1000v
1062  
1063 @@ -280,8 +382,6 @@ if hiera('step') >= 3 {
1064    }
1065  
1066    Service['neutron-server'] -> Service['neutron-dhcp-service']
1067 -  Service['neutron-server'] -> Service['neutron-l3']
1068 -  Service['neutron-server'] -> Service['neutron-ovs-agent-service']
1069    Service['neutron-server'] -> Service['neutron-metadata']
1070  
1071    include ::cinder
1072 @@ -447,6 +547,20 @@ if hiera('step') >= 3 {
1073  
1074    Cron <| title == 'ceilometer-expirer' |> { command => "sleep $((\$(od -A n -t d -N 3 /dev/urandom) % 86400)) && ${::ceilometer::params::expirer_command}" }
1075  
1076 +  # Aodh
1077 +  include ::aodh::auth
1078 +  include ::aodh::api
1079 +  include ::aodh::evaluator
1080 +  include ::aodh::notifier
1081 +  include ::aodh::listener
1082 +  include ::aodh::client
1083 +  include ::aodh::db::sync
1084 +  class { '::aodh' :
1085 +    database_connection => $ceilometer_database_connection,
1086 +  }
1087 +  # To manage the upgrade:
1088 +  Exec['ceilometer-dbsync'] -> Exec['aodh-db-sync']
1089 +
1090    # Heat
1091    include ::heat
1092    include ::heat::api
1093 diff --git a/puppet/manifests/overcloud_controller_pacemaker.pp b/puppet/manifests/overcloud_controller_pacemaker.pp
1094 index 3fb92f3..cb00e9a 100644
1095 --- a/puppet/manifests/overcloud_controller_pacemaker.pp
1096 +++ b/puppet/manifests/overcloud_controller_pacemaker.pp
1097 @@ -380,6 +380,21 @@ if hiera('step') >= 2 {
1098  
1099    }
1100  
1101 +  if str2bool(hiera('opendaylight_install', 'false')) {
1102 +    class {"opendaylight":
1103 +      extra_features => any2array(hiera('opendaylight_features', 'odl-ovsdb-openstack')),
1104 +      odl_rest_port  => hiera('opendaylight_port'),
1105 +      enable_l3      => hiera('opendaylight_enable_l3', 'no'),
1106 +    }
1107 +  }
1108 +
1109 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
1110 +    # install onos and config ovs
1111 +    class {"onos":
1112 +      controllers_ip => $controller_node_ips
1113 +    }
1114 +  }
1115 +  
1116    exec { 'galera-ready' :
1117      command     => '/usr/bin/clustercheck >/dev/null',
1118      timeout     => 30,
1119 @@ -584,7 +599,14 @@ if hiera('step') >= 3 {
1120    include ::nova::network::neutron
1121  
1122    # Neutron class definitions
1123 -  include ::neutron
1124 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
1125 +    # config neutron service_plugins to onos driver
1126 +    class { '::neutron':
1127 +      service_plugins  => [hiera('neutron_service_plugins')]
1128 +    }
1129 +  } else {
1130 +    include ::neutron
1131 +  }
1132    class { '::neutron::server' :
1133      sync_db        => $sync_db,
1134      manage_service => false,
1135 @@ -594,10 +616,6 @@ if hiera('step') >= 3 {
1136      manage_service => false,
1137      enabled        => false,
1138    }
1139 -  class { '::neutron::agents::l3' :
1140 -    manage_service => false,
1141 -    enabled        => false,
1142 -  }
1143    class { '::neutron::agents::metadata':
1144      manage_service => false,
1145      enabled        => false,
1146 @@ -609,18 +627,80 @@ if hiera('step') >= 3 {
1147      notify  => Service['neutron-dhcp-service'],
1148      require => Package['neutron'],
1149    }
1150 +
1151 +  # SDNVPN Hack
1152 +  if ('networking_bgpvpn.neutron.services.plugin.BGPVPNPlugin' in hiera('neutron::service_plugins'))
1153 +  {
1154 +    class  { 'neutron::config':
1155 +      server_config => {
1156 +        'service_providers/service_provider' => {
1157 +          'value' => 'BGPVPN:Dummy:networking_bgpvpn.neutron.services.service_drivers.driver_api.BGPVPNDriver:default'
1158 +        }
1159 +      }
1160 +    }
1161 +  }
1162 +
1163    class { '::neutron::plugins::ml2':
1164      flat_networks        => split(hiera('neutron_flat_networks'), ','),
1165      tenant_network_types => [hiera('neutron_tenant_network_type')],
1166      mechanism_drivers    => [hiera('neutron_mechanism_drivers')],
1167    }
1168 -  class { '::neutron::agents::ml2::ovs':
1169 -    manage_service  => false,
1170 -    enabled         => false,
1171 -    bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
1172 -    tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
1173 -  }
1174 +  if 'opendaylight' in hiera('neutron_mechanism_drivers') {
1175 +    if str2bool(hiera('opendaylight_install', 'false')) {
1176 +      $controller_ips = split(hiera('controller_node_ips'), ',')
1177 +      $opendaylight_controller_ip = $controller_ips[0]
1178 +    } else {
1179 +      $opendaylight_controller_ip = hiera('opendaylight_controller_ip')
1180 +    }
1181 +
1182 +    $opendaylight_port = hiera('opendaylight_port')
1183 +    $private_ip = hiera('neutron::agents::ml2::ovs::local_ip')
1184 +
1185 +    class { 'neutron::plugins::ml2::opendaylight':
1186 +      odl_controller_ip => $opendaylight_controller_ip,
1187 +      odl_username      => hiera('opendaylight_username'),
1188 +      odl_password      => hiera('opendaylight_password'),
1189 +      odl_port          => hiera('opendaylight_port'),
1190 +    }
1191 +
1192 +    if str2bool(hiera('opendaylight_install', 'false')) {
1193 +      class { 'neutron::plugins::ovs::opendaylight':
1194 +        odl_controller_ip => $opendaylight_controller_ip,
1195 +        tunnel_ip         => hiera('neutron::agents::ml2::ovs::local_ip'),
1196 +        odl_port          => hiera('opendaylight_port'),
1197 +        odl_username      => hiera('opendaylight_username'),
1198 +        odl_password      => hiera('opendaylight_password'),
1199 +      }
1200 +    }
1201 +    if ! str2bool(hiera('opendaylight_enable_l3', 'no')) {
1202 +      class { '::neutron::agents::l3' :
1203 +        manage_service => false,
1204 +        enabled        => false,
1205 +      }
1206 +    }
1207 +  } elsif 'onos_ml2' in hiera('neutron_mechanism_drivers') {
1208 +    #config ml2_conf.ini with onos url address
1209 +    $onos_port = hiera('onos_port')
1210 +    $private_ip = hiera('neutron::agents::ml2::ovs::local_ip')
1211  
1212 +    neutron_plugin_ml2 {
1213 +      'onos/username':         value => 'admin';
1214 +      'onos/password':         value => 'admin';
1215 +      'onos/url_path':         value => "http://${controller_node_ips[0]}:${onos_port}/onos/vtn";
1216 +    }
1217 +
1218 +  } else {
1219 +    class { '::neutron::agents::l3' :
1220 +      manage_service => false,
1221 +      enabled        => false,
1222 +    }
1223 +    class { 'neutron::agents::ml2::ovs':
1224 +      manage_service   => false,
1225 +      enabled          => false,
1226 +      bridge_mappings  => split(hiera('neutron_bridge_mappings'), ','),
1227 +      tunnel_types     => split(hiera('neutron_tunnel_types'), ','),
1228 +    }
1229 +  }
1230    if 'cisco_ucsm' in hiera('neutron_mechanism_drivers') {
1231      include ::neutron::plugins::ml2::cisco::ucsm
1232    }
1233 @@ -645,8 +725,10 @@ if hiera('step') >= 3 {
1234    if hiera('neutron_enable_bigswitch_ml2', false) {
1235      include ::neutron::plugins::ml2::bigswitch::restproxy
1236    }
1237 -  neutron_l3_agent_config {
1238 -    'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
1239 +  if !('onos_ml2' in hiera('neutron_mechanism_drivers') or str2bool(hiera('opendaylight_enable_l3', 'no'))) {
1240 +    neutron_l3_agent_config {
1241 +      'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
1242 +    }
1243    }
1244    neutron_dhcp_agent_config {
1245      'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
1246 @@ -813,13 +895,13 @@ if hiera('step') >= 3 {
1247      swift::storage::filter::healthcheck { $swift_components : }
1248    }
1249  
1250 +  $mongo_node_string = join($mongo_node_ips_with_port, ',')
1251    # Ceilometer
1252    case downcase(hiera('ceilometer_backend')) {
1253      /mysql/: {
1254        $ceilometer_database_connection = hiera('ceilometer_mysql_conn_string')
1255      }
1256      default: {
1257 -      $mongo_node_string = join($mongo_node_ips_with_port, ',')
1258        $ceilometer_database_connection = "mongodb://${mongo_node_string}/ceilometer?replicaSet=${mongodb_replset}"
1259      }
1260    }
1261 @@ -879,6 +961,62 @@ if hiera('step') >= 3 {
1262      enabled        => false,
1263    }
1264  
1265 +  $aodh_database_connection = "mongodb://${mongo_node_string}/aodh?replicaSet=${mongodb_replset}"
1266 +
1267 +  class { '::aodh::db':
1268 +    database_connection => $aodh_database_connection
1269 +  }
1270 +
1271 +  # Aodh
1272 +  include ::aodh
1273 +  include ::aodh::config
1274 +  include ::aodh::auth
1275 +  include ::aodh::client
1276 +  class { '::aodh::api':
1277 +    manage_service => false,
1278 +    enabled        => false,
1279 +  }
1280 +  class { '::aodh::evaluator':
1281 +    manage_service => false,
1282 +    enabled        => false,
1283 +  }
1284 +  class { '::aodh::notifier':
1285 +    manage_service => false,
1286 +    enabled        => false,
1287 +  }
1288 +  class { '::aodh::listener':
1289 +    manage_service => false,
1290 +    enabled        => false,
1291 +  }
1292 +
1293 +  $event_pipeline = "---
1294 +sources:
1295 +    - name: event_source
1296 +      events:
1297 +          - \"*\"
1298 +      sinks:
1299 +          - event_sink
1300 +sinks:
1301 +    - name: event_sink
1302 +      transformers:
1303 +      triggers:
1304 +      publishers:
1305 +          - notifier://?topic=alarm.all
1306 +          - notifier://
1307 +"
1308 +
1309 +  # aodh hacks
1310 +  file { '/etc/ceilometer/event_pipeline.yaml':
1311 +    ensure  => present,
1312 +    content => $event_pipeline
1313 +  }
1314 +
1315 +  user { 'aodh':
1316 +     groups => 'nobody'
1317 +  }
1318 +
1319 +
1320 +
1321    # httpd/apache and horizon
1322    # NOTE(gfidente): server-status can be consumed by the pacemaker resource agent
1323    class { '::apache' :
1324 @@ -1055,62 +1193,21 @@ if hiera('step') >= 4 {
1325        clone_params => 'interleave=true',
1326        require      => Pacemaker::Resource::Service[$::keystone::params::service_name],
1327      }
1328 -    pacemaker::resource::service { $::neutron::params::l3_agent_service:
1329 -      clone_params => 'interleave=true',
1330 +    if !('onos_ml2' in hiera('neutron_mechanism_drivers')) {
1331 +      pacemaker::resource::service { $::neutron::params::l3_agent_service:
1332 +        clone_params => 'interleave=true',
1333 +      }
1334      }
1335      pacemaker::resource::service { $::neutron::params::dhcp_agent_service:
1336        clone_params => 'interleave=true',
1337      }
1338 -    pacemaker::resource::service { $::neutron::params::ovs_agent_service:
1339 -      clone_params => 'interleave=true',
1340 -    }
1341      pacemaker::resource::service { $::neutron::params::metadata_agent_service:
1342        clone_params => 'interleave=true',
1343      }
1344 -    pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
1345 -      ocf_agent_name => 'neutron:OVSCleanup',
1346 -      clone_params   => 'interleave=true',
1347 -    }
1348      pacemaker::resource::ocf { 'neutron-netns-cleanup':
1349        ocf_agent_name => 'neutron:NetnsCleanup',
1350        clone_params   => 'interleave=true',
1351      }
1352 -
1353 -    # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent
1354 -    pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
1355 -      constraint_type => 'order',
1356 -      first_resource  => "${::neutron::params::ovs_cleanup_service}-clone",
1357 -      second_resource => 'neutron-netns-cleanup-clone',
1358 -      first_action    => 'start',
1359 -      second_action   => 'start',
1360 -      require         => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
1361 -                          Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1362 -    }
1363 -    pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
1364 -      source  => 'neutron-netns-cleanup-clone',
1365 -      target  => "${::neutron::params::ovs_cleanup_service}-clone",
1366 -      score   => 'INFINITY',
1367 -      require => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
1368 -                  Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1369 -    }
1370 -    pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
1371 -      constraint_type => 'order',
1372 -      first_resource  => 'neutron-netns-cleanup-clone',
1373 -      second_resource => "${::neutron::params::ovs_agent_service}-clone",
1374 -      first_action    => 'start',
1375 -      second_action   => 'start',
1376 -      require         => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
1377 -                          Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1378 -    }
1379 -    pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
1380 -      source  => "${::neutron::params::ovs_agent_service}-clone",
1381 -      target  => 'neutron-netns-cleanup-clone',
1382 -      score   => 'INFINITY',
1383 -      require => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
1384 -                  Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1385 -    }
1386 -
1387 -    #another chain keystone-->neutron-server-->ovs-agent-->dhcp-->l3
1388      pacemaker::constraint::base { 'keystone-to-neutron-server-constraint':
1389        constraint_type => 'order',
1390        first_resource  => "${::keystone::params::service_name}-clone",
1391 @@ -1120,65 +1217,110 @@ if hiera('step') >= 4 {
1392        require         => [Pacemaker::Resource::Service[$::keystone::params::service_name],
1393                            Pacemaker::Resource::Service[$::neutron::params::server_service]],
1394      }
1395 -    pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint':
1396 -      constraint_type => 'order',
1397 -      first_resource  => "${::neutron::params::server_service}-clone",
1398 -      second_resource => "${::neutron::params::ovs_agent_service}-clone",
1399 -      first_action    => 'start',
1400 -      second_action   => 'start',
1401 -      require         => [Pacemaker::Resource::Service[$::neutron::params::server_service],
1402 -                          Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1403 -    }
1404 -    pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint':
1405 -      constraint_type => 'order',
1406 -      first_resource  => "${::neutron::params::ovs_agent_service}-clone",
1407 -      second_resource => "${::neutron::params::dhcp_agent_service}-clone",
1408 -      first_action    => 'start',
1409 -      second_action   => 'start',
1410 -      require         => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service],
1411 -                          Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
1412 +    if 'openvswitch' in hiera('neutron_mechanism_drivers') {
1413 +      pacemaker::resource::service { $::neutron::params::ovs_agent_service:
1414 +        clone_params => "interleave=true",
1415 +      }
1416 +      pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
1417 +        ocf_agent_name => "neutron:OVSCleanup",
1418 +        clone_params => "interleave=true",
1419 +      }
1420 +      # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent
1421 +      pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
1422 +        constraint_type => "order",
1423 +        first_resource => "${::neutron::params::ovs_cleanup_service}-clone",
1424 +        second_resource => "neutron-netns-cleanup-clone",
1425 +        first_action => "start",
1426 +        second_action => "start",
1427 +        require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"],
1428 +                    Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1429 +      }
1430 +      pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
1431 +        source => "neutron-netns-cleanup-clone",
1432 +        target => "${::neutron::params::ovs_cleanup_service}-clone",
1433 +        score => "INFINITY",
1434 +        require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"],
1435 +                    Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1436 +      }
1437 +      pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
1438 +        constraint_type => "order",
1439 +        first_resource => "neutron-netns-cleanup-clone",
1440 +        second_resource => "${::neutron::params::ovs_agent_service}-clone",
1441 +        first_action => "start",
1442 +        second_action => "start",
1443 +        require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"],
1444 +                    Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]],
1445 +      }
1446 +      pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
1447 +        source => "${::neutron::params::ovs_agent_service}-clone",
1448 +        target => "neutron-netns-cleanup-clone",
1449 +        score => "INFINITY",
1450 +        require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"],
1451 +                    Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]],
1452 +      }
1453  
1454 +      #another chain keystone-->neutron-server-->ovs-agent-->dhcp-->l3
1455 +      pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint':
1456 +        constraint_type => "order",
1457 +        first_resource => "${::neutron::params::server_service}-clone",
1458 +        second_resource => "${::neutron::params::ovs_agent_service}-clone",
1459 +        first_action => "start",
1460 +        second_action => "start",
1461 +        require => [Pacemaker::Resource::Service[$::neutron::params::server_service],
1462 +                    Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1463 +      }
1464 +      pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint':
1465 +        constraint_type => "order",
1466 +        first_resource => "${::neutron::params::ovs_agent_service}-clone",
1467 +        second_resource => "${::neutron::params::dhcp_agent_service}-clone",
1468 +        first_action => "start",
1469 +        second_action => "start",
1470 +        require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"],
1471 +                    Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]],
1472 +
1473 +      }
1474 +      pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation':
1475 +        source => "${::neutron::params::dhcp_agent_service}-clone",
1476 +        target => "${::neutron::params::ovs_agent_service}-clone",
1477 +        score => "INFINITY",
1478 +        require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"],
1479 +                    Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]],
1480 +      }
1481      }
1482 -    pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation':
1483 -      source  => "${::neutron::params::dhcp_agent_service}-clone",
1484 -      target  => "${::neutron::params::ovs_agent_service}-clone",
1485 -      score   => 'INFINITY',
1486 -      require => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service],
1487 -                  Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
1488 -    }
1489 -    pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint':
1490 -      constraint_type => 'order',
1491 -      first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
1492 -      second_resource => "${::neutron::params::l3_agent_service}-clone",
1493 -      first_action    => 'start',
1494 -      second_action   => 'start',
1495 -      require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1496 -                          Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
1497 -    }
1498 -    pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-l3-agent-colocation':
1499 -      source  => "${::neutron::params::l3_agent_service}-clone",
1500 -      target  => "${::neutron::params::dhcp_agent_service}-clone",
1501 -      score   => 'INFINITY',
1502 -      require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1503 -                  Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
1504 -    }
1505 -    pacemaker::constraint::base { 'neutron-l3-agent-to-metadata-agent-constraint':
1506 -      constraint_type => 'order',
1507 -      first_resource  => "${::neutron::params::l3_agent_service}-clone",
1508 -      second_resource => "${::neutron::params::metadata_agent_service}-clone",
1509 -      first_action    => 'start',
1510 -      second_action   => 'start',
1511 -      require         => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
1512 -                          Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1513 -    }
1514 -    pacemaker::constraint::colocation { 'neutron-l3-agent-to-metadata-agent-colocation':
1515 -      source  => "${::neutron::params::metadata_agent_service}-clone",
1516 -      target  => "${::neutron::params::l3_agent_service}-clone",
1517 -      score   => 'INFINITY',
1518 -      require => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
1519 -                  Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1520 +    if !('onos_ml2' in hiera('neutron_mechanism_drivers') or str2bool(hiera('opendaylight_enable_l3', 'no'))) {
1521 +      pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint':
1522 +        constraint_type => 'order',
1523 +        first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
1524 +        second_resource => "${::neutron::params::l3_agent_service}-clone",
1525 +        first_action    => 'start',
1526 +        second_action   => 'start',
1527 +        require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1528 +                            Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
1529 +      }
1530 +      pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-l3-agent-colocation':
1531 +        source  => "${::neutron::params::l3_agent_service}-clone",
1532 +        target  => "${::neutron::params::dhcp_agent_service}-clone",
1533 +        score   => 'INFINITY',
1534 +        require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1535 +                    Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
1536 +      }
1537 +      pacemaker::constraint::base { 'neutron-l3-agent-to-metadata-agent-constraint':
1538 +        constraint_type => 'order',
1539 +        first_resource  => "${::neutron::params::l3_agent_service}-clone",
1540 +        second_resource => "${::neutron::params::metadata_agent_service}-clone",
1541 +        first_action    => 'start',
1542 +        second_action   => 'start',
1543 +        require         => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
1544 +                            Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1545 +      }
1546 +      pacemaker::constraint::colocation { 'neutron-l3-agent-to-metadata-agent-colocation':
1547 +        source  => "${::neutron::params::metadata_agent_service}-clone",
1548 +        target  => "${::neutron::params::l3_agent_service}-clone",
1549 +        score   => 'INFINITY',
1550 +        require => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
1551 +                    Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1552 +      }
1553      }
1554 -
1555      # Nova
1556      pacemaker::resource::service { $::nova::params::api_service_name :
1557        clone_params => 'interleave=true',
1558 @@ -1276,7 +1418,7 @@ if hiera('step') >= 4 {
1559                    Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1560      }
1561  
1562 -    # Ceilometer
1563 +    # Ceilometer and Aodh
1564      case downcase(hiera('ceilometer_backend')) {
1565        /mysql/: {
1566          pacemaker::resource::service { $::ceilometer::params::agent_central_service_name :
1567 @@ -1298,10 +1440,19 @@ if hiera('step') >= 4 {
1568      pacemaker::resource::service { $::ceilometer::params::api_service_name :
1569        clone_params => 'interleave=true',
1570      }
1571 -    pacemaker::resource::service { $::ceilometer::params::alarm_evaluator_service_name :
1572 +    pacemaker::resource::service { $::aodh::params::notifier_service_name :
1573        clone_params => 'interleave=true',
1574      }
1575 -    pacemaker::resource::service { $::ceilometer::params::alarm_notifier_service_name :
1576 +    pacemaker::resource::service { $::aodh::params::expirer_package_serice :
1577 +      clone_params => 'interleave=true',
1578 +    }
1579 +    pacemaker::resource::service { $::aodh::params::listener_service_name :
1580 +      clone_params => 'interleave=true',
1581 +    }
1582 +    pacemaker::resource::service { $::aodh::params::api_service_name :
1583 +      clone_params => 'interleave=true',
1584 +    }
1585 +    pacemaker::resource::service { $::aodh::params::evaluator_service_name :
1586        clone_params => 'interleave=true',
1587      }
1588      pacemaker::resource::service { $::ceilometer::params::agent_notification_service_name :
1589 @@ -1315,8 +1466,19 @@ if hiera('step') >= 4 {
1590      # Fedora doesn't know `require-all` parameter for constraints yet
1591      if $::operatingsystem == 'Fedora' {
1592        $redis_ceilometer_constraint_params = undef
1593 +      $redis_aodh_constraint_params = undef
1594      } else {
1595        $redis_ceilometer_constraint_params = 'require-all=false'
1596 +      $redis_aodh_constraint_params = 'require-all=false'
1597 +    }
1598 +    pacemaker::constraint::base { 'keystone-then-aodh-api-constraint':
1599 +      constraint_type => 'order',
1600 +      first_resource  => "${::keystone::params::service_name}-clone",
1601 +      second_resource => "${::aodh::params::api_service_name}-clone",
1602 +      first_action    => 'start',
1603 +      second_action   => 'start',
1604 +      require         => [Pacemaker::Resource::Service[$::aodh::params::api_service_name],
1605 +                          Pacemaker::Resource::Service[$::keystone::params::service_name]],
1606      }
1607      pacemaker::constraint::base { 'redis-then-ceilometer-central-constraint':
1608        constraint_type   => 'order',
1609 @@ -1328,6 +1490,16 @@ if hiera('step') >= 4 {
1610        require           => [Pacemaker::Resource::Ocf['redis'],
1611                              Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name]],
1612      }
1613 +    pacemaker::constraint::base { 'redis-then-aodh-evaluator-constraint':
1614 +      constraint_type   => 'order',
1615 +      first_resource    => 'redis-master',
1616 +      second_resource   => "${::aodh::params::evaluator_service_name}-clone",
1617 +      first_action      => 'promote',
1618 +      second_action     => 'start',
1619 +      constraint_params => $redis_aodh_constraint_params,
1620 +      require           => [Pacemaker::Resource::Ocf['redis'],
1621 +                            Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name]],
1622 +    }
1623      pacemaker::constraint::base { 'keystone-then-ceilometer-central-constraint':
1624        constraint_type => 'order',
1625        first_resource  => "${::keystone::params::service_name}-clone",
1626 @@ -1378,53 +1550,37 @@ if hiera('step') >= 4 {
1627        require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1628                    Pacemaker::Resource::Ocf['delay']],
1629      }
1630 -    pacemaker::constraint::base { 'ceilometer-delay-then-ceilometer-alarm-evaluator-constraint':
1631 +    pacemaker::constraint::base { 'aodh-delay-then-aodh-evaluator-constraint':
1632        constraint_type => 'order',
1633        first_resource  => 'delay-clone',
1634 -      second_resource => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1635 +      second_resource => "${::aodh::params::evaluator_service_name}-clone",
1636        first_action    => 'start',
1637        second_action   => 'start',
1638 -      require         => [Pacemaker::Resource::Service[$::ceilometer::params::alarm_evaluator_service_name],
1639 +      require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1640                            Pacemaker::Resource::Ocf['delay']],
1641      }
1642 -    pacemaker::constraint::colocation { 'ceilometer-alarm-evaluator-with-ceilometer-delay-colocation':
1643 -      source  => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1644 +    pacemaker::constraint::colocation { 'aodh-evaluator-with-aodh-delay-colocation':
1645 +      source  => "${::aodh::params::evaluator_service_name}-clone",
1646        target  => 'delay-clone',
1647        score   => 'INFINITY',
1648 -      require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1649 +      require => [Pacemaker::Resource::Service[$::horizon::params::http_service],
1650                    Pacemaker::Resource::Ocf['delay']],
1651      }
1652 -    pacemaker::constraint::base { 'ceilometer-alarm-evaluator-then-ceilometer-alarm-notifier-constraint':
1653 -      constraint_type => 'order',
1654 -      first_resource  => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1655 -      second_resource => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1656 -      first_action    => 'start',
1657 -      second_action   => 'start',
1658 -      require         => [Pacemaker::Resource::Service[$::ceilometer::params::alarm_evaluator_service_name],
1659 -                          Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1660 -    }
1661 -    pacemaker::constraint::colocation { 'ceilometer-alarm-notifier-with-ceilometer-alarm-evaluator-colocation':
1662 -      source  => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1663 -      target  => "${::ceilometer::params::alarm_evaluator_service_name}-clone",
1664 -      score   => 'INFINITY',
1665 -      require => [Pacemaker::Resource::Service[$::ceilometer::params::alarm_evaluator_service_name],
1666 -                  Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1667 -    }
1668 -    pacemaker::constraint::base { 'ceilometer-alarm-notifier-then-ceilometer-notification-constraint':
1669 +    pacemaker::constraint::base { 'aodh-evaluator-then-aodh-notifier-constraint':
1670        constraint_type => 'order',
1671 -      first_resource  => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1672 -      second_resource => "${::ceilometer::params::agent_notification_service_name}-clone",
1673 +      first_resource  => "${::aodh::params::evaluator_service_name}-clone",
1674 +      second_resource => "${::aodh::params::notifier_service_name}-clone",
1675        first_action    => 'start',
1676        second_action   => 'start',
1677 -      require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name],
1678 -                          Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1679 +      require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1680 +                          Pacemaker::Resource::Service[$::aodh::params::notifier_service_name]],
1681      }
1682 -    pacemaker::constraint::colocation { 'ceilometer-notification-with-ceilometer-alarm-notifier-colocation':
1683 -      source  => "${::ceilometer::params::agent_notification_service_name}-clone",
1684 -      target  => "${::ceilometer::params::alarm_notifier_service_name}-clone",
1685 +    pacemaker::constraint::colocation { 'aodh-notifier-with-aodh-evaluator-colocation':
1686 +      source  => "${::aodh::params::notifier_service_name}-clone",
1687 +      target  => "${::aodh::params::evaluator_service_name}-clone",
1688        score   => 'INFINITY',
1689 -      require => [Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name],
1690 -                  Pacemaker::Resource::Service[$::ceilometer::params::alarm_notifier_service_name]],
1691 +      require => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1692 +                  Pacemaker::Resource::Service[$::aodh::params::notifier_service_name]],
1693      }
1694      if downcase(hiera('ceilometer_backend')) == 'mongodb' {
1695        pacemaker::constraint::base { 'mongodb-then-ceilometer-central-constraint':
1696 diff --git a/puppet/manifests/overcloud_opendaylight.pp b/puppet/manifests/overcloud_opendaylight.pp
1697 new file mode 100644
1698 index 0000000..aeb31be
1699 --- /dev/null
1700 +++ b/puppet/manifests/overcloud_opendaylight.pp
1701 @@ -0,0 +1,27 @@
1702 +# Copyright 2015 Red Hat, Inc.
1703 +# All Rights Reserved.
1704 +#
1705 +# Licensed under the Apache License, Version 2.0 (the "License"); you may
1706 +# not use this file except in compliance with the License. You may obtain
1707 +# a copy of the License at
1708 +#
1709 +#     http://www.apache.org/licenses/LICENSE-2.0
1710 +#
1711 +# Unless required by applicable law or agreed to in writing, software
1712 +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1713 +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1714 +# License for the specific language governing permissions and limitations
1715 +# under the License.
1716 +
1717 +include ::tripleo::packages
1718 +
1719 +if count(hiera('ntp::servers')) > 0 {
1720 +  include ::ntp
1721 +}
1722 +
1723 +class {"opendaylight":
1724 +  extra_features => any2array(hiera('opendaylight_features', 'odl-ovsdb-openstack')),
1725 +  odl_rest_port  => hiera('opendaylight_port'),
1726 +  enable_l3      => hiera('opendaylight_enable_l3', 'no'),
1727 +}
1728 +
1729 diff --git a/puppet/opendaylight-puppet.yaml b/puppet/opendaylight-puppet.yaml
1730 new file mode 100644
1731 index 0000000..6488e0e
1732 --- /dev/null
1733 +++ b/puppet/opendaylight-puppet.yaml
1734 @@ -0,0 +1,223 @@
1735 +heat_template_version: 2015-04-30
1736 +
1737 +description: >
1738 +  OpenDaylight node configured by Puppet.
1739 +
1740 +parameters:
1741 +  OpenDaylightFlavor:
1742 +    default: baremetal
1743 +    description: The flavor to use for the OpenDaylight node
1744 +    type: string
1745 +  OpenDaylightImage:
1746 +    default: overcloud-full
1747 +    description: The image to use for the OpenDaylight node
1748 +    type: string
1749 +  OpenDaylightHostname:
1750 +    default: opendaylight-server
1751 +    description: The hostname to use for the OpenDaylight node
1752 +    type: string
1753 +  OpenDaylightUsername:
1754 +    default: admin
1755 +    description: The admin user for the OpenDaylight node
1756 +    type: string
1757 +  OpenDaylightPassword:
1758 +    default: ''
1759 +    description: The admin password for the OpenDaylight node
1760 +    type: string
1761 +    hidden: true
1762 +  OpenDaylightEnableL3:
1763 +    description: Knob to enable/disable ODL L3
1764 +    type: string
1765 +    default: 'no'
1766 +  OpenDaylightFeatures:
1767 +    description: List of features to install with ODL
1768 +    type: comma_delimited_list
1769 +    default: "odl-ovsdb-openstack"
1770 +  OpenDaylightPort:
1771 +    default: 8081
1772 +    description: Set OpenDaylight service port
1773 +    type: number
1774 +  KeyName:
1775 +    description: The keypair to use for SSH access to the node (via heat-admin user)
1776 +    type: string
1777 +    default: default
1778 +    constraints:
1779 +      - custom_constraint: nova.keypair
1780 +  ImageUpdatePolicy:
1781 +    default: 'REBUILD_PRESERVE_EPHEMERAL'
1782 +    description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
1783 +    type: string
1784 +  UpdateIdentifier:
1785 +    default: ''
1786 +    type: string
1787 +    description: >
1788 +      Setting to a previously unused value during stack-update will trigger
1789 +      package update on all nodes
1790 +  NtpServer:
1791 +    type: string
1792 +    default: ''
1793 +  PublicInterface:
1794 +    default: nic1
1795 +    description: What interface to bridge onto br-ex for network nodes.
1796 +    type: string
1797 +
1798 +resources:
1799 +  OpenDaylightNode:
1800 +    type: OS::Nova::Server
1801 +    properties:
1802 +      image: {get_param: OpenDaylightImage}
1803 +      image_update_policy: {get_param: ImageUpdatePolicy}
1804 +      flavor: {get_param: OpenDaylightFlavor}
1805 +      key_name: {get_param: KeyName}
1806 +      networks:
1807 +        - network: ctlplane
1808 +      user_data_format: SOFTWARE_CONFIG
1809 +      user_data: {get_resource: NodeUserData}
1810 +      name: {get_param: OpenDaylightHostname}
1811 +
1812 +  NodeUserData:
1813 +    type: OS::TripleO::NodeUserData
1814 +
1815 +  ExternalPort:
1816 +    type: OS::TripleO::Controller::Ports::ExternalPort
1817 +    properties:
1818 +      ControlPlaneIP: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1819 +
1820 +  InternalApiPort:
1821 +    type: OS::TripleO::Controller::Ports::InternalApiPort
1822 +    properties:
1823 +      ControlPlaneIP: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1824 +
1825 +  NetIpMap:
1826 +    type: OS::TripleO::Network::Ports::NetIpMap
1827 +    properties:
1828 +      ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1829 +      ExternalIp: {get_attr: [ExternalPort, ip_address]}
1830 +      InternalApiIp: {get_attr: [InternalApiPort, ip_address]}
1831 +
1832 +  NetIpSubnetMap:
1833 +    type: OS::TripleO::Network::Ports::NetIpSubnetMap
1834 +    properties:
1835 +      ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1836 +      ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]}
1837 +      InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]}
1838 +
1839 +  NetworkConfig:
1840 +    type: OS::TripleO::Controller::Net::SoftwareConfig
1841 +    properties:
1842 +      ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1843 +      ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]}
1844 +      InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]}
1845 +
1846 +  NetworkDeployment:
1847 +    type: OS::TripleO::SoftwareDeployment
1848 +    properties:
1849 +      config: {get_resource: NetworkConfig}
1850 +      server: {get_resource: OpenDaylightNode}
1851 +      input_values:
1852 +        bridge_name: br-ex
1853 +        interface_name: {get_param: PublicInterface}
1854 +
1855 +  OpenDaylightDeployment:
1856 +    type: OS::TripleO::SoftwareDeployment
1857 +    depends_on: NetworkDeployment
1858 +    properties:
1859 +      config: {get_resource: OpenDaylightConfig}
1860 +      server: {get_resource: OpenDaylightNode}
1861 +      input_values:
1862 +        ntp_servers:
1863 +          str_replace:
1864 +            template: '["server"]'
1865 +            params:
1866 +              server: {get_param: NtpServer}
1867 +        opendaylight_port: {get_param: OpenDaylightPort}
1868 +        opendaylight_enable_l3: {get_param: OpenDaylightEnableL3}
1869 +        opendaylight_username: {get_param: OpenDaylightUsername}
1870 +        opendaylight_password: {get_param: OpenDaylightPassword}
1871 +        opendaylight_features: {get_param: OpenDaylightFeatures}
1872 +
1873 +  OpenDaylightConfig:
1874 +    type: OS::Heat::StructuredConfig
1875 +    properties:
1876 +      group: os-apply-config
1877 +      config:
1878 +        hiera:
1879 +          hierarchy:
1880 +            - '"%{::uuid}"'
1881 +            - heat_config_%{::deploy_config_name}
1882 +            - extraconfig
1883 +            - bootstrap_node # provided by BootstrapNodeConfig
1884 +            - all_nodes # provided by allNodesConfig
1885 +            - vip_data # provided by vip-config
1886 +            - RedHat # Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1236143
1887 +            - common
1888 +          datafiles:
1889 +            common:
1890 +              raw_data: {get_file: hieradata/common.yaml}
1891 +              mapped_data:
1892 +                ntp::servers: {get_input: ntp_servers}
1893 +                opendaylight::admin_username: {get_param: OpenDaylightUsername}
1894 +                opendaylight::admin_password: {get_param: OpenDaylightPassword}
1895 +                opendaylight_port: {get_input: opendaylight_port}
1896 +                opendaylight_enable_l3: {get_input: opendaylight_enable_l3}
1897 +                opendaylight_features: {get_input: opendaylight_features}
1898 +            ceph:
1899 +              raw_data: {get_file: hieradata/ceph.yaml}
1900 +
1901 +  UpdateConfig:
1902 +    type: OS::TripleO::Tasks::PackageUpdate
1903 +
1904 +  UpdateDeployment:
1905 +    type: OS::Heat::SoftwareDeployment
1906 +    properties:
1907 +      config: {get_resource: UpdateConfig}
1908 +      server: {get_resource: OpenDaylightNode}
1909 +      input_values:
1910 +        update_identifier:
1911 +          get_param: UpdateIdentifier
1912 +
1913 +  OpenDaylightHostsConfig:
1914 +    type: OS::Heat::SoftwareConfig
1915 +    properties:
1916 +      group: script
1917 +      config: |
1918 +        #!/usr/bin/env bash
1919 +        echo -e "$(facter ipaddress)\t\t$(hostname -f)\t$(hostname -s)" >> /etc/hosts
1920 +
1921 +  OpenDaylightHostsDeployment:
1922 +    type: OS::Heat::StructuredDeployment
1923 +    depends_on: OpenDaylightDeployment
1924 +    properties:
1925 +      server: {get_resource: OpenDaylightNode}
1926 +      config: {get_resource: OpenDaylightHostsConfig}
1927 +
1928 +  OpenDaylightPuppetConfig:
1929 +    type: OS::Heat::SoftwareConfig
1930 +    properties:
1931 +      group: puppet
1932 +      config:
1933 +        get_file: manifests/overcloud_opendaylight.pp
1934 +
1935 +  OpenDaylightPuppetDeployment:
1936 +    depends_on: OpenDaylightHostsDeployment
1937 +    type: OS::Heat::StructuredDeployment
1938 +    properties:
1939 +      server: {get_resource: OpenDaylightNode}
1940 +      config: {get_resource: OpenDaylightPuppetConfig}
1941 +      input_values:
1942 +        update_identifier: {get_param: UpdateIdentifier}
1943 +
1944 +outputs:
1945 +  ip_address:
1946 +    description: IP address of the server in the ctlplane network
1947 +    value: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1948 +  opendaylight_controller_ip:
1949 +    description: IP address of the server on the internal network
1950 +    value: {get_attr: [InternalApiPort, ip_address]}
1951 +  config_identifier:
1952 +    description: identifier which changes if the node configuration may need re-applying
1953 +    value:
1954 +      list_join:
1955 +      - ','
1956 +      - - {get_attr: [OpenDaylightDeployment, deploy_stdout]}
1957 +        - {get_param: UpdateIdentifier}
1958 -- 
1959 1.8.3.1
1960