Пример #1
0
    def create_acl(self, sg):
        """Creates an ACL on Arista Switch.

        Deals with multiple configurations - such as multiple switches
        """
        # Do nothing if Security Groups are not enabled
        if not self.sg_enabled:
            return

        if not sg:
            msg = _('Invalid or Empty Security Group Specified')
            raise arista_exc.AristaSecurityGroupError(msg=msg)

        in_cmds, out_cmds = self._create_acl_shell(sg['id'])
        for sgr in sg['security_group_rules']:
            in_cmds, out_cmds = self._create_acl_rule(in_cmds, out_cmds, sgr)
        in_cmds.append('exit')
        out_cmds.append('exit')

        for s in self._servers:
            try:
                self._run_openstack_sg_cmds(in_cmds, s)
                self._run_openstack_sg_cmds(out_cmds, s)

            except Exception:
                msg = (_('Failed to create ACL on EOS %s') % s)
                LOG.exception(msg)
                raise arista_exc.AristaSecurityGroupError(msg=msg)
Пример #2
0
    def create_acl_rule(self, sgr):
        """Creates an ACL on Arista Switch.

        For a given Security Group (ACL), it adds additional rule
        Deals with multiple configurations - such as multiple switches
        """
        # Do nothing if Security Groups are not enabled
        if not self.sg_enabled:
            return

        name = self._arista_acl_name(sgr['security_group_id'],
                                     sgr['direction'])
        cmds = []
        for c in self.aclCreateDict['create']:
            cmds.append(c.format(name))
        in_cmds, out_cmds = self._create_acl_rule(cmds, cmds, sgr)

        cmds = in_cmds
        if sgr['direction'] == 'egress':
            cmds = out_cmds

        cmds.append('exit')

        for s in self._servers:
            try:
                self._run_openstack_sg_cmds(cmds, s)
            except Exception:
                msg = (_('Failed to create ACL rule on EOS %s') % s)
                LOG.exception(msg)
                raise arista_exc.AristaSecurityGroupError(msg=msg)
Пример #3
0
    def delete_acl_rule(self, sgr):
        """Deletes an ACL rule on Arista Switch.

        For a given Security Group (ACL), it adds removes a rule
        Deals with multiple configurations - such as multiple switches
        """
        # Do nothing if Security Groups are not enabled
        if not self.sg_enabled:
            return

        # Only deal with valid protocols - skip the rest
        if not sgr or sgr['protocol'] not in SUPPORTED_SG_PROTOCOLS:
            return

        # Build seperate ACL for ingress and egress
        name = self._arista_acl_name(sgr['security_group_id'],
                                     sgr['direction'])
        remote_ip = sgr['remote_ip_prefix']
        if not remote_ip:
            remote_ip = 'any'
        min_port = sgr['port_range_min']
        if not min_port:
            min_port = 0
        max_port = sgr['port_range_max']
        if not max_port and sgr['protocol'] != 'icmp':
            max_port = 65535
        for s in self._servers:
            try:
                self._delete_acl_rule_from_eos(name, sgr['protocol'],
                                               remote_ip, min_port, max_port,
                                               sgr['direction'], s)
            except Exception:
                msg = (_('Failed to delete ACL on EOS %s') % s)
                LOG.exception(msg)
                raise arista_exc.AristaSecurityGroupError(msg=msg)
 def create_security_group_rule(self, sgr):
     try:
         self.rpc.create_acl_rule(sgr)
     except Exception:
         msg = (_('Failed to create ACL rule on EOS %s') % sgr)
         LOG.exception(msg)
         raise arista_exc.AristaSecurityGroupError(msg=msg)
 def update_security_group(self, sg):
     try:
         self.rpc.create_acl(sg)
     except Exception:
         msg = (_('Failed to create ACL on EOS %s') % sg)
         LOG.exception(msg)
         raise arista_exc.AristaSecurityGroupError(msg=msg)
