Add resource CRUD to connection class

Once a user has a resource, there is no need to use the proxy
to perform operations on it.  These CRUD methods allow the user
to perform them direction on the object.  For instance:

    project = conn.identity.find_project('foo')
    project['enabled'] = False
    conn.update(project)

Change-Id: I801de6b56f2f44c568b6edcf9c1429014f42a65f
This commit is contained in:
Terry Howe
2014-11-01 10:32:01 -06:00
parent 94e83e34a3
commit 5edaf879ee
2 changed files with 131 additions and 0 deletions

View File

@@ -179,3 +179,48 @@ class Connection(object):
setattr(self, attr_name, proxy(self.session))
except Exception as e:
_logger.warn("Unable to load %s: %s" % (module, e))
def create(self, obj):
"""Create an object.
:param obj: A resource object.
:type resource: :class:`~openstack.resource.Resource`
"""
obj.create(self.session)
return obj
def get(self, obj, include_headers=False):
"""Get an object.
:param obj: A resource object.
:type resource: :class:`~openstack.resource.Resource`
:param bool include_headers: Read object headers.
"""
obj.get(self.session, include_headers)
return obj
def head(self, obj):
"""Get an object.
:param obj: A resource object.
:type resource: :class:`~openstack.resource.Resource`
"""
obj.head(self.session)
return obj
def update(self, obj):
"""Update an object.
:param obj: A resource object.
:type resource: :class:`~openstack.resource.Resource`
"""
obj.update(self.session)
return obj
def delete(self, obj):
"""Delete an object.
:param obj: A resource object.
:type resource: :class:`~openstack.resource.Resource`
"""
obj.delete(self.session)

View File

@@ -10,9 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from openstack.auth.identity import v2
from openstack.auth import service_filter
from openstack import connection
from openstack import exceptions
from openstack import resource
from openstack.tests import base
from openstack import transport
from openstack import user_preference
@@ -24,6 +28,9 @@ class TestConnection(base.TestCase):
self.xport = transport.Transport()
self.auth = v2.Auth(auth_url='http://127.0.0.1/v2', token='b')
self.pref = user_preference.UserPreference()
self.conn = connection.Connection(authenticator=mock.MagicMock(),
transport=mock.MagicMock())
self.conn.session = mock.MagicMock()
def test_create_transport(self):
conn = connection.Connection(authenticator='2', verify=True,
@@ -107,3 +114,82 @@ class TestConnection(base.TestCase):
conn.orchestration.__class__.__module__)
self.assertEqual('openstack.telemetry.v2._proxy',
conn.telemetry.__class__.__module__)
class TestService(service_filter.ServiceFilter):
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self):
super(TestService, self).__init__(service_type='test')
class TestResource(resource.Resource):
resource_key = "testable"
resources_key = "testables"
base_path = "/testables"
service = TestService()
allow_create = True
allow_retrieve = True
allow_update = True
allow_delete = True
allow_list = True
allow_head = True
name = resource.prop('name')
class TestConnectionObjectMethods(base.TestCase):
def setUp(self):
super(TestConnectionObjectMethods, self).setUp()
self.conn = connection.Connection(authenticator=mock.MagicMock(),
transport=mock.MagicMock())
self.conn.session = mock.MagicMock()
self.args = {'name': 'fee', 'id': 'fie'}
self.body = {'testable': self.args}
self.response = mock.Mock
self.response.body = self.body
def test_obj_create(self):
test = TestResource.existing(**self.args)
self.conn.session.put = mock.MagicMock()
self.conn.session.put.and_return = self.response
self.assertEqual(test, self.conn.create(test))
url = 'testables/fie'
self.conn.session.put.assert_called_with(url, json=self.body,
service=test.service)
def test_obj_get(self):
test = TestResource.existing(**self.args)
self.conn.session.get = mock.MagicMock()
self.conn.session.get.and_return = self.response
self.assertEqual(test, self.conn.get(test))
url = 'testables/fie'
self.conn.session.get.assert_called_with(url, service=test.service)
def test_obj_head(self):
test = TestResource.existing(**self.args)
self.conn.session.head = mock.MagicMock()
self.conn.session.head.and_return = self.response
self.assertEqual(test, self.conn.head(test))
url = 'testables/fie'
self.conn.session.head.assert_called_with(url, service=test.service,
accept=None)
def test_obj_update(self):
test = TestResource.existing(**self.args)
test['name'] = 'newname'
self.body = {'testable': {'name': 'newname'}}
self.conn.session.patch = mock.MagicMock()
self.conn.session.patch.and_return = self.response
self.assertEqual(test, self.conn.update(test))
url = 'testables/fie'
self.conn.session.patch.assert_called_with(url, json=self.body,
service=test.service)
def test_obj_delete(self):
test = TestResource.existing(**self.args)
self.conn.session.delete = mock.MagicMock()
self.conn.session.delete.and_return = self.response
self.assertEqual(None, self.conn.delete(test))
url = 'testables/fie'
self.conn.session.delete.assert_called_with(url, service=test.service,
accept=None)