Adds onos support
[apex.git] / build / opnfv-tripleo-heat-templates.patch
1 From 63f8b6412f526ba245d86f40eb6b1ae1ee06485d Mon Sep 17 00:00:00 2001
2 From: Dan Radez <dradez@redhat.com>
3 Date: Sun, 13 Dec 2015 21:20:40 -0500
4 Subject: [PATCH] Adds OpenDaylight support
5
6 To enable OpenDaylight on controllers use environments/opendaylight.yaml
7 To enable OpenDaylight on external node use
8 environments/opendaylight-external.yaml
9
10 Adds onos support
11 ---
12  environments/onos.yaml                             |   8 +
13  environments/opendaylight-external.yaml            |  25 ++
14  environments/opendaylight.yaml                     |  25 ++
15  overcloud-resource-registry-puppet.yaml            |   3 +
16  overcloud-without-mergepy.yaml                     |  62 +++++
17  puppet/all-nodes-config.yaml                       |   6 +
18  puppet/compute.yaml                                |  25 ++
19  puppet/controller.yaml                             |  35 +++
20  puppet/manifests/overcloud_compute.pp              |  33 ++-
21  puppet/manifests/overcloud_controller.pp           |  80 +++++-
22  puppet/manifests/overcloud_controller_pacemaker.pp | 299 +++++++++++++--------
23  puppet/manifests/overcloud_opendaylight.pp         |  26 ++
24  puppet/opendaylight-puppet.yaml                    | 209 ++++++++++++++
25  13 files changed, 712 insertions(+), 124 deletions(-)
26  create mode 100644 environments/onos.yaml
27  create mode 100644 environments/opendaylight-external.yaml
28  create mode 100644 environments/opendaylight.yaml
29  create mode 100644 puppet/manifests/overcloud_opendaylight.pp
30  create mode 100644 puppet/opendaylight-puppet.yaml
31
32 diff --git a/environments/onos.yaml b/environments/onos.yaml
33 new file mode 100644
34 index 0000000..510aca9
35 --- /dev/null
36 +++ b/environments/onos.yaml
37 @@ -0,0 +1,8 @@
38 +parameters:
39 +    #This a bug for odl deployment. Once bug fixed OpenDaylightCount can be remove.
40 +    OpenDaylightCount: 0
41 +    NeutronL3HA: false
42 +    ExtraConfig:
43 +      neutron_service_plugins: ['onos_router']
44 +      neutron_mechanism_drivers: ['onos_ml2']
45 +      neutron_tenant_network_type: vxlan
46 diff --git a/environments/opendaylight-external.yaml b/environments/opendaylight-external.yaml
47 new file mode 100644
48 index 0000000..411df21
49 --- /dev/null
50 +++ b/environments/opendaylight-external.yaml
51 @@ -0,0 +1,25 @@
52 +# Environment file used to enable OpenDaylight
53 +# Currently uses overcloud image that is assumed
54 +# to be virt-customized with ODL RPM already on it
55 +
56 +# These parameters customize the OpenDaylight Node
57 +# The user name and password are for the ODL service
58 +# Defaults are included here for reference
59 +#parameter_defaults:
60 +#  OpenDaylightFlavor: baremetal
61 +#  OpenDaylightHostname: opendaylight-server
62 +#  OpenDaylightImage: overcloud-full
63 +#  OpenDaylightUsername: admin
64 +#  OpenDaylightPassword: admin
65 +
66 +parameters:
67 +    # increase this if you need more ODL nodes
68 +    OpenDaylightCount: 1
69 +    NeutronL3HA: false
70 +    ExtraConfig:
71 +      neutron_mechanism_drivers: ['opendaylight']
72 +      neutron_tenant_network_type: vxlan
73 +      # Enable this if you want OpenDaylight on the contollers
74 +      # reduce OpenDaylightCount to 0 if you don't want any
75 +      # OpenDaylight only nodes
76 +      #opendaylight_install: true
77 diff --git a/environments/opendaylight.yaml b/environments/opendaylight.yaml
78 new file mode 100644
79 index 0000000..c8abf75
80 --- /dev/null
81 +++ b/environments/opendaylight.yaml
82 @@ -0,0 +1,25 @@
83 +# Environment file used to enable OpenDaylight
84 +# Currently uses overcloud image that is assumed
85 +# to be virt-customized with ODL RPM already on it
86 +
87 +# These parameters customize the OpenDaylight Node
88 +# The user name and password are for the ODL service
89 +# Defaults are included here for reference
90 +#parameter_defaults:
91 +#  OpenDaylightFlavor: baremetal
92 +#  OpenDaylightHostname: opendaylight-server
93 +#  OpenDaylightImage: overcloud-full
94 +#  OpenDaylightUsername: admin
95 +#  OpenDaylightPassword: admin
96 +
97 +parameters:
98 +    # increase this if you need more ODL nodes
99 +    # OpenDaylightCount: 1
100 +    NeutronL3HA: false
101 +    ExtraConfig:
102 +      neutron_mechanism_drivers: ['opendaylight']
103 +      neutron_tenant_network_type: vxlan
104 +      # Enable this if you want OpenDaylight on the contollers
105 +      # reduce OpenDaylightCount to 0 if you don't want any
106 +      # OpenDaylight only nodes
107 +      opendaylight_install: true
108 diff --git a/overcloud-resource-registry-puppet.yaml b/overcloud-resource-registry-puppet.yaml
109 index c072c29..2413450 100644
110 --- a/overcloud-resource-registry-puppet.yaml
111 +++ b/overcloud-resource-registry-puppet.yaml
112 @@ -27,6 +27,9 @@ resource_registry:
113    # To disable, replace with firstboot/userdata_default.yaml
114    OS::TripleO::NodeAdminUserData: firstboot/userdata_heat_admin.yaml
115  
116 +  # This configures OpenDaylight to drive the network
117 +  OS::TripleO::OpenDaylightNode: puppet/opendaylight-puppet.yaml
118 +
119    # Hooks for operator extra config
120    # NodeUserData == Cloud-init additional user-data, e.g cloud-config
121    # ControllerExtraConfigPre == Controller configuration pre service deployment
122 diff --git a/overcloud-without-mergepy.yaml b/overcloud-without-mergepy.yaml
123 index 01c0079..210ec11 100644
124 --- a/overcloud-without-mergepy.yaml
125 +++ b/overcloud-without-mergepy.yaml
126 @@ -227,6 +227,23 @@ parameters:
127      default: false
128      description: Should MongoDb journaling be disabled
129      type: boolean
130 +  OpenDaylightPort:
131 +    default: 8081
132 +    description: Set opendaylight service port
133 +    type: number
134 +  OpenDaylightInstall:
135 +    default: false
136 +    description: Whether to install OpenDaylight on the control nodes.
137 +    type: boolean
138 +  OpenDaylightUsername:
139 +    default: 'admin'
140 +    description: The username for the opendaylight server.
141 +    type: string
142 +  OpenDaylightPassword:
143 +    default: 'admin'
144 +    type: string
145 +    description: The password for the opendaylight server.
146 +    hidden: true
147    PublicVirtualFixedIPs:
148      default: []
149      description: >
150 @@ -650,6 +667,18 @@ parameters:
151        structure as ExtraConfig.
152      type: json
153  
154 +# OpenDaylight specific parameters
155 +  OpenDaylightCount:
156 +    type: number
157 +    default: 0
158 +  OpenDaylightImage:
159 +    default: overcloud-full
160 +    type: string
161 +  OpenDaylightFlavor:
162 +    default: baremetal
163 +    description: Flavor for OpenDaylight node
164 +    type: string
165 +
166    # Hostname format for each role
167    # Note %index% is translated into the index of the node, e.g 0/1/2 etc
168    # and %stackname% is replaced with OS::stack_name in the template below.
169 @@ -674,6 +703,10 @@ parameters:
170      type: string
171      description: Format for CephStorage node hostnames
172      default: '%stackname%-cephstorage-%index%'
173 +  OpenDaylightHostnameFormat:
174 +    type: string
175 +    description: Format for OpenDaylight node hostnames
176 +    default: '%stackname%-opendaylight-%index%'
177  
178    # Identifiers to trigger tasks on nodes
179    UpdateIdentifier:
180 @@ -756,6 +789,27 @@ resources:
181        SwiftProxyVirtualIP: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, SwiftProxyNetwork]}]}
182        PublicVirtualIP: {get_attr: [VipMap, net_ip_map, external]}
183  
184 +  OpenDaylightNode:
185 +    type: OS::Heat::ResourceGroup
186 +    depends_on: Networks
187 +    properties:
188 +      count: {get_param: OpenDaylightCount}
189 +      removal_policies: {get_param: ComputeRemovalPolicies}
190 +      resource_def:
191 +        type: OS::TripleO::OpenDaylightNode
192 +        properties:
193 +          UpdateIdentifier: {get_param: UpdateIdentifier}
194 +          OpenDaylightFlavor: {get_param: OpenDaylightFlavor}
195 +          OpenDaylightImage: {get_param: OpenDaylightImage}
196 +          OpenDaylightPort: {get_param: OpenDaylightPort}
197 +          OpenDaylightUsername: {get_param: OpenDaylightUsername}
198 +          OpenDaylightPassword: {get_param: OpenDaylightPassword}
199 +          OpenDaylightHostname:
200 +            str_replace:
201 +              template: {get_param: OpenDaylightHostnameFormat}
202 +              params:
203 +                '%stackname%': {get_param: 'OS::stack_name'}
204 +
205    Controller:
206      type: OS::Heat::ResourceGroup
207      depends_on: Networks
208 @@ -839,6 +893,10 @@ resources:
209            NovaPassword: {get_param: NovaPassword}
210            NtpServer: {get_param: NtpServer}
211            MongoDbNoJournal: {get_param: MongoDbNoJournal}
212 +          OpenDaylightPort: {get_param: OpenDaylightPort}
213 +          OpenDaylightInstall: {get_param: OpenDaylightInstall}
214 +          OpenDaylightUsername: {get_param: OpenDaylightUsername}
215 +          OpenDaylightPassword: {get_param: OpenDaylightPassword}
216            PcsdPassword: {get_resource: PcsdPassword}
217            PublicVirtualInterface: {get_param: PublicVirtualInterface}
218            RabbitPassword: {get_param: RabbitPassword}
219 @@ -933,6 +991,9 @@ resources:
220            NovaPublicIP: {get_attr: [VipMap, net_ip_map, external]}
221            NovaPassword: {get_param: NovaPassword}
222            NtpServer: {get_param: NtpServer}
223 +          OpenDaylightPort: {get_param: OpenDaylightPort}
224 +          OpenDaylightUsername: {get_param: OpenDaylightUsername}
225 +          OpenDaylightPassword: {get_param: OpenDaylightPassword}
226            RabbitHost: {get_attr: [VipMap, net_ip_map, {get_param: [ServiceNetMap, RabbitMqNetwork]}]}
227            RabbitPassword: {get_param: RabbitPassword}
228            RabbitUserName: {get_param: RabbitUserName}
229 @@ -1053,6 +1114,7 @@ resources:
230        compute_hosts: {get_attr: [Compute, hosts_entry]}
231        controller_hosts: {get_attr: [Controller, hosts_entry]}
232        controller_ips: {get_attr: [Controller, ip_address]}
233 +      opendaylight_ip: {get_attr: [OpenDaylightNode, ip_address]}
234        block_storage_hosts: {get_attr: [BlockStorage, hosts_entry]}
235        object_storage_hosts: {get_attr: [ObjectStorage, hosts_entry]}
236        ceph_storage_hosts: {get_attr: [CephStorage, hosts_entry]}
237 diff --git a/puppet/all-nodes-config.yaml b/puppet/all-nodes-config.yaml
238 index 2bc519b..98283c2 100644
239 --- a/puppet/all-nodes-config.yaml
240 +++ b/puppet/all-nodes-config.yaml
241 @@ -8,6 +8,8 @@ parameters:
242      type: comma_delimited_list
243    controller_ips:
244      type: comma_delimited_list
245 +  opendaylight_ip:
246 +    type: comma_delimited_list
247    block_storage_hosts:
248      type: comma_delimited_list
249    object_storage_hosts:
250 @@ -82,6 +84,10 @@ resources:
251                raw_data: {get_file: hieradata/RedHat.yaml}
252              all_nodes:
253                mapped_data:
254 +                opendaylight_controller_ip:
255 +                  list_join:
256 +                  - ','
257 +                  - {get_param: opendaylight_ip}
258                  controller_node_ips:
259                    list_join:
260                    - ','
261 diff --git a/puppet/compute.yaml b/puppet/compute.yaml
262 index e259cff..5527669 100644
263 --- a/puppet/compute.yaml
264 +++ b/puppet/compute.yaml
265 @@ -213,6 +213,23 @@ parameters:
266    NtpServer:
267      type: string
268      default: ''
269 +  OpenDaylightPort:
270 +    default: 8081
271 +    description: Set opendaylight service port
272 +    type: number
273 +  OpenDaylightUsername:
274 +    default: 'admin'
275 +    description: The username for the opendaylight server.
276 +    type: string
277 +  OpenDaylightPassword:
278 +    default: 'admin'
279 +    type: string
280 +    description: The password for the opendaylight server.
281 +    hidden: true
282 +  ONOSPort:
283 +    default: 8181
284 +    description: Set onos service port
285 +    type: number
286    RabbitHost:
287      type: string
288      default: ''  # Has to be here because of the ignored empty value bug
289 @@ -415,6 +432,10 @@ resources:
290                  neutron::rabbit_user: {get_input: rabbit_username}
291                  neutron::rabbit_use_ssl: {get_input: rabbit_client_use_ssl}
292                  neutron::rabbit_port: {get_input: rabbit_client_port}
293 +                opendaylight_port: {get_input: opendaylight_port}
294 +                opendaylight_username: {get_input: opendaylight_username}
295 +                opendaylight_password: {get_input: opendaylight_password}
296 +                onos_port: {get_input: onos_port}
297                  neutron_flat_networks: {get_input: neutron_flat_networks}
298                  neutron_host: {get_input: neutron_host}
299                  neutron::agents::ml2::ovs::local_ip: {get_input: neutron_local_ip}
300 @@ -468,6 +489,10 @@ resources:
301          snmpd_readonly_user_name: {get_param: SnmpdReadonlyUserName}
302          snmpd_readonly_user_password: {get_param: SnmpdReadonlyUserPassword}
303          glance_api_servers: {get_param: [EndpointMap, GlanceInternal, uri]}
304 +        opendaylight_port: {get_param: OpenDaylightPort}
305 +        opendaylight_username: {get_param: OpenDaylightUsername}
306 +        opendaylight_password: {get_param: OpenDaylightPassword}
307 +        onos_port: {get_param: ONOSPort}
308          neutron_flat_networks: {get_param: NeutronFlatNetworks}
309          neutron_host: {get_param: NeutronHost}
310          neutron_local_ip: {get_attr: [NetIpMap, net_ip_map, {get_param: [ServiceNetMap, NeutronTenantNetwork]}]}
311 diff --git a/puppet/controller.yaml b/puppet/controller.yaml
312 index fdc1821..865a838 100644
313 --- a/puppet/controller.yaml
314 +++ b/puppet/controller.yaml
315 @@ -443,6 +443,27 @@ parameters:
316    NtpServer:
317      type: string
318      default: ''
319 +  OpenDaylightPort:
320 +    default: 8081
321 +    description: Set opendaylight service port
322 +    type: number
323 +  OpenDaylightInstall:
324 +    default: false
325 +    description: Whether to install OpenDaylight on the control nodes.
326 +    type: boolean
327 +  OpenDaylightUsername:
328 +    default: 'admin'
329 +    description: The username for the opendaylight server.
330 +    type: string
331 +  OpenDaylightPassword:
332 +    default: 'admin'
333 +    type: string
334 +    description: The password for the opendaylight server.
335 +    hidden: true
336 +  ONOSPort:
337 +    default: 8181
338 +    description: Set onos service port
339 +    type: number
340    PcsdPassword:
341      type: string
342      description: The password for the 'pcsd' user.
343 @@ -819,6 +840,11 @@ resources:
344              template: tripleo-CLUSTER
345              params:
346                CLUSTER: {get_param: MysqlClusterUniquePart}
347 +        opendaylight_port: {get_param: OpenDaylightPort}
348 +        opendaylight_install: {get_param: OpenDaylightInstall}
349 +        opendaylight_username: {get_param: OpenDaylightUsername}
350 +        opendaylight_password: {get_param: OpenDaylightPassword}
351 +        onos_port: {get_param: ONOSPort}
352          neutron_flat_networks: {get_param: NeutronFlatNetworks}
353          neutron_metadata_proxy_shared_secret: {get_param: NeutronMetadataProxySharedSecret}
354          neutron_agent_mode: {get_param: NeutronAgentMode}
355 @@ -1151,6 +1177,15 @@ resources:
356                  mysql_bind_host: {get_input: mysql_network}
357                  mysql_virtual_ip: {get_input: mysql_virtual_ip}
358  
359 +                # OpenDaylight
360 +                opendaylight_port: {get_input: opendaylight_port}
361 +                opendaylight_install: {get_input: opendaylight_install}
362 +                opendaylight_username: {get_input: opendaylight_username}
363 +                opendaylight_password: {get_input: opendaylight_password}
364 +                
365 +                # ONOS
366 +                onos_port: {get_input: onos_port}
367 +
368                  # Neutron
369                  neutron::bind_host: {get_input: neutron_api_network}
370                  neutron::rabbit_password: {get_input: rabbit_password}
371 diff --git a/puppet/manifests/overcloud_compute.pp b/puppet/manifests/overcloud_compute.pp
372 index cd41cc7..b8336ee 100644
373 --- a/puppet/manifests/overcloud_compute.pp
374 +++ b/puppet/manifests/overcloud_compute.pp
375 @@ -75,9 +75,36 @@ class { '::neutron::plugins::ml2':
376    tenant_network_types => [hiera('neutron_tenant_network_type')],
377  }
378  
379 -class { '::neutron::agents::ml2::ovs':
380 -  bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
381 -  tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
382 +if 'opendaylight' in hiera('neutron_mechanism_drivers') {
383 +
384 +  if str2bool(hiera('opendaylight_install', 'false')) {
385 +    $controller_ips = split(hiera('controller_node_ips'), ',')
386 +    $opendaylight_controller_ip = $controller_ips[0]
387 +  } else {
388 +    $opendaylight_controller_ip = hiera('opendaylight_controller_ip')
389 +  }
390 +
391 +  if str2bool(hiera('opendaylight_install', 'false')) {
392 +    class { 'neutron::plugins::ovs::opendaylight':
393 +      odl_controller_ip => $opendaylight_controller_ip,
394 +      tunnel_ip         => hiera('neutron::agents::ml2::ovs::local_ip'),
395 +      odl_port          => hiera('opendaylight_port'),
396 +      odl_username      => hiera('opendaylight_username'),
397 +      odl_password      => hiera('opendaylight_password'),
398 +    }
399 +  }
400 +
401 +} elsif 'onos_ml2' in hiera('neutron_mechanism_drivers') {
402 +  $controller_ips = split(hiera('controller_node_ips'), ',')
403 +  class {'onos::ovs_computer':
404 +    manager_ip => $controller_ips[0]
405 +  }
406 +
407 +} else {
408 +  class { 'neutron::agents::ml2::ovs':
409 +    bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
410 +    tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
411 +  }
412  }
413  
414  if 'cisco_n1kv' in hiera('neutron_mechanism_drivers') {
415 diff --git a/puppet/manifests/overcloud_controller.pp b/puppet/manifests/overcloud_controller.pp
416 index 1b0429b..d3f3d2d 100644
417 --- a/puppet/manifests/overcloud_controller.pp
418 +++ b/puppet/manifests/overcloud_controller.pp
419 @@ -30,6 +30,20 @@ if hiera('step') >= 1 {
420  
421  if hiera('step') >= 2 {
422  
423 +  if str2bool(hiera('opendaylight_install', 'false')) {
424 +    class {"opendaylight":
425 +      extra_features => ['odl-ovsdb-openstack'],
426 +      odl_rest_port  => hiera('opendaylight_port'),
427 +    }
428 +  }
429 +  
430 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
431 +    # install onos and config ovs
432 +    class {"onos":
433 +      controllers_ip => $controller_node_ips
434 +    }
435 +  }
436 +
437    if count(hiera('ntp::servers')) > 0 {
438      include ::ntp
439    }
440 @@ -223,9 +237,7 @@
441    include ::nova::scheduler
442    include ::nova::scheduler::filter
443  
444 -  include ::neutron
445    include ::neutron::server
446 -  include ::neutron::agents::l3
447    include ::neutron::agents::dhcp
448    include ::neutron::agents::metadata
449  
450 @@ -238,15 +250,71 @@ if hiera('step') >= 3 {
451      require => Package['neutron'],
452    }
453  
454 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
455 +    # config neutron service_plugins to onos driver
456 +    class { '::neutron':
457 +      service_plugins  => [hiera('neutron_service_plugins')]
458 +    }
459 +  } else {
460 +    include ::neutron
461 +    include ::neutron::agents::l3
462 +  }
463 +  
464    class { '::neutron::plugins::ml2':
465      flat_networks        => split(hiera('neutron_flat_networks'), ','),
466      tenant_network_types => [hiera('neutron_tenant_network_type')],
467      mechanism_drivers    => [hiera('neutron_mechanism_drivers')],
468    }
469 -  class { '::neutron::agents::ml2::ovs':
470 -    bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
471 -    tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
472 +
473 +  if 'opendaylight' in hiera('neutron_mechanism_drivers') {
474 +
475 +    if str2bool(hiera('opendaylight_install', 'false')) {
476 +      $controller_ips = split(hiera('controller_node_ips'), ',')
477 +      $opendaylight_controller_ip = $controller_ips[0]
478 +    } else {
479 +      $opendaylight_controller_ip = hiera('opendaylight_controller_ip')
480 +    }
481 +
482 +    class { 'neutron::plugins::ml2::opendaylight':
483 +      odl_controller_ip => $opendaylight_controller_ip,
484 +      odl_username      => hiera('opendaylight_username'),
485 +      odl_password      => hiera('opendaylight_password'),
486 +      odl_port          => hiera('opendaylight_port'),
487 +    }
488 +
489 +    if str2bool(hiera('opendaylight_install', 'false')) {
490 +      class { 'neutron::plugins::ovs::opendaylight':
491 +        odl_controller_ip => $opendaylight_controller_ip,
492 +        tunnel_ip         => hiera('neutron::agents::ml2::ovs::local_ip'),
493 +        odl_port          => hiera('opendaylight_port'),
494 +        odl_username      => hiera('opendaylight_username'),
495 +        odl_password      => hiera('opendaylight_password'),
496 +      }
497 +    }
498 +    Service['neutron-server'] -> Service['neutron-l3']
499 +
500 +  } elsif 'onos_ml2' in hiera('neutron_mechanism_drivers') {
501 +    #config ml2_conf.ini with onos url address
502 +    $onos_port = hiera('onos_port')
503 +    $private_ip = hiera('neutron::agents::ml2::ovs::local_ip')
504 +
505 +    neutron_plugin_ml2 {
506 +      'onos/username':         value => 'admin';
507 +      'onos/password':         value => 'admin';
508 +      'onos/url_path':         value => "http://${controller_node_ips[0]}:${onos_port}/onos/vtn";
509 +    }
510 +
511 +  } else {
512 +
513 +    class { 'neutron::agents::ml2::ovs':
514 +      bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
515 +      tunnel_types => split(hiera('neutron_tunnel_types'), ','),
516 +    }
517 +
518 +    Service['neutron-server'] -> Service['neutron-ovs-agent-service']
519 +    Service['neutron-server'] -> Service['neutron-l3']
520    }
521 +
522    if 'cisco_n1kv' in hiera('neutron_mechanism_drivers') {
523      include ::neutron::plugins::ml2::cisco::nexus1000v
524  
525 @@ -281,8 +349,6 @@ if hiera('step') >= 3 {
526    }
527  
528    Service['neutron-server'] -> Service['neutron-dhcp-service']
529 -  Service['neutron-server'] -> Service['neutron-l3']
530 -  Service['neutron-server'] -> Service['neutron-ovs-agent-service']
531    Service['neutron-server'] -> Service['neutron-metadata']
532  
533    include ::cinder
534 diff --git a/puppet/manifests/overcloud_controller_pacemaker.pp b/puppet/manifests/overcloud_controller_pacemaker.pp
535 index 863cc5f..5b1c37a 100644
536 --- a/puppet/manifests/overcloud_controller_pacemaker.pp
537 +++ b/puppet/manifests/overcloud_controller_pacemaker.pp
538 @@ -380,6 +380,20 @@ if hiera('step') >= 2 {
539  
540    }
541  
542 +  if str2bool(hiera('opendaylight_install', 'false')) {
543 +    class {"opendaylight":
544 +      extra_features => ['odl-ovsdb-openstack'],
545 +      odl_rest_port  => hiera('opendaylight_port'),
546 +    }
547 +  }
548 +
549 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
550 +    # install onos and config ovs
551 +    class {"onos":
552 +      controllers_ip => $controller_node_ips
553 +    }
554 +  }
555 +  
556    exec { 'galera-ready' :
557      command     => '/usr/bin/clustercheck >/dev/null',
558      timeout     => 30,
559 @@ -584,7 +598,14 @@ if hiera('step') >= 3 {
560    include ::nova::network::neutron
561  
562    # Neutron class definitions
563 -  include ::neutron
564 +  if 'onos_ml2' in hiera('neutron_mechanism_drivers') {
565 +    # config neutron service_plugins to onos driver
566 +    class { '::neutron':
567 +      service_plugins  => [hiera('neutron_service_plugins')]
568 +    }
569 +  } else {
570 +    include ::neutron
571 +  }
572    class { '::neutron::server' :
573      sync_db        => $sync_db,
574      manage_service => false,
575 @@ -595,10 +616,6 @@ if hiera('step') >= 3 {
576      manage_service => false,
577      enabled        => false,
578    }
579 -  class { '::neutron::agents::l3' :
580 -    manage_service => false,
581 -    enabled        => false,
582 -  }
583    class { '::neutron::agents::metadata':
584      manage_service => false,
585      enabled        => false,
586 @@ -610,18 +627,66 @@ if hiera('step') >= 3 {
587      notify  => Service['neutron-dhcp-service'],
588      require => Package['neutron'],
589    }
590 +
591    class { '::neutron::plugins::ml2':
592      flat_networks        => split(hiera('neutron_flat_networks'), ','),
593      tenant_network_types => [hiera('neutron_tenant_network_type')],
594      mechanism_drivers    => [hiera('neutron_mechanism_drivers')],
595    }
596 -  class { '::neutron::agents::ml2::ovs':
597 -    manage_service  => false,
598 -    enabled         => false,
599 -    bridge_mappings => split(hiera('neutron_bridge_mappings'), ','),
600 -    tunnel_types    => split(hiera('neutron_tunnel_types'), ','),
601 -  }
602 +  if 'opendaylight' in hiera('neutron_mechanism_drivers') {
603 +    if str2bool(hiera('opendaylight_install', 'false')) {
604 +      $controller_ips = split(hiera('controller_node_ips'), ',')
605 +      $opendaylight_controller_ip = $controller_ips[0]
606 +    } else {
607 +      $opendaylight_controller_ip = hiera('opendaylight_controller_ip')
608 +    }
609 +
610 +    $opendaylight_port = hiera('opendaylight_port')
611 +    $private_ip = hiera('neutron::agents::ml2::ovs::local_ip')
612 +
613 +    class { 'neutron::plugins::ml2::opendaylight':
614 +      odl_controller_ip => $opendaylight_controller_ip,
615 +      odl_username      => hiera('opendaylight_username'),
616 +      odl_password      => hiera('opendaylight_password'),
617 +      odl_port          => hiera('opendaylight_port'),
618 +    }
619 +
620 +    if str2bool(hiera('opendaylight_install', 'false')) {
621 +      class { 'neutron::plugins::ovs::opendaylight':
622 +        odl_controller_ip => $opendaylight_controller_ip,
623 +        tunnel_ip         => hiera('neutron::agents::ml2::ovs::local_ip'),
624 +        odl_port          => hiera('opendaylight_port'),
625 +        odl_username      => hiera('opendaylight_username'),
626 +        odl_password      => hiera('opendaylight_password'),
627 +      }
628 +    }
629 +    class { '::neutron::agents::l3' :
630 +      manage_service => false,
631 +      enabled        => false,
632 +    }
633 +  } elsif 'onos_ml2' in hiera('neutron_mechanism_drivers') {
634 +    #config ml2_conf.ini with onos url address
635 +    $onos_port = hiera('onos_port')
636 +    $private_ip = hiera('neutron::agents::ml2::ovs::local_ip')
637 +
638 +    neutron_plugin_ml2 {
639 +      'onos/username':         value => 'admin';
640 +      'onos/password':         value => 'admin';
641 +      'onos/url_path':         value => "http://${controller_node_ips[0]}:${onos_port}/onos/vtn";
642 +    }
643  
644 +  } else {
645 +    class { '::neutron::agents::l3' :
646 +      manage_service => false,
647 +      enabled        => false,
648 +    }
649 +    class { 'neutron::agents::ml2::ovs':
650 +      manage_service   => false,
651 +      enabled          => false,
652 +      bridge_mappings  => split(hiera('neutron_bridge_mappings'), ','),
653 +      tunnel_types     => split(hiera('neutron_tunnel_types'), ','),
654 +    }
655 +  }
656    if 'cisco_ucsm' in hiera('neutron_mechanism_drivers') {
657      include ::neutron::plugins::ml2::cisco::ucsm
658    }
659 @@ -646,8 +711,10 @@ if hiera('step') >= 3 {
660    if hiera('neutron_enable_bigswitch_ml2', false) {
661      include ::neutron::plugins::ml2::bigswitch::restproxy
662    }
663 -  neutron_l3_agent_config {
664 -    'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
665 +  if !('onos_ml2' in hiera('neutron_mechanism_drivers')) {
666 +    neutron_l3_agent_config {
667 +      'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
668 +    }
669    }
670    neutron_dhcp_agent_config {
671      'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
672 @@ -1073,62 +1140,21 @@ if hiera('step') >= 4 {
673          require      => Pacemaker::Resource::Service[$::keystone::params::service_name]
674        }
675      }
676 -    pacemaker::resource::service { $::neutron::params::l3_agent_service:
677 -      clone_params => 'interleave=true',
678 +    if !('onos_ml2' in hiera('neutron_mechanism_drivers')) {
679 +      pacemaker::resource::service { $::neutron::params::l3_agent_service:
680 +        clone_params => 'interleave=true',
681 +      }
682      }
683      pacemaker::resource::service { $::neutron::params::dhcp_agent_service:
684        clone_params => 'interleave=true',
685      }
686 -    pacemaker::resource::service { $::neutron::params::ovs_agent_service:
687 -      clone_params => 'interleave=true',
688 -    }
689      pacemaker::resource::service { $::neutron::params::metadata_agent_service:
690        clone_params => 'interleave=true',
691      }
692 -    pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
693 -      ocf_agent_name => 'neutron:OVSCleanup',
694 -      clone_params   => 'interleave=true',
695 -    }
696      pacemaker::resource::ocf { 'neutron-netns-cleanup':
697        ocf_agent_name => 'neutron:NetnsCleanup',
698        clone_params   => 'interleave=true',
699      }
700 -
701 -    # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent
702 -    pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
703 -      constraint_type => 'order',
704 -      first_resource  => "${::neutron::params::ovs_cleanup_service}-clone",
705 -      second_resource => 'neutron-netns-cleanup-clone',
706 -      first_action    => 'start',
707 -      second_action   => 'start',
708 -      require         => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
709 -                          Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
710 -    }
711 -    pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
712 -      source  => 'neutron-netns-cleanup-clone',
713 -      target  => "${::neutron::params::ovs_cleanup_service}-clone",
714 -      score   => 'INFINITY',
715 -      require => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
716 -                  Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
717 -    }
718 -    pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
719 -      constraint_type => 'order',
720 -      first_resource  => 'neutron-netns-cleanup-clone',
721 -      second_resource => "${::neutron::params::ovs_agent_service}-clone",
722 -      first_action    => 'start',
723 -      second_action   => 'start',
724 -      require         => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
725 -                          Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
726 -    }
727 -    pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
728 -      source  => "${::neutron::params::ovs_agent_service}-clone",
729 -      target  => 'neutron-netns-cleanup-clone',
730 -      score   => 'INFINITY',
731 -      require => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
732 -                  Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
733 -    }
734 -
735 -    #another chain keystone-->neutron-server-->ovs-agent-->dhcp-->l3
736      pacemaker::constraint::base { 'keystone-to-neutron-server-constraint':
737        constraint_type => 'order',
738        first_resource  => "${::keystone::params::service_name}-clone",
739 @@ -1138,65 +1164,110 @@ if hiera('step') >= 4 {
740        require         => [Pacemaker::Resource::Service[$::keystone::params::service_name],
741                            Pacemaker::Resource::Service[$::neutron::params::server_service]],
742      }
743 -    pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint':
744 -      constraint_type => 'order',
745 -      first_resource  => "${::neutron::params::server_service}-clone",
746 -      second_resource => "${::neutron::params::ovs_agent_service}-clone",
747 -      first_action    => 'start',
748 -      second_action   => 'start',
749 -      require         => [Pacemaker::Resource::Service[$::neutron::params::server_service],
750 -                          Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
751 -    }
752 -    pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint':
753 -      constraint_type => 'order',
754 -      first_resource  => "${::neutron::params::ovs_agent_service}-clone",
755 -      second_resource => "${::neutron::params::dhcp_agent_service}-clone",
756 -      first_action    => 'start',
757 -      second_action   => 'start',
758 -      require         => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service],
759 -                          Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
760 +    if 'openvswitch' in hiera('neutron_mechanism_drivers') {
761 +      pacemaker::resource::service { $::neutron::params::ovs_agent_service:
762 +        clone_params => "interleave=true",
763 +      }
764 +      pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
765 +        ocf_agent_name => "neutron:OVSCleanup",
766 +        clone_params => "interleave=true",
767 +      }
768 +      # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent
769 +      pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
770 +        constraint_type => "order",
771 +        first_resource => "${::neutron::params::ovs_cleanup_service}-clone",
772 +        second_resource => "neutron-netns-cleanup-clone",
773 +        first_action => "start",
774 +        second_action => "start",
775 +        require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"],
776 +                    Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
777 +      }
778 +      pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
779 +        source => "neutron-netns-cleanup-clone",
780 +        target => "${::neutron::params::ovs_cleanup_service}-clone",
781 +        score => "INFINITY",
782 +        require => [Pacemaker::Resource::Ocf["${::neutron::params::ovs_cleanup_service}"],
783 +                    Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
784 +      }
785 +      pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
786 +        constraint_type => "order",
787 +        first_resource => "neutron-netns-cleanup-clone",
788 +        second_resource => "${::neutron::params::ovs_agent_service}-clone",
789 +        first_action => "start",
790 +        second_action => "start",
791 +        require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"],
792 +                    Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]],
793 +      }
794 +      pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
795 +        source => "${::neutron::params::ovs_agent_service}-clone",
796 +        target => "neutron-netns-cleanup-clone",
797 +        score => "INFINITY",
798 +        require => [Pacemaker::Resource::Ocf["neutron-netns-cleanup"],
799 +                    Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"]],
800 +      }
801  
802 +      #another chain keystone-->neutron-server-->ovs-agent-->dhcp-->l3
803 +      pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint':
804 +        constraint_type => "order",
805 +        first_resource => "${::neutron::params::server_service}-clone",
806 +        second_resource => "${::neutron::params::ovs_agent_service}-clone",
807 +        first_action => "start",
808 +        second_action => "start",
809 +        require => [Pacemaker::Resource::Service[$::neutron::params::server_service],
810 +                    Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
811 +      }
812 +      pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint':
813 +        constraint_type => "order",
814 +        first_resource => "${::neutron::params::ovs_agent_service}-clone",
815 +        second_resource => "${::neutron::params::dhcp_agent_service}-clone",
816 +        first_action => "start",
817 +        second_action => "start",
818 +        require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"],
819 +                    Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]],
820 +
821 +      }
822 +      pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation':
823 +        source => "${::neutron::params::dhcp_agent_service}-clone",
824 +        target => "${::neutron::params::ovs_agent_service}-clone",
825 +        score => "INFINITY",
826 +        require => [Pacemaker::Resource::Service["${::neutron::params::ovs_agent_service}"],
827 +                    Pacemaker::Resource::Service["${::neutron::params::dhcp_agent_service}"]],
828 +      }
829      }
830 -    pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation':
831 -      source  => "${::neutron::params::dhcp_agent_service}-clone",
832 -      target  => "${::neutron::params::ovs_agent_service}-clone",
833 -      score   => 'INFINITY',
834 -      require => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service],
835 -                  Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
836 -    }
837 -    pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint':
838 -      constraint_type => 'order',
839 -      first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
840 -      second_resource => "${::neutron::params::l3_agent_service}-clone",
841 -      first_action    => 'start',
842 -      second_action   => 'start',
843 -      require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
844 -                          Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
845 -    }
846 -    pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-l3-agent-colocation':
847 -      source  => "${::neutron::params::l3_agent_service}-clone",
848 -      target  => "${::neutron::params::dhcp_agent_service}-clone",
849 -      score   => 'INFINITY',
850 -      require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
851 -                  Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
852 -    }
853 -    pacemaker::constraint::base { 'neutron-l3-agent-to-metadata-agent-constraint':
854 -      constraint_type => 'order',
855 -      first_resource  => "${::neutron::params::l3_agent_service}-clone",
856 -      second_resource => "${::neutron::params::metadata_agent_service}-clone",
857 -      first_action    => 'start',
858 -      second_action   => 'start',
859 -      require         => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
860 -                          Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
861 -    }
862 -    pacemaker::constraint::colocation { 'neutron-l3-agent-to-metadata-agent-colocation':
863 -      source  => "${::neutron::params::metadata_agent_service}-clone",
864 -      target  => "${::neutron::params::l3_agent_service}-clone",
865 -      score   => 'INFINITY',
866 -      require => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
867 -                  Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
868 +    if !('onos_ml2' in hiera('neutron_mechanism_drivers')) {
869 +      pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint':
870 +        constraint_type => 'order',
871 +        first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
872 +        second_resource => "${::neutron::params::l3_agent_service}-clone",
873 +        first_action    => 'start',
874 +        second_action   => 'start',
875 +        require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
876 +                            Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
877 +      }
878 +      pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-l3-agent-colocation':
879 +        source  => "${::neutron::params::l3_agent_service}-clone",
880 +        target  => "${::neutron::params::dhcp_agent_service}-clone",
881 +        score   => 'INFINITY',
882 +        require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
883 +                    Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]],
884 +      }
885 +      pacemaker::constraint::base { 'neutron-l3-agent-to-metadata-agent-constraint':
886 +        constraint_type => 'order',
887 +        first_resource  => "${::neutron::params::l3_agent_service}-clone",
888 +        second_resource => "${::neutron::params::metadata_agent_service}-clone",
889 +        first_action    => 'start',
890 +        second_action   => 'start',
891 +        require         => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
892 +                            Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
893 +      }
894 +      pacemaker::constraint::colocation { 'neutron-l3-agent-to-metadata-agent-colocation':
895 +        source  => "${::neutron::params::metadata_agent_service}-clone",
896 +        target  => "${::neutron::params::l3_agent_service}-clone",
897 +        score   => 'INFINITY',
898 +        require => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
899 +                    Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
900 +     }
901      }
902 -
903      # Nova
904      pacemaker::resource::service { $::nova::params::api_service_name :
905        clone_params => 'interleave=true',
906 diff --git a/puppet/manifests/overcloud_opendaylight.pp b/puppet/manifests/overcloud_opendaylight.pp
907 new file mode 100644
908 index 0000000..aea6568
909 --- /dev/null
910 +++ b/puppet/manifests/overcloud_opendaylight.pp
911 @@ -0,0 +1,26 @@
912 +# Copyright 2015 Red Hat, Inc.
913 +# All Rights Reserved.
914 +#
915 +# Licensed under the Apache License, Version 2.0 (the "License"); you may
916 +# not use this file except in compliance with the License. You may obtain
917 +# a copy of the License at
918 +#
919 +#     http://www.apache.org/licenses/LICENSE-2.0
920 +#
921 +# Unless required by applicable law or agreed to in writing, software
922 +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
923 +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
924 +# License for the specific language governing permissions and limitations
925 +# under the License.
926 +
927 +include ::tripleo::packages
928 +
929 +if count(hiera('ntp::servers')) > 0 {
930 +  include ::ntp
931 +}
932 +
933 +class {"opendaylight":
934 +  extra_features => ['odl-ovsdb-openstack'],
935 +  odl_rest_port  => hiera('opendaylight_port'),
936 +}
937 +
938 diff --git a/puppet/opendaylight-puppet.yaml b/puppet/opendaylight-puppet.yaml
939 new file mode 100644
940 index 0000000..70f2543
941 --- /dev/null
942 +++ b/puppet/opendaylight-puppet.yaml
943 @@ -0,0 +1,209 @@
944 +heat_template_version: 2015-04-30
945 +
946 +description: >
947 +  OpenDaylight node configured by Puppet.
948 +
949 +parameters:
950 +  OpenDaylightFlavor:
951 +    default: baremetal
952 +    description: The flavor to use for the OpenDaylight node
953 +    type: string
954 +  OpenDaylightImage:
955 +    default: overcloud-full
956 +    description: The image to use for the OpenDaylight node
957 +    type: string
958 +  OpenDaylightHostname:
959 +    default: opendaylight-server
960 +    description: The hostname to use for the OpenDaylight node
961 +    type: string
962 +  OpenDaylightUsername:
963 +    default: admin
964 +    description: The admin user for the OpenDaylight node
965 +    type: string
966 +  OpenDaylightPassword:
967 +    default: ''
968 +    description: The admin password for the OpenDaylight node
969 +    type: string
970 +    hidden: true
971 +  OpenDaylightPort:
972 +    default: 8081
973 +    description: Set OpenDaylight service port
974 +    type: number
975 +  KeyName:
976 +    description: The keypair to use for SSH access to the node (via heat-admin user)
977 +    type: string
978 +    default: default
979 +    constraints:
980 +      - custom_constraint: nova.keypair
981 +  ImageUpdatePolicy:
982 +    default: 'REBUILD_PRESERVE_EPHEMERAL'
983 +    description: What policy to use when reconstructing instances. REBUILD for rebuilds, REBUILD_PRESERVE_EPHEMERAL to preserve /mnt.
984 +    type: string
985 +  UpdateIdentifier:
986 +    default: ''
987 +    type: string
988 +    description: >
989 +      Setting to a previously unused value during stack-update will trigger
990 +      package update on all nodes
991 +  NtpServer:
992 +    type: string
993 +    default: ''
994 +  PublicInterface:
995 +    default: nic1
996 +    description: What interface to bridge onto br-ex for network nodes.
997 +    type: string
998 +
999 +resources:
1000 +  OpenDaylightNode:
1001 +    type: OS::Nova::Server
1002 +    properties:
1003 +      image: {get_param: OpenDaylightImage}
1004 +      image_update_policy: {get_param: ImageUpdatePolicy}
1005 +      flavor: {get_param: OpenDaylightFlavor}
1006 +      key_name: {get_param: KeyName}
1007 +      networks:
1008 +        - network: ctlplane
1009 +      user_data_format: SOFTWARE_CONFIG
1010 +      user_data: {get_resource: NodeUserData}
1011 +      name: {get_param: OpenDaylightHostname}
1012 +
1013 +  NodeUserData:
1014 +    type: OS::TripleO::NodeUserData
1015 +
1016 +  ExternalPort:
1017 +    type: OS::TripleO::Controller::Ports::ExternalPort
1018 +    properties:
1019 +      ControlPlaneIP: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1020 +
1021 +  InternalApiPort:
1022 +    type: OS::TripleO::Controller::Ports::InternalApiPort
1023 +    properties:
1024 +      ControlPlaneIP: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1025 +
1026 +  NetIpMap:
1027 +    type: OS::TripleO::Network::Ports::NetIpMap
1028 +    properties:
1029 +      ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1030 +      ExternalIp: {get_attr: [ExternalPort, ip_address]}
1031 +      InternalApiIp: {get_attr: [InternalApiPort, ip_address]}
1032 +
1033 +  NetIpSubnetMap:
1034 +    type: OS::TripleO::Network::Ports::NetIpSubnetMap
1035 +    properties:
1036 +      ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1037 +      ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]}
1038 +      InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]}
1039 +
1040 +  NetworkConfig:
1041 +    type: OS::TripleO::Controller::Net::SoftwareConfig
1042 +    properties:
1043 +      ControlPlaneIp: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1044 +      ExternalIpSubnet: {get_attr: [ExternalPort, ip_subnet]}
1045 +      InternalApiIpSubnet: {get_attr: [InternalApiPort, ip_subnet]}
1046 +
1047 +  NetworkDeployment:
1048 +    type: OS::TripleO::SoftwareDeployment
1049 +    properties:
1050 +      config: {get_resource: NetworkConfig}
1051 +      server: {get_resource: OpenDaylightNode}
1052 +      input_values:
1053 +        bridge_name: br-ex
1054 +        interface_name: {get_param: PublicInterface}
1055 +
1056 +  OpenDaylightDeployment:
1057 +    type: OS::TripleO::SoftwareDeployment
1058 +    depends_on: NetworkDeployment
1059 +    properties:
1060 +      config: {get_resource: OpenDaylightConfig}
1061 +      server: {get_resource: OpenDaylightNode}
1062 +      input_values:
1063 +        ntp_servers:
1064 +          str_replace:
1065 +            template: '["server"]'
1066 +            params:
1067 +              server: {get_param: NtpServer}
1068 +        opendaylight_port: {get_param: OpenDaylightPort}
1069 +
1070 +  OpenDaylightConfig:
1071 +    type: OS::Heat::StructuredConfig
1072 +    properties:
1073 +      group: os-apply-config
1074 +      config:
1075 +        hiera:
1076 +          hierarchy:
1077 +            - '"%{::uuid}"'
1078 +            - heat_config_%{::deploy_config_name}
1079 +            - extraconfig
1080 +            - bootstrap_node # provided by BootstrapNodeConfig
1081 +            - all_nodes # provided by allNodesConfig
1082 +            - vip_data # provided by vip-config
1083 +            - RedHat # Workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1236143
1084 +            - common
1085 +          datafiles:
1086 +            common:
1087 +              raw_data: {get_file: hieradata/common.yaml}
1088 +              mapped_data:
1089 +                ntp::servers: {get_input: ntp_servers}
1090 +                opendaylight::admin_username: {get_param: OpenDaylightUsername}
1091 +                opendaylight::admin_password: {get_param: OpenDaylightPassword}
1092 +                opendaylight_port: {get_input: opendaylight_port}
1093 +            ceph:
1094 +              raw_data: {get_file: hieradata/ceph.yaml}
1095 +
1096 +  UpdateConfig:
1097 +    type: OS::TripleO::Tasks::PackageUpdate
1098 +
1099 +  UpdateDeployment:
1100 +    type: OS::Heat::SoftwareDeployment
1101 +    properties:
1102 +      config: {get_resource: UpdateConfig}
1103 +      server: {get_resource: OpenDaylightNode}
1104 +      input_values:
1105 +        update_identifier:
1106 +          get_param: UpdateIdentifier
1107 +
1108 +  OpenDaylightHostsConfig:
1109 +    type: OS::Heat::SoftwareConfig
1110 +    properties:
1111 +      group: script
1112 +      config: |
1113 +        #!/usr/bin/env bash
1114 +        echo -e "$(facter ipaddress)\t\t$(hostname -f)\t$(hostname -s)" >> /etc/hosts
1115 +
1116 +  OpenDaylightHostsDeployment:
1117 +    type: OS::Heat::StructuredDeployment
1118 +    depends_on: OpenDaylightDeployment
1119 +    properties:
1120 +      server: {get_resource: OpenDaylightNode}
1121 +      config: {get_resource: OpenDaylightHostsConfig}
1122 +
1123 +  OpenDaylightPuppetConfig:
1124 +    type: OS::Heat::SoftwareConfig
1125 +    properties:
1126 +      group: puppet
1127 +      config:
1128 +        get_file: manifests/overcloud_opendaylight.pp
1129 +
1130 +  OpenDaylightPuppetDeployment:
1131 +    depends_on: OpenDaylightHostsDeployment
1132 +    type: OS::Heat::StructuredDeployment
1133 +    properties:
1134 +      server: {get_resource: OpenDaylightNode}
1135 +      config: {get_resource: OpenDaylightPuppetConfig}
1136 +      input_values:
1137 +        update_identifier: {get_param: UpdateIdentifier}
1138 +
1139 +outputs:
1140 +  ip_address:
1141 +    description: IP address of the server in the ctlplane network
1142 +    value: {get_attr: [OpenDaylightNode, networks, ctlplane, 0]}
1143 +  opendaylight_controller_ip:
1144 +    description: IP address of the server on the internal network
1145 +    value: {get_attr: [InternalApiPort, ip_address]}
1146 +  config_identifier:
1147 +    description: identifier which changes if the node configuration may need re-applying
1148 +    value:
1149 +      list_join:
1150 +      - ','
1151 +      - - {get_attr: [OpenDaylightDeployment, deploy_stdout]}
1152 +        - {get_param: UpdateIdentifier}
1153 -- 
1154 2.5.0
1155