@@ -32,8 +32,8 @@ index c59161daaf..22869c2fda 100644
32
32
VIF_TYPE_VIF = 'vif'
33
33
VIF_TYPE_UNBOUND = 'unbound'
34
34
+ VIF_TYPE_TRUNK_SUBPORT = 'trunk-subport'
35
-
36
-
35
+
36
+
37
37
# Constants for dictionary keys in the 'vif_details' field in the VIF
38
38
@@ -413,7 +414,7 @@ class VIF(Model):
39
39
qbh_params=None, qbg_params=None, active=False,
@@ -42,16 +42,16 @@ index c59161daaf..22869c2fda 100644
42
42
- **kwargs):
43
43
+ trunk_vifs=None, **kwargs):
44
44
super(VIF, self).__init__()
45
-
45
+
46
46
self['id'] = id
47
47
@@ -431,6 +432,7 @@ class VIF(Model):
48
48
self['profile'] = profile
49
49
self['preserve_on_delete'] = preserve_on_delete
50
50
self['delegate_create'] = delegate_create
51
51
+ self['trunk_vifs'] = trunk_vifs or []
52
-
52
+
53
53
self._set_meta(kwargs)
54
-
54
+
55
55
@@ -438,7 +440,8 @@ class VIF(Model):
56
56
keys = ['id', 'address', 'network', 'vnic_type',
57
57
'type', 'profile', 'details', 'devname',
@@ -60,12 +60,12 @@ index c59161daaf..22869c2fda 100644
60
60
+ 'active', 'preserve_on_delete', 'delegate_create',
61
61
+ 'trunk_vifs']
62
62
return all(self[k] == other[k] for k in keys)
63
-
63
+
64
64
def __ne__(self, other):
65
65
@@ -509,9 +512,17 @@ class VIF(Model):
66
66
phy_network = self['details'].get(VIF_DETAILS_PHYSICAL_NETWORK)
67
67
return phy_network
68
-
68
+
69
69
+ def add_trunk_vif(self, vif):
70
70
+ for _vif in self['trunk_vifs']:
71
71
+ if vif["id"] == _vif["id"]:
@@ -75,19 +75,19 @@ index c59161daaf..22869c2fda 100644
75
75
@classmethod
76
76
def hydrate(cls, vif):
77
77
vif = cls(**vif)
78
- + vif['trunk_vifs'] = [VIF.hydrate(** trunk_vif) for trunk_vif
78
+ + vif['trunk_vifs'] = [VIF.hydrate(trunk_vif) for trunk_vif
79
79
+ in vif.get('trunk_vifs', [])]
80
80
vif['network'] = Network.hydrate(vif['network'])
81
81
return vif
82
-
82
+
83
83
diff --git a/nova/network/neutron.py b/nova/network/neutron.py
84
84
index f24177de15..da2ae27555 100644
85
85
--- a/nova/network/neutron.py
86
86
+++ b/nova/network/neutron.py
87
87
@@ -3420,13 +3420,17 @@ class API:
88
88
preserve_on_delete = (current_neutron_port['id'] in
89
89
preexisting_port_ids)
90
-
90
+
91
91
+ vif_type = current_neutron_port.get('binding:vif_type')
92
92
+ if current_neutron_port.get('device_owner') == 'trunk:subport':
93
93
+ vif_type = network_model.VIF_TYPE_TRUNK_SUBPORT
@@ -106,7 +106,7 @@ index f24177de15..da2ae27555 100644
106
106
@@ -3455,6 +3459,20 @@ class API:
107
107
instance=instance
108
108
)
109
-
109
+
110
110
+ def _populate_trunk_info(self, vif, current_neutron_port, context, client):
111
111
+ trunk_details = current_neutron_port.get("trunk_details", {})
112
112
+ for subport in trunk_details.get("sub_ports", []):
@@ -153,7 +153,7 @@ index 1c604975b0..089d5f655c 100644
153
153
@@ -1081,6 +1081,38 @@ class TestNetworkMetadata(test.NoDBTestCase):
154
154
def test_get_network_metadata_json_ipv6_addr_mode_stateless(self):
155
155
self._test_get_network_metadata_json_ipv6_addr_mode('dhcpv6-stateless')
156
-
156
+
157
157
+ def test_get_network_metadata_json_trunks(self):
158
158
+
159
159
+ parent_vif = fake_network_cache_model.new_vif(
@@ -196,7 +196,7 @@ index fa794cb012..f974e84f47 100644
196
196
@@ -3345,6 +3345,85 @@ class TestAPI(TestAPIBase):
197
197
mock_get_physnet.assert_has_calls([
198
198
mock.call(self.context, mocked_client, 'net-id')] * 6)
199
-
199
+
200
200
+ @mock.patch.object(neutronapi.API, '_get_physnet_tunneled_info',
201
201
+ return_value=(None, False))
202
202
+ @mock.patch.object(neutronapi.API, '_get_preexisting_port_ids',
@@ -285,8 +285,8 @@ index 2bc78134a1..9bc3381027 100644
285
285
+++ b/nova/virt/netutils.py
286
286
@@ -165,6 +165,12 @@ def get_injected_network_template(network_info, template=None,
287
287
'libvirt_virt_type': libvirt_virt_type})
288
-
289
-
288
+
289
+
290
290
+ def get_vif_from_network_info(vif_id, network_info):
291
291
+ for vif in network_info:
292
292
+ if vif["id"] == vif_id:
@@ -295,11 +295,11 @@ index 2bc78134a1..9bc3381027 100644
295
295
+
296
296
def get_network_metadata(network_info):
297
297
"""Gets a more complete representation of the instance network information.
298
-
298
+
299
299
@@ -186,10 +192,26 @@ def get_network_metadata(network_info):
300
300
ifc_num = -1
301
301
net_num = -1
302
-
302
+
303
303
+ trunk_vifs = []
304
304
for vif in network_info:
305
305
+ for trunk_vif in vif['trunk_vifs']:
@@ -308,7 +308,7 @@ index 2bc78134a1..9bc3381027 100644
308
308
+ for vif in network_info + trunk_vifs:
309
309
if not vif.get('network') or not vif['network'].get('subnets'):
310
310
continue
311
-
311
+
312
312
+ parent_vif = None
313
313
+ if vif['type'] == 'trunk-subport':
314
314
+ vif_profile = vif.get("profile")
@@ -324,22 +324,22 @@ index 2bc78134a1..9bc3381027 100644
324
324
# NOTE(JoshNang) currently, only supports the first IPv4 and first
325
325
# IPv6 subnet on network, a limitation that also exists in the
326
326
@@ -202,7 +224,7 @@ def get_network_metadata(network_info):
327
-
327
+
328
328
# Get the VIF or physical NIC data
329
329
if subnet_v4 or subnet_v6:
330
330
- link = _get_eth_link(vif, ifc_num)
331
331
+ link = _get_eth_link(vif, ifc_num, parent_vif)
332
332
links.append(link)
333
-
333
+
334
334
# Add IPv4 and IPv6 networks if they exist
335
335
@@ -240,7 +262,7 @@ def get_ec2_ip_info(network_info):
336
336
return ip_info
337
-
338
-
337
+
338
+
339
339
- def _get_eth_link(vif, ifc_num):
340
340
+ def _get_eth_link(vif, ifc_num, parent_vif=None):
341
341
"""Get a VIF or physical NIC representation.
342
-
342
+
343
343
:param vif: Neutron VIF
344
344
@@ -256,6 +278,8 @@ def _get_eth_link(vif, ifc_num):
345
345
# Use 'phy' for physical links. Ethernet can be confusing
@@ -349,7 +349,7 @@ index 2bc78134a1..9bc3381027 100644
349
349
+ nic_type = 'vlan'
350
350
else:
351
351
nic_type = 'phy'
352
-
352
+
353
353
@@ -266,6 +290,15 @@ def _get_eth_link(vif, ifc_num):
354
354
'mtu': _get_link_mtu(vif),
355
355
'ethernet_mac_address': vif.get('address'),
@@ -364,8 +364,8 @@ index 2bc78134a1..9bc3381027 100644
364
364
+ })
365
365
+
366
366
return link
367
-
368
-
367
+
368
+
369
369
diff --git a/releasenotes/notes/vlan-aware-network-data-9b9b5e8c0fd191ba.yaml b/releasenotes/notes/vlan-aware-network-data-9b9b5e8c0fd191ba.yaml
370
370
new file mode 100644
371
371
index 0000000000..dfa4e9394d
@@ -377,5 +377,5 @@ index 0000000000..dfa4e9394d
377
377
+ - |
378
378
+ When deploing instance with trunks generate required
379
379
+ network_data for cloudinit.
380
- - -
380
+ - -
381
381
2.39.5 (Apple Git-154)
0 commit comments