Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jsonify show neighbor,adj-rib-in,adj-rib-out cmds output #1240

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

vish-321
Copy link

This PR updates ExaBGP to optionally provide JSON output for API commands such as show neighbor, adj-rib-in, and adj-rib-out.

Existing Commands:

show neighbor [optional neighbor ip] summary
show neighbor [optional neighbor ip] extensive
show neighbor [optional neighbor ip] configuration
show adj-rib in [extensive] (to be integrated with neighbor)
show adj-rib out [extensive] (to be integrated with neighbor)

Example Usage for JSON Output:

show neighbor [optional json] [optional neighbor ip] summary
show neighbor [optional json] [optional neighbor ip] extensive
show adj-rib in [optional json] [extensive] (to be integrated with neighbor)
show adj-rib out [optional json] [extensive] (to be integrated with neighbor)

Examples:

show neighbor json summary
show neighbor json extensive
show adj-rib out json

This should also resolve the issue detailed in #909

@@ -7,6 +7,8 @@
License: 3-clause BSD. (See the COPYRIGHT file)
"""

import json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not believe this import is required.

}

if json:
return data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code seems to return a dict and not a string, it should be a string. While python is dynamic, I attempt to only return one type per function, like in C, to ease debugging.

class Neighbor(object):
extensive_kv = ' %-20s %15s %15s %15s'
extensive_template = """\
Neighbor %(peer-address)s
Session Local
Session Local
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like spaces have been converted to tabs


@classmethod
def extensive(cls, answer):
def extensive(cls, answer, output_format='text'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extensive is unlikely to be right as a @classmethod, it is a normal one class function.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One for me to look into if the previous code was already a @classmethod

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, using an output_format as a string, not a boolean or an "enum", is wrong. String should not be given magical if it is possible to compare them.

@@ -73,99 +63,98 @@ class Neighbor(object):
summary_template = '%-15s %-7s %9s %-12s %10d %10d'

@classmethod
def as_dict(cls, answer):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as_dict should not be inlined. It would be better to have as _string added and use two functions for clarity.

@@ -194,22 +183,23 @@ def teardown(self, reactor, service, line):
return False


@Command.register('text', 'show neighbor', False, ['summary', 'extensive', 'configuration', 'json'])
@Command.register('text', 'show neighbor', False, ['summary', 'extensive', 'configuration'])
@Command.register('text', 'show neighbor json', False, ['summary', 'extensive'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we register json, we should also register text and make it work.

peer = self._peers.get(peer_name, None)
if not peer:
log.critical('could not find referenced peer', 'reactor')
return ""
return peer.neighbor.name()
if json:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if statement is not required, return peer.neighbor.name(json) does the same thing AFAICS.

@@ -172,12 +172,16 @@ def neighbor(self, peer_name):
return
return peer.neighbor

def neighbor_name(self, peer_name):
def neighbor_name(self, peer_name, json=False):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

json should be made mandatory and not defaulted to False

try:
rib = words[2]
if not rib in ('in', 'out'):
if not rib in ('in', 'out', 'json'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic seems wrong ... I would need to look more in depth to say why but I can not ATM.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity it is also about the if rib == 'json' part too.

@thomas-mangin
Copy link
Member

Thank you for this PR, I can not accept it as it but I have no objection to adding the feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants