Merge "Provide one resource for Compute v2 Limits"

This commit is contained in:
Jenkins
2015-02-20 17:00:48 +00:00
committed by Gerrit Code Review
8 changed files with 272 additions and 262 deletions

View File

@@ -14,8 +14,7 @@ from openstack.compute.v2 import extension
from openstack.compute.v2 import flavor
from openstack.compute.v2 import image
from openstack.compute.v2 import keypair
from openstack.compute.v2 import limits_absolute
from openstack.compute.v2 import limits_rate
from openstack.compute.v2 import limits
from openstack.compute.v2 import server
from openstack.compute.v2 import server_interface
from openstack.compute.v2 import server_ip
@@ -86,17 +85,15 @@ class Proxy(object):
def update_keypair(self, **data):
return keypair.Keypair(data).update(self.session)
def find_limits_absolute(self, name_or_id):
return limits_absolute.LimitsAbsolute.find(self.session, name_or_id)
def limits(self):
"""Retrieve limits that are applied to the project's account
def list_limits_absolute(self):
return limits_absolute.LimitsAbsolute.list(self.session)
def find_limits_rate(self, name_or_id):
return limits_rate.LimitsRate.find(self.session, name_or_id)
def list_limits_rate(self):
return limits_rate.LimitsRate.list(self.session)
:returns: A Limits object, including both
:class:`~openstack.compute.v2.limits.AbsoluteLimits` and
:class:`~openstack.compute.v2.limits.RateLimits`
:rtype: :class:`~openstack.compute.v2.limits.Limits`
"""
return limits.Limits().get(self.session)
def create_server(self, **data):
return server.Server(data).create(self.session)

View File

@@ -0,0 +1,104 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
class AbsoluteLimits(resource.Resource):
#: The maximum amount of key-value pairs to be set as image metadata.
image_meta = resource.prop("maxImageMeta")
#: The maximum number of personality contents that can be supplied.
personality = resource.prop("maxPersonality")
#: The maximum size, in bytes, of a personality.
personality_size = resource.prop("maxPersonalitySize")
#: The maximum amount of security group rules allowed.
security_group_rules = resource.prop("maxSecurityGroupRules")
#: The maximum amount of security groups allowed.
security_groups = resource.prop("maxSecurityGroups")
#: The amount of security groups currently in use.
security_groups_used = resource.prop("totalSecurityGroupsUsed")
#: The maximum amount of key-value pairs to be set as sever metadata.
server_meta = resource.prop("maxServerMeta")
#: The maximum amount of cores.
total_cores = resource.prop("maxTotalCores")
#: The amount of cores currently in use.
total_cores_used = resource.prop("totalCoresUsed")
#: The maximum amount of floating IPs.
floating_ips = resource.prop("maxTotalFloatingIps")
#: The amount of floating IPs currently in use.
floating_ips_used = resource.prop("totalFloatingIpsUsed")
#: The maximum amount of instances.
instances = resource.prop("maxTotalInstances")
#: The amount of instances currently in use.
instances_used = resource.prop("totalInstancesUsed")
#: The maximum amount of keypairs.
keypairs = resource.prop("maxTotalKeypairs")
#: The maximum RAM size in megabytes.
total_ram = resource.prop("maxTotalRAMSize")
#: The RAM size in megabytes currently in use.
total_ram_used = resource.prop("totalRAMUsed")
#: The maximum amount of server groups.
server_groups = resource.prop("maxServerGroups")
#: The amount of server groups currently in use.
server_groups_used = resource.prop("totalServerGroupsUsed")
#: The maximum number of members in a server group.
server_group_members = resource.prop("maxServerGroupMembers")
class RateLimits(resource.Resource):
#: A list of the specific limits that apply to the ``regex`` and ``uri``.
limits = resource.prop("limit", type=list)
#: A regex representing which routes this rate limit applies to.
regex = resource.prop("regex")
#: A URI representing which routes this rate limit applies to.
uri = resource.prop("uri")
class Limits(resource.Resource):
base_path = "/limits"
resource_key = "limits"
service = compute_service.ComputeService()
allow_retrieve = True
absolute = resource.prop("absolute", type=AbsoluteLimits)
rate = resource.prop("rate", type=list)
def get(self, session, include_headers=False):
"""Get the Limits resource.
:param session: The session to use for making this request.
:type session: :class:`~openstack.session.Session`
:returns: A Limits instance
:rtype: :class:`~openstack.compute.v2.limits.Limits`
"""
body = self.get_data_by_id(session, self.id, path_args=self,
include_headers=include_headers)
# Split the rates away from absolute limits. We can create
# the `absolute` property and AbsoluteLimits resource directly
# from the body. We have to iterate through the list inside `rate`
# in order to create the RateLimits instances for the `rate` property.
rate_body = body.pop("rate")
self._attrs.update(body)
rates = []
for rate in rate_body:
rates.append(RateLimits(rate))
self._attrs.update({"rate": rates})
self._loaded = True
return self

View File

@@ -1,38 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import six
from openstack.compute import compute_service
from openstack import resource
class LimitsAbsolute(resource.Resource):
resource_key = 'limits_absolute'
resources_key = 'limits_absolutes'
base_path = '/limits'
service = compute_service.ComputeService()
# capabilities
allow_list = True
# Properties
name = resource.prop('name')
value = resource.prop('value')
@classmethod
def list(cls, session, path_args=None, **params):
url = cls.base_path
resp = session.get(url, service=cls.service, params=params).body
resp = resp['limits']['absolute']
return [cls.existing(name=key, value=value)
for key, value in six.iteritems(resp)]

View File

@@ -1,36 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.compute import compute_service
from openstack import resource
class LimitsRate(resource.Resource):
resource_key = 'limits_rate'
resources_key = 'limits_rates'
base_path = '/limits'
service = compute_service.ComputeService()
# capabilities
allow_list = True
# Properties
limit = resource.prop('limit')
regex = resource.prop('regex')
uri = resource.prop('uri')
@classmethod
def list(cls, session, path_args=None, **params):
url = cls.base_path
resp = session.get(url, service=cls.service, params=params).body
resp = resp['limits']['rate']
return [cls.existing(**data) for data in resp]

View File

@@ -0,0 +1,155 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
import testtools
from openstack.compute.v2 import limits
ABSOLUTE_LIMITS = {
"maxImageMeta": 128,
"maxPersonality": 5,
"maxPersonalitySize": 10240,
"maxSecurityGroupRules": 20,
"maxSecurityGroups": 10,
"maxServerMeta": 128,
"maxTotalCores": 20,
"maxTotalFloatingIps": 10,
"maxTotalInstances": 10,
"maxTotalKeypairs": 100,
"maxTotalRAMSize": 51200,
"maxServerGroups": 10,
"maxServerGroupMembers": 10,
"totalFloatingIpsUsed": 1,
"totalSecurityGroupsUsed": 2,
"totalRAMUsed": 4,
"totalInstancesUsed": 5,
"totalServerGroupsUsed": 6,
"totalCoresUsed": 7
}
RATE_LIMIT = {
"limit": [
{
"next-available": "2012-11-27T17:22:18Z",
"remaining": 120,
"unit": "MINUTE",
"value": 120,
"verb": "POST"
},
],
"regex": ".*",
"uri": "*"
}
LIMITS_BODY = {
"limits": {
"absolute": ABSOLUTE_LIMITS,
"rate": [RATE_LIMIT]
}
}
class TestAbsoluteLimits(testtools.TestCase):
def test_basic(self):
sot = limits.AbsoluteLimits()
self.assertIsNone(sot.resource_key)
self.assertIsNone(sot.resources_key)
self.assertEqual("", sot.base_path)
self.assertIsNone(sot.service)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_retrieve)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_delete)
self.assertFalse(sot.allow_list)
def test_make_it(self):
sot = limits.AbsoluteLimits(ABSOLUTE_LIMITS)
self.assertEqual(ABSOLUTE_LIMITS["maxImageMeta"], sot.image_meta)
self.assertEqual(ABSOLUTE_LIMITS["maxPersonality"], sot.personality)
self.assertEqual(ABSOLUTE_LIMITS["maxPersonalitySize"],
sot.personality_size)
self.assertEqual(ABSOLUTE_LIMITS["maxSecurityGroupRules"],
sot.security_group_rules)
self.assertEqual(ABSOLUTE_LIMITS["maxSecurityGroups"],
sot.security_groups)
self.assertEqual(ABSOLUTE_LIMITS["maxServerMeta"], sot.server_meta)
self.assertEqual(ABSOLUTE_LIMITS["maxTotalCores"], sot.total_cores)
self.assertEqual(ABSOLUTE_LIMITS["maxTotalFloatingIps"],
sot.floating_ips)
self.assertEqual(ABSOLUTE_LIMITS["maxTotalInstances"],
sot.instances)
self.assertEqual(ABSOLUTE_LIMITS["maxTotalKeypairs"],
sot.keypairs)
self.assertEqual(ABSOLUTE_LIMITS["maxTotalRAMSize"],
sot.total_ram)
self.assertEqual(ABSOLUTE_LIMITS["maxServerGroups"], sot.server_groups)
self.assertEqual(ABSOLUTE_LIMITS["maxServerGroupMembers"],
sot.server_group_members)
self.assertEqual(ABSOLUTE_LIMITS["totalFloatingIpsUsed"],
sot.floating_ips_used)
self.assertEqual(ABSOLUTE_LIMITS["totalSecurityGroupsUsed"],
sot.security_groups_used)
self.assertEqual(ABSOLUTE_LIMITS["totalRAMUsed"], sot.total_ram_used)
self.assertEqual(ABSOLUTE_LIMITS["totalInstancesUsed"],
sot.instances_used)
self.assertEqual(ABSOLUTE_LIMITS["totalServerGroupsUsed"],
sot.server_groups_used)
self.assertEqual(ABSOLUTE_LIMITS["totalCoresUsed"],
sot.total_cores_used)
class TestRateLimits(testtools.TestCase):
def test_basic(self):
sot = limits.RateLimits()
self.assertIsNone(sot.resource_key)
self.assertIsNone(sot.resources_key)
self.assertEqual("", sot.base_path)
self.assertIsNone(sot.service)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_retrieve)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_delete)
self.assertFalse(sot.allow_list)
def test_make_it(self):
sot = limits.RateLimits(RATE_LIMIT)
self.assertEqual(RATE_LIMIT["regex"], sot.regex)
self.assertEqual(RATE_LIMIT["uri"], sot.uri)
self.assertEqual(RATE_LIMIT["limit"], sot.limits)
class TestLimits(testtools.TestCase):
def test_basic(self):
sot = limits.Limits()
self.assertEqual("limits", sot.resource_key)
self.assertEqual("/limits", sot.base_path)
self.assertEqual("compute", sot.service.service_type)
self.assertTrue(sot.allow_retrieve)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_delete)
self.assertFalse(sot.allow_list)
@mock.patch("openstack.resource.Resource.get_data_by_id")
def test_get(self, mock_get):
# Only return values under the limits key since that's our
# resource_key, which would be filtered out in get_data_by_id.
mock_get.return_value = LIMITS_BODY["limits"]
sot = limits.Limits().get("fake session")
self.assertEqual(sot.absolute, limits.AbsoluteLimits(ABSOLUTE_LIMITS))
self.assertEqual(sot.rate, [limits.RateLimits(RATE_LIMIT)])

View File

@@ -1,79 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
import six
import testtools
from openstack.compute.v2 import limits_absolute
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
'name': 'maxImageMeta',
'value': '2',
}
FAKE_RESPONSES = {
"limits": {
"absolute": {
"maxImageMeta": 128,
"maxPersonality": 5,
"maxPersonalitySize": 10240,
"maxSecurityGroupRules": 20,
"maxSecurityGroups": 10,
"maxServerMeta": 128,
"maxTotalCores": 20,
"maxTotalFloatingIps": 10,
"maxTotalInstances": 10,
"maxTotalKeypairs": 100,
"maxTotalRAMSize": 51200,
}
}
}
class TestLimitsAbsolute(testtools.TestCase):
def test_basic(self):
sot = limits_absolute.LimitsAbsolute()
self.assertEqual('limits_absolute', sot.resource_key)
self.assertEqual('limits_absolutes', sot.resources_key)
self.assertEqual('/limits', sot.base_path)
self.assertEqual('compute', sot.service.service_type)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_retrieve)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_delete)
self.assertTrue(sot.allow_list)
def test_make_it(self):
sot = limits_absolute.LimitsAbsolute(EXAMPLE)
self.assertEqual(EXAMPLE['name'], sot.name)
self.assertEqual(EXAMPLE['value'], sot.value)
def test_list(self):
resp = mock.Mock()
resp.body = FAKE_RESPONSES
sess = mock.Mock()
sess.get = mock.MagicMock()
sess.get.return_value = resp
sot = limits_absolute.LimitsAbsolute()
resp = sot.list(sess)
url = '/limits'
sess.get.assert_called_with(url, service=sot.service, params={})
absolute = FAKE_RESPONSES['limits']['absolute']
cnt = 0
for key, value in six.iteritems(absolute):
self.assertEqual(key, resp[cnt].name)
self.assertEqual(value, resp[cnt].value)
cnt = cnt + 1

View File

@@ -1,80 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
import testtools
from openstack.compute.v2 import limits_rate
IDENTIFIER = 'IDENTIFIER'
EXAMPLE = {
'limit': '1',
'regex': '2',
'uri': '3',
}
FAKE_RESPONSES = {
"limits": {
"rate": [
{
"limit": "1",
"regex": ".*",
"uri": "*"
},
{
"limit": "2",
"regex": "^/servers",
"uri": "*/servers"
},
]
}
}
class TestLimitsRate(testtools.TestCase):
def test_basic(self):
sot = limits_rate.LimitsRate()
self.assertEqual('limits_rate', sot.resource_key)
self.assertEqual('limits_rates', sot.resources_key)
self.assertEqual('/limits', sot.base_path)
self.assertEqual('compute', sot.service.service_type)
self.assertFalse(sot.allow_create)
self.assertFalse(sot.allow_retrieve)
self.assertFalse(sot.allow_update)
self.assertFalse(sot.allow_delete)
self.assertTrue(sot.allow_list)
def test_make_it(self):
sot = limits_rate.LimitsRate(EXAMPLE)
self.assertEqual(EXAMPLE['limit'], sot.limit)
self.assertEqual(EXAMPLE['regex'], sot.regex)
self.assertEqual(EXAMPLE['uri'], sot.uri)
def test_list(self):
resp = mock.Mock()
resp.body = FAKE_RESPONSES
sess = mock.Mock()
sess.get = mock.MagicMock()
sess.get.return_value = resp
sot = limits_rate.LimitsRate()
resp = sot.list(sess)
url = '/limits'
sess.get.assert_called_with(url, service=sot.service, params={})
rate = FAKE_RESPONSES['limits']['rate']
cnt = 0
for value in rate:
self.assertEqual(value['limit'], resp[cnt].limit)
self.assertEqual(value['regex'], resp[cnt].regex)
self.assertEqual(value['uri'], resp[cnt].uri)
cnt = cnt + 1

View File

@@ -99,23 +99,10 @@ class TestComputeProxy(test_proxy_base.TestProxyBase):
self.verify_update('openstack.compute.v2.keypair.Keypair.update',
self.proxy.update_keypair)
def test_limits_absolute_find(self):
self.verify_find(
'openstack.compute.v2.limits_absolute.LimitsAbsolute.find',
self.proxy.find_limits_absolute)
def test_limits_absolute_list(self):
self.verify_list(
'openstack.compute.v2.limits_absolute.LimitsAbsolute.list',
self.proxy.list_limits_absolute)
def test_limits_rate_find(self):
self.verify_find('openstack.compute.v2.limits_rate.LimitsRate.find',
self.proxy.find_limits_rate)
def test_limits_rate_list(self):
self.verify_list('openstack.compute.v2.limits_rate.LimitsRate.list',
self.proxy.list_limits_rate)
def test_limits(self):
self.verify_get(
'openstack.compute.v2.limits.Limits.get',
self.proxy.limits)
def test_server_interface_create(self):
self.verify_create(