Update the template_version alias for all the templates to pike.
[apex-tripleo-heat-templates.git] / puppet / extraconfig / all_nodes / neutron-ml2-cisco-nexus-ucsm.yaml
1 heat_template_version: pike
2
3 description: Configure hieradata for Network Cisco configuration
4
5 parameters:
6   # Parameters passed from the parent template
7   servers:
8     type: json
9
10   # extra parameters passed via parameter_defaults
11   NetworkUCSMIp:
12     type: string
13     description: Cisco UCSM IP
14     default: 127.0.0.1
15   NetworkUCSMUsername:
16     type: string
17     description: Cisco UCSM username
18     default: admin
19   NetworkUCSMPassword:
20     type: string
21     description: Cisco UCSM password
22     default: password
23   NetworkUCSMHostList:
24     type: string
25     description: >
26       Mac address to service profile mapping for UCSM-controlled hosts
27       The format is
28       '<host1-mac>:<profile>, <host2-mac>:<profile>, ...'
29     default: ''
30   NetworkUCSMSupportedPciDevs:
31     type: string
32     description: Cisco UCSM SR-IOV and VM-FEX vendors supported
33     default: ''
34   NetworkNexusConfig:
35     type: json
36     description: Nexus switch configuration
37     default: {}
38   NetworkNexusManagedPhysicalNetwork:
39     type: string
40     description: The name of the physical_network
41     default: ''
42   NetworkNexusVlanNamePrefix:
43     type: string
44     description: A short prefix to prepend to the VLAN name
45     default: 'q-'
46   NetworkNexusSviRoundRobin:
47     type: boolean
48     description: A flag to enable round robin scheduling
49     default: false
50   NetworkNexusProviderVlanNamePrefix:
51     type: string
52     description:  A short prefix to prepend to the VLAN name
53     default: 'p-'
54   NetworkNexusPersistentSwitchConfig:
55     type: string
56     description: To make Nexus device persistent
57     default: false
58   NetworkNexusSwitchHeartbeatTime:
59     type: number
60     description: >
61       Time interval to check the state of the Nexus device. The units of this
62       object are seconds.  Setting this object to a value of 0 disables the
63       replay feature.
64     default: 0
65   NetworkNexusSwitchReplayCount:
66     type: number
67     description: >
68       This configuration item is OBSOLETE.  The Nexus driver replay behavior
69       is to continue to attempt to connect to the down Nexus device with a
70       period equal to the heartbeat time interval.  This was previously the
71       Number of times to attempt config replay.
72     default: 3
73   NetworkNexusProviderVlanAutoCreate:
74     type: boolean
75     description: A flag whether to manage the creation and removal of VLANs
76     default: true
77   NetworkNexusProviderVlanAutoTrunk:
78     type: boolean
79     description: A flag whether to manage the trunk ports on the Nexus
80     default: true
81   NetworkNexusVxlanGlobalConfig:
82     type: boolean
83     description: A flag whether to manage the VXLAN global settings
84     default: true
85   NetworkNexusHostKeyChecks:
86     type: boolean
87     description: enable strict host key checks when connecting to Nexus switches
88     default: false
89   NetworkNexusVxlanVniRanges:
90     type: string
91     description: VXLAN Network IDs that are available for tenant network
92     default: ''
93   NetworkNexusVxlanMcastRanges:
94     type: string
95     description: Multicast groups for the VXLAN interface.
96     default: ''
97
98
99 resources:
100   # First we lay down the base configuration via the static hieradata mappings
101   NetworkCiscoConfig:
102     type: OS::Heat::StructuredConfig
103     properties:
104       group: hiera
105       config:
106         datafiles:
107           neutron_cisco_data:
108             mapped_data:
109               neutron::plugins::ml2::cisco::ucsm::ucsm_ip: {get_input: UCSM_ip}
110               neutron::plugins::ml2::cisco::ucsm::ucsm_username: {get_input: UCSM_username}
111               neutron::plugins::ml2::cisco::ucsm::ucsm_password: {get_input: UCSM_password}
112               neutron::plugins::ml2::cisco::ucsm::ucsm_host_list: {get_input: UCSM_host_list}
113               neutron::plugins::ml2::cisco::ucsm::supported_pci_devs:  {get_input: UCSMSupportedPciDevs}
114               neutron::plugins::ml2::cisco::nexus::nexus_config: {get_input: NexusConfig}
115               neutron::plugins::ml2::cisco::nexus::managed_physical_network: {get_input: NexusManagedPhysicalNetwork}
116               neutron::plugins::ml2::cisco::nexus::vlan_name_prefix: {get_input: NexusVlanNamePrefix}
117               neutron::plugins::ml2::cisco::nexus::svi_round_robin: {get_input: NexusSviRoundRobin}
118               neutron::plugins::ml2::cisco::nexus::provider_vlan_name_prefix: {get_input: NexusProviderVlanNamePrefix}
119               neutron::plugins::ml2::cisco::nexus::persistent_switch_config: {get_input: NexusPersistentSwitchConfig}
120               neutron::plugins::ml2::cisco::nexus::switch_heartbeat_time: {get_input: NexusSwitchHeartbeatTime}
121               neutron::plugins::ml2::cisco::nexus::switch_replay_count: {get_input: NexusSwitchReplayCount}
122               neutron::plugins::ml2::cisco::nexus::provider_vlan_auto_create: {get_input: NexusProviderVlanAutoCreate}
123               neutron::plugins::ml2::cisco::nexus::provider_vlan_auto_trunk: {get_input: NexusProviderVlanAutoTrunk}
124               neutron::plugins::ml2::cisco::nexus::vxlan_global_config: {get_input: NexusVxlanGlobalConfig}
125               neutron::plugins::ml2::cisco::nexus::host_key_checks: {get_input: NexusHostKeyChecks}
126               neutron::plugins::ml2::cisco::type_nexus_vxlan::vni_ranges: {get_input: NexusVxlanVniRanges}
127               neutron::plugins::ml2::cisco::type_nexus_vxlan::mcast_ranges: {get_input: NexusVxlanMcastRanges}
128
129   NetworkCiscoDeployment:
130     type: OS::Heat::StructuredDeployments
131     properties:
132       name: NetworkCiscoDeployment
133       config: {get_resource: NetworkCiscoConfig}
134       servers:  {get_param: [servers, Controller]}
135       input_values:
136         UCSM_ip: {get_param: NetworkUCSMIp}
137         UCSM_username: {get_param: NetworkUCSMUsername}
138         UCSM_password: {get_param: NetworkUCSMPassword}
139         UCSM_host_list: {get_attr: [MappingToUCSMDeploymentsController, deploy_stdout]}
140         UCSMSupportedPciDevs: {get_param: NetworkUCSMSupportedPciDevs}
141         NexusConfig: {get_attr: [MappingToNexusDeploymentsController, deploy_stdout]}
142         NexusManagedPhysicalNetwork: {get_param: NetworkNexusManagedPhysicalNetwork}
143         NexusVlanNamePrefix: {get_param: NetworkNexusVlanNamePrefix}
144         NexusSviRoundRobin: {get_param: NetworkNexusSviRoundRobin}
145         NexusProviderVlanNamePrefix: {get_param: NetworkNexusProviderVlanNamePrefix}
146         NexusPersistentSwitchConfig: {get_param: NetworkNexusPersistentSwitchConfig}
147         NexusSwitchHeartbeatTime: {get_param: NetworkNexusSwitchHeartbeatTime}
148         NexusSwitchReplayCount: {get_param: NetworkNexusSwitchReplayCount}
149         NexusProviderVlanAutoCreate: {get_param: NetworkNexusProviderVlanAutoCreate}
150         NexusProviderVlanAutoTrunk: {get_param: NetworkNexusProviderVlanAutoTrunk}
151         NexusVxlanGlobalConfig: {get_param: NetworkNexusVxlanGlobalConfig}
152         NexusHostKeyChecks: {get_param: NetworkNexusHostKeyChecks}
153         NexusVxlanVniRanges: {get_param: NetworkNexusVxlanVniRanges}
154         NexusVxlanMcastRanges: {get_param: NetworkNexusVxlanMcastRanges}
155
156   # Now we collect the Mac->Hostname mappings for all nodes, which enables
157   # calculation of the neutron::plugins::ml2::cisco::nexus::nexus_config data
158   CollectMacConfig:
159     type: OS::Heat::SoftwareConfig
160     properties:
161       group: script
162       config: |
163         #!/bin/sh
164         MACS=$(ifconfig  | grep ether | awk '{print $2}' | tr "\n" " ")
165         HOST_FQDN=$(hostname -f)
166         if [ -z "$HOST_FQDN" ]; then
167           HOSTNAME=$(hostname -s)
168           # hardcoding the domain name to avoid DNS lookup dependency
169           # same type of hardcoding appears elsewhere
170           # --ie. controller-puppet.yaml
171           # FIXME_HOSTNAME_DOMAIN_HARDCODE
172           echo "$HOSTNAME.localdomain $MACS"
173         else
174           echo "$HOST_FQDN $MACS"
175         fi
176
177   CollectMacDeploymentsController:
178     type: OS::Heat::SoftwareDeployments
179     properties:
180       name: CollectMacDeploymentsController
181       servers:  {get_param: [servers, Controller]}
182       config: {get_resource: CollectMacConfig}
183       actions: ['CREATE'] # Only do this on CREATE
184
185   CollectMacDeploymentsCompute:
186     type: OS::Heat::SoftwareDeployments
187     properties:
188       name: CollectMacDeploymentsCompute
189       servers:  {get_param: [servers, Compute]}
190       config: {get_resource: CollectMacConfig}
191       actions: ['CREATE'] # Only do this on CREATE
192
193   CollectMacDeploymentsBlockStorage:
194     type: OS::Heat::SoftwareDeployments
195     properties:
196       name: CollectMacDeploymentsBlockStorage
197       servers:  {get_param: [servers, BlockStorage]}
198       config: {get_resource: CollectMacConfig}
199       actions: ['CREATE'] # Only do this on CREATE
200
201   CollectMacDeploymentsObjectStorage:
202     type: OS::Heat::SoftwareDeployments
203     properties:
204       name: CollectMacDeploymentsObjectStorage
205       servers:  {get_param: [servers, ObjectStorage]}
206       config: {get_resource: CollectMacConfig}
207       actions: ['CREATE'] # Only do this on CREATE
208
209   CollectMacDeploymentsCephStorage:
210     type: OS::Heat::SoftwareDeployments
211     properties:
212       name: CollectMacDeploymentsCephStorage
213       servers:  {get_param: [servers, CephStorage]}
214       config: {get_resource: CollectMacConfig}
215       actions: ['CREATE'] # Only do this on CREATE
216
217   # Now we calculate the additional nexus config based on the mappings
218   MappingToNexusConfig:
219     type: OS::Heat::SoftwareConfig
220     properties:
221       group: script
222       inputs:
223       - name: controller_mappings
224       - name: compute_mappings
225       - name: blockstorage_mappings
226       - name: objectstorage_mappings
227       - name: cephstorage_mappings
228       - name: nexus_config
229       config: |
230         #!/bin/python
231         import ast
232         import json
233         import os
234         from copy import deepcopy
235
236         mappings = ['controller_mappings',
237                     'compute_mappings',
238                     'blockstorage_mappings',
239                     'objectstorage_mappings',
240                     'cephstorage_mappings',
241                     'nexus_config']
242         mapdict_list = []
243         nexus = {}
244         for map_name in mappings:
245           f_name = '/root/' + map_name
246           map_data = os.getenv(map_name, "Nada")
247           with os.fdopen(os.open(f_name,
248                                  os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644),
249                          'w') as f:
250             f.write(map_data)
251           if map_data is not "Nada":
252             if map_name is not 'nexus_config':
253               mapdict_list.append(ast.literal_eval(map_data))
254             else:
255               nexus = ast.literal_eval(map_data)
256
257         mac2host = {}
258         for mapdict in mapdict_list:
259           for (listnum, host2mac_list) in mapdict.iteritems():
260             vals = host2mac_list.rstrip().split()
261             for mac in vals[1:]:
262               mac2host[mac.lower()] = vals[0]
263
264         with os.fdopen(os.open('/root/mac2host',
265                                os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o644),
266                        'w') as f:
267           f.write(str(mac2host))
268
269         # now we have mac to host, map host to switchport in hieradata
270         # nexus = ast.literal_eval(os.getenv('nexus_config', None))
271         nexus_cp = deepcopy(nexus)
272         for nexus_switch in nexus:
273           for (mac,swport) in nexus[nexus_switch]['servers'].iteritems():
274             lmac=mac.lower()
275             if lmac in mac2host:
276               hostname = mac2host[lmac]
277               # for puppet we need a unique title even at the 2nd key level
278               serv_key = nexus_switch + "::" + hostname
279               if serv_key in nexus_cp[nexus_switch]['servers']:
280                 nexus_cp[nexus_switch]['servers'][serv_key]['ports'] += ',' + swport['ports']
281               else:
282                 nexus_cp[nexus_switch]['servers'][serv_key] = swport
283                 nexus_cp[nexus_switch]['servers'][serv_key]['hostname'] = hostname
284             del nexus_cp[nexus_switch]['servers'][mac]
285         # Note this echo means you can view the data via heat deployment-show
286         print json.dumps(nexus_cp)
287
288   MappingToNexusDeploymentsController:
289     type: OS::Heat::SoftwareDeployment
290     properties:
291       name: MappingToNexusDeploymentsController
292       server:  {get_param: [servers, Controller, '0']}
293       config: {get_resource: MappingToNexusConfig}
294       input_values:
295         # FIXME(shardy): It'd be more convenient if we could join these
296         # items together but because the returned format is a map (not a list)
297         # we can't use list_join or str_replace.  Possible Heat TODO.
298         controller_mappings: {get_attr: [CollectMacDeploymentsController, deploy_stdouts]}
299         compute_mappings: {get_attr: [CollectMacDeploymentsCompute, deploy_stdouts]}
300         blockstorage_mappings: {get_attr: [CollectMacDeploymentsBlockStorage, deploy_stdouts]}
301         objectstorage_mappings: {get_attr: [CollectMacDeploymentsObjectStorage, deploy_stdouts]}
302         cephstorage_mappings: {get_attr: [CollectMacDeploymentsCephStorage, deploy_stdouts]}
303         nexus_config: {get_param: NetworkNexusConfig}
304       actions: ['CREATE'] # Only do this on CREATE
305
306   MappingToUCSMConfig:
307     type: OS::Heat::SoftwareConfig
308     properties:
309       group: script
310       inputs:
311        - name: ucsm_config
312       config: |
313         #!/bin/python
314         import ast
315         import os
316         with open('/root/mac2host', 'r') as f:
317           s=f.read()
318           m2h=ast.literal_eval(s)
319         ucs_config = os.getenv('ucsm_config', "Nada")
320         ucs_data = []
321         lines = ucs_config.split(',')
322         for line in lines:
323           entry=line.rsplit(":",1)
324           mac = entry[0].lower().strip()
325           if mac in m2h:
326             ucs_data.append(m2h[mac] + ":" + entry[1])
327
328         print ", ".join(ucs_data)
329
330
331   MappingToUCSMDeploymentsController:
332     type: OS::Heat::SoftwareDeployment
333     depends_on: MappingToNexusDeploymentsController
334     properties:
335       name: MappingToUCSMDeploymentsController
336       server:  {get_param: [servers, Controller, '0']}
337       config: {get_resource: MappingToUCSMConfig}
338       input_values:
339         ucsm_config: {get_param: NetworkUCSMHostList}
340       actions: ['CREATE'] # Only do this on CREATE