)]}'
{"ironic_python_agent/agent.py":[{"author":{"_account_id":18653,"name":"Milan Kováčik","email":"mkovacik@redhat.com","username":"dparalen"},"change_message_id":"7a9a07860a145ae7abe67ba042aa66cc7b816d62","unresolved":false,"context_lines":[{"line_number":214,"context_line":"            return"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"        try:"},{"line_number":217,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":218,"context_line":"            if source.lower().startswith(\u0027fe80:\u0027):"},{"line_number":219,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":220,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":221,"context_line":"                return"},{"line_number":222,"context_line":"            return source"},{"line_number":223,"context_line":"        except IndexError:"},{"line_number":224,"context_line":"            LOG.warning(\u0027No route to host %(dest)s, route record: %(rec)s\u0027,"},{"line_number":225,"context_line":"                        {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    def set_agent_advertise_addr(self):"},{"line_number":228,"context_line":"        \"\"\"Set advertised IP address for the agent, if not already set."}],"source_content_type":"text/x-python","patch_set":2,"id":"1f485f77_cca61fac","line":225,"range":{"start_line":217,"start_character":12,"end_line":225,"end_character":51},"updated":"2017-11-16 14:09:05.000000000","message":"wouldn\u0027t this be useful also for IPv4? how about:\n\n   import ipaddress\n   ...\n\n   try:\n       source \u003d  ...\n       if ipaddress.ip_address(src).is_link_local:\n           # give the interface a chance to configure route\n           # by returning None here\n           LOG.warning(...)\n           return None\n   except IndexError, ValueError: \n       # value err shouldn\u0027t really happen but better\n       # safe than sorry\n       LOG.warning(...)\n   else:\n       return source\n\nIpaddress is tracked in global requirements[1] already so shouldn\u0027t be a big deal to introduce here.\n\n[1] https://github.com/openstack/requirements/blob/master/global-requirements.txt#L83","commit_id":"c055c4c708c5344258ab239d88f2359be98d16a2"},{"author":{"_account_id":18653,"name":"Milan Kováčik","email":"mkovacik@redhat.com","username":"dparalen"},"change_message_id":"ab6a45ea42e1ae3ef0ffba1516c7057d083f5bae","unresolved":false,"context_lines":[{"line_number":214,"context_line":"            return"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"        try:"},{"line_number":217,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":218,"context_line":"            if source.lower().startswith(\u0027fe80:\u0027):"},{"line_number":219,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":220,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":221,"context_line":"                return"},{"line_number":222,"context_line":"            return source"},{"line_number":223,"context_line":"        except IndexError:"},{"line_number":224,"context_line":"            LOG.warning(\u0027No route to host %(dest)s, route record: %(rec)s\u0027,"},{"line_number":225,"context_line":"                        {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    def set_agent_advertise_addr(self):"},{"line_number":228,"context_line":"        \"\"\"Set advertised IP address for the agent, if not already set."}],"source_content_type":"text/x-python","patch_set":2,"id":"1f485f77_ec567b2a","line":225,"range":{"start_line":217,"start_character":12,"end_line":225,"end_character":51},"in_reply_to":"1f485f77_cca61fac","updated":"2017-11-16 14:16:38.000000000","message":"actually, netaddr can be used instead of ipaddr as well:\n\n  netaddr.ip.IPAddress(\u0027fe80::1\u0027).is_link_local()","commit_id":"c055c4c708c5344258ab239d88f2359be98d16a2"},{"author":{"_account_id":18653,"name":"Milan Kováčik","email":"mkovacik@redhat.com","username":"dparalen"},"change_message_id":"d009f27f82410aba0454cc8d79bdb7254efd54d2","unresolved":false,"context_lines":[{"line_number":214,"context_line":"            return"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"        try:"},{"line_number":217,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":218,"context_line":"            if source.lower().startswith(\u0027fe80:\u0027):"},{"line_number":219,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":220,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":221,"context_line":"                return"},{"line_number":222,"context_line":"            return source"},{"line_number":223,"context_line":"        except IndexError:"},{"line_number":224,"context_line":"            LOG.warning(\u0027No route to host %(dest)s, route record: %(rec)s\u0027,"},{"line_number":225,"context_line":"                        {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    def set_agent_advertise_addr(self):"},{"line_number":228,"context_line":"        \"\"\"Set advertised IP address for the agent, if not already set."}],"source_content_type":"text/x-python","patch_set":2,"id":"1f485f77_2324a1ae","line":225,"range":{"start_line":217,"start_character":12,"end_line":225,"end_character":51},"in_reply_to":"1f485f77_e0255f0a","updated":"2017-11-16 14:48:04.000000000","message":"yeah I\u0027m afraid we actually should do it for IPv4 too (same reason -- to retry)\nThe source.lower() shouldn\u0027t be necessary:\n\n  In [10]: netaddr.ip.IPAddress(\u0027FE80::1\u0027)\n  Out[10]: IPAddress(\u0027fe80::1\u0027)","commit_id":"c055c4c708c5344258ab239d88f2359be98d16a2"},{"author":{"_account_id":21909,"name":"Bob Fournier","email":"bfournie@redhat.com","username":"bfournie"},"change_message_id":"ee7f453df54119bd0c2224b840b12bd9e9157265","unresolved":false,"context_lines":[{"line_number":214,"context_line":"            return"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"        try:"},{"line_number":217,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":218,"context_line":"            if source.lower().startswith(\u0027fe80:\u0027):"},{"line_number":219,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":220,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":221,"context_line":"                return"},{"line_number":222,"context_line":"            return source"},{"line_number":223,"context_line":"        except IndexError:"},{"line_number":224,"context_line":"            LOG.warning(\u0027No route to host %(dest)s, route record: %(rec)s\u0027,"},{"line_number":225,"context_line":"                        {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":226,"context_line":""},{"line_number":227,"context_line":"    def set_agent_advertise_addr(self):"},{"line_number":228,"context_line":"        \"\"\"Set advertised IP address for the agent, if not already set."}],"source_content_type":"text/x-python","patch_set":2,"id":"1f485f77_e0255f0a","line":225,"range":{"start_line":217,"start_character":12,"end_line":225,"end_character":51},"in_reply_to":"1f485f77_ec567b2a","updated":"2017-11-16 14:38:35.000000000","message":"+1, I like using netaddr.  I think the syntax would be:\n\nif netaddr.IPAddress(source.lower()).is_link_local()\n\n...\n\nI think its fine to use this even with IPv4 addresses, the netaddr check for an IPv4 link local address is 169.254.0.0/16.","commit_id":"c055c4c708c5344258ab239d88f2359be98d16a2"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"ee6a5df32c9c8b2265f1dbbb0ba85eb0168dc8f2","unresolved":false,"context_lines":[{"line_number":216,"context_line":""},{"line_number":217,"context_line":"        try:"},{"line_number":218,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":219,"context_line":"            if netaddr.ip.IPAddress(source).is_link_local():"},{"line_number":220,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":221,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":222,"context_line":"                return"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f485f77_befbedbe","line":219,"updated":"2017-11-17 08:55:58.000000000","message":"nit: s/ip.// (can be imported from the main module)","commit_id":"bcf2f1a8badcc9810dd4671707f85ba2bb45252e"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ef60e8ea9ea955c90ea100175ba784e126255764","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        try:"},{"line_number":218,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":219,"context_line":"            if netaddr.IPAddress(source).is_link_local():"},{"line_number":220,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":221,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":222,"context_line":"                return"},{"line_number":223,"context_line":"            return source"}],"source_content_type":"text/x-python","patch_set":6,"id":"ff82abbf_8de9b481","line":220,"updated":"2017-11-20 22:35:30.000000000","message":"I wonder why it is a warning instead of an info, since we are ignoring it. I mean, do we even need to LOG anything (or maybe debug?)","commit_id":"d7c0ad47749bc4ddf7464ab83c14085f403fcaf6"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"cf12c9511eaf8d20cbfac04cf74262f5af036c00","unresolved":false,"context_lines":[{"line_number":217,"context_line":"        try:"},{"line_number":218,"context_line":"            source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]"},{"line_number":219,"context_line":"            if netaddr.IPAddress(source).is_link_local():"},{"line_number":220,"context_line":"                LOG.warning(\u0027Ignoring link-local source to %(dest)s: %(rec)s\u0027,"},{"line_number":221,"context_line":"                            {\u0027dest\u0027: dest, \u0027rec\u0027: out})"},{"line_number":222,"context_line":"                return"},{"line_number":223,"context_line":"            return source"}],"source_content_type":"text/x-python","patch_set":6,"id":"ff82abbf_47762009","line":220,"updated":"2017-11-21 07:43:36.000000000","message":"yeah, I think LOG.info is better","commit_id":"d7c0ad47749bc4ddf7464ab83c14085f403fcaf6"}],"ironic_python_agent/tests/unit/test_agent.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"ee6a5df32c9c8b2265f1dbbb0ba85eb0168dc8f2","unresolved":false,"context_lines":[{"line_number":509,"context_line":"        mock_execute.return_value \u003d ("},{"line_number":510,"context_line":"            \u0027XXX src fe80::1234:1234:1234:1234 metric XXX\\n    cache\u0027, None)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"        source \u003d self.agent._get_route_source(\u0027XXX\u0027)"},{"line_number":513,"context_line":"        self.assertIsNone(source)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"    @mock.patch.object(agent, \u0027LOG\u0027, autospec\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f485f77_de10e902","line":512,"updated":"2017-11-17 08:55:58.000000000","message":"++, I\u0027d avoid too much mocking","commit_id":"bcf2f1a8badcc9810dd4671707f85ba2bb45252e"},{"author":{"_account_id":18653,"name":"Milan Kováčik","email":"mkovacik@redhat.com","username":"dparalen"},"change_message_id":"5fcb870adaed0613ff739451713f986c4b390471","unresolved":false,"context_lines":[{"line_number":509,"context_line":"        mock_execute.return_value \u003d ("},{"line_number":510,"context_line":"            \u0027XXX src fe80::1234:1234:1234:1234 metric XXX\\n    cache\u0027, None)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"        source \u003d self.agent._get_route_source(\u0027XXX\u0027)"},{"line_number":513,"context_line":"        self.assertIsNone(source)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"    @mock.patch.object(agent, \u0027LOG\u0027, autospec\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f485f77_f974f669","line":512,"range":{"start_line":512,"start_character":22,"end_line":512,"end_character":45},"updated":"2017-11-16 15:52:17.000000000","message":"I\u0027d probably mock.patch the agent.netaddr.ip.IPAddr here to assert things are sane but that\u0027s maybe not critical... dunno","commit_id":"bcf2f1a8badcc9810dd4671707f85ba2bb45252e"},{"author":{"_account_id":18653,"name":"Milan Kováčik","email":"mkovacik@redhat.com","username":"dparalen"},"change_message_id":"b55c6ee8a35f0f5f0a64060f2d275098fbebbdc8","unresolved":false,"context_lines":[{"line_number":509,"context_line":"        mock_execute.return_value \u003d ("},{"line_number":510,"context_line":"            \u0027XXX src fe80::1234:1234:1234:1234 metric XXX\\n    cache\u0027, None)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"        source \u003d self.agent._get_route_source(\u0027XXX\u0027)"},{"line_number":513,"context_line":"        self.assertIsNone(source)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"    @mock.patch.object(agent, \u0027LOG\u0027, autospec\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f485f77_ff526334","line":512,"range":{"start_line":512,"start_character":22,"end_line":512,"end_character":45},"in_reply_to":"1f485f77_39fdee6d","updated":"2017-11-19 13:50:35.000000000","message":"\u003e If we do that then we\u0027re not testing this line any longer\n\u003e   source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]\n\u003e as we\u0027d be returning None regardless\n\nI\u0027m not sure I follow. I think if the IPAddr is mocked, one can actually assert that the out.strip().split.... is sane:\n\n   self._get_route_source(\u0027XXX\u0027)\n   mock_IPAddress.assert_called_once_with(\u0027fe80:...:1234\u0027)\n\nmoreover, this would allow checking all the cases:\n\n   mock_IPAddress.return_value.is_link_local.return_value \u003d True/False\n   mock.IPAddress.return_value.side_effect \u003d ValueError(\u0027Oops!\u0027)\n\nI don\u0027t mind much tho...","commit_id":"bcf2f1a8badcc9810dd4671707f85ba2bb45252e"},{"author":{"_account_id":1926,"name":"Derek Higgins","email":"derekh@redhat.com","username":"derekh"},"change_message_id":"9428aaba3896dd4df315239d09139f19a566c48a","unresolved":false,"context_lines":[{"line_number":509,"context_line":"        mock_execute.return_value \u003d ("},{"line_number":510,"context_line":"            \u0027XXX src fe80::1234:1234:1234:1234 metric XXX\\n    cache\u0027, None)"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"        source \u003d self.agent._get_route_source(\u0027XXX\u0027)"},{"line_number":513,"context_line":"        self.assertIsNone(source)"},{"line_number":514,"context_line":""},{"line_number":515,"context_line":"    @mock.patch.object(agent, \u0027LOG\u0027, autospec\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1f485f77_39fdee6d","line":512,"range":{"start_line":512,"start_character":22,"end_line":512,"end_character":45},"in_reply_to":"1f485f77_f974f669","updated":"2017-11-16 16:31:45.000000000","message":"If we do that then we\u0027re not testing this line any longer\n    source \u003d out.strip().split(\u0027\\n\u0027)[0].split(\u0027src\u0027)[1].split()[0]\nas we\u0027d be returning None regardless","commit_id":"bcf2f1a8badcc9810dd4671707f85ba2bb45252e"}],"releasenotes/notes/no-link-local-2e861978c5c7bf30.yaml":[{"author":{"_account_id":18653,"name":"Milan Kováčik","email":"mkovacik@redhat.com","username":"dparalen"},"change_message_id":"b55c6ee8a35f0f5f0a64060f2d275098fbebbdc8","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - No longer pick up link-local ip addresses to be used as"},{"line_number":4,"context_line":"    part of the callback_url."}],"source_content_type":"text/x-yaml","patch_set":5,"id":"1f485f77_9fb6cf89","line":4,"range":{"start_line":4,"start_character":16,"end_line":4,"end_character":28},"updated":"2017-11-19 13:50:35.000000000","message":"nit: ``callback_url``","commit_id":"1d4c81b14d981f1284f2093d21fafe6dc3ef7f3f"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"ef60e8ea9ea955c90ea100175ba784e126255764","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"fixes:"},{"line_number":3,"context_line":"  - No longer pick up link-local ip addresses to be used as"},{"line_number":4,"context_line":"    part of the ``callback_url``."}],"source_content_type":"text/x-yaml","patch_set":6,"id":"ff82abbf_2da8a81d","line":4,"updated":"2017-11-20 22:35:30.000000000","message":"How about\n\nFixes the issue where link-local IP addresses were sometimes used as part of the callback URL given to ironic. The routable address is used instead. See `bug 1732692 \u003chttps://bugs.launchpad.net/ironic-python-agent/+bug/1732692\u003e`_ for more details.","commit_id":"d7c0ad47749bc4ddf7464ab83c14085f403fcaf6"}]}
