diff --git a/cdn/provider/__init__.py b/cdn/provider/__init__.py index 214c1563..53ccbc12 100644 --- a/cdn/provider/__init__.py +++ b/cdn/provider/__init__.py @@ -4,4 +4,4 @@ from cdn.provider import base # Hoist classes into package namespace CDNProviderBase = base.CDNProviderBase -HostBase = base.HostBase +ServiceBase = base.ServiceBase diff --git a/cdn/provider/base.py b/cdn/provider/base.py index ddf359c7..df33fb69 100644 --- a/cdn/provider/base.py +++ b/cdn/provider/base.py @@ -22,8 +22,8 @@ import sys from oslo.config import cfg _LIMITS_OPTIONS = [ - cfg.IntOpt('default_hostname_paging', default=10, - help='Default hostname pagination size') + cfg.IntOpt('default_services_paging', default=10, + help='Default services pagination size') ] _LIMITS_GROUP = 'limits:storage' @@ -66,15 +66,14 @@ class CDNProviderBase(ProviderBase): raise NotImplementedError @abc.abstractproperty - def host_controller(self): + def service_controller(self): """Returns the extension's hostname controller.""" raise NotImplementedError @six.add_metaclass(abc.ABCMeta) -class HostBase(object): - """This class is responsible for managing hostnames. - Hostname operations include CRUD, etc. +class ServiceBase(object): + """This class is responsible for managing services. """ __metaclass__ = abc.ABCMeta diff --git a/cdn/provider/fastly/controllers.py b/cdn/provider/fastly/controllers.py index fdec6827..0bc6bf50 100644 --- a/cdn/provider/fastly/controllers.py +++ b/cdn/provider/fastly/controllers.py @@ -22,6 +22,6 @@ Field Mappings: updated and documented in each controller class. """ -from cdn.provider.fastly import hosts +from cdn.provider.fastly import services -HostController = hosts.HostController +ServiceController = services.ServiceController diff --git a/cdn/provider/fastly/driver.py b/cdn/provider/fastly/driver.py index de43cf10..27ee9af3 100644 --- a/cdn/provider/fastly/driver.py +++ b/cdn/provider/fastly/driver.py @@ -52,5 +52,5 @@ class CDNProvider(provider.CDNProviderBase): return self.client @decorators.lazy_property(write=False) - def host_controller(self): - return controllers.HostController(self) + def service_controller(self): + return controllers.ServiceController(self) diff --git a/cdn/provider/fastly/hosts.py b/cdn/provider/fastly/services.py similarity index 96% rename from cdn/provider/fastly/hosts.py rename to cdn/provider/fastly/services.py index 46879305..5591ade0 100644 --- a/cdn/provider/fastly/hosts.py +++ b/cdn/provider/fastly/services.py @@ -19,10 +19,10 @@ import json from cdn.provider import base -class HostController(base.HostBase): +class ServiceController(base.ServiceBase): def __init__(self, driver): - super(HostController, self).__init__() + super(ServiceController, self).__init__() self.client = driver.client self.current_customer = self.client.get_current_customer() diff --git a/cdn/provider/sample/controllers.py b/cdn/provider/sample/controllers.py index db8bf690..facdd7fe 100644 --- a/cdn/provider/sample/controllers.py +++ b/cdn/provider/sample/controllers.py @@ -22,6 +22,6 @@ Field Mappings: updated and documented in each controller class. """ -from cdn.provider.sample import hosts +from cdn.provider.sample import services -HostController = hosts.HostController +ServiceController = services.ServiceController diff --git a/cdn/provider/sample/driver.py b/cdn/provider/sample/driver.py index 8150eb63..bfc290df 100644 --- a/cdn/provider/sample/driver.py +++ b/cdn/provider/sample/driver.py @@ -34,5 +34,5 @@ class CDNProvider(provider.CDNProviderBase): return True @decorators.lazy_property(write=False) - def host_controller(self): - return controllers.HostController() + def service_controller(self): + return controllers.ServiceController() diff --git a/cdn/provider/sample/hosts.py b/cdn/provider/sample/services.py similarity index 91% rename from cdn/provider/sample/hosts.py rename to cdn/provider/sample/services.py index 91198e91..8e5a40ba 100644 --- a/cdn/provider/sample/hosts.py +++ b/cdn/provider/sample/services.py @@ -17,10 +17,10 @@ from cdn.provider import base -class HostController(base.HostBase): +class ServiceController(base.ServiceBase): def __init__(self): - super(HostController, self).__init__() + super(ServiceController, self).__init__() self.provider_resp = base.ProviderResponse("sample") diff --git a/cdn/storage/__init__.py b/cdn/storage/__init__.py index 6c45a05c..71bd8565 100644 --- a/cdn/storage/__init__.py +++ b/cdn/storage/__init__.py @@ -4,5 +4,4 @@ from cdn.storage import base # Hoist classes into package namespace StorageDriverBase = base.StorageDriverBase - -HostBase = base.HostBase +ServicesBase = base.ServicesBase diff --git a/cdn/storage/base.py b/cdn/storage/base.py index 5ab2cc13..b7382291 100644 --- a/cdn/storage/base.py +++ b/cdn/storage/base.py @@ -19,8 +19,8 @@ import six from oslo.config import cfg _LIMITS_OPTIONS = [ - cfg.IntOpt('default_hostname_paging', default=10, - help='Default hostname pagination size') + cfg.IntOpt('default_services_paging', default=10, + help='Default services pagination size') ] _LIMITS_GROUP = 'limits:storage' @@ -67,7 +67,7 @@ class StorageDriverBase(DriverBase): raise NotImplementedError @abc.abstractproperty - def host_controller(self): + def service_controller(self): """Returns the driver's hostname controller.""" raise NotImplementedError @@ -84,14 +84,13 @@ class ControllerBase(object): @six.add_metaclass(abc.ABCMeta) -class HostBase(ControllerBase): - """This class is responsible for managing hostnames. - Hostname operations include CRUD, etc. +class ServicesBase(ControllerBase): + """This class is responsible for managing Services """ __metaclass__ = abc.ABCMeta def __init__(self, driver): - super(HostBase, self).__init__(driver) + super(ServicesBase, self).__init__(driver) self.wrapper = ProviderWrapper() @@ -119,12 +118,12 @@ class HostBase(ControllerBase): class ProviderWrapper(object): def create(self, ext, service_name, service_json): - return ext.obj.host_controller.create(service_name, service_json) + return ext.obj.service_controller.create(service_name, service_json) def update(self, ext, service_name): - return ext.obj.host_controller.update(service_name) + return ext.obj.service_controller.update(service_name) def delete(self, ext, service_name): - return ext.obj.host_controller.delete(service_name) + return ext.obj.service_controller.delete(service_name) diff --git a/cdn/storage/cassandra/controllers.py b/cdn/storage/cassandra/controllers.py index da212c60..f74114a8 100644 --- a/cdn/storage/cassandra/controllers.py +++ b/cdn/storage/cassandra/controllers.py @@ -23,6 +23,6 @@ Field Mappings: updated and documented in each controller class. """ -from cdn.storage.cassandra import hosts +from cdn.storage.cassandra import services -HostController = hosts.HostController +ServicesController = services.ServicesController diff --git a/cdn/storage/cassandra/driver.py b/cdn/storage/cassandra/driver.py index cd1b4452..05545114 100644 --- a/cdn/storage/cassandra/driver.py +++ b/cdn/storage/cassandra/driver.py @@ -61,9 +61,9 @@ class StorageDriver(storage.StorageDriverBase): return _connection(self.cassandra_conf) @decorators.lazy_property(write=False) - def host_controller(self): - return controllers.HostController(self) + def service_controller(self): + return controllers.ServicesController(self) @decorators.lazy_property(write=False) - def host_database(self): + def service_database(self): return self.connection diff --git a/cdn/storage/cassandra/hosts.py b/cdn/storage/cassandra/hosts.py deleted file mode 100644 index 0b7a6fbe..00000000 --- a/cdn/storage/cassandra/hosts.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (c) 2014 Rackspace, Inc. -# -# 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 uuid - -from cdn.storage import base - -CQL_CREATE_SERVICE = ''' - INSERT INTO services (servicename, serviceid) - VALUES (%s, %s) -''' - -class HostController(base.HostBase): - - def __init__(self, *args, **kwargs): - super(HostController, self).__init__(*args, **kwargs) - - self._session = self.driver.host_database - - - def list(self): - hostnames = [ - { - 'hostname': 'www.mywebsite.com', - 'description': 'My Sample Website using Cassandra' - }, - { - 'hostname': 'www.myotherwebsite.com', - 'description': 'My Other Website' - } - ] - - return hostnames - - def get(self): - # get the requested hostname from storage - print "get hostname" - - def create(self, service_name, service_json): - - # create the hostname in storage - service = service_json - - """Creates a new service""" - args = (service_name, uuid.uuid1()) - res = self._session.execute(CQL_CREATE_SERVICE, args) - - print "stored new record in cassandra" - - - # create at providers - providers = super(HostController, self).create(service_name, service) - - return providers - - def update(self, service_name, service_json): - # update configuration in storage - - # update at providers - return super(HostController, self).update(service_name, service_json) - - def delete(self, service_name): - # delete local configuration from storage - - # delete from providers - return super(HostController, self).delete(service_name) - - diff --git a/cdn/storage/cassandra/services.py b/cdn/storage/cassandra/services.py new file mode 100644 index 00000000..6f4a6834 --- /dev/null +++ b/cdn/storage/cassandra/services.py @@ -0,0 +1,123 @@ +# Copyright (c) 2014 Rackspace, Inc. +# +# 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 uuid + +from cdn.storage import base + +CQL_CREATE_SERVICE = ''' + INSERT INTO services (servicename, serviceid) + VALUES (%s, %s) +''' + +class ServicesController(base.ServicesBase): + + def __init__(self, *args, **kwargs): + super(ServicesController, self).__init__(*args, **kwargs) + + self._session = self.driver.service_database + + + def list(self): + services = { + "links": [ + { + "rel": "next", + "href": "/v1.0/services?marker=www.myothersite.com&limit=20" + } + ], + "services" : [ + { + "domains": [ + { + "domain": "www.mywebsite.com" + } + ], + "origins": [ + { + "origin": "mywebsite.com", + "port": 80, + "ssl": False + } + ], + "caching": [ + { "name" : "default", "ttl" : 3600 }, + { + "name" : "home", + "ttl" : 17200, + "rules" : [ + { "name" : "index", "request_url" : "/index.htm" } + ] + }, + { + "name" : "images", + "ttl" : 12800, + "rules" : [ + { "name" : "images", "request_url" : "*.png" } + ] + } + ], + "restrictions" : [ + { + "name" : "website only", + "rules" : [ { "name" : "mywebsite.com", "http_host" : "www.mywebsite.com" } ] + } + ], + "links" : [ + { + "href": "/v1.0/services/mywebsite", + "rel" : "self" + } + ] + } + ] + } + + return services + + def get(self): + # get the requested service from storage + print "get service" + + def create(self, service_name, service_json): + + # create the service in storage + service = service_json + + """Creates a new service""" + args = (service_name, uuid.uuid1()) + res = self._session.execute(CQL_CREATE_SERVICE, args) + + print "stored new record in cassandra" + + + # create at providers + providers = super(ServicesController, self).create(service_name, service) + + return providers + + def update(self, service_name, service_json): + # update configuration in storage + + # update at providers + return super(ServicesController, self).update(service_name, service_json) + + def delete(self, service_name): + # delete local configuration from storage + + # delete from providers + return super(ServicesController, self).delete(service_name) + + diff --git a/cdn/storage/mongodb/controllers.py b/cdn/storage/mongodb/controllers.py index b9e430e0..992882de 100644 --- a/cdn/storage/mongodb/controllers.py +++ b/cdn/storage/mongodb/controllers.py @@ -24,4 +24,4 @@ Field Mappings: from cdn.storage.mongodb import hosts -HostController = hosts.HostController +ServicesController = servicess.ServicesController diff --git a/cdn/storage/mongodb/driver.py b/cdn/storage/mongodb/driver.py index 007f7f57..e51de1d9 100644 --- a/cdn/storage/mongodb/driver.py +++ b/cdn/storage/mongodb/driver.py @@ -79,21 +79,23 @@ class StorageDriver(storage.StorageDriverBase): except pymongo.errors.PyMongoError: return False - @decorators.lazy_property(write=False) - def host_database(self): - """Database dedicated to the "host" collection. - - The host collection is separated out into its own database. - """ - - name = self.mongodb_conf.database + '_host' - return self.connection[name] - @decorators.lazy_property(write=False) def connection(self): """MongoDB client connection instance.""" return _connection(self.mongodb_conf) @decorators.lazy_property(write=False) - def host_controller(self): - return controllers.HostController(self.providers) + def service_controller(self): + return controllers.ServicesController(self.providers) + + @decorators.lazy_property(write=False) + def service_database(self): + """Database dedicated to the "services" collection. + + The services collection is separated out into its own database. + """ + + name = self.mongodb_conf.database + '_services' + return self.connection[name] + + diff --git a/cdn/storage/mongodb/hosts.py b/cdn/storage/mongodb/hosts.py deleted file mode 100644 index f4f73345..00000000 --- a/cdn/storage/mongodb/hosts.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2014 Rackspace, Inc. -# -# 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. - -# stevedore/example/simple.py -from cdn.storage import base - - -class HostController(base.HostBase): - - def list(self): - hostnames = [ - { - 'hostname': 'www.mywebsite.com', - 'description': 'My Sample Website using Mongo' - }, - { - 'hostname': 'www.myotherwebsite.com', - 'description': 'My Other Website' - } - ] - - return hostnames - - def get(self): - # get the requested hostname from storage - print "get hostname" - - def create(self, service_name, service_json): - - # create the hostname in storage - service = service_json - - # create at providers - return super(HostController, self).create(service_name, service) - - def update(self, service_name, service_json): - # update configuration in storage - - # update at providers - return super(HostController, self).update(service_name, service_json) - - def delete(self, service_name): - # delete local configuration from storage - - # delete from providers - return super(HostController, self).delete(service_name) - - diff --git a/cdn/storage/mongodb/services.py b/cdn/storage/mongodb/services.py new file mode 100644 index 00000000..011b633e --- /dev/null +++ b/cdn/storage/mongodb/services.py @@ -0,0 +1,103 @@ +# Copyright (c) 2014 Rackspace, Inc. +# +# 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. + +# stevedore/example/simple.py +from cdn.storage import base + + +class ServicesController(base.ServicesBase): + + def list(self): + services = { + "links": [ + { + "rel": "next", + "href": "/v1.0/services?marker=www.myothersite.com&limit=20" + } + ], + "services" : [ + { + "domains": [ + { + "domain": "www.mywebsite.com" + } + ], + "origins": [ + { + "origin": "mywebsite.com", + "port": 80, + "ssl": False + } + ], + "caching": [ + { "name" : "default", "ttl" : 3600 }, + { + "name" : "home", + "ttl" : 17200, + "rules" : [ + { "name" : "index", "request_url" : "/index.htm" } + ] + }, + { + "name" : "images", + "ttl" : 12800, + "rules" : [ + { "name" : "images", "request_url" : "*.png" } + ] + } + ], + "restrictions" : [ + { + "name" : "website only", + "rules" : [ { "name" : "mywebsite.com", "http_host" : "www.mywebsite.com" } ] + } + ], + "links" : [ + { + "href": "/v1.0/services/mywebsite", + "rel" : "self" + } + ] + } + ] + } + + return services + + def get(self): + # get the requested service from storage + print "get service" + + def create(self, service_name, service_json): + + # create the service in storage + service = service_json + + # create at providers + return super(ServicesController, self).create(service_name, service) + + def update(self, service_name, service_json): + # update configuration in storage + + # update at providers + return super(ServicesController, self).update(service_name, service_json) + + def delete(self, service_name): + # delete local configuration from storage + + # delete from providers + return super(ServicesController, self).delete(service_name) + + diff --git a/cdn/transport/falcon/driver.py b/cdn/transport/falcon/driver.py index 67d53bf5..4926d842 100644 --- a/cdn/transport/falcon/driver.py +++ b/cdn/transport/falcon/driver.py @@ -23,7 +23,7 @@ import six import cdn.openstack.common.log as logging from cdn import transport from cdn.transport.falcon import ( - v1, hosts + v1, services ) @@ -59,17 +59,17 @@ class TransportDriver(transport.DriverBase): version_path = "/v1.0" # init the controllers - host_controller = self._storage.host_controller + service_controller = self._storage.service_controller # setup the routes self.app.add_route(version_path, v1.V1Resource()) - self.app.add_route(version_path + '/hosts', - hosts.HostsResource(host_controller)) + self.app.add_route(version_path + '/services', + services.ServicesResource(service_controller)) - self.app.add_route(version_path + '/hosts/{service_name}', - hosts.HostResource(host_controller)) + self.app.add_route(version_path + '/services/{service_name}', + services.ServiceResource(service_controller)) def listen(self): """Self-host using 'bind' and 'port' from the WSGI config group.""" diff --git a/cdn/transport/falcon/hosts.py b/cdn/transport/falcon/services.py similarity index 63% rename from cdn/transport/falcon/hosts.py rename to cdn/transport/falcon/services.py index a298ecd9..29ccf936 100644 --- a/cdn/transport/falcon/hosts.py +++ b/cdn/transport/falcon/services.py @@ -17,48 +17,48 @@ import falcon import json -class HostsResource: - def __init__(self, host_controller): - self.host_controller = host_controller +class ServicesResource: + def __init__(self, services_controller): + self.services_controller = services_controller def on_get(self, req, resp): """Handles GET requests """ - hostnames = self.host_controller.list() + services = self.services_controller.list() resp.status = falcon.HTTP_200 - resp.body = json.dumps(hostnames) + resp.body = json.dumps(services) -class HostResource: - def __init__(self, host_controller): - self.host_controller = host_controller +class ServiceResource: + def __init__(self, service_controller): + self.service_controller = service_controller def on_get(self, req, resp, service_name): """Handles GET requests """ - host_response = self.host_controller.find(service_name) + service = self.service_controller.find(service_name) resp.status = falcon.HTTP_200 - resp.body = json.dumps(host_response) + resp.body = json.dumps(service) def on_put(self, req, resp, service_name): """Handles PUT requests """ service_json = json.loads(req.stream.read(req.content_length)) - host_response = self.host_controller.create(service_name, service_json) + service = self.service_controller.create(service_name, service_json) resp.status = falcon.HTTP_200 - resp.body = json.dumps(host_response) + resp.body = json.dumps(service) def on_patch(self, req, resp, service_name): """Handles PATCH requests """ - host_response = self.host_controller.update(service_name) + service = self.service_controller.update(service_name) resp.status = falcon.HTTP_200 - resp.body = json.dumps(host_response) + resp.body = json.dumps(service) def on_delete(self, req, resp, service_name): """Handles DELETE requests """ - host_response = self.host_controller.delete(service_name) + service = self.service_controller.delete(service_name) resp.status = falcon.HTTP_204 - resp.body = json.dumps(host_response) + resp.body = json.dumps(service)