-
Notifications
You must be signed in to change notification settings - Fork 6
/
neutron-packet-flow.yml
328 lines (273 loc) · 14 KB
/
neutron-packet-flow.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# Playbook to trace packet flow of an instance
# Usage: Inspect traffic along packet route for an instance
# ansible-playbook neutron-packet-flow.yml -i hosts -e nova_instance=<uuid>
# View output at results/neutron-packet-flow-<uuid>.log
#
# To skip the debug flag check:
# ansible-playbook nova-trace-logs.yml -i hosts -e nova_instance=<uuid> -e force_debug_logs=false
# NOTE: You won't see full details of the instance without debug logs on. But you have the option to check first without enabling them...
- hosts: localhost
gather_facts: false
tasks:
- name: Fail if nova_instance not set
fail: msg="You must set a nova_instance variable to execute this playbook"
when: "nova_instance is undefined"
changed_when: no
- hosts: controller
name: Controller Checks
remote_user: "{{ remote_user }}"
become: "{{ become }}"
tags:
- controller
vars:
os_cli_opts: "--os-username={{ os_admin_username }} --os-password={{ os_admin_password }} --os-auth-url={{ os_auth_url }} --os-project-name={{ os_admin_project_name}}"
tasks:
- name: Controller | Find hypervisor the instance is on
shell: openstack {{ os_cli_opts }} server show {{ nova_instance }} --column OS-EXT-SRV-ATTR:hypervisor_hostname --format=value
register: nova_hypervisor
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Controller | hypervisor
debug:
var: nova_hypervisor.stdout
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Controller | Set hypervisor fact
set_fact:
nova_hypervisor: "{{ nova_hypervisor.stdout }}"
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: hostvars[inventory_hostname].nova_hypervisor
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- hosts: compute
name: Compute Checks
remote_user: "{{ remote_user }}"
become: "{{ become }}"
tags:
- compute
vars:
os_cli_opts: "--os-username={{ os_admin_username }} --os-password={{ os_admin_password }} --os-auth-url={{ os_auth_url }} --os-project-name={{ os_admin_project_name}}"
tasks:
- debug:
var: hostvars[groups['controller'][0]].nova_hypervisor
verbosity: 1
- name: Compute | Collect Neutron port id
command: neutron {{ os_cli_opts }} port-list --device_id={{ nova_instance }} --format value --column id
register: port_id
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Set short port id fact
set_fact:
short_port_id: "{{ port_id.stdout.split('-').0 + '-' + port_id.stdout.split('-').1.0 + port_id.stdout.split('-').1.1 }}"
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: short_port_id
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Install tcpdump
yum:
name: tcpdump
state: present
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect tap interface
command: timeout 5s tcpdump -eni tap{{ short_port_id }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_tap
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_tap.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect qbr interface
command: timeout 5s tcpdump -eni qbr{{ short_port_id }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_qbr
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_qbr.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect qvb interface
command: timeout 5s tcpdump -eni qvb{{ short_port_id }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_qvb
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_qvb.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect qvo interface
command: timeout 5s tcpdump -eni qvo{{ short_port_id }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_qvo
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_qvo.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect vxlan interface
command: timeout 5s tcpdump -eni vxlan_sys_4789 port bootpc or port bootps
ignore_errors: true
register: tcpdump_vxlan
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_vxlan.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect tunnel interface
command: timeout 5s tcpdump -eni {{ tunnel_interface }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_tunnel
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_tunnel.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- name: Compute | Inspect packet flows
shell: for i in {1..10}; do ovs-ofctl dump-flows br-tun | head -n 2; sleep 1; done
ignore_errors: true
register: tcpdump_flows
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- debug:
var: tcpdump_flows.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].nova_hypervisor }}"
- hosts: network
name: Network Checks
remote_user: "{{ remote_user }}"
become: "{{ become }}"
tags:
- network
vars:
os_cli_opts: "--os-username={{ os_admin_username }} --os-password={{ os_admin_password }} --os-auth-url={{ os_auth_url }} --os-project-name={{ os_admin_project_name}}"
tasks:
- name: Networker | Install tcpdump
yum:
name: tcpdump
state: present
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Inspect packet flows
shell: for i in {1..10}; do ovs-ofctl dump-flows br-tun | head -n 2; sleep 1; done
ignore_errors: true
register: tcpdump_flows
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: tcpdump_flows.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Inspect tunnel interface
command: timeout 5s tcpdump -eni {{ tunnel_interface }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_tunnel
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: tcpdump_tunnel.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Inspect vxlan interface
command: timeout 5s tcpdump -eni vxlan_sys_4789 port bootpc or port bootps
ignore_errors: true
register: tcpdump_vxlan
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: tcpdump_vxlan.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Find instance project id
command: openstack {{ os_cli_opts }} server show {{ nova_instance }} --column project_id --format value
register: project_id
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Gather routers
command: openstack {{ os_cli_opts}} router list -c ID -f value
register: router_list
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Gather router details
command: openstack {{ os_cli_opts}} router show {{ item }}
with_items: "{{ router_list.stdout_lines }}"
register: router_show
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: router_show
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Find router for instance project
set_fact:
router: "{{ item.item }}"
when:
- "{{ project_id.stdout in item.stdout }}"
- "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
with_items: "{{ router_show.results }}"
- debug:
var: router
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Gather dhcp ports
command: openstack {{ os_cli_opts}} port list --device-owner network:dhcp --column ID --format value
register: dhcp_list
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: dhcp_list.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Gather router details
command: openstack {{ os_cli_opts}} port show {{ item }}
with_items: "{{ dhcp_list.stdout_lines }}"
register: dhcp_show
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: dhcp_show
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Find DHCP ID for instance project
set_fact:
dhcp_port_id: "{{ item.item }}"
when:
- "{{ project_id.stdout in item.stdout }}"
- "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
with_items: "{{ dhcp_show.results }}"
- name: Networker | Find Network ID for DHCP
command: openstack {{ os_cli_opts }} port show {{ dhcp_port_id }} --column network_id --format value
register: dhcp_network_id
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: dhcp_network_id.stdout
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Set DHCP ID
set_fact:
dhcp: "{{ dhcp_network_id.stdout }}"
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Test router namespace
command: ip netns exec qrouter-{{ router }} ip a
register: router_namespace
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: router_namespace.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Test DHCP namespace
command: ip netns exec qdhcp-{{ dhcp }} ip a
register: dhcp_namespace
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: dhcp_namespace.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Set short DHCP port id fact
set_fact:
short_dhcp_port_id: "{{ dhcp_port_id.split('-').0 + '-' + dhcp_port_id.split('-').1.0 + dhcp_port_id.split('-').1.1 }}"
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- name: Networker | Inspect tap interface in network namespace
command: ip netns exec qdhcp-{{ dhcp }} timeout 5s tcpdump -leni tap{{ short_dhcp_port_id }} port bootpc or port bootps
ignore_errors: true
register: tcpdump_ns_tap
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- debug:
var: tcpdump_ns_tap.stdout_lines
verbosity: 1
when: "{{ hostvars[inventory_hostname].ansible_fqdn == hostvars[groups['controller'][0]].ansible_fqdn }}"
- hosts: localhost
name: Generating report
tags:
- report
tasks:
- local_action: template src=templates/neutron-packet-flow.log.j2 dest={{result_dir}}/neutron-packet-flow-{{nova_instance}}.log