Пример #6
0
    def _clean_acls(self, sg, failed_switch, switches_to_clean):
        """This is a helper function to clean up ACLs on switches.

        This called from within an exception - when apply_acl fails.
        Therefore, ensure that exception is raised after the cleanup
        is done.
        :param sg: Security Group to be removed
        :param failed_switch: IP of the switch where ACL failed
        :param switches_to_clean: List of switches containing link info
        """
        if not switches_to_clean:
            # This means the no switch needs cleaning - so, simply raise the
            # the exception and bail out
            msg = (_("Failed to apply ACL %(sg)s on switch %(switch)s") % {
                'sg': sg,
                'switch': failed_switch
            })
            LOG.error(msg)

        for s in switches_to_clean:
            try:
                # Port is being updated to remove security groups
                self.security_group_driver.remove_acl(sg, s['switch_id'],
                                                      s['port_id'],
                                                      s['switch_info'])
            except Exception:
                msg = (_("Failed to remove ACL %(sg)s on switch %(switch)%") %
                       {
                           'sg': sg,
                           'switch': s['switch_info']
                       })
                LOG.warning(msg)
        raise arista_exc.AristaSecurityGroupError(msg=msg)
 def delete_security_group_rule(self, sgr_id):
     if sgr_id:
         sgr = self.ndb.get_security_group_rule(sgr_id)
         if sgr:
             try:
                 self.rpc.delete_acl_rule(sgr)
             except Exception:
                 msg = (_('Failed to delete ACL rule on EOS %s') % sgr)
                 LOG.exception(msg)
                 raise arista_exc.AristaSecurityGroupError(msg=msg)
Пример #8
0
    def _create_acl_on_eos(self, in_cmds, out_cmds, protocol, cidr, from_port,
                           to_port, direction):
        """Creates an ACL on Arista HW Device.

        :param name: Name for the ACL
        :param server: Server endpoint on the Arista switch to be configured
        """
        if protocol == 'icmp':
            # ICMP rules require special processing
            if ((from_port and to_port) or (not from_port and not to_port)):
                rule = 'icmp_custom2'
            elif from_port and not to_port:
                rule = 'icmp_custom1'
            else:
                msg = _('Invalid ICMP rule specified')
                LOG.exception(msg)
                raise arista_exc.AristaSecurityGroupError(msg=msg)
            rule_type = 'in'
            cmds = in_cmds
            if direction == 'egress':
                rule_type = 'out'
                cmds = out_cmds
            final_rule = rule_type + '_' + rule
            acl_dict = self.aclCreateDict[final_rule]

            # None port is probematic - should be replaced with 0
            if not from_port:
                from_port = 0
            if not to_port:
                to_port = 0

            for c in acl_dict:
                if rule == 'icmp_custom2':
                    cmds.append(c.format(cidr, from_port, to_port))
                else:
                    cmds.append(c.format(cidr, from_port))
            return in_cmds, out_cmds
        else:
            # Non ICMP rules processing here
            acl_dict = self.aclCreateDict['in_rule']
            cmds = in_cmds
            if direction == 'egress':
                acl_dict = self.aclCreateDict['out_rule']
                cmds = out_cmds
            if not protocol:
                acl_dict = self.aclCreateDict['default']

            for c in acl_dict:
                cmds.append(c.format(protocol, cidr, from_port, to_port))
            return in_cmds, out_cmds
Пример #9
0
    def apply_acl(self, sgs, switch_id, port_id, switch_info):
        """Creates an ACL on Arista Switch.

        Applies ACLs to the baremetal ports only. The port/switch
        details is passed through the parameters.
        Deals with multiple configurations - such as multiple switches
        param sgs: List of Security Groups
        param switch_id: Switch ID of TOR where ACL needs to be applied
        param port_id: Port ID of port where ACL needs to be applied
        param switch_info: IP address of the TOR
        """
        # Do nothing if Security Groups are not enabled
        if not self.sg_enabled:
            return

        # We do not support more than one security group on a port
        if not sgs or len(sgs) > 1:
            msg = (_('Only one Security Group Supported on a port %s') % sgs)
            raise arista_exc.AristaSecurityGroupError(msg=msg)

        sg = self._ndb.get_security_group(sgs[0])

        # We already have ACLs on the TORs.
        # Here we need to find out which ACL is applicable - i.e.
        # Ingress ACL, egress ACL or both
        direction = ['ingress', 'egress']

        server = self._make_eapi_client(switch_info)

        for d in range(len(direction)):
            name = self._arista_acl_name(sg['id'], direction[d])
            try:
                self._apply_acl_on_eos(port_id, name, direction[d], server)
            except Exception:
                msg = (_('Failed to apply ACL on port %s') % port_id)
                LOG.exception(msg)
                raise arista_exc.AristaSecurityGroupError(msg=msg)
