41
40
# NOTE(vish): if you change these flags, make sure to change the
42
41
# flags in the corresponding section in nova-dhcpbridge
43
42
self.flags(connection_type='fake',
46
44
auth_driver='nova.auth.ldapdriver.FakeLdapDriver',
48
47
logging.getLogger().setLevel(logging.DEBUG)
49
48
self.manager = manager.AuthManager()
50
49
self.user = self.manager.create_user('netuser', 'netuser', 'netuser')
52
self.projects.append(self.manager.create_project('netuser',
51
self.network = utils.import_object(FLAGS.network_manager)
52
self.context = context.APIRequestContext(project=None, user=self.user)
56
54
name = 'project%s' % i
57
55
self.projects.append(self.manager.create_project(name,
60
vpn.NetworkData.create(self.projects[i].id)
61
self.service = service.VlanNetworkService()
58
# create the necessary network data for the project
59
self.network.set_network_host(self.context, self.projects[i].id)
60
instance_ref = db.instance_create(None,
61
{'mac_address': utils.generate_mac()})
62
self.instance_id = instance_ref['id']
63
instance_ref = db.instance_create(None,
64
{'mac_address': utils.generate_mac()})
65
self.instance2_id = instance_ref['id']
63
67
def tearDown(self): # pylint: disable-msg=C0103
64
68
super(NetworkTestCase, self).tearDown()
69
# TODO(termie): this should really be instantiating clean datastores
70
# in between runs, one failure kills all the tests
71
db.instance_destroy(None, self.instance_id)
72
db.instance_destroy(None, self.instance2_id)
65
73
for project in self.projects:
66
74
self.manager.delete_project(project)
67
75
self.manager.delete_user(self.user)
69
def test_public_network_allocation(self):
77
def _create_address(self, project_num, instance_id=None):
78
"""Create an address in given project num"""
79
if instance_id is None:
80
instance_id = self.instance_id
81
self.context.project = self.projects[project_num]
82
return self.network.allocate_fixed_ip(self.context, instance_id)
84
def test_public_network_association(self):
70
85
"""Makes sure that we can allocaate a public ip"""
86
# TODO(vish): better way of adding floating ips
71
87
pubnet = IPy.IP(flags.FLAGS.public_range)
72
address = self.service.allocate_elastic_ip(self.user.id,
74
self.assertTrue(IPy.IP(address) in pubnet)
88
address = str(pubnet[0])
90
db.floating_ip_get_by_address(None, address)
91
except exception.NotFound:
92
db.floating_ip_create(None, {'address': address,
94
float_addr = self.network.allocate_floating_ip(self.context,
96
fix_addr = self._create_address(0)
97
self.assertEqual(float_addr, str(pubnet[0]))
98
self.network.associate_floating_ip(self.context, float_addr, fix_addr)
99
address = db.instance_get_floating_address(None, self.instance_id)
100
self.assertEqual(address, float_addr)
101
self.network.disassociate_floating_ip(self.context, float_addr)
102
address = db.instance_get_floating_address(None, self.instance_id)
103
self.assertEqual(address, None)
104
self.network.deallocate_floating_ip(self.context, float_addr)
105
self.network.deallocate_fixed_ip(self.context, fix_addr)
76
107
def test_allocate_deallocate_fixed_ip(self):
77
108
"""Makes sure that we can allocate and deallocate a fixed ip"""
78
result = self.service.allocate_fixed_ip(
79
self.user.id, self.projects[0].id)
80
address = result['private_dns_name']
81
mac = result['mac_address']
82
net = model.get_project_network(self.projects[0].id, "default")
83
self.assertEqual(True, is_in_project(address, self.projects[0].id))
84
hostname = "test-host"
85
issue_ip(mac, address, hostname, net.bridge_name)
86
self.service.deallocate_fixed_ip(address)
109
address = self._create_address(0)
110
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
112
self.network.deallocate_fixed_ip(self.context, address)
88
114
# Doesn't go away until it's dhcp released
89
self.assertEqual(True, is_in_project(address, self.projects[0].id))
115
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
91
release_ip(mac, address, hostname, net.bridge_name)
92
self.assertEqual(False, is_in_project(address, self.projects[0].id))
118
self.assertFalse(is_allocated_in_project(address, self.projects[0].id))
94
120
def test_side_effects(self):
95
121
"""Ensures allocating and releasing has no side effects"""
96
hostname = "side-effect-host"
97
result = self.service.allocate_fixed_ip(self.user.id,
99
mac = result['mac_address']
100
address = result['private_dns_name']
101
result = self.service.allocate_fixed_ip(self.user,
103
secondmac = result['mac_address']
104
secondaddress = result['private_dns_name']
106
net = model.get_project_network(self.projects[0].id, "default")
107
secondnet = model.get_project_network(self.projects[1].id, "default")
109
self.assertEqual(True, is_in_project(address, self.projects[0].id))
110
self.assertEqual(True, is_in_project(secondaddress,
111
self.projects[1].id))
112
self.assertEqual(False, is_in_project(address, self.projects[1].id))
122
address = self._create_address(0)
123
address2 = self._create_address(1, self.instance2_id)
125
self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
126
self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
127
self.assertFalse(is_allocated_in_project(address, self.projects[1].id))
114
129
# Addresses are allocated before they're issued
115
issue_ip(mac, address, hostname, net.bridge_name)
116
issue_ip(secondmac, secondaddress, hostname, secondnet.bridge_name)
118
self.service.deallocate_fixed_ip(address)
119
release_ip(mac, address, hostname, net.bridge_name)
120
self.assertEqual(False, is_in_project(address, self.projects[0].id))
133
self.network.deallocate_fixed_ip(self.context, address)
135
self.assertFalse(is_allocated_in_project(address, self.projects[0].id))
122
137
# First address release shouldn't affect the second
123
self.assertEqual(True, is_in_project(secondaddress,
124
self.projects[1].id))
138
self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
126
self.service.deallocate_fixed_ip(secondaddress)
127
release_ip(secondmac, secondaddress, hostname, secondnet.bridge_name)
128
self.assertEqual(False, is_in_project(secondaddress,
129
self.projects[1].id))
140
self.network.deallocate_fixed_ip(self.context, address2)
142
self.assertFalse(is_allocated_in_project(address2,
143
self.projects[1].id))
131
145
def test_subnet_edge(self):
132
146
"""Makes sure that private ips don't overlap"""
133
result = self.service.allocate_fixed_ip(self.user.id,
135
firstaddress = result['private_dns_name']
136
hostname = "toomany-hosts"
147
first = self._create_address(0)
137
150
for i in range(1, 5):
138
project_id = self.projects[i].id
139
result = self.service.allocate_fixed_ip(
140
self.user, project_id)
141
mac = result['mac_address']
142
address = result['private_dns_name']
143
result = self.service.allocate_fixed_ip(
144
self.user, project_id)
145
mac2 = result['mac_address']
146
address2 = result['private_dns_name']
147
result = self.service.allocate_fixed_ip(
148
self.user, project_id)
149
mac3 = result['mac_address']
150
address3 = result['private_dns_name']
151
net = model.get_project_network(project_id, "default")
152
issue_ip(mac, address, hostname, net.bridge_name)
153
issue_ip(mac2, address2, hostname, net.bridge_name)
154
issue_ip(mac3, address3, hostname, net.bridge_name)
155
self.assertEqual(False, is_in_project(address,
156
self.projects[0].id))
157
self.assertEqual(False, is_in_project(address2,
158
self.projects[0].id))
159
self.assertEqual(False, is_in_project(address3,
160
self.projects[0].id))
161
self.service.deallocate_fixed_ip(address)
162
self.service.deallocate_fixed_ip(address2)
163
self.service.deallocate_fixed_ip(address3)
164
release_ip(mac, address, hostname, net.bridge_name)
165
release_ip(mac2, address2, hostname, net.bridge_name)
166
release_ip(mac3, address3, hostname, net.bridge_name)
167
net = model.get_project_network(self.projects[0].id, "default")
168
self.service.deallocate_fixed_ip(firstaddress)
151
mac = utils.generate_mac()
152
instance_ref = db.instance_create(None,
153
{'mac_address': mac})
154
instance_ids.append(instance_ref['id'])
155
address = self._create_address(i, instance_ref['id'])
156
mac = utils.generate_mac()
157
instance_ref = db.instance_create(None,
158
{'mac_address': mac})
159
instance_ids.append(instance_ref['id'])
160
address2 = self._create_address(i, instance_ref['id'])
161
mac = utils.generate_mac()
162
instance_ref = db.instance_create(None,
163
{'mac_address': mac})
164
instance_ids.append(instance_ref['id'])
165
address3 = self._create_address(i, instance_ref['id'])
169
self.assertFalse(is_allocated_in_project(address,
170
self.projects[0].id))
171
self.assertFalse(is_allocated_in_project(address2,
172
self.projects[0].id))
173
self.assertFalse(is_allocated_in_project(address3,
174
self.projects[0].id))
175
self.network.deallocate_fixed_ip(self.context, address)
176
self.network.deallocate_fixed_ip(self.context, address2)
177
self.network.deallocate_fixed_ip(self.context, address3)
181
for instance_id in instance_ids:
182
db.instance_destroy(None, instance_id)
184
self.network.deallocate_fixed_ip(self.context, first)
170
186
def test_vpn_ip_and_port_looks_valid(self):
171
187
"""Ensure the vpn ip and port are reasonable"""
172
188
self.assert_(self.projects[0].vpn_ip)
173
self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start_port)
174
self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_end_port)
189
self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start)
190
self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_start +
176
def test_too_many_vpns(self):
177
"""Ensure error is raised if we run out of vpn ports"""
179
for i in xrange(vpn.NetworkData.num_ports_for_ip(FLAGS.vpn_ip)):
180
vpns.append(vpn.NetworkData.create("vpnuser%s" % i))
181
self.assertRaises(vpn.NoMorePorts, vpn.NetworkData.create, "boom")
182
for network_datum in vpns:
183
network_datum.destroy()
193
def test_too_many_networks(self):
194
"""Ensure error is raised if we run out of networks"""
196
networks_left = FLAGS.num_networks - db.network_count(None)
197
for i in range(networks_left):
198
project = self.manager.create_project('many%s' % i, self.user)
199
projects.append(project)
200
self.assertRaises(db.NoMoreNetworks,
201
self.manager.create_project,
204
for project in projects:
205
self.manager.delete_project(project)
185
207
def test_ips_are_reused(self):
186
208
"""Makes sure that ip addresses that are deallocated get reused"""
187
net = model.get_project_network(self.projects[0].id, "default")
189
hostname = "reuse-host"
192
num_available_ips = net.num_available_ips
193
for i in range(num_available_ips - 1):
194
result = self.service.allocate_fixed_ip(self.user.id,
196
macs[i] = result['mac_address']
197
addresses[i] = result['private_dns_name']
198
issue_ip(macs[i], addresses[i], hostname, net.bridge_name)
200
result = self.service.allocate_fixed_ip(self.user.id,
202
mac = result['mac_address']
203
address = result['private_dns_name']
205
issue_ip(mac, address, hostname, net.bridge_name)
206
self.service.deallocate_fixed_ip(address)
207
release_ip(mac, address, hostname, net.bridge_name)
209
result = self.service.allocate_fixed_ip(
210
self.user, self.projects[0].id)
211
secondmac = result['mac_address']
212
secondaddress = result['private_dns_name']
213
self.assertEqual(address, secondaddress)
214
issue_ip(secondmac, secondaddress, hostname, net.bridge_name)
215
self.service.deallocate_fixed_ip(secondaddress)
216
release_ip(secondmac, secondaddress, hostname, net.bridge_name)
218
for i in range(len(addresses)):
219
self.service.deallocate_fixed_ip(addresses[i])
220
release_ip(macs[i], addresses[i], hostname, net.bridge_name)
209
address = self._create_address(0)
211
self.network.deallocate_fixed_ip(self.context, address)
214
address2 = self._create_address(0)
215
self.assertEqual(address, address2)
216
self.network.deallocate_fixed_ip(self.context, address2)
222
218
def test_available_ips(self):
223
219
"""Make sure the number of available ips for the network is correct
230
226
There are ips reserved at the bottom and top of the range.
231
227
services (network, gateway, CloudPipe, broadcast)
233
net = model.get_project_network(self.projects[0].id, "default")
234
num_preallocated_ips = len(net.assigned)
229
network = db.project_get_network(None, self.projects[0].id)
235
230
net_size = flags.FLAGS.network_size
236
num_available_ips = net_size - (net.num_bottom_reserved_ips +
237
num_preallocated_ips +
238
net.num_top_reserved_ips)
239
self.assertEqual(num_available_ips, net.num_available_ips)
231
total_ips = (db.network_count_available_ips(None, network['id']) +
232
db.network_count_reserved_ips(None, network['id']) +
233
db.network_count_allocated_ips(None, network['id']))
234
self.assertEqual(total_ips, net_size)
241
236
def test_too_many_addresses(self):
242
237
"""Test for a NoMoreAddresses exception when all fixed ips are used.
244
net = model.get_project_network(self.projects[0].id, "default")
246
hostname = "toomany-hosts"
249
num_available_ips = net.num_available_ips
250
for i in range(num_available_ips):
251
result = self.service.allocate_fixed_ip(self.user.id,
253
macs[i] = result['mac_address']
254
addresses[i] = result['private_dns_name']
255
issue_ip(macs[i], addresses[i], hostname, net.bridge_name)
257
self.assertEqual(net.num_available_ips, 0)
258
self.assertRaises(NoMoreAddresses, self.service.allocate_fixed_ip,
259
self.user.id, self.projects[0].id)
261
for i in range(len(addresses)):
262
self.service.deallocate_fixed_ip(addresses[i])
263
release_ip(macs[i], addresses[i], hostname, net.bridge_name)
264
self.assertEqual(net.num_available_ips, num_available_ips)
267
def is_in_project(address, project_id):
239
network = db.project_get_network(None, self.projects[0].id)
240
num_available_ips = db.network_count_available_ips(None,
244
for i in range(num_available_ips):
245
mac = utils.generate_mac()
246
instance_ref = db.instance_create(None,
247
{'mac_address': mac})
248
instance_ids.append(instance_ref['id'])
249
address = self._create_address(0, instance_ref['id'])
250
addresses.append(address)
253
self.assertEqual(db.network_count_available_ips(None,
255
self.assertRaises(db.NoMoreAddresses,
256
self.network.allocate_fixed_ip,
260
for i in range(num_available_ips):
261
self.network.deallocate_fixed_ip(self.context, addresses[i])
262
release_ip(addresses[i])
263
db.instance_destroy(None, instance_ids[i])
264
self.assertEqual(db.network_count_available_ips(None,
269
def is_allocated_in_project(address, project_id):
268
270
"""Returns true if address is in specified project"""
269
return address in model.get_project_network(project_id).assigned
271
project_net = db.project_get_network(None, project_id)
272
network = db.fixed_ip_get_network(None, address)
273
instance = db.fixed_ip_get_instance(None, address)
274
# instance exists until release
275
return instance is not None and network['id'] == project_net['id']
272
278
def binpath(script):