def test_ensure_legal_operations(): """Test to ensure that ensure_legal_operations works as expected""" # create a project and a network api.project_create('anvil-nextgen') network_create_simple('hammernet', 'anvil-nextgen') network_create_simple('pineapple', 'anvil-nextgen') # register a switch of type dellnos9 and add a port to it api.switch_register('s3048', type=SWITCH_TYPE, username="******", password="******", hostname="switchname", interface_type="GigabitEthernet") api.switch_register_port('s3048', '1/3') switch = api.get_or_404(model.Switch, 's3048') # register a ndoe and a nic api.node_register( node='compute-01', obmd={ 'uri': 'http://obmd.example.com', 'admin_token': 'secret', }, ) api.project_connect_node('anvil-nextgen', 'compute-01') api.node_register_nic('compute-01', 'eth0', 'DE:AD:BE:EF:20:14') nic = api.get_or_404(model.Nic, 'eth0') api.port_connect_nic('s3048', '1/3', 'compute-01', 'eth0') # connecting a trunked network wihtout having a native should fail. # call the method directly and test the API too. with pytest.raises(BlockedError): switch.ensure_legal_operation(nic, 'connect', 'vlan/1212') with pytest.raises(BlockedError): api.node_connect_network('compute-01', 'eth0', 'hammernet', 'vlan/40') # doing these operations in the correct order, that is native network first # and then trunked, should work. api.node_connect_network('compute-01', 'eth0', 'hammernet', 'vlan/native') mock_networking_action() api.node_connect_network('compute-01', 'eth0', 'pineapple', 'vlan/41') mock_networking_action() # removing these networks in the wrong order should not work. with pytest.raises(BlockedError): switch.ensure_legal_operation(nic, 'detach', 'vlan/native') with pytest.raises(BlockedError): api.node_detach_network('compute-01', 'eth0', 'hammernet') # removing networks in the right order should work api.node_detach_network('compute-01', 'eth0', 'pineapple') mock_networking_action() api.node_detach_network('compute-01', 'eth0', 'hammernet') mock_networking_action() db.session.close()
def test_user_add_project(self): """Test that user_add_project correctly adds the user.""" self.dbauth.user_create('charlie', 'secret') api.project_create('acme-corp') self.dbauth.user_add_project('charlie', 'acme-corp') user = api.get_or_404(self.dbauth.User, 'charlie') project = api.get_or_404(model.Project, 'acme-corp') assert project in user.projects assert user in project.users
def user_remove_project(user, project): """Remove a user from a project. If the project or user does not exist, a NotFoundError will be raised. """ get_auth_backend().require_admin() user = api.get_or_404(User, user) project = api.get_or_404(model.Project, project) if project not in user.projects: raise errors.NotFoundError("User %s is not in project %s" % (user.label, project.label)) user.projects.remove(project) db.session.commit()
def user_add_project(user, project): """Add a user to a project. If the project or user does not exist, a NotFoundError will be raised. """ get_auth_backend().require_admin() user = api.get_or_404(User, user) project = api.get_or_404(model.Project, project) if project in user.projects: raise errors.DuplicateError( 'User %s is already in project %s' % (user.label, project.label)) user.projects.append(project) db.session.commit()
def test_project_detach_node_maintenance(self, maintenance_proj_init): """Test that project_detach_node removes the node from the project. Note that the maintenance server has a fake url. We expect it to fail during the connection.""" api.project_create('anvil-nextgen') new_node('node-99') api.project_connect_node('anvil-nextgen', 'node-99') # Should raise error due to arbitrary POST url: with pytest.raises(LoggedWarningError): api.project_detach_node('anvil-nextgen', 'node-99') maintenance_proj = api.get_or_404(model.Project, 'maintenance') node = api.get_or_404(model.Node, 'node-99') assert node.project == maintenance_proj
def user_add_project(user, project): """Add a user to a project. If the project or user does not exist, a NotFoundError will be raised. """ get_auth_backend().require_admin() user = api.get_or_404(User, user) project = api.get_or_404(model.Project, project) if project in user.projects: raise errors.DuplicateError('User %s is already in project %s' % (user.label, project.label)) user.projects.append(project) db.session.commit()
def user_remove_project(user, project): """Remove a user from a project. If the project or user does not exist, a NotFoundError will be raised. """ get_auth_backend().require_admin() user = api.get_or_404(User, user) project = api.get_or_404(model.Project, project) if project not in user.projects: raise errors.NotFoundError( "User %s is not in project %s" % (user.label, project.label)) user.projects.remove(project) db.session.commit()
def delete_networks(): """Tear down things set up by create_networks again, we do various checks along the way. """ # Query the DB for nodes on this project project = api.get_or_404(model.Project, 'anvil-nextgen') nodes = project.nodes ports = self.get_all_ports(nodes) # Remove all nodes from their networks. We do this in two different # ways for different ports to test the different mechanisms. For # the first two nodes we explicity remove the attachments. For the # latter two we call port_revert. for node in nodes[:2]: attachment = model.NetworkAttachment.query \ .filter_by(nic=node.nics[0]).one() api.node_detach_network(node.label, node.nics[0].label, attachment.network.label) for node in nodes[2:]: port = node.nics[0].port api.port_revert(port.owner.label, port.label) deferred.apply_networking() # Assert that none of the nodes are on any network port_networks = self.get_port_networks(ports) for node in nodes: assert self.get_network(node.nics[0].port, port_networks) == \ set() # Delete the networks api.network_delete('net-0') api.network_delete('net-1')
def teardown(): """Teardown the setup from create_multi_nets. """ # Query the DB for nodes on this project project = api.get_or_404(model.Project, 'anvil-nextgen') nodes = project.nodes ports = self.get_all_ports(nodes) # Remove all nodes from their networks using port_revert. for node in nodes: port = node.nics[0].port api.port_revert(port.owner.label, port.label) deferred.apply_networking() # Assert that none of the nodes are on any network port_networks = self.get_port_networks(ports) for node in nodes: assert self.get_network(node.nics[0].port, port_networks) == \ set() # Delete the networks api.network_delete('net-0') api.network_delete('net-1') api.network_delete('net-2') api.network_delete('net-3')
def user_set_admin(user, is_admin): """Set whether the user is an admin.""" get_auth_backend().require_admin() user = api.get_or_404(User, user) if user.label == local.auth.label: raise errors.IllegalStateError("Cannot set own admin status") user.is_admin = is_admin db.session.commit()
def spoof_enable_obm(nodename): """spoof "enabling" the named node's obm. Stores a phony token in the node's obmd_node_token. This is necessary for tests where we can't actually get a token from obmd, but need to run other tests that will check for a token. """ node = api.get_or_404(Node, nodename) node.obmd_node_token = '0123456789' db.session.commit()
def user_delete(user): """Delete user. If the user does not exist, a NotFoundError will be raised. """ get_auth_backend().require_admin() # XXX: We need to do a bit of refactoring, so this is available outside of # hil.api: user = api.get_or_404(User, user) db.session.delete(user) db.session.commit()
def test_create_network_with_id_outside_pool(self): """Test creation of networks whose ID is not in the pool.""" # create an admin owned network api.network_create('hammernet', 'admin', '', 1511) # administrators should be able to make different networks with the # same network id api.network_create('starfish', 'admin', '', 1511) network = api.get_or_404(model.Network, 'starfish') net_id = int(network.network_id) assert network.allocated is False assert net_id == 1511
def test_create_network_with_id_from_pool(self): """Test creation of networks with IDs from the pool.""" api.project_create('nuggets') # create a project owned network and get its network_id api.network_create('hammernet', 'nuggets', 'nuggets', '') network = api.get_or_404(model.Network, 'hammernet') net_id = int(network.network_id) assert network.allocated is True # create an admin owned network with net_id from pool api.network_create('nailnet', 'admin', '', 103) network = api.get_or_404(model.Network, 'nailnet') assert network.allocated is True # creating a network with the same network id should raise an error with pytest.raises(errors.BlockedError): api.network_create('redbone', 'admin', '', 103) with pytest.raises(errors.BlockedError): api.network_create('starfish', 'admin', '', net_id) # free the network ids by deleting the networks api.network_delete('hammernet') api.network_delete('nailnet') api.absent_or_conflict(model.Network, 'hammernet') api.absent_or_conflict(model.Network, 'nailnet') # after deletion we should be able to create admin networks with those # network_ids api.network_create('redbone', 'admin', '', 103) network = api.get_or_404(model.Network, 'redbone') assert int(network.network_id) == 103 api.network_create('starfish', 'admin', '', net_id) network = api.get_or_404(model.Network, 'starfish') assert int(network.network_id) == net_id
def authenticate(self): # pylint: disable=missing-docstring local.auth = None if flask.request.authorization is None: return False authorization = flask.request.authorization if authorization.password is None: return False user = api.get_or_404(User, authorization.username) if user.verify_password(authorization.password): local.auth = user logger.info("Successful authentication for user %r", user.label) return True else: logger.info("Failed authentication for user %r", user.label) return False
def delete_networks(): """Tear down things set up by create_networks again, we do various checks along the way. """ # Query the DB for nodes on this project project = api.get_or_404(model.Project, 'anvil-nextgen') nodes = project.nodes ports = self.get_all_ports(nodes) # Remove all nodes from their networks. We do this in two ways, to # test the different mechanisms. # For the first two nodes, we first build up a list of # the arguments to the API calls, which has no direct references to # database objects, and then make the API calls and invoke # deferred.apply_networking after. This is important -- # The API calls and apply_networking normally run in their own # transaction. We get away with not doing this in the tests because # we serialize everything ourselves, so there's no risk of # interference. If we were to hang on to references to database # objects across such calls however, things could get harry. all_attachments = [] net = namedtuple('net', 'node nic network channel') for node in nodes[:2]: attachments = model.NetworkAttachment.query \ .filter_by(nic=node.nics[0]).all() for attachment in attachments: all_attachments.append( net(node=node.label, nic=node.nics[0].label, network=attachment.network.label, channel=attachment.channel)) switch = nodes[0].nics[0].port.owner # in some switches, the native network can only be disconnected # after we remove all tagged networks first. The following checks # for that and rearranges the networks (all_attachments) such that # tagged networks are removed first. if 'nativeless-trunk-mode' not in switch.get_capabilities(): # sort by channel; vlan/<integer> comes before vlan/native # because the ASCII for numbers comes before ASCII for letters. all_attachments = sorted(all_attachments, key=lambda net: net.channel) for attachment in all_attachments: api.node_detach_network(attachment.node, attachment.nic, attachment.network) deferred.apply_networking() # For the second two nodes, we just call port_revert on the nic's # port. for node in nodes[2:]: port = node.nics[0].port api.port_revert(port.owner.label, port.label) deferred.apply_networking() # Assert that none of the nodes are on any network port_networks = self.get_port_networks(ports) for node in nodes: assert self.get_network(node.nics[0].port, port_networks) == \ set() # Delete the networks api.network_delete('net-0') api.network_delete('net-1') api.network_delete('net-2') api.network_delete('net-3')