diff --git a/bin/manage_db.py b/bin/manage_db.py index 4d969b63..afd5c46e 100755 --- a/bin/manage_db.py +++ b/bin/manage_db.py @@ -21,13 +21,9 @@ import sys from flask.ext.script import Manager -from compass.actions import clean_deployment -from compass.actions import clean_installing_progress from compass.actions import deploy from compass.actions import reinstall -from compass.actions import search from compass.api import app -from compass.config_management.utils import config_manager from compass.db.api import database from compass.tasks.client import celery from compass.utils import flags @@ -98,8 +94,9 @@ def checkdb(): @app_manager.command def createdb(): """Creates database from sqlalchemy models.""" + database.init() try: - dropdb() + database.drop_db() except Exception: pass @@ -114,12 +111,14 @@ def createdb(): @app_manager.command def dropdb(): """Drops database from sqlalchemy models.""" + database.init() database.drop_db() @app_manager.command def createtable(): """Create database table.""" + database.init() if not flags.OPTIONS.table_name: print 'flag --table_name is missing' return @@ -135,6 +134,7 @@ def createtable(): @app_manager.command def droptable(): """Drop database table.""" + database.init() if not flags.OPTIONS.table_name: print 'flag --table_name is missing' return @@ -147,68 +147,6 @@ def droptable(): database.drop_table(TABLE_MAPPING[table_name]) -@app_manager.command -def sync_from_installers(): - """set adapters in Adapter table from installers.""" - with database.session(): - manager = config_manager.ConfigManager() - manager.update_adapters_from_installers() - - -@app_manager.command -def sync_switch_configs(): - """Set switch configs in SwitchConfig table from setting. - - .. note:: - the switch config is stored in SWITCHES list in setting config. - for each entry in the SWITCHES, its type is dict and must contain - fields 'switch_ips' and 'filter_ports'. - The format of switch_ips is - .... - ip_blocks consists of ip_block separated by comma. - ip_block can be an integer and a range of integer like xx-xx. - The example of switch_ips is like: xxx.xxx.xxx-yyy,xxx-yyy.xxx,yyy - The format of filter_ports consists of list of - separated by comma. port_range can be an - integer or a rnage of integer like xx-xx. - The example of filter_ports is like: ae1-5,20-40. - """ - with database.session(): - manager = config_manager.ConfigManager() - manager.update_switch_filters() - - -@app_manager.command -def clean_clusters(): - """Delete clusters and hosts. - - .. note:: - The clusters and hosts are defined in --clusters. - the clusters flag is as clusterid:hostname1,hostname2,...;... - """ - cluster_hosts = util.get_clusters_from_str(flags.OPTIONS.clusters) - if flags.OPTIONS.async: - celery.send_task('compass.tasks.clean_deployment', (cluster_hosts,)) - else: - clean_deployment.clean_deployment(cluster_hosts) - - -@app_manager.command -def clean_installation_progress(): - """Clean clusters and hosts installation progress. - - .. note:: - The cluster and hosts is defined in --clusters. - The clusters flags is as clusterid:hostname1,hostname2,...;... - """ - cluster_hosts = util.get_clusters_from_str(flags.OPTIONS.clusters) - if flags.OPTIONS.async: - celery.send_task('compass.tasks.clean_installing_progress', - (cluster_hosts,)) - else: - clean_installing_progress.clean_installing_progress(cluster_hosts) - - @app_manager.command def reinstall_clusters(): """Reinstall hosts in clusters. @@ -217,7 +155,7 @@ def reinstall_clusters(): The hosts are defined in --clusters. The clusters flag is as clusterid:hostname1,hostname2,...;... """ - cluster_hosts = util.get_clusters_from_str(flags.OPTIONS.clusters) + cluster_hosts = flags.OPTIONS.clusters if flags.OPTIONS.async: celery.send_task('compass.tasks.reinstall', (cluster_hosts,)) else: @@ -232,77 +170,13 @@ def deploy_clusters(): The hosts are defined in --clusters. The clusters flag is as clusterid:hostname1,hostname2,...;... """ - cluster_hosts = util.get_clusters_from_str(flags.OPTIONS.clusters) + cluster_hosts = flags.OPTIONS.clusters if flags.OPTIONS.async: celery.send_task('compass.tasks.deploy', (cluster_hosts,)) else: deploy.deploy(cluster_hosts) -@app_manager.command -def set_switch_machines(): - """Set switches and machines. - - .. note:: - --switch_machines_file is the filename which stores all switches - and machines information. - each line in fake_switches_files presents one machine. - the format of each line machine,,,, - or switch,,,, - , - """ - if not flags.OPTIONS.switch_machines_file: - print 'flag --switch_machines_file is missing' - return - - switches, switch_machines = util.get_switch_machines_from_file( - flags.OPTIONS.switch_machines_file) - with database.session(): - manager = config_manager.ConfigManager() - manager.update_switch_and_machines(switches, switch_machines) - - -@app_manager.command -def search_cluster_hosts(): - """Search cluster hosts by properties. - - .. note:: - --search_cluster_properties defines what properties are used to search. - the format of search_cluster_properties is as - =;... If no search properties are set, - It will returns properties of all hosts. - --print_cluster_properties defines what properties to print. - the format of print_cluster_properties is as - ;... - --search_host_properties defines what properties are used to search. - the format of search_host_properties is as - =;... If no search properties are set, - It will returns properties of all hosts. - --print_host_properties defines what properties to print. - the format of print_host_properties is as - ;... - - """ - cluster_properties = util.get_properties_from_str( - flags.OPTIONS.search_cluster_properties) - cluster_properties_name = util.get_properties_name_from_str( - flags.OPTIONS.print_cluster_properties) - host_properties = util.get_properties_from_str( - flags.OPTIONS.search_host_properties) - host_properties_name = util.get_properties_name_from_str( - flags.OPTIONS.print_host_properties) - cluster_hosts = util.get_clusters_from_str(flags.OPTIONS.clusters) - cluster_properties, cluster_host_properties = search.search( - cluster_hosts, cluster_properties, - cluster_properties_name, host_properties, - host_properties_name) - print 'clusters properties:' - util.print_properties(cluster_properties) - for clusterid, host_properties in cluster_host_properties.items(): - print 'hosts properties under cluster %s' % clusterid - util.print_properties(host_properties) - - if __name__ == "__main__": flags.init() logsetting.init() diff --git a/compass/actions/deploy.py b/compass/actions/deploy.py index b3ab0ecd..0e8a5988 100644 --- a/compass/actions/deploy.py +++ b/compass/actions/deploy.py @@ -19,7 +19,6 @@ import logging from compass.actions import util -from compass.config_management.utils.config_manager import ConfigManager from compass.db.api import database @@ -37,10 +36,3 @@ def deploy(cluster_hosts): raise Exception('failed to acquire lock to deploy') logging.debug('deploy cluster_hosts: %s', cluster_hosts) - with database.session(): - cluster_hosts, os_versions, target_systems = ( - util.update_cluster_hosts(cluster_hosts)) - manager = ConfigManager() - manager.install_cluster_and_hosts( - cluster_hosts, os_versions, target_systems) - manager.sync() diff --git a/compass/actions/reinstall.py b/compass/actions/reinstall.py index 42619e86..62d1bcb4 100644 --- a/compass/actions/reinstall.py +++ b/compass/actions/reinstall.py @@ -19,7 +19,6 @@ import logging from compass.actions import util -from compass.config_management.utils.config_manager import ConfigManager from compass.db.api import database @@ -36,12 +35,4 @@ def reinstall(cluster_hosts): if not lock: raise Exception( 'failed to acquire lock to reinstall') - logging.debug('reinstall cluster_hosts: %s', cluster_hosts) - with database.session(): - cluster_hosts, os_versions, target_systems = ( - util.update_cluster_hosts(cluster_hosts)) - manager = ConfigManager() - manager.reinstall_cluster_and_hosts( - cluster_hosts, os_versions, target_systems) - manager.sync() diff --git a/compass/api/__init__.py b/compass/api/__init__.py index c33faa56..ab7a2a47 100644 --- a/compass/api/__init__.py +++ b/compass/api/__init__.py @@ -40,5 +40,3 @@ app.config['REMEMBER_COOKIE_DURATION'] = ( login_manager = LoginManager() login_manager.login_view = 'login' login_manager.init_app(app) - -from compass.api import api as compass_api diff --git a/compass/api/api.py b/compass/api/api.py index 3a20f758..9204509f 100644 --- a/compass/api/api.py +++ b/compass/api/api.py @@ -16,6 +16,7 @@ """Define all the RestfulAPI entry points.""" import datetime import functools +import logging import netaddr import simplejson as json @@ -36,6 +37,7 @@ from compass.api import exception_handler from compass.api import utils from compass.db.api import adapter_holder as adapter_api from compass.db.api import cluster as cluster_api +from compass.db.api import database from compass.db.api import host as host_api from compass.db.api import machine as machine_api from compass.db.api import metadata_holder as metadata_api @@ -1885,7 +1887,15 @@ def update_host_state(host_id): ) +def init(): + logging.info('init flask') + database.init() + adapter_api.load_adapters() + metadata_api.load_metadatas() + + if __name__ == '__main__': flags.init() logsetting.init() + init() app.run(host='0.0.0.0') diff --git a/compass/db/api/adapter_holder.py b/compass/db/api/adapter_holder.py index 22367986..425320ca 100644 --- a/compass/db/api/adapter_holder.py +++ b/compass/db/api/adapter_holder.py @@ -13,6 +13,8 @@ # limitations under the License. """Adapter related object holder.""" +import logging + from compass.db.api import adapter as adapter_api from compass.db.api import database from compass.db.api import permission @@ -34,12 +36,14 @@ PACKAGE_FIELD_MAPPING = { } -def load_adapters(): - with database.session() as session: - return adapter_api.get_adapters_internal(session) +@database.run_in_session() +def load_adapters(session): + global ADAPTER_MAPPING + logging.info('load adapters into memory') + ADAPTER_MAPPING = adapter_api.get_adapters_internal(session) -ADAPTER_MAPPING = load_adapters() +ADAPTER_MAPPING = {} def _filter_adapters(adapter_config, filter_name, filter_value): @@ -62,7 +66,11 @@ def _filter_adapters(adapter_config, filter_name, filter_value): @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_adapters(lister, **filters): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_ADAPTERS +) +def list_adapters(session, lister, **filters): """list adapters.""" translated_filters = {} for filter_name, filter_value in filters: @@ -71,51 +79,51 @@ def list_adapters(lister, **filters): OS_FIELD_MAPPING[filter_name] ] = filter_value elif filter_name in PACKAGE_FIELD_MAPPING: - translated_filters.setdefault('package-adapter', {})[ + translated_filters.setdefault('package_adapter', {})[ PACKAGE_FIELD_MAPPING[filter_name] ] = filter_value else: translated_filters[filter_name] = filter_value - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_ADAPTERS) - filtered_adapter_dicts = [] - adapter_dicts = ADAPTER_MAPPING.values() - for adapter_dict in adapter_dicts: - if all([ - _filter_adapters(adapter_dict, filter_name, filter_value) - for filter_name, filter_value in translated_filters.items() - ]): - filtered_adapter_dicts.append(adapter_dict) - return filtered_adapter_dicts + + filtered_adapter_dicts = [] + adapter_dicts = ADAPTER_MAPPING.values() + for adapter_dict in adapter_dicts: + if all([ + _filter_adapters(adapter_dict, filter_name, filter_value) + for filter_name, filter_value in translated_filters.items() + ]): + filtered_adapter_dicts.append(adapter_dict) + return filtered_adapter_dicts @utils.supported_filters([]) -def get_adapter(getter, adapter_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_ADAPTERS +) +def get_adapter(session, getter, adapter_id, **kwargs): """get adapter.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_ADAPTERS) - if adapter_id not in ADAPTER_MAPPING: - raise exception.RecordNotExists( - 'adpater %s does not exist' % adapter_id - ) - return ADAPTER_MAPPING[adapter_id] + if adapter_id not in ADAPTER_MAPPING: + raise exception.RecordNotExists( + 'adpater %s does not exist' % adapter_id + ) + return ADAPTER_MAPPING[adapter_id] @utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_ADAPTERS +) def get_adapter_roles(getter, adapter_id, **kwargs): """get adapter roles.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_ADAPTERS) - if adapter_id not in ADAPTER_MAPPING: - raise exception.RecordNotExists( - 'adpater %s does not exist' % adapter_id - ) - adapter_dict = ADAPTER_MAPPING[adapter_id] - if 'package_adapter' not in adapter_dict: - raise exception.RecordNotExists( - 'adapter %s does not contain package_adapter' % adapter_id - ) - return ADAPTER_MAPPING[adapter_id]['package_adapter']['roles'] + if adapter_id not in ADAPTER_MAPPING: + raise exception.RecordNotExists( + 'adpater %s does not exist' % adapter_id + ) + adapter_dict = ADAPTER_MAPPING[adapter_id] + if 'package_adapter' not in adapter_dict: + raise exception.RecordNotExists( + 'adapter %s does not contain package_adapter' % adapter_id + ) + return ADAPTER_MAPPING[adapter_id]['package_adapter']['roles'] diff --git a/compass/db/api/cluster.py b/compass/db/api/cluster.py index 69731d8d..89f4dcce 100644 --- a/compass/db/api/cluster.py +++ b/compass/db/api/cluster.py @@ -94,31 +94,30 @@ UPDATED_CLUSTERHOST_STATE_FIELDS = [ ] -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_clusters(lister, **filters): - """List clusters.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_CLUSTERS) - return [ - cluster.to_dict() - for cluster in utils.list_db_objects( - session, models.Cluster, **filters - ) - ] - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERS +) @utils.wrap_to_dict(RESP_FIELDS) +def list_clusters(session, lister, **filters): + """List clusters.""" + return utils.list_db_objects( + session, models.Cluster, **filters + ) + + @utils.supported_filters([]) -def get_cluster(getter, cluster_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERS +) +@utils.wrap_to_dict(RESP_FIELDS) +def get_cluster(session, getter, cluster_id, **kwargs): """Get cluster info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_CLUSTERS) - return utils.get_db_object( - session, models.Cluster, id=cluster_id - ).to_dict() + return utils.get_db_object( + session, models.Cluster, id=cluster_id + ) def _conditional_exception(cluster, exception_when_not_editable): @@ -135,152 +134,147 @@ def is_cluster_editable( reinstall_distributed_system_set=False, exception_when_not_editable=True ): - with session.begin(subtransactions=True): - if reinstall_distributed_system_set: - if cluster.state.state == 'INSTALLING': - return _conditional_exception( - cluster, exception_when_not_editable - ) - elif not cluster.reinstall_distributed_system: - return _conditional_exception( - cluster, exception_when_not_editable - ) - if not user.is_admin and cluster.creator_id != user.id: + if reinstall_distributed_system_set: + if cluster.state.state == 'INSTALLING': return _conditional_exception( cluster, exception_when_not_editable ) + elif not cluster.reinstall_distributed_system: + return _conditional_exception( + cluster, exception_when_not_editable + ) + if not user.is_admin and cluster.creator_id != user.id: + return _conditional_exception( + cluster, exception_when_not_editable + ) return True -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(ADDED_FIELDS) -def add_cluster(creator, name, adapter_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_CLUSTER +) +@utils.wrap_to_dict(RESP_FIELDS) +def add_cluster(session, creator, name, adapter_id, **kwargs): """Create a cluster.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, creator, permission.PERMISSION_ADD_CLUSTER) - cluster = utils.add_db_object( - session, models.Cluster, True, - name, adapter_id=adapter_id, creator_id=creator.id, **kwargs - ) - cluster_dict = cluster.to_dict() - return cluster_dict + return utils.add_db_object( + session, models.Cluster, True, + name, adapter_id=adapter_id, creator_id=creator.id, **kwargs + ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=UPDATED_FIELDS) -def update_cluster(updater, cluster_id, **kwargs): - """Update a cluster.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTER) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - is_cluster_editable( - session, cluster, updater, - reinstall_distributed_system_set=( - kwargs.get('reinstall_distributed_system', False) - ) - ) - utils.update_db_object(session, cluster, **kwargs) - return cluster.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_CLUSTER +) @utils.wrap_to_dict(RESP_FIELDS) -@utils.supported_filters([]) -def del_cluster(deleter, cluster_id, **kwargs): - """Delete a cluster.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_CLUSTER) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id +def update_cluster(session, updater, cluster_id, **kwargs): + """Update a cluster.""" + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + is_cluster_editable( + session, cluster, updater, + reinstall_distributed_system_set=( + kwargs.get('reinstall_distributed_system', False) ) - is_cluster_editable(session, cluster, deleter) - utils.del_db_object(session, cluster) - return cluster.to_dict() + ) + return utils.update_db_object(session, cluster, **kwargs) -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters([]) -def get_cluster_config(getter, cluster_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_CLUSTER +) +@utils.wrap_to_dict(RESP_FIELDS) +def del_cluster(session, deleter, cluster_id, **kwargs): + """Delete a cluster.""" + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + is_cluster_editable(session, cluster, deleter) + return utils.del_db_object(session, cluster) + + +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTER_CONFIG +) +@utils.wrap_to_dict(RESP_CONFIG_FIELDS) +def get_cluster_config(session, getter, cluster_id, **kwargs): """Get cluster config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_CLUSTER_CONFIG) - return utils.get_db_object( - session, models.Cluster, id=cluster_id - ).to_dict() + return utils.get_db_object( + session, models.Cluster, id=cluster_id + ) +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_CLUSTER_CONFIG +) +@utils.wrap_to_dict(RESP_CONFIG_FIELDS) def update_cluster_config_internal(session, updater, cluster, **kwargs): """Update a cluster config.""" - with session.begin(subtransactions=True): - is_cluster_editable(session, cluster, updater) - utils.update_db_object( - session, cluster, config_validated=False, **kwargs + is_cluster_editable(session, cluster, updater) + utils.update_db_object( + session, cluster, config_validated=False, **kwargs + ) + os_config = cluster.os_config + if os_config: + metadata_api.validate_os_config( + os_config, cluster.adapter_id ) - os_config = cluster.os_config - if os_config: - metadata_api.validate_os_config( - os_config, cluster.adapter_id - ) - package_config = cluster.package_config - if package_config: - metadata_api.validate_package_config( - package_config, cluster.adapter_id - ) + package_config = cluster.package_config + if package_config: + metadata_api.validate_package_config( + package_config, cluster.adapter_id + ) + return cluster -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters(optional_support_keys=UPDATED_CONFIG_FIELDS) -def update_cluster_config(updater, cluster_id, **kwargs): +@database.run_in_session() +def update_cluster_config(session, updater, cluster_id, **kwargs): """Update cluster config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTER_CONFIG) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - update_cluster_config_internal( - session, updater, cluster, **kwargs - ) - return cluster.to_dict() + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + return update_cluster_config_internal( + session, updater, cluster, **kwargs + ) -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters(optional_support_keys=PATCHED_CONFIG_FIELDS) -def patch_cluster_config(updater, cluster_id, **kwargs): +@database.run_in_session() +def patch_cluster_config(session, updater, cluster_id, **kwargs): """patch cluster config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTER_CONFIG) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - update_cluster_config_internal( - session, updater, cluster, **kwargs - ) - return cluster.to_dict() + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + return update_cluster_config_internal( + session, updater, cluster, **kwargs + ) -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters([]) -def del_cluster_config(deleter, cluster_id): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_CLUSTER_CONFIG +) +@utils.wrap_to_dict(RESP_CONFIG_FIELDS) +def del_cluster_config(session, deleter, cluster_id): """Delete a cluster config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_CLUSTER_CONFIG) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - is_cluster_editable(session, cluster, deleter) - utils.update_db_object( - session, cluster, os_config={}, - package_config={}, config_validated=False - ) - return cluster.to_dict() + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + is_cluster_editable(session, cluster, deleter) + return utils.update_db_object( + session, cluster, os_config={}, + package_config={}, config_validated=False + ) @utils.supported_filters( @@ -331,467 +325,477 @@ def add_clusterhost_internal( def _add_clusterhosts(session, cluster, machine_dicts): - with session.begin(subtransactions=True): - for machine_dict in machine_dicts: - add_clusterhost_internal( - session, cluster, - **machine_dict - ) + for machine_dict in machine_dicts: + add_clusterhost_internal( + session, cluster, **machine_dict + ) def _remove_clusterhosts(session, cluster, host_ids): - with session.begin(subtransactions=True): - utils.del_db_objects( - session, models.ClusterHost, - cluster_id=cluster.id, host_id=host_ids - ) + utils.del_db_objects( + session, models.ClusterHost, + cluster_id=cluster.id, host_id=host_ids + ) def _set_clusterhosts(session, cluster, machine_dicts): - with session.begin(subtransactions=True): - utils.del_db_objects( - session, models.ClusterHost, - cluster_id=cluster.id + utils.del_db_objects( + session, models.ClusterHost, + cluster_id=cluster.id + ) + for machine_dict in machine_dicts: + add_clusterhost_internal( + session, cluster, True, **machine_dict ) - for machine_dict in machine_dicts: - add_clusterhost_internal( - session, cluster, - True, **machine_dict - ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_CLUSTERHOST_FIELDS) -def list_cluster_hosts(lister, cluster_id, **filters): - """Get cluster host info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_CLUSTERHOSTS) - return [ - clusterhost.to_dict() - for clusterhost in utils.list_db_objects( - session, models.ClusterHost, cluster_id=cluster_id, - **filters - ) - ] - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERHOSTS +) @utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) +def list_cluster_hosts(session, lister, cluster_id, **filters): + """Get cluster host info.""" + return utils.list_db_objects( + session, models.ClusterHost, cluster_id=cluster_id, + **filters + ) + + @utils.supported_filters(optional_support_keys=SUPPORTED_CLUSTERHOST_FIELDS) -def list_clusterhosts(lister, **filters): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERHOSTS +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) +def list_clusterhosts(session, lister, **filters): """Get cluster host info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_CLUSTERHOSTS) - return [ - clusterhost.to_dict() - for clusterhost in utils.list_db_objects( - session, models.ClusterHost, - **filters - ) - ] + return utils.list_db_objects( + session, models.ClusterHost, **filters + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) @utils.supported_filters([]) -def get_cluster_host(getter, cluster_id, host_id, **kwargs): - """Get clusterhost info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_CLUSTERHOSTS) - return utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ).to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERHOSTS +) @utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) +def get_cluster_host(session, getter, cluster_id, host_id, **kwargs): + """Get clusterhost info.""" + return utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ) + + @utils.supported_filters([]) -def get_clusterhost(getter, clusterhost_id, **kwargs): - """Get clusterhost info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_CLUSTERHOSTS) - return utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ).to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERHOSTS +) @utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) +def get_clusterhost(session, getter, clusterhost_id, **kwargs): + """Get clusterhost info.""" + return utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ) + + @utils.supported_filters( ADDED_CLUSTERHOST_FIELDS, optional_support_keys=UPDATED_CLUSTERHOST_FIELDS ) -def add_cluster_host(creator, cluster_id, machine_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_CLUSTER_HOSTS +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) +def add_cluster_host(session, creator, cluster_id, machine_id, **kwargs): """Add cluster host.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, creator, permission.PERMISSION_UPDATE_CLUSTER_HOSTS) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - clusterhost = add_clusterhost_internal( - session, cluster, True, - machine_id=machine_id, **kwargs - ) - return clusterhost.to_dict() + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + return add_clusterhost_internal( + session, cluster, True, + machine_id=machine_id, **kwargs + ) +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_CLUSTER_HOST +) @utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) -@utils.supported_filters([]) -def del_cluster_host(deleter, cluster_id, host_id, **kwargs): +def del_cluster_host(session, deleter, cluster_id, host_id, **kwargs): """Delete cluster host.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_CLUSTER_HOST) - clusterhost = utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ) - utils.del_db_object( - session, clusterhost - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ) + return utils.del_db_object( + session, clusterhost + ) +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_CLUSTER_HOST +) @utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) -@utils.supported_filters([]) -def del_clusterhost(deleter, clusterhost_id, **kwargs): +def del_clusterhost(session, deleter, clusterhost_id, **kwargs): """Delete cluster host.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_CLUSTER_HOST) - clusterhost = utils.get_db_object( - session, models.ClusterHost, - id=clusterhost_id - ) - utils.del_db_object( - session, clusterhost - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, + id=clusterhost_id + ) + return utils.del_db_object( + session, clusterhost + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) @utils.supported_filters([]) -def get_cluster_host_config(getter, cluster_id, host_id, **kwargs): - """Get clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_CLUSTERHOST_CONFIG) - return utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ).to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERHOST_CONFIG +) @utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) -@utils.supported_filters([]) -def get_clusterhost_config(getter, clusterhost_id, **kwargs): +def get_cluster_host_config(session, getter, cluster_id, host_id, **kwargs): """Get clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_CLUSTERHOST_CONFIG) - return utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ).to_dict() + return utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ) +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_CLUSTERHOST_CONFIG +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) +def get_clusterhost_config(session, getter, clusterhost_id, **kwargs): + """Get clusterhost config.""" + return utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ) + + +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_CLUSTERHOST_CONFIG +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) def update_clusterhost_config_internal( session, updater, clusterhost, **kwargs ): """Update clusterhost config internal.""" - with session.begin(subtransactions=True): - is_cluster_editable(session, clusterhost.cluster, updater) - utils.update_db_object( - session, clusterhost, config_validated=False, **kwargs + is_cluster_editable(session, clusterhost.cluster, updater) + utils.update_db_object( + session, clusterhost, config_validated=False, **kwargs + ) + package_config = clusterhost.package_config + if package_config: + metadata_api.validate_package_config( + package_config, clusterhost.cluster.adapter_id ) - package_config = clusterhost.package_config - if package_config: - metadata_api.validate_package_config( - package_config, clusterhost.cluster.adapter_id - ) + return clusterhost -@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) @utils.supported_filters( optional_support_keys=UPDATED_CLUSTERHOST_CONFIG_FIELDS ) -def update_cluster_host_config(updater, cluster_id, host_id, **kwargs): +@database.run_in_session() +def update_cluster_host_config( + session, updater, cluster_id, host_id, **kwargs +): """Update clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTERHOST_CONFIG) - clusterhost = utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ) - update_clusterhost_config_internal( - session, updater, clusterhost, **kwargs - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ) + return update_clusterhost_config_internal( + session, updater, clusterhost, **kwargs + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) @utils.supported_filters( optional_support_keys=UPDATED_CLUSTERHOST_CONFIG_FIELDS ) -def update_clusterhost_config(updater, clusterhost_id, **kwargs): +@database.run_in_session() +def update_clusterhost_config( + session, updater, clusterhost_id, **kwargs +): """Update clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTERHOST_CONFIG) - clusterhost = utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ) - update_clusterhost_config_internal( - session, updater, clusterhost, **kwargs - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ) + return update_clusterhost_config_internal( + session, updater, clusterhost, **kwargs + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) @utils.supported_filters(PATCHED_CLUSTERHOST_CONFIG_FIELDS) -def patch_cluster_host_config(updater, cluster_id, host_id, **kwargs): +@database.run_in_session() +def patch_cluster_host_config( + session, updater, cluster_id, host_id, **kwargs +): """patch clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTERHOST_CONFIG) - clusterhost = utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ) - update_clusterhost_config_internal( - session, updater, clusterhost, **kwargs - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ) + return update_clusterhost_config_internal( + session, updater, clusterhost, **kwargs + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) @utils.supported_filters(PATCHED_CLUSTERHOST_CONFIG_FIELDS) -def patch_clusterhost_config(updater, clusterhost_id, **kwargs): +@database.run_in_session() +def patch_clusterhost_config( + session, updater, clusterhost_id, **kwargs +): """patch clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_CLUSTERHOST_CONFIG) - clusterhost = utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ) - update_clusterhost_config_internal( - session, updater, clusterhost, **kwargs - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ) + return update_clusterhost_config_internal( + session, updater, clusterhost, **kwargs + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) @utils.supported_filters([]) -def delete_cluster_host_config(deleter, cluster_id, host_id): - """Delet a clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_CLUSTERHOST_CONFIG) - clusterhost = utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, hsot_id=host_id - ) - is_cluster_editable(session, clusterhost.cluster, deleter) - utils.update_db_object( - session, clusterhost, package_config={}, config_validated=False - ) - return clusterhost.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_CLUSTERHOST_CONFIG +) @utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) +def delete_cluster_host_config( + session, deleter, cluster_id, host_id +): + """Delete a clusterhost config.""" + clusterhost = utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, hsot_id=host_id + ) + is_cluster_editable(session, clusterhost.cluster, deleter) + return utils.update_db_object( + session, clusterhost, package_config={}, config_validated=False + ) + + @utils.supported_filters([]) -def delete_clusterhost_config(deleter, clusterhost_id): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_CLUSTERHOST_CONFIG +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_CONFIG_FIELDS) +def delete_clusterhost_config(session, deleter, clusterhost_id): """Delet a clusterhost config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_CLUSTERHOST_CONFIG) - clusterhost = utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ) - is_cluster_editable(session, clusterhost.cluster, deleter) - utils.update_db_object( - session, clusterhost, package_config={}, config_validated=False - ) - return clusterhost.to_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ) + is_cluster_editable(session, clusterhost.cluster, deleter) + return utils.update_db_object( + session, clusterhost, package_config={}, config_validated=False + ) -@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) @utils.supported_filters( optional_support_keys=['add_hosts', 'remove_hosts', 'set_hosts'] ) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_CLUSTER_HOSTS +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_FIELDS) def update_cluster_hosts( - updater, cluster_id, add_hosts=[], set_hosts=None, + session, updater, cluster_id, add_hosts=[], set_hosts=None, remove_hosts=[] ): """Update cluster hosts.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_UPDATE_CLUSTER_HOSTS) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - is_cluster_editable(session, cluster, updater) - if remove_hosts: - _remove_clusterhosts(session, cluster, remove_hosts) - if add_hosts: - _add_clusterhosts(session, cluster, add_hosts) - if set_hosts is not None: - _set_clusterhosts(session, cluster, set_hosts) - return [host.to_dict() for host in cluster.clusterhosts] + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + is_cluster_editable(session, cluster, updater) + if remove_hosts: + _remove_clusterhosts(session, cluster, remove_hosts) + if add_hosts: + _add_clusterhosts(session, cluster, add_hosts) + if set_hosts is not None: + _set_clusterhosts(session, cluster, set_hosts) + return cluster.clusterhosts -@utils.wrap_to_dict(RESP_REVIEW_FIELDS) @utils.supported_filters([]) -def review_cluster(reviewer, cluster_id): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_REVIEW_CLUSTER +) +@utils.wrap_to_dict(RESP_REVIEW_FIELDS) +def review_cluster(session, reviewer, cluster_id): """review cluster.""" from compass.db.api import host as host_api - with database.session() as session: - user_api.check_user_permission_internal( - session, reviewer, permission.PERMISSION_REVIEW_CLUSTER) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + is_cluster_editable(session, cluster, reviewer) + os_config = cluster.os_config + if os_config: + metadata_api.validate_os_config( + os_config, cluster.adapter_id, True ) - is_cluster_editable(session, cluster, reviewer) - os_config = cluster.os_config - if os_config: + for clusterhost in cluster.clusterhosts: + host = clusterhost.host + if not host_api.is_host_editable( + session, host, reviewer, False + ): + logging.info( + 'ignore update host %s config ' + 'since it is not editable' % host.name + ) + continue + host_os_config = host.os_config + deployed_os_config = util.merge_dict( + os_config, host_os_config + ) metadata_api.validate_os_config( - os_config, cluster.adapter_id, True + deployed_os_config, host.adapter_id, True + ) + host.deployed_os_config = deployed_os_config + host.config_validated = True + package_config = cluster.package_config + if package_config: + metadata_api.validate_package_config( + package_config, cluster.adapter_id, True + ) + for clusterhost in cluster.clusterhosts: + clusterhost_package_config = clusterhost.package_config + deployed_package_config = util.mrege_dict( + package_config, clusterhost_package_config ) - for clusterhost in cluster.clusterhosts: - host = clusterhost.host - if not host_api.is_host_editable( - session, host, reviewer, False - ): - logging.info( - 'ignore update host %s config ' - 'since it is not editable' % host.name - ) - continue - host_os_config = host.os_config - deployed_os_config = util.merge_dict( - os_config, host_os_config - ) - metadata_api.validate_os_config( - deployed_os_config, host.adapter_id, True - ) - host.deployed_os_config = deployed_os_config - host.config_validated = True - package_config = cluster.package_config - if package_config: metadata_api.validate_package_config( - package_config, cluster.adapter_id, True + deployed_package_config, + cluster.adapter_id, True ) - for clusterhost in cluster.clusterhosts: - clusterhost_package_config = clusterhost.package_config - deployed_package_config = util.mrege_dict( - package_config, clusterhost_package_config - ) - metadata_api.validate_os_config( - deployed_package_config, - cluster.adapter_id, True - ) - clusterhost.deployed_package_config = deployed_package_config - clusterhost.config_validated = True - cluster.config_validated = True - return { - 'cluster': cluster.to_dict(), - 'clusterhosts': [ - clusterhost.to_dict() - for clusterhost in cluster.clusterhosts - ] - } + clusterhost.deployed_package_config = deployed_package_config + clusterhost.config_validated = True + cluster.config_validated = True + return { + 'cluster': cluster.to_dict(), + 'clusterhosts': [ + clusterhost.to_dict() + for clusterhost in cluster.clusterhosts + ] + } -@utils.wrap_to_dict(RESP_ACTION_FIELDS) @utils.supported_filters(optional_support_keys=['clusterhosts']) -def deploy_cluster(deployer, cluster_id, clusterhosts=[], **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEPLOY_CLUSTER +) +@utils.wrap_to_dict(RESP_ACTION_FIELDS) +def deploy_cluster( + session, deployer, cluster_id, clusterhosts=[], **kwargs +): """deploy cluster.""" from compass.tasks import client as celery_client - with database.session() as session: - user_api.check_user_permission_internal( - session, deployer, permission.PERMISSION_DEPLOY_CLUSTER) - cluster = utils.get_db_object( - session, models.Cluster, id=cluster_id - ) - is_cluster_editable(session, cluster, deployer) - celery_client.celery.send_task( - 'compass.tasks.deploy', - (cluster_id, clusterhosts) - ) - return { - 'status': 'deploy action sent', - 'details': { - } + cluster = utils.get_db_object( + session, models.Cluster, id=cluster_id + ) + is_cluster_editable(session, cluster, deployer) + celery_client.celery.send_task( + 'compass.tasks.deploy', + (cluster_id, clusterhosts) + ) + return { + 'status': 'deploy action sent', + 'details': { } + } +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_GET_CLUSTER_STATE +) @utils.wrap_to_dict(RESP_STATE_FIELDS) -@utils.supported_filters([]) -def get_cluster_state(getter, cluster_id, **kwargs): +def get_cluster_state(session, getter, cluster_id, **kwargs): """Get cluster state info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_GET_CLUSTER_STATE) - return utils.get_db_object( - session, models.Cluster, id=cluster_id - ).state_dict() + return utils.get_db_object( + session, models.Cluster, id=cluster_id + ).state_dict() -@utils.wrap_to_dict(RESP_CLUSTERHOST_STATE_FIELDS) @utils.supported_filters([]) -def get_cluster_host_state(getter, cluster_id, host_id, **kwargs): - """Get clusterhost state info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_GET_CLUSTERHOST_STATE) - return utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ).state_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_GET_CLUSTERHOST_STATE +) @utils.wrap_to_dict(RESP_CLUSTERHOST_STATE_FIELDS) +def get_cluster_host_state( + session, getter, cluster_id, host_id, **kwargs +): + """Get clusterhost state info.""" + return utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ).state_dict() + + @utils.supported_filters([]) -def get_clusterhost_state(getter, clusterhost_id, **kwargs): - """Get clusterhost state info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_GET_CLUSTERHOST_STATE) - return utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ).state_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_GET_CLUSTERHOST_STATE +) @utils.wrap_to_dict(RESP_CLUSTERHOST_STATE_FIELDS) +def get_clusterhost_state( + session, getter, clusterhost_id, **kwargs +): + """Get clusterhost state info.""" + return utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ).state_dict() + + @utils.supported_filters( optional_support_keys=UPDATED_CLUSTERHOST_STATE_FIELDS ) -def update_cluster_host_state(updater, cluster_id, host_id, **kwargs): - """Update a clusterhost state.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_UPDATE_CLUSTERHOST_STATE) - clusterhost = utils.get_db_object( - session, models.ClusterHost, - cluster_id=cluster_id, host_id=host_id - ) - utils.update_db_object(session, clusterhost.state, **kwargs) - return clusterhost.state_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_CLUSTERHOST_STATE +) @utils.wrap_to_dict(RESP_CLUSTERHOST_STATE_FIELDS) +def update_cluster_host_state( + session, updater, cluster_id, host_id, **kwargs +): + """Update a clusterhost state.""" + clusterhost = utils.get_db_object( + session, models.ClusterHost, + cluster_id=cluster_id, host_id=host_id + ) + utils.update_db_object(session, clusterhost.state, **kwargs) + return clusterhost.state_dict() + + @utils.supported_filters( optional_support_keys=UPDATED_CLUSTERHOST_STATE_FIELDS ) -def update_clusterhost_state(updater, clusterhost_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_CLUSTERHOST_STATE +) +@utils.wrap_to_dict(RESP_CLUSTERHOST_STATE_FIELDS) +def update_clusterhost_state( + session, updater, clusterhost_id, **kwargs +): """Update a clusterhost state.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_UPDATE_CLUSTERHOST_STATE) - clusterhost = utils.get_db_object( - session, models.ClusterHost, id=clusterhost_id - ) - is_cluster_editable(session, clusterhost.cluster, updater) - return clusterhost.state_dict() + clusterhost = utils.get_db_object( + session, models.ClusterHost, id=clusterhost_id + ) + utils.update_db_object(session, clusterhost.state, **kwargs) + return clusterhost.state_dict() diff --git a/compass/db/api/database.py b/compass/db/api/database.py index 722ce4df..d478272c 100644 --- a/compass/db/api/database.py +++ b/compass/db/api/database.py @@ -13,6 +13,7 @@ # limitations under the License. """Provider interface to manipulate database.""" +import functools import logging import netaddr @@ -33,22 +34,22 @@ SCOPED_SESSION = None SESSION_HOLDER = local() -def init(database_url): +def init(database_url=None): """Initialize database. :param database_url: string, database url. """ global ENGINE global SCOPED_SESSION + if not database_url: + database_url = setting.SQLALCHEMY_DATABASE_URI + logging.info('init database %s', database_url) ENGINE = create_engine(database_url, convert_unicode=True) SESSION.configure(bind=ENGINE) SCOPED_SESSION = scoped_session(SESSION) models.BASE.query = SCOPED_SESSION.query_property() -init(setting.SQLALCHEMY_DATABASE_URI) - - def in_session(): """check if in database session scope.""" if hasattr(SESSION_HOLDER, 'session'): @@ -105,6 +106,16 @@ def current_session(): raise exception.DatabaseException(str(error)) +def run_in_session(): + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + with session() as my_session: + return func(my_session, *args, **kwargs) + return wrapper + return decorator + + def _setup_user_table(user_session): """Initialize default user.""" logging.info('setup user table') @@ -229,25 +240,25 @@ def _setup_package_adapter_roles(role_session): adapter.add_roles_internal(role_session) -def create_db(): +@run_in_session() +def create_db(my_session): """Create database.""" models.BASE.metadata.create_all(bind=ENGINE) - with session() as my_session: - _setup_permission_table(my_session) - _setup_user_table(my_session) - _setup_switch_table(my_session) - _setup_os_installers(my_session) - _setup_package_installers(my_session) - _setup_oses(my_session) - _setup_distributed_systems(my_session) - _setup_os_adapters(my_session) - _setup_package_adapters(my_session) - _setup_package_adapter_roles(my_session) - _setup_adapters(my_session) - _setup_os_fields(my_session) - _setup_package_fields(my_session) - _setup_os_metadatas(my_session) - _setup_package_metadatas(my_session) + _setup_permission_table(my_session) + _setup_user_table(my_session) + _setup_switch_table(my_session) + _setup_os_installers(my_session) + _setup_package_installers(my_session) + _setup_oses(my_session) + _setup_distributed_systems(my_session) + _setup_os_adapters(my_session) + _setup_package_adapters(my_session) + _setup_package_adapter_roles(my_session) + _setup_adapters(my_session) + _setup_os_fields(my_session) + _setup_package_fields(my_session) + _setup_os_metadatas(my_session) + _setup_package_metadatas(my_session) def drop_db(): @@ -255,50 +266,50 @@ def drop_db(): models.BASE.metadata.drop_all(bind=ENGINE) -def create_table(table): +@run_in_session() +def create_table(my_session, table): """Create table. :param table: Class of the Table defined in the model. """ table.__table__.create(bind=ENGINE, checkfirst=True) - with session() as my_session: - if table == models.User: - _setup_user_table(my_session) - elif table == models.Permission: - _setup_permission_table(my_session) - elif table == models.Switch: - _setup_switch_table(my_session) - elif table in [ - models.OSInstaller, - models.PackageInstaller, - models.OperatingSystem, - models.DistributedSystems, - models.OSAdapter, - models.PackageAdapter, - models.Adapter - ]: - _setup_os_installers(my_session) - _setup_package_installers(my_session) - _setup_os_adapters(my_session) - _setup_package_adapters(my_session) - _setup_package_adapter_roles(my_session) - _setup_adapters(my_session) - _setup_os_fields(my_session) - _setup_os_metadatas(my_session) - _setup_package_fields(my_session) - _setup_package_metadatas(my_session) - elif table == models.PackageAdapterRole: - _setup_package_adapter_roles(my_session) - elif table in [ - models.OSConfigField, - models.PackageConfigField, - models.OSConfigMetadata, - models.PackageConfigMetadata - ]: - _setup_os_fields(my_session) - _setup_os_metadatas(my_session) - _setup_package_fields(my_session) - _setup_package_metadatas(my_session) + if table == models.User: + _setup_user_table(my_session) + elif table == models.Permission: + _setup_permission_table(my_session) + elif table == models.Switch: + _setup_switch_table(my_session) + elif table in [ + models.OSInstaller, + models.PackageInstaller, + models.OperatingSystem, + models.DistributedSystems, + models.OSAdapter, + models.PackageAdapter, + models.Adapter + ]: + _setup_os_installers(my_session) + _setup_package_installers(my_session) + _setup_os_adapters(my_session) + _setup_package_adapters(my_session) + _setup_package_adapter_roles(my_session) + _setup_adapters(my_session) + _setup_os_fields(my_session) + _setup_os_metadatas(my_session) + _setup_package_fields(my_session) + _setup_package_metadatas(my_session) + elif table == models.PackageAdapterRole: + _setup_package_adapter_roles(my_session) + elif table in [ + models.OSConfigField, + models.PackageConfigField, + models.OSConfigMetadata, + models.PackageConfigMetadata + ]: + _setup_os_fields(my_session) + _setup_os_metadatas(my_session) + _setup_package_fields(my_session) + _setup_package_metadatas(my_session) def drop_table(table): diff --git a/compass/db/api/host.py b/compass/db/api/host.py index 9b8f85f0..a09ea77e 100644 --- a/compass/db/api/host.py +++ b/compass/db/api/host.py @@ -68,45 +68,44 @@ UPDATED_STATE_FIELDS = [ ] -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_hosts(lister, **filters): - """List hosts.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_HOSTS) - return [ - host.to_dict() - for host in utils.list_db_objects( - session, models.Host, **filters - ) - ] - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOSTS +) @utils.wrap_to_dict(RESP_FIELDS) +def list_hosts(session, lister, **filters): + """List hosts.""" + return utils.list_db_objects( + session, models.Host, **filters + ) + + @utils.supported_filters([]) -def get_host(getter, host_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOSTS +) +@utils.wrap_to_dict(RESP_FIELDS) +def get_host(session, getter, host_id, **kwargs): """get host info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_HOSTS) - return utils.get_db_object( - session, models.Host, id=host_id - ).to_dict() + return utils.get_db_object( + session, models.Host, id=host_id + ) -@utils.wrap_to_dict(RESP_CLUSTER_FIELDS) @utils.supported_filters([]) -def get_host_clusters(getter, host_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOST_CLUSTERS +) +@utils.wrap_to_dict(RESP_CLUSTER_FIELDS) +def get_host_clusters(session, getter, host_id, **kwargs): """get host clusters.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_HOST_CLUSTERS) - host = utils.get_db_object( - session, models.Host, id=host_id - ) - clusterhosts = host.clusterhosts - return [clusterhost.cluster.to_dict() for clusterhost in clusterhosts] + host = utils.get_db_object( + session, models.Host, id=host_id + ) + return [clusterhost.cluster for clusterhost in host.clusterhosts] def _conditional_exception(host, exception_when_not_editable): @@ -139,262 +138,266 @@ def is_host_editable( return True -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(UPDATED_FIELDS) -def update_host(updater, host_id, **kwargs): - """Update a host.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_UPDATE_HOST) - host = utils.get_db_object( - session, models.Host, id=host_id - ) - is_host_editable( - session, host, updater, - reinstall_os_set=kwargs.get('reinstall_os', False) - ) - utils.update_db_object(session, host, **kwargs) - return host.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_HOST +) @utils.wrap_to_dict(RESP_FIELDS) +def update_host(session, updater, host_id, **kwargs): + """Update a host.""" + host = utils.get_db_object( + session, models.Host, id=host_id + ) + is_host_editable( + session, host, updater, + reinstall_os_set=kwargs.get('reinstall_os', False) + ) + return utils.update_db_object(session, host, **kwargs) + + @utils.supported_filters([]) -def del_host(deleter, host_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_HOST +) +@utils.wrap_to_dict(RESP_FIELDS) +def del_host(session, deleter, host_id, **kwargs): """Delete a host.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_HOST) - host = utils.get_db_object( - session, models.Host, id=host_id - ) - is_host_editable(session, host, deleter) - utils.del_db_object(session, host) - return host.to_dict() + host = utils.get_db_object( + session, models.Host, id=host_id + ) + is_host_editable(session, host, deleter) + return utils.del_db_object(session, host) -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters([]) -def get_host_config(getter, host_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOST_CONFIG +) +@utils.wrap_to_dict(RESP_CONFIG_FIELDS) +def get_host_config(session, getter, host_id, **kwargs): """Get host config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_HOST_CONFIG) - return utils.get_db_object( - session, models.Host, id=host_id - ).to_dict() + return utils.get_db_object( + session, models.Host, id=host_id + ) -def _update_host_config(updater, host_id, **kwargs): +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_HOST_CONFIG +) +@utils.wrap_to_dict(RESP_CONFIG_FIELDS) +def _update_host_config(session, updater, host_id, **kwargs): """Update host config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_HOST_CONFIG) - host = utils.get_db_object( - session, models.Host, id=host_id + host = utils.get_db_object( + session, models.Host, id=host_id + ) + is_host_editable(session, host, updater) + utils.update_db_object(session, host, config_validated=False, **kwargs) + os_config = host.os_config + if os_config: + metadata_api.validate_os_config( + os_config, host.adapter_id ) - is_host_editable(session, host, updater) - utils.update_db_object(session, host, config_validated=False, **kwargs) - os_config = host.os_config - if os_config: - metadata_api.validate_os_config( - os_config, host.adapter_id - ) - return host.to_dict() + return host -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters(UPDATED_CONFIG_FIELDS) -def update_host_config(updater, host_id, **kwargs): - return _update_host_config(updater, host_id, **kwargs) +@database.run_in_session() +def update_host_config(session, updater, host_id, **kwargs): + return _update_host_config(session, updater, host_id, **kwargs) -@utils.wrap_to_dict(RESP_CONFIG_FIELDS) @utils.supported_filters(PATCHED_CONFIG_FIELDS) -def patch_host_config(updater, host_id, **kwargs): - return _update_host_config(updater, host_id, **kwargs) +@database.run_in_session() +def patch_host_config(session, updater, host_id, **kwargs): + return _update_host_config(session, updater, host_id, **kwargs) +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_HOST_CONFIG +) @utils.wrap_to_dict(RESP_CONFIG_FIELDS) -@utils.supported_filters([]) -def del_host_config(deleter, host_id): +def del_host_config(session, deleter, host_id): """delete a host config.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_HOST_CONFIG) - host = utils.get_db_object( - session, models.Host, id=host_id - ) - is_host_editable(session, host, deleter) - utils.update_db_object( - session, host, os_config={}, config_validated=False - ) - return host.to_dict() + host = utils.get_db_object( + session, models.Host, id=host_id + ) + is_host_editable(session, host, deleter) + return utils.update_db_object( + session, host, os_config={}, config_validated=False + ) -@utils.wrap_to_dict(RESP_NETWORK_FIELDS) @utils.supported_filters( optional_support_keys=SUPPORTED_NETOWORK_FIELDS ) -def list_host_networks(lister, host_id, **filters): - """Get host networks.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_HOST_NETWORKS) - host_networks = utils.list_db_objects( - session, models.HostNetwork, - host_id=host_id, **filters - ) - return [host_network.to_dict() for host_network in host_networks] - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOST_NETWORKS +) @utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def list_host_networks(session, lister, host_id, **filters): + """Get host networks.""" + return utils.list_db_objects( + session, models.HostNetwork, + host_id=host_id, **filters + ) + + @utils.supported_filters( optional_support_keys=SUPPORTED_NETOWORK_FIELDS ) -def list_hostnetworks(lister, **filters): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOST_NETWORKS +) +@utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def list_hostnetworks(session, lister, **filters): """Get host networks.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_HOST_NETWORKS) - host_networks = utils.list_db_objects( - session, models.HostNetwork, **filters - ) - return [host_network.to_dict() for host_network in host_networks] + return utils.list_db_objects( + session, models.HostNetwork, **filters + ) -@utils.wrap_to_dict(RESP_NETWORK_FIELDS) @utils.supported_filters([]) -def get_host_network(getter, host_id, subnet_id, **kwargs): - """Get host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_HOST_NETWORKS) - host_network = utils.get_db_object( - session, models.HostNetwork, - host_id=host_id, subnet_id=subnet_id - ) - return host_network.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOST_NETWORKS +) @utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def get_host_network(session, getter, host_id, subnet_id, **kwargs): + """Get host network.""" + return utils.get_db_object( + session, models.HostNetwork, + host_id=host_id, subnet_id=subnet_id + ) + + @utils.supported_filters([]) -def get_hostnetwork(getter, host_network_id, **kwargs): - """Get host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_HOST_NETWORKS) - host_network = utils.get_db_object( - session, models.HostNetwork, - id=host_network_id - ) - return host_network.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_HOST_NETWORKS +) @utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def get_hostnetwork(session, getter, host_network_id, **kwargs): + """Get host network.""" + return utils.get_db_object( + session, models.HostNetwork, + id=host_network_id + ) + + @utils.supported_filters( ADDED_NETWORK_FIELDS, optional_support_keys=OPTIONAL_ADDED_NETWORK_FIELDS ) -def add_host_network(creator, host_id, **kwargs): - """Create a host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, creator, permission.PERMISSION_ADD_HOST_NETWORK) - host = utils.get_db_object( - session, models.Host, id=host_id - ) - is_host_editable(session, host, creator) - host_network = utils.add_db_object( - session, models.HostNetwork, True, - host_id, **kwargs - ) - return host_network.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_HOST_NETWORK +) @utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def add_host_network(session, creator, host_id, **kwargs): + """Create a host network.""" + host = utils.get_db_object( + session, models.Host, id=host_id + ) + is_host_editable(session, host, creator) + return utils.add_db_object( + session, models.HostNetwork, True, + host_id, **kwargs + ) + + @utils.supported_filters( optional_support_keys=UPDATED_NETWORK_FIELDS ) -def update_host_network(updater, host_id, subnet_id, **kwargs): - """Update a host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_HOST_NETWORK) - host_network = utils.get_db_object( - session, models.HostNetwork, - host_id=host_id, subnet_id=subnet_id - ) - is_host_editable(session, host_network.host, updater) - utils.update_db_object(session, host_network, **kwargs) - return host_network.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_HOST_NETWORK +) @utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def update_host_network(session, updater, host_id, subnet_id, **kwargs): + """Update a host network.""" + host_network = utils.get_db_object( + session, models.HostNetwork, + host_id=host_id, subnet_id=subnet_id + ) + is_host_editable(session, host_network.host, updater) + return utils.update_db_object(session, host_network, **kwargs) + + @utils.supported_filters(UPDATED_NETWORK_FIELDS) -def update_hostnetwork(updater, host_network_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_HOST_NETWORK +) +@utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def update_hostnetwork(session, updater, host_network_id, **kwargs): """Update a host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_HOST_NETWORK) - host_network = utils.get_db_object( - session, models.HostNetwork, id=host_network_id - ) - is_host_editable(session, host_network.host, updater) - utils.update_db_object(session, host_network, **kwargs) - return host_network.to_dict() + host_network = utils.get_db_object( + session, models.HostNetwork, id=host_network_id + ) + is_host_editable(session, host_network.host, updater) + return utils.update_db_object(session, host_network, **kwargs) -@utils.wrap_to_dict(RESP_NETWORK_FIELDS) @utils.supported_filters([]) -def del_host_network(deleter, host_id, subnet_id, **kwargs): - """Delete a host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_HOST_NETWORK) - host_network = utils.get_db_object( - session, models.HostNetwork, - host_id=host_id, subnet_id=subnet_id - ) - is_host_editable(session, host_network.host, deleter) - utils.del_db_object(session, host_network) - return host_network.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_HOST_NETWORK +) @utils.wrap_to_dict(RESP_NETWORK_FIELDS) -@utils.supported_filters([]) -def del_hostnetwork(deleter, host_network_id, **kwargs): +def del_host_network(session, deleter, host_id, subnet_id, **kwargs): """Delete a host network.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_HOST_NETWORK) - host_network = utils.get_db_object( - session, models.HostNetwork, id=host_network_id - ) - is_host_editable(session, host_network.host, deleter) - utils.del_db_object(session, host_network) - return host_network.to_dict() + host_network = utils.get_db_object( + session, models.HostNetwork, + host_id=host_id, subnet_id=subnet_id + ) + is_host_editable(session, host_network.host, deleter) + return utils.del_db_object(session, host_network) +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_HOST_NETWORK +) +@utils.wrap_to_dict(RESP_NETWORK_FIELDS) +def del_hostnetwork(session, deleter, host_network_id, **kwargs): + """Delete a host network.""" + host_network = utils.get_db_object( + session, models.HostNetwork, id=host_network_id + ) + is_host_editable(session, host_network.host, deleter) + return utils.del_db_object(session, host_network) + + +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_GET_HOST_STATE +) @utils.wrap_to_dict(RESP_STATE_FIELDS) -@utils.supported_filters([]) -def get_host_state(getter, host_id, **kwargs): +def get_host_state(session, getter, host_id, **kwargs): """Get host state info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_GET_HOST_STATE) - return utils.get_db_object( - session, models.Host, id=host_id - ).state_dict() + return utils.get_db_object( + session, models.Host, id=host_id + ).state_dict() -@utils.wrap_to_dict(RESP_STATE_FIELDS) @utils.supported_filters(UPDATED_STATE_FIELDS) -def update_host_state(updater, host_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_HOST_STATE +) +@utils.wrap_to_dict(RESP_STATE_FIELDS) +def update_host_state(session, updater, host_id, **kwargs): """Update a host state.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_UPDATE_HOST_STATE) - host = utils.get_db_object( - session, models.Host, id=host_id - ) - utils.update_db_object(session, host.state, **kwargs) - return host.state_dict() + host = utils.get_db_object( + session, models.Host, id=host_id + ) + utils.update_db_object(session, host.state, **kwargs) + return host.state_dict() diff --git a/compass/db/api/installer.py b/compass/db/api/installer.py index a81dbd1b..ae1b435d 100644 --- a/compass/db/api/installer.py +++ b/compass/db/api/installer.py @@ -39,11 +39,9 @@ def _add_installers(session, model, configs): def add_os_installers_internal(session): configs = util.load_configs(setting.OS_INSTALLER_DIR) - with session.begin(subtransactions=True): - return _add_installers(session, models.OSInstaller, configs) + return _add_installers(session, models.OSInstaller, configs) def add_package_installers_internal(session): configs = util.load_configs(setting.PACKAGE_INSTALLER_DIR) - with session.begin(subtransactions=True): - return _add_installers(session, models.PackageInstaller, configs) + return _add_installers(session, models.PackageInstaller, configs) diff --git a/compass/db/api/machine.py b/compass/db/api/machine.py index 3b54a66d..9220e532 100644 --- a/compass/db/api/machine.py +++ b/compass/db/api/machine.py @@ -66,8 +66,8 @@ def _check_ipmi_credentials(ipmi_credentials): ) check_ipmi_credential_field = '_check_ipmi_credentials_%s' % key this_module = globals() - if hasattr(this_module, check_ipmi_credential_field): - getattr(this_module, check_ipmi_credential_field)( + if check_ipmi_credential_field in this_module: + this_module[check_ipmi_credential_field]( ipmi_credentials[key] ) else: @@ -76,80 +76,73 @@ def _check_ipmi_credentials(ipmi_credentials): ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters([]) -def get_machine(getter, machine_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_MACHINES +) +@utils.wrap_to_dict(RESP_FIELDS) +def get_machine(session, getter, machine_id, **kwargs): """get field dict of a machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_MACHINES) - return utils.get_db_object( - session, models.Machine, True, id=machine_id - ).to_dict() + return utils.get_db_object( + session, models.Machine, True, id=machine_id + ) +@utils.supported_filters( + optional_support_keys=SUPPORTED_FIELDS +) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_MACHINES +) @utils.output_filters( tag=utils.general_filter_callback, location=utils.general_filter_callback ) @utils.wrap_to_dict(RESP_FIELDS) -@utils.supported_filters( - optional_support_keys=SUPPORTED_FIELDS -) -def list_machines(lister, **filters): +def list_machines(session, lister, **filters): """List machines.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_MACHINES) - return [ - machine.to_dict() - for machine in utils.list_db_objects( - session, models.Machine, **filters - ) - ] + return utils.list_db_objects( + session, models.Machine, **filters + ) -def _update_machine(updater, machine_id, **kwargs): +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_MACHINE +) +@utils.wrap_to_dict(RESP_FIELDS) +def _update_machine(session, updater, machine_id, **kwargs): """Update a machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_MACHINE) - machine = utils.get_db_object(session, models.Machine, id=machine_id) - utils.update_db_object(session, machine, **kwargs) - machine_dict = machine.to_dict() - utils.validate_outputs( - {'ipmi_credentials': _check_ipmi_credentials}, - machine_dict - ) - return machine_dict + machine = utils.get_db_object(session, models.Machine, id=machine_id) + return utils.update_db_object(session, machine, **kwargs) -@utils.wrap_to_dict(RESP_FIELDS) -@utils.input_validates(ipmi_credentials=_check_ipmi_credentials) @utils.supported_filters(optional_support_keys=UPDATED_FIELDS) -def update_machine(updater, machine_id, **kwargs): +@utils.input_validates(ipmi_credentials=_check_ipmi_credentials) +@database.run_in_session() +def update_machine(session, updater, machine_id, **kwargs): return _update_machine( - updater, machine_id, - **kwargs + session, updater, machine_id, **kwargs ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=PATCHED_FIELDS) -def patch_machine(updater, machine_id, **kwargs): +@database.run_in_session() +@utils.output_validates(ipmi_credentials=_check_ipmi_credentials) +def patch_machine(session, updater, machine_id, **kwargs): return _update_machine( - updater, machine_id, - **kwargs + session, updater, machine_id, **kwargs ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters() -def del_machine(deleter, machine_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_MACHINE +) +@utils.wrap_to_dict(RESP_FIELDS) +def del_machine(session, deleter, machine_id, **kwargs): """Delete a machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_MACHINE) - machine = utils.get_db_object(session, models.Switch, id=machine_id) - utils.del_db_object(session, machine) - return machine.to_dict() + machine = utils.get_db_object(session, models.Switch, id=machine_id) + return utils.del_db_object(session, machine) diff --git a/compass/db/api/metadata.py b/compass/db/api/metadata.py index ce0ae696..2ba31fb7 100644 --- a/compass/db/api/metadata.py +++ b/compass/db/api/metadata.py @@ -67,7 +67,6 @@ def _add_metadata( parent=None, adapter=None ): metadata = config.get('_self', {}) - print 'add metadata %s to adapter %s' % (metadata, adapter) if 'field' in metadata: field = utils.get_db_object( session, field_model, field=metadata['field'] diff --git a/compass/db/api/metadata_holder.py b/compass/db/api/metadata_holder.py index f411329d..a3f14398 100644 --- a/compass/db/api/metadata_holder.py +++ b/compass/db/api/metadata_holder.py @@ -23,12 +23,14 @@ from compass.db.api import utils from compass.db import exception -def load_metadatas(): - with database.session() as session: - return metadata_api.get_metadatas_internal(session) +@database.run_in_session() +def load_metadatas(session): + global METADATA_MAPPING + logging.info('load metadatas into memory') + METADATA_MAPPING = metadata_api.get_metadatas_internal(session) -METADATA_MAPPING = load_metadatas() +METADATA_MAPPING = {} def _validate_config( @@ -84,13 +86,14 @@ def _filter_metadata(metadata): @utils.supported_filters([]) -def get_metadata(getter, adapter_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_METADATAS +) +def get_metadata(session, getter, adapter_id, **kwargs): """get adapter.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_METADATAS) - if adapter_id not in METADATA_MAPPING: - raise exception.RecordNotExists( - 'adpater %s does not exist' % adapter_id - ) - return _filter_metadata(METADATA_MAPPING[adapter_id]) + if adapter_id not in METADATA_MAPPING: + raise exception.RecordNotExists( + 'adpater %s does not exist' % adapter_id + ) + return _filter_metadata(METADATA_MAPPING[adapter_id]) diff --git a/compass/db/api/network.py b/compass/db/api/network.py index 9fdd1062..d7033156 100644 --- a/compass/db/api/network.py +++ b/compass/db/api/network.py @@ -39,73 +39,70 @@ def _check_subnet(subnet): 'subnet %s format unrecognized' % subnet) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_subnets(lister, **filters): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_NETWORKS +) +@utils.wrap_to_dict(RESP_FIELDS) +def list_subnets(session, lister, **filters): """List subnets.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_NETWORKS) - return [ - network.to_dict() - for network in utils.list_db_objects( - session, models.Network, **filters - ) - ] + return utils.list_db_objects( + session, models.Network, **filters + ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters([]) -def get_subnet(getter, subnet_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_NETWORKS +) +@utils.wrap_to_dict(RESP_FIELDS) +def get_subnet(session, getter, subnet_id, **kwargs): """Get subnet info.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_NETWORKS) - return utils.get_db_object( - session, models.Network, id=subnet_id - ).to_dict() + return utils.get_db_object( + session, models.Network, id=subnet_id + ) -@utils.wrap_to_dict(RESP_FIELDS) -@utils.input_validates(subnet=_check_subnet) @utils.supported_filters(ADDED_FIELDS) -def add_subnet(creator, subnet, **kwargs): - """Create a subnet.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, creator, permission.PERMISSION_ADD_NETWORK) - network = utils.add_db_object( - session, models.Network, True, subnet - ) - network_dict = network.to_dict() - print 'network: %s' % network_dict - return network_dict - - -@utils.wrap_to_dict(RESP_FIELDS) @utils.input_validates(subnet=_check_subnet) -@utils.supported_filters(UPDATED_FIELDS) -def update_subnet(updater, subnet_id, **kwargs): - """Update a subnet.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_NETWORK) - network = utils.get_db_object( - session, models.Network, id=subnet_id - ) - utils.update_db_object(session, network, **kwargs) - return network.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_NETWORK +) @utils.wrap_to_dict(RESP_FIELDS) +def add_subnet(session, creator, subnet, **kwargs): + """Create a subnet.""" + return utils.add_db_object( + session, models.Network, True, subnet + ) + + +@utils.supported_filters(UPDATED_FIELDS) +@utils.input_validates(subnet=_check_subnet) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_NETWORK +) +@utils.wrap_to_dict(RESP_FIELDS) +def update_subnet(session, updater, subnet_id, **kwargs): + """Update a subnet.""" + network = utils.get_db_object( + session, models.Network, id=subnet_id + ) + return utils.update_db_object(session, network, **kwargs) + + @utils.supported_filters([]) -def del_subnet(deleter, subnet_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_NETWORK +) +@utils.wrap_to_dict(RESP_FIELDS) +def del_subnet(session, deleter, subnet_id, **kwargs): """Delete a subnet.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_NETWORK) - network = utils.get_db_object( - session, models.Network, id=subnet_id - ) - utils.del_db_object(session, network) - return network.to_dict() + network = utils.get_db_object( + session, models.Network, id=subnet_id + ) + return utils.del_db_object(session, network) diff --git a/compass/db/api/permission.py b/compass/db/api/permission.py index e7ada8cf..baaac6ef 100644 --- a/compass/db/api/permission.py +++ b/compass/db/api/permission.py @@ -14,6 +14,7 @@ """Permission database operations.""" from compass.db.api import database +from compass.db.api import user as user_api from compass.db.api import utils from compass.db import exception from compass.db import models @@ -43,9 +44,19 @@ PERMISSION_LIST_PERMISSIONS = PermissionWrapper( PERMISSION_LIST_SWITCHES = PermissionWrapper( 'list_switches', 'list switches', 'list all switches' ) +PERMISSION_LIST_SWITCH_FILTERS = PermissionWrapper( + 'list_switch_filters', + 'list switch filters', + 'list switch filters' +) PERMISSION_ADD_SWITCH = PermissionWrapper( 'add_switch', 'add switch', 'add switch' ) +PERMISSION_UPDATE_SWITCH_FILTERS = PermissionWrapper( + 'update_switch_filters', + 'update switch filters', + 'update switch filters' +) PERMISSION_DEL_SWITCH = PermissionWrapper( 'delete_switch', 'delete switch', 'delete switch' ) @@ -195,6 +206,8 @@ PERMISSIONS = [ PERMISSION_LIST_SWITCHES, PERMISSION_ADD_SWITCH, PERMISSION_DEL_SWITCH, + PERMISSION_LIST_SWITCH_FILTERS, + PERMISSION_UPDATE_SWITCH_FILTERS, PERMISSION_LIST_SWITCH_MACHINES, PERMISSION_ADD_SWITCH_MACHINE, PERMISSION_DEL_SWITCH_MACHINE, @@ -244,51 +257,40 @@ def list_permissions_internal(session, **filters): return utils.list_db_objects(session, models.Permission, **filters) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_permissions(lister, **filters): - """list permissions.""" - from compass.db.api import user as user_api - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, PERMISSION_LIST_PERMISSIONS - ) - return [ - permission.to_dict() - for permission in utils.list_db_objects( - session, models.Permission, **filters - ) - ] - - +@database.run_in_session() +@user_api.check_user_permission_in_session(PERMISSION_LIST_PERMISSIONS) @utils.wrap_to_dict(RESP_FIELDS) +def list_permissions(session, lister, **filters): + """list permissions.""" + return utils.list_db_objects( + session, models.Permission, **filters + ) + + @utils.supported_filters() -def get_permission(getter, permission_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session(PERMISSION_LIST_PERMISSIONS) +@utils.wrap_to_dict(RESP_FIELDS) +def get_permission(session, getter, permission_id, **kwargs): """get permissions.""" - from compass.db.api import user as user_api - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, PERMISSION_LIST_PERMISSIONS - ) - permission = utils.get_db_object( - session, models.Permission, id=permission_id - ) - return permission.to_dict() + return utils.get_db_object( + session, models.Permission, id=permission_id + ) def add_permissions_internal(session): """internal functions used by other db.api modules only.""" permissions = [] - with session.begin(subtransactions=True): - for permission in PERMISSIONS: - permissions.append( - utils.add_db_object( - session, models.Permission, - True, - permission.name, - alias=permission.alias, - description=permission.description - ) + for permission in PERMISSIONS: + permissions.append( + utils.add_db_object( + session, models.Permission, + True, + permission.name, + alias=permission.alias, + description=permission.description ) + ) return permissions diff --git a/compass/db/api/switch.py b/compass/db/api/switch.py index 12502dd9..95f4ee7b 100644 --- a/compass/db/api/switch.py +++ b/compass/db/api/switch.py @@ -170,156 +170,149 @@ def get_switch_internal( ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters([]) -def get_switch(getter, switch_id, **kwargs): - """get field dict of a switch.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_SWITCHES) - return utils.get_db_object( - session, models.Switch, id=switch_id - ).to_dict() - - -@utils.wrap_to_dict(RESP_FIELDS) -@utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_switches(lister, **filters): - """List switches.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_SWITCHES) - return [ - switch.to_dict() - for switch in utils.list_db_objects( - session, models.Switch, **filters - ) - ] - - -@utils.wrap_to_dict(RESP_FIELDS) -@utils.supported_filters([]) -def del_switch(deleter, switch_id, **kwargs): - """Delete a switch.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_SWITCH) - switch = utils.get_db_object(session, models.Switch, id=switch_id) - utils.del_db_object(session, switch) - return switch.to_dict() - - -@utils.wrap_to_dict(RESP_FIELDS) -@utils.input_validates( - ip=utils.check_ip, - credentials=_check_credentials +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCHES ) +@utils.wrap_to_dict(RESP_FIELDS) +def get_switch(session, getter, switch_id, **kwargs): + """get field dict of a switch.""" + return utils.get_db_object( + session, models.Switch, id=switch_id + ) + + +@utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCHES +) +@utils.wrap_to_dict(RESP_FIELDS) +def list_switches(session, lister, **filters): + """List switches.""" + return utils.list_db_objects( + session, models.Switch, **filters + ) + + +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_SWITCH +) +@utils.wrap_to_dict(RESP_FIELDS) +def del_switch(session, deleter, switch_id, **kwargs): + """Delete a switch.""" + switch = utils.get_db_object(session, models.Switch, id=switch_id) + return utils.del_db_object(session, switch) + + @utils.supported_filters( ADDED_FIELDS, optional_support_keys=OPTIONAL_ADDED_FIELDS ) -def add_switch(creator, ip, **kwargs): +@utils.input_validates( + ip=utils.check_ip, + credentials=_check_credentials +) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH +) +@utils.wrap_to_dict(RESP_FIELDS) +def add_switch(session, creator, ip, **kwargs): """Create a switch.""" ip_int = long(netaddr.IPAddress(ip)) - with database.session() as session: - user_api.check_user_permission_internal( - session, creator, permission.PERMISSION_ADD_SWITCH) - return add_switch_internal( - session, ip_int, **kwargs - ).to_dict() + return add_switch_internal( + session, ip_int, **kwargs + ) def update_switch_internal(session, switch, **kwargs): """update switch.""" - with session.begin(subtransactions=True): - return utils.update_db_object( - session, switch, - **kwargs - ) - - -def _update_switch(updater, switch_id, **kwargs): - """Update a switch.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH) - switch = utils.get_db_object( - session, models.Switch, id=switch_id - ) - utils.update_db_object(session, switch, **kwargs) - switch_dict = switch.to_dict() - utils.validate_outputs( - {'credentials': _check_credentials}, - switch_dict - ) - return switch_dict + return utils.update_db_object( + session, switch, + **kwargs + ) +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH +) @utils.wrap_to_dict(RESP_FIELDS) -@utils.input_validates(credentials=_check_credentials) +def _update_switch(session, updater, switch_id, **kwargs): + """Update a switch.""" + switch = utils.get_db_object( + session, models.Switch, id=switch_id + ) + return utils.update_db_object(session, switch, **kwargs) + + @utils.supported_filters(optional_support_keys=UPDATED_FIELDS) -def update_switch(updater, switch_id, **kwargs): - _update_switch(updater, switch_id, **kwargs) +@utils.input_validates(credentials=_check_credentials) +@database.run_in_session() +def update_switch(session, updater, switch_id, **kwargs): + return _update_switch(session, updater, switch_id, **kwargs) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=PATCHED_FIELDS) -def patch_switch(updater, switch_id, **kwargs): - _update_switch(updater, switch_id, **kwargs) +@database.run_in_session() +@utils.output_validates(credentials=_check_credentials) +def patch_switch(session, updater, switch_id, **kwargs): + return _update_switch(session, updater, switch_id, **kwargs) -@utils.wrap_to_dict(RESP_FILTERS_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_FILTER_FIELDS) -def list_switch_filters(lister, **filters): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCH_FILTERS +) +@utils.wrap_to_dict(RESP_FILTERS_FIELDS) +def list_switch_filters(session, lister, **filters): """list switch filters.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_SWITCHES - ) - return [ - switch.to_dict() - for switch in utils.list_db_objects( - session, models.Switch, **filters - ) - ] + return utils.list_db_objects( + session, models.Switch, **filters + ) -@utils.wrap_to_dict(RESP_FILTERS_FIELDS) @utils.supported_filters() -def get_switch_filters(getter, switch_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCH_FILTERS +) +@utils.wrap_to_dict(RESP_FILTERS_FIELDS) +def get_switch_filters(session, getter, switch_id, **kwargs): """get switch filter.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_SWITCHES) - return utils.get_db_object( - session, models.Switch, id=switch_id - ).to_dict() + return utils.get_db_object( + session, models.Switch, id=switch_id + ) -@utils.wrap_to_dict(RESP_FILTERS_FIELDS) -@utils.input_validates(filters=_check_filter) @utils.supported_filters(optional_support_keys=UPDATED_FILTERS_FIELDS) -def update_switch_filters(updater, switch_id, **kwargs): - """Update a switch filter.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH) - switch = utils.get_db_object(session, models.Switch, id=switch_id) - utils.update_db_object(session, switch, **kwargs) - return switch.to_dict() - - +@utils.input_validates(filters=_check_filter) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_SWITCH_FILTERS +) @utils.wrap_to_dict(RESP_FILTERS_FIELDS) -@utils.input_validates(patched_filters=_check_filter) +def update_switch_filters(session, updater, switch_id, **kwargs): + """Update a switch filter.""" + switch = utils.get_db_object(session, models.Switch, id=switch_id) + return utils.update_db_object(session, switch, **kwargs) + + @utils.supported_filters(optional_support_keys=PATCHED_FILTERS_FIELDS) -def patch_switch_filter(updater, switch_id, **kwargs): - """Update a switch.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH) - switch = utils.get_db_object(session, models.Switch, id=switch_id) - utils.update_db_object(session, switch, **kwargs) - return switch.to_dict() +@utils.input_validates(patched_filters=_check_filter) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_SWITCH_FILTERS +) +@utils.wrap_to_dict(RESP_FILTERS_FIELDS) +def patch_switch_filter(session, updater, switch_id, **kwargs): + """Patch a switch filter.""" + switch = utils.get_db_object(session, models.Switch, id=switch_id) + return utils.update_db_object(session, switch, **kwargs) def filter_machine_internal(filters, port): @@ -415,155 +408,149 @@ def _filter_vlans(vlan_filter, obj): return True +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCH_MACHINES +) @utils.output_filters(port=_filter_port, vlans=_filter_vlans) @utils.wrap_to_dict(RESP_MACHINES_FIELDS) -@utils.supported_filters(optional_support_keys=SUPPORTED_MACHINES_FIELDS) -def list_switch_machines(getter, switch_id, **filters): - """Get switch machines.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_SWITCH_MACHINES) - switch_machines = get_switch_machines_internal( - session, switch_id=switch_id, **filters +def _list_switch_machines(session, user, switch_machines): + return [ + switch_machine for switch_machine in switch_machines + if filter_machine_internal( + switch_machine.switch.filters, + switch_machine.port ) - return [ - switch_machine.to_dict() for switch_machine in switch_machines - if filter_machine_internal( - switch_machine.switch.filters, - switch_machine.port - ) - ] + ] + + +@utils.supported_filters(optional_support_keys=SUPPORTED_MACHINES_FIELDS) +@database.run_in_session() +def list_switch_machines(session, getter, switch_id, **filters): + """Get switch machines.""" + switch_machines = get_switch_machines_internal( + session, switch_id=switch_id, **filters + ) + return _list_switch_machines(session, getter, switch_machines) -@utils.output_filters(port=_filter_port, vlans=_filter_vlans) -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) @utils.supported_filters( optional_support_keys=SUPPORTED_SWITCH_MACHINES_FIELDS ) -def list_switchmachines(lister, **filters): +@database.run_in_session() +def list_switchmachines(session, lister, **filters): """List switch machines.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, lister, permission.PERMISSION_LIST_SWITCH_MACHINES) - switch_machines = [ - switch_machine - for switch_machine in get_switch_machines_internal( - session, **filters - ) - if filter_machine_internal( - switch_machine.switch.filters, switch_machine.port - ) - ] - return [ - switch_machine.to_dict() - for switch_machine in switch_machines - ] + switch_machines = get_switch_machines_internal( + session, **filters + ) + return _list_switch_machines(session, lister, switch_machines) def add_switch_machines_internal( session, switch, machine_dicts, exception_when_switch_machine_existing=True ): - with session.begin(subtransactions=True): - machine_id_switch_machine_dict = {} - for mac, all_dict in machine_dicts.items(): - switch_machine_dict = {} - machine_dict = {} - for key, value in all_dict.items(): - if key in ALL_ADDED_MACHINES_FIELDS: - switch_machine_dict[key] = value - else: - machine_dict[key] = value - #TODO(xiaodong): add ipmi field checks' - machine = utils.add_db_object( - session, models.Machine, False, - mac, **machine_dict) - machine_id_switch_machine_dict[machine.id] = switch_machine_dict + machine_id_switch_machine_dict = {} + for mac, all_dict in machine_dicts.items(): + switch_machine_dict = {} + machine_dict = {} + for key, value in all_dict.items(): + if key in ALL_ADDED_MACHINES_FIELDS: + switch_machine_dict[key] = value + else: + machine_dict[key] = value + #TODO(xiaodong): add ipmi field checks' + machine = utils.add_db_object( + session, models.Machine, False, + mac, **machine_dict) + machine_id_switch_machine_dict[machine.id] = switch_machine_dict - switches = [switch] - if switch.ip != setting.DEFAULT_SWITCH_IP: - switches.append(utils.get_db_object( - session, models.Switch, - ip_int=long(netaddr.IPAddress(setting.DEFAULT_SWITCH_IP)) - )) + switches = [switch] + if switch.ip != setting.DEFAULT_SWITCH_IP: + switches.append(utils.get_db_object( + session, models.Switch, + ip_int=long(netaddr.IPAddress(setting.DEFAULT_SWITCH_IP)) + )) - switch_machines = [] - for machine_switch in switches: - for machine_id, switch_machine_dict in ( - machine_id_switch_machine_dict.items() - ): - utils.add_db_object( - session, models.SwitchMachine, - exception_when_switch_machine_existing, - machine_switch.id, machine_id, **switch_machine_dict - ) - switch_machines.extend(machine_switch.switch_machines) + switch_machines = [] + for machine_switch in switches: + for machine_id, switch_machine_dict in ( + machine_id_switch_machine_dict.items() + ): + utils.add_db_object( + session, models.SwitchMachine, + exception_when_switch_machine_existing, + machine_switch.id, machine_id, **switch_machine_dict + ) + switch_machines.extend(machine_switch.switch_machines) - return switch_machines + return switch_machines -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) -@utils.input_validates(mac=utils.check_mac, vlans=_check_vlan) @utils.supported_filters( ADDED_MACHINES_FIELDS, optional_support_keys=OPTIONAL_ADDED_MACHINES_FIELDS ) -def add_switch_machine(creator, switch_id, mac, port, **kwargs): +@utils.input_validates(mac=utils.check_mac, vlans=_check_vlan) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH_MACHINE +) +@utils.wrap_to_dict(RESP_MACHINES_FIELDS) +def add_switch_machine(session, creator, switch_id, mac, **kwargs): """Add switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, creator, permission.PERMISSION_ADD_SWITCH_MACHINE) - switch = utils.get_db_object( - session, models.Switch, id=switch_id) - kwargs['port'] = port - switch_machines = add_switch_machines_internal( - session, switch, {mac: kwargs}) - return switch_machines[0].to_dict() + switch = utils.get_db_object( + session, models.Switch, id=switch_id) + switch_machines = add_switch_machines_internal( + session, switch, {mac: kwargs}) + return switch_machines[0] -@utils.wrap_to_dict(RESP_ACTION_FIELDS) @utils.supported_filters() -def poll_switch_machines(poller, switch_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_SWITCH_MACHINES +) +@utils.wrap_to_dict(RESP_ACTION_FIELDS) +def poll_switch_machines(session, poller, switch_id, **kwargs): """poll switch machines.""" from compass.tasks import client as celery_client - with database.session() as session: - user_api.check_user_permission_internal( - session, poller, permission.PERMISSION_UPDATE_SWITCH_MACHINES) - switch = utils.get_db_object(session, models.Switch, id=switch_id) - celery_client.celery.send_task( - 'compass.tasks.pollswitch', - (switch.ip, switch.credentials) - ) - return { - 'status': 'find_machines action sent', - 'details': { - } + switch = utils.get_db_object(session, models.Switch, id=switch_id) + celery_client.celery.send_task( + 'compass.tasks.pollswitch', + (switch.ip, switch.credentials) + ) + return { + 'status': 'find_machines action sent', + 'details': { } + } -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) @utils.supported_filters([]) -def get_switch_machine(getter, switch_id, machine_id, **kwargs): - """get field dict of a switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_SWITCH_MACHINES) - return utils.get_db_object( - session, models.SwitchMachine, - switch_id=switch_id, machine_id=machine_id - ).to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCH_MACHINES +) @utils.wrap_to_dict(RESP_MACHINES_FIELDS) -@utils.supported_filters([]) -def get_switchmachine(getter, switch_machine_id, **kwargs): +def get_switch_machine(session, getter, switch_id, machine_id, **kwargs): """get field dict of a switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, getter, permission.PERMISSION_LIST_SWITCH_MACHINES) - return utils.get_db_object( - session, models.SwitchMachine, id=switch_machine_id - ).to_dict() + return utils.get_db_object( + session, models.SwitchMachine, + switch_id=switch_id, machine_id=machine_id + ) + + +@utils.supported_filters([]) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_LIST_SWITCH_MACHINES +) +@utils.wrap_to_dict(RESP_MACHINES_FIELDS) +def get_switchmachine(session, getter, switch_machine_id, **kwargs): + """get field dict of a switch machine.""" + return utils.get_db_object( + session, models.SwitchMachine, id=switch_machine_id + ) def update_switch_machine_internal( @@ -577,131 +564,127 @@ def update_switch_machine_internal( switch_machine_dict[key] = value else: machine_dict[key] = value - with session.begin(subtransactions=True): + if machine_dict: utils.update_db_object( - session, switch_machine, **switch_machine_dict + session, switch_machine.machine, **machine_dict ) - if machine_dict: - utils.update_db_object( - session, switch_machine.machine, **machine_dict - ) + return utils.update_db_object( + session, switch_machine, **switch_machine_dict + ) -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) -@utils.input_validates(vlans=_check_vlan) @utils.supported_filters(optional_support_keys=UPDATED_MACHINES_FIELDS) -def update_switch_machine(updater, switch_id, machine_id, **kwargs): - """Update switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH_MACHINE) - switch_machine = utils.get_db_object( - session, models.SwitchMachine, - switch_id=switch_id, machine_id=machine_id - ) - update_switch_machine_internal( - session, switch_machine, - UPDATED_SWITCH_MACHINES_FIELDS, **kwargs - ) - return switch_machine.to_dict() - - -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) @utils.input_validates(vlans=_check_vlan) -@utils.supported_filters(optional_support_keys=UPDATED_MACHINES_FIELDS) -def update_switchmachine(updater, switch_machine_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH_MACHINE +) +@utils.wrap_to_dict(RESP_MACHINES_FIELDS) +def update_switch_machine(session, updater, switch_id, machine_id, **kwargs): """Update switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH_MACHINE) - switch_machine = utils.get_db_object( - session, models.SwitchMachine, - id=switch_machine_id - ) - update_switch_machine_internal( - session, switch_machine, - UPDATED_SWITCH_MACHINES_FIELDS, **kwargs - ) - return switch_machine.to_dict() + switch_machine = utils.get_db_object( + session, models.SwitchMachine, + switch_id=switch_id, machine_id=machine_id + ) + return update_switch_machine_internal( + session, switch_machine, + UPDATED_SWITCH_MACHINES_FIELDS, **kwargs + ) +@utils.supported_filters(optional_support_keys=UPDATED_MACHINES_FIELDS) +@utils.input_validates(vlans=_check_vlan) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH_MACHINE +) @utils.wrap_to_dict(RESP_MACHINES_FIELDS) -@utils.input_validates(patched_vlans=_check_vlan) +def update_switchmachine(session, updater, switch_machine_id, **kwargs): + """Update switch machine.""" + switch_machine = utils.get_db_object( + session, models.SwitchMachine, + id=switch_machine_id + ) + return update_switch_machine_internal( + session, switch_machine, + UPDATED_SWITCH_MACHINES_FIELDS, **kwargs + ) + + @utils.supported_filters(optional_support_keys=PATCHED_MACHINES_FIELDS) -def patch_switch_machine(updater, switch_id, machine_id, **kwargs): - """Patch switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH_MACHINE) - switch_machine = utils.get_db_object( - session, models.SwitchMachine, - switch_id=switch_id, machine_id=machine_id - ) - update_switch_machine_internal( - session, switch_machine, - PATCHED_SWITCH_MACHINES_FIELDS, **kwargs - ) - return switch_machine.to_dict() - - -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) @utils.input_validates(patched_vlans=_check_vlan) -@utils.supported_filters(optional_support_keys=PATCHED_MACHINES_FIELDS) -def patch_switchmachine(updater, switch_machine_id, **kwargs): +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH_MACHINE +) +@utils.wrap_to_dict(RESP_MACHINES_FIELDS) +def patch_switch_machine(session, updater, switch_id, machine_id, **kwargs): """Patch switch machine.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_ADD_SWITCH_MACHINE) - switch_machine = utils.get_db_object( - session, models.SwitchMachine, - id=switch_machine_id - ) - update_switch_machine_internal( - session, switch_machine, - PATCHED_SWITCH_MACHINES_FIELDS, **kwargs - ) - return switch_machine.to_dict() + switch_machine = utils.get_db_object( + session, models.SwitchMachine, + switch_id=switch_id, machine_id=machine_id + ) + return update_switch_machine_internal( + session, switch_machine, + PATCHED_SWITCH_MACHINES_FIELDS, **kwargs + ) +@utils.supported_filters(optional_support_keys=PATCHED_MACHINES_FIELDS) +@utils.input_validates(patched_vlans=_check_vlan) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_ADD_SWITCH_MACHINE +) @utils.wrap_to_dict(RESP_MACHINES_FIELDS) +def patch_switchmachine(session, updater, switch_machine_id, **kwargs): + """Patch switch machine.""" + switch_machine = utils.get_db_object( + session, models.SwitchMachine, + id=switch_machine_id + ) + return update_switch_machine_internal( + session, switch_machine, + PATCHED_SWITCH_MACHINES_FIELDS, **kwargs + ) + + @utils.supported_filters() -def del_switch_machine(deleter, switch_id, machine_id, **kwargs): - """Delete switch machines.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_SWITCH_MACHINE - ) - switch_machine = utils.get_db_object( - session, models.SwitchMachine, - switch_id=switch_id, machine_id=machine_id - ) - utils.del_db_object(session, switch_machine) - return switch_machine.to_dict() - - +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_SWITCH_MACHINE +) @utils.wrap_to_dict(RESP_MACHINES_FIELDS) -@utils.supported_filters() -def del_switchmachine(deleter, switch_machine_id, **kwargs): +def del_switch_machine(session, deleter, switch_id, machine_id, **kwargs): """Delete switch machines.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, deleter, permission.PERMISSION_DEL_SWITCH_MACHINE - ) - switch_machine = utils.get_db_object( - session, models.SwitchMachine, - id=switch_machine_id - ) - utils.del_db_object(session, switch_machine) - return switch_machine.to_dict() + switch_machine = utils.get_db_object( + session, models.SwitchMachine, + switch_id=switch_id, machine_id=machine_id + ) + return utils.del_db_object(session, switch_machine) + + +@utils.supported_filters() +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_DEL_SWITCH_MACHINE +) +@utils.wrap_to_dict(RESP_MACHINES_FIELDS) +def del_switchmachine(session, deleter, switch_machine_id, **kwargs): + """Delete switch machines.""" + switch_machine = utils.get_db_object( + session, models.SwitchMachine, + id=switch_machine_id + ) + return utils.del_db_object(session, switch_machine) @utils.supported_filters(optional_support_keys=UPDATED_SWITCH_MACHINES_FIELDS) def _update_machine_internal(session, switch_id, machine_id, **kwargs): - with session.begin(subtransactions=True): - utils.add_db_object( - session, models.SwitchMachine, False, switch_id, machine_id, - **kwargs - ) + utils.add_db_object( + session, models.SwitchMachine, False, switch_id, machine_id, + **kwargs + ) def _add_machines(session, switch, machines): @@ -712,60 +695,53 @@ def _add_machines(session, switch, machines): def _remove_machines(session, switch, machines): - with session.begin(subtransactions=True): - utils.del_db_objects( - session, models.SwitchMachine, - switch_id=switch.id, machine_id=machines - ) + utils.del_db_objects( + session, models.SwitchMachine, + switch_id=switch.id, machine_id=machines + ) def _set_machines(session, switch, machines): - with session.begin(subtransactions=True): - utils.del_db_objects( - session, models.SwitchMachine, - switch_id=switch.id - ) + utils.del_db_objects( + session, models.SwitchMachine, + switch_id=switch.id + ) for machine_id, switch_machine_attrs in machines.items(): _update_machine_internal( session, switch.id, machine_id, **switch_machine_attrs ) -@utils.wrap_to_dict(RESP_MACHINES_FIELDS) @utils.supported_filters( optional_support_keys=[ 'add_machines', 'remove_machines', 'set_machines' ] ) +@database.run_in_session() +@user_api.check_user_permission_in_session( + permission.PERMISSION_UPDATE_SWITCH_MACHINES +) +@utils.wrap_to_dict(RESP_MACHINES_FIELDS) def update_switch_machines( - updater, switch_id, + session, updater, switch_id, add_machines=[], remove_machines=[], set_machines=None, **kwargs ): """update switch machines.""" - with database.session() as session: - user_api.check_user_permission_internal( - session, updater, permission.PERMISSION_UPDATE_SWITCH_MACHINES) - switch = utils.get_db_object( - session, models.Switch, id=switch_id + switch = utils.get_db_object( + session, models.Switch, id=switch_id + ) + if remove_machines: + _remove_machines( + session, switch, remove_machines ) - if remove_machines: - _remove_machines( - session, switch, remove_machines - ) - - if add_machines: - _add_machines( - session, switch, add_machines - ) - - if set_machines is not None: - _set_machines( - session, switch, - set_machines - ) - - return [ - switch_machine.to_dict() - for switch_machine in switch.switch_machines - ] + if add_machines: + _add_machines( + session, switch, add_machines + ) + if set_machines is not None: + _set_machines( + session, switch, + set_machines + ) + return switch.switch_machines diff --git a/compass/db/api/user.py b/compass/db/api/user.py index b2c0a5c2..62e42b2c 100644 --- a/compass/db/api/user.py +++ b/compass/db/api/user.py @@ -14,11 +14,11 @@ """User database operations.""" import datetime +import functools from flask.ext.login import UserMixin from compass.db.api import database -from compass.db.api import permission from compass.db.api import utils from compass.db import exception from compass.db import models @@ -81,20 +81,59 @@ def add_user_internal( def _check_user_permission(session, user, permission): """Check user has permission.""" - with session.begin(subtransactions=True): - if user.is_admin: - return + if user.is_admin: + return - user_permission = utils.get_db_object( - session, models.UserPermission, - False, user_id=user.id, name=permission.name - ) - if not user_permission: - raise exception.Forbidden( - 'user %s does not have permission %s' % ( - user.email, permission.name - ) + user_permission = utils.get_db_object( + session, models.UserPermission, + False, user_id=user.id, name=permission.name + ) + if not user_permission: + raise exception.Forbidden( + 'user %s does not have permission %s' % ( + user.email, permission.name ) + ) + + +def check_user_permission_in_session(permission): + def decorator(func): + @functools.wraps(func) + def wrapper(session, user, *args, **kwargs): + _check_user_permission(session, user, permission) + return func(session, user, *args, **kwargs) + return wrapper + return decorator + + +def check_user_admin(): + def decorator(func): + @functools.wraps(func) + def wrapper(user, *args, **kwargs): + if not user.is_admin: + raise exception.Forbidden( + 'User %s is not admin.' % ( + user.email + ) + ) + return func(user, *args, **kwargs) + return wrapper + return decorator + + +def check_user_admin_or_owner(): + def decorator(func): + @functools.wraps(func) + def wrapper(user, user_id, *args, **kwargs): + if not user.is_admin and user.id != user_id: + raise exception.Forbidden( + 'User %s is not admin or the owner of user id %s.' % ( + user.email, user_id + ) + ) + return func(user, user_id, *args, **kwargs) + return wrapper + return decorator def check_user_permission_internal(session, user, permission): @@ -105,39 +144,36 @@ def check_user_permission_internal(session, user, permission): def _add_user_permissions(session, user, **permission_filters): """add permissions to a user.""" from compass.db.api import permission as permission_api - with session.begin(subtransactions=True): - for api_permission in permission_api.list_permissions_internal( - session, **permission_filters - ): - utils.add_db_object( - session, models.UserPermission, False, - user.id, api_permission.id - ) + for api_permission in permission_api.list_permissions_internal( + session, **permission_filters + ): + utils.add_db_object( + session, models.UserPermission, False, + user.id, api_permission.id + ) def _remove_user_permissions(session, user, **permission_filters): """remove permissions to a user.""" from compass.db.api import permission as permission_api - with session.begin(subtransactions=True): - permission_ids = [] + permission_ids = [ + api_permission.id for api_permission in permission_api.list_permissions_internal( session, **permission_filters - ): - permission_ids.append(api_permission.id) - utils.del_db_objects( - session, models.UserPermission, - user_id=user.id, permission_id=permission_ids ) + ] + utils.del_db_objects( + session, models.UserPermission, + user_id=user.id, permission_id=permission_ids + ) def _set_user_permissions(session, user, **permission_filters): """set permissions to a user.""" - from compass.db.api import permission as permission_api - with session.begin(subtransactions=True): - utils.del_db_objects( - session, models.UserPermission, - user_id=user.id, permission_id=permission.id - ) + utils.del_db_objects( + session, models.UserPermission, + user_id=user.id + ) _add_user_permissions(session, user, **permission_filters) @@ -180,304 +216,211 @@ class UserWrapper(UserMixin): self.__class__.__name__, self.email, self.password) -def get_user_object(email, **kwargs): - with database.session() as session: - user_dict = utils.get_db_object( - session, models.User, email=email - ).to_dict() - user_dict.update(kwargs) - return UserWrapper(**user_dict) +@database.run_in_session() +def get_user_object(session, email, **kwargs): + user_dict = utils.get_db_object( + session, models.User, email=email + ).to_dict() + user_dict.update(kwargs) + return UserWrapper(**user_dict) -def get_user_object_from_token(token): +@database.run_in_session() +def get_user_object_from_token(session, token): expire_timestamp = { 'ge': datetime.datetime.now() } - with database.session() as session: - user_token = utils.get_db_object( - session, models.UserToken, - token=token, expire_timestamp=expire_timestamp - ) - user_dict = utils.get_db_object( - session, models.User, id=user_token.user_id - ).to_dict() - user_dict['token'] = token - user_dict['expire_timestamp'] = user_token.expire_timestamp - return UserWrapper(**user_dict) + user_token = utils.get_db_object( + session, models.UserToken, + token=token, expire_timestamp=expire_timestamp + ) + user_dict = utils.get_db_object( + session, models.User, id=user_token.user_id + ).to_dict() + user_dict['token'] = token + user_dict['expire_timestamp'] = user_token.expire_timestamp + return UserWrapper(**user_dict) -@utils.wrap_to_dict(RESP_TOKEN_FIELDS) @utils.supported_filters() -def record_user_token(user, token, expire_timestamp): +@database.run_in_session() +@utils.wrap_to_dict(RESP_TOKEN_FIELDS) +def record_user_token(session, user, token, expire_timestamp): """record user token in database.""" - with database.session() as session: - user_token = utils.add_db_object( - session, models.UserToken, True, - token, user_id=user.id, - expire_timestamp=expire_timestamp - ) - return user_token.to_dict() + return utils.add_db_object( + session, models.UserToken, True, + token, user_id=user.id, + expire_timestamp=expire_timestamp + ) +@utils.supported_filters() +@database.run_in_session() @utils.wrap_to_dict(RESP_TOKEN_FIELDS) -@utils.supported_filters() -def clean_user_token(user, token): +def clean_user_token(session, user, token): """clean user token in database.""" - with database.session() as session: - user_tokens = utils.del_db_objects( - session, models.UserToken, - token=token - ) - return [user_token.to_dict() for user_token in user_tokens] + return utils.del_db_objects( + session, models.UserToken, + token=token, user_id=user.id + ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters() -def get_user(getter, user_id, **kwargs): - """get field dict of a user.""" - with database.session() as session: - user = utils.get_db_object(session, models.User, id=user_id) - if not getter.is_admin and getter.id != user_id: - # The user is not allowed to get user - raise exception.Forbidden( - 'User %s has no permission to list user %s.' % ( - getter.email, user.email - ) - ) - - return user.to_dict() - - +@check_user_admin_or_owner() +@database.run_in_session() @utils.wrap_to_dict(RESP_FIELDS) +def get_user(session, getter, user_id, **kwargs): + """get field dict of a user.""" + return utils.get_db_object(session, models.User, id=user_id) + + @utils.supported_filters( optional_support_keys=SUPPORTED_FIELDS ) -def list_users(lister, **filters): - """List fields of all users by some fields.""" - with database.session() as session: - if not lister.is_admin: - # The user is not allowed to list users - raise exception.Forbidden( - 'User %s has no permission to list users.' % ( - lister.email - ) - ) - return [ - user.to_dict() - for user in utils.list_db_objects( - session, models.User, **filters - ) - ] - - +@check_user_admin() +@database.run_in_session() @utils.wrap_to_dict(RESP_FIELDS) +def list_users(session, lister, **filters): + """List fields of all users by some fields.""" + return utils.list_db_objects( + session, models.User, **filters + ) + + @utils.input_validates(email=_check_email) @utils.supported_filters( ADDED_FIELDS, optional_support_keys=OPTIONAL_ADDED_FIELDS ) -def add_user(creator, email, password, **kwargs): +@check_user_admin() +@database.run_in_session() +@utils.wrap_to_dict(RESP_FIELDS) +def add_user(session, creator, email, password, **kwargs): """Create a user and return created user object.""" - with database.session() as session: - if not creator.is_admin: - # The user is not allowed to create a user. - raise exception.Forbidden( - 'User %s has no permission to create user.' % ( - creator.email - ) - ) - - return add_user_internal( - session, email, password, **kwargs - ).to_dict() + return add_user_internal( + session, email, password, **kwargs + ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters() -def del_user(deleter, user_id, **kwargs): +@database.run_in_session() +@check_user_admin() +@utils.wrap_to_dict(RESP_FIELDS) +def del_user(session, deleter, user_id, **kwargs): """delete a user and return the deleted user object.""" - with database.session() as session: - if not deleter.is_admin: - raise exception.Forbidden( - 'User %s has no permission to delete user.' % ( - deleter.email - ) - ) - - user = utils.get_db_object(session, models.User, id=user_id) - utils.del_db_object(session, user) - return user.to_dict() + user = utils.get_db_object(session, models.User, id=user_id) + return utils.del_db_object(session, user) -@utils.wrap_to_dict(RESP_FIELDS) -@utils.input_validates(email=_check_email) @utils.supported_filters(optional_support_keys=UPDATED_FIELDS) -def update_user(updater, user_id, **kwargs): +@utils.input_validates(email=_check_email) +@database.run_in_session() +@utils.wrap_to_dict(RESP_FIELDS) +def update_user(session, updater, user_id, **kwargs): """Update a user and return the updated user object.""" - with database.session() as session: - user = utils.get_db_object(session, models.User, id=user_id) - update_info = {} - if updater.is_admin: - update_info.update(dict([ - (key, value) for key, value in kwargs.items() - if key in ADMIN_UPDATED_FIELDS - ])) - kwargs = dict([ - (key, value) for key, value in kwargs.items() - if key not in ADMIN_UPDATED_FIELDS - ]) - - if updater.id == user_id: - update_info.update(dict([ - (key, value) for key, value in kwargs.items() - if key in SELF_UPDATED_FIELDS - ])) - kwargs = dict([ - (key, value) for key, value in kwargs.items() - if key not in SELF_UPDATED_FIELDS - ]) - - if kwargs: + user = utils.get_db_object( + session, models.User, id=user_id + ) + allowed_fields = set() + if updater.is_admin: + allowed_fields |= set(ADMIN_UPDATED_FIELDS) + if updater.id == user_id: + allowed_fields |= set(SELF_UPDATED_FIELDS) + unsupported_fields = allowed_fields - set(kwargs) + if unsupported_fields: # The user is not allowed to update a user. - raise exception.Forbidden( - 'User %s has no permission to update user %s: %s.' % ( - updater.email, user.email, kwargs - ) + raise exception.Forbidden( + 'User %s has no permission to update user %s fields %s.' % ( + updater.email, user.email, unsupported_fields ) - - utils.update_db_object(session, user, **update_info) - return user.to_dict() + ) + return utils.update_db_object(session, user, **kwargs) -@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) @utils.supported_filters(optional_support_keys=PERMISSION_SUPPORTED_FIELDS) -def get_permissions(getter, user_id, **kwargs): +@check_user_admin_or_owner() +@database.run_in_session() +@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) +def get_permissions(session, getter, user_id, **kwargs): """List permissions of a user.""" - with database.session() as session: - if not getter.is_admin and getter.id != user_id: - # The user is not allowed to list permissions - raise exception.Forbidden( - 'User %s has no permission to list user %s permissions.' % ( - getter.email, user_id - ) - ) - user_permissions = utils.list_db_objects( - session, models.UserPermission, user_id=user_id, **kwargs - ) - return [ - user_permission.to_dict() - for user_permission in user_permissions - ] + return utils.list_db_objects( + session, models.UserPermission, user_id=user_id, **kwargs + ) -@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) @utils.supported_filters() -def get_permission(getter, user_id, permission_id, **kwargs): +@check_user_admin_or_owner() +@database.run_in_session() +@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) +def get_permission(session, getter, user_id, permission_id, **kwargs): """Get a specific user permission.""" - with database.session() as session: - if not getter.is_admin and getter.id != user_id: - # The user is not allowed to get permission - raise exception.Forbidden( - 'User %s has no permission to get user %s permission.' % ( - getter.email, user_id - ) - ) - - user_permission = utils.get_db_object( - session, models.UserPermission, - user_id=user_id, permission_id=permission_id, - **kwargs - ) - return user_permission.to_dict() + return utils.get_db_object( + session, models.UserPermission, + user_id=user_id, permission_id=permission_id, + **kwargs + ) -@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) @utils.supported_filters() -def del_permission(deleter, user_id, permission_id, **kwargs): +@check_user_admin_or_owner() +@database.run_in_session() +@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) +def del_permission(session, deleter, user_id, permission_id, **kwargs): """Delete a specific user permission.""" - with database.session() as session: - if not deleter.is_admin and deleter.id != user_id: - # The user is not allowed to delete permission - raise exception.Forbidden( - 'User %s has no permission to delete user %s permission.' % ( - deleter.email, user_id - ) - ) - - user_permission = utils.get_db_object( - session, models.UserPermission, - user_id=user_id, permission_id=permission_id, - **kwargs - ) - utils.del_db_object(session, user_permission) - return user_permission.to_dict() + user_permission = utils.get_db_object( + session, models.UserPermission, + user_id=user_id, permission_id=permission_id, + **kwargs + ) + return utils.del_db_object(session, user_permission) +@utils.supported_filters(PERMISSION_ADDED_FIELDS) +@check_user_admin() +@database.run_in_session() @utils.wrap_to_dict(PERMISSION_RESP_FIELDS) -@utils.supported_filters( - PERMISSION_ADDED_FIELDS -) -def add_permission(creator, user_id, permission_id): +def add_permission(session, creator, user_id, permission_id): """Add an user permission.""" - with database.session() as session: - if not creator.is_admin: - # The user is not allowed to add a permission. - raise exception.Forbidden( - 'User %s has no permission to add a permission.' % ( - creator.email - ) - ) - user_permission = utils.add_db_object( - session, models.UserPermission, True, - user_id, permission_id - ) - return user_permission.to_dict() + return utils.add_db_object( + session, models.UserPermission, True, + user_id, permission_id + ) + + +def _get_permission_filters(permission_ids): + if permission_ids == 'all': + return {} + else: + return {'id': permission_ids} -@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) @utils.supported_filters( optional_support_keys=[ 'add_permissions', 'remove_permissions', 'set_permissions' ] ) +@check_user_admin() +@database.run_in_session() +@utils.wrap_to_dict(PERMISSION_RESP_FIELDS) def update_permissions( - updater, user_id, + session, updater, user_id, add_permissions=[], remove_permissions=[], set_permissions=None, **kwargs ): """update user permissions.""" - def get_permission_filters(permission_ids): - if permission_ids == 'all': - return {} - else: - return {'id': permission_ids} - - with database.session() as session: - if not updater.is_admin: - raise exception.Forbidden( - 'User %s has no permission to update user %s: %s.' % ( - updater.email, user_id, kwargs - ) - ) - user = utils.get_db_object(session, models.User, id=user_id) - if remove_permissions: - _remove_user_permissions( - session, user, - **get_permission_filters(remove_permissions) - ) - - if add_permissions: - _add_user_permissions( - session, user, - **get_permission_filters(add_permissions) - ) - - if set_permissions is not None: - _set_user_permissions( - session, user, - **get_permission_filters(set_permissions) - ) - - return [ - user_permission.to_dict() - for user_permission in user.user_permissions - ] + user = utils.get_db_object(session, models.User, id=user_id) + if remove_permissions: + _remove_user_permissions( + session, user, + **_get_permission_filters(remove_permissions) + ) + if add_permissions: + _add_user_permissions( + session, user, + **_get_permission_filters(add_permissions) + ) + if set_permissions is not None: + _set_user_permissions( + session, user, + **_get_permission_filters(set_permissions) + ) + return user.user_permissions diff --git a/compass/db/api/user_log.py b/compass/db/api/user_log.py index c55907f7..449bb684 100644 --- a/compass/db/api/user_log.py +++ b/compass/db/api/user_log.py @@ -27,113 +27,86 @@ USER_SUPPORTED_FIELDS = ['timestamp'] RESP_FIELDS = ['user_id', 'logs', 'timestamp'] -def log_user_action(user_id, action): +@database.run_in_session() +def log_user_action(session, user_id, action): """Log user action.""" - with database.session() as session: - utils.add_db_object( - session, models.UserLog, True, user_id=user_id, action=action - ) + utils.add_db_object( + session, models.UserLog, True, user_id=user_id, action=action + ) + + +def _compress_response(actions, user_id): + user_actions = [] + for action in actions: + action_dict = action.to_dict() + del action_dict['user_id'] + user_actions.append(action_dict) + return {'user_id': user_id, 'logs': user_actions} + + +def _compress_response_by_user(actions): + actions = {} + for action in actions: + action_dict = action.to_dict() + user_id = action_dict['user_id'] + del action_dict['user_id'] + actions.setdefault(user_id, []).append(action_dict) + + return [ + {'user_id': user_id, 'logs': user_actions} + for user_id, user_actions in actions.items() + ] -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=USER_SUPPORTED_FIELDS) -def list_user_actions(lister, user_id, **filters): +@user_api.check_user_admin_or_owner() +@database.run_in_session() +@utils.wrap_to_dict(RESP_FIELDS) +def list_user_actions(session, lister, user_id, **filters): """list user actions.""" - with database.session() as session: - if not lister.is_admin and lister.id != user_id: - # The user is not allowed to list users actions. - raise exception.Forbidden( - 'User %s has no permission to list user %s actions.' % ( - lister.email, user_id - ) - ) - - user_actions = [] - for action in utils.list_db_objects( - session, models.UserLog, user_id=user_id, **filters - ): - action_dict = action.to_dict() - del action_dict['user_id'] - user_actions.append(action_dict) - - return {'user_id': user_id, 'logs': user_actions} + return _compress_response( + utils.list_db_objects( + session, models.UserLog, user_id=user_id, **filters + ), + user_id + ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def list_actions(lister, **filters): +@user_api.check_user_admin() +@database.run_in_session() +@utils.wrap_to_dict(RESP_FIELDS) +def list_actions(session, lister, **filters): """list actions.""" - with database.session() as session: - if not lister.is_admin: - # The user is not allowed to list users actions. - raise exception.Forbidden( - 'User %s has no permission to list all users actions.' % ( - lister.email - ) - ) - - actions = {} - for action in utils.list_db_objects( + return _compress_response_by_user( + utils.list_db_objects( session, models.UserLog, **filters - ): - action_dict = action.to_dict() - user_id = action_dict['user_id'] - del action_dict['user_id'] - actions.setdefault(user_id, []).append(action_dict) - - return [ - {'user_id': user_id, 'logs': user_actions} - for user_id, user_actions in actions.items() - ] + ) + ) -@utils.wrap_to_dict(RESP_FIELDS) @utils.supported_filters(optional_support_keys=USER_SUPPORTED_FIELDS) -def del_user_actions(deleter, user_id, **filters): - """delete user actions.""" - with database.session() as session: - if not deleter.is_admin and deleter.id != user_id: - # The user is not allowed to delete users actions. - raise exception.Forbidden( - 'User %s has no permission to delete user %s actions.' % ( - deleter.email, user_id - ) - ) - - user_actions = [] - for action in utils.del_db_objects( - session, models.UserLog, user_id=user_id, **filters - ): - action_dict = action.to_dict() - del action_dict['user_id'] - user_actions.append(action_dict) - - return {'user_id': user_id, 'logs': user_actions} - - +@user_api.check_user_admin_or_owner() +@database.run_in_session() @utils.wrap_to_dict(RESP_FIELDS) +def del_user_actions(session, deleter, user_id, **filters): + """delete user actions.""" + return _compress_response( + utils.del_db_objects( + session, models.UserLog, user_id=user_id, **filters + ), + user_id + ) + + @utils.supported_filters(optional_support_keys=SUPPORTED_FIELDS) -def del_actions(deleter, **filters): +@user_api.check_user_admin() +@database.run_in_session() +@utils.wrap_to_dict(RESP_FIELDS) +def del_actions(session, deleter, **filters): """delete actions.""" - with database.session() as session: - if not deleter.is_admin: - # The user is not allowed to delete users actions. - raise exception.Forbidden( - 'User %s has no permission to delete all users actions.' % ( - deleter.email - ) - ) - - actions = {} - for action in utils.del_db_objects( + return _compress_response_by_user( + utils.del_db_objects( session, models.UserLog, **filters - ): - action_dict = action.to_dict() - user_id = action_dict['user_id'] - del action_dict['user_id'] - actions.setdefault(user_id, []).append(action_dict) - - return [ - {'user_id': user_id, 'logs': user_actions} - for user_id, user_actions in actions.items() - ] + ) + ) diff --git a/compass/db/api/utils.py b/compass/db/api/utils.py index 5048fc2c..68dd6759 100644 --- a/compass/db/api/utils.py +++ b/compass/db/api/utils.py @@ -71,7 +71,7 @@ def _model_filter_by_condition( def _between_condition(col_attr, value): if value[0] is not None and value[1] is not None: - col_attr.between(value[0], value[1]) + return col_attr.between(value[0], value[1]) if value[0] is not None: return col_attr >= value[0] if value[1] is not None: @@ -80,7 +80,6 @@ def _between_condition(col_attr, value): def model_filter(query, model, **filters): - print 'model query %s: filter %s' % (query, filters) for key, value in filters.items(): col_attr = getattr(model, key) if isinstance(value, list): @@ -118,19 +117,19 @@ def model_filter(query, model, **filters): ) if 'ne' in value: query = _model_filter_by_condition( - query, col_attr, value['eq'], None, + query, col_attr, value['ne'], None, lambda attr, data, condition_func: ~attr.in_(data) ) if 'in' in value: query = query.filter(col_attr.in_(value['in'])) if 'startswith' in value: query = _model_filter_by_condition( - query, col_attr, value['startswitch'], + query, col_attr, value['startswith'], lambda attr, data: attr.like('%s%%' % data) ) if 'endswith' in value: query = _model_filter_by_condition( - query, col_attr, value['endswitch'], + query, col_attr, value['endswith'], lambda attr, data: attr.like('%%%s' % data) ) if 'like' in value: @@ -153,21 +152,22 @@ def wrap_to_dict(support_keys=[]): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): - obj = func(*args, **kwargs) - if isinstance(obj, list): - obj = [_wrapper_dict(o, support_keys) for o in obj] - else: - obj = _wrapper_dict(obj, support_keys) - return obj + return _wrapper_dict(func(*args, **kwargs), support_keys) return wrapper return decorator def _wrapper_dict(data, support_keys): """Helper for warpping db object into dictionary.""" - info = {} - if not isinstance(data, dict): + if isinstance(data, list): + return [_wrapper_dict(item, support_keys) for item in data] + if isinstance(data, models.HelperMixin): data = data.to_dict() + if not isinstance(data, dict): + raise exception.InvalidResponse( + 'response %s type is not dict' % data + ) + info = {} for key in support_keys: if key in data: info[key] = data[key] @@ -178,26 +178,24 @@ def supported_filters(support_keys=[], optional_support_keys=[]): def decorator(func): @functools.wraps(func) def wrapper(*args, **filters): - print 'filter %s %s' % (args, filters) must_support_keys = set(support_keys) all_support_keys = must_support_keys | set(optional_support_keys) - supports = {} - for filter_key, filter_value in filters.items(): - if filter_key not in all_support_keys: - raise exception.InvalidParameter( - 'filter key %s is not supported' % filter_key - ) - - if filter_key in must_support_keys: - must_support_keys.remove(filter_key) - - supports[filter_key] = filter_value - - if must_support_keys: + filter_keys = set(filters) + unsupported_keys = filter_keys - all_support_keys + if unsupported_keys: raise exception.InvalidParameter( - 'filter keys %s not found' % list(must_support_keys) + 'filter keys %s are not supported' % str( + list(unsupported_keys) + ) ) - return func(*args, **supports) + missing_keys = must_support_keys - filter_keys + if missing_keys: + raise exception.InvalidParameter( + 'filter keys %s not found' % str( + list(missing_keys) + ) + ) + return func(*args, **filters) return wrapper return decorator @@ -314,10 +312,18 @@ def input_validates(*args_validators, **kwargs_validators): def _output_validates(kwargs_validators, obj): - if not isinstance(obj, dict): + if isinstance(obj, list): + for item in obj: + _output_validates(kwargs_validators, item) + return + if isinstance(obj, models.HelperMixin): obj = obj.to_dict() + if not isinstance(obj, dict): + raise exception.InvalidResponse( + 'response %s type is not dict' % str(obj) + ) for key, value in obj.items(): - if kwargs_validators.get(key): + if key in kwargs_validators: kwargs_validators[key](value) @@ -438,6 +444,7 @@ def update_db_object(session, db_object, **kwargs): db_object.initialize() session.flush() db_object.validate() + return db_object def del_db_object(session, db_object): @@ -445,6 +452,7 @@ def del_db_object(session, db_object): with session.begin(subtransactions=True): logging.debug('delete db object %s', db_object) session.delete(db_object) + return db_object def check_ip(ip): diff --git a/compass/db/models.py b/compass/db/models.py index 3cc41cbc..5fcd70be 100644 --- a/compass/db/models.py +++ b/compass/db/models.py @@ -1162,6 +1162,20 @@ class SwitchMachine(BASE, HelperMixin, TimestampMixin): self.machine_id = machine_id super(SwitchMachine, self).__init__(**kwargs) + def validate(self): + if not self.switch: + raise exception.InvalidParameter( + 'switch is not set in %s' % self.id + ) + if not self.machine: + raise exception.Invalidparameter( + 'machine is not set in %s' % self.id + ) + if not self.port: + raise exception.InvalidParameter( + 'port is not set in %s' % self.id + ) + @hybrid_property def mac(self): return self.machine.mac diff --git a/misc/apache/compass.wsgi b/misc/apache/compass.wsgi index 83619ea4..b6fc9253 100755 --- a/misc/apache/compass.wsgi +++ b/misc/apache/compass.wsgi @@ -1,5 +1,4 @@ #!/usr/bin/env python -from compass.api import app as application from compass.utils import flags from compass.utils import logsetting from compass.utils import setting_wrapper as setting @@ -7,3 +6,7 @@ from compass.utils import setting_wrapper as setting flags.init() flags.OPTIONS.logfile = setting.WEB_LOGFILE logsetting.init() + +from compass.api import api as compass_api +compass_api.init() +application = compass_api.app diff --git a/misc/apache/ods-server b/misc/apache/ods-server.conf similarity index 72% rename from misc/apache/ods-server rename to misc/apache/ods-server.conf index b4359a67..9b86631a 100644 --- a/misc/apache/ods-server +++ b/misc/apache/ods-server.conf @@ -3,11 +3,14 @@ # Specify python path if you use virtualenv # WSGIPythonHome /home/vagrant/hwtest +WSGIDaemonProcess api threads=4 display-name=%{GROUP} +WSGIProcessGroup api +WSGIScriptAlias /api /var/www/compass/compass.wsgi +WSGISocketPrefix /var/run/wsgi + DocumentRoot /var/www/compass_web RewriteRule ^/$ /ods/ods.html [R=301,L] - WSGIScriptAlias /api /var/www/compass/compass.wsgi - RewriteEngine on RewriteRule ^/$ /ods/ods.html [R]