Support get & update for rate limit
Rate limit is returned as a part of node/services/http response In order to update one should: 1. GET the current configuration 2. PUT the updated configuration (the http response will be 202) 3. POST a restart action request (the http response will be 202) Change-Id: I35a05f9810832e9a22ec9db43f167f13df0744a4
This commit is contained in:
parent
9bf329a0e3
commit
faeb5b8605
|
@ -1650,6 +1650,54 @@ class LogicalDhcpServerTestCase(BaseTestResource):
|
|||
headers=self.default_headers())
|
||||
|
||||
|
||||
class NodeHttpServicePropertiesTestCase(BaseTestResource):
|
||||
|
||||
def setUp(self):
|
||||
super(NodeHttpServicePropertiesTestCase, self).setUp(
|
||||
resources.NodeHttpServiceProperties)
|
||||
|
||||
def test_get_resource(self):
|
||||
self.skipTest("The action is not supported by this resource")
|
||||
|
||||
def test_list_all(self):
|
||||
self.skipTest("The action is not supported by this resource")
|
||||
|
||||
def test_delete_resource(self):
|
||||
self.skipTest("The action is not supported by this resource")
|
||||
|
||||
def test_get_rate_limit(self):
|
||||
mocked_resource = self.get_mocked_resource()
|
||||
rate_limit = 40
|
||||
body = {'service_properties': {'api_rate_limit': rate_limit}}
|
||||
with mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
|
||||
return_value='2.2.0'),\
|
||||
mock.patch.object(mocked_resource.client, "url_get",
|
||||
return_value=body):
|
||||
result = mocked_resource.get_rate_limit()
|
||||
self.assertEqual(rate_limit, result)
|
||||
|
||||
def test_update_rate_limit(self):
|
||||
mocked_resource = self.get_mocked_resource()
|
||||
old_rate_limit = 40
|
||||
new_rate_limit = 50
|
||||
body = {'service_properties': {'api_rate_limit': old_rate_limit}}
|
||||
with mock.patch("vmware_nsxlib.v3.NsxLib.get_version",
|
||||
return_value='2.2.0'),\
|
||||
mock.patch.object(mocked_resource.client, "url_get",
|
||||
return_value=body):
|
||||
mocked_resource.update_rate_limit(new_rate_limit)
|
||||
body['service_properties']['api_rate_limit'] = new_rate_limit
|
||||
test_client.assert_json_call(
|
||||
'put', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/node/services/http',
|
||||
data=jsonutils.dumps(body, sort_keys=True),
|
||||
headers=self.default_headers())
|
||||
test_client.assert_json_call(
|
||||
'post', mocked_resource,
|
||||
'https://1.2.3.4/api/v1/node/services/http?action=restart',
|
||||
headers=self.default_headers())
|
||||
|
||||
|
||||
class DummyCachedResource(utils.NsxLibApiBase):
|
||||
|
||||
@property
|
||||
|
|
|
@ -276,6 +276,8 @@ class NsxLib(NsxLibBase):
|
|||
self.client, self.nsxlib_config, nsxlib=self)
|
||||
self.vpn_ipsec = vpn_ipsec.VpnIpSec(
|
||||
self.client, self.nsxlib_config, nsxlib=self)
|
||||
self.http_services = resources.NodeHttpServiceProperties(
|
||||
self.client, self.nsxlib_config, nsxlib=self)
|
||||
|
||||
# Update tag limits
|
||||
self.tag_limits = self.get_tag_limits()
|
||||
|
@ -300,6 +302,7 @@ class NsxLib(NsxLibBase):
|
|||
if (feature == nsx_constants.FEATURE_VLAN_ROUTER_INTERFACE or
|
||||
feature == nsx_constants.FEATURE_IPSEC_VPN or
|
||||
feature == nsx_constants.FEATURE_ON_BEHALF_OF or
|
||||
feature == nsx_constants.FEATURE_RATE_LIMIT or
|
||||
feature == nsx_constants.FEATURE_TRUNK_VLAN):
|
||||
return True
|
||||
|
||||
|
|
|
@ -87,14 +87,18 @@ class RESTClient(object):
|
|||
def get(self, uuid, headers=None, silent=False):
|
||||
return self.url_get(uuid, headers=headers, silent=silent)
|
||||
|
||||
def delete(self, uuid, headers=None):
|
||||
return self.url_delete(uuid, headers=headers)
|
||||
def delete(self, uuid, headers=None, expected_results=None):
|
||||
return self.url_delete(uuid, headers=headers,
|
||||
expected_results=expected_results)
|
||||
|
||||
def update(self, uuid, body=None, headers=None):
|
||||
return self.url_put(uuid, body, headers=headers)
|
||||
def update(self, uuid, body=None, headers=None, expected_results=None):
|
||||
return self.url_put(uuid, body, headers=headers,
|
||||
expected_results=expected_results)
|
||||
|
||||
def create(self, resource='', body=None, headers=None):
|
||||
return self.url_post(resource, body, headers=headers)
|
||||
def create(self, resource='', body=None, headers=None,
|
||||
expected_results=None):
|
||||
return self.url_post(resource, body, headers=headers,
|
||||
expected_results=expected_results)
|
||||
|
||||
def url_list(self, url, headers=None, silent=False):
|
||||
concatenate_response = self.url_get(url, headers=headers)
|
||||
|
@ -112,14 +116,17 @@ class RESTClient(object):
|
|||
return self._rest_call(url, method='GET', headers=headers,
|
||||
silent=silent)
|
||||
|
||||
def url_delete(self, url, headers=None):
|
||||
return self._rest_call(url, method='DELETE', headers=headers)
|
||||
def url_delete(self, url, headers=None, expected_results=None):
|
||||
return self._rest_call(url, method='DELETE', headers=headers,
|
||||
expected_results=expected_results)
|
||||
|
||||
def url_put(self, url, body, headers=None):
|
||||
return self._rest_call(url, method='PUT', body=body, headers=headers)
|
||||
def url_put(self, url, body, headers=None, expected_results=None):
|
||||
return self._rest_call(url, method='PUT', body=body, headers=headers,
|
||||
expected_results=expected_results)
|
||||
|
||||
def url_post(self, url, body, headers=None):
|
||||
return self._rest_call(url, method='POST', body=body, headers=headers)
|
||||
def url_post(self, url, body, headers=None, expected_results=None):
|
||||
return self._rest_call(url, method='POST', body=body, headers=headers,
|
||||
expected_results=expected_results)
|
||||
|
||||
def _raise_error(self, status_code, operation, result_msg,
|
||||
error_code=None):
|
||||
|
@ -177,7 +184,7 @@ class RESTClient(object):
|
|||
return re.sub(pattern, '"password": "********"', json)
|
||||
|
||||
def _rest_call(self, url, method='GET', body=None, headers=None,
|
||||
silent=False):
|
||||
silent=False, expected_results=None):
|
||||
request_headers = headers.copy() if headers else {}
|
||||
request_headers.update(self._default_headers)
|
||||
if utils.INJECT_HEADERS_CALLBACK:
|
||||
|
@ -206,8 +213,10 @@ class RESTClient(object):
|
|||
result.json() if result.content else '',
|
||||
te - ts)
|
||||
|
||||
if not expected_results:
|
||||
expected_results = RESTClient._VERB_RESP_CODES[method.lower()]
|
||||
self._validate_result(
|
||||
result, RESTClient._VERB_RESP_CODES[method.lower()],
|
||||
result, expected_results,
|
||||
_("%(verb)s %(url)s") % {'verb': method, 'url': request_url},
|
||||
silent=silent)
|
||||
return result
|
||||
|
|
|
@ -135,6 +135,7 @@ FEATURE_LOAD_BALANCER = 'Load Balancer'
|
|||
FEATURE_DHCP_RELAY = 'DHCP Relay'
|
||||
FEATURE_NSX_POLICY = 'NSX Policy'
|
||||
FEATURE_VLAN_ROUTER_INTERFACE = 'VLAN Router Interface'
|
||||
FEATURE_RATE_LIMIT = 'Requests Rate Limit'
|
||||
FEATURE_IPSEC_VPN = 'IPSec VPN'
|
||||
FEATURE_ON_BEHALF_OF = 'On Behalf Of'
|
||||
FEATURE_TRUNK_VLAN = 'Trunk Vlan'
|
||||
|
|
|
@ -17,6 +17,7 @@ import netaddr
|
|||
|
||||
from oslo_log import log
|
||||
from oslo_log import versionutils
|
||||
import requests
|
||||
|
||||
from vmware_nsxlib._i18n import _
|
||||
from vmware_nsxlib.v3 import core_resources
|
||||
|
@ -602,3 +603,69 @@ class IpPool(utils.NsxLibApiBase):
|
|||
"""Return information about the allocated IPs in the pool."""
|
||||
url = "%s/allocations" % pool_id
|
||||
return self.client.url_get(self.get_path(url))
|
||||
|
||||
|
||||
class NodeHttpServiceProperties(utils.NsxLibApiBase):
|
||||
@property
|
||||
def uri_segment(self):
|
||||
return 'node/services/http'
|
||||
|
||||
@property
|
||||
def resource_type(self):
|
||||
return 'NodeHttpServiceProperties'
|
||||
|
||||
def get_properties(self):
|
||||
return self.client.get(self.get_path())
|
||||
|
||||
def get_rate_limit(self):
|
||||
if (self.nsxlib and
|
||||
not self.nsxlib.feature_supported(
|
||||
nsx_constants.FEATURE_RATE_LIMIT)):
|
||||
msg = (_("Rate limit is not supported by NSX version %s") %
|
||||
self.nsxlib.get_version())
|
||||
raise exceptions.ManagerError(details=msg)
|
||||
|
||||
properties = self.get_properties()
|
||||
return properties.get('service_properties', {}).get('api_rate_limit')
|
||||
|
||||
def update_rate_limit(self, value):
|
||||
"""update the NSX rate limit. default value is 40. 0 means no limit"""
|
||||
if (self.nsxlib and
|
||||
not self.nsxlib.feature_supported(
|
||||
nsx_constants.FEATURE_RATE_LIMIT)):
|
||||
msg = (_("Rate limit is not supported by NSX version %s") %
|
||||
self.nsxlib.get_version())
|
||||
raise exceptions.ManagerError(details=msg)
|
||||
|
||||
properties = self.get_properties()
|
||||
if 'service_properties' in properties:
|
||||
properties['service_properties']['api_rate_limit'] = int(value)
|
||||
|
||||
# update the value using a PUT command, which is expected to return 202
|
||||
expected_results = [requests.codes.accepted]
|
||||
self.client.update(self.uri_segment, properties,
|
||||
expected_results=expected_results)
|
||||
|
||||
# restart the http service using POST, which is expected to return 202
|
||||
restart_url = self.uri_segment + '?action=restart'
|
||||
self.client.create(restart_url, expected_results=expected_results)
|
||||
|
||||
def delete(self, uuid):
|
||||
"""Not supported"""
|
||||
msg = _("Delete is not supported for %s") % self.uri_segment
|
||||
raise exceptions.ManagerError(details=msg)
|
||||
|
||||
def get(self, uuid):
|
||||
"""Not supported"""
|
||||
msg = _("Get is not supported for %s") % self.uri_segment
|
||||
raise exceptions.ManagerError(details=msg)
|
||||
|
||||
def list(self):
|
||||
"""Not supported"""
|
||||
msg = _("List is not supported for %s") % self.uri_segment
|
||||
raise exceptions.ManagerError(details=msg)
|
||||
|
||||
def find_by_display_name(self, display_name):
|
||||
"""Not supported"""
|
||||
msg = _("Find is not supported for %s") % self.uri_segment
|
||||
raise exceptions.ManagerError(details=msg)
|
||||
|
|
Loading…
Reference in New Issue