From: Vincent Bernat Date: Tue, 15 Aug 2017 17:22:00 +0000 (+0200) Subject: client: add "json0" to the list of available formats X-Git-Tag: 0.9.8~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=479d49853a47802b5b631776f93da8e6c30d916e;p=thirdparty%2Flldpd.git client: add "json0" to the list of available formats This enables a more verbose JSON output whose structure is kept the same with one or several neighbors. It's easier to parse than the current structure. Fix #236 --- diff --git a/NEWS b/NEWS index 223bc0eb..2ec8a224 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ lldpd (0.9.8) link information anymore. + Add "configure system hostname ." option to not use a FQDN for system name. + + Add "-f json0" to provide a more regular/machine-parsable output + to JSON output, even when not compiled with --enable-json0. * Fixes: + Handle team interfaces like a bond. Real MAC address cannot be retrieved yet. diff --git a/src/client/json_writer.c b/src/client/json_writer.c index 7ab6d484..163ae19c 100644 --- a/src/client/json_writer.c +++ b/src/client/json_writer.c @@ -49,6 +49,7 @@ struct element { struct json_writer_private { FILE *fh; + int variant; struct element *root; struct element *current; /* should always be an object */ }; @@ -310,7 +311,8 @@ json_element_cleanup(struct element *el) static void json_cleanup(struct json_writer_private *p) { - json_element_cleanup(p->root); + if (p->variant != 0) + json_element_cleanup(p->root); } static void @@ -346,7 +348,7 @@ json_finish(struct writer *w) } struct writer* -json_init(FILE *fh) +json_init(FILE *fh, int variant) { struct writer *result; struct json_writer_private *priv; @@ -356,6 +358,7 @@ json_init(FILE *fh) priv->fh = fh; priv->root = priv->current = json_element_new(NULL, NULL, OBJECT); + priv->variant = variant; result = malloc(sizeof(*result)); if (result == NULL) fatal(NULL, NULL); diff --git a/src/client/lldpcli.8.in b/src/client/lldpcli.8.in index 5f064f03..1a20fa84 100644 --- a/src/client/lldpcli.8.in +++ b/src/client/lldpcli.8.in @@ -60,11 +60,18 @@ version. When repeated, show more build information. Choose the output format. Currently .Em plain , .Em xml , -.Em json +.Em json , +.Em json0 and .Em keyvalue formats are available. The default is .Em plain . +.Em json0 +is more verbose than +.Em json +but the structure of the JSON object is not affected by the number of +interfaces or the number of neighbors. It is therefore easier to +parse. .It Fl c Ar file Read the given configuration file. This option may be repeated several times. If a directory is provided, each file contained in it will be diff --git a/src/client/lldpcli.c b/src/client/lldpcli.c index 7263483c..93da36a4 100644 --- a/src/client/lldpcli.c +++ b/src/client/lldpcli.c @@ -272,7 +272,8 @@ cmd_exec(lldpctl_conn_t *conn, const char *fmt, int argc, const char **argv) if (strcmp(fmt, "plain") == 0) w = txt_init(stdout); else if (strcmp(fmt, "keyvalue") == 0) w = kv_init(stdout); - else if (strcmp(fmt, "json") == 0) w = json_init(stdout); + else if (strcmp(fmt, "json") == 0) w = json_init(stdout, 1); + else if (strcmp(fmt, "json0") == 0) w = json_init(stdout, 0); #ifdef USE_XML else if (strcmp(fmt, "xml") == 0) w = xml_init(stdout); #endif diff --git a/src/client/writer.h b/src/client/writer.h index be9f96a6..e15b30e3 100644 --- a/src/client/writer.h +++ b/src/client/writer.h @@ -37,7 +37,7 @@ struct writer { extern struct writer *txt_init(FILE *); extern struct writer *kv_init(FILE *); -extern struct writer *json_init(FILE *); +extern struct writer *json_init(FILE *, int); #ifdef USE_XML extern struct writer *xml_init(FILE *); diff --git a/tests/integration/test_lldpcli.py b/tests/integration/test_lldpcli.py index d828c06b..dd5b2d71 100644 --- a/tests/integration/test_lldpcli.py +++ b/tests/integration/test_lldpcli.py @@ -117,6 +117,60 @@ def test_json_output(lldpd1, lldpd, lldpcli, namespaces, uname): assert j == expected +@pytest.mark.skipif('JSON' not in pytest.config.lldpcli.outputs, + reason="JSON not supported") +def test_json0_output(lldpd1, lldpd, lldpcli, namespaces, uname): + with namespaces(2): + lldpd() + with namespaces(1): + result = lldpcli("-f", "json0", "show", "neighbors", "details") + assert result.returncode == 0 + out = result.stdout.decode('ascii') + j = json.loads(out) + + eth0 = j['lldp'][0]['interface'][0] + del eth0['age'] + del eth0['chassis'][0]['capability'][3] + del eth0['chassis'][0]['capability'][1] + expected = {"lldp": [{ + "interface": [{ + "name": "eth0", + "via": "LLDP", + "rid": "1", + "chassis": [{ + "id": [{ + "type": "mac", + "value": "00:00:00:00:00:02" + }], + "name": [{"value": "ns-2.example.com"}], + "descr": [{"value": "Spectacular GNU/Linux 2016 {}".format(uname)}], + "mgmt-ip": [{"value": "fe80::200:ff:fe00:2"}], + "capability": [ + {"type": "Bridge", "enabled": False}, + {"type": "Wlan", "enabled": False}, + ]} + ], + "port": [{ + "id": [{ + "type": "mac", + "value": "00:00:00:00:00:02" + }], + "descr": [{"value": "eth1"}], + "ttl": [{"value": "120"}] + }] + }]} + ]} + + if 'Dot3' in pytest.config.lldpd.features: + expected['lldp'][0]['interface'][0]['port'][0]['auto-negotiation'] = [{ + "enabled": False, + "supported": False, + "current": [{"value": + "10GigBaseCX4 - X copper over 8 pair 100-Ohm balanced cable"}] + }] + assert j == expected + + @pytest.mark.skipif('XML' not in pytest.config.lldpcli.outputs, reason="XML not supported") def test_xml_output(lldpd1, lldpd, lldpcli, namespaces, uname):