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)) setattr(self, attr_name, proxy(self.session))
except Exception as e: except Exception as e:
_logger.warn("Unable to load %s: %s" % (module, 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 # License for the specific language governing permissions and limitations
# under the License. # under the License.
import mock
from openstack.auth.identity import v2 from openstack.auth.identity import v2
from openstack.auth import service_filter
from openstack import connection from openstack import connection
from openstack import exceptions from openstack import exceptions
from openstack import resource
from openstack.tests import base from openstack.tests import base
from openstack import transport from openstack import transport
from openstack import user_preference from openstack import user_preference
@@ -24,6 +28,9 @@ class TestConnection(base.TestCase):
self.xport = transport.Transport() self.xport = transport.Transport()
self.auth = v2.Auth(auth_url='http://127.0.0.1/v2', token='b') self.auth = v2.Auth(auth_url='http://127.0.0.1/v2', token='b')
self.pref = user_preference.UserPreference() 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): def test_create_transport(self):
conn = connection.Connection(authenticator='2', verify=True, conn = connection.Connection(authenticator='2', verify=True,
@@ -107,3 +114,82 @@ class TestConnection(base.TestCase):
conn.orchestration.__class__.__module__) conn.orchestration.__class__.__module__)
self.assertEqual('openstack.telemetry.v2._proxy', self.assertEqual('openstack.telemetry.v2._proxy',
conn.telemetry.__class__.__module__) 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)