def setUp(self): super(TestNeutronDriver, self).setUp() self.mox.StubOutWithMock(neutronapi, 'get_client') self.moxed_client = self.mox.CreateMock(client.Client) neutronapi.get_client(mox.IgnoreArg()).MultipleTimes().AndReturn( self.moxed_client) self.context = context.RequestContext('userid', 'my_tenantid') setattr(self.context, 'auth_token', 'bff4a5a6b9eb4ea2a6efec6eefb77936')
def add_rules(self, context, id, name, vals): """Add security group rule(s) to security group. Note: the Nova security group API doesn't support adding multiple security group rules at once but the EC2 one does. Therefore, this function is written to support both. Multiple rules are installed to a security group in neutron using bulk support. """ neutron = neutronapi.get_client(context) body = self._make_neutron_security_group_rules_list(vals) try: rules = neutron.create_security_group_rule( body).get('security_group_rules') except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: LOG.exception(_LE("Neutron Error getting security group %s"), name) self.raise_not_found(six.text_type(e)) elif e.status_code == 409: LOG.exception(_LE("Neutron Error adding rules to security " "group %s"), name) self.raise_over_quota(six.text_type(e)) elif e.status_code == 400: LOG.exception(_LE("Neutron Error: %s"), six.text_type(e)) self.raise_invalid_property(six.text_type(e)) else: LOG.exception(_LE("Neutron Error:")) raise exc_info[0], exc_info[1], exc_info[2] converted_rules = [] for rule in rules: converted_rules.append( self._convert_to_patron_security_group_rule_format(rule)) return converted_rules
def list(self, context, names=None, ids=None, project=None, search_opts=None): """Returns list of security group rules owned by tenant.""" neutron = neutronapi.get_client(context) search_opts = {} if names: search_opts['name'] = names if ids: search_opts['id'] = ids if project: search_opts['tenant_id'] = project try: security_groups = neutron.list_security_groups( **search_opts).get('security_groups') except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error getting security groups")) converted_rules = [] for security_group in security_groups: converted_rules.append( self._convert_to_patron_security_group_format(security_group)) return converted_rules
def get(self, context, name=None, id=None, map_exception=False): neutron = neutronapi.get_client(context) try: if not id and name: # NOTE(flwang): The project id should be honoured so as to get # the correct security group id when user(with admin role but # non-admin project) try to query by name, so as to avoid # getting more than duplicated records with the same name. id = neutronv20.find_resourceid_by_name_or_id( neutron, 'security_group', name, context.project_id) group = neutron.show_security_group(id).get('security_group') return self._convert_to_patron_security_group_format(group) except n_exc.NeutronClientNoUniqueMatch as e: raise exception.NoUniqueMatch(six.text_type(e)) except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: LOG.debug("Neutron security group %s not found", name) raise exception.SecurityGroupNotFound(six.text_type(e)) else: LOG.error(_LE("Neutron Error: %s"), e) raise exc_info[0], exc_info[1], exc_info[2] except TypeError as e: LOG.error(_LE("Neutron Error: %s"), e) msg = _("Invalid security group name: %(name)s.") % {"name": name} raise exception.SecurityGroupNotFound(six.text_type(msg))
def remove_from_instance(self, context, instance, security_group_name): """Remove the security group associated with the instance.""" neutron = neutronapi.get_client(context) try: security_group_id = neutronv20.find_resourceid_by_name_or_id( neutron, 'security_group', security_group_name, context.project_id) except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: msg = (_("Security group %(name)s is not found for " "project %(project)s") % {'name': security_group_name, 'project': context.project_id}) self.raise_not_found(msg) else: LOG.exception(_LE("Neutron Error:")) raise exc_info[0], exc_info[1], exc_info[2] params = {'device_id': instance.uuid} try: ports = neutron.list_ports(**params).get('ports') except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:")) if not ports: msg = (_("instance_id %s could not be found as device id on" " any ports") % instance.uuid) self.raise_not_found(msg) found_security_group = False for port in ports: try: port.get('security_groups', []).remove(security_group_id) except ValueError: # When removing a security group from an instance the security # group should be on both ports since it was added this way if # done through the patron api. In case it is not a 404 is only # raised if the security group is not found on any of the # ports on the instance. continue updated_port = {'security_groups': port['security_groups']} try: LOG.info(_LI("Adding security group %(security_group_id)s to " "port %(port_id)s"), {'security_group_id': security_group_id, 'port_id': port['id']}) neutron.update_port(port['id'], {'port': updated_port}) found_security_group = True except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:")) if not found_security_group: msg = (_("Security group %(security_group_name)s not associated " "with the instance %(instance)s") % {'security_group_name': security_group_name, 'instance': instance.uuid}) self.raise_not_found(msg)
def add_to_instance(self, context, instance, security_group_name): """Add security group to the instance.""" neutron = neutronapi.get_client(context) try: security_group_id = neutronv20.find_resourceid_by_name_or_id( neutron, 'security_group', security_group_name, context.project_id) except n_exc.NeutronClientNoUniqueMatch as e: raise exception.NoUniqueMatch(six.text_type(e)) except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: msg = (_("Security group %(name)s is not found for " "project %(project)s") % { 'name': security_group_name, 'project': context.project_id }) self.raise_not_found(msg) else: LOG.exception(_LE("Neutron Error:")) raise exc_info[0], exc_info[1], exc_info[2] params = {'device_id': instance.uuid} try: ports = neutron.list_ports(**params).get('ports') except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:")) if not ports: msg = (_("instance_id %s could not be found as device id on" " any ports") % instance.uuid) self.raise_not_found(msg) for port in ports: if not self._has_security_group_requirements(port): LOG.warning( _LW("Cannot add security group %(name)s to " "%(instance)s since the port %(port_id)s " "does not meet security requirements"), { 'name': security_group_name, 'instance': instance.uuid, 'port_id': port['id'] }) raise exception.SecurityGroupCannotBeApplied() if 'security_groups' not in port: port['security_groups'] = [] port['security_groups'].append(security_group_id) updated_port = {'security_groups': port['security_groups']} try: LOG.info( _LI("Adding security group %(security_group_id)s to " "port %(port_id)s"), { 'security_group_id': security_group_id, 'port_id': port['id'] }) neutron.update_port(port['id'], {'port': updated_port}) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:"))
def add_to_instance(self, context, instance, security_group_name): """Add security group to the instance.""" neutron = neutronapi.get_client(context) try: security_group_id = neutronv20.find_resourceid_by_name_or_id( neutron, 'security_group', security_group_name, context.project_id) except n_exc.NeutronClientNoUniqueMatch as e: raise exception.NoUniqueMatch(six.text_type(e)) except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: msg = (_("Security group %(name)s is not found for " "project %(project)s") % {'name': security_group_name, 'project': context.project_id}) self.raise_not_found(msg) else: LOG.exception(_LE("Neutron Error:")) raise exc_info[0], exc_info[1], exc_info[2] params = {'device_id': instance.uuid} try: ports = neutron.list_ports(**params).get('ports') except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:")) if not ports: msg = (_("instance_id %s could not be found as device id on" " any ports") % instance.uuid) self.raise_not_found(msg) for port in ports: if not self._has_security_group_requirements(port): LOG.warning(_LW("Cannot add security group %(name)s to " "%(instance)s since the port %(port_id)s " "does not meet security requirements"), {'name': security_group_name, 'instance': instance.uuid, 'port_id': port['id']}) raise exception.SecurityGroupCannotBeApplied() if 'security_groups' not in port: port['security_groups'] = [] port['security_groups'].append(security_group_id) updated_port = {'security_groups': port['security_groups']} try: LOG.info(_LI("Adding security group %(security_group_id)s to " "port %(port_id)s"), {'security_group_id': security_group_id, 'port_id': port['id']}) neutron.update_port(port['id'], {'port': updated_port}) except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:"))
def get_rule(self, context, id): neutron = neutronapi.get_client(context) try: rule = neutron.show_security_group_rule( id).get('security_group_rule') except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: LOG.debug("Neutron security group rule %s not found", id) self.raise_not_found(six.text_type(e)) else: LOG.error(_LE("Neutron Error: %s"), e) raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_patron_security_group_rule_format(rule)
def get_rule(self, context, id): neutron = neutronapi.get_client(context) try: rule = neutron.show_security_group_rule(id).get( 'security_group_rule') except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: LOG.debug("Neutron security group rule %s not found", id) self.raise_not_found(six.text_type(e)) else: LOG.error(_LE("Neutron Error: %s"), e) raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_patron_security_group_rule_format(rule)
def remove_rules(self, context, security_group, rule_ids): neutron = neutronapi.get_client(context) rule_ids = set(rule_ids) try: # The ec2 api allows one to delete multiple security group rules # at once. Since there is no bulk delete for neutron the best # thing we can do is delete the rules one by one and hope this # works.... :/ for rule_id in range(0, len(rule_ids)): neutron.delete_security_group_rule(rule_ids.pop()) except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error unable to delete %s"), rule_ids)
def destroy(self, context, security_group): """This function deletes a security group.""" neutron = neutronapi.get_client(context) try: neutron.delete_security_group(security_group['id']) except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: self.raise_not_found(six.text_type(e)) elif e.status_code == 409: self.raise_invalid_property(six.text_type(e)) else: LOG.error(_LE("Neutron Error: %s"), e) raise exc_info[0], exc_info[1], exc_info[2]
def update_security_group(self, context, security_group, name, description): neutron = neutronapi.get_client(context) body = self._make_neutron_security_group_dict(name, description) try: security_group = neutron.update_security_group( security_group['id'], body).get('security_group') except n_exc.NeutronClientException as e: exc_info = sys.exc_info() LOG.exception(_LE("Neutron Error updating security group %s"), name) if e.status_code == 401: # TODO(arosen) Cannot raise generic response from neutron here # as this error code could be related to bad input or over # quota raise exc.HTTPBadRequest() raise exc_info[0], exc_info[1], exc_info[2] return self._convert_to_patron_security_group_format(security_group)
def list(self, context, names=None, ids=None, project=None, search_opts=None): """Returns list of security group rules owned by tenant.""" neutron = neutronapi.get_client(context) search_opts = {} if names: search_opts['name'] = names if ids: search_opts['id'] = ids if project: search_opts['tenant_id'] = project try: security_groups = neutron.list_security_groups(**search_opts).get( 'security_groups') except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error getting security groups")) converted_rules = [] for security_group in security_groups: converted_rules.append( self._convert_to_patron_security_group_format(security_group)) return converted_rules
def get_instances_security_groups_bindings(self, context, servers, detailed=False): """Returns a dict(instance_id, [security_groups]) to allow obtaining all of the instances and their security groups in one shot. """ neutron = neutronapi.get_client(context) ports = self._get_ports_from_server_list(servers, neutron) security_groups = self._get_secgroups_from_port_list(ports, neutron) instances_security_group_bindings = {} for port in ports: for port_sg_id in port.get('security_groups', []): # Note: have to check we found port_sg as its possible # the port has an SG that this user doesn't have access to port_sg = security_groups.get(port_sg_id) if port_sg: if detailed: sg_entry = self._convert_to_patron_security_group_format( port_sg) instances_security_group_bindings.setdefault( port['device_id'], []).append(sg_entry) else: # name is optional in neutron so if not specified # return id name = port_sg.get('name') if not name: name = port_sg.get('id') sg_entry = {'name': name} instances_security_group_bindings.setdefault( port['device_id'], []).append(sg_entry) return instances_security_group_bindings
def add_rules(self, context, id, name, vals): """Add security group rule(s) to security group. Note: the Nova security group API doesn't support adding multiple security group rules at once but the EC2 one does. Therefore, this function is written to support both. Multiple rules are installed to a security group in neutron using bulk support. """ neutron = neutronapi.get_client(context) body = self._make_neutron_security_group_rules_list(vals) try: rules = neutron.create_security_group_rule(body).get( 'security_group_rules') except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: LOG.exception(_LE("Neutron Error getting security group %s"), name) self.raise_not_found(six.text_type(e)) elif e.status_code == 409: LOG.exception( _LE("Neutron Error adding rules to security " "group %s"), name) self.raise_over_quota(six.text_type(e)) elif e.status_code == 400: LOG.exception(_LE("Neutron Error: %s"), six.text_type(e)) self.raise_invalid_property(six.text_type(e)) else: LOG.exception(_LE("Neutron Error:")) raise exc_info[0], exc_info[1], exc_info[2] converted_rules = [] for rule in rules: converted_rules.append( self._convert_to_patron_security_group_rule_format(rule)) return converted_rules
def remove_from_instance(self, context, instance, security_group_name): """Remove the security group associated with the instance.""" neutron = neutronapi.get_client(context) try: security_group_id = neutronv20.find_resourceid_by_name_or_id( neutron, 'security_group', security_group_name, context.project_id) except n_exc.NeutronClientException as e: exc_info = sys.exc_info() if e.status_code == 404: msg = (_("Security group %(name)s is not found for " "project %(project)s") % { 'name': security_group_name, 'project': context.project_id }) self.raise_not_found(msg) else: LOG.exception(_LE("Neutron Error:")) raise exc_info[0], exc_info[1], exc_info[2] params = {'device_id': instance.uuid} try: ports = neutron.list_ports(**params).get('ports') except n_exc.NeutronClientException: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:")) if not ports: msg = (_("instance_id %s could not be found as device id on" " any ports") % instance.uuid) self.raise_not_found(msg) found_security_group = False for port in ports: try: port.get('security_groups', []).remove(security_group_id) except ValueError: # When removing a security group from an instance the security # group should be on both ports since it was added this way if # done through the patron api. In case it is not a 404 is only # raised if the security group is not found on any of the # ports on the instance. continue updated_port = {'security_groups': port['security_groups']} try: LOG.info( _LI("Adding security group %(security_group_id)s to " "port %(port_id)s"), { 'security_group_id': security_group_id, 'port_id': port['id'] }) neutron.update_port(port['id'], {'port': updated_port}) found_security_group = True except Exception: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Neutron Error:")) if not found_security_group: msg = (_("Security group %(security_group_name)s not associated " "with the instance %(instance)s") % { 'security_group_name': security_group_name, 'instance': instance.uuid }) self.raise_not_found(msg)