Merge "High level interface"

This commit is contained in:
Jenkins 2014-10-29 22:57:37 +00:00 committed by Gerrit Code Review
commit 94e83e34a3
29 changed files with 327 additions and 4 deletions

View File

@ -25,12 +25,25 @@ filter to match a service.
from openstack import exceptions
class ValidVersion(object):
def __init__(self, module, path=None):
"""" Valid service version.
:param string module: Module associated with version.
:param string path: URL path version.
"""
self.module = module
self.path = path or module
class ServiceFilter(object):
ANY = 'any'
PUBLIC = 'public'
INTERNAL = 'internal'
ADMIN = 'admin'
VISIBILITY = [PUBLIC, INTERNAL, ADMIN]
valid_versions = []
def __init__(self, service_type=ANY, visibility=PUBLIC, region=None,
service_name=None, version=None):
@ -115,3 +128,20 @@ class ServiceFilter(object):
msg = "Visibility <%s> not in %s" % (visibility, self.VISIBILITY)
raise exceptions.SDKException(msg)
self.visibility = visibility
def get_module(self):
"""Get the full module name associated with the service."""
module = self.__class__.__module__.split('.')
module = ".".join(module[:-1])
# NOTE(thowe): Only support for one valid version right now.
module = module + "." + self.valid_versions[0].module
return module
def get_service_module(self):
"""Get the module version of the service name.
This would often be the same as the service type except in cases like
object store where the service type is `object-store` and the module
is `object_store`.
"""
return self.__class__.__module__.split('.')[1]

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class ComputeService(service_filter.ServiceFilter):
"""The compute service."""
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self):
"""Create an compute service."""
super(ComputeService, self).__init__(service_type='compute')

View File

@ -0,0 +1,22 @@
# 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.v2 import flavor
class Proxy(object):
def __init__(self, session):
self.session = session
def list_flavors(self, **params):
return flavor.Flavor.list(self.session, **params)

View File

@ -58,6 +58,8 @@ try to find it and if that fails, you would create it::
network = conn.network.create_network({"name": "jenkins"})
"""
import logging
import sys
from stevedore import driver
@ -68,6 +70,7 @@ from openstack import transport as xport
USER_AGENT = 'OSPythonSDK'
"""Default value for the HTTP User-Agent header"""
_logger = logging.getLogger(__name__)
class Connection(object):
@ -128,6 +131,7 @@ class Connection(object):
**auth_args)
self.session = session.Session(self.transport, self.authenticator,
preference)
self._open()
def _create_transport(self, transport, verify, user_agent):
if transport:
@ -157,3 +161,21 @@ class Connection(object):
valid_list = plugin.valid_options
args = dict((n, auth_args[n]) for n in valid_list if n in auth_args)
return plugin(**args)
def _open(self):
"""Open the connection.
NOTE(thowe): Have this set up some lazy loader instead.
"""
for service in self.session.get_services():
self._load(service)
def _load(self, service):
attr_name = service.get_service_module()
module = service.get_module() + "._proxy"
try:
__import__(module)
proxy = getattr(sys.modules[module], "Proxy")
setattr(self, attr_name, proxy(self.session))
except Exception as e:
_logger.warn("Unable to load %s: %s" % (module, e))

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class DatabaseService(service_filter.ServiceFilter):
"""The database service."""
valid_versions = [service_filter.ValidVersion('v1')]
def __init__(self):
"""Create an database service."""
super(DatabaseService, self).__init__(service_type='database')

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -16,6 +16,11 @@ from openstack.auth import service_filter
class IdentityService(service_filter.ServiceFilter):
"""The identity service."""
valid_versions = [
service_filter.ValidVersion('v3'),
service_filter.ValidVersion('v2'),
]
def __init__(self, **kwargs):
"""Create an identity service."""
kwargs['service_type'] = 'identity'

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -0,0 +1,43 @@
# 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.identity.v3 import project
class Proxy(object):
def __init__(self, session):
self.session = session
def create_project(self, **data):
obj = project.Project(**data)
obj.create(self.session)
return obj
def get_project(self, r_id):
obj = project.Project({'id': r_id})
obj.get(self.session)
return obj
def update_project(self, **data):
obj = project.Project(**data)
obj.update(self.session)
def delete_project(self, r_id):
obj = project.Project({'id': r_id})
obj.delete(self.session)
def list_projects(self, **params):
return project.Project.list(self.session, **params)
def find_project(self, name_or_id):
return project.Project.find(self.session, name_or_id)

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class ImageService(service_filter.ServiceFilter):
"""The image service."""
valid_versions = [service_filter.ValidVersion('v1')]
def __init__(self):
"""Create an image service."""
super(ImageService, self).__init__(service_type='image')

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class NetworkService(service_filter.ServiceFilter):
"""The network service."""
valid_versions = [service_filter.ValidVersion('v2', 'v2.0')]
def __init__(self):
"""Create an network service."""
super(NetworkService, self).__init__(service_type='network')

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class ObjectStoreService(service_filter.ServiceFilter):
"""The object store service."""
valid_versions = [service_filter.ValidVersion('v1')]
def __init__(self):
"""Create an object store service."""
super(ObjectStoreService, self).__init__(service_type='object-store')

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class OrchestrationService(service_filter.ServiceFilter):
"""The orchestration service."""
valid_versions = [service_filter.ValidVersion('v1')]
def __init__(self):
"""Create an orchestration service."""
super(OrchestrationService, self).__init__(

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -16,6 +16,8 @@ from openstack.auth import service_filter
class TelemetryService(service_filter.ServiceFilter):
"""The telemetry service."""
valid_versions = [service_filter.ValidVersion('v2')]
def __init__(self):
"""Create a telemetry service."""
super(TelemetryService, self).__init__(service_type='metering')

View File

@ -0,0 +1,17 @@
# 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.
class Proxy(object):
def __init__(self, session):
self.session = session

View File

@ -15,6 +15,7 @@ import testtools
from openstack.auth import service_filter as filt
from openstack import exceptions
from openstack.identity import identity_service
class TestServiceFilter(testtools.TestCase):
@ -124,3 +125,15 @@ class TestServiceFilter(testtools.TestCase):
self.assertEqual('internal', sot.visibility)
sot.set_visibility("ADMINURL")
self.assertEqual('admin', sot.visibility)
def test_get_module(self):
sot = identity_service.IdentityService()
self.assertEqual('openstack.identity.v3', sot.get_module())
self.assertEqual('identity', sot.get_service_module())
class TestValidVersion(testtools.TestCase):
def test_constructor(self):
sot = filt.ValidVersion('v1.0', 'v1')
self.assertEqual('v1.0', sot.module)
self.assertEqual('v1', sot.path)

View File

@ -23,3 +23,6 @@ class TestComputeService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v2', sot.valid_versions[0].module)
self.assertEqual('v2', sot.valid_versions[0].path)

View File

@ -23,3 +23,6 @@ class TestDatabaseService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v1', sot.valid_versions[0].module)
self.assertEqual('v1', sot.valid_versions[0].path)

View File

@ -23,6 +23,11 @@ class TestIdentityService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(2, len(sot.valid_versions))
self.assertEqual('v3', sot.valid_versions[0].module)
self.assertEqual('v3', sot.valid_versions[0].path)
self.assertEqual('v2', sot.valid_versions[1].module)
self.assertEqual('v2', sot.valid_versions[1].path)
def test_admin_service(self):
sot = identity_service.AdminService()

View File

@ -23,3 +23,6 @@ class TestImageService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v1', sot.valid_versions[0].module)
self.assertEqual('v1', sot.valid_versions[0].path)

View File

@ -23,3 +23,6 @@ class TestNetworkService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v2', sot.valid_versions[0].module)
self.assertEqual('v2.0', sot.valid_versions[0].path)

View File

@ -23,3 +23,6 @@ class TestObjectStoreService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v1', sot.valid_versions[0].module)
self.assertEqual('v1', sot.valid_versions[0].path)

View File

@ -23,3 +23,6 @@ class TestOrchestrationService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v1', sot.valid_versions[0].module)
self.assertEqual('v1', sot.valid_versions[0].path)

View File

@ -23,3 +23,6 @@ class TestTelemetryService(testtools.TestCase):
self.assertEqual('public', sot.visibility)
self.assertIsNone(sot.region)
self.assertIsNone(sot.service_name)
self.assertEqual(1, len(sot.valid_versions))
self.assertEqual('v2', sot.valid_versions[0].module)
self.assertEqual('v2', sot.valid_versions[0].path)

View File

@ -10,12 +10,21 @@
# License for the specific language governing permissions and limitations
# under the License.
from openstack.auth.identity import v2
from openstack import connection
from openstack import exceptions
from openstack.tests import base
from openstack import transport
from openstack import user_preference
class TestConnection(base.TestCase):
def setUp(self):
super(TestConnection, self).setUp()
self.xport = transport.Transport()
self.auth = v2.Auth(auth_url='http://127.0.0.1/v2', token='b')
self.pref = user_preference.UserPreference()
def test_create_transport(self):
conn = connection.Connection(authenticator='2', verify=True,
user_agent='1')
@ -73,8 +82,28 @@ class TestConnection(base.TestCase):
)
def test_create_session(self):
args = {'transport': '0', 'authenticator': '1', 'preference': '2'}
args = {
'transport': self.xport,
'authenticator': self.auth,
'preference': self.pref,
}
conn = connection.Connection(**args)
self.assertEqual('0', conn.session.transport)
self.assertEqual('1', conn.session.authenticator)
self.assertEqual('2', conn.session.preference)
self.assertEqual(self.xport, conn.session.transport)
self.assertEqual(self.auth, conn.session.authenticator)
self.assertEqual(self.pref, conn.session.preference)
self.assertEqual('openstack.compute.v2._proxy',
conn.compute.__class__.__module__)
self.assertEqual('openstack.database.v1._proxy',
conn.database.__class__.__module__)
self.assertEqual('openstack.identity.v3._proxy',
conn.identity.__class__.__module__)
self.assertEqual('openstack.image.v1._proxy',
conn.image.__class__.__module__)
self.assertEqual('openstack.network.v2._proxy',
conn.network.__class__.__module__)
self.assertEqual('openstack.object_store.v1._proxy',
conn.object_store.__class__.__module__)
self.assertEqual('openstack.orchestration.v1._proxy',
conn.orchestration.__class__.__module__)
self.assertEqual('openstack.telemetry.v2._proxy',
conn.telemetry.__class__.__module__)