From 4f65e00c31ea011576a2b5203ff41e131e9a2c03 Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Wed, 3 Mar 2021 13:33:47 +0000 Subject: [PATCH 01/21] Added support for dynamic interface attachment detection --- acos_client/v30/action.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/acos_client/v30/action.py b/acos_client/v30/action.py index 0c122e02..4980474b 100644 --- a/acos_client/v30/action.py +++ b/acos_client/v30/action.py @@ -119,3 +119,11 @@ def get_vcs_summary_oper(self): def get_thunder_up_time(self): url = "/miscellenious-alb/oper" return self._get(url) + + def probe_network_devices(self): + url = "/system/probe-network-devices" + self._post(url) + + def get_acos_version(self): + url = "/version/oper" + return self._get(url) From ba24047795d3f1d2bf557986524b2d3bc28db830 Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Thu, 4 Mar 2021 10:04:50 +0000 Subject: [PATCH 02/21] Modified tox to fix travis issues --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 6d2467e2..9e989c12 100644 --- a/tox.ini +++ b/tox.ini @@ -17,6 +17,7 @@ deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = python setup.py test -q {posargs} +uhashring==1.2 [testenv:pep8] basepython = python3.6 From 2e8ed15368a8a503dc4fe35004904bef74c2facd Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Thu, 4 Mar 2021 10:21:40 +0000 Subject: [PATCH 03/21] Fixed travis issue --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9e989c12..ee06b718 100644 --- a/tox.ini +++ b/tox.ini @@ -16,8 +16,8 @@ install_command = pip install -U {opts} {packages} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt + uhashring==1.2 commands = python setup.py test -q {posargs} -uhashring==1.2 [testenv:pep8] basepython = python3.6 From 879c46bedcfe573515a62b2077972cf2a3e304e9 Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Thu, 4 Mar 2021 10:27:08 +0000 Subject: [PATCH 04/21] reverted tox changes and modified requirements --- requirements.txt | 2 +- tox.ini | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d7be1a21..3a7c54ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ requests>=2.3.0 six -uhashring +uhashring==1.2 ipaddress==1.0.22; python_version < '3.0' diff --git a/tox.ini b/tox.ini index ee06b718..6d2467e2 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,6 @@ install_command = pip install -U {opts} {packages} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt - uhashring==1.2 commands = python setup.py test -q {posargs} [testenv:pep8] From 9096e760368315174897da76b757b3bb785ca865 Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Mon, 8 Mar 2021 07:22:45 +0000 Subject: [PATCH 05/21] Incorporated review comment to add reload_reboot method --- acos_client/v30/action.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/acos_client/v30/action.py b/acos_client/v30/action.py index 4980474b..1163dd51 100644 --- a/acos_client/v30/action.py +++ b/acos_client/v30/action.py @@ -127,3 +127,18 @@ def probe_network_devices(self): def get_acos_version(self): url = "/version/oper" return self._get(url) + + def reload_reboot(self, acos_version=None): + if not acos_version: + version_summary = self.get_acos_version() + acos_version = version_summary['version']['oper']['sw-version'].split(',')[0] + + major = acos_version.split('.')[0] + minor = acos_version.split('.')[1] + patch = acos_version.split('.')[2] + + if major >= 5 and minor >= 2 and patch >= 0: + self.probe_network_devices() + self.reload() + else: + self.reboot() From fa8c04c419a1a4be2b37d4bba9c0e5f216e7d940 Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Tue, 9 Mar 2021 07:01:11 +0000 Subject: [PATCH 06/21] Modified API name from reload_reboot to reload_reboot_for_interface_attachment --- acos_client/v30/action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acos_client/v30/action.py b/acos_client/v30/action.py index 1163dd51..bb017f8b 100644 --- a/acos_client/v30/action.py +++ b/acos_client/v30/action.py @@ -128,7 +128,7 @@ def get_acos_version(self): url = "/version/oper" return self._get(url) - def reload_reboot(self, acos_version=None): + def reload_reboot_for_interface_attachment(self, acos_version=None): if not acos_version: version_summary = self.get_acos_version() acos_version = version_summary['version']['oper']['sw-version'].split(',')[0] From 7066a752af6a587282eb9447884520b80d03e8c8 Mon Sep 17 00:00:00 2001 From: NehaKembalkarA10 Date: Fri, 12 Mar 2021 15:34:19 +0000 Subject: [PATCH 07/21] Added API for performing reload/reboot for interface detachment --- acos_client/v30/action.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/acos_client/v30/action.py b/acos_client/v30/action.py index bb017f8b..71a3848f 100644 --- a/acos_client/v30/action.py +++ b/acos_client/v30/action.py @@ -142,3 +142,18 @@ def reload_reboot_for_interface_attachment(self, acos_version=None): self.reload() else: self.reboot() + + def reload_reboot_for_interface_detachment(self, acos_version=None): + if not acos_version: + version_summary = self.get_acos_version() + acos_version = version_summary['version']['oper']['sw-version'].split(',')[0] + + major = acos_version.split('.')[0] + minor = acos_version.split('.')[1] + patch = acos_version.split('.')[2] + + if major >= 5 and minor >= 2 and patch >= 1: + self.probe_network_devices() + self.reload() + else: + self.reboot() From 6dcd76209c4791f250a4ce0d02b8fd65a43135af Mon Sep 17 00:00:00 2001 From: hthompson Date: Wed, 7 Apr 2021 11:55:39 -0700 Subject: [PATCH 08/21] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 6fb717de..14f8da87 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,6 @@ $ tox ## Issues and Inquiries For all issues, please send an email to support@a10networks.com -For general inquiries, please send an email to opensource@a10networks.com - ## Helpful links From e99a34d03b5a1667aa2928d7c0d93d821b0d7a93 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Tue, 13 Apr 2021 15:18:16 +0000 Subject: [PATCH 09/21] [STACK-2220] acos-client timeout too short --- acos_client/v30/base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acos_client/v30/base.py b/acos_client/v30/base.py index 719f839f..47c5f2d2 100644 --- a/acos_client/v30/base.py +++ b/acos_client/v30/base.py @@ -64,19 +64,19 @@ def _request(self, method, action, params, retry_count=0, max_retries=None, timeout=timeout, axapi_args=axapi_args, **kwargs) raise e - def _get(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): + def _get(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): return self._request('GET', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _post(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): + def _post(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): return self._request('POST', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _put(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): + def _put(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): return self._request('PUT', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _delete(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): + def _delete(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): return self._request('DELETE', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) From 377168165e3d0b33494d929970c1e7c1684f9088 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Tue, 13 Apr 2021 15:44:12 +0000 Subject: [PATCH 10/21] fix unit-test issues --- acos_client/tests/unit/v30/test_bladeparam.py | 26 +++++++++---------- acos_client/tests/unit/v30/test_dns.py | 10 +++---- acos_client/tests/unit/v30/test_interface.py | 16 ++++++------ acos_client/tests/unit/v30/test_vlan.py | 20 +++++++------- acos_client/tests/unit/v30/test_vrrpa.py | 18 ++++++------- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/acos_client/tests/unit/v30/test_bladeparam.py b/acos_client/tests/unit/v30/test_bladeparam.py index a5df3246..03ffcc5e 100644 --- a/acos_client/tests/unit/v30/test_bladeparam.py +++ b/acos_client/tests/unit/v30/test_bladeparam.py @@ -83,21 +83,21 @@ def _build_ipv6gateway(self, ip_address, priority_cost=1): def test_blade_get(self): self.target.get(0) self.client.http.request.assert_called_with("GET", self.url_prefix.format(0), {}, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_create(self): self.target.create(4) self.client.http.request.assert_called_with( "POST", self.url_prefix.format(4), self._expected_payload(), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_create_priority(self): self.target.create(4, 122) self.client.http.request.assert_called_with( "POST", self.url_prefix.format(4), self._expected_payload(122), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_create_interface(self): interface = self._build_interface() @@ -107,7 +107,7 @@ def test_blade_create_interface(self): self.client.http.request.assert_called_with( "POST", self.url_prefix.format(4), self._expected_payload(interface=interface), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_create_gateway(self): gateway = self._build_ipv4gateway('1.1.1.1') @@ -117,7 +117,7 @@ def test_blade_create_gateway(self): self.client.http.request.assert_called_with( "POST", self.url_prefix.format(4), self._expected_payload(gateway=gateway), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_create_gateway_ipv6(self): gateway = self._build_ipv6gateway('1.1.1.1') @@ -127,7 +127,7 @@ def test_blade_create_gateway_ipv6(self): self.client.http.request.assert_called_with( "POST", self.url_prefix.format(4), self._expected_payload(gateway=gateway), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_create_interface_gateway(self): interface = self._build_interface() @@ -139,21 +139,21 @@ def test_blade_create_interface_gateway(self): self.client.http.request.assert_called_with( "POST", self.url_prefix.format(4), self._expected_payload(interface=interface, gateway=gateway), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_update(self): self.target.update(4) self.client.http.request.assert_called_with( "PUT", self.url_prefix.format(4), self._expected_payload(), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_update_priority(self): self.target.update(4, 122) self.client.http.request.assert_called_with( "PUT", self.url_prefix.format(4), self._expected_payload(122), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_update_interface(self): interface = self._build_interface() @@ -163,7 +163,7 @@ def test_blade_update_interface(self): self.client.http.request.assert_called_with( "PUT", self.url_prefix.format(4), self._expected_payload(interface=interface), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_update_gateway(self): gateway = self._build_ipv4gateway('1.1.1.1') @@ -173,7 +173,7 @@ def test_blade_update_gateway(self): self.client.http.request.assert_called_with( "PUT", self.url_prefix.format(4), self._expected_payload(gateway=gateway), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_update_gateway_ipv6(self): gateway = self._build_ipv6gateway('1.1.1.1') @@ -183,7 +183,7 @@ def test_blade_update_gateway_ipv6(self): self.client.http.request.assert_called_with( "PUT", self.url_prefix.format(4), self._expected_payload(gateway=gateway), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_blade_update_interface_gateway(self): interface = self._build_interface() @@ -195,4 +195,4 @@ def test_blade_update_interface_gateway(self): self.client.http.request.assert_called_with( "PUT", self.url_prefix.format(4), self._expected_payload(interface=interface, gateway=gateway), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) diff --git a/acos_client/tests/unit/v30/test_dns.py b/acos_client/tests/unit/v30/test_dns.py index 4ba1ea16..1ede339d 100644 --- a/acos_client/tests/unit/v30/test_dns.py +++ b/acos_client/tests/unit/v30/test_dns.py @@ -38,7 +38,7 @@ def test_primary_ipv4(self): self.client.http.request.assert_called_with("POST", self.url_prefix + 'primary', expected_payload, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def test_primary_ipv6(self): expected = '0:0:0:0:0:FFFF:129.144.52.38' @@ -48,7 +48,7 @@ def test_primary_ipv6(self): self.client.http.request.assert_called_with("POST", self.url_prefix + 'primary', expected_payload, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def test_secondary_ipv4(self): expected = '192.0.2.5' @@ -58,7 +58,7 @@ def test_secondary_ipv4(self): self.client.http.request.assert_called_with("POST", self.url_prefix + 'secondary', expected_payload, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def test_secondary_ipv6(self): expected = '0:0:0:0:0:FFFF:129.144.52.39' @@ -68,7 +68,7 @@ def test_secondary_ipv6(self): self.client.http.request.assert_called_with("POST", self.url_prefix + 'secondary', expected_payload, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def test_suffix(self): expected = 'example.com' @@ -78,4 +78,4 @@ def test_suffix(self): self.client.http.request.assert_called_with("POST", self.url_prefix + 'suffix', expected_payload, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) diff --git a/acos_client/tests/unit/v30/test_interface.py b/acos_client/tests/unit/v30/test_interface.py index 21e8132d..61a612ea 100644 --- a/acos_client/tests/unit/v30/test_interface.py +++ b/acos_client/tests/unit/v30/test_interface.py @@ -33,12 +33,12 @@ def setUp(self): def test_interface_get_list(self): self.target.get_list() self.client.http.request.assert_called_with("GET", self.url_prefix, {}, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def test_interface_get(self): self.target.get() self.client.http.request.assert_called_with("GET", self.url_prefix, {}, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def _test_interface_create_dhcp(self, dhcp=True): expected = 1 if dhcp else 0 @@ -47,7 +47,7 @@ def _test_interface_create_dhcp(self, dhcp=True): self.target.create(ifnum, dhcp=dhcp) self.client.http.request.assert_called_with("POST", self.url_prefix, # URL + ifnum expected expected_payload, mock.ANY, axapi_args=None, - max_retries=None, timeout=None) + max_retries=None, timeout=mock.ANY) def test_interface_create_dhcp_negative(self): self._test_interface_create_dhcp(False) @@ -61,14 +61,14 @@ def test_interface_create_ipaddress(self): ip_netmask = "255.255.255.0" self.target.create(ifnum, dhcp=False, ip_address=ip_address, ip_netmask=ip_netmask) self.client.http.request.assert_called_with("POST", self.url_prefix, mock.ANY, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_interface_delete(self): ifnum = 1 self.target.delete(1) self.client.http.request.assert_called_with("DELETE", self.url_prefix + str(ifnum), mock.ANY, mock.ANY, axapi_args=None, max_retries=None, - timeout=None) + timeout=mock.ANY) def test_interface_update(self): ifnum = 1 @@ -79,7 +79,7 @@ def test_interface_update(self): self.client.http.request.assert_called_with("POST", self.url_prefix + str(ifnum), mock.ANY, mock.ANY, axapi_args=None, max_retries=None, - timeout=None) + timeout=mock.ANY) def test_interface_enable_positive(self): ifnum = 1 @@ -94,7 +94,7 @@ def test_interface_enable_positive(self): self.client.http.request.assert_called_with("POST", self.url_prefix + str(ifnum), mock.ANY, mock.ANY, axapi_args=None, max_retries=None, - timeout=None) + timeout=mock.ANY) def test_interface_enable_negative(self): ifnum = 1 @@ -110,7 +110,7 @@ def test_interface_enable_negative(self): self.client.http.request.assert_called_with("POST", self.url_prefix + str(ifnum), mock.ANY, mock.ANY, axapi_args=None, max_retries=None, - timeout=None) + timeout=mock.ANY) class TestEthernetInterface(TestInterface): diff --git a/acos_client/tests/unit/v30/test_vlan.py b/acos_client/tests/unit/v30/test_vlan.py index a10ce17b..53c0315c 100644 --- a/acos_client/tests/unit/v30/test_vlan.py +++ b/acos_client/tests/unit/v30/test_vlan.py @@ -35,13 +35,13 @@ def setUp(self): def test_interface_get_list(self): self.target.get_list() self.client.http.request.assert_called_with("GET", self.url_prefix, {}, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_interface_get(self): self.target.get(self.vlan_id) self.client.http.request.assert_called_with( "GET", '{0}/{1}'.format(self.url_prefix, self.vlan_id), {}, mock.ANY, - axapi_args=None, max_retries=None, timeout=None + axapi_args=None, max_retries=None, timeout=mock.ANY ) def test_vlan_create_shared(self): @@ -51,7 +51,7 @@ def test_vlan_create_shared(self): ep = self.expected_payload ep['vlan']['shared-vlan'] = True self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_create_untagged_eths(self): untagged_eths = [{'untagged-ethernet-start': 2, 'untagged-ethernet-end': 2}] @@ -62,7 +62,7 @@ def test_vlan_create_untagged_eths(self): ep = self.expected_payload ep['vlan']['untagged-eth-list'] = untagged_eths self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_create_untagged_trunks(self): untagged_trunks = [{'untagged-trunk-start': 2, 'untagged-trunk-end': 2}] @@ -74,7 +74,7 @@ def test_vlan_create_untagged_trunks(self): ep = self.expected_payload ep['vlan']['untagged-trunk-list'] = untagged_trunks self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_create_tagged_eths(self): tagged_eths = [{'tagged-ethernet-start': 2, 'tagged-ethernet-end': 2}] @@ -85,7 +85,7 @@ def test_vlan_create_tagged_eths(self): ep = self.expected_payload ep['vlan']['tagged-eth-list'] = tagged_eths self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_create_tagged_trunks(self): tagged_trunks = [{'tagged-trunk-start': 2, 'tagged-trunk-end': 2}] @@ -96,7 +96,7 @@ def test_vlan_create_tagged_trunks(self): ep = self.expected_payload ep['vlan']['tagged-trunk-list'] = tagged_trunks self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_create_ve(self): self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[], @@ -105,7 +105,7 @@ def test_vlan_create_ve(self): ep = self.expected_payload ep['vlan']['ve'] = 1 self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_create_lif(self): self.target.create(self.vlan_id, shared_vlan=False, untagged_eths=[], untagged_trunks=[], @@ -114,11 +114,11 @@ def test_vlan_create_lif(self): ep = self.expected_payload ep['vlan']['untagged-lif'] = 6 self.client.http.request.assert_called_with("POST", self.url_prefix, ep, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vlan_delete(self): self.target.delete(self.vlan_id) self.client.http.request.assert_called_with( "DELETE", '{0}/{1}'.format(self.url_prefix, self.vlan_id), mock.ANY, mock.ANY, - axapi_args=None, max_retries=None, timeout=None + axapi_args=None, max_retries=None, timeout=mock.ANY ) diff --git a/acos_client/tests/unit/v30/test_vrrpa.py b/acos_client/tests/unit/v30/test_vrrpa.py index 65266ef6..1e08e2d0 100644 --- a/acos_client/tests/unit/v30/test_vrrpa.py +++ b/acos_client/tests/unit/v30/test_vrrpa.py @@ -46,19 +46,19 @@ def expected_payload(self, vrid_val, threshold=1, disable=0, is_partition=None): def test_vrid_get(self): self.target.get(0) self.client.http.request.assert_called_with("GET", self.url_prefix + '0', {}, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vrid_create_threshold(self): self.target.create(4, threshold=2) self.client.http.request.assert_called_with( "POST", self.url_prefix, self.expected_payload(4, threshold=2), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vrid_create_disable(self): self.target.create(4, disable=1) self.client.http.request.assert_called_with( "POST", self.url_prefix, self.expected_payload(4, disable=1), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vrid_create_floating_ip(self): self.target.create(4, threshold=1, disable=0, floating_ips=['10.10.10.8']) @@ -66,19 +66,19 @@ def test_vrid_create_floating_ip(self): payload['vrid']['floating-ip'] = mock.ANY self.client.http.request.assert_called_with( "POST", self.url_prefix, payload, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vrid_update_threshold(self): self.target.update(4, threshold=2) self.client.http.request.assert_called_with( "PUT", self.url_prefix + '4', self.expected_payload(4, threshold=2), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vrid_update_disable(self): self.target.update(4, disable=1) self.client.http.request.assert_called_with( "PUT", self.url_prefix + '4', self.expected_payload(4, disable=1), mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_vrid_update_floating_ip(self): self.target.update(4, threshold=1, disable=0, floating_ips=['10.10.10.9']) @@ -86,7 +86,7 @@ def test_vrid_update_floating_ip(self): payload['vrid']['floating-ip'] = mock.ANY self.client.http.request.assert_called_with( "PUT", self.url_prefix + '4', payload, - mock.ANY, axapi_args=None, max_retries=None, timeout=None) + mock.ANY, axapi_args=None, max_retries=None, timeout=mock.ANY) def test_patition_vrid_create_floating_ip(self): self.target.create(4, threshold=1, disable=0, floating_ips=['10.10.10.8'], is_partition=True) @@ -94,7 +94,7 @@ def test_patition_vrid_create_floating_ip(self): payload['vrid']['floating-ip'] = mock.ANY self.client.http.request.assert_called_with( "POST", self.url_prefix, payload, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_partition_vrid_update_floating_ip(self): self.target.update(4, threshold=1, disable=0, floating_ips=['10.10.10.9'], is_partition=True) @@ -102,7 +102,7 @@ def test_partition_vrid_update_floating_ip(self): payload['vrid']['floating-ip'] = mock.ANY self.client.http.request.assert_called_with( "PUT", self.url_prefix + '4', payload, mock.ANY, - axapi_args=None, max_retries=None, timeout=None) + axapi_args=None, max_retries=None, timeout=mock.ANY) def test_build_params_multi_ip(self): floating_ips = ['11.11.11.11', '12.12.12.12', '13.13.13.13'] From 0521c00c8f9ab5e0f415417212527efed8a7bb72 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Fri, 16 Apr 2021 02:08:11 +0000 Subject: [PATCH 11/21] Define a default timeout value for acos-client --- acos_client/v30/base.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/acos_client/v30/base.py b/acos_client/v30/base.py index 47c5f2d2..e4553bad 100644 --- a/acos_client/v30/base.py +++ b/acos_client/v30/base.py @@ -22,6 +22,7 @@ class BaseV30(object): + AXAPI_DEFAULT_REQ_TIMEOUT = 300 def __init__(self, client): self.client = client @@ -64,19 +65,23 @@ def _request(self, method, action, params, retry_count=0, max_retries=None, timeout=timeout, axapi_args=axapi_args, **kwargs) raise e - def _get(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): + def _get(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, + axapi_args=None, **kwargs): return self._request('GET', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _post(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): + def _post(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, + axapi_args=None, **kwargs): return self._request('POST', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _put(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): + def _put(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, + axapi_args=None, **kwargs): return self._request('PUT', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _delete(self, action, params={}, max_retries=None, timeout=300, axapi_args=None, **kwargs): + def _delete(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, + axapi_args=None, **kwargs): return self._request('DELETE', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) From f69d782bcea8c4448e17e9f54abf8423882c40c1 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Fri, 16 Apr 2021 05:16:28 +0000 Subject: [PATCH 12/21] move default value to axapi_http.py --- acos_client/v30/axapi_http.py | 4 +++- acos_client/v30/base.py | 13 ++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index e59cd93e..0b74947f 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -32,12 +32,14 @@ class HttpClient(object): + AXAPI_DEFAULT_REQ_TIMEOUT = 300 HEADERS = { "Content-type": "application/json", "User-Agent": "ACOS-Client-AGENT-%s" % acos_client.VERSION, } - def __init__(self, host, port=None, protocol="https", max_retries=3, timeout=5): + def __init__(self, host, port=None, protocol="https", max_retries=3, + timeout=AXAPI_DEFAULT_REQ_TIMEOUT): if port is None: if protocol is 'http': self.port = 80 diff --git a/acos_client/v30/base.py b/acos_client/v30/base.py index e4553bad..719f839f 100644 --- a/acos_client/v30/base.py +++ b/acos_client/v30/base.py @@ -22,7 +22,6 @@ class BaseV30(object): - AXAPI_DEFAULT_REQ_TIMEOUT = 300 def __init__(self, client): self.client = client @@ -65,23 +64,19 @@ def _request(self, method, action, params, retry_count=0, max_retries=None, timeout=timeout, axapi_args=axapi_args, **kwargs) raise e - def _get(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, - axapi_args=None, **kwargs): + def _get(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): return self._request('GET', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _post(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, - axapi_args=None, **kwargs): + def _post(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): return self._request('POST', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _put(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, - axapi_args=None, **kwargs): + def _put(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): return self._request('PUT', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) - def _delete(self, action, params={}, max_retries=None, timeout=AXAPI_DEFAULT_REQ_TIMEOUT, - axapi_args=None, **kwargs): + def _delete(self, action, params={}, max_retries=None, timeout=None, axapi_args=None, **kwargs): return self._request('DELETE', action, params, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) From e698cd0a5fadd12cb42fcdcb890688622cf1a4db Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Thu, 29 Apr 2021 16:08:23 +0000 Subject: [PATCH 13/21] [STACK-2301] axapi retry when ACOS System busy --- acos_client/errors.py | 8 +++++ acos_client/tests/unit/v30/test_slb_aflex.py | 12 ++++---- acos_client/v30/axapi_http.py | 32 ++++++++++++++++++-- acos_client/v30/responses.py | 10 ++++++ 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/acos_client/errors.py b/acos_client/errors.py index 562f9d87..ccc980f1 100644 --- a/acos_client/errors.py +++ b/acos_client/errors.py @@ -113,3 +113,11 @@ class KeyParsingFailed(ACOSException): class FeatureNotSupported(ACOSException): pass + + +class ACOSSystemNotReady(ACOSException): + pass + + +class ACOSSystemIsBusy(ACOSException): + pass diff --git a/acos_client/tests/unit/v30/test_slb_aflex.py b/acos_client/tests/unit/v30/test_slb_aflex.py index 0050dab2..8aa1e2c3 100644 --- a/acos_client/tests/unit/v30/test_slb_aflex.py +++ b/acos_client/tests/unit/v30/test_slb_aflex.py @@ -56,8 +56,8 @@ def test_aflex_create(self, mocked_get): self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.method, responses.POST) self.assertEqual(responses.calls[1].request.url, CREATE_URL) - self.assertIn(filename, responses.calls[1].request.body.decode('UTF-8')) - self.assertIn(action, responses.calls[1].request.body.decode('UTF-8')) + self.assertIn(filename, responses.calls[1].request.body) + self.assertIn(action, responses.calls[1].request.body) @mock.patch('acos_client.v30.slb.aflex_policy.AFlexPolicy.get') @responses.activate @@ -76,8 +76,8 @@ def test_aflex_update(self, mocked_get): self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.method, responses.POST) self.assertEqual(responses.calls[1].request.url, CREATE_URL) - self.assertIn(filename, responses.calls[1].request.body.decode('UTF-8')) - self.assertIn(action, responses.calls[1].request.body.decode('UTF-8')) + self.assertIn(filename, responses.calls[1].request.body) + self.assertIn(action, responses.calls[1].request.body) @mock.patch('acos_client.v30.slb.aflex_policy.AFlexPolicy.get') @responses.activate @@ -93,5 +93,5 @@ def test_aflex_delete(self, mocked_get): self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.method, responses.POST) self.assertEqual(responses.calls[1].request.url, CREATE_URL) - self.assertIn(filename, responses.calls[1].request.body.decode('UTF-8')) - self.assertIn('delete', responses.calls[1].request.body.decode('UTF-8')) + self.assertIn(filename, responses.calls[1].request.body) + self.assertIn('delete', responses.calls[1].request.body) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index e59cd93e..0d5df13b 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -17,10 +17,13 @@ import json import logging +import time + from requests.adapters import HTTPAdapter from requests import Session import acos_client +from acos_client import errors as ae from acos_client import logutils from acos_client.v30 import responses as acos_responses @@ -64,9 +67,9 @@ def dict_underscore_to_dash(self, my_dict): else: return my_dict - def request(self, method, api_url, params={}, headers=None, - file_name=None, file_content=None, axapi_args=None, - max_retries=None, timeout=None, **kwargs): + def request_impl(self, method, api_url, params={}, headers=None, + file_name=None, file_content=None, axapi_args=None, + max_retries=None, timeout=None, **kwargs): LOG.debug("axapi_http: full url = %s", self.url_base + api_url) LOG.debug("axapi_http: %s url = %s", method, api_url) LOG.debug("axapi_http: params = %s", json.dumps(logutils.clean(params), indent=4)) @@ -157,6 +160,29 @@ def request(self, method, api_url, params={}, headers=None, return json_response + def request(self, method, api_url, params={}, headers=None, + file_name=None, file_content=None, axapi_args=None, + max_retries=None, timeout=None, **kwargs): + attemps = 300 + if timeout and timeout > attemps: + attemps = timeout + + while attemps > 0: + try: + return self.request_impl(method, api_url, params, headers, + max_retries=max_retries, + timeout=timeout, axapi_args=axapi_args, + **kwargs) + + except (ae.ACOSSystemIsBusy) as e: + LOG.warning("ACOS response System is busy 1: %s", str(e)) + attemps = attemps - 2 + if attemps <= 0: + raise e + time.sleep(2) + except (Exception) as e: + raise e + def get(self, api_url, params={}, headers=None, max_retries=None, timeout=None, axapi_args=None, **kwargs): return self.request("GET", api_url, params, headers, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) diff --git a/acos_client/v30/responses.py b/acos_client/v30/responses.py index c9f4fca2..09b6351d 100644 --- a/acos_client/v30/responses.py +++ b/acos_client/v30/responses.py @@ -200,6 +200,16 @@ '*': ae.Exists } }, + 1023464192: { + '*': { + '*': ae.ACOSSystemNotReady + } + }, + 1023464193: { + '*': { + '*': ae.ACOSSystemIsBusy + } + }, 1023475727: { '*': { '*': ae.NotFound From 0167eb47471346828cf739e243f4dae11961f518 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Thu, 29 Apr 2021 16:55:08 +0000 Subject: [PATCH 14/21] refine log message --- acos_client/v30/axapi_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index 0d5df13b..ec703e3f 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -175,7 +175,7 @@ def request(self, method, api_url, params={}, headers=None, **kwargs) except (ae.ACOSSystemIsBusy) as e: - LOG.warning("ACOS response System is busy 1: %s", str(e)) + LOG.warning("ACOS device system is busy: %s", str(e)) attemps = attemps - 2 if attemps <= 0: raise e From 998e181c09522c4a360e021b89b9f96498cefbb3 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Mon, 3 May 2021 15:58:47 +0000 Subject: [PATCH 15/21] [STACK-2302] Fix aFlex script import failed --- acos_client/tests/unit/v30/test_slb_aflex.py | 12 ++++++------ acos_client/v30/axapi_http.py | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/acos_client/tests/unit/v30/test_slb_aflex.py b/acos_client/tests/unit/v30/test_slb_aflex.py index 8aa1e2c3..a634319c 100644 --- a/acos_client/tests/unit/v30/test_slb_aflex.py +++ b/acos_client/tests/unit/v30/test_slb_aflex.py @@ -56,8 +56,8 @@ def test_aflex_create(self, mocked_get): self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.method, responses.POST) self.assertEqual(responses.calls[1].request.url, CREATE_URL) - self.assertIn(filename, responses.calls[1].request.body) - self.assertIn(action, responses.calls[1].request.body) + self.assertIn(filename, responses.calls[1].request.body.decode("utf-8")) + self.assertIn(action, responses.calls[1].request.body.decode("utf-8")) @mock.patch('acos_client.v30.slb.aflex_policy.AFlexPolicy.get') @responses.activate @@ -76,8 +76,8 @@ def test_aflex_update(self, mocked_get): self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.method, responses.POST) self.assertEqual(responses.calls[1].request.url, CREATE_URL) - self.assertIn(filename, responses.calls[1].request.body) - self.assertIn(action, responses.calls[1].request.body) + self.assertIn(filename, responses.calls[1].request.body.decode("utf-8")) + self.assertIn(action, responses.calls[1].request.body.decode("utf-8")) @mock.patch('acos_client.v30.slb.aflex_policy.AFlexPolicy.get') @responses.activate @@ -93,5 +93,5 @@ def test_aflex_delete(self, mocked_get): self.assertEqual(len(responses.calls), 2) self.assertEqual(responses.calls[1].request.method, responses.POST) self.assertEqual(responses.calls[1].request.url, CREATE_URL) - self.assertIn(filename, responses.calls[1].request.body) - self.assertIn('delete', responses.calls[1].request.body) + self.assertIn(filename, responses.calls[1].request.body.decode("utf-8")) + self.assertIn('delete', responses.calls[1].request.body.decode("utf-8")) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index 3c1d9336..518cd92f 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -172,6 +172,7 @@ def request(self, method, api_url, params={}, headers=None, while attemps > 0: try: return self.request_impl(method, api_url, params, headers, + file_name=file_name, file_content=file_content, max_retries=max_retries, timeout=timeout, axapi_args=axapi_args, **kwargs) From b7fa066612e31bf0261b0a91aaf7cf7d5c759ec5 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Wed, 5 May 2021 13:22:23 +0000 Subject: [PATCH 16/21] [STACK-2307] axapi request may fail when system is not ready --- acos_client/v30/axapi_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index 518cd92f..6386304d 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -177,7 +177,7 @@ def request(self, method, api_url, params={}, headers=None, timeout=timeout, axapi_args=axapi_args, **kwargs) - except (ae.ACOSSystemIsBusy) as e: + except (ae.ACOSSystemIsBusy, ae.ACOSSystemNotReady) as e: LOG.warning("ACOS device system is busy: %s", str(e)) attemps = attemps - 2 if attemps <= 0: From 38db5b5b1c275705adb2f730ef0dbe2e89a9992e Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Wed, 5 May 2021 15:08:44 +0000 Subject: [PATCH 17/21] [STACK-2307] vcs retry forever --- acos_client/v30/action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acos_client/v30/action.py b/acos_client/v30/action.py index 71a3848f..59627332 100644 --- a/acos_client/v30/action.py +++ b/acos_client/v30/action.py @@ -89,7 +89,7 @@ def set_vcs_device(self, device_id, priority): def set_vcs_para(self, floating_ip, floating_ip_mask): data = {"vcs-para": {"floating-ip-cfg": [{"floating-ip": floating_ip, - "floating-ip-mask": floating_ip_mask}]}} + "floating-ip-mask": floating_ip_mask}], "forever": 1}} url = "/vcs/vcs-para" self._post(url, data) From 3f8777ee6586745055a7e1d580cda1b25eff34a1 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Tue, 11 May 2021 15:24:05 +0000 Subject: [PATCH 18/21] [STACK-2313] backup plug interface failed because of reloading --- acos_client/v30/axapi_http.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index 6386304d..e05a4f6b 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -21,6 +21,7 @@ from requests.adapters import HTTPAdapter from requests import Session +from requests import exceptions as req_exceptions import acos_client from acos_client import errors as ae @@ -177,7 +178,7 @@ def request(self, method, api_url, params={}, headers=None, timeout=timeout, axapi_args=axapi_args, **kwargs) - except (ae.ACOSSystemIsBusy, ae.ACOSSystemNotReady) as e: + except (ae.ACOSSystemIsBusy, ae.ACOSSystemNotReady, req_exceptions.ConnectionError) as e: LOG.warning("ACOS device system is busy: %s", str(e)) attemps = attemps - 2 if attemps <= 0: From 8e2bf2dbdc3ac9e4333fc593a24fc749f8a878c2 Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Tue, 11 May 2021 16:38:53 +0000 Subject: [PATCH 19/21] fix pep8 issue --- acos_client/v30/axapi_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acos_client/v30/axapi_http.py b/acos_client/v30/axapi_http.py index e05a4f6b..cce61217 100644 --- a/acos_client/v30/axapi_http.py +++ b/acos_client/v30/axapi_http.py @@ -20,8 +20,8 @@ import time from requests.adapters import HTTPAdapter -from requests import Session from requests import exceptions as req_exceptions +from requests import Session import acos_client from acos_client import errors as ae From e0a11e11563c8827b5b6d22e1b0318d3d1c8b3d5 Mon Sep 17 00:00:00 2001 From: Jake Reynolds Date: Tue, 18 May 2021 16:09:12 +0100 Subject: [PATCH 20/21] Add 'stats' function to system --- acos_client/v30/system.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/acos_client/v30/system.py b/acos_client/v30/system.py index fc6c3c37..a85960c9 100644 --- a/acos_client/v30/system.py +++ b/acos_client/v30/system.py @@ -31,3 +31,8 @@ def partition(self): def information(self): return self._get("/system") + + def stats(self, name='', max_retries=None, timeout=None, **kwargs): + return self._get("/system/" + name + '/stats', + max_retries=max_retries, timeout=timeout, + **kwargs) From 2ebfd2aba610c87321c666145470f32c47bd2bff Mon Sep 17 00:00:00 2001 From: ytsai-a10 Date: Wed, 2 Jun 2021 19:36:04 +0800 Subject: [PATCH 21/21] Change version to v2.7.0 --- acos_client/version.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/acos_client/version.py b/acos_client/version.py index 71936a03..c1745784 100644 --- a/acos_client/version.py +++ b/acos_client/version.py @@ -12,4 +12,4 @@ # License for the specific language governing permissions and limitations # under the License. -VERSION = '2.6.1' +VERSION = '2.7.0' diff --git a/setup.py b/setup.py index 2679fd0e..da97c5e7 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ setup( name = "acos-client", - version = "2.6.1", + version = "2.7.0", packages = find_packages(), author = "A10 Networks",