def test_create_correctly_excludes_blocks(self): pool = IPPool(network='192.168.1.1/32') db.session.add(pool) db.session.commit() expected_block_ips = {u'192.168.2.1', u'192.168.2.3', u'192.168.2.4', u'192.168.2.5', u'192.168.2.7'} block = '192.168.2.1,192.168.2.3-192.168.2.5,192.168.2.7' data = { 'network': u'192.168.2.0/24', 'autoblock': block, 'node': self.node.hostname, } pool = ippool.IpAddrPool().create(data) self.assertEqual({ 'network': pool.network, 'blocked_list': pool.get_blocked_set() }, { 'network': data['network'], 'blocked_list': expected_block_ips, }) invalid_block = 'qwerty' data = { 'network': '192.168.4.0/24', 'autoblock': invalid_block } with self.assertRaises(APIError): ippool.IpAddrPool().create(data) networks = db.session.query(IPPool).order_by(IPPool.network) self.assertEqual( [item.network for item in networks], [u'192.168.1.1/32', u'192.168.2.0/24'], )
def test_suspend(self, _run): """AC-1608 In case of unsuspend, return all public IPs""" # Disable as otherwise test breaks. Was created before introducing # this feature current_app.config['FIXED_IP_POOLS'] = False user = self.user url = self.item_url(self.user.id) ippool = IPPool(network='192.168.1.252/30') ippool.block_ip([u'192.168.1.252', u'192.168.1.255']) ippool.save() min_pod = { 'restartPolicy': 'Always', 'kube_type': 0, 'containers': [{ 'image': 'nginx', 'name': 'fk8i0gai', 'args': ['nginx', '-g', 'daemon off;'], 'ports': [{ 'protocol': 'tcp', 'isPublic': True, 'containerPort': 80 }], }] } # pod-1 res = PodCollection(user).add(dict(min_pod, name='pod-1'), skip_check=False) pod_1 = Pod.query.get(res['id']) pod_1.with_ip_conf = { 'public_ip': res['public_ip'], 'containers': [{ 'ports': [{ 'isPublic': True }] }], } pod_1.without_ip_conf = { 'public_ip_before_freed': res['public_ip'], 'containers': [{ 'ports': [{ 'isPublic_before_freed': True }] }], } # pod-2 res = PodCollection(user).add(dict(min_pod, name='pod-2'), skip_check=False) pod_2 = Pod.query.get(res['id']) pod_2.with_ip_conf = { 'public_ip': res['public_ip'], 'containers': [{ 'ports': [{ 'isPublic': True }] }], } pod_2.without_ip_conf = { 'public_ip_before_freed': res['public_ip'], 'containers': [{ 'ports': [{ 'isPublic_before_freed': True }] }], } # helpers def _has_public_ip(pod): podip = PodIP.query.filter_by(pod_id=pod.id).first() conf = pod.get_dbconfig() port = conf['containers'][0]['ports'][0] if podip is None: self.assertFalse(port.get('isPublic')) self.assertFalse(conf.get('public_ip')) self.assertTrue(port.get('isPublic_before_freed')) self.assertTrue(conf.get('public_ip_before_freed')) return False self.assertFalse(port.get('isPublic_before_freed')) self.assertFalse(conf.get('public_ip_before_freed')) self.assertTrue(port.get('isPublic')) self.assertEqual(conf.get('public_ip'), unicode(ip_address(podip.ip_address))) return True def _count_pods_with_public_ip(): return _has_public_ip(pod_1) + _has_public_ip(pod_2) # suspend user. Both ip must be freed self.assertEqual(_count_pods_with_public_ip(), 2, 'all pods must have public ip in the beginning') data = {'suspended': True} response = self.admin_open(url=url, method='PUT', json=data) self.assert200(response) self.assertEqual(_count_pods_with_public_ip(), 0, 'all pods must lose public ip') # unsuspend must be atomic, so if one pod cannot get public ip, # all won't ippool.block_ip(ippool.free_hosts(as_int=True)[0]) db.session.commit() data = {'suspended': False} response = self.admin_open(url=url, method='PUT', json=data) self.assertAPIError(response, 400, 'NoFreeIPs') self.assertEqual( _count_pods_with_public_ip(), 0, "operation must be atomic, so if one pod can't get " "public ip, all won't") # unblock ip in ippool to be able to unsuspend user ippool.unblock_ip(ippool.get_blocked_set(as_int=True).pop()) db.session.commit() data = {'suspended': False} response = self.admin_open(url=url, method='PUT', json=data) self.assert200(response) self.assertEqual(_count_pods_with_public_ip(), 2, 'all pods must get their ip back')
def test_update(self, remove_public_mock): """Test IpAddrPool.update method.""" network = u'192.168.2.0/24' with self.assertRaises(APIError): ippool.IpAddrPool().update(network, None) pool = IPPool(network='192.168.1.0/24') node = self.node db.session.add(pool) db.session.commit() block = '192.168.2.1,192.168.2.3-192.168.2.5,192.168.2.7' data = { 'network': network, 'autoblock': block, 'node': node.hostname, } ippool.IpAddrPool().create(data) pool = ippool.IpAddrPool().update(network, None) self.assertIsNotNone(pool) blocked_list1 = pool.get_blocked_set() self.assertEqual(pool.network, network) # add already blocked ip block_ip = u'192.168.2.1' params = {'block_ip': block_ip} with self.assertRaises(APIError): ippool.IpAddrPool().update(network, params) # block new ip block_ip1 = u'192.168.2.111' params = {'block_ip': block_ip1} blocked_list = ippool.IpAddrPool().update(network, params)\ .get_blocked_set() self.assertEqual( blocked_list, blocked_list1 | {block_ip1} ) # and one else block_ip2 = u'192.168.2.112' params = {'block_ip': block_ip2} blocked_list = ippool.IpAddrPool().update(network, params)\ .get_blocked_set() self.assertEqual( blocked_list, blocked_list1 | {block_ip1, block_ip2} ) unblock_ip = block_ip1 params = {'unblock_ip': unblock_ip} blocked_list = ippool.IpAddrPool().update(network, params)\ .get_blocked_set() self.assertEqual( blocked_list, blocked_list1 | {block_ip2} ) self.assertFalse(remove_public_mock.called) unbind_ip = '192.168.2.222' params = {'unbind_ip': unbind_ip} blocked_list = ippool.IpAddrPool().update(network, params)\ .get_blocked_set() self.assertEqual( blocked_list, blocked_list1 | {block_ip2} ) remove_public_mock.assert_called_once_with(ip=unbind_ip) pool = ippool.IpAddrPool().update(network, {'node': node.hostname}) self.assertEqual(pool.node, node)