Merge "Add update yaml backward compatibe with PublicVirtualIP on ctlplane"
[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: Time interval to check the state of the Nexus device
69     default: 0
70   NetworkNexusSwitchReplayCount:
71     type: number
72     description: Number of times to attempt config replay
73     default: 3
74   NetworkNexusProviderVlanAutoCreate:
75     type: boolean
76     description: A flag whether to manage the creation and removal of VLANs
77     default: true
78   NetworkNexusProviderVlanAutoTrunk:
79     type: boolean
80     description: A flag whether to manage the trunk ports on the Nexus
81     default: true
82   NetworkNexusVxlanGlobalConfig:
83     type: boolean
84     description: A flag whether to manage the VXLAN global settings
85     default: true
86   NetworkNexusHostKeyChecks:
87     type: boolean
88     description: enable strict host key checks when connecting to Nexus switches
89     default: false
90   NetworkNexusVxlanVniRanges:
91     type: string
92     description: VXLAN Network IDs that are available for tenant network
93     default: ''
94   NetworkNexusVxlanMcastRanges:
95     type: string
96     description: Multicast groups for the VXLAN interface.
97     default: ''
98
99
100 resources:
101   # First we lay down the base configuration via the static hieradata mappings
102   NetworkCiscoConfig:
103     type: OS::Heat::StructuredConfig
104     properties:
105       group: os-apply-config
106       config:
107         hiera:
108           datafiles:
109             neutron_cisco_data:
110               mapped_data:
111                 neutron::plugins::ml2::cisco::ucsm::ucsm_ip: {get_input: UCSM_ip}
112                 neutron::plugins::ml2::cisco::ucsm::ucsm_username: {get_input: UCSM_username}
113                 neutron::plugins::ml2::cisco::ucsm::ucsm_password: {get_input: UCSM_password}
114                 neutron::plugins::ml2::cisco::ucsm::ucsm_host_list: {get_input: UCSM_host_list}
115                 neutron::plugins::ml2::cisco::ucsm::supported_pci_devs:  {get_input: UCSMSupportedPciDevs}
116                 neutron::plugins::ml2::cisco::nexus::nexus_config: {get_input: NexusConfig}
117                 neutron::plugins::ml2::cisco::nexus::managed_physical_network: {get_input: NexusManagedPhysicalNetwork}
118                 neutron::plugins::ml2::cisco::nexus::vlan_name_prefix: {get_input: NexusVlanNamePrefix}
119                 neutron::plugins::ml2::cisco::nexus::svi_round_robin: {get_input: NexusSviRoundRobin}
120                 neutron::plugins::ml2::cisco::nexus::provider_vlan_name_prefix: {get_input: NexusProviderVlanNamePrefix}
121                 neutron::plugins::ml2::cisco::nexus::persistent_switch_config: {get_input: NexusPersistentSwitchConfig}
122                 neutron::plugins::ml2::cisco::nexus::switch_heartbeat_time: {get_input: NexusSwitchHeartbeatTime}
123                 neutron::plugins::ml2::cisco::nexus::switch_replay_count: {get_input: NexusSwitchReplayCount}
124                 neutron::plugins::ml2::cisco::nexus::provider_vlan_auto_create: {get_input: NexusProviderVlanAutoCreate}
125                 neutron::plugins::ml2::cisco::nexus::provider_vlan_auto_trunk: {get_input: NexusProviderVlanAutoTrunk}
126                 neutron::plugins::ml2::cisco::nexus::vxlan_global_config: {get_input: NexusVxlanGlobalConfig}
127                 neutron::plugins::ml2::cisco::nexus::host_key_checks: {get_input: NexusHostKeyChecks}
128                 neutron::plugins::ml2::cisco::type_nexus_vxlan::vni_ranges: {get_input: NexusVxlanVniRanges}
129                 neutron::plugins::ml2::cisco::type_nexus_vxlan::mcast_ranges: {get_input: NexusVxlanMcastRanges}
130
131   NetworkCiscoDeployment:
132     type: OS::Heat::StructuredDeployments
133     properties:
134       name: NetworkCiscoDeployment
135       config: {get_resource: NetworkCiscoConfig}
136       servers:  {get_param: controller_servers}
137       input_values:
138         UCSM_ip: {get_param: NetworkUCSMIp}
139         UCSM_username: {get_param: NetworkUCSMUsername}
140         UCSM_password: {get_param: NetworkUCSMPassword}
141         UCSM_host_list: {get_attr: [MappingToUCSMDeploymentsController, deploy_stdout]}
142         UCSMSupportedPciDevs: {get_param: NetworkUCSMSupportedPciDevs}
143         NexusConfig: {get_attr: [MappingToNexusDeploymentsController, deploy_stdout]}
144         NexusManagedPhysicalNetwork: {get_param: NetworkNexusManagedPhysicalNetwork}
145         NexusVlanNamePrefix: {get_param: NetworkNexusVlanNamePrefix}
146         NexusSviRoundRobin: {get_param: NetworkNexusSviRoundRobin}
147         NexusProviderVlanNamePrefix: {get_param: NetworkNexusProviderVlanNamePrefix}
148         NexusPersistentSwitchConfig: {get_param: NetworkNexusPersistentSwitchConfig}
149         NexusSwitchHeartbeatTime: {get_param: NetworkNexusSwitchHeartbeatTime}
150         NexusSwitchReplayCount: {get_param: NetworkNexusSwitchReplayCount}
151         NexusProviderVlanAutoCreate: {get_param: NetworkNexusProviderVlanAutoCreate}
152         NexusProviderVlanAutoTrunk: {get_param: NetworkNexusProviderVlanAutoTrunk}
153         NexusVxlanGlobalConfig: {get_param: NetworkNexusVxlanGlobalConfig}
154         NexusHostKeyChecks: {get_param: NetworkNexusHostKeyChecks}
155         NexusVxlanVniRanges: {get_param: NetworkNexusVxlanVniRanges}
156         NexusVxlanMcastRanges: {get_param: NetworkNexusVxlanMcastRanges}
157
158   # Now we collect the Mac->Hostname mappings for all nodes, which enables
159   # calculation of the neutron::plugins::ml2::cisco::nexus::nexus_config data
160   CollectMacConfig:
161     type: OS::Heat::SoftwareConfig
162     properties:
163       group: script
164       config: |
165         #!/bin/sh
166         MACS=$(ifconfig  | grep ether | awk '{print $2}' | tr "\n" " ")
167         HOST_FQDN=$(hostname -f)
168         if [ -z "$HOST_FQDN" ]; then
169           HOSTNAME=$(hostname -s)
170           # hardcoding the domain name to avoid DNS lookup dependency
171           # same type of hardcoding appears elsewhere
172           # --ie. controller-puppet.yaml
173           # FIXME_HOSTNAME_DOMAIN_HARDCODE
174           echo "$HOSTNAME.localdomain $MACS"
175         else
176           echo "$HOST_FQDN $MACS"
177         fi
178
179   CollectMacDeploymentsController:
180     type: OS::Heat::SoftwareDeployments
181     properties:
182       name: CollectMacDeploymentsController
183       servers:  {get_param: controller_servers}
184       config: {get_resource: CollectMacConfig}
185       actions: ['CREATE'] # Only do this on CREATE
186
187   CollectMacDeploymentsCompute:
188     type: OS::Heat::SoftwareDeployments
189     properties:
190       name: CollectMacDeploymentsCompute
191       servers:  {get_param: compute_servers}
192       config: {get_resource: CollectMacConfig}
193       actions: ['CREATE'] # Only do this on CREATE
194
195   CollectMacDeploymentsBlockStorage:
196     type: OS::Heat::SoftwareDeployments
197     properties:
198       name: CollectMacDeploymentsBlockStorage
199       servers:  {get_param: blockstorage_servers}
200       config: {get_resource: CollectMacConfig}
201       actions: ['CREATE'] # Only do this on CREATE
202
203   CollectMacDeploymentsObjectStorage:
204     type: OS::Heat::SoftwareDeployments
205     properties:
206       name: CollectMacDeploymentsObjectStorage
207       servers:  {get_param: objectstorage_servers}
208       config: {get_resource: CollectMacConfig}
209       actions: ['CREATE'] # Only do this on CREATE
210
211   CollectMacDeploymentsCephStorage:
212     type: OS::Heat::SoftwareDeployments
213     properties:
214       name: CollectMacDeploymentsCephStorage
215       servers:  {get_param: cephstorage_servers}
216       config: {get_resource: CollectMacConfig}
217       actions: ['CREATE'] # Only do this on CREATE
218
219   # Now we calculate the additional nexus config based on the mappings
220   MappingToNexusConfig:
221     type: OS::Heat::SoftwareConfig
222     properties:
223       group: script
224       inputs:
225       - name: controller_mappings
226       - name: compute_mappings
227       - name: blockstorage_mappings
228       - name: objectstorage_mappings
229       - name: cephstorage_mappings
230       - name: nexus_config
231       config: |
232         #!/bin/python
233         import ast
234         import json
235         import os
236         from copy import deepcopy
237
238         mappings = ['controller_mappings',
239                     'compute_mappings',
240                     'blockstorage_mappings',
241                     'objectstorage_mappings',
242                     'cephstorage_mappings',
243                     'nexus_config']
244         mapdict_list = []
245         nexus = {}
246         for map_name in mappings:
247           f_name = '/root/' + map_name
248           map_data = os.getenv(map_name, "Nada")
249           with open(f_name, 'a') 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 open('/root/mac2host', 'a') as f:
265           f.write(str(mac2host))
266
267         # now we have mac to host, map host to switchport in hieradata
268         # nexus = ast.literal_eval(os.getenv('nexus_config', None))
269         nexus_cp = deepcopy(nexus)
270         for nexus_switch in nexus:
271           for (mac,swport) in nexus[nexus_switch]['servers'].iteritems():
272             lmac=mac.lower()
273             if lmac in mac2host:
274               hostname = mac2host[lmac]
275               # for puppet we need a unique title even at the 2nd key level
276               serv_key = nexus_switch + "::" + hostname
277               if serv_key in nexus_cp[nexus_switch]['servers']:
278                 nexus_cp[nexus_switch]['servers'][serv_key]['ports'] += ',' + swport['ports']
279               else:
280                 nexus_cp[nexus_switch]['servers'][serv_key] = swport
281                 nexus_cp[nexus_switch]['servers'][serv_key]['hostname'] = hostname
282             del nexus_cp[nexus_switch]['servers'][mac]
283         # Note this echo means you can view the data via heat deployment-show
284         print json.dumps(nexus_cp)
285
286   MappingToNexusDeploymentsController:
287     type: OS::Heat::SoftwareDeployment
288     properties:
289       name: MappingToNexusDeploymentsController
290       server:  {get_param: [controller_servers, '0']}
291       config: {get_resource: MappingToNexusConfig}
292       input_values:
293         # FIXME(shardy): It'd be more convenient if we could join these
294         # items together but because the returned format is a map (not a list)
295         # we can't use list_join or str_replace.  Possible Heat TODO.
296         controller_mappings: {get_attr: [CollectMacDeploymentsController, deploy_stdouts]}
297         compute_mappings: {get_attr: [CollectMacDeploymentsCompute, deploy_stdouts]}
298         blockstorage_mappings: {get_attr: [CollectMacDeploymentsBlockStorage, deploy_stdouts]}
299         objectstorage_mappings: {get_attr: [CollectMacDeploymentsObjectStorage, deploy_stdouts]}
300         cephstorage_mappings: {get_attr: [CollectMacDeploymentsCephStorage, deploy_stdouts]}
301         nexus_config: {get_param: NetworkNexusConfig}
302       actions: ['CREATE'] # Only do this on CREATE
303
304   MappingToUCSMConfig:
305     type: OS::Heat::SoftwareConfig
306     properties:
307       group: script
308       inputs:
309        - name: ucsm_config
310       config: |
311         #!/bin/python
312         import ast
313         import os
314         with open('/root/mac2host', 'r') as f:
315           s=f.read()
316           m2h=ast.literal_eval(s)
317         ucs_config = os.getenv('ucsm_config', "Nada")
318         ucs_data = []
319         lines = ucs_config.split(',')
320         for line in lines:
321           entry=line.rsplit(":",1)
322           mac = entry[0].lower().strip()
323           if mac in m2h:
324             ucs_data.append(m2h[mac] + ":" + entry[1])
325
326         print ", ".join(ucs_data)
327
328
329   MappingToUCSMDeploymentsController:
330     type: OS::Heat::SoftwareDeployment
331     depends_on: MappingToNexusDeploymentsController
332     properties:
333       name: MappingToUCSMDeploymentsController
334       server:  {get_param: [controller_servers, '0']}
335       config: {get_resource: MappingToUCSMConfig}
336       input_values:
337         ucsm_config: {get_param: NetworkUCSMHostList}
338       actions: ['CREATE'] # Only do this on CREATE
339
340 outputs:
341   # The Deployment applying the hieradata outputs the derived config-id, which
342   # changes if the input_values change, so if the stdouts from
343   # NetworkCiscoDeployment change, we need to reapply puppet (which will
344   # happen if we return a different config_identifier)
345   config_identifier:
346     value: {get_attr: [NetworkCiscoDeployment, deploy_stdouts]}