)]}'
{"docs/Plugins.md":[{"author":{"_account_id":11515,"name":"Syd Logan","email":"syd.logan@broadcom.com","username":"slogan621"},"change_message_id":"d2c8fadb41c67239db6882921c4cbdeee72dca56","unresolved":false,"context_lines":[{"line_number":1396,"context_line":""},{"line_number":1397,"context_line":"### Overview"},{"line_number":1398,"context_line":"This plugin provides metrics for neutron virtual routers implemented with Open vSwitch.  Much like the libvirt plugin,"},{"line_number":1399,"context_line":"this plug will publish metrics both to the project associated with the virtual router, as well as the infrastructure"},{"line_number":1400,"context_line":"project.  Also similar to the libvirt plugin, metric names that are cross-posted to the infrastructure project will"},{"line_number":1401,"context_line":"have the `vm.` prefix."},{"line_number":1402,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":17,"id":"1a122d0e_0619e879","line":1399,"updated":"2016-05-02 19:31:55.000000000","message":"Nit - this \"plugin\" will publish","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"29e05318363be3baef3a77e96fb35d5c09041809","unresolved":false,"context_lines":[{"line_number":1396,"context_line":""},{"line_number":1397,"context_line":"### Overview"},{"line_number":1398,"context_line":"This plugin provides metrics for neutron virtual routers implemented with Open vSwitch.  Much like the libvirt plugin,"},{"line_number":1399,"context_line":"this plug will publish metrics both to the project associated with the virtual router, as well as the infrastructure"},{"line_number":1400,"context_line":"project.  Also similar to the libvirt plugin, metric names that are cross-posted to the infrastructure project will"},{"line_number":1401,"context_line":"have the `vm.` prefix."},{"line_number":1402,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":17,"id":"1a122d0e_93398f42","line":1399,"in_reply_to":"1a122d0e_0619e879","updated":"2016-05-03 20:25:34.000000000","message":"great catch -- will fix","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"}],"monasca_agent/collector/checks_d/ovs.py":[{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"891a29be75c2e5d82400c542ee6e14990541d2a9","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"        self.use_bits \u003d self.init_config.get(\u0027network_use_bits\u0027)"},{"line_number":44,"context_line":"        cache_dir \u003d self.init_config.get(\u0027cache_dir\u0027)"},{"line_number":45,"context_line":"        self.ctr_cache_file \u003d \"{0}/{1}\".format(cache_dir, \u0027ovs_metrics.json\u0027)"},{"line_number":46,"context_line":"        self.rtr_cache_file \u003d \"{0}/{1}\".format(cache_dir, \u0027ovs_routers.json\u0027)"},{"line_number":47,"context_line":"        self._update_router_cache()"},{"line_number":48,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1a122d0e_b0d59c1c","line":45,"range":{"start_line":45,"start_character":30,"end_line":45,"end_character":77},"updated":"2016-04-22 22:58:50.000000000","message":"Would be better to os.path.join","commit_id":"34a1fa1718cfa0fbcccce0aba1c4dd36afed7080"},{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"891a29be75c2e5d82400c542ee6e14990541d2a9","unresolved":false,"context_lines":[{"line_number":187,"context_line":"                        ifx_name \u003d line[column_num]"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"            # Put the interface data in the main dictionary"},{"line_number":190,"context_line":"            parsed_ovs_data.update({ifx_name: ifx_data})"},{"line_number":191,"context_line":""},{"line_number":192,"context_line":"        return parsed_ovs_data"},{"line_number":193,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1a122d0e_d0bbf873","line":190,"range":{"start_line":190,"start_character":36,"end_line":190,"end_character":44},"updated":"2016-04-22 22:58:50.000000000","message":"Does you need to ensure that ifx_name and ifx_data were actually set to something valid?","commit_id":"34a1fa1718cfa0fbcccce0aba1c4dd36afed7080"},{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"891a29be75c2e5d82400c542ee6e14990541d2a9","unresolved":false,"context_lines":[{"line_number":228,"context_line":""},{"line_number":229,"context_line":"            return errcode, stdout, stderr"},{"line_number":230,"context_line":"        except Exception:"},{"line_number":231,"context_line":"            self.log.error(\"Failure while executing command - {0}\"."},{"line_number":232,"context_line":"                           format(command))"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def _process_command(self, command):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a122d0e_902fc0a0","line":231,"range":{"start_line":231,"start_character":12,"end_line":231,"end_character":26},"updated":"2016-04-22 22:58:50.000000000","message":"You log the error but you don\u0027t set an explicit return.","commit_id":"34a1fa1718cfa0fbcccce0aba1c4dd36afed7080"},{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"891a29be75c2e5d82400c542ee6e14990541d2a9","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            for line in stdout:"},{"line_number":241,"context_line":"                cmd_output \u003d cmd_output + line"},{"line_number":242,"context_line":"            return cmd_output"},{"line_number":243,"context_line":"        except Exception as e:"},{"line_number":244,"context_line":"            self.log.error(\u0027Failure while processing output - {0}\u0027.format(e))"},{"line_number":245,"context_line":""},{"line_number":246,"context_line":"    def _can_sudo(self):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a122d0e_b3012607","line":243,"range":{"start_line":243,"start_character":8,"end_line":243,"end_character":30},"updated":"2016-04-22 22:58:50.000000000","message":"You already catch Exception in _run_command","commit_id":"34a1fa1718cfa0fbcccce0aba1c4dd36afed7080"},{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"891a29be75c2e5d82400c542ee6e14990541d2a9","unresolved":false,"context_lines":[{"line_number":311,"context_line":""},{"line_number":312,"context_line":"        self.log.debug(\"Retrieving Neutron port data\")"},{"line_number":313,"context_line":"        nc \u003d self._get_neutron_client()"},{"line_number":314,"context_line":"        all_ports_data \u003d nc.list_ports()"},{"line_number":315,"context_line":"        all_ports_data \u003d all_ports_data[\u0027ports\u0027]"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"        self.log.debug(\"Retrieving Neutron router data\")"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a122d0e_536892ba","line":314,"range":{"start_line":314,"start_character":25,"end_line":314,"end_character":40},"updated":"2016-04-22 22:58:50.000000000","message":"I assume this can fail because of invalid credentials, etc. What kind of Exception is thrown in that case? I don\u0027t see a handle of that kind of exception, esp in __init__","commit_id":"34a1fa1718cfa0fbcccce0aba1c4dd36afed7080"},{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"34d940cd3cd4dbd352783940bb7b0070e1a01ec0","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        \"\"\""},{"line_number":252,"context_line":"        errcode, stdout, stderr \u003d self._run_command(command)"},{"line_number":253,"context_line":"        cmd_output \u003d \u0027\u0027"},{"line_number":254,"context_line":"        for line in stdout:"},{"line_number":255,"context_line":"            cmd_output \u003d cmd_output + line"},{"line_number":256,"context_line":"        return cmd_output"},{"line_number":257,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_b32338aa","line":254,"range":{"start_line":254,"start_character":20,"end_line":254,"end_character":26},"updated":"2016-04-29 22:06:58.000000000","message":"If the process failed in _run_command, stdout will be None and you will get:\n\nTypeError: \u0027NoneType\u0027 object is not iterable","commit_id":"bd3af1b2763f9be3684a245213b30c17fc71d3ab"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"5117f8baad3d0eee14eff9611fe734b82e2430f9","unresolved":false,"context_lines":[{"line_number":251,"context_line":"        \"\"\""},{"line_number":252,"context_line":"        errcode, stdout, stderr \u003d self._run_command(command)"},{"line_number":253,"context_line":"        cmd_output \u003d \u0027\u0027"},{"line_number":254,"context_line":"        for line in stdout:"},{"line_number":255,"context_line":"            cmd_output \u003d cmd_output + line"},{"line_number":256,"context_line":"        return cmd_output"},{"line_number":257,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_3db7d8f6","line":254,"range":{"start_line":254,"start_character":20,"end_line":254,"end_character":26},"in_reply_to":"1a122d0e_b32338aa","updated":"2016-05-02 14:14:39.000000000","message":"Good catch -- will address in the next patch.","commit_id":"bd3af1b2763f9be3684a245213b30c17fc71d3ab"},{"author":{"_account_id":11809,"name":"Craig Bryant","email":"craig.bryant@hpe.com","username":"craig-bryant"},"change_message_id":"34d940cd3cd4dbd352783940bb7b0070e1a01ec0","unresolved":false,"context_lines":[{"line_number":396,"context_line":""},{"line_number":397,"context_line":"        active_host \u003d None"},{"line_number":398,"context_line":"        local_host \u003d socket.gethostname()"},{"line_number":399,"context_line":"        result \u003d self.neutron_client.list_l3_agent_hosting_routers(router_uuid)"},{"line_number":400,"context_line":"        for agent in result[\u0027agents\u0027]:"},{"line_number":401,"context_line":"            if \u0027ha_state\u0027 not in agent.keys() or agent[\u0027ha_state\u0027] is None:"},{"line_number":402,"context_line":"                #"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_33ad68eb","line":399,"range":{"start_line":399,"start_character":0,"end_line":399,"end_character":79},"updated":"2016-04-29 22:06:58.000000000","message":"This is another call to Neutron. I assume this can fail because of Neutron being down, etc. I don\u0027t see a handle of any exception from this method","commit_id":"bd3af1b2763f9be3684a245213b30c17fc71d3ab"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"5117f8baad3d0eee14eff9611fe734b82e2430f9","unresolved":false,"context_lines":[{"line_number":396,"context_line":""},{"line_number":397,"context_line":"        active_host \u003d None"},{"line_number":398,"context_line":"        local_host \u003d socket.gethostname()"},{"line_number":399,"context_line":"        result \u003d self.neutron_client.list_l3_agent_hosting_routers(router_uuid)"},{"line_number":400,"context_line":"        for agent in result[\u0027agents\u0027]:"},{"line_number":401,"context_line":"            if \u0027ha_state\u0027 not in agent.keys() or agent[\u0027ha_state\u0027] is None:"},{"line_number":402,"context_line":"                #"}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_ddc6a467","line":399,"range":{"start_line":399,"start_character":0,"end_line":399,"end_character":79},"in_reply_to":"1a122d0e_33ad68eb","updated":"2016-05-02 14:14:39.000000000","message":"Great catch -- will fix.","commit_id":"bd3af1b2763f9be3684a245213b30c17fc71d3ab"},{"author":{"_account_id":11515,"name":"Syd Logan","email":"syd.logan@broadcom.com","username":"slogan621"},"change_message_id":"9fac0c18b17295a2ffc2873141daec54937ed74d","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                    ifx_deltas[ifx][idx] \u003d val_diff"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"                if metric_name not in ctr_cache[ifx]:"},{"line_number":114,"context_line":"                    ctr_cache[ifx][metric_name] \u003d {}"},{"line_number":115,"context_line":"                #"},{"line_number":116,"context_line":"                # Save the current counter for this metric to the cache"},{"line_number":117,"context_line":"                # for the next time we wake up"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a122d0e_e675cccc","line":114,"updated":"2016-05-02 19:44:14.000000000","message":"This seems to be clobbered by line 119, is it possible you want to add a \"continue\" statement following this?","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"29e05318363be3baef3a77e96fb35d5c09041809","unresolved":false,"context_lines":[{"line_number":111,"context_line":"                    ifx_deltas[ifx][idx] \u003d val_diff"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"                if metric_name not in ctr_cache[ifx]:"},{"line_number":114,"context_line":"                    ctr_cache[ifx][metric_name] \u003d {}"},{"line_number":115,"context_line":"                #"},{"line_number":116,"context_line":"                # Save the current counter for this metric to the cache"},{"line_number":117,"context_line":"                # for the next time we wake up"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a122d0e_33bb5b77","line":114,"in_reply_to":"1a122d0e_e675cccc","updated":"2016-05-03 20:25:34.000000000","message":"almost -- it\u0027s inititializing to empty the first time the cache is built, but you\u0027re right, it\u0027s not needed, will remove.","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":11515,"name":"Syd Logan","email":"syd.logan@broadcom.com","username":"slogan621"},"change_message_id":"9fac0c18b17295a2ffc2873141daec54937ed74d","unresolved":false,"context_lines":[{"line_number":271,"context_line":"                ctr_cache \u003d json.load(cache_json)"},{"line_number":272,"context_line":"        except (IOError, TypeError, ValueError):"},{"line_number":273,"context_line":"            # The file may not exist yet."},{"line_number":274,"context_line":"            self.log.warning(\"Counter cache missing or corrupt, rebuilding.\")"},{"line_number":275,"context_line":"            ctr_cache \u003d {}"},{"line_number":276,"context_line":"            pass"},{"line_number":277,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a122d0e_e65cac4e","line":274,"updated":"2016-05-02 19:44:14.000000000","message":"Comment seems a little misplaced, unless setting the cache to {} is what you mean by rebuilding. Could the log message maybe be more descriptive of what is happening here (unless setting to {} is what you mean by rebuilding).","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"29e05318363be3baef3a77e96fb35d5c09041809","unresolved":false,"context_lines":[{"line_number":271,"context_line":"                ctr_cache \u003d json.load(cache_json)"},{"line_number":272,"context_line":"        except (IOError, TypeError, ValueError):"},{"line_number":273,"context_line":"            # The file may not exist yet."},{"line_number":274,"context_line":"            self.log.warning(\"Counter cache missing or corrupt, rebuilding.\")"},{"line_number":275,"context_line":"            ctr_cache \u003d {}"},{"line_number":276,"context_line":"            pass"},{"line_number":277,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a122d0e_f380c38d","line":274,"in_reply_to":"1a122d0e_e65cac4e","updated":"2016-05-03 20:25:34.000000000","message":"yup, that\u0027s what it means, will clarify.","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":11515,"name":"Syd Logan","email":"syd.logan@broadcom.com","username":"slogan621"},"change_message_id":"d2c8fadb41c67239db6882921c4cbdeee72dca56","unresolved":false,"context_lines":[{"line_number":273,"context_line":"            # The file may not exist yet."},{"line_number":274,"context_line":"            self.log.warning(\"Counter cache missing or corrupt, rebuilding.\")"},{"line_number":275,"context_line":"            ctr_cache \u003d {}"},{"line_number":276,"context_line":"            pass"},{"line_number":277,"context_line":""},{"line_number":278,"context_line":"        return ctr_cache"},{"line_number":279,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a122d0e_c6909051","line":276,"updated":"2016-05-02 19:31:55.000000000","message":"Perhaps this can be removed?","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"29e05318363be3baef3a77e96fb35d5c09041809","unresolved":false,"context_lines":[{"line_number":273,"context_line":"            # The file may not exist yet."},{"line_number":274,"context_line":"            self.log.warning(\"Counter cache missing or corrupt, rebuilding.\")"},{"line_number":275,"context_line":"            ctr_cache \u003d {}"},{"line_number":276,"context_line":"            pass"},{"line_number":277,"context_line":""},{"line_number":278,"context_line":"        return ctr_cache"},{"line_number":279,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a122d0e_b35dab4a","line":276,"in_reply_to":"1a122d0e_c6909051","updated":"2016-05-03 20:25:34.000000000","message":"good catch","commit_id":"2f19f030c1edcdec35ba2b2b704d4392ac53a798"},{"author":{"_account_id":15130,"name":"Sonu","email":"sonu.sudhakaran@gmail.com","username":"sonu"},"change_message_id":"69e14a59e0258d38a7f356d43b7a93ff08d303f6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":18,"id":"dab17558_d75ac629","updated":"2016-05-09 04:01:34.000000000","message":"Can this plugin be run on compute in case of DVR? In that case, I would say, add a dimension in router to depict if it is distributed versus centralized.\n\nThis also means, it can run alongside libvirt plugin.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6f011fda1623aa40bca4411a4ff4c300a198ff00","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":18,"id":"dab17558_2b7479fb","in_reply_to":"dab17558_d75ac629","updated":"2016-05-09 14:37:58.000000000","message":"Yes, this can be run on compute nodes -- in fact that\u0027s how i\u0027m testing it.  When posting vrouter metrics to the infrastructure project, the hostname is a dimension, which accomplishes what you are describing.  And it does run along side the libvirt plugin just fine:\n\nSuccessfully initialized checks: [\u0027load\u0027, \u0027ovs\u0027, \u0027network\u0027, \u0027process\u0027, \u0027nagios_wrapper\u0027, \u0027libvirt\u0027, \u0027memory\u0027, \u0027disk\u0027, \u0027cpu\u0027]","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":19,"context_line":"sudo /usr/bin/ovs-vsctl \\"},{"line_number":20,"context_line":"--columns\u003dname,external_ids,statistics,options \\"},{"line_number":21,"context_line":"--format\u003djson --data\u003djson list Interface\\"},{"line_number":22,"context_line":"\"\"\""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"\"\"\"Monasca Agent interface for ovs router metrics\"\"\""},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_1f051dc1","line":22,"range":{"start_line":22,"start_character":0,"end_line":22,"end_character":3},"updated":"2016-05-05 20:36:53.000000000","message":"This is a security issue using \"sudo\" to run the command.\n\nThe recommendation from the HPE security team to address this is to copy the command to a new location and the use setcap.\n\nWe discuss this a bit at, https://github.com/openstack/monasca-agent/blob/master/docs/Plugins.md#configuration","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":19,"context_line":"sudo /usr/bin/ovs-vsctl \\"},{"line_number":20,"context_line":"--columns\u003dname,external_ids,statistics,options \\"},{"line_number":21,"context_line":"--format\u003djson --data\u003djson list Interface\\"},{"line_number":22,"context_line":"\"\"\""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"\"\"\"Monasca Agent interface for ovs router metrics\"\"\""},{"line_number":25,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_dee83f7f","line":22,"range":{"start_line":22,"start_character":0,"end_line":22,"end_character":3},"in_reply_to":"1a122d0e_1f051dc1","updated":"2016-05-06 20:29:13.000000000","message":"Hmm.  I wonder if we can make this configurable.  Not all environments have this sudo restriction, and forcing everyone to copy and use setcap seems unnecessary.  Nor do all installations use the monasca-setup process.  What if we had a ovs command path (and \u0027use_sudo\u0027) setting in the cfg file?","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        self.rtr_cache_file \u003d os.path.join(cache_dir, \u0027ovs_routers.json\u0027)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"        self.use_bits \u003d self.init_config.get(\u0027network_use_bits\u0027)"},{"line_number":49,"context_line":"        self.check_router_ha \u003d self.init_config.get(\u0027check_router_ha\u0027)"},{"line_number":50,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_ff7dc1e7","line":49,"range":{"start_line":49,"start_character":36,"end_line":49,"end_character":47},"updated":"2016-05-05 20:36:53.000000000","message":"Are there any other limitations/constraints on when this works. For example, vlan, vxlan, ...","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":15130,"name":"Sonu","email":"sonu.sudhakaran@gmail.com","username":"sonu"},"change_message_id":"69e14a59e0258d38a7f356d43b7a93ff08d303f6","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        self.rtr_cache_file \u003d os.path.join(cache_dir, \u0027ovs_routers.json\u0027)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"        self.use_bits \u003d self.init_config.get(\u0027network_use_bits\u0027)"},{"line_number":49,"context_line":"        self.check_router_ha \u003d self.init_config.get(\u0027check_router_ha\u0027)"},{"line_number":50,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_b72bc393","line":49,"range":{"start_line":49,"start_character":13,"end_line":49,"end_character":28},"updated":"2016-05-09 04:01:34.000000000","message":"It would be nice, if the plugin can automatically detect if the router configured is HA or not. in neutron.conf, you could use the variable \u0027l3_ha\u0027. \nI wont think it would be a good idea to leave it to the installer to set this variable.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        self.rtr_cache_file \u003d os.path.join(cache_dir, \u0027ovs_routers.json\u0027)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"        self.use_bits \u003d self.init_config.get(\u0027network_use_bits\u0027)"},{"line_number":49,"context_line":"        self.check_router_ha \u003d self.init_config.get(\u0027check_router_ha\u0027)"},{"line_number":50,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_fe86e3b7","line":49,"range":{"start_line":49,"start_character":36,"end_line":49,"end_character":47},"in_reply_to":"1a122d0e_ff7dc1e7","updated":"2016-05-06 20:29:13.000000000","message":"This \u0027check_router_ha\u0027 is more a setting for the installer who knows if they support router ha in their environment.  For environments that don\u0027t  yet support router ha -- it\u0027s better to set this to false and avoid additional neutron calls.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6f011fda1623aa40bca4411a4ff4c300a198ff00","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        self.rtr_cache_file \u003d os.path.join(cache_dir, \u0027ovs_routers.json\u0027)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"        self.use_bits \u003d self.init_config.get(\u0027network_use_bits\u0027)"},{"line_number":49,"context_line":"        self.check_router_ha \u003d self.init_config.get(\u0027check_router_ha\u0027)"},{"line_number":50,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_ee0f1f2c","line":49,"range":{"start_line":49,"start_character":13,"end_line":49,"end_character":28},"in_reply_to":"dab17558_b72bc393","updated":"2016-05-09 14:37:58.000000000","message":"Sonu -- we\u0027re running a form of router ha and checking this l3_ha wouldn\u0027t detect this for us:\n\n[DEV] root@bfd02-compute-001:/etc/neutron# grep l3_ha /etc/neutron/neutron.conf\n# l3_ha \u003d False\n# l3_ha_net_cidr \u003d 169.254.192.0/18\n\nBKlein-MBPro:~ bklein$ neutron l3-agent-list-hosting-router 8f2976e8-9ee6-4122-90d2-9a9cbded1d8f\n+--------------------------------------+-------------------+----------------+-------+----------+\n| id                                   | host              | admin_state_up | alive | ha_state |\n+--------------------------------------+-------------------+----------------+-------+----------+\n| 3df1f8da-9d83-4328-be59-5384b8c29e7e | bfd02-compute-006 | True           | :-)   | standby  |\n| 5faf96d9-ff11-48e0-865d-deb29f17f053 | bfd02-compute-001 | True           | :-)   | standby  |\n| 2bba8487-425d-4128-9e2e-0627635dd71d | bfd02-compute-002 | True           | :-)   | active   |\n+--------------------------------------+-------------------+----------------+-------+----------+\n\nIf someone who actually uses the monasca setup process wants to contribute the detection part of this that would be great, but we don\u0027t here and i\u0027d likely not get it right.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":15130,"name":"Sonu","email":"sonu.sudhakaran@gmail.com","username":"sonu"},"change_message_id":"fdee5ea5de29067e1ab9dda6ad79f91ab3a07ce2","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        self.rtr_cache_file \u003d os.path.join(cache_dir, \u0027ovs_routers.json\u0027)"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"        self.use_bits \u003d self.init_config.get(\u0027network_use_bits\u0027)"},{"line_number":49,"context_line":"        self.check_router_ha \u003d self.init_config.get(\u0027check_router_ha\u0027)"},{"line_number":50,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_d5d3ac02","line":49,"range":{"start_line":49,"start_character":13,"end_line":49,"end_character":28},"in_reply_to":"dab17558_ee0f1f2c","updated":"2016-05-10 07:45:01.000000000","message":"Brad That\u0027s correct you cannot decide only based on l3_ha in neutron.conf, since neutron allow creation of HA router using CLI  by admin (only admins) (using --ha) irrespective of l3_ha conf. A run-time check is needed.\n\nAs part of detect plugin, we can minimally enable collection of HA status for each router if lr_ha is True. \nFor all other cases (with admin created HA routers) we rely on your config to collect HA stats.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def check(self, instance):"},{"line_number":54,"context_line":"        self.log.info(\"Collecting OVS router metrics\")"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        if not self._can_sudo():"},{"line_number":57,"context_line":"            raise Exception(\u0027The monasca-agent user does not have sudo access\u0027)"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_8d5e2743","line":54,"range":{"start_line":54,"start_character":13,"end_line":54,"end_character":16},"updated":"2016-05-05 20:36:53.000000000","message":"Do you really want a log info message everytime metrics are collected. Could fill up log files.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        self._update_router_cache()"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def check(self, instance):"},{"line_number":54,"context_line":"        self.log.info(\"Collecting OVS router metrics\")"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        if not self._can_sudo():"},{"line_number":57,"context_line":"            raise Exception(\u0027The monasca-agent user does not have sudo access\u0027)"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_9ebcf76d","line":54,"range":{"start_line":54,"start_character":13,"end_line":54,"end_character":16},"in_reply_to":"1a122d0e_8d5e2743","updated":"2016-05-06 20:29:13.000000000","message":"Good catch -- will remove.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        self.log.info(\"Collecting OVS router metrics\")"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        if not self._can_sudo():"},{"line_number":57,"context_line":"            raise Exception(\u0027The monasca-agent user does not have sudo access\u0027)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        time_start \u003d time.time()"},{"line_number":60,"context_line":"        interface_data \u003d self._get_ovs_data()"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_4d0ecf3d","line":57,"range":{"start_line":57,"start_character":18,"end_line":57,"end_character":27},"updated":"2016-05-05 20:36:53.000000000","message":"I pointed this out up above, but the preferred mechanism is really to copy the command over and then use setcap, such that sudo access is not required.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        self.log.info(\"Collecting OVS router metrics\")"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"        if not self._can_sudo():"},{"line_number":57,"context_line":"            raise Exception(\u0027The monasca-agent user does not have sudo access\u0027)"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        time_start \u003d time.time()"},{"line_number":60,"context_line":"        interface_data \u003d self._get_ovs_data()"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_3ea86b1f","line":57,"range":{"start_line":57,"start_character":18,"end_line":57,"end_character":27},"in_reply_to":"1a122d0e_4d0ecf3d","updated":"2016-05-06 20:29:13.000000000","message":"I can also make this conditional on a config file setting?","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        sample_time \u003d float(\"{:9f}\".format(time.time()))"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        if not interface_data:"},{"line_number":64,"context_line":"            self.log.info(\"No OVS data to report\")"},{"line_number":65,"context_line":"            return"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        rtr_cache \u003d self._load_router_cache()"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_686579df","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":16},"updated":"2016-05-05 20:36:53.000000000","message":"Do you really want to log a message just because you don\u0027t have anything to report?","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        sample_time \u003d float(\"{:9f}\".format(time.time()))"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        if not interface_data:"},{"line_number":64,"context_line":"            self.log.info(\"No OVS data to report\")"},{"line_number":65,"context_line":"            return"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"        rtr_cache \u003d self._load_router_cache()"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_de6ddf05","line":64,"range":{"start_line":64,"start_character":12,"end_line":64,"end_character":16},"in_reply_to":"1a122d0e_686579df","updated":"2016-05-06 20:29:13.000000000","message":"Good catch, will remove.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        ctr_cache \u003d self._load_counter_cache()"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        dims_base \u003d self._set_dimensions({\u0027service\u0027: \u0027neutron\u0027,"},{"line_number":71,"context_line":"                                          \u0027component\u0027: \u0027vm\u0027},"},{"line_number":72,"context_line":"                                         instance)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"        ifx_deltas \u003d {}"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_884bb52a","line":71,"range":{"start_line":71,"start_character":43,"end_line":71,"end_character":52},"updated":"2016-05-05 20:36:53.000000000","message":"Service should be \"networking\" to align with what we use in, https://github.com/openstack/monasca-agent/blob/master/monasca_setup/detection/plugins/neutron.py#L17, as well as the \"generic\" names that we\u0027ve been using so far. For example, compute, image-service, block-storage, object-storage, ...\n\nComponent should be the component that is being measured, such as vswitch or something else. My main point being that I don\u0027t think \"vm\" is a good value as \"vm\" is for virtual machine. I\u0027m not sure what the component that you are measuring in your case is.\n\nI would not supply the service and component dimensions for the customer/tenant metrics, only the operator metrics.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        ctr_cache \u003d self._load_counter_cache()"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        dims_base \u003d self._set_dimensions({\u0027service\u0027: \u0027neutron\u0027,"},{"line_number":71,"context_line":"                                          \u0027component\u0027: \u0027vm\u0027},"},{"line_number":72,"context_line":"                                         instance)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"        ifx_deltas \u003d {}"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_7e4f9392","line":71,"range":{"start_line":71,"start_character":43,"end_line":71,"end_character":52},"in_reply_to":"1a122d0e_884bb52a","updated":"2016-05-06 20:29:13.000000000","message":"Agreed -- will remove service and component from customer metrics, and set service to \u0027networking\u0027, and component to \u0027ovs\u0027.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"35c62525d484bd6be410f6dc3beaca13eea35020","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                                     password\u003dpassword,"},{"line_number":216,"context_line":"                                     tenant_name\u003dtenant_name,"},{"line_number":217,"context_line":"                                     auth_url\u003dauth_url,"},{"line_number":218,"context_line":"                                     endpoint_type\u003d\u0027internalURL\u0027)"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    def _run_command(self, command, input\u003dNone):"},{"line_number":221,"context_line":"        self.log.debug(\"Executing command - {0}\".format(command))"}],"source_content_type":"text/x-python","patch_set":18,"id":"1a122d0e_dfee05b4","line":218,"range":{"start_line":218,"start_character":37,"end_line":218,"end_character":50},"updated":"2016-05-05 20:36:53.000000000","message":"You should probably checkout how the neutron client is initialized in the libvirt plugin at, https://github.com/openstack/monasca-agent/blob/master/monasca_agent/collector/checks_d/libvirt.py#L100\n\nI believe that we only import the neutron client at the point of initialization to allow the plugin to be loaded even if the neutron client is not available on the system.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6dc4e9f8059c30449e8ef284b5f908733f730e3d","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                                     password\u003dpassword,"},{"line_number":216,"context_line":"                                     tenant_name\u003dtenant_name,"},{"line_number":217,"context_line":"                                     auth_url\u003dauth_url,"},{"line_number":218,"context_line":"                                     endpoint_type\u003d\u0027internalURL\u0027)"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    def _run_command(self, command, input\u003dNone):"},{"line_number":221,"context_line":"        self.log.debug(\"Executing command - {0}\".format(command))"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_0138a8d2","line":218,"range":{"start_line":218,"start_character":37,"end_line":218,"end_character":50},"in_reply_to":"1a122d0e_dfee05b4","updated":"2016-05-06 20:29:13.000000000","message":"I see -- will change this to be similar to libvirt, so it could initialize w/out neutron","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":15130,"name":"Sonu","email":"sonu.sudhakaran@gmail.com","username":"sonu"},"change_message_id":"69e14a59e0258d38a7f356d43b7a93ff08d303f6","unresolved":false,"context_lines":[{"line_number":406,"context_line":"            # the router active."},{"line_number":407,"context_line":"            #"},{"line_number":408,"context_line":"            self.log.error(\"Unable to get the hosting agent: {0}\".format(e))"},{"line_number":409,"context_line":"            return True"},{"line_number":410,"context_line":"        for agent in result[\u0027agents\u0027]:"},{"line_number":411,"context_line":"            if \u0027ha_state\u0027 not in agent.keys() or agent[\u0027ha_state\u0027] is None:"},{"line_number":412,"context_line":"                #"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_9702fe07","line":409,"range":{"start_line":409,"start_character":0,"end_line":409,"end_character":12},"updated":"2016-05-09 04:01:34.000000000","message":"This will be mis-leading. If we cannot get the data, do a retry and appropriately set the data to \"unavailable\" rather than setting the value to True. \nFailures would get un-noticed.","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"6f011fda1623aa40bca4411a4ff4c300a198ff00","unresolved":false,"context_lines":[{"line_number":406,"context_line":"            # the router active."},{"line_number":407,"context_line":"            #"},{"line_number":408,"context_line":"            self.log.error(\"Unable to get the hosting agent: {0}\".format(e))"},{"line_number":409,"context_line":"            return True"},{"line_number":410,"context_line":"        for agent in result[\u0027agents\u0027]:"},{"line_number":411,"context_line":"            if \u0027ha_state\u0027 not in agent.keys() or agent[\u0027ha_state\u0027] is None:"},{"line_number":412,"context_line":"                #"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_8b2da548","line":409,"range":{"start_line":409,"start_character":0,"end_line":409,"end_character":12},"in_reply_to":"dab17558_9702fe07","updated":"2016-05-09 14:37:58.000000000","message":"Good point.  I think logging the error and setting to False is the right thing to do and similar to how the libvirt plugin operates.  The result is data won\u0027t be reported for the virtual router for this period, but will be retried the next time the agent wakes up (30 seconds typically).","commit_id":"af4256ba11bb701aaa54bdf3ba71e50c56a6e545"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        rtr_cache \u003d self._load_router_cache()"},{"line_number":58,"context_line":"        ctr_cache \u003d self._load_counter_cache()"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        dims_base \u003d self._set_dimensions({\u0027service\u0027: \u0027networking\u0027,"},{"line_number":61,"context_line":"                                          \u0027component\u0027: \u0027ovs\u0027},"},{"line_number":62,"context_line":"                                         instance)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_eab40b36","line":60,"range":{"start_line":60,"start_character":54,"end_line":60,"end_character":64},"updated":"2016-05-10 07:41:55.000000000","message":"is the dimension value should be monitoring or networking?","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        rtr_cache \u003d self._load_router_cache()"},{"line_number":58,"context_line":"        ctr_cache \u003d self._load_counter_cache()"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        dims_base \u003d self._set_dimensions({\u0027service\u0027: \u0027networking\u0027,"},{"line_number":61,"context_line":"                                          \u0027component\u0027: \u0027ovs\u0027},"},{"line_number":62,"context_line":"                                         instance)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_e26b79ef","line":60,"range":{"start_line":60,"start_character":54,"end_line":60,"end_character":64},"in_reply_to":"dab17558_eab40b36","updated":"2016-05-10 14:38:39.000000000","message":"definitely networking -- see previous exchange with roland","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":63,"context_line":""},{"line_number":64,"context_line":"        ifx_deltas \u003d {}"},{"line_number":65,"context_line":"        for ifx in interface_data:"},{"line_number":66,"context_line":"            if not re.match(r\"^qg-\", ifx):"},{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            if ifx not in ctr_cache:"}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_8af1ff03","line":66,"range":{"start_line":66,"start_character":12,"end_line":66,"end_character":14},"updated":"2016-05-10 07:41:55.000000000","message":"can we make it generic for fetching the interface list ?\nwe can have one excluded interface list fetching from conf file like network.py? so that in future if someone wants to collect the metrics for any other interfaces it would be beneficiary.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":63,"context_line":""},{"line_number":64,"context_line":"        ifx_deltas \u003d {}"},{"line_number":65,"context_line":"        for ifx in interface_data:"},{"line_number":66,"context_line":"            if not re.match(r\"^qg-\", ifx):"},{"line_number":67,"context_line":"                continue"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"            if ifx not in ctr_cache:"}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_dd5578fa","line":66,"range":{"start_line":66,"start_character":12,"end_line":66,"end_character":14},"in_reply_to":"dab17558_8af1ff03","updated":"2016-05-10 14:38:39.000000000","message":"that\u0027s certainly a possible future enhancement -- but it\u0027ll take significantly more than changing this line to publish metrics beyond just the virtual router (qg).  that\u0027s beyond the scope of this initial plugin, but a great idea.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    def _get_ovs_data(self):"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        data_columns \u003d [\u0027name\u0027, \u0027external_ids\u0027, \u0027statistics\u0027, \u0027options\u0027]"},{"line_number":155,"context_line":"        output \u003d self._process_command(self.ovs_cmd)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        parsed_ovs_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_4ad2775d","line":154,"range":{"start_line":154,"start_character":33,"end_line":154,"end_character":45},"updated":"2016-05-10 07:41:55.000000000","message":"can we make the data_columns dynamic ? there can be other names also applicable lets say mac,status etc.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    def _get_ovs_data(self):"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"        data_columns \u003d [\u0027name\u0027, \u0027external_ids\u0027, \u0027statistics\u0027, \u0027options\u0027]"},{"line_number":155,"context_line":"        output \u003d self._process_command(self.ovs_cmd)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"        parsed_ovs_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_9d84905e","line":154,"range":{"start_line":154,"start_character":33,"end_line":154,"end_character":45},"in_reply_to":"dab17558_4ad2775d","updated":"2016-05-10 14:38:39.000000000","message":"as above, if we made these dynamic, we\u0027d also need to add a bunch more code to digest and publish additional metrics (beyond the base metrics for this initial implementation).  but hey -- this is open source -- feel free to add that after this merges :).","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        write_ctr_cache \u003d deepcopy(ctr_cache)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        if self.use_bits:"},{"line_number":277,"context_line":"            metric_name \u003d \u0027vrouter.in_bits_sec\u0027"},{"line_number":278,"context_line":"        else:"},{"line_number":279,"context_line":"            metric_name \u003d \u0027vrouter.in_bytes_sec\u0027"},{"line_number":280,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_ea152be5","line":277,"range":{"start_line":277,"start_character":0,"end_line":277,"end_character":12},"updated":"2016-05-10 07:41:55.000000000","message":"can we have one common function for getting the bytes or bits ?\nI believe Line 295 to 298 also does the same","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":274,"context_line":"        write_ctr_cache \u003d deepcopy(ctr_cache)"},{"line_number":275,"context_line":""},{"line_number":276,"context_line":"        if self.use_bits:"},{"line_number":277,"context_line":"            metric_name \u003d \u0027vrouter.in_bits_sec\u0027"},{"line_number":278,"context_line":"        else:"},{"line_number":279,"context_line":"            metric_name \u003d \u0027vrouter.in_bytes_sec\u0027"},{"line_number":280,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_ddde1710","line":277,"range":{"start_line":277,"start_character":0,"end_line":277,"end_character":12},"in_reply_to":"dab17558_ea152be5","updated":"2016-05-10 14:38:39.000000000","message":"good catch, will clean up.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"3a525125da9bf6dc1d04e14f12cc450190d4065f","unresolved":false,"context_lines":[{"line_number":297,"context_line":"        else:"},{"line_number":298,"context_line":"            measure \u003d \u0027bytes\u0027"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"        metrics_map \u003d {\"vrouter.out_%s_sec\" % measure: \"tx_bytes\","},{"line_number":301,"context_line":"                       \"vrouter.in_%s_sec\" % measure: \"rx_bytes\","},{"line_number":302,"context_line":"                       \"vrouter.in_packets_sec\": \"rx_packets\","},{"line_number":303,"context_line":"                       \"vrouter.out_packets_sec\": \"tx_packets\","}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_c4100a5c","line":300,"range":{"start_line":300,"start_character":56,"end_line":300,"end_character":64},"updated":"2016-05-10 12:17:11.000000000","message":"if the measure is bits then the metrics_map value would still be rx_bytes?","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":297,"context_line":"        else:"},{"line_number":298,"context_line":"            measure \u003d \u0027bytes\u0027"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"        metrics_map \u003d {\"vrouter.out_%s_sec\" % measure: \"tx_bytes\","},{"line_number":301,"context_line":"                       \"vrouter.in_%s_sec\" % measure: \"rx_bytes\","},{"line_number":302,"context_line":"                       \"vrouter.in_packets_sec\": \"rx_packets\","},{"line_number":303,"context_line":"                       \"vrouter.out_packets_sec\": \"tx_packets\","}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_7d9a8b6f","line":300,"range":{"start_line":300,"start_character":56,"end_line":300,"end_character":64},"in_reply_to":"dab17558_c4100a5c","updated":"2016-05-10 14:38:39.000000000","message":"yes -- rx_bytes is how the data is returned by ovs-vsctl, and we take that and either publish bits or bytes depending on the config file setting.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"6a40bf364cae6cb9412c49ca854acbf67ba4d8ab","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        \"\"\"Collect port_uuid, router_uuid, router_name, and tenant_id"},{"line_number":313,"context_line":"        for all routers."},{"line_number":314,"context_line":"        \"\"\""},{"line_number":315,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":316,"context_line":"        router_cache \u003d {}"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_d8a8eedd","line":315,"range":{"start_line":315,"start_character":35,"end_line":315,"end_character":54},"updated":"2016-05-10 12:20:51.000000000","message":"for each ifx_deltas at line no 115 why do we need to get the neutron client _get_neutron_client?","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":312,"context_line":"        \"\"\"Collect port_uuid, router_uuid, router_name, and tenant_id"},{"line_number":313,"context_line":"        for all routers."},{"line_number":314,"context_line":"        \"\"\""},{"line_number":315,"context_line":"        self.neutron_client \u003d self._get_neutron_client()"},{"line_number":316,"context_line":"        router_cache \u003d {}"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_3d1f6309","line":315,"range":{"start_line":315,"start_character":35,"end_line":315,"end_character":54},"in_reply_to":"dab17558_d8a8eedd","updated":"2016-05-10 14:38:39.000000000","message":"will change this to see if we already have the neutron client -- attempting to lazy load it (and avoid it in the init() method -- see previous comments).","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        for port_data in all_ports_data:"},{"line_number":331,"context_line":"            port_uuid \u003d port_data[\u0027id\u0027]"},{"line_number":332,"context_line":"            router_uuid \u003d port_data[\u0027device_id\u0027]"},{"line_number":333,"context_line":"            router_info \u003d self._get_os_info(router_uuid, all_routers_data)"},{"line_number":334,"context_line":"            #"},{"line_number":335,"context_line":"            # If we don\u0027t have router info for the port, let\u0027s not"},{"line_number":336,"context_line":"            # cache it."}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_350b1890","line":333,"range":{"start_line":333,"start_character":56,"end_line":333,"end_character":57},"updated":"2016-05-10 07:41:55.000000000","message":"Just a question . do we need to provide all the router data for each port for getting the router info?","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":330,"context_line":"        for port_data in all_ports_data:"},{"line_number":331,"context_line":"            port_uuid \u003d port_data[\u0027id\u0027]"},{"line_number":332,"context_line":"            router_uuid \u003d port_data[\u0027device_id\u0027]"},{"line_number":333,"context_line":"            router_info \u003d self._get_os_info(router_uuid, all_routers_data)"},{"line_number":334,"context_line":"            #"},{"line_number":335,"context_line":"            # If we don\u0027t have router info for the port, let\u0027s not"},{"line_number":336,"context_line":"            # cache it."}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_fdb67bf7","line":333,"range":{"start_line":333,"start_character":56,"end_line":333,"end_character":57},"in_reply_to":"dab17558_350b1890","updated":"2016-05-10 14:38:39.000000000","message":"we aren\u0027t re-collecting router data for each port -- that would be bad :).  we\u0027re just grabbing a given router\u0027s data from what was already collected for each port.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":373,"context_line":"                        self._update_router_cache()"},{"line_number":374,"context_line":"        except (IOError, TypeError, ValueError):"},{"line_number":375,"context_line":"            # The file may not exist yet, or is corrupt.  Rebuild it now."},{"line_number":376,"context_line":"            self.log.warning(\"Router cache missing or corrupt, rebuilding.\")"},{"line_number":377,"context_line":"            router_cache \u003d self._update_router_cache()"},{"line_number":378,"context_line":"            pass"},{"line_number":379,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_75ebe078","line":376,"range":{"start_line":376,"start_character":21,"end_line":376,"end_character":28},"updated":"2016-05-10 07:41:55.000000000","message":"log.warning- \u003e error?","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":373,"context_line":"                        self._update_router_cache()"},{"line_number":374,"context_line":"        except (IOError, TypeError, ValueError):"},{"line_number":375,"context_line":"            # The file may not exist yet, or is corrupt.  Rebuild it now."},{"line_number":376,"context_line":"            self.log.warning(\"Router cache missing or corrupt, rebuilding.\")"},{"line_number":377,"context_line":"            router_cache \u003d self._update_router_cache()"},{"line_number":378,"context_line":"            pass"},{"line_number":379,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_7dbd6cb6","line":376,"range":{"start_line":376,"start_character":21,"end_line":376,"end_character":28},"in_reply_to":"dab17558_75ebe078","updated":"2016-05-10 14:38:39.000000000","message":"good comment.  i think warning is appropriate, given that we\u0027ll hit this the first time the agent runs and initially builds the file.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":10781,"name":"selvakumar","email":"selvakumar.s2@hpe.com","username":"selvakumar"},"change_message_id":"8bee279c331138c1aca0b1d7ceeb1ce2d8baa8b6","unresolved":false,"context_lines":[{"line_number":375,"context_line":"            # The file may not exist yet, or is corrupt.  Rebuild it now."},{"line_number":376,"context_line":"            self.log.warning(\"Router cache missing or corrupt, rebuilding.\")"},{"line_number":377,"context_line":"            router_cache \u003d self._update_router_cache()"},{"line_number":378,"context_line":"            pass"},{"line_number":379,"context_line":""},{"line_number":380,"context_line":"        return router_cache"},{"line_number":381,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_151ff4b7","line":378,"range":{"start_line":378,"start_character":0,"end_line":378,"end_character":12},"updated":"2016-05-10 07:41:55.000000000","message":"is pass  required here?","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"3b295601760a40695a39743927219c5daa7b9041","unresolved":false,"context_lines":[{"line_number":375,"context_line":"            # The file may not exist yet, or is corrupt.  Rebuild it now."},{"line_number":376,"context_line":"            self.log.warning(\"Router cache missing or corrupt, rebuilding.\")"},{"line_number":377,"context_line":"            router_cache \u003d self._update_router_cache()"},{"line_number":378,"context_line":"            pass"},{"line_number":379,"context_line":""},{"line_number":380,"context_line":"        return router_cache"},{"line_number":381,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"dab17558_3da9247c","line":378,"range":{"start_line":378,"start_character":0,"end_line":378,"end_character":12},"in_reply_to":"dab17558_151ff4b7","updated":"2016-05-10 14:38:39.000000000","message":"good catch!  will remove.","commit_id":"e041de500ebf4f3838c5253a39e93f09e418362e"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"41b720e9fb8b08d900b8ead8187786144c5c651b","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def check(self, instance):"},{"line_number":44,"context_line":"        if not self._can_sudo():"},{"line_number":45,"context_line":"            raise Exception(\u0027The monasca-agent user does not have sudo access\u0027)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"        time_start \u003d time.time()"},{"line_number":48,"context_line":"        interface_data \u003d self._get_ovs_data()"}],"source_content_type":"text/x-python","patch_set":21,"id":"bab6814e_6f823454","line":45,"range":{"start_line":45,"start_character":17,"end_line":45,"end_character":18},"updated":"2016-05-18 23:07:48.000000000","message":"It doesn\u0027t look like you addressed that sudo is required. Our security group won\u0027t allow us to run the command as sudo.","commit_id":"c2cc71260b38d4aab694df8aba0ed63e581fd112"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"076ac6b7bb9318fd60d0decbbc767e8f99734290","unresolved":false,"context_lines":[{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def check(self, instance):"},{"line_number":44,"context_line":"        if not self._can_sudo():"},{"line_number":45,"context_line":"            raise Exception(\u0027The monasca-agent user does not have sudo access\u0027)"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"        time_start \u003d time.time()"},{"line_number":48,"context_line":"        interface_data \u003d self._get_ovs_data()"}],"source_content_type":"text/x-python","patch_set":21,"id":"bab6814e_f31e4a5e","line":45,"range":{"start_line":45,"start_character":17,"end_line":45,"end_character":18},"in_reply_to":"bab6814e_6f823454","updated":"2016-05-23 19:24:56.000000000","message":"Good catch roland.  i\u0027d change this such that you can specify the location (and sudo) of the ovs-vsctl command in the config file.  This should allow installations like yours to run from a customized location with a command modified by setcap -- and other installations to simply call it in it\u0027s installed location with sudo.  I\u0027d just forgotten to remove this check.","commit_id":"c2cc71260b38d4aab694df8aba0ed63e581fd112"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"41b720e9fb8b08d900b8ead8187786144c5c651b","unresolved":false,"context_lines":[{"line_number":76,"context_line":"                    cache_time \u003d ctr_cache[ifx][metric_name][\u0027timestamp\u0027]"},{"line_number":77,"context_line":"                    time_diff \u003d sample_time - float(cache_time)"},{"line_number":78,"context_line":"                    val_diff \u003d (value - ctr_cache[ifx][metric_name][\u0027value\u0027]) \\"},{"line_number":79,"context_line":"                        / time_diff"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"                    if val_diff \u003c 0:"},{"line_number":82,"context_line":"                        #"}],"source_content_type":"text/x-python","patch_set":21,"id":"bab6814e_6fd07454","line":79,"range":{"start_line":79,"start_character":26,"end_line":79,"end_character":35},"updated":"2016-05-18 23:07:48.000000000","message":"Can time_diff \u003d 0 and result in an exception?","commit_id":"c2cc71260b38d4aab694df8aba0ed63e581fd112"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"076ac6b7bb9318fd60d0decbbc767e8f99734290","unresolved":false,"context_lines":[{"line_number":76,"context_line":"                    cache_time \u003d ctr_cache[ifx][metric_name][\u0027timestamp\u0027]"},{"line_number":77,"context_line":"                    time_diff \u003d sample_time - float(cache_time)"},{"line_number":78,"context_line":"                    val_diff \u003d (value - ctr_cache[ifx][metric_name][\u0027value\u0027]) \\"},{"line_number":79,"context_line":"                        / time_diff"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"                    if val_diff \u003c 0:"},{"line_number":82,"context_line":"                        #"}],"source_content_type":"text/x-python","patch_set":21,"id":"bab6814e_73337af7","line":79,"range":{"start_line":79,"start_character":26,"end_line":79,"end_character":35},"in_reply_to":"bab6814e_6fd07454","updated":"2016-05-23 19:24:56.000000000","message":"Anything is possible :).  I\u0027ll add a check...","commit_id":"c2cc71260b38d4aab694df8aba0ed63e581fd112"},{"author":{"_account_id":2419,"name":"Roland Hochmuth","email":"roland.hochmuth@hpe.com","username":"roland-hochmuth-s"},"change_message_id":"41b720e9fb8b08d900b8ead8187786144c5c651b","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        if not output:"},{"line_number":159,"context_line":"            return parsed_ovs_data"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        raw_ovs_json_data \u003d json.loads(output)"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"        # There are multiple lines returned, one for each device"},{"line_number":164,"context_line":"        for line in raw_ovs_json_data[\u0027data\u0027]:"}],"source_content_type":"text/x-python","patch_set":21,"id":"bab6814e_ef4bc429","line":161,"range":{"start_line":161,"start_character":33,"end_line":161,"end_character":38},"updated":"2016-05-18 23:07:48.000000000","message":"Is output guaranteed to be valid json?","commit_id":"c2cc71260b38d4aab694df8aba0ed63e581fd112"},{"author":{"_account_id":8126,"name":"Bradley Klein","email":"bradley.klein@charter.com","username":"bklei"},"change_message_id":"076ac6b7bb9318fd60d0decbbc767e8f99734290","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        if not output:"},{"line_number":159,"context_line":"            return parsed_ovs_data"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"        raw_ovs_json_data \u003d json.loads(output)"},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"        # There are multiple lines returned, one for each device"},{"line_number":164,"context_line":"        for line in raw_ovs_json_data[\u0027data\u0027]:"}],"source_content_type":"text/x-python","patch_set":21,"id":"bab6814e_d35a262a","line":161,"range":{"start_line":161,"start_character":33,"end_line":161,"end_character":38},"in_reply_to":"bab6814e_ef4bc429","updated":"2016-05-23 19:24:56.000000000","message":"great comment.  can\u0027t hurt to add a check -- will roll another patch when i rebase...","commit_id":"c2cc71260b38d4aab694df8aba0ed63e581fd112"}]}
