Skip to content

Instantly share code, notes, and snippets.

@namnh68
Created May 24, 2016 08:22
Show Gist options
  • Save namnh68/07604db42a0355bfbb4b0787c763e892 to your computer and use it in GitHub Desktop.
Save namnh68/07604db42a0355bfbb4b0787c763e892 to your computer and use it in GitHub Desktop.
[Following Mike's suggestion] Patch set for Postgresql pat1
"""Add SP and trigger for CIDR overlap
Revision ID: cfbd4c516845
Revises: d3435b514502
Create Date: 2016-05-17 19:14:41.915533
"""
from alembic import op
from neutron.db.migration.alembic_migrations import replaceable_obj
# revision identifiers, used by Alembic.
revision = 'cfbd4c516845'
down_revision = 'd3435b514502'
add_stored_procedure_for_mysql = replaceable_obj.ReplaceableObject(
"cidr_overlap(cidr1 varchar(30), cidr2 varchar(30))",
"""
RETURNS TINYINT
BEGIN
DECLARE bitmask INT;
SET bitmask = pow(
2,
(32 - least(
cast(substring_index(cidr1, '/', -1) as signed integer),
cast(substring_index(cidr2, '/', -1) as signed integer)
))
) - 1;
RETURN
inet_aton(substring_index(cidr1, '/', 1)) & ~bitmask =
inet_aton(substring_index(cidr2, '/', 1)) & ~bitmask;
END
"""
)
add_trigger_for_mysql = replaceable_obj.ReplaceableObject(
"no_overlap_cidr_subnets",
"""
BEFORE INSERT ON subnets
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(200);
IF (EXISTS(SELECT * FROM subnets WHERE network_id = NEW.network_id
AND cidr_overlap(cidr, NEW.cidr))) THEN
SET msg = CONCAT(
'inserted subnet ', NEW.cidr,
' conflicts with existing subnets');
SIGNAL sqlstate '45000'
SET MESSAGE_TEXT = msg;
END IF;
END
"""
)
add_stored_procedure_1_for_postgresql = replaceable_obj.ReplaceableObject(
"cidr_overlap (cidr1 CIDR, cidr2 CIDR)",
"""
RETURNS BOOLEAN AS
$$
BEGIN
RETURN
(cidr1 <<= cidr2) OR (cidr2 <<= cidr1);
END;
$$ LANGUAGE plpgsql;
"""
)
add_operator_for_postgresql = replaceable_obj.ReplaceableObject(
"&&",
"""
( PROCEDURE = cidr_overlap,
LEFTARG = CIDR,
RIGHTARG = CIDR,
COMMUTATOR = &&,
NEGATOR = !&&
)
"""
)
add_operator_class_for_postgresql = replaceable_obj.ReplaceableObject(
"custom_cidr_class FOR TYPE CIDR",
"""
USING gist AS
OPERATOR 3 &&
"""
)
def upgrade():
if op.get_bind().engine.name == 'mysql':
op.create_sp(add_stored_procedure_for_mysql)
op.create_trigger(add_trigger_for_mysql)
elif op.get_bind().engine.name == 'postgresql':
op.create_sp(add_stored_procedure_1_for_postgresql)
op.create_operator(add_operator_for_postgresql)
op.create_operator_class(add_operator_class_for_postgresql)
else:
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment