)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"8f04d5474231d0e0d6cb1f312be8c58620eef095","unresolved":false,"context_lines":[{"line_number":16,"context_line":"will be the reference OVS gateway implementation"},{"line_number":17,"context_line":"for use in conjunction with ML2."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Implements: blueprint neutron-external-ports"},{"line_number":20,"context_line":"Change-Id: I51cc1c852f45d5f443ee0c0d1d1c6304a6d55992"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"baada198_413a7a99","line":19,"updated":"2014-07-08 00:19:54.000000000","message":"neutron-external-attachment-points ?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"}],"neutron/db/externalattachment_db.py":[{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"d915be6ae6cd78848bf4fce2ef5df193fd583054","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"class ExternalAttachmentPoint(model_base.BASEV2, models_v2.HasId,"},{"line_number":37,"context_line":"                              models_v2.HasTenant,"},{"line_number":38,"context_line":"                              models_v2.HasStatusDescription):"},{"line_number":39,"context_line":"    \"\"\" Represents a network external attachment point. \"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_b9c95d7b","line":38,"updated":"2014-06-02 11:19:34.000000000","message":"Do you really need both status and status_description?","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"355b2497d290349caac2880dbf2f29b864b6efa4","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"class ExternalAttachmentPoint(model_base.BASEV2, models_v2.HasId,"},{"line_number":37,"context_line":"                              models_v2.HasTenant,"},{"line_number":38,"context_line":"                              models_v2.HasStatusDescription):"},{"line_number":39,"context_line":"    \"\"\" Represents a network external attachment point. \"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_c0f2a0d1","line":38,"in_reply_to":"1ae5cdf2_b9c95d7b","updated":"2014-06-02 18:18:04.000000000","message":"I think it\u0027s a good idea so there is a place to store the error message on a failure. If it\u0027s an asynchronous style of provisioning these ports, a regular exception won\u0027t be propagated back to the user on a failure.","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"d915be6ae6cd78848bf4fce2ef5df193fd583054","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"},{"line_number":42,"context_line":"    name \u003d sa.Column(sa.String(255))"},{"line_number":43,"context_line":"    description \u003d sa.Column(sa.String(255))"},{"line_number":44,"context_line":"    attachment_id \u003d sa.Column(sa.String(1024))"},{"line_number":45,"context_line":"    attachment_type \u003d sa.Column(sa.String(255))"},{"line_number":46,"context_line":"    network_id \u003d sa.Column(sa.String(36),"},{"line_number":47,"context_line":"                           sa.ForeignKey(\u0027networks.id\u0027, ondelete\u003d\u0027SET NULL\u0027),"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_59277964","line":44,"updated":"2014-06-02 11:19:34.000000000","message":"id is usually 36, and description 1024","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"bc1cb90a0d70540f2b8a26c3dd359a0366253e9d","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"},{"line_number":42,"context_line":"    name \u003d sa.Column(sa.String(255))"},{"line_number":43,"context_line":"    description \u003d sa.Column(sa.String(255))"},{"line_number":44,"context_line":"    attachment_id \u003d sa.Column(sa.String(1024))"},{"line_number":45,"context_line":"    attachment_type \u003d sa.Column(sa.String(255))"},{"line_number":46,"context_line":"    network_id \u003d sa.Column(sa.String(36),"},{"line_number":47,"context_line":"                           sa.ForeignKey(\u0027networks.id\u0027, ondelete\u003d\u0027SET NULL\u0027),"}],"source_content_type":"text/x-python","patch_set":2,"id":"baada198_1390bb94","line":44,"in_reply_to":"1ae5cdf2_59277964","updated":"2014-07-04 06:05:52.000000000","message":"This isn\u0027t a UUID. This is an identifier for the backend to locate the port.","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"d915be6ae6cd78848bf4fce2ef5df193fd583054","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\u0027SET NULL\u0027),"},{"line_number":62,"context_line":"                        nullable\u003dTrue)"},{"line_number":63,"context_line":"    name \u003d sa.Column(sa.String(255))"},{"line_number":64,"context_line":"    description \u003d sa.Column(sa.String(255))"},{"line_number":65,"context_line":"    mac_address \u003d sa.Column(sa.String(32), nullable\u003dFalse)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_19bb31e6","line":64,"updated":"2014-06-02 11:19:34.000000000","message":"nit: description is usually 1024","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"d915be6ae6cd78848bf4fce2ef5df193fd583054","unresolved":false,"context_lines":[{"line_number":183,"context_line":"    def _verify_vlan(self, vlan):"},{"line_number":184,"context_line":"        try:"},{"line_number":185,"context_line":"            if (str(vlan) !\u003d \u0027untagged\u0027 and"},{"line_number":186,"context_line":"                int(vlan) not in range(1, 4095)):"},{"line_number":187,"context_line":"                    raise ValueError()"},{"line_number":188,"context_line":"        except ValueError:"},{"line_number":189,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_39cb8d1f","line":186,"updated":"2014-06-02 11:19:34.000000000","message":"it seems to me that this operation is not optimal as it would try to find a number in a list, while you only need to check it against 0, 4095 boundaries.","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"355b2497d290349caac2880dbf2f29b864b6efa4","unresolved":false,"context_lines":[{"line_number":183,"context_line":"    def _verify_vlan(self, vlan):"},{"line_number":184,"context_line":"        try:"},{"line_number":185,"context_line":"            if (str(vlan) !\u003d \u0027untagged\u0027 and"},{"line_number":186,"context_line":"                int(vlan) not in range(1, 4095)):"},{"line_number":187,"context_line":"                    raise ValueError()"},{"line_number":188,"context_line":"        except ValueError:"},{"line_number":189,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_40b210e7","line":186,"in_reply_to":"1ae5cdf2_39cb8d1f","updated":"2014-06-02 18:18:04.000000000","message":"yes, it\u0027s very bad. it constructs an entire list and checks for membership, but it certainly looks nice. :-)\n\nI will remove it and replace it with the ugly greater than, less than checks next patch.","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"d915be6ae6cd78848bf4fce2ef5df193fd583054","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        # remove any previous associations"},{"line_number":313,"context_line":"        context.session.query(PortExternalAttachmentBinding).filter_by("},{"line_number":314,"context_line":"            port_id\u003dport[\u0027id\u0027]).delete()"},{"line_number":315,"context_line":"        if not ext_id:"},{"line_number":316,"context_line":"            return"},{"line_number":317,"context_line":"        # make sure the external attachment point exists"},{"line_number":318,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_9441c83b","line":315,"updated":"2014-06-02 11:19:34.000000000","message":"Should it be the first statement in the method?","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"355b2497d290349caac2880dbf2f29b864b6efa4","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        # remove any previous associations"},{"line_number":313,"context_line":"        context.session.query(PortExternalAttachmentBinding).filter_by("},{"line_number":314,"context_line":"            port_id\u003dport[\u0027id\u0027]).delete()"},{"line_number":315,"context_line":"        if not ext_id:"},{"line_number":316,"context_line":"            return"},{"line_number":317,"context_line":"        # make sure the external attachment point exists"},{"line_number":318,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_40e930b7","line":315,"in_reply_to":"1ae5cdf2_9441c83b","updated":"2014-06-02 18:18:04.000000000","message":"No, because setting an attachment point to None is okay. In that case we just need to remove the old association.","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"d915be6ae6cd78848bf4fce2ef5df193fd583054","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        query \u003d context.session.query(PortExternalAttachmentBinding).filter_by("},{"line_number":339,"context_line":"            external_attachment_id\u003did)"},{"line_number":340,"context_line":"        if query.count() \u003e 0:"},{"line_number":341,"context_line":"            port_ids \u003d [r.port_id for r in query.all()]"},{"line_number":342,"context_line":"            raise externalattachment.ExternalAttachmentPointInUse("},{"line_number":343,"context_line":"                id\u003did, port_ids\u003dport_ids)"},{"line_number":344,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_546f40c5","line":341,"updated":"2014-06-02 11:19:34.000000000","message":".all() is unnecessary here as query itself is iterable","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"355b2497d290349caac2880dbf2f29b864b6efa4","unresolved":false,"context_lines":[{"line_number":338,"context_line":"        query \u003d context.session.query(PortExternalAttachmentBinding).filter_by("},{"line_number":339,"context_line":"            external_attachment_id\u003did)"},{"line_number":340,"context_line":"        if query.count() \u003e 0:"},{"line_number":341,"context_line":"            port_ids \u003d [r.port_id for r in query.all()]"},{"line_number":342,"context_line":"            raise externalattachment.ExternalAttachmentPointInUse("},{"line_number":343,"context_line":"                id\u003did, port_ids\u003dport_ids)"},{"line_number":344,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1ae5cdf2_804098a6","line":341,"in_reply_to":"1ae5cdf2_546f40c5","updated":"2014-06-02 18:18:04.000000000","message":"cool. thanks","commit_id":"636d73e0e0a952c43d7778d01f304b0a0096acbb"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"8f04d5474231d0e0d6cb1f312be8c58620eef095","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"},{"line_number":45,"context_line":"    name \u003d sa.Column(sa.String(255))"},{"line_number":46,"context_line":"    description \u003d sa.Column(sa.String(1024))"},{"line_number":47,"context_line":"    attachment_id \u003d sa.Column(sa.String(1024), unique\u003dTrue)"},{"line_number":48,"context_line":"    attachment_type \u003d sa.Column(sa.String(255))"},{"line_number":49,"context_line":"    network_id \u003d sa.Column(sa.String(36),"},{"line_number":50,"context_line":"                           sa.ForeignKey(\u0027networks.id\u0027, ondelete\u003d\u0027SET NULL\u0027),"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_8198126b","line":47,"range":{"start_line":47,"start_character":47,"end_line":47,"end_character":58},"updated":"2014-07-08 00:19:54.000000000","message":"is this unique among attachment_type?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    Holds the association between neutron ports and external attachments"},{"line_number":57,"context_line":"    so the neutron port table doesn\u0027t have to be modified to include"},{"line_number":58,"context_line":"    an external_attachment_id column."},{"line_number":59,"context_line":"    \"\"\""},{"line_number":60,"context_line":"    port_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":62,"context_line":"                        primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_c1498361","line":59,"updated":"2014-07-03 20:04:05.000000000","message":"I think you have a 0..1-\u003e0..1 relationships between port and attachment.  Assuming the frequent operations are \u0027does this port have an external attachment\u0027 and \u0027is this attachment in use\u0027 I\u0027m not clear why the pattern you\u0027re using here is any better than adding a column to the external_attachment_points that is nullable, unique and referencing ports.  You don\u0027t have the many-many relationship that usually suggests this pattern and I don\u0027t see the advantage in the intermediate table.  (Or is this just the way we do extensions when they add an attr to \u0027ports\u0027?  I admit my ignorance here.)","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    Holds the association between neutron ports and external attachments"},{"line_number":57,"context_line":"    so the neutron port table doesn\u0027t have to be modified to include"},{"line_number":58,"context_line":"    an external_attachment_id column."},{"line_number":59,"context_line":"    \"\"\""},{"line_number":60,"context_line":"    port_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":62,"context_line":"                        primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_93b7d2f4","line":59,"in_reply_to":"baada198_01ca9b1a","updated":"2014-07-04 06:05:57.000000000","message":"This a 1 to many relationship. A single attachment point could have several neutron ports. \n\nSee the L2 gateway use case in the spec. \n\nhttps://github.com/openstack/neutron-specs/blob/master/specs/juno/neutron-external-attachment-points.rst#use-cases","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"7f56de56ed90f1a96c4ae54056feba350ba7ea65","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    Holds the association between neutron ports and external attachments"},{"line_number":57,"context_line":"    so the neutron port table doesn\u0027t have to be modified to include"},{"line_number":58,"context_line":"    an external_attachment_id column."},{"line_number":59,"context_line":"    \"\"\""},{"line_number":60,"context_line":"    port_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":62,"context_line":"                        primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_3db3ec4d","line":59,"in_reply_to":"baada198_7396a940","updated":"2014-07-07 21:55:59.000000000","message":"Other way around. Multiple neutron ports can belong to a single attachment point.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"7b45d5f95b89d4ba703ec3addb713d927dc5af33","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    Holds the association between neutron ports and external attachments"},{"line_number":57,"context_line":"    so the neutron port table doesn\u0027t have to be modified to include"},{"line_number":58,"context_line":"    an external_attachment_id column."},{"line_number":59,"context_line":"    \"\"\""},{"line_number":60,"context_line":"    port_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":62,"context_line":"                        primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_7396a940","line":59,"in_reply_to":"baada198_93b7d2f4","updated":"2014-07-04 19:47:15.000000000","message":"OK, so you\u0027re imagining that I would attach multiple Neutron networks to a single switch port.\n\nYou\u0027re aware you\u0027ve just reinvented provider networks, right?  Albeit in a nicer way.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"599d40f635c5b87225acddffa961feefeb7b9840","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    Holds the association between neutron ports and external attachments"},{"line_number":57,"context_line":"    so the neutron port table doesn\u0027t have to be modified to include"},{"line_number":58,"context_line":"    an external_attachment_id column."},{"line_number":59,"context_line":"    \"\"\""},{"line_number":60,"context_line":"    port_id \u003d sa.Column(sa.String(36),"},{"line_number":61,"context_line":"                        sa.ForeignKey(\u0027ports.id\u0027, ondelete\u003d\"CASCADE\"),"},{"line_number":62,"context_line":"                        primary_key\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_01ca9b1a","line":59,"in_reply_to":"baada198_c1498361","updated":"2014-07-03 20:07:37.000000000","message":"That said, I may be confused here.  Is an \u0027attachment point\u0027 a think I can associate with at most one port (i.e. a switch port) - or is it a thing I can associate with many ports (i.e. a switch)?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":62,"context_line":"                        primary_key\u003dTrue)"},{"line_number":63,"context_line":"    external_attachment_id \u003d sa.Column("},{"line_number":64,"context_line":"        sa.String(36), sa.ForeignKey(\u0027external_attachment_points.id\u0027,"},{"line_number":65,"context_line":"                                     ondelete\u003d\u0027CASCADE\u0027), nullable\u003dFalse)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    external_attachment_point \u003d sa.orm.relationship("},{"line_number":68,"context_line":"        ExternalAttachmentPoint,"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_6f250308","line":65,"updated":"2014-07-03 20:04:05.000000000","message":"Probably not ON DELETE CASCADE - you shouldn\u0027t be able to delete an attachment if a port is bound to it","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":62,"context_line":"                        primary_key\u003dTrue)"},{"line_number":63,"context_line":"    external_attachment_id \u003d sa.Column("},{"line_number":64,"context_line":"        sa.String(36), sa.ForeignKey(\u0027external_attachment_points.id\u0027,"},{"line_number":65,"context_line":"                                     ondelete\u003d\u0027CASCADE\u0027), nullable\u003dFalse)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    external_attachment_point \u003d sa.orm.relationship("},{"line_number":68,"context_line":"        ExternalAttachmentPoint,"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_f39c8e6c","line":65,"in_reply_to":"baada198_6f250308","updated":"2014-07-04 06:05:57.000000000","message":"Good catch.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"f528807643230bd4f57038204d804e39feaf7515","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    port \u003d sa.orm.relationship("},{"line_number":72,"context_line":"        models_v2.Port,"},{"line_number":73,"context_line":"        backref\u003dsa.orm.backref(\"external_attachments\", uselist\u003dFalse,"},{"line_number":74,"context_line":"                               cascade\u003d\u0027delete\u0027, lazy\u003d\u0027joined\u0027))"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"class ExternalAttachmentMixin(eap.ExternalAttachmentBase,"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_7cfeb1af","line":74,"updated":"2014-07-03 12:19:21.000000000","message":"looking at the mixin code i don\u0027t see where is this relation used.\nDo you need lazy\u003d\u0027joined\u0027 then?\nYou have to disable eager loads each time now.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":71,"context_line":"    port \u003d sa.orm.relationship("},{"line_number":72,"context_line":"        models_v2.Port,"},{"line_number":73,"context_line":"        backref\u003dsa.orm.backref(\"external_attachments\", uselist\u003dFalse,"},{"line_number":74,"context_line":"                               cascade\u003d\u0027delete\u0027, lazy\u003d\u0027joined\u0027))"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"class ExternalAttachmentMixin(eap.ExternalAttachmentBase,"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_f3d80e20","line":74,"in_reply_to":"baada198_7cfeb1af","updated":"2014-07-04 06:05:57.000000000","message":"I had created this early-on in anticipation that the port attributes might need to be checked. So far it\u0027s seems like it isn\u0027t needed yet so I can probably leave it at the default of \u0027select\u0027.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    ATTACHMENT_TYPE_VALIDATORS \u003d {"},{"line_number":85,"context_line":"        \u0027vlan_switch\u0027: \u0027validate_vlan_switch_attachment\u0027,"},{"line_number":86,"context_line":"        \u0027ovs_gateway\u0027: \u0027validate_ovs_gateway_attachment\u0027,"},{"line_number":87,"context_line":"        \u0027bonded_port_group\u0027: \u0027validate_port_group_attachment\u0027,"},{"line_number":88,"context_line":"    }"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    # Default status to put newly created attachment points in."}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_8f4c17ca","line":87,"updated":"2014-07-03 20:04:05.000000000","message":"This here makes me think that you\u0027re making it difficult to add additional attachment types beyond those listed (and it seems reasonable that you would want to add attachment types with a plugin mechanism).","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"7b45d5f95b89d4ba703ec3addb713d927dc5af33","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    ATTACHMENT_TYPE_VALIDATORS \u003d {"},{"line_number":85,"context_line":"        \u0027vlan_switch\u0027: \u0027validate_vlan_switch_attachment\u0027,"},{"line_number":86,"context_line":"        \u0027ovs_gateway\u0027: \u0027validate_ovs_gateway_attachment\u0027,"},{"line_number":87,"context_line":"        \u0027bonded_port_group\u0027: \u0027validate_port_group_attachment\u0027,"},{"line_number":88,"context_line":"    }"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    # Default status to put newly created attachment points in."}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_13abad75","line":87,"in_reply_to":"baada198_3314469f","updated":"2014-07-04 19:47:15.000000000","message":"This doesn\u0027t want to be here.  You\u0027ve not got the complete list of attachment port types and you can\u0027t possibly have them here, so there\u0027s no way you can list all the validators here.  Your comment below hits the mark, I think.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    ATTACHMENT_TYPE_VALIDATORS \u003d {"},{"line_number":85,"context_line":"        \u0027vlan_switch\u0027: \u0027validate_vlan_switch_attachment\u0027,"},{"line_number":86,"context_line":"        \u0027ovs_gateway\u0027: \u0027validate_ovs_gateway_attachment\u0027,"},{"line_number":87,"context_line":"        \u0027bonded_port_group\u0027: \u0027validate_port_group_attachment\u0027,"},{"line_number":88,"context_line":"    }"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    # Default status to put newly created attachment points in."}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_3314469f","line":87,"in_reply_to":"baada198_8f4c17ca","updated":"2014-07-04 06:05:57.000000000","message":"I assumed here someone could just add to this dict in their plugin\u0027s init method. Would it help if I had a helper function to add a validator to this, or do you not want it to be stored here at all?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        if type not in self.ATTACHMENT_TYPE_VALIDATORS.keys():"},{"line_number":95,"context_line":"            return False"},{"line_number":96,"context_line":"        if not getattr(self, self.ATTACHMENT_TYPE_VALIDATORS[type], False):"},{"line_number":97,"context_line":"            # a type was defined without a corresponding validation function"},{"line_number":98,"context_line":"            raise exceptions.NotFound("},{"line_number":99,"context_line":"                _(\"Missing validation function %(func)s for type %(type)s\") %"},{"line_number":100,"context_line":"                {\u0027func\u0027: self.ATTACHMENT_TYPE_VALIDATORS[type], \u0027type\u0027: type}"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_4f04bf49","line":97,"updated":"2014-07-03 20:04:05.000000000","message":"Seems wrong to be introspecting this class to find validators - you should have attachment types as a class with several implementations, and validation as a method on that class.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        if type not in self.ATTACHMENT_TYPE_VALIDATORS.keys():"},{"line_number":95,"context_line":"            return False"},{"line_number":96,"context_line":"        if not getattr(self, self.ATTACHMENT_TYPE_VALIDATORS[type], False):"},{"line_number":97,"context_line":"            # a type was defined without a corresponding validation function"},{"line_number":98,"context_line":"            raise exceptions.NotFound("},{"line_number":99,"context_line":"                _(\"Missing validation function %(func)s for type %(type)s\") %"},{"line_number":100,"context_line":"                {\u0027func\u0027: self.ATTACHMENT_TYPE_VALIDATORS[type], \u0027type\u0027: type}"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_730a3e7a","line":97,"in_reply_to":"baada198_4f04bf49","updated":"2014-07-04 06:05:57.000000000","message":"That makes sense. So how about an abstract class that they all inherit from that makes sure they implement a \u0027validate\u0027 method?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"7b45d5f95b89d4ba703ec3addb713d927dc5af33","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        if type not in self.ATTACHMENT_TYPE_VALIDATORS.keys():"},{"line_number":95,"context_line":"            return False"},{"line_number":96,"context_line":"        if not getattr(self, self.ATTACHMENT_TYPE_VALIDATORS[type], False):"},{"line_number":97,"context_line":"            # a type was defined without a corresponding validation function"},{"line_number":98,"context_line":"            raise exceptions.NotFound("},{"line_number":99,"context_line":"                _(\"Missing validation function %(func)s for type %(type)s\") %"},{"line_number":100,"context_line":"                {\u0027func\u0027: self.ATTACHMENT_TYPE_VALIDATORS[type], \u0027type\u0027: type}"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_f3c8f956","line":97,"in_reply_to":"baada198_730a3e7a","updated":"2014-07-04 19:47:15.000000000","message":"Yup, exactly - and it wants the code to actually perform the attachment, too, I think, in separate methods, so the whole thing works out nicely.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"7f56de56ed90f1a96c4ae54056feba350ba7ea65","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        if type not in self.ATTACHMENT_TYPE_VALIDATORS.keys():"},{"line_number":95,"context_line":"            return False"},{"line_number":96,"context_line":"        if not getattr(self, self.ATTACHMENT_TYPE_VALIDATORS[type], False):"},{"line_number":97,"context_line":"            # a type was defined without a corresponding validation function"},{"line_number":98,"context_line":"            raise exceptions.NotFound("},{"line_number":99,"context_line":"                _(\"Missing validation function %(func)s for type %(type)s\") %"},{"line_number":100,"context_line":"                {\u0027func\u0027: self.ATTACHMENT_TYPE_VALIDATORS[type], \u0027type\u0027: type}"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_dd4d903f","line":97,"in_reply_to":"baada198_f3c8f956","updated":"2014-07-07 21:55:59.000000000","message":"There will likely be many different implementations of \u0027attaching\u0027 a given attachment type. Each one would then have to reimplement the same validation logic. Is that the way we want to go here?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"8f04d5474231d0e0d6cb1f312be8c58620eef095","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        return True"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    @log.log"},{"line_number":105,"context_line":"    def validate_external_attachment_identifier(self, context, type, body):"},{"line_number":106,"context_line":"        if not self._verify_valid_type(type):"},{"line_number":107,"context_line":"            raise eap.InvalidAttachmentType("},{"line_number":108,"context_line":"                type\u003dtype, reason\u003d\"Invalid type %s\" % type)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_21990679","line":105,"range":{"start_line":105,"start_character":63,"end_line":105,"end_character":67},"updated":"2014-07-08 00:19:54.000000000","message":"can you avoid shadowing python builtin \"type\"?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"886a0f408b8839b2da862f6c360af5e2c269b8eb","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        return True"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    @log.log"},{"line_number":105,"context_line":"    def validate_external_attachment_identifier(self, context, type, body):"},{"line_number":106,"context_line":"        if not self._verify_valid_type(type):"},{"line_number":107,"context_line":"            raise eap.InvalidAttachmentType("},{"line_number":108,"context_line":"                type\u003dtype, reason\u003d\"Invalid type %s\" % type)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_850473c7","line":105,"in_reply_to":"baada198_21990679","updated":"2014-07-08 23:03:18.000000000","message":"Is there a precedent for this or a hacking check for this? I see other uses of \u0027type\u0027 as a variable name in the codebase.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"8f04d5474231d0e0d6cb1f312be8c58620eef095","unresolved":false,"context_lines":[{"line_number":173,"context_line":"        return True"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @log.log"},{"line_number":176,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":177,"context_line":"        try:"},{"line_number":178,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":179,"context_line":"        except sa_exc.NoResultFound:"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_8181f2fc","line":176,"range":{"start_line":176,"start_character":54,"end_line":176,"end_character":56},"updated":"2014-07-08 00:19:54.000000000","message":"ditto for \"id\"","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @log.log"},{"line_number":176,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":177,"context_line":"        try:"},{"line_number":178,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":179,"context_line":"        except sa_exc.NoResultFound:"},{"line_number":180,"context_line":"            raise eap.ExternalAttachmentPointNotFound(id\u003did)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_2166bfc1","line":177,"updated":"2014-07-03 20:04:05.000000000","message":"We really need all of _get_external_attachment_point, _by_id, and get_external_attachment_point?  (And if the answer is \u0027yes\u0027 then the question would be \u0027where are the comments to explain the differences\u0027?)","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @log.log"},{"line_number":176,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":177,"context_line":"        try:"},{"line_number":178,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":179,"context_line":"        except sa_exc.NoResultFound:"},{"line_number":180,"context_line":"            raise eap.ExternalAttachmentPointNotFound(id\u003did)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_9347d276","line":177,"in_reply_to":"baada198_2166bfc1","updated":"2014-07-04 06:05:57.000000000","message":"Whoops. It looks like _get_external_attachment_point_by_id is just a duplicate of get_external_attachment_point so I can get rid of it.\n\nThe other two are still needed to get either the DB object or to get a dict.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"7b45d5f95b89d4ba703ec3addb713d927dc5af33","unresolved":false,"context_lines":[{"line_number":174,"context_line":""},{"line_number":175,"context_line":"    @log.log"},{"line_number":176,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":177,"context_line":"        try:"},{"line_number":178,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":179,"context_line":"        except sa_exc.NoResultFound:"},{"line_number":180,"context_line":"            raise eap.ExternalAttachmentPointNotFound(id\u003did)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_93e5fddd","line":177,"in_reply_to":"baada198_9347d276","updated":"2014-07-04 19:47:15.000000000","message":"Per enikarov below, do you need functions to return both?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"f528807643230bd4f57038204d804e39feaf7515","unresolved":false,"context_lines":[{"line_number":208,"context_line":"                LOG.error(_(\"The external attachment point \""},{"line_number":209,"context_line":"                            \"\u0027%s\u0027 doesn\u0027t exist\"), id)"},{"line_number":210,"context_line":"                raise eap.ExternalAttachmentPointNotFound(id\u003did)"},{"line_number":211,"context_line":"        return self._make_external_attachment_point_dict(ext_point)"},{"line_number":212,"context_line":""},{"line_number":213,"context_line":"    @log.log"},{"line_number":214,"context_line":"    def get_external_attachment_points(self, context, filters\u003dNone,"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_7cd6b1f2","line":211,"updated":"2014-07-03 12:19:21.000000000","message":"i think db object should be returned here, not dict","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                                       fields\u003dNone, sorts\u003dNone,"},{"line_number":216,"context_line":"                                       limit\u003dNone, marker\u003dNone,"},{"line_number":217,"context_line":"                                       page_reverse\u003dFalse):"},{"line_number":218,"context_line":"        return self._get_collection(context, ExternalAttachmentPoint,"},{"line_number":219,"context_line":"                                    self._make_external_attachment_point_dict,"},{"line_number":220,"context_line":"                                    filters\u003dfilters, fields\u003dfields)"},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_e15da716","line":218,"updated":"2014-07-03 20:04:05.000000000","message":"Gonna be big...  (Probably not that big, but it seems an odd thing to load the whole thing into memory rather than iterating when its size is out of your control)","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"7b45d5f95b89d4ba703ec3addb713d927dc5af33","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                                       fields\u003dNone, sorts\u003dNone,"},{"line_number":216,"context_line":"                                       limit\u003dNone, marker\u003dNone,"},{"line_number":217,"context_line":"                                       page_reverse\u003dFalse):"},{"line_number":218,"context_line":"        return self._get_collection(context, ExternalAttachmentPoint,"},{"line_number":219,"context_line":"                                    self._make_external_attachment_point_dict,"},{"line_number":220,"context_line":"                                    filters\u003dfilters, fields\u003dfields)"},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_b3ea01aa","line":218,"in_reply_to":"baada198_b3dcd6e5","updated":"2014-07-04 19:47:15.000000000","message":"The limit\u0027s key, I think.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                                       fields\u003dNone, sorts\u003dNone,"},{"line_number":216,"context_line":"                                       limit\u003dNone, marker\u003dNone,"},{"line_number":217,"context_line":"                                       page_reverse\u003dFalse):"},{"line_number":218,"context_line":"        return self._get_collection(context, ExternalAttachmentPoint,"},{"line_number":219,"context_line":"                                    self._make_external_attachment_point_dict,"},{"line_number":220,"context_line":"                                    filters\u003dfilters, fields\u003dfields)"},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_b3dcd6e5","line":218,"in_reply_to":"baada198_e15da716","updated":"2014-07-04 06:05:57.000000000","message":"This is the same as the get methods for other neutron objects. However, it does look like I forgot to pass the limit param down into the _get_collection call.\n\nhttps://github.com/openstack/neutron/blob/master/neutron/db/db_base_plugin_v2.py#L1054\n\nhttps://github.com/openstack/neutron/blob/master/neutron/db/db_base_plugin_v2.py#L1573\n\nhttps://github.com/openstack/neutron/blob/master/neutron/db/db_base_plugin_v2.py#L1379","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"23e60555d146983155d595c3c4071c051c0a836b","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    @log.log"},{"line_number":228,"context_line":"    def create_external_attachment_point(self, context,"},{"line_number":229,"context_line":"                                         external_attachment_point):"},{"line_number":230,"context_line":"        ext_ap \u003d external_attachment_point[\u0027external_attachment_point\u0027]"},{"line_number":231,"context_line":"        tenant_id \u003d self._get_tenant_id_for_create(context, ext_ap)"},{"line_number":232,"context_line":"        self.validate_external_attachment_identifier("},{"line_number":233,"context_line":"            context, ext_ap[\u0027attachment_type\u0027], ext_ap[\u0027attachment_id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_a1f80fc4","line":230,"updated":"2014-07-03 20:04:05.000000000","message":"Hm, the line above says that the thing you\u0027re getting is not an external attachment point structure, or the thing you\u0027re starting with is not an external attachment point structure.  Variable naming, therefore, could be better.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    @log.log"},{"line_number":228,"context_line":"    def create_external_attachment_point(self, context,"},{"line_number":229,"context_line":"                                         external_attachment_point):"},{"line_number":230,"context_line":"        ext_ap \u003d external_attachment_point[\u0027external_attachment_point\u0027]"},{"line_number":231,"context_line":"        tenant_id \u003d self._get_tenant_id_for_create(context, ext_ap)"},{"line_number":232,"context_line":"        self.validate_external_attachment_identifier("},{"line_number":233,"context_line":"            context, ext_ap[\u0027attachment_type\u0027], ext_ap[\u0027attachment_id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_d36b0a1c","line":230,"in_reply_to":"baada198_a1f80fc4","updated":"2014-07-04 06:05:57.000000000","message":"This is standard across the code-base when dealing will incoming data from the API.\n\nhttps://github.com/openstack/neutron/blob/master/neutron/db/db_base_plugin_v2.py#L1399\n\nhttps://github.com/openstack/neutron/blob/master/neutron/db/db_base_plugin_v2.py#L1168\n\nhttps://github.com/openstack/neutron/blob/master/neutron/db/db_base_plugin_v2.py#L994","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":3217,"name":"Ian Wells","username":"ijw-ubuntu"},"change_message_id":"7b45d5f95b89d4ba703ec3addb713d927dc5af33","unresolved":false,"context_lines":[{"line_number":227,"context_line":"    @log.log"},{"line_number":228,"context_line":"    def create_external_attachment_point(self, context,"},{"line_number":229,"context_line":"                                         external_attachment_point):"},{"line_number":230,"context_line":"        ext_ap \u003d external_attachment_point[\u0027external_attachment_point\u0027]"},{"line_number":231,"context_line":"        tenant_id \u003d self._get_tenant_id_for_create(context, ext_ap)"},{"line_number":232,"context_line":"        self.validate_external_attachment_identifier("},{"line_number":233,"context_line":"            context, ext_ap[\u0027attachment_type\u0027], ext_ap[\u0027attachment_id\u0027])"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_13d9ed21","line":230,"in_reply_to":"baada198_d36b0a1c","updated":"2014-07-04 19:47:15.000000000","message":"I\u0027ll just go \u0027ew\u0027 and leave it at that.","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"26a689a14ba83bb4e37bab4225edf394f8cf9057","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    description \u003d sa.Column(sa.String(1024))"},{"line_number":62,"context_line":"    attachment_id \u003d sa.Column(sa.String(1024), unique\u003dTrue)"},{"line_number":63,"context_line":"    attachment_type \u003d sa.Column(sa.String(255))"},{"line_number":64,"context_line":"    uix \u003d sa.UniqueConstraint(\u0027attachment_id\u0027, \u0027attachment_type\u0027)"},{"line_number":65,"context_line":"    network_id \u003d sa.Column(sa.String(36),"},{"line_number":66,"context_line":"                           sa.ForeignKey(\u0027networks.id\u0027, ondelete\u003d\u0027SET NULL\u0027),"},{"line_number":67,"context_line":"                           nullable\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_7d2e5d8d","line":64,"updated":"2014-08-22 09:25:23.000000000","message":"UniqueConstraint should be added in __table_args__","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def register_attachment_type_driver(self, driver):"},{"line_number":120,"context_line":"        # use object attribute instead of class attribute"},{"line_number":121,"context_line":"        self.ATTACHMENT_TYPE_DRIVERS \u003d self.ATTACHMENT_TYPE_DRIVERS or {}"},{"line_number":122,"context_line":"        if not self.ATTACHMENT_TYPE_DRIVERS.get(driver.ATTACHMENT_TYPE):"},{"line_number":123,"context_line":"            self.ATTACHMENT_TYPE_DRIVERS[driver.ATTACHMENT_TYPE] \u003d []"},{"line_number":124,"context_line":"        # call initialize to give drivers an opportunity to load necessary"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_47900343","line":121,"updated":"2014-08-29 02:39:00.000000000","message":"self.__class__.ATTACHMENT_TYPE_DRIVERS can be used to avoid creating instance attribute.","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        # use object attribute instead of class attribute"},{"line_number":121,"context_line":"        self.ATTACHMENT_TYPE_DRIVERS \u003d self.ATTACHMENT_TYPE_DRIVERS or {}"},{"line_number":122,"context_line":"        if not self.ATTACHMENT_TYPE_DRIVERS.get(driver.ATTACHMENT_TYPE):"},{"line_number":123,"context_line":"            self.ATTACHMENT_TYPE_DRIVERS[driver.ATTACHMENT_TYPE] \u003d []"},{"line_number":124,"context_line":"        # call initialize to give drivers an opportunity to load necessary"},{"line_number":125,"context_line":"        # configurations"},{"line_number":126,"context_line":"        driver.initialize()"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_e7a02f92","line":123,"updated":"2014-08-29 02:39:00.000000000","message":"dict.setdefault()","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":168,"context_line":"        ext_ap \u003d self._get_external_attachment_point(context, id)"},{"line_number":169,"context_line":"        return self._make_external_attachment_point_dict(ext_ap, fields)"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"    def bind_attachment_point_to_network(self, context, ap, network_id):"},{"line_number":172,"context_line":"        network \u003d self.get_network(context, network_id)"},{"line_number":173,"context_line":"        bound \u003d False"},{"line_number":174,"context_line":"        for driver in self.get_attachment_drivers_for_type("}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_67bc1fbc","line":171,"updated":"2014-08-29 02:39:00.000000000","message":"Is this method public?","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":175,"context_line":"                ap[\u0027attachment_type\u0027]):"},{"line_number":176,"context_line":"            if not bound:"},{"line_number":177,"context_line":"                bound \u003d driver.bind_attachment_point_to_network("},{"line_number":178,"context_line":"                    context, ap, network)"},{"line_number":179,"context_line":"        if not bound:"},{"line_number":180,"context_line":"            raise eap.BindingOperationFailed(operation\u003d\u0027bind\u0027, ext_ap\u003dap,"},{"line_number":181,"context_line":"                                             net_id\u003dnetwork_id)"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_27bea7ae","line":178,"updated":"2014-08-29 02:39:00.000000000","message":"break should be used instead of introducing flag","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":176,"context_line":"            if not bound:"},{"line_number":177,"context_line":"                bound \u003d driver.bind_attachment_point_to_network("},{"line_number":178,"context_line":"                    context, ap, network)"},{"line_number":179,"context_line":"        if not bound:"},{"line_number":180,"context_line":"            raise eap.BindingOperationFailed(operation\u003d\u0027bind\u0027, ext_ap\u003dap,"},{"line_number":181,"context_line":"                                             net_id\u003dnetwork_id)"},{"line_number":182,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_a7e9d7b8","line":179,"updated":"2014-08-29 02:39:00.000000000","message":"for else syntax can be used. Maybe matter of taste though.","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":186,"context_line":"        for driver in self.get_attachment_drivers_for_type("},{"line_number":187,"context_line":"                ap[\u0027attachment_type\u0027]):"},{"line_number":188,"context_line":"            if not unbound:"},{"line_number":189,"context_line":"                unbound \u003d driver.bind_attachment_point_to_network(context,"},{"line_number":190,"context_line":"                                                                  ap, network)"},{"line_number":191,"context_line":"        if not unbound:"},{"line_number":192,"context_line":"            raise eap.BindingOperationFailed(operation\u003d\u0027unbind\u0027, ext_ap\u003dap,"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_27d5c7e4","line":189,"updated":"2014-08-29 02:39:00.000000000","message":"typo? unbind.","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        for driver in self.get_attachment_drivers_for_type(etype):"},{"line_number":203,"context_line":"            try:"},{"line_number":204,"context_line":"                driver.validate_attachment_id(context, body)"},{"line_number":205,"context_line":"                return"},{"line_number":206,"context_line":"            except eap.InvalidAttachmentType as e:"},{"line_number":207,"context_line":"                errors.append(e)"},{"line_number":208,"context_line":"        raise eap.InvalidAttachmentType("}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_87321b5c","line":205,"updated":"2014-08-29 02:39:00.000000000","message":"Only check by first driver?","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":283,"context_line":"                                                  new_network_id)"},{"line_number":284,"context_line":"        return self._make_external_attachment_point_dict(ext_ap_db)"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":"    def set_port_external_attachment_point(self, context, port, ext_id):"},{"line_number":287,"context_line":"        # remove any previous associations"},{"line_number":288,"context_line":"        context.session.query(PortExternalAttachmentBinding).filter_by("},{"line_number":289,"context_line":"            port_id\u003dport[\u0027id\u0027]).delete()"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_e7ad8f32","line":286,"updated":"2014-08-29 02:39:00.000000000","message":"Isn\u0027t this method declaration a part of ExternalAttachmentBase?","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":333,"name":"Isaku Yamahata","email":"isaku.yamahata@gmail.com","username":"yamahata"},"change_message_id":"5672353200b8b9e487c8d0c06c5fe9a77196f713","unresolved":false,"context_lines":[{"line_number":332,"context_line":"            context.session.delete(ext_ap_db)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":""},{"line_number":335,"context_line":"class GenericAttachmentDriver(object):"},{"line_number":336,"context_line":"    \"\"\"Base class for attachment driver types."},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"    Implementations should not inherit from this directly. They should inherit"}],"source_content_type":"text/x-python","patch_set":12,"id":"1abeadc6_a76f17fb","line":335,"updated":"2014-08-29 02:39:00.000000000","message":"This naming is confusing.\nAttachmendDriverBase?","commit_id":"1cea24b1360f020eb73055cf4e6faa6a4de592d7"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"d23da2434185a6fc58772f9eb6dbaa25122d4961","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ExternalAttachmentPoint(model_base.BASEV2, models_v2.HasId,"},{"line_number":34,"context_line":"                              models_v2.HasTenant):"},{"line_number":35,"context_line":"    \"\"\" Stores information about an external attachment point. \"\"\""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"},{"line_number":38,"context_line":"    name \u003d sa.Column(sa.String(255))"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_26e74042","line":35,"range":{"start_line":35,"start_character":7,"end_line":35,"end_character":8},"updated":"2014-09-01 03:45:48.000000000","message":"extra whitespace","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"class ExternalAttachmentPoint(model_base.BASEV2, models_v2.HasId,"},{"line_number":34,"context_line":"                              models_v2.HasTenant):"},{"line_number":35,"context_line":"    \"\"\" Stores information about an external attachment point. \"\"\""},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    __tablename__ \u003d \u0027external_attachment_points\u0027"},{"line_number":38,"context_line":"    name \u003d sa.Column(sa.String(255))"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_4e2a527f","line":35,"in_reply_to":"fa98f980_26e74042","updated":"2014-09-02 08:45:03.000000000","message":"Done","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"d23da2434185a6fc58772f9eb6dbaa25122d4961","unresolved":false,"context_lines":[{"line_number":48,"context_line":"                                eap.ExternalAttachmentMixin,"},{"line_number":49,"context_line":"                                base_db.CommonDbMixin):"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":52,"context_line":"        try:"},{"line_number":53,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":54,"context_line":"        except sa_exc.NoResultFound:"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_c6cf54af","line":51,"range":{"start_line":51,"start_character":54,"end_line":51,"end_character":56},"updated":"2014-09-01 03:45:48.000000000","message":"can you avoid shadowing python builtin \"id\"?\n(throughout this module)","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"4edc994ff93145cfc01230c830b1c9852b307b2c","unresolved":false,"context_lines":[{"line_number":48,"context_line":"                                eap.ExternalAttachmentMixin,"},{"line_number":49,"context_line":"                                base_db.CommonDbMixin):"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":52,"context_line":"        try:"},{"line_number":53,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":54,"context_line":"        except sa_exc.NoResultFound:"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_668adac0","line":51,"in_reply_to":"fa98f980_0e192a79","updated":"2014-09-02 09:24:56.000000000","message":"ok, i don\u0027t insist.","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":48,"context_line":"                                eap.ExternalAttachmentMixin,"},{"line_number":49,"context_line":"                                base_db.CommonDbMixin):"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def _get_external_attachment_point(self, context, id):"},{"line_number":52,"context_line":"        try:"},{"line_number":53,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":54,"context_line":"        except sa_exc.NoResultFound:"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_0e192a79","line":51,"in_reply_to":"fa98f980_c6cf54af","updated":"2014-09-02 08:45:03.000000000","message":"There are currently 525 occurrences of this in the codebase. It feels strange to me to not use the most obvious variable name for an id. Until there is a hacking/PEP8 check to stop this, I don\u0027t want to make these changes because this seems like an arbitrary enforcement.\n\n\n~$ grep -nR \"def \" *  | grep -e \" id)\" -e \" id,\" -e \"(id,\" | wc -l\n\n525","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":12737,"name":"Jacek Swiderski","email":"jacek.swiderski@codilime.com","username":"Altran"},"change_message_id":"d93cfbbd1b6fd1224d66a69216c85fbf434d6e8a","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        try:"},{"line_number":53,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":54,"context_line":"        except sa_exc.NoResultFound:"},{"line_number":55,"context_line":"            LOG.error(_(\"The external attachment point \""},{"line_number":56,"context_line":"                        \"\u0027%s\u0027 doesn\u0027t exist\"), id)"},{"line_number":57,"context_line":"            raise eap.ExternalAttachmentPointNotFound(id\u003did)"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_7149f6cf","line":55,"updated":"2014-09-01 11:09:27.000000000","message":"_LE","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        try:"},{"line_number":53,"context_line":"            return self._get_by_id(context, ExternalAttachmentPoint, id)"},{"line_number":54,"context_line":"        except sa_exc.NoResultFound:"},{"line_number":55,"context_line":"            LOG.error(_(\"The external attachment point \""},{"line_number":56,"context_line":"                        \"\u0027%s\u0027 doesn\u0027t exist\"), id)"},{"line_number":57,"context_line":"            raise eap.ExternalAttachmentPointNotFound(id\u003did)"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_ee6226d7","line":55,"in_reply_to":"fa98f980_7149f6cf","updated":"2014-09-02 08:45:03.000000000","message":"Done","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":12737,"name":"Jacek Swiderski","email":"jacek.swiderski@codilime.com","username":"Altran"},"change_message_id":"d93cfbbd1b6fd1224d66a69216c85fbf434d6e8a","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        try:"},{"line_number":61,"context_line":"            identifier \u003d jsonutils.loads(ext_ap[\u0027attachment_id\u0027])"},{"line_number":62,"context_line":"        except ValueError:"},{"line_number":63,"context_line":"            LOG.error(_(\"Error parsing attachment_id for external attachment \""},{"line_number":64,"context_line":"                        \"point %(id)s. The following is not valid JSON:\\n\""},{"line_number":65,"context_line":"                        \"%(attachment_id)s\"), ext_ap)"},{"line_number":66,"context_line":"            identifier \u003d {}"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_91465abe","line":63,"updated":"2014-09-01 11:09:27.000000000","message":"ditto","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        try:"},{"line_number":61,"context_line":"            identifier \u003d jsonutils.loads(ext_ap[\u0027attachment_id\u0027])"},{"line_number":62,"context_line":"        except ValueError:"},{"line_number":63,"context_line":"            LOG.error(_(\"Error parsing attachment_id for external attachment \""},{"line_number":64,"context_line":"                        \"point %(id)s. The following is not valid JSON:\\n\""},{"line_number":65,"context_line":"                        \"%(attachment_id)s\"), ext_ap)"},{"line_number":66,"context_line":"            identifier \u003d {}"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_0e5e8a12","line":63,"in_reply_to":"fa98f980_91465abe","updated":"2014-09-02 08:45:03.000000000","message":"Done","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"d23da2434185a6fc58772f9eb6dbaa25122d4961","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                    \u0027admin_state_up\u0027: True,"},{"line_number":98,"context_line":"                    \u0027name\u0027: ap.name}}"},{"line_number":99,"context_line":"        p \u003d self.create_port(context, pbody)"},{"line_number":100,"context_line":"        return p"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def create_external_attachment_point(self, context,"},{"line_number":103,"context_line":"                                         external_attachment_point):"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_296c739c","line":100,"updated":"2014-09-01 03:45:48.000000000","message":"this intermediate variable p seems unnecessary.","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                    \u0027admin_state_up\u0027: True,"},{"line_number":98,"context_line":"                    \u0027name\u0027: ap.name}}"},{"line_number":99,"context_line":"        p \u003d self.create_port(context, pbody)"},{"line_number":100,"context_line":"        return p"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def create_external_attachment_point(self, context,"},{"line_number":103,"context_line":"                                         external_attachment_point):"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_4e86d266","line":100,"in_reply_to":"fa98f980_296c739c","updated":"2014-09-02 08:45:03.000000000","message":"Done","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"d23da2434185a6fc58772f9eb6dbaa25122d4961","unresolved":false,"context_lines":[{"line_number":113,"context_line":"                        name\u003dext_ap[\u0027name\u0027], description\u003dext_ap[\u0027name\u0027],"},{"line_number":114,"context_line":"                        attachment_id\u003djsonutils.dumps(ext_ap[\u0027attachment_id\u0027]))"},{"line_number":115,"context_line":"                    context.session.add(ext_ap_db)"},{"line_number":116,"context_line":"            except d_exc.DBDuplicateEntry:"},{"line_number":117,"context_line":"                raise eap.DuplicateExternalAttachmentPoint("},{"line_number":118,"context_line":"                    id\u003dext_ap[\u0027attachment_id\u0027])"},{"line_number":119,"context_line":"            if attributes.is_attr_set(ext_ap[\u0027network_id\u0027]):"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_b4f8bae6","line":116,"updated":"2014-09-01 03:45:48.000000000","message":"is jsonutils.dumps output stable enough for this usage of DBDuplicateEntry?\ni guess you want to specify sort_keys\u003dTrue at least.","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":113,"context_line":"                        name\u003dext_ap[\u0027name\u0027], description\u003dext_ap[\u0027name\u0027],"},{"line_number":114,"context_line":"                        attachment_id\u003djsonutils.dumps(ext_ap[\u0027attachment_id\u0027]))"},{"line_number":115,"context_line":"                    context.session.add(ext_ap_db)"},{"line_number":116,"context_line":"            except d_exc.DBDuplicateEntry:"},{"line_number":117,"context_line":"                raise eap.DuplicateExternalAttachmentPoint("},{"line_number":118,"context_line":"                    id\u003dext_ap[\u0027attachment_id\u0027])"},{"line_number":119,"context_line":"            if attributes.is_attr_set(ext_ap[\u0027network_id\u0027]):"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_2e06eece","line":116,"in_reply_to":"fa98f980_b4f8bae6","updated":"2014-09-02 08:45:03.000000000","message":"If sorted it should be.","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":12737,"name":"Jacek Swiderski","email":"jacek.swiderski@codilime.com","username":"Altran"},"change_message_id":"d93cfbbd1b6fd1224d66a69216c85fbf434d6e8a","unresolved":false,"context_lines":[{"line_number":132,"context_line":"                ext_ap_db \u003d (context.session.query(ExternalAttachmentPoint)."},{"line_number":133,"context_line":"                             filter_by(id\u003did).one())"},{"line_number":134,"context_line":"            except sa_exc.NoResultFound:"},{"line_number":135,"context_line":"                LOG.error(_(\"The external attachment point \""},{"line_number":136,"context_line":"                            \"\u0027%s\u0027 doesn\u0027t exist\"), id)"},{"line_number":137,"context_line":"                raise eap.ExternalAttachmentPointNotFound(id\u003did)"},{"line_number":138,"context_line":"            orig_tenant_id \u003d ext_ap_db.tenant_id"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_f15a4682","line":135,"updated":"2014-09-01 11:09:27.000000000","message":"ditto","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":132,"context_line":"                ext_ap_db \u003d (context.session.query(ExternalAttachmentPoint)."},{"line_number":133,"context_line":"                             filter_by(id\u003did).one())"},{"line_number":134,"context_line":"            except sa_exc.NoResultFound:"},{"line_number":135,"context_line":"                LOG.error(_(\"The external attachment point \""},{"line_number":136,"context_line":"                            \"\u0027%s\u0027 doesn\u0027t exist\"), id)"},{"line_number":137,"context_line":"                raise eap.ExternalAttachmentPointNotFound(id\u003did)"},{"line_number":138,"context_line":"            orig_tenant_id \u003d ext_ap_db.tenant_id"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_ce1ba21a","line":135,"in_reply_to":"fa98f980_f15a4682","updated":"2014-09-02 08:45:03.000000000","message":"Done","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"6cde8fbca464230b2f3cb234da46d183d8292316","unresolved":false,"context_lines":[{"line_number":107,"context_line":"            context, ext_ap[\u0027attachment_id\u0027])"},{"line_number":108,"context_line":"        with context.session.begin(subtransactions\u003dTrue):"},{"line_number":109,"context_line":"            try:"},{"line_number":110,"context_line":"                with context.session.begin(subtransactions\u003dTrue):"},{"line_number":111,"context_line":"                    ext_ap_db \u003d ExternalAttachmentPoint("},{"line_number":112,"context_line":"                        id\u003duuidutils.generate_uuid(), tenant_id\u003dtenant_id,"},{"line_number":113,"context_line":"                        name\u003dext_ap[\u0027name\u0027], description\u003dext_ap[\u0027name\u0027],"}],"source_content_type":"text/x-python","patch_set":16,"id":"fa98f980_cd963ef0","line":110,"updated":"2014-09-02 13:01:15.000000000","message":"why another transaction?","commit_id":"7ede5aa6f1a4d86c9c11910e7d849f591ea8bc87"},{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"6cde8fbca464230b2f3cb234da46d183d8292316","unresolved":false,"context_lines":[{"line_number":167,"context_line":"    def delete_external_attachment_point(self, context, id):"},{"line_number":168,"context_line":"        with context.session.begin(subtransactions\u003dTrue):"},{"line_number":169,"context_line":"            try:"},{"line_number":170,"context_line":"                ext_ap_db \u003d (context.session.query(ExternalAttachmentPoint)."},{"line_number":171,"context_line":"                             filter_by(id\u003did).one())"},{"line_number":172,"context_line":"            except sa_exc.NoResultFound:"},{"line_number":173,"context_line":"                raise eap.ExternalAttachmentPointNotFound(id\u003did)"}],"source_content_type":"text/x-python","patch_set":16,"id":"fa98f980_2d498a8b","line":170,"updated":"2014-09-02 13:01:15.000000000","message":"_get_external_attachment_point here?","commit_id":"7ede5aa6f1a4d86c9c11910e7d849f591ea8bc87"}],"neutron/db/migration/alembic_migrations/versions/30c3572ef845_external_attachment_point.py":[{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"26a689a14ba83bb4e37bab4225edf394f8cf9057","unresolved":false,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"migration_for_plugins \u003d ["},{"line_number":29,"context_line":"    \u0027*\u0027"},{"line_number":30,"context_line":"]"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"from alembic import op"},{"line_number":33,"context_line":"import sqlalchemy as sa"}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_39d15acd","line":30,"updated":"2014-08-22 09:25:23.000000000","message":"Migrations are unconditional now. It was decided to remove all checks that related to it. https://review.openstack.org/108700","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"26a689a14ba83bb4e37bab4225edf394f8cf9057","unresolved":false,"context_lines":[{"line_number":37,"context_line":""},{"line_number":38,"context_line":"def upgrade(active_plugins\u003dNone, options\u003dNone):"},{"line_number":39,"context_line":"    if not migration.should_run(active_plugins, migration_for_plugins):"},{"line_number":40,"context_line":"        return"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    op.create_table("},{"line_number":43,"context_line":"        \u0027external_attachment_points\u0027,"}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_59d456bc","line":40,"updated":"2014-08-22 09:25:23.000000000","message":"Remove this check","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"26a689a14ba83bb4e37bab4225edf394f8cf9057","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        sa.Column(\u0027id\u0027, sa.String(36), nullable\u003dFalse),"},{"line_number":45,"context_line":"        sa.Column(\u0027tenant_id\u0027, sa.String(255), nullable\u003dTrue),"},{"line_number":46,"context_line":"        sa.Column(\u0027name\u0027, sa.String(length\u003d255), nullable\u003dFalse),"},{"line_number":47,"context_line":"        sa.Column(\u0027description\u0027, sa.String(length\u003d1024), nullable\u003dFalse),"},{"line_number":48,"context_line":"        sa.Column(\u0027attachment_id\u0027, sa.String(length\u003d1024), nullable\u003dTrue),"},{"line_number":49,"context_line":"        sa.Column(\u0027attachment_type\u0027, sa.String(length\u003d255), nullable\u003dTrue),"},{"line_number":50,"context_line":"        sa.Column(\u0027network_id\u0027, sa.String(36), nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_79611204","line":47,"updated":"2014-08-22 09:25:23.000000000","message":"Columns name and description don\u0027t have nullable\u003dFalse in model. Remove this here or add to model.","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"26a689a14ba83bb4e37bab4225edf394f8cf9057","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        sa.Column(\u0027status_description\u0027, sa.String(255), nullable\u003dTrue),"},{"line_number":53,"context_line":"        sa.ForeignKeyConstraint([\u0027network_id\u0027], [\u0027networks.id\u0027],"},{"line_number":54,"context_line":"                                ondelete\u003d\u0027SET NULL\u0027),"},{"line_number":55,"context_line":"        sa.PrimaryKeyConstraint(\u0027id\u0027)"},{"line_number":56,"context_line":"    )"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    op.create_table("}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_b9056a15","line":55,"updated":"2014-08-22 09:25:23.000000000","message":"UniqueConstraint for attachment_id is missing.","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"7079e22d576c0b58ada57ba6e6e8b4bed98d8b8d","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        sa.Column(\u0027status_description\u0027, sa.String(255), nullable\u003dTrue),"},{"line_number":53,"context_line":"        sa.ForeignKeyConstraint([\u0027network_id\u0027], [\u0027networks.id\u0027],"},{"line_number":54,"context_line":"                                ondelete\u003d\u0027SET NULL\u0027),"},{"line_number":55,"context_line":"        sa.PrimaryKeyConstraint(\u0027id\u0027)"},{"line_number":56,"context_line":"    )"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    op.create_table("}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_9d3419fd","line":55,"in_reply_to":"1abeadc6_b9056a15","updated":"2014-08-22 10:11:42.000000000","message":"UniqueConstraint does not work on MySQL with a key that large. The constraint can be enforced in the model but not by the DB engine.","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"},{"author":{"_account_id":7249,"name":"Ann Taraday","email":"akamyshnikova@mirantis.com","username":"AKamyshnikova"},"change_message_id":"26a689a14ba83bb4e37bab4225edf394f8cf9057","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"def downgrade(active_plugins\u003dNone, options\u003dNone):"},{"line_number":69,"context_line":"    if not migration.should_run(active_plugins, migration_for_plugins):"},{"line_number":70,"context_line":"        return"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    op.drop_table(\u0027external_attachment_points\u0027)"},{"line_number":73,"context_line":"    op.drop_table(\u0027portexternalattachmentbindings\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1abeadc6_79de72de","line":70,"updated":"2014-08-22 09:25:23.000000000","message":"The same","commit_id":"35589798fb90ef76d96156acd2c8d35a2506cd58"}],"neutron/extensions/external_attachment_points.py":[{"author":{"_account_id":6072,"name":"Eugene Nikanorov","email":"enikanorov@mirantis.com","username":"enikanorov"},"change_message_id":"f528807643230bd4f57038204d804e39feaf7515","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    def get_extended_resources(self, version):"},{"line_number":155,"context_line":"        if version \u003d\u003d \"2.0\":"},{"line_number":156,"context_line":"            #attr.PLURALS.update({\u0027external_attachment_points\u0027:"},{"line_number":157,"context_line":"            #                     \u0027external-attachment-point\u0027})"},{"line_number":158,"context_line":"            return dict(EXTENDED_ATTRIBUTES_2_0.items() +"},{"line_number":159,"context_line":"                        RESOURCE_ATTRIBUTE_MAP.items())"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_1c56955c","line":156,"updated":"2014-07-03 12:19:21.000000000","message":"?","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2ba8737834032ec6962504c14673af9aa890d54c","unresolved":false,"context_lines":[{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    def get_extended_resources(self, version):"},{"line_number":155,"context_line":"        if version \u003d\u003d \"2.0\":"},{"line_number":156,"context_line":"            #attr.PLURALS.update({\u0027external_attachment_points\u0027:"},{"line_number":157,"context_line":"            #                     \u0027external-attachment-point\u0027})"},{"line_number":158,"context_line":"            return dict(EXTENDED_ATTRIBUTES_2_0.items() +"},{"line_number":159,"context_line":"                        RESOURCE_ATTRIBUTE_MAP.items())"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_539c5a0f","line":156,"in_reply_to":"baada198_1c56955c","updated":"2014-07-04 06:05:57.000000000","message":"Leftover stuff from getting the extension setup. :-)","commit_id":"122eb7f401bdfdb9025f390b4748968e7cb78e90"},{"author":{"_account_id":6854,"name":"YAMAMOTO Takashi","email":"yamamoto@midokura.com","username":"yamamoto"},"change_message_id":"d23da2434185a6fc58772f9eb6dbaa25122d4961","unresolved":false,"context_lines":[{"line_number":277,"context_line":"        pass"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    @abc.abstractmethod"},{"line_number":280,"context_line":"    def update_external_attachment_point(self, context, id, attachment_point):"},{"line_number":281,"context_line":"        pass"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @abc.abstractmethod"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_49c5375a","line":280,"range":{"start_line":280,"start_character":56,"end_line":280,"end_character":58},"updated":"2014-09-01 03:45:48.000000000","message":"can you avoid shadowing id?","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"}],"neutron/tests/unit/test_extension_externalattachment.py":[{"author":{"_account_id":12737,"name":"Jacek Swiderski","email":"jacek.swiderski@codilime.com","username":"Altran"},"change_message_id":"d93cfbbd1b6fd1224d66a69216c85fbf434d6e8a","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            req.environ[\u0027neutron.context\u0027] \u003d neutron_context"},{"line_number":133,"context_line":"        res \u003d req.get_response(self.ext_api)"},{"line_number":134,"context_line":"        if expected_res_status:"},{"line_number":135,"context_line":"            self.assertEqual(res.status_int, expected_res_status)"},{"line_number":136,"context_line":"        return res"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def _get_ext_ap(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_91a73a4f","line":135,"updated":"2014-09-01 11:09:27.000000000","message":"nit: expected, observed","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8c25089c9e9937149d90401b598741e0489a1929","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            req.environ[\u0027neutron.context\u0027] \u003d neutron_context"},{"line_number":133,"context_line":"        res \u003d req.get_response(self.ext_api)"},{"line_number":134,"context_line":"        if expected_res_status:"},{"line_number":135,"context_line":"            self.assertEqual(res.status_int, expected_res_status)"},{"line_number":136,"context_line":"        return res"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def _get_ext_ap(self, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":15,"id":"fa98f980_6ea0f643","line":135,"in_reply_to":"fa98f980_91a73a4f","updated":"2014-09-02 08:45:03.000000000","message":"Done","commit_id":"41ed5043a416b6b3a04afdf3dd7671ea7fb9a393"}]}
