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