From fa1e4a6389d8fee859234aa130692c028444b6ac Mon Sep 17 00:00:00 2001 From: Garfield Lee Freeman Date: Fri, 18 Sep 2020 13:56:44 -0700 Subject: [PATCH] feat: Add `PanDevice.plugins()` This adds a new function to all `PanDevice` objects, `plugins()`, that returns a list of dicts of plugin information from PAN-OS. This function initially only existed on Panorama, but later existed on firewall as well. PR: #263 --- panos/base.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ tests/test_base.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/panos/base.py b/panos/base.py index c0da0621..cfb169a9 100644 --- a/panos/base.py +++ b/panos/base.py @@ -5235,3 +5235,47 @@ def clock(self): fmt = "%a %b %d %H:%M:%S %Z %Y" text = res.text.strip() return datetime.strptime(text, fmt) + + def plugins(self): + """Returns plugin information. + + Each dict in the list returned has the following keys: + * name + * version + * release_date + * release_note_url + * package_file + * size + * platform + * installed + * downloaded + + Returns: + list of dicts + """ + # Older versions of PAN-OS do not have this command, so if we get an + # exception, just return None. + try: + res = self.op("", cmd_xml=False) + except err.PanDeviceError: + return None + + ans = [] + for o in res.findall("./result/plugins/entry"): + ans.append( + { + "name": o.find("./name").text, + "version": o.find("./version").text, + "release_date": o.find("./release-date").text, + "release_note_url": ( + o.find("./release-note-url").text or "" + ).strip(), + "package_file": o.find("./pkg-file").text, + "size": o.find("./size").text, + "platform": o.find("./platform").text, + "installed": o.find("./installed").text, + "downloaded": o.find("./downloaded").text, + } + ) + + return ans diff --git a/tests/test_base.py b/tests/test_base.py index 6be77961..57d18f20 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1326,5 +1326,50 @@ def test_dot(self): self.assertEqual(ret_val, expected) +class TestPanDevice(unittest.TestCase): + def setUp(self): + self.obj = Base.PanDevice("localhost", "admin", "admin", "secret") + self.obj._version_info = (99, 0, 0) + + def test_plugins_empty_release_note(self): + resp = [ + '', + "", + "vm_series", + "1.0.11", + "Built-in", + "", + "vm_series-1.0.11", + "15M", + "any", + "yes", + "yes", + "", + "", + ] + + spec = { + "return_value": ET.fromstring("".join(resp)), + } + self.obj.op = mock.Mock(**spec) + + ans = self.obj.plugins() + self.assertTrue(ans is not None) + self.assertTrue(isinstance(ans, list)) + self.assertTrue(len(ans) == 1) + + ad = ans[0] + self.assertTrue(isinstance(ad, dict)) + self.assertEqual(ad.get("name"), "vm_series") + self.assertEqual(ad.get("version"), "1.0.11") + self.assertEqual(ad.get("release_date"), "Built-in") + self.assertEqual(ad.get("release_note_url"), "") + self.assertEqual(ad.get("package_file"), "vm_series-1.0.11") + self.assertEqual(ad.get("size"), "15M") + self.assertEqual(ad.get("platform"), "any") + self.assertEqual(ad.get("installed"), "yes") + self.assertEqual(ad.get("downloaded"), "yes") + + if __name__ == "__main__": unittest.main()