From 0154bbb2adff3f47c1f7e7c8d96c2b614ae77293 Mon Sep 17 00:00:00 2001 From: Peter Balland Date: Thu, 26 Jun 2014 15:26:14 -0700 Subject: [PATCH] Wire API models to policy engine Previously, the API was wired to dummy data models. We now initialize the policy engine and API together from congress_server.py Note: you must set the policy_path param in congress/etc/congress.conf.sample for the server to work properly. Change-Id: I6ae855fc217dc2401035b6c9f89d1d6607f8ac10 --- congress/api/application.py | 65 --------------------- congress/common/config.py | 6 +- congress/server/congress_server.py | 91 +++++++++++++++++++++++++----- etc/congress.conf.sample | 3 + 4 files changed, 84 insertions(+), 81 deletions(-) diff --git a/congress/api/application.py b/congress/api/application.py index 9a4d3bea7..5f2737286 100644 --- a/congress/api/application.py +++ b/congress/api/application.py @@ -18,11 +18,8 @@ import traceback import webob import webob.dec -from congress.api.webservice import CollectionHandler -from congress.api.webservice import ElementHandler from congress.api.webservice import INTERNAL_ERROR_RESPONSE from congress.api.webservice import NOT_SUPPORTED_RESPONSE -from congress.api.webservice import SimpleDataModel from congress.openstack.common.gettextutils import _ from congress.openstack.common import log as logging @@ -115,65 +112,3 @@ class ResourceManager(object): def get_model(self, model_id): return self.models.get(model_id) - - -def initialize_resources(resource_mgr): - """Bootstrap data models and handlers for the current API definition.""" - policies = SimpleDataModel('policies') - resource_mgr.register_model('policies', policies) - #system policy is always present - policies.add_item({'id': 'system', 'owner': 'system'}, 'system') - - policy_collection_handler = CollectionHandler( - r'/policies', policies, allow_create=False) - resource_mgr.register_handler(policy_collection_handler) - policy_element_handler = ElementHandler( - r'/policies/(?P[^/]+)', policies, policy_collection_handler, - allow_replace=False, allow_update=False, allow_delete=False) - resource_mgr.register_handler(policy_element_handler) - - policy_rules = SimpleDataModel('rules') - resource_mgr.register_model('rules', policy_rules) - rule_collection_handler = CollectionHandler( - r'/policies/(?P[^/]+)/rules', policy_rules, "{policy_id}") - resource_mgr.register_handler(rule_collection_handler) - rule_element_handler = ElementHandler( - r'/policies/(?P[^/]+)/rules/(?P[^/]+)', - policy_rules, "{policy_id}") - resource_mgr.register_handler(rule_element_handler) - - data_sources = SimpleDataModel('data_sources') - resource_mgr.register_model('data_sources', data_sources) - ds_collection_handler = CollectionHandler(r'/data-sources', data_sources) - resource_mgr.register_handler(ds_collection_handler) - ds_path = r'/data-sources/(?P[^/]+)' - ds_element_handler = ElementHandler(ds_path, data_sources) - resource_mgr.register_handler(ds_element_handler) - - # TODO(pballand) register models for schema and status - #schema_path = "%s/schema" % ds_path - #schema_element_handler = ElementHandler(schema_path, XXX, - # "schema") - #resource_mgr.register_handler(schema_element_handler) - #status_path = "%s/status" % ds_path - #status_element_handler = ElementHandler(status_path, XXX, - # "status") - #resource_mgr.register_handler(status_element_handler) - - tables = SimpleDataModel('tables') - resource_mgr.register_model('tables', tables) - tables_path = "%s/tables" % ds_path - table_collection_handler = CollectionHandler(tables_path, tables) - resource_mgr.register_handler(table_collection_handler) - table_path = "%s/(?P[^/]+)" % tables_path - table_element_handler = ElementHandler(table_path, tables) - resource_mgr.register_handler(table_element_handler) - - table_rows = SimpleDataModel('table_rows') - resource_mgr.register_model('table_rows', table_rows) - rows_path = "%s/rows" % table_path - row_collection_handler = CollectionHandler(rows_path, table_rows) - resource_mgr.register_handler(row_collection_handler) - row_path = "%s/(?P[^/]+)" % rows_path - row_element_handler = ElementHandler(row_path, table_rows) - resource_mgr.register_handler(row_element_handler) diff --git a/congress/common/config.py b/congress/common/config.py index 9fcc6a91c..ef21a3228 100644 --- a/congress/common/config.py +++ b/congress/common/config.py @@ -33,8 +33,10 @@ core_opts = [ 'server socket. Only applies if tcp_keepalive is ' 'true. Not supported on OS X.'), cfg.IntOpt('api_workers', default=1, - help='The number of worker processes to serve the congress ' - 'API application.'), + help='The number of worker processes to server the congress ' + 'WSGI application.'), + cfg.StrOpt('policy_path', default=None, + help="The path to the latest policy dump"), ] # Register the configuration options diff --git a/congress/server/congress_server.py b/congress/server/congress_server.py index 83d41ef3d..f6ce21b21 100755 --- a/congress/server/congress_server.py +++ b/congress/server/congress_server.py @@ -24,9 +24,11 @@ from oslo.config import cfg import sys from congress.api import application +from congress.api.webservice import CollectionHandler +from congress.api.webservice import ElementHandler from congress.common import config from congress.common import eventlet_server -import congress.dse.d6cage +from congress import harness from congress.openstack.common.gettextutils import _ from congress.openstack.common import log as logging from congress.openstack.common import service @@ -53,9 +55,17 @@ class ServerWrapper(object): launcher.launch_service(self.server) -def create_api_server(conf, name, host, port, workers): +def create_api_server(conf, name, host, port, workers, + src_path=None, policy_path=None): + if src_path is None: + fpath = os.path.dirname(os.path.realpath(__file__)) + src_path = os.path.dirname(fpath) + src_path = os.path.dirname(fpath) + if policy_path is None: + policy_path = src_path + cage = harness.create(src_path, policy_path) api_resource_mgr = application.ResourceManager() - application.initialize_resources(api_resource_mgr) + initialize_resources(api_resource_mgr, cage) api_webapp = application.ApiApplication(api_resource_mgr) congress_api_server = eventlet_server.Server( api_webapp, host=host, port=port, @@ -102,14 +112,13 @@ class EventLoop(object): pool: An eventlet GreenPool instance. """ - def __init__(self, pool_size, module_dir=None): + def __init__(self, pool_size, module_dir=None, policy_path=None): """Init EventLoop with a given eventlet pool_size and module_dir.""" if module_dir is None: fpath = os.path.dirname(os.path.realpath(__file__)) module_dir = os.path.dirname(fpath) self.module_dir = module_dir - self.cage = congress.dse.d6cage.d6Cage() - + self.cage = harness.create(self.module_dir, policy_path) self.pool = eventlet.GreenPool(pool_size) def register_service(self, service_name, module_name, module_path, @@ -130,6 +139,66 @@ class EventLoop(object): pass +def initialize_resources(resource_mgr, cage): + """Bootstrap data models and handlers for the current API definition.""" + policies = cage.service_object('api-policy') + resource_mgr.register_model('policies', policies) + + policy_collection_handler = CollectionHandler( + r'/policies', policies, allow_create=False) + resource_mgr.register_handler(policy_collection_handler) + policy_element_handler = ElementHandler( + r'/policies/(?P[^/]+)', policies, policy_collection_handler, + allow_replace=False, allow_update=False, allow_delete=False) + resource_mgr.register_handler(policy_element_handler) + + policy_rules = cage.service_object('api-rule') + resource_mgr.register_model('rules', policy_rules) + rule_collection_handler = CollectionHandler( + r'/policies/(?P[^/]+)/rules', policy_rules, "{policy_id}") + resource_mgr.register_handler(rule_collection_handler) + rule_element_handler = ElementHandler( + r'/policies/(?P[^/]+)/rules/(?P[^/]+)', + policy_rules, "{policy_id}") + resource_mgr.register_handler(rule_element_handler) + + data_sources = cage.service_object('api-datasource') + resource_mgr.register_model('data_sources', data_sources) + ds_collection_handler = CollectionHandler(r'/data-sources', data_sources) + resource_mgr.register_handler(ds_collection_handler) + ds_path = r'/data-sources/(?P[^/]+)' + ds_element_handler = ElementHandler(ds_path, data_sources) + resource_mgr.register_handler(ds_element_handler) + + # TODO(pballand) register models for schema and status + #schema_path = "%s/schema" % ds_path + #schema_element_handler = ElementHandler(schema_path, XXX, + # "schema") + #resource_mgr.register_handler(schema_element_handler) + #status_path = "%s/status" % ds_path + #status_element_handler = ElementHandler(status_path, XXX, + # "status") + #resource_mgr.register_handler(status_element_handler) + + tables = cage.service_object('api-table') + resource_mgr.register_model('tables', tables) + tables_path = "%s/tables" % ds_path + table_collection_handler = CollectionHandler(tables_path, tables) + resource_mgr.register_handler(table_collection_handler) + table_path = "%s/(?P[^/]+)" % tables_path + table_element_handler = ElementHandler(table_path, tables) + resource_mgr.register_handler(table_element_handler) + + table_rows = cage.service_object('api-row') + resource_mgr.register_model('table_rows', table_rows) + rows_path = "%s/rows" % table_path + row_collection_handler = CollectionHandler(rows_path, table_rows) + resource_mgr.register_handler(row_collection_handler) + row_path = "%s/(?P[^/]+)" % rows_path + row_element_handler = ElementHandler(row_path, table_rows) + resource_mgr.register_handler(row_element_handler) + + def main(): config.init(sys.argv[1:]) if not cfg.CONF.config_file: @@ -139,13 +208,6 @@ def main(): config.setup_logging() LOG.info("Starting congress server") - # TODO(pballand): Fix the policy enginge registration to work with the - # latest policy changes. - # engine = loop.register_service( - # "engine", "PolicyEngine", "policy/dsepolicy.py", - # "Policy Engine (DseRuntime instance)") - # engine.initialize_table_subscriptions() - # API resource runtime encapsulation: # event loop -> wsgi server -> webapp -> resource manager @@ -156,7 +218,8 @@ def main(): "congress-api-server", cfg.CONF.bind_host, cfg.CONF.bind_port, - cfg.CONF.api_workers)) + cfg.CONF.api_workers, + policy_path=cfg.CONF.policy_path)) serve(*servers) diff --git a/etc/congress.conf.sample b/etc/congress.conf.sample index 539214367..f41a35651 100644 --- a/etc/congress.conf.sample +++ b/etc/congress.conf.sample @@ -29,3 +29,6 @@ # Port the bind the API server to # bind_port = 9696 + +policy_path = '/Users/thinrichs/congress/congress/tests/snapshot' +