'Create a new security group rule.
:param parent_group_id: security group id a rule is created to
:param direction: ``ingress`` or ``egress``
:param ethertype: ``IPv4`` or ``IPv6``
:param ip_protocol: tcp, udp, icmp
:param from_port: L4 port range min
:param to_port: L4 port range max
:param cidr: Remote IP CIDR
:param group_id: ID of Source Security Group
:returns: SecurityGroupRule object'

@profiler.trace
def rule_create(self, parent_group_id, direction=None, ethertype=None, ip_protocol=None, from_port=None, to_port=None, cidr=None, group_id=None):

    if (not cidr):
        cidr = None
    if (from_port < 0):
        from_port = None
    if (to_port < 0):
        to_port = None
    if (isinstance(ip_protocol, int) and (ip_protocol < 0)):
        ip_protocol = None
    body = {'security_group_rule': {'security_group_id': parent_group_id, 'direction': direction, 'ethertype': ethertype, 'protocol': ip_protocol, 'port_range_min': from_port, 'port_range_max': to_port, 'remote_ip_prefix': cidr, 'remote_group_id': group_id}}
    try:
        rule = self.client.create_security_group_rule(body)
    except neutron_exc.Conflict:
        raise exceptions.Conflict(_('Security    group    rule    already    exists.'))
    rule = rule.get('security_group_rule')
    sg_dict = self._sg_name_dict(parent_group_id, [rule])
    return SecurityGroupRule(rule, sg_dict)
