Merge "High level interface"
This commit is contained in:
commit
94e83e34a3
@ -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]
|
||||
|
@ -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')
|
||||
|
22
openstack/compute/v2/_proxy.py
Normal file
22
openstack/compute/v2/_proxy.py
Normal 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)
|
@ -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))
|
||||
|
@ -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')
|
||||
|
17
openstack/database/v1/_proxy.py
Normal file
17
openstack/database/v1/_proxy.py
Normal 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
|
@ -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'
|
||||
|
17
openstack/identity/v2/_proxy.py
Normal file
17
openstack/identity/v2/_proxy.py
Normal 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
|
43
openstack/identity/v3/_proxy.py
Normal file
43
openstack/identity/v3/_proxy.py
Normal 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)
|
@ -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')
|
||||
|
17
openstack/image/v1/_proxy.py
Normal file
17
openstack/image/v1/_proxy.py
Normal 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
|
@ -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')
|
||||
|
17
openstack/network/v2/_proxy.py
Normal file
17
openstack/network/v2/_proxy.py
Normal 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
|
@ -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')
|
||||
|
17
openstack/object_store/v1/_proxy.py
Normal file
17
openstack/object_store/v1/_proxy.py
Normal 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
|
@ -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__(
|
||||
|
17
openstack/orchestration/v1/_proxy.py
Normal file
17
openstack/orchestration/v1/_proxy.py
Normal 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
|
@ -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')
|
||||
|
17
openstack/telemetry/v2/_proxy.py
Normal file
17
openstack/telemetry/v2/_proxy.py
Normal 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
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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__)
|
||||
|
Loading…
Reference in New Issue
Block a user