Пример #10
0
    def delete_acl(self, sg):
        """Deletes an ACL from Arista Switch.

        Deals with multiple configurations - such as multiple switches
        """
        # Do nothing if Security Groups are not enabled
        if not self.sg_enabled:
            return

        if not sg:
            msg = _('Invalid or Empty Security Group Specified')
            raise arista_exc.AristaSecurityGroupError(msg=msg)

        direction = ['ingress', 'egress']
        for d in range(len(direction)):
            name = self._arista_acl_name(sg['id'], direction[d])

            for s in self._servers:
                try:
                    self._delete_acl_from_eos(name, s)
                except Exception:
                    msg = (_('Failed to create ACL on EOS %s') % s)
                    LOG.exception(msg)
                    raise arista_exc.AristaSecurityGroupError(msg=msg)
Пример #11
0
    def _delete_acl_rule_from_eos(self, name, protocol, cidr, from_port,
                                  to_port, direction, server):
        """deletes an ACL from Arista HW Device.

        :param name: Name for the ACL
        :param server: Server endpoint on the Arista switch to be configured
        """
        cmds = []

        if protocol == 'icmp':
            # ICMP rules require special processing
            if ((from_port and to_port) or (not from_port and not to_port)):
                rule = 'icmp_custom2'
            elif from_port and not to_port:
                rule = 'icmp_custom1'
            else:
                msg = _('Invalid ICMP rule specified')
                LOG.exception(msg)
                raise arista_exc.AristaSecurityGroupError(msg=msg)
            rule_type = 'del_in'
            if direction == 'egress':
                rule_type = 'del_out'
            final_rule = rule_type + '_' + rule
            acl_dict = self.aclCreateDict[final_rule]

            # None port is probematic - should be replaced with 0
            if not from_port:
                from_port = 0
            if not to_port:
                to_port = 0

            for c in acl_dict:
                if rule == 'icmp_custom2':
                    cmds.append(c.format(name, cidr, from_port, to_port))
                else:
                    cmds.append(c.format(name, cidr, from_port))

        else:
            acl_dict = self.aclCreateDict['del_in_acl_rule']
            if direction == 'egress':
                acl_dict = self.aclCreateDict['del_out_acl_rule']

            for c in acl_dict:
                cmds.append(c.format(name, protocol, cidr, from_port, to_port))

        self._run_openstack_sg_cmds(cmds, server)
Пример #12
0
    def remove_acl(self, sgs, switch_id, port_id, switch_info):
        """Removes an ACL from Arista Switch.

        Removes ACLs from the baremetal ports only. The port/switch
        details is passed throuhg the parameters.
        param sgs: List of Security Groups
        param switch_id: Switch ID of TOR where ACL needs to be removed
        param port_id: Port ID of port where ACL needs to be removed
        param switch_info: IP address of the TOR
        """
        # Do nothing if Security Groups are not enabled
        if not self.sg_enabled:
            return

        # We do not support more than one security group on a port
        if not sgs or len(sgs) > 1:
            msg = (_('Only one Security Group Supported on a port %s') % sgs)
            raise arista_exc.AristaSecurityGroupError(msg=msg)

        sg = self._ndb.get_security_group(sgs[0])

        # We already have ACLs on the TORs.
        # Here we need to find out which ACL is applicable - i.e.
        # Ingress ACL, egress ACL or both
        direction = []
        for sgr in sg['security_group_rules']:
            # Only deal with valid protocols - skip the rest
            if not sgr or sgr['protocol'] not in SUPPORTED_SG_PROTOCOLS:
                continue

            if sgr['direction'] not in direction:
                direction.append(sgr['direction'])

        # THIS IS TOTAL HACK NOW - just for testing
        # Assumes the credential of all switches are same as specified
        # in the condig file
        server = jsonrpclib.Server(self._eapi_host_url(switch_info))
        for d in range(len(direction)):
            name = self._arista_acl_name(sg['id'], direction[d])
            try:
                self._remove_acl_from_eos(port_id, name, direction[d], server)
            except Exception:
                msg = (_('Failed to remove ACL on port %s') % port_id)
                LOG.exception(msg)