change adapter code

Change-Id: Id5709d8ac723b31596ec97cf251ef09f343372c6
This commit is contained in:
xiaodongwang 2014-07-25 09:40:54 -07:00
parent 76436d717a
commit e8055850a1
35 changed files with 1422 additions and 926 deletions

View File

@ -118,6 +118,40 @@ def _get_request_args():
return dict(request.args) return dict(request.args)
def _group_data_action(data, **data_callbacks):
if not data:
raise exception_handler.BadRequest(
'no action to take'
)
unsupported_keys = list(set(data) - set(data_callbacks))
if unsupported_keys:
raise exception_handler.BadMethod(
'unsupported actions: %s' % unsupported_keys
)
callback_datas = {}
for data_key, data_value in data.items():
callback = data_callbacks[data_key]
callback_datas.setdefault(id(callback), {})[data_key] = data_value
if len(callback_datas) > 1:
raise exception_handler.BadRequest(
'multi actions are not supported'
)
callback_ids = {}
for data_key, data_callback in data_callbacks.items():
callback_ids[id(data_callback)] = data_callback
for callback_id, callback_data in callback_datas.items():
return callback_ids[callback_id](**callback_data)
def _wrap_response(func, response_code):
def wrapped_func(*args, **kwargs):
return utils.make_json_response(
response_code,
func(*args, **kwargs)
)
return wrapped_func
def _login(use_cookie): def _login(use_cookie):
"""User login helper function.""" """User login helper function."""
data = _get_request_data() data = _get_request_data()
@ -245,18 +279,23 @@ def list_user_permissions(user_id):
) )
@app.route("/users/<int:user_id>/permissions/actions", methods=['POST']) @app.route("/users/<int:user_id>/action", methods=['POST'])
@log_user_action @log_user_action
@login_required @login_required
def update_user_permissions(user_id): def take_user_action(user_id):
"""Update user permissions.""" """Update user permissions."""
data = _get_request_data() data = _get_request_data()
return utils.make_json_response( update_permissions_func = _wrap_response(
200, functools.partial(
user_api.update_permissions( user_api.update_permissions, current_user, user_id
current_user, user_id, ),
**data 200
) )
return _group_data_action(
data,
add_permission=update_permissions_func,
remove_permissions=update_permissions_func,
set_permissions=update_permissions_func
) )
@ -626,12 +665,12 @@ def _filter_port(data):
) )
def _filter_vlans(data): def _filter_general(data, key):
vlan_filter = {} general_filter = {}
vlans = _get_data_list(data, 'vlans') general = _get_data_list(data, key)
if vlans: if general:
vlan_filter['resp_in'] = vlans general_filter['resp_in'] = general
data['vlans'] = vlan_filter data[key] = general_filter
def _filter_tag(data): def _filter_tag(data):
@ -665,7 +704,7 @@ def list_switch_machines(switch_id):
"""Get switch machines.""" """Get switch machines."""
data = _get_request_args() data = _get_request_args()
_filter_port(data) _filter_port(data)
_filter_vlans(data) _filter_general(data, 'vlans')
_filter_tag(data) _filter_tag(data)
_filter_location(data) _filter_location(data)
return utils.make_json_response( return utils.make_json_response(
@ -676,6 +715,26 @@ def list_switch_machines(switch_id):
) )
@app.route("/switches/<int:switch_id>/machines-hosts", methods=['GET'])
@log_user_action
@login_required
def list_switch_machines_hosts(switch_id):
"""Get switch machines or hosts."""
data = _get_request_args()
_filter_port(data)
_filter_general(data, 'vlans')
_filter_tag(data)
_filter_location(data)
_filter_general(data, 'os_name')
_filter_general(data, 'os_id')
return utils.make_json_response(
200,
switch_api.list_switch_machines_hosts(
current_user, switch_id, **data
)
)
@app.route("/switches/<int:switch_id>/machines", methods=['POST']) @app.route("/switches/<int:switch_id>/machines", methods=['POST'])
@log_user_action @log_user_action
@login_required @login_required
@ -705,23 +764,6 @@ def show_switch_machine(switch_id, machine_id):
) )
@app.route(
'/switches/<int:switch_id>/machines/actions',
methods=['POST']
)
@log_user_action
@login_required
def update_switch_machines(switch_id):
"""update switch machine."""
data = _get_request_data()
return utils.make_json_response(
200,
switch_api.update_switch_machines(
current_user, switch_id, **data
)
)
@app.route( @app.route(
'/switches/<int:switch_id>/machines/<int:machine_id>', '/switches/<int:switch_id>/machines/<int:machine_id>',
methods=['PUT'] methods=['PUT']
@ -782,27 +824,31 @@ def delete_switch_machine(switch_id, machine_id):
) )
@app.route("/switches/<int:switch_id>/actions", methods=['POST']) @app.route("/switches/<int:switch_id>/action", methods=['POST'])
@log_user_action @log_user_action
@login_required @login_required
def take_switch_action(switch_id): def take_switch_action(switch_id):
"""update switch.""" """update switch."""
data = _get_request_data() data = _get_request_data()
if 'find_machines' in data: poll_switch_machines_func = _wrap_response(
return utils.make_json_response( functools.partial(
202, switch_api.poll_switch_machines, current_user, switch_id
switch_api.poll_switch_machines( ),
current_user, switch_id, **data['find_machines'] 202
) )
) update_switch_machines_func = _wrap_response(
else: functools.partial(
return utils.make_json_response( switch_api.update_switch_machines, current_user, switch_id
200, ),
{ 200
'status': 'unknown action', )
'details': 'supported actions: %s' % str(['find_machines']) return _group_data_action(
} data,
) find_machines=poll_switch_machines_func,
add_machines=update_switch_machines_func,
remove_machines=update_switch_machines_func,
set_machines=update_switch_machines_func
)
@app.route("/switch-machines", methods=['GET']) @app.route("/switch-machines", methods=['GET'])
@ -812,8 +858,9 @@ def list_switchmachines():
"""List switch machines.""" """List switch machines."""
data = _get_request_args() data = _get_request_args()
_filter_ip(data) _filter_ip(data)
_replace_data(data, {'ip_int': 'switch_ip_int'})
_filter_port(data) _filter_port(data)
_filter_vlans(data) _filter_general(data, 'vlans')
_filter_tag(data) _filter_tag(data)
_filter_location(data) _filter_location(data)
return utils.make_json_response( return utils.make_json_response(
@ -824,6 +871,28 @@ def list_switchmachines():
) )
@app.route("/switches-machines-hosts", methods=['GET'])
@log_user_action
@login_required
def list_switchmachines_hosts():
"""List switch machines or hosts."""
data = _get_request_args()
_filter_ip(data)
_replace_data(data, {'ip_int': 'switch_ip_int'})
_filter_port(data)
_filter_general(data, 'vlans')
_filter_tag(data)
_filter_location(data)
_filter_general(data, 'os_name')
_filter_general(data, 'os_id')
return utils.make_json_response(
200,
switch_api.list_switchmachines_hosts(
current_user, **data
)
)
@app.route( @app.route(
'/switch-machines/<int:switch_machine_id>', '/switch-machines/<int:switch_machine_id>',
methods=['GET'] methods=['GET']
@ -975,7 +1044,7 @@ def delete_machine(machine_id):
) )
@app.route("/networks", methods=['GET']) @app.route("/subnets", methods=['GET'])
@log_user_action @log_user_action
@login_required @login_required
def list_subnets(): def list_subnets():
@ -989,7 +1058,7 @@ def list_subnets():
) )
@app.route("/networks/<int:subnet_id>", methods=['GET']) @app.route("/subnets/<int:subnet_id>", methods=['GET'])
@log_user_action @log_user_action
@login_required @login_required
def show_subnet(subnet_id): def show_subnet(subnet_id):
@ -1003,7 +1072,7 @@ def show_subnet(subnet_id):
) )
@app.route("/networks", methods=['POST']) @app.route("/subnets", methods=['POST'])
@log_user_action @log_user_action
@login_required @login_required
def add_subnet(): def add_subnet():
@ -1015,7 +1084,7 @@ def add_subnet():
) )
@app.route("/networks/<int:subnet_id>", methods=['PUT']) @app.route("/subnets/<int:subnet_id>", methods=['PUT'])
@log_user_action @log_user_action
@login_required @login_required
def update_subnet(subnet_id): def update_subnet(subnet_id):
@ -1029,7 +1098,7 @@ def update_subnet(subnet_id):
) )
@app.route("/networks/<int:subnet_id>", methods=['DELETE']) @app.route("/subnets/<int:subnet_id>", methods=['DELETE'])
@log_user_action @log_user_action
@login_required @login_required
def delete_subnet(subnet_id): def delete_subnet(subnet_id):
@ -1049,6 +1118,10 @@ def delete_subnet(subnet_id):
def list_adapters(): def list_adapters():
"""List adapters.""" """List adapters."""
data = _get_request_args() data = _get_request_args()
_filter_general(data, 'name')
_filter_general(data, 'distributed_system_name')
_filter_general(data, 'os_installer_name')
_filter_general(data, 'package_installer_name')
return utils.make_json_response( return utils.make_json_response(
200, 200,
adapter_api.list_adapters( adapter_api.list_adapters(
@ -1088,17 +1161,31 @@ def show_adapter_roles(adapter_id):
@app.route("/adapters/<int:adapter_id>/metadata", methods=['GET']) @app.route("/adapters/<int:adapter_id>/metadata", methods=['GET'])
@log_user_action @log_user_action
@login_required @login_required
def show_metadata(adapter_id): def show_adapter_metadata(adapter_id):
"""Get adapter metadata.""" """Get adapter metadata."""
data = _get_request_args() data = _get_request_args()
return utils.make_json_response( return utils.make_json_response(
200, 200,
metadata_api.get_metadata( metadata_api.get_package_metadata(
current_user, adapter_id, **data current_user, adapter_id, **data
) )
) )
@app.route("/oses/<int:os_id>/metadata", methods=['GET'])
@log_user_action
@login_required
def show_os_metadata(os_id):
"""Get os metadata."""
data = _get_request_args()
return utils.make_json_response(
200,
metadata_api.get_os_metadata(
current_user, os_id, **data
)
)
@app.route("/clusters", methods=['GET']) @app.route("/clusters", methods=['GET'])
@log_user_action @log_user_action
@login_required @login_required
@ -1181,6 +1268,20 @@ def show_cluster_config(cluster_id):
) )
@app.route("/clusters/<int:cluster_id>/metadata", methods=['GET'])
@log_user_action
@login_required
def show_cluster_metadata(cluster_id):
"""Get cluster config."""
data = _get_request_args()
return utils.make_json_response(
200,
cluster_api.get_cluster_metadata(
current_user, cluster_id, **data
)
)
@app.route("/clusters/<int:cluster_id>/config", methods=['PUT']) @app.route("/clusters/<int:cluster_id>/config", methods=['PUT'])
@log_user_action @log_user_action
@login_required @login_required
@ -1233,37 +1334,37 @@ def delete_cluster_config(cluster_id):
) )
@app.route("/clusters/<int:cluster_id>/review", methods=['POST']) @app.route("/clusters/<int:cluster_id>/action", methods=['POST'])
@log_user_action
@login_required
def review_cluster(cluster_id):
"""review cluster"""
data = _get_request_data()
return utils.make_json_response(
200,
cluster_api.review_cluster(current_user, cluster_id, **data)
)
@app.route("/clusters/<int:cluster_id>/actions", methods=['POST'])
@log_user_action @log_user_action
@login_required @login_required
def take_cluster_action(cluster_id): def take_cluster_action(cluster_id):
"""take cluster action.""" """take cluster action."""
data = _get_request_data() data = _get_request_data()
if 'deploy' in data: update_cluster_hosts_func = _wrap_response(
return utils.make_json_response( functools.partial(
202, cluster_api.update_cluster_hosts, current_user, cluster_id
cluster_api.deploy_cluster( ),
current_user, cluster_id, **data['deploy'] 200
) )
) review_cluster_func = _wrap_response(
return utils.make_json_response( functools.partial(
200, cluster_api.review_cluster, current_user, cluster_id
{ ),
'status': 'unknown action', 200
'details': 'supported actions: %s' % str(['deploy']) )
} deploy_cluster_func = _wrap_response(
functools.partial(
cluster_api.deploy_cluster, current_user, cluster_id
),
202
)
return _group_data_action(
data,
add_hosts=update_cluster_hosts_func,
set_hosts=update_cluster_hosts_func,
remove_hosts=update_cluster_hosts_func,
review=review_cluster_func,
deploy=deploy_cluster_func
) )
@ -1383,18 +1484,6 @@ def delete_clusterhost(clusterhost_id):
) )
@app.route("/clusters/<int:cluster_id>/hosts/actions", methods=['POST'])
@log_user_action
@login_required
def update_cluster_hosts(cluster_id):
"""update cluster hosts."""
data = _get_request_data()
return utils.make_json_response(
200,
cluster_api.update_cluster_hosts(current_user, cluster_id, **data)
)
@app.route( @app.route(
"/clusters/<int:cluster_id>/hosts/<int:host_id>/config", "/clusters/<int:cluster_id>/hosts/<int:host_id>/config",
methods=['GET'] methods=['GET']
@ -1633,6 +1722,38 @@ def show_host(host_id):
) )
@app.route("/machines-hosts", methods=['GET'])
@log_user_action
@login_required
def list_machines_or_hosts():
"""Get host."""
data = _get_request_args()
_filter_tag(data)
_filter_location(data)
_filter_general(data, 'os_name')
_filter_general(data, 'os_name')
return utils.make_json_response(
200,
host_api.list_machines_or_hosts(
current_user, **data
)
)
@app.route("/machines-hosts/<int:host_id>", methods=['GET'])
@log_user_action
@login_required
def show_machine_or_host(host_id):
"""Get host."""
data = _get_request_args()
return utils.make_json_response(
200,
host_api.get_machine_or_host(
current_user, host_id, **data
)
)
@app.route("/hosts/<int:host_id>", methods=['PUT']) @app.route("/hosts/<int:host_id>", methods=['PUT'])
@log_user_action @log_user_action
@login_required @login_required
@ -1887,6 +2008,64 @@ def update_host_state(host_id):
) )
def _poweron_host(*args, **kwargs):
return utils.make_json_response(
202,
host_api.poweron_host(
*args, **kwargs
)
)
def _poweroff_host(*args, **kwargs):
return utils.make_json_response(
202,
host_api.poweroff_host(
*args, **kwargs
)
)
def _reset_host(*args, **kwargs):
return utils.make_json_response(
202,
host_api.reset_host(
*args, **kwargs
)
)
@app.route("/hosts/<int:host_id>/action", methods=['POST'])
@log_user_action
@login_required
def take_host_action(host_id):
"""take host action."""
data = _get_request_data()
poweron_func = _wrap_response(
functools.partial(
host_api.poweron_host, current_user, host_id
),
202
)
poweroff_func = _wrap_response(
functools.partial(
host_api.poweroff_host, current_user, host_id
),
202
)
reset_func = _wrap_response(
functools.partial(
host_api.reset_host, current_user, host_id
)
)
return _group_data_action(
data,
poweron=poweron_func,
poweroff=poweroff_func,
reset=reset_func,
)
def init(): def init():
logging.info('init flask') logging.info('init flask')
database.init() database.init()

View File

@ -25,48 +25,13 @@ from compass.utils import setting_wrapper as setting
from compass.utils import util from compass.utils import util
def _copy_adapters_from_parent(session, model, parent, system_name):
for child in parent.children:
if not child.adapters:
for adapter in parent.adapters:
if adapter.children:
continue
utils.add_db_object(
session, model,
True,
'%s(%s)' % (child.name, adapter.installer_name),
system_name=child, parent=adapter
)
_copy_adapters_from_parent(session, model, child, system_name)
def _complement_os_adapters(session):
with session.begin(subtransactions=True):
root_oses = utils.list_db_objects(
session, models.OperatingSystem,
parent_id=None
)
for root_os in root_oses:
_copy_adapters_from_parent(
session, models.OSAdapter, root_os, 'os'
)
def _complement_distributed_system_adapters(session):
with session.begin(subtransactions=True):
root_dses = utils.list_db_objects(
session, models.DistributedSystem,
parent_id=None
)
for root_ds in root_dses:
_copy_adapters_from_parent(
session, models.PackageAdapter, root_ds, 'distributed_system'
)
def _add_system(session, model, configs): def _add_system(session, model, configs):
parents = {} parents = {}
for config in configs: for config in configs:
logging.info(
'add config %s to %s',
config, model
)
object = utils.add_db_object( object = utils.add_db_object(
session, model, session, model,
True, config['NAME'], True, config['NAME'],
@ -85,154 +50,111 @@ def _add_system(session, model, configs):
def add_oses_internal(session): def add_oses_internal(session):
configs = util.load_configs(setting.OS_DIR) configs = util.load_configs(setting.OS_DIR)
with session.begin(subtransactions=True): _add_system(session, models.OperatingSystem, configs)
_add_system(session, models.OperatingSystem, configs)
def add_distributed_systems_internal(session): def add_distributed_systems_internal(session):
configs = util.load_configs(setting.DISTRIBUTED_SYSTEM_DIR) configs = util.load_configs(setting.DISTRIBUTED_SYSTEM_DIR)
with session.begin(subtransactions=True): _add_system(session, models.DistributedSystem, configs)
_add_system(session, models.DistributedSystem, configs)
def add_os_adapters_internal(session):
parents = {}
configs = util.load_configs(setting.OS_ADAPTER_DIR)
with session.begin(subtransactions=True):
for config in configs:
if 'OS' in config:
os = utils.get_db_object(
session, models.OperatingSystem,
name=config['OS']
)
else:
os = None
if 'INSTALLER' in config:
installer = utils.get_db_object(
session, models.OSInstaller,
name=config['INSTALLER']
)
else:
installer = None
object = utils.add_db_object(
session, models.OSAdapter,
True, config['NAME'], os=os, installer=installer
)
parents[config['NAME']] = (object, config.get('PARENT', None))
for name, (object, parent_name) in parents.items():
if parent_name:
parent, _ = parents[parent_name]
else:
parent = None
utils.update_db_object(
session, object, parent=parent
)
_complement_os_adapters(session)
def add_package_adapters_internal(session):
parents = {}
configs = util.load_configs(setting.PACKAGE_ADAPTER_DIR)
with session.begin(subtransactions=True):
for config in configs:
if 'DISTRIBUTED_SYSTEM' in config:
distributed_system = utils.get_db_object(
session, models.DistributedSystem,
name=config['DISTRIBUTED_SYSTEM']
)
else:
distributed_system = None
if 'INSTALLER' in config:
installer = utils.get_db_object(
session, models.PackageInstaller,
name=config['INSTALLER']
)
else:
installer = None
object = utils.add_db_object(
session, models.PackageAdapter,
True,
config['NAME'],
distributed_system=distributed_system,
installer=installer,
supported_os_patterns=config.get('SUPPORTED_OS_PATTERNS', [])
)
parents[config['NAME']] = (object, config.get('PARENT', None))
for name, (object, parent_name) in parents.items():
if parent_name:
parent, _ = parents[parent_name]
else:
parent = None
utils.update_db_object(session, object, parent=parent)
_complement_distributed_system_adapters(session)
def add_roles_internal(session):
configs = util.load_configs(setting.PACKAGE_ROLE_DIR)
with session.begin(subtransactions=True):
for config in configs:
package_adapter = utils.get_db_object(
session, models.PackageAdapter,
name=config['ADAPTER_NAME']
)
for role_dict in config['ROLES']:
utils.add_db_object(
session, models.PackageAdapterRole,
True, role_dict['role'], package_adapter.id,
description=role_dict['description'],
optional=role_dict.get('optional', False)
)
def add_adapters_internal(session): def add_adapters_internal(session):
with session.begin(subtransactions=True): parents = {}
package_adapters = [ configs = util.load_configs(setting.ADAPTER_DIR)
package_adapter for config in configs:
for package_adapter in utils.list_db_objects( logging.info('add config %s to adapter', config)
session, models.PackageAdapter if 'DISTRIBUTED_SYSTEM' in config:
distributed_system = utils.get_db_object(
session, models.DistributedSystem,
name=config['DISTRIBUTED_SYSTEM']
) )
if package_adapter.deployable else:
] distributed_system = None
os_adapters = [ if 'OS_INSTALLER' in config:
os_adapter os_installer = utils.get_db_object(
for os_adapter in utils.list_db_objects( session, models.OSInstaller,
session, models.OSAdapter name=config['OS_INSTALLER']
) )
if os_adapter.deployable else:
os_installer = None
if 'PACKAGE_INSTALLER' in config:
package_installer = utils.get_db_object(
session, models.PackageInstaller,
name=config['PACKAGE_INSTALLER']
)
else:
package_installer = None
adapter = utils.add_db_object(
session, models.Adapter,
True,
config['NAME'],
display_name=config.get('DISPLAY_NAME', None),
distributed_system=distributed_system,
os_installer=os_installer,
package_installer=package_installer,
deployable=config.get('DEPLOYABLE', False)
)
supported_os_patterns = [
re.compile(supported_os_pattern)
for supported_os_pattern in config.get('SUPPORTED_OS_PATTERNS', [])
] ]
adapters = [] oses = utils.list_db_objects(
for os_adapter in os_adapters: session, models.OperatingSystem
adapters.append(utils.add_db_object( )
session, models.Adapter, True, for os in oses:
os_adapter.id, None if not os.deployable:
)) continue
for package_adapter in package_adapters: os_name = os.name
adapters.append(utils.add_db_object( for supported_os_pattern in supported_os_patterns:
session, models.Adapter, True, if supported_os_pattern.match(os_name):
None, package_adapter.id utils.add_db_object(
)) session, models.AdapterOS,
for os_adapter in os_adapters: True,
for os_pattern in ( os.id, adapter.id
package_adapter.adapter_supported_os_patterns )
): break
if re.match(os_pattern, os_adapter.name): parents[config['NAME']] = (adapter, config.get('PARENT', None))
adapters.append(utils.add_db_object(
session, models.Adapter, True, for name, (adapter, parent_name) in parents.items():
os_adapter.id, package_adapter.id if parent_name:
)) parent, _ = parents[parent_name]
break else:
return adapters parent = None
utils.update_db_object(session, adapter, parent=parent)
def add_roles_internal(session):
configs = util.load_configs(setting.ADAPTER_ROLE_DIR)
for config in configs:
logging.info(
'add config to role', config
)
adapter = utils.get_db_object(
session, models.Adapter,
name=config['ADAPTER_NAME']
)
for role_dict in config['ROLES']:
utils.add_db_object(
session, models.AdapterRole,
True, role_dict['role'], adapter.id,
display_name=role_dict.get('display_name', None),
description=role_dict.get('description', None),
optional=role_dict.get('optional', False)
)
def get_adapters_internal(session): def get_adapters_internal(session):
adapter_mapping = {} adapter_mapping = {}
with session.begin(subtransactions=True): adapters = utils.list_db_objects(
adapters = utils.list_db_objects( session, models.Adapter
session, models.Adapter )
) for adapter in adapters:
for adapter in adapters: if adapter.deployable:
adapter_dict = adapter.to_dict() adapter_dict = adapter.to_dict()
adapter_mapping[adapter.id] = adapter_dict adapter_mapping[adapter.id] = adapter_dict
else:
logging.info(
'ignore adapter %s since it is not deployable',
adapter_dict
)
return adapter_mapping return adapter_mapping

View File

@ -24,16 +24,22 @@ from compass.db import exception
SUPPORTED_FIELDS = [ SUPPORTED_FIELDS = [
'name', 'os', 'distributed_system', 'os_installer', 'package_installer' 'name',
'distributed_system_name',
'os_installer_name',
'package_installer_name',
]
RESP_FIELDS = [
'id', 'name', 'roles', 'os_installer_name',
'package_installer_name', 'distributed_system_name',
'supported_oses', 'display_name'
]
RESP_OS_FIELDS = [
'id', 'os_id', 'name'
]
RESP_ROLES_FIELDS = [
'id', 'name', 'description', 'optional'
] ]
OS_FIELD_MAPPING = {
'os': 'os_name',
'os_installer': 'installer_type'
}
PACKAGE_FIELD_MAPPING = {
'distributed_system': 'distributed_system_name',
'package_installer': 'installer_type'
}
@database.run_in_session() @database.run_in_session()
@ -70,30 +76,19 @@ def _filter_adapters(adapter_config, filter_name, filter_value):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_ADAPTERS permission.PERMISSION_LIST_ADAPTERS
) )
@utils.output_filters(
name=utils.general_filter_callback,
distributed_system_name=utils.general_filter_callback,
os_installer_name=utils.general_filter_callback,
package_installer_name=utils.general_filter_callback
)
@utils.wrap_to_dict(
RESP_FIELDS,
supported_oses=RESP_OS_FIELDS
)
def list_adapters(session, lister, **filters): def list_adapters(session, lister, **filters):
"""list adapters.""" """list adapters."""
translated_filters = {} return ADAPTER_MAPPING.values()
for filter_name, filter_value in filters:
if filter_name in OS_FIELD_MAPPING:
translated_filters.setdefault('os_adapter', {})[
OS_FIELD_MAPPING[filter_name]
] = filter_value
elif filter_name in PACKAGE_FIELD_MAPPING:
translated_filters.setdefault('package_adapter', {})[
PACKAGE_FIELD_MAPPING[filter_name]
] = filter_value
else:
translated_filters[filter_name] = filter_value
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([]) @utils.supported_filters([])
@ -101,6 +96,10 @@ def list_adapters(session, lister, **filters):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_ADAPTERS permission.PERMISSION_LIST_ADAPTERS
) )
@utils.wrap_to_dict(
RESP_FIELDS,
supported_oses=RESP_OS_FIELDS
)
def get_adapter(session, getter, adapter_id, **kwargs): def get_adapter(session, getter, adapter_id, **kwargs):
"""get adapter.""" """get adapter."""
if adapter_id not in ADAPTER_MAPPING: if adapter_id not in ADAPTER_MAPPING:
@ -115,15 +114,11 @@ def get_adapter(session, getter, adapter_id, **kwargs):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_ADAPTERS permission.PERMISSION_LIST_ADAPTERS
) )
def get_adapter_roles(getter, adapter_id, **kwargs): @utils.wrap_to_dict(RESP_ROLES_FIELDS)
def get_adapter_roles(session, getter, adapter_id, **kwargs):
"""get adapter roles.""" """get adapter roles."""
if adapter_id not in ADAPTER_MAPPING: if adapter_id not in ADAPTER_MAPPING:
raise exception.RecordNotExists( raise exception.RecordNotExists(
'adpater %s does not exist' % adapter_id 'adpater %s does not exist' % adapter_id
) )
adapter_dict = ADAPTER_MAPPING[adapter_id] return ADAPTER_MAPPING[adapter_id].get('roles', [])
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']

View File

@ -30,7 +30,8 @@ SUPPORTED_FIELDS = [
] ]
SUPPORTED_CLUSTERHOST_FIELDS = [] SUPPORTED_CLUSTERHOST_FIELDS = []
RESP_FIELDS = [ RESP_FIELDS = [
'id', 'name', 'os_name', 'reinstall_distributed_system', 'id', 'name', 'os_name', 'os_id', 'distributed_system_id',
'reinstall_distributed_system',
'distributed_system_name', 'distributed_system_installed', 'distributed_system_name', 'distributed_system_installed',
'owner', 'adapter_id', 'owner', 'adapter_id',
'created_at', 'updated_at' 'created_at', 'updated_at'
@ -51,10 +52,16 @@ RESP_CONFIG_FIELDS = [
'created_at', 'created_at',
'updated_at' 'updated_at'
] ]
RESP_METADATA_FIELDS = [
'os_config',
'package_config'
]
RESP_CLUSTERHOST_CONFIG_FIELDS = [ RESP_CLUSTERHOST_CONFIG_FIELDS = [
'package_config', 'package_config',
'os_config',
'config_step', 'config_step',
'config_validated', 'config_validated',
'networks',
'created_at', 'created_at',
'updated_at' 'updated_at'
] ]
@ -67,15 +74,15 @@ RESP_CLUSTERHOST_STATE_FIELDS = [
'created_at', 'updated_at' 'created_at', 'updated_at'
] ]
RESP_REVIEW_FIELDS = [ RESP_REVIEW_FIELDS = [
'cluster', 'hosts' 'cluster', 'clusterhosts'
] ]
RESP_ACTION_FIELDS = [ RESP_DEPLOY_FIELDS = [
'status', 'details' 'status', 'cluster', 'clusterhosts'
] ]
ADDED_FIELDS = ['name', 'adapter_id'] ADDED_FIELDS = ['name', 'adapter_id']
OPTIONAL_ADDED_FIELDS = ['os_id']
UPDATED_FIELDS = ['name', 'reinstall_distributed_system'] UPDATED_FIELDS = ['name', 'reinstall_distributed_system']
ADDED_CLUSTERHOST_FIELDS = ['machine_id'] ADDED_HOST_FIELDS = ['machine_id']
UPDATED_CLUSTERHOST_FIELDS = ['name', 'reinstall_os']
UPDATED_HOST_FIELDS = ['name', 'reinstall_os'] UPDATED_HOST_FIELDS = ['name', 'reinstall_os']
UPDATED_CONFIG_FIELDS = [ UPDATED_CONFIG_FIELDS = [
'put_os_config', 'put_package_config', 'config_step' 'put_os_config', 'put_package_config', 'config_step'
@ -129,6 +136,25 @@ def _conditional_exception(cluster, exception_when_not_editable):
return False return False
def is_cluster_validated(
session, cluster
):
if not cluster.config_validated:
raise exception.Forbidden(
'cluster %s is not validated' % cluster.name
)
for clusterhost in cluster.clusterhsots:
if not clusterhost.config_validated:
raise exception.Forbidden(
'clusterhost %s is not validated' % clusterhost.name
)
host = clusterhost.host
if not host.config_validated:
raise exception.Forbidden(
'host %s is not validated' % host.name
)
def is_cluster_editable( def is_cluster_editable(
session, cluster, user, session, cluster, user,
reinstall_distributed_system_set=False, reinstall_distributed_system_set=False,
@ -150,7 +176,9 @@ def is_cluster_editable(
return True return True
@utils.supported_filters(ADDED_FIELDS) @utils.supported_filters(
ADDED_FIELDS, optional_support_keys=OPTIONAL_ADDED_FIELDS
)
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_ADD_CLUSTER permission.PERMISSION_ADD_CLUSTER
@ -160,7 +188,8 @@ def add_cluster(session, creator, name, adapter_id, **kwargs):
"""Create a cluster.""" """Create a cluster."""
return utils.add_db_object( return utils.add_db_object(
session, models.Cluster, True, session, models.Cluster, True,
name, adapter_id=adapter_id, creator_id=creator.id, **kwargs name, creator_id=creator.id, adapter_id=adapter_id,
**kwargs
) )
@ -212,6 +241,31 @@ def get_cluster_config(session, getter, cluster_id, **kwargs):
) )
@utils.supported_filters([])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_METADATAS
)
@utils.wrap_to_dict(RESP_METADATA_FIELDS)
def get_cluster_metadata(session, getter, cluster_id, **kwargs):
"""Get cluster metadata."""
cluster = utils.get_db_object(
session, models.Cluster, id=cluster_id
)
metadatas = {}
os = cluster.os
if os:
metadatas['os_config'] = metadata_api.get_os_metadata_internal(
os.id
)
adapter = cluster.adapter
if adapter:
metadatas['package_ocnfig'] = (
metadata_api.get_package_metadata_internal(adapter.id)
)
return metadatas
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_ADD_CLUSTER_CONFIG permission.PERMISSION_ADD_CLUSTER_CONFIG
) )
@ -225,7 +279,7 @@ def update_cluster_config_internal(session, updater, cluster, **kwargs):
os_config = cluster.os_config os_config = cluster.os_config
if os_config: if os_config:
metadata_api.validate_os_config( metadata_api.validate_os_config(
os_config, cluster.adapter_id os_config, cluster.os_id
) )
package_config = cluster.package_config package_config = cluster.package_config
if package_config: if package_config:
@ -278,8 +332,8 @@ def del_cluster_config(session, deleter, cluster_id):
@utils.supported_filters( @utils.supported_filters(
ADDED_CLUSTERHOST_FIELDS, ADDED_HOST_FIELDS,
optional_support_keys=UPDATED_CLUSTERHOST_FIELDS optional_support_keys=UPDATED_HOST_FIELDS
) )
def add_clusterhost_internal( def add_clusterhost_internal(
session, cluster, session, cluster,
@ -287,41 +341,32 @@ def add_clusterhost_internal(
machine_id=None, **kwargs machine_id=None, **kwargs
): ):
from compass.db.api import host as host_api from compass.db.api import host as host_api
host_dict = {} host = utils.get_db_object(
clusterhost_dict = {} session, models.Host, False, id=machine_id
for key, value in kwargs.items(): )
if key in UPDATED_HOST_FIELDS: if host:
host_dict[key] = value if host_api.is_host_editable(
else: session, host, cluster.creator,
clusterhost_dict[key] = value reinstall_os_set=kwargs.get('reinstall_os', False),
with session.begin(subtransactions=True): exception_when_not_editable=False
host = utils.get_db_object( ):
session, models.Host, False, id=machine_id utils.update_db_object(
) session, host,
if host: **kwargs
if host_api.is_host_editable(
session, host, cluster.creator,
reinstall_os_set=host_dict.get('reinstall_os', False),
exception_when_not_editable=False
):
utils.update_db_object(
session, host, adapter=cluster.adapter.os_adapter,
**host_dict
)
else:
logging.info('host %s is not editable', host.name)
else:
utils.add_db_object(
session, models.Host, False, machine_id,
os=cluster.os,
adapter=cluster.adapter.os_adapter,
creator=cluster.creator,
**host_dict
) )
return utils.add_db_object( else:
session, models.ClusterHost, exception_when_existing, logging.info('host %s is not editable', host.name)
cluster.id, machine_id, **clusterhost_dict else:
utils.add_db_object(
session, models.Host, False, machine_id,
os=cluster.os,
creator=cluster.creator,
**kwargs
) )
return utils.add_db_object(
session, models.ClusterHost, exception_when_existing,
cluster.id, machine_id
)
def _add_clusterhosts(session, cluster, machine_dicts): def _add_clusterhosts(session, cluster, machine_dicts):
@ -404,8 +449,8 @@ def get_clusterhost(session, getter, clusterhost_id, **kwargs):
@utils.supported_filters( @utils.supported_filters(
ADDED_CLUSTERHOST_FIELDS, ADDED_HOST_FIELDS,
optional_support_keys=UPDATED_CLUSTERHOST_FIELDS optional_support_keys=UPDATED_HOST_FIELDS
) )
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
@ -629,13 +674,17 @@ def update_cluster_hosts(
return cluster.clusterhosts return cluster.clusterhosts
@utils.supported_filters([]) @utils.supported_filters(optional_support_keys=['review'])
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_REVIEW_CLUSTER permission.PERMISSION_REVIEW_CLUSTER
) )
@utils.wrap_to_dict(RESP_REVIEW_FIELDS) @utils.wrap_to_dict(
def review_cluster(session, reviewer, cluster_id): RESP_REVIEW_FIELDS,
cluster=RESP_CONFIG_FIELDS,
clusterhosts=RESP_CLUSTERHOST_CONFIG_FIELDS
)
def review_cluster(session, reviewer, cluster_id, review={}, **kwargs):
"""review cluster.""" """review cluster."""
from compass.db.api import host as host_api from compass.db.api import host as host_api
cluster = utils.get_db_object( cluster = utils.get_db_object(
@ -645,7 +694,7 @@ def review_cluster(session, reviewer, cluster_id):
os_config = cluster.os_config os_config = cluster.os_config
if os_config: if os_config:
metadata_api.validate_os_config( metadata_api.validate_os_config(
os_config, cluster.adapter_id, True os_config, cluster.os_id, True
) )
for clusterhost in cluster.clusterhosts: for clusterhost in cluster.clusterhosts:
host = clusterhost.host host = clusterhost.host
@ -662,8 +711,9 @@ def review_cluster(session, reviewer, cluster_id):
os_config, host_os_config os_config, host_os_config
) )
metadata_api.validate_os_config( metadata_api.validate_os_config(
deployed_os_config, host.adapter_id, True deployed_os_config, host.os_id, True
) )
host_api.validate_host(session, host)
host.deployed_os_config = deployed_os_config host.deployed_os_config = deployed_os_config
host.config_validated = True host.config_validated = True
package_config = cluster.package_config package_config = cluster.package_config
@ -684,37 +734,38 @@ def review_cluster(session, reviewer, cluster_id):
clusterhost.config_validated = True clusterhost.config_validated = True
cluster.config_validated = True cluster.config_validated = True
return { return {
'cluster': cluster.to_dict(), 'cluster': cluster,
'clusterhosts': [ 'clusterhosts': cluster.clusterhosts
clusterhost.to_dict()
for clusterhost in cluster.clusterhosts
]
} }
@utils.supported_filters(optional_support_keys=['clusterhosts']) @utils.supported_filters(optional_support_keys=['deploy'])
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_DEPLOY_CLUSTER permission.PERMISSION_DEPLOY_CLUSTER
) )
@utils.wrap_to_dict(RESP_ACTION_FIELDS) @utils.wrap_to_dict(
RESP_DEPLOY_FIELDS,
cluster=RESP_CONFIG_FIELDS,
clusterhosts=RESP_CLUSTERHOST_FIELDS
)
def deploy_cluster( def deploy_cluster(
session, deployer, cluster_id, clusterhosts=[], **kwargs session, deployer, cluster_id, deploy={}, **kwargs
): ):
"""deploy cluster.""" """deploy cluster."""
from compass.tasks import client as celery_client from compass.tasks import client as celery_client
cluster = utils.get_db_object( cluster = utils.get_db_object(
session, models.Cluster, id=cluster_id session, models.Cluster, id=cluster_id
) )
is_cluster_editable(session, cluster, deployer) is_cluster_validated(session, cluster)
celery_client.celery.send_task( celery_client.celery.send_task(
'compass.tasks.deploy', 'compass.tasks.deploy',
(cluster_id, clusterhosts) (cluster_id, deploy.get('clusterhosts', []))
) )
return { return {
'status': 'deploy action sent', 'status': 'deploy action sent',
'details': { 'cluster': cluster,
} 'clusterhosts': cluster.clusterhosts
} }

View File

@ -182,27 +182,12 @@ def _setup_distributed_systems(distributed_system_session):
) )
def _setup_os_adapters(adapter_session):
"""Initialize os adapter table."""
logging.info('setup os adapter table')
from compass.db.api import adapter
adapter.add_os_adapters_internal(
adapter_session)
def _setup_package_adapters(adapter_session):
"""Initialize package adapter table."""
logging.info('setup package adapter table')
from compass.db.api import adapter
adapter.add_package_adapters_internal(
adapter_session)
def _setup_adapters(adapter_session): def _setup_adapters(adapter_session):
"""Initialize adapter table.""" """Initialize package adapter table."""
logging.info('setup adapter table') logging.info('setup adapter table')
from compass.db.api import adapter from compass.db.api import adapter
adapter.add_adapters_internal(adapter_session) adapter.add_adapters_internal(
adapter_session)
def _setup_os_fields(field_session): def _setup_os_fields(field_session):
@ -233,9 +218,9 @@ def _setup_package_metadatas(metadata_session):
metadata.add_package_metadata_internal(metadata_session) metadata.add_package_metadata_internal(metadata_session)
def _setup_package_adapter_roles(role_session): def _setup_adapter_roles(role_session):
"""Initialize package adapter role table.""" """Initialize package adapter role table."""
logging.info('setup package adapter role table') logging.info('setup adapter role table')
from compass.db.api import adapter from compass.db.api import adapter
adapter.add_roles_internal(role_session) adapter.add_roles_internal(role_session)
@ -251,10 +236,8 @@ def create_db(my_session):
_setup_package_installers(my_session) _setup_package_installers(my_session)
_setup_oses(my_session) _setup_oses(my_session)
_setup_distributed_systems(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_adapters(my_session)
_setup_adapter_roles(my_session)
_setup_os_fields(my_session) _setup_os_fields(my_session)
_setup_package_fields(my_session) _setup_package_fields(my_session)
_setup_os_metadatas(my_session) _setup_os_metadatas(my_session)
@ -284,22 +267,18 @@ def create_table(my_session, table):
models.PackageInstaller, models.PackageInstaller,
models.OperatingSystem, models.OperatingSystem,
models.DistributedSystems, models.DistributedSystems,
models.OSAdapter,
models.PackageAdapter,
models.Adapter models.Adapter
]: ]:
_setup_os_installers(my_session) _setup_os_installers(my_session)
_setup_package_installers(my_session) _setup_package_installers(my_session)
_setup_os_adapters(my_session) _setup_adapter_roles(my_session)
_setup_package_adapters(my_session)
_setup_package_adapter_roles(my_session)
_setup_adapters(my_session) _setup_adapters(my_session)
_setup_os_fields(my_session) _setup_os_fields(my_session)
_setup_os_metadatas(my_session) _setup_os_metadatas(my_session)
_setup_package_fields(my_session) _setup_package_fields(my_session)
_setup_package_metadatas(my_session) _setup_package_metadatas(my_session)
elif table == models.PackageAdapterRole: elif table == models.AdapterRole:
_setup_package_adapter_roles(my_session) _setup_adapter_roles(my_session)
elif table in [ elif table in [
models.OSConfigField, models.OSConfigField,
models.PackageConfigField, models.PackageConfigField,

View File

@ -25,12 +25,13 @@ from compass.db import models
SUPPORTED_FIELDS = ['name', 'os_name', 'owner', 'mac'] SUPPORTED_FIELDS = ['name', 'os_name', 'owner', 'mac']
SUPPORTED_MACHINE_HOST_FIELDS = ['mac', 'tag', 'location', 'os_name', 'os_id']
SUPPORTED_NETOWORK_FIELDS = [ SUPPORTED_NETOWORK_FIELDS = [
'interface', 'ip', 'subnet', 'is_mgmt', 'is_promiscuous' 'interface', 'ip', 'subnet', 'is_mgmt', 'is_promiscuous'
] ]
RESP_FIELDS = [ RESP_FIELDS = [
'id', 'name', 'os_name', 'owner', 'mac', 'id', 'name', 'os_name', 'os_id', 'owner', 'mac',
'reinstall_os', 'os_installed', 'tag', 'location', 'reinstall_os', 'os_installed', 'tag', 'location', 'networks',
'created_at', 'updated_at' 'created_at', 'updated_at'
] ]
RESP_CLUSTER_FIELDS = [ RESP_CLUSTER_FIELDS = [
@ -40,10 +41,19 @@ RESP_CLUSTER_FIELDS = [
'adapter_id', 'created_at', 'updated_at' 'adapter_id', 'created_at', 'updated_at'
] ]
RESP_NETWORK_FIELDS = [ RESP_NETWORK_FIELDS = [
'id', 'ip', 'interface', 'netmask', 'is_mgmt', 'is_promiscuous' 'id', 'ip', 'interface', 'netmask', 'is_mgmt', 'is_promiscuous',
'created_at', 'updated_at'
] ]
RESP_CONFIG_FIELDS = [ RESP_CONFIG_FIELDS = [
'os_config', 'os_config',
'config_setp',
'config_validated',
'networks',
'created_at',
'updated_at'
]
RESP_DEPLOY_FIELDS = [
'status', 'host'
] ]
UPDATED_FIELDS = ['name', 'reinstall_os'] UPDATED_FIELDS = ['name', 'reinstall_os']
UPDATED_CONFIG_FIELDS = [ UPDATED_CONFIG_FIELDS = [
@ -81,6 +91,35 @@ def list_hosts(session, lister, **filters):
) )
@utils.supported_filters(
optional_support_keys=SUPPORTED_MACHINE_HOST_FIELDS)
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_HOSTS
)
@utils.output_filters(
missing_ok=True,
tag=utils.general_filter_callback,
location=utils.general_filter_callback,
os_name=utils.general_filter_callback,
os_id=utils.general_filter_callback
)
@utils.wrap_to_dict(RESP_FIELDS)
def list_machines_or_hosts(session, lister, **filters):
"""List hosts."""
machines = utils.list_db_objects(
session, models.Machine, **filters
)
machines_or_hosts = []
for machine in machines:
host = machine.host
if host:
machines_or_hosts.append(host)
else:
machines_or_hosts.append(machine)
return machines_or_hosts
@utils.supported_filters([]) @utils.supported_filters([])
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
@ -94,6 +133,24 @@ def get_host(session, getter, host_id, **kwargs):
) )
@utils.supported_filters([])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_HOSTS
)
@utils.wrap_to_dict(RESP_FIELDS)
def get_machine_or_host(session, getter, host_id, **kwargs):
"""get host info."""
machine = utils.get_db_object(
session, models.Machine, id=host_id
)
host = machine.host
if host:
return host
else:
return machine
@utils.supported_filters([]) @utils.supported_filters([])
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
@ -117,27 +174,54 @@ def _conditional_exception(host, exception_when_not_editable):
return False return False
def is_host_validated(session, host):
if not host.config_validated:
raise exception.Forbidden(
'host %s is not validated' % host.name
)
def is_host_editable( def is_host_editable(
session, host, user, session, host, user,
reinstall_os_set=False, exception_when_not_editable=True reinstall_os_set=False, exception_when_not_editable=True
): ):
with session.begin(subtransactions=True): if reinstall_os_set:
if reinstall_os_set: if host.state.state == 'INSTALLING':
if host.state.state == 'INSTALLING':
return _conditional_exception(
host, exception_when_not_editable
)
elif not host.reinstall_os:
return _conditional_exception(
host, exception_when_not_editable
)
if not user.is_admin and host.creator_id != user.id:
return _conditional_exception( return _conditional_exception(
host, exception_when_not_editable host, exception_when_not_editable
) )
elif not host.reinstall_os:
return _conditional_exception(
host, exception_when_not_editable
)
if not user.is_admin and host.creator_id != user.id:
return _conditional_exception(
host, exception_when_not_editable
)
return True return True
def validate_host(session, host):
mgmt_interface_set = False
for host_network in host.host_networks:
if host_network.is_mgmt:
if mgmt_interface_set:
raise exception.InvalidParameter(
'%s multi interfaces set mgmt ' % host.name
)
if host_network.is_promiscuous:
raise exception.InvalidParameter(
'%s interface %s is mgmt but promiscuous' % (
host.name, host_network.interface
)
)
mgmt_interface_set = True
if not mgmt_interface_set:
raise exception.InvalidParameter(
'host has no mgmt interface' % host.name
)
@utils.supported_filters(UPDATED_FIELDS) @utils.supported_filters(UPDATED_FIELDS)
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
@ -401,3 +485,87 @@ def update_host_state(session, updater, host_id, **kwargs):
) )
utils.update_db_object(session, host.state, **kwargs) utils.update_db_object(session, host.state, **kwargs)
return host.state_dict() return host.state_dict()
@utils.supported_filters(optional_support_keys=['poweron'])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEPLOY_HOST
)
@utils.wrap_to_dict(
RESP_DEPLOY_FIELDS,
host=RESP_CONFIG_FIELDS
)
def poweron_host(
session, deployer, host_id, poweron={}, **kwargs
):
"""power on host."""
from compass.tasks import client as celery_client
host = utils.get_db_object(
session, models.host, id=host_id
)
is_host_validated(session, host)
celery_client.celery.send_task(
'compass.tasks.poweron_host',
(host_id,)
)
return {
'status': 'poweron %s action sent' % host.name,
'host': host
}
@utils.supported_filters(optional_support_keys=['poweroff'])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEPLOY_HOST
)
@utils.wrap_to_dict(
RESP_DEPLOY_FIELDS,
host=RESP_CONFIG_FIELDS
)
def poweroff_host(
session, deployer, host_id, poweroff={}, **kwargs
):
"""power off host."""
from compass.tasks import client as celery_client
host = utils.get_db_object(
session, models.host, id=host_id
)
is_host_validated(session, host)
celery_client.celery.send_task(
'compass.tasks.poweroff_host',
(host_id,)
)
return {
'status': 'poweroff %s action sent' % host.name,
'host': host
}
@utils.supported_filters(optional_support_keys=['reset'])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_DEPLOY_HOST
)
@utils.wrap_to_dict(
RESP_DEPLOY_FIELDS,
host=RESP_CONFIG_FIELDS
)
def reset_host(
session, deployer, host_id, reset={}, **kwargs
):
"""reset host."""
from compass.tasks import client as celery_client
host = utils.get_db_object(
session, models.host, id=host_id
)
is_host_validated(session, host)
celery_client.celery.send_task(
'compass.tasks.reset_host',
(host_id,)
)
return {
'status': 'reset %s action sent' % host.name,
'host': host
}

View File

@ -26,7 +26,7 @@ from compass.utils import setting_wrapper as setting
from compass.utils import util from compass.utils import util
SUPPORTED_FIELDS = ['mac', 'tag'] SUPPORTED_FIELDS = ['mac', 'tag', 'location']
UPDATED_FIELDS = ['ipmi_credentials', 'tag', 'location'] UPDATED_FIELDS = ['ipmi_credentials', 'tag', 'location']
PATCHED_FIELDS = [ PATCHED_FIELDS = [
'patched_ipmi_credentials', 'patched_tag', 'patched_ipmi_credentials', 'patched_tag',

View File

@ -45,10 +45,9 @@ def add_os_field_internal(session):
setting.OS_FIELD_DIR, setting.OS_FIELD_DIR,
env_locals=validator.VALIDATOR_LOCALS env_locals=validator.VALIDATOR_LOCALS
) )
with session.begin(subtransactions=True): return _add_field_internal(
return _add_field_internal( session, models.OSConfigField, configs
session, models.OSConfigField, configs )
)
def add_package_field_internal(session): def add_package_field_internal(session):
@ -56,46 +55,46 @@ def add_package_field_internal(session):
setting.PACKAGE_FIELD_DIR, setting.PACKAGE_FIELD_DIR,
env_locals=validator.VALIDATOR_LOCALS env_locals=validator.VALIDATOR_LOCALS
) )
with session.begin(subtransactions=True): return _add_field_internal(
return _add_field_internal( session, models.PackageConfigField, configs
session, models.PackageConfigField, configs )
)
def _add_metadata( def _add_metadata(
session, field_model, metadata_model, name, config, session, field_model, metadata_model, name, config,
parent=None, adapter=None parent=None, **kwargs
): ):
metadata = config.get('_self', {}) metadata_self = config.get('_self', {})
if 'field' in metadata: if 'field' in metadata_self:
field = utils.get_db_object( field = utils.get_db_object(
session, field_model, field=metadata['field'] session, field_model, field=metadata_self['field']
) )
else: else:
field = None field = None
object = utils.add_db_object( metadata = utils.add_db_object(
session, metadata_model, True, session, metadata_model, True,
name, adapter=adapter, parent=parent, field=field, name, parent=parent, field=field,
display_name=metadata.get('display_name', name), display_name=metadata_self.get('display_name', name),
description=metadata.get('description', None), description=metadata_self.get('description', None),
is_required=metadata.get('is_required', False), is_required=metadata_self.get('is_required', False),
required_in_whole_config=metadata.get( required_in_whole_config=metadata_self.get(
'required_in_whole_config', False 'required_in_whole_config', False
), ),
mapping_to=metadata.get('mapping_to', None), mapping_to=metadata_self.get('mapping_to', None),
validator=metadata.get('validator', None), validator=metadata_self.get('validator', None),
js_validator=metadata.get('js_validator', None), js_validator=metadata_self.get('js_validator', None),
default_value=metadata.get('default_value', None), default_value=metadata_self.get('default_value', None),
options=metadata.get('options', []), options=metadata_self.get('options', []),
required_in_options=metadata.get('required_in_options', False) required_in_options=metadata_self.get('required_in_options', False),
**kwargs
) )
for key, value in config.items(): for key, value in config.items():
if key not in '_self': if key not in '_self':
_add_metadata( _add_metadata(
session, field_model, metadata_model, key, value, session, field_model, metadata_model, key, value,
parent=object, adapter=adapter, parent=metadata, **kwargs
) )
return object return metadata
def add_os_metadata_internal(session): def add_os_metadata_internal(session):
@ -104,19 +103,18 @@ def add_os_metadata_internal(session):
setting.OS_METADATA_DIR, setting.OS_METADATA_DIR,
env_locals=validator.VALIDATOR_LOCALS env_locals=validator.VALIDATOR_LOCALS
) )
with session.begin(subtransactions=True): for config in configs:
for config in configs: os = utils.get_db_object(
adapter = utils.get_db_object( session, models.OperatingSystem, name=config['OS']
session, models.OSAdapter, name=config['ADAPTER'] )
) for key, value in config['METADATA'].items():
for key, value in config['METADATA'].items(): os_metadatas.append(_add_metadata(
os_metadatas.append(_add_metadata( session, models.OSConfigField,
session, models.OSConfigField, models.OSConfigMetadata,
models.OSConfigMetadata, key, value, parent=None,
key, value, parent=None, os=os
adapter=adapter ))
)) return os_metadatas
return os_metadatas
def add_package_metadata_internal(session): def add_package_metadata_internal(session):
@ -125,31 +123,52 @@ def add_package_metadata_internal(session):
setting.PACKAGE_METADATA_DIR, setting.PACKAGE_METADATA_DIR,
env_locals=validator.VALIDATOR_LOCALS env_locals=validator.VALIDATOR_LOCALS
) )
with session.begin(subtransactions=True): for config in configs:
for config in configs: adapter = utils.get_db_object(
adapter = utils.get_db_object( session, models.Adapter, name=config['ADAPTER']
session, models.PackageAdapter, name=config['ADAPTER']
)
for key, value in config['METADATA'].items():
package_metadatas.append(_add_metadata(
session, models.PackageConfigField,
models.PackageConfigMetadata,
key, value, parent=None,
adapter=adapter
))
return package_metadatas
def get_metadatas_internal(session):
metadata_mapping = {}
with session.begin(subtransactions=True):
adapters = utils.list_db_objects(
session, models.Adapter
) )
for adapter in adapters: for key, value in config['METADATA'].items():
package_metadatas.append(_add_metadata(
session, models.PackageConfigField,
models.PackageConfigMetadata,
key, value, parent=None,
adapter=adapter
))
return package_metadatas
def get_package_metadatas_internal(session):
metadata_mapping = {}
adapters = utils.list_db_objects(
session, models.Adapter
)
for adapter in adapters:
if adapter.deployable:
metadata_dict = adapter.metadata_dict() metadata_dict = adapter.metadata_dict()
metadata_mapping[adapter.id] = metadata_dict metadata_mapping[adapter.id] = metadata_dict
return metadata_mapping else:
logging.info(
'ignore metadata since its adapter %s is not deployable',
adapter.id
)
return metadata_mapping
def get_os_metadatas_internal(session):
metadata_mapping = {}
oses = utils.list_db_objects(
session, models.OperatingSystem
)
for os in oses:
if os.deployable:
metadata_dict = os.metadata_dict()
metadata_mapping[os.id] = metadata_dict
else:
logging.info(
'ignore metadata since its os %s is not deployable',
os.id
)
return metadata_mapping
def _validate_self( def _validate_self(

View File

@ -25,41 +25,43 @@ from compass.db import exception
@database.run_in_session() @database.run_in_session()
def load_metadatas(session): def load_metadatas(session):
global METADATA_MAPPING global OS_METADATA_MAPPING
global PACKAGE_METADATA_MAPPING
logging.info('load metadatas into memory') logging.info('load metadatas into memory')
METADATA_MAPPING = metadata_api.get_metadatas_internal(session) OS_METADATA_MAPPING = metadata_api.get_os_metadatas_internal(session)
PACKAGE_METADATA_MAPPING = (
metadata_api.get_package_metadatas_internal(session)
METADATA_MAPPING = {}
def _validate_config(
config, adapter_id,
metadata_mapping, metadata_field, whole_check
):
if adapter_id not in metadata_mapping:
raise exception.InvalidParameter(
'adapter id %s is not found in metadata mapping' % adapter_id
)
metadatas = metadata_mapping[adapter_id]
if metadata_field not in metadatas:
return
metadata_api.validate_config_internal(
config, metadatas[metadata_field], whole_check
) )
def validate_os_config(config, adapter_id, whole_check=False): OS_METADATA_MAPPING = {}
PACKAGE_METADATA_MAPPING = {}
def _validate_config(
config, id, metadata_mapping, whole_check
):
if id not in metadata_mapping:
raise exception.InvalidParameter(
'adapter id %s is not found in metadata mapping' % id
)
metadatas = metadata_mapping[id]
metadata_api.validate_config_internal(
config, metadatas, whole_check
)
def validate_os_config(config, os_id, whole_check=False):
_validate_config( _validate_config(
config, adapter_id, METADATA_MAPPING, 'os_config', config, os_id, OS_METADATA_MAPPING,
whole_check whole_check
) )
def validate_package_config(config, adapter_id, whole_check=False): def validate_package_config(config, adapter_id, whole_check=False):
_validate_config( _validate_config(
config, adapter_id, METADATA_MAPPING, config, adapter_id, PACKAGE_METADATA_MAPPING,
'package_config', whole_check whole_check
) )
@ -85,15 +87,38 @@ def _filter_metadata(metadata):
return filtered_metadata return filtered_metadata
def get_package_metadata_internal(adapter_id):
"""get package metadata internal."""
if adapter_id not in PACKAGE_METADATA_MAPPING:
raise exception.RecordNotExists(
'adpater %s does not exist' % adapter_id
)
return _filter_metadata(PACKAGE_METADATA_MAPPING[adapter_id])
@utils.supported_filters([]) @utils.supported_filters([])
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_METADATAS permission.PERMISSION_LIST_METADATAS
) )
def get_metadata(session, getter, adapter_id, **kwargs): def get_package_metadata(session, getter, adapter_id, **kwargs):
"""get adapter.""" return get_package_metadata_internal(adapter_id)
if adapter_id not in METADATA_MAPPING:
def get_os_metadata_internal(os_id):
"""get os metadata internal."""
if os_id not in OS_METADATA_MAPPING:
raise exception.RecordNotExists( raise exception.RecordNotExists(
'adpater %s does not exist' % adapter_id 'os %s does not exist' % os_id
) )
return _filter_metadata(METADATA_MAPPING[adapter_id]) return _filter_metadata(OS_METADATA_MAPPING[os_id])
@utils.supported_filters([])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_METADATAS
)
def get_os_metadata(session, getter, os_id, **kwargs):
"""get os metadatas."""
return get_os_metadata_internal(os_id)

View File

@ -24,10 +24,19 @@ from compass.db import exception
from compass.db import models from compass.db import models
SUPPORTED_FIELDS = ['subnet'] SUPPORTED_FIELDS = ['subnet', 'name']
RESP_FIELDS = ['id', 'subnet', 'created_at', 'updated_at'] RESP_FIELDS = [
'id', 'name', 'subnet', 'created_at', 'updated_at'
]
ADDED_FIELDS = ['subnet'] ADDED_FIELDS = ['subnet']
UPDATED_FIELDS = ['subnet'] OPTIONAL_ADDED_FIELDS = ['name']
IGNORE_ADDED_FIELDS = [
'id', 'created_at', 'updated_at'
]
UPDATED_FIELDS = ['subnet', 'name']
IGNORE_UPDATED_FIELDS = [
'id', 'created_at', 'updated_at'
]
def _check_subnet(subnet): def _check_subnet(subnet):
@ -65,7 +74,10 @@ def get_subnet(session, getter, subnet_id, **kwargs):
) )
@utils.supported_filters(ADDED_FIELDS) @utils.supported_filters(
ADDED_FIELDS, optional_support_keys=OPTIONAL_ADDED_FIELDS,
ignore_support_keys=IGNORE_ADDED_FIELDS
)
@utils.input_validates(subnet=_check_subnet) @utils.input_validates(subnet=_check_subnet)
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
@ -75,11 +87,14 @@ def get_subnet(session, getter, subnet_id, **kwargs):
def add_subnet(session, creator, subnet, **kwargs): def add_subnet(session, creator, subnet, **kwargs):
"""Create a subnet.""" """Create a subnet."""
return utils.add_db_object( return utils.add_db_object(
session, models.Network, True, subnet session, models.Network, True, subnet, **kwargs
) )
@utils.supported_filters(UPDATED_FIELDS) @utils.supported_filters(
optional_support_keys=UPDATED_FIELDS,
ignore_support_keys=IGNORE_UPDATED_FIELDS
)
@utils.input_validates(subnet=_check_subnet) @utils.input_validates(subnet=_check_subnet)
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(

View File

@ -130,6 +130,9 @@ PERMISSION_REVIEW_CLUSTER = PermissionWrapper(
PERMISSION_DEPLOY_CLUSTER = PermissionWrapper( PERMISSION_DEPLOY_CLUSTER = PermissionWrapper(
'deploy_cluster', 'deploy cluster', 'deploy cluster' 'deploy_cluster', 'deploy cluster', 'deploy cluster'
) )
PERMISSION_DEPLOY_HOST = PermissionWrapper(
'deploy_host', 'deploy host', 'deploy host'
)
PERMISSION_GET_CLUSTER_STATE = PermissionWrapper( PERMISSION_GET_CLUSTER_STATE = PermissionWrapper(
'get_cluster_state', 'get cluster state', 'get cluster state' 'get_cluster_state', 'get cluster state', 'get cluster state'
) )
@ -243,6 +246,7 @@ PERMISSIONS = [
PERMISSION_DEL_HOST_NETWORK, PERMISSION_DEL_HOST_NETWORK,
PERMISSION_GET_HOST_STATE, PERMISSION_GET_HOST_STATE,
PERMISSION_UPDATE_HOST_STATE, PERMISSION_UPDATE_HOST_STATE,
PERMISSION_DEPLOY_HOST,
PERMISSION_LIST_CLUSTERHOSTS, PERMISSION_LIST_CLUSTERHOSTS,
PERMISSION_LIST_CLUSTERHOST_CONFIG, PERMISSION_LIST_CLUSTERHOST_CONFIG,
PERMISSION_ADD_CLUSTERHOST_CONFIG, PERMISSION_ADD_CLUSTERHOST_CONFIG,

View File

@ -28,8 +28,20 @@ from compass.utils import setting_wrapper as setting
SUPPORTED_FIELDS = ['ip_int', 'vendor', 'state'] SUPPORTED_FIELDS = ['ip_int', 'vendor', 'state']
SUPPORTED_FILTER_FIELDS = ['ip_int', 'vendor', 'state'] SUPPORTED_FILTER_FIELDS = ['ip_int', 'vendor', 'state']
SUPPORTED_SWITCH_MACHINES_FIELDS = ['ip_int', 'port', 'vlans', 'mac', 'tag'] SUPPORTED_SWITCH_MACHINES_FIELDS = [
SUPPORTED_MACHINES_FIELDS = ['port', 'vlans', 'mac', 'tag'] 'switch_ip_int', 'port', 'vlans', 'mac', 'tag', 'location'
]
SUPPORTED_MACHINES_FIELDS = [
'port', 'vlans', 'mac', 'tag', 'location'
]
SUPPORTED_SWITCH_MACHINES_HOSTS_FIELDS = [
'switch_ip_int', 'port', 'vlans', 'mac',
'tag', 'location', 'os_name', 'os_id'
]
SUPPORTED_MACHINES_HOSTS_FIELDS = [
'port', 'vlans', 'mac', 'tag', 'location',
'os_name', 'os_id'
]
ADDED_FIELDS = ['ip'] ADDED_FIELDS = ['ip']
OPTIONAL_ADDED_FIELDS = ['credentials', 'vendor', 'state', 'err_msg'] OPTIONAL_ADDED_FIELDS = ['credentials', 'vendor', 'state', 'err_msg']
UPDATED_FIELDS = ['credentials', 'vendor', 'state', 'err_msg'] UPDATED_FIELDS = ['credentials', 'vendor', 'state', 'err_msg']
@ -67,10 +79,15 @@ RESP_ACTION_FIELDS = [
'status', 'details' 'status', 'details'
] ]
RESP_MACHINES_FIELDS = [ RESP_MACHINES_FIELDS = [
'id', 'switch_id', 'machine_id', 'port', 'vlans', 'mac', 'id', 'switch_id', 'switch_ip', 'machine_id', 'port', 'vlans', 'mac',
'ipmi_credentials', 'tag', 'location', 'ipmi_credentials', 'tag', 'location',
'created_at', 'updated_at' 'created_at', 'updated_at'
] ]
RESP_MACHINES_HOSTS_FIELDS = [
'id', 'switch_id', 'switch_ip', 'machine_id', 'port', 'vlans', 'mac',
'ipmi_credentials', 'tag', 'location',
'name', 'os_name', 'clusters'
]
def _check_credentials_version(version): def _check_credentials_version(version):
@ -354,10 +371,9 @@ def filter_machine_internal(filters, port):
def get_switch_machines_internal(session, **filters): def get_switch_machines_internal(session, **filters):
with session.begin(subtransactions=True): return utils.list_db_objects(
return utils.list_db_objects( session, models.SwitchMachine, **filters
session, models.SwitchMachine, **filters )
)
def _filter_port(port_filter, obj): def _filter_port(port_filter, obj):
@ -411,9 +427,13 @@ def _filter_vlans(vlan_filter, obj):
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_SWITCH_MACHINES permission.PERMISSION_LIST_SWITCH_MACHINES
) )
@utils.output_filters(port=_filter_port, vlans=_filter_vlans) @utils.output_filters(
port=_filter_port, vlans=_filter_vlans,
tag=utils.general_filter_callback,
location=utils.general_filter_callback
)
@utils.wrap_to_dict(RESP_MACHINES_FIELDS) @utils.wrap_to_dict(RESP_MACHINES_FIELDS)
def _list_switch_machines(session, user, switch_machines): def _list_switch_machines(session, user, switch_machines, **filters):
return [ return [
switch_machine for switch_machine in switch_machines switch_machine for switch_machine in switch_machines
if filter_machine_internal( if filter_machine_internal(
@ -423,14 +443,59 @@ def _list_switch_machines(session, user, switch_machines):
] ]
@utils.supported_filters(optional_support_keys=SUPPORTED_MACHINES_FIELDS) @user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_SWITCH_MACHINES
)
@utils.output_filters(
missing_ok=True,
port=_filter_port, vlans=_filter_vlans,
tag=utils.general_filter_callback,
location=utils.general_filter_callback,
os_name=utils.general_filter_callback,
os_id=utils.general_filter_callback
)
@utils.wrap_to_dict(RESP_MACHINES_HOSTS_FIELDS)
def _list_switch_machines_hosts(session, user, switch_machines, **filters):
filtered_switch_machines = [
switch_machine for switch_machine in switch_machines
if filter_machine_internal(
switch_machine.switch.filters,
switch_machine.port
)
]
switch_machines_hosts = []
for switch_machine in filtered_switch_machines:
switch_machine_host_dict = {}
machine = switch_machine.machine
host = machine.host
if host:
clusters = [
clusterhost.cluster
for clusterhost in host.clusterhosts
]
switch_machine_host_dict.update(
host.to_dict()
)
switch_machine_host_dict['clusters'] = [
cluster.to_dict() for cluster in clusters
]
switch_machine_host_dict.update(
switch_machine.to_dict()
)
switch_machines_hosts.append(switch_machine_host_dict)
return switch_machines_hosts
@utils.supported_filters(
optional_support_keys=SUPPORTED_MACHINES_FIELDS
)
@database.run_in_session() @database.run_in_session()
def list_switch_machines(session, getter, switch_id, **filters): def list_switch_machines(session, getter, switch_id, **filters):
"""Get switch machines.""" """Get switch machines."""
switch_machines = get_switch_machines_internal( switch_machines, host_filters = get_switch_machines_internal(
session, switch_id=switch_id, **filters session, switch_id=switch_id, **filters
) )
return _list_switch_machines(session, getter, switch_machines) return _list_switch_machines(session, getter, switch_machines, **filters)
@utils.supported_filters( @utils.supported_filters(
@ -442,7 +507,35 @@ def list_switchmachines(session, lister, **filters):
switch_machines = get_switch_machines_internal( switch_machines = get_switch_machines_internal(
session, **filters session, **filters
) )
return _list_switch_machines(session, lister, switch_machines) return _list_switch_machines(session, lister, switch_machines, **filters)
@utils.supported_filters(
optional_support_keys=SUPPORTED_MACHINES_HOSTS_FIELDS
)
@database.run_in_session()
def list_switch_machines_hosts(session, getter, switch_id, **filters):
"""Get switch machines hosts."""
switch_machines = get_switch_machines_internal(
session, switch_id=switch_id, **filters
)
return _list_switch_machines_hosts(
session, getter, switch_machines, **filters
)
@utils.supported_filters(
optional_support_keys=SUPPORTED_SWITCH_MACHINES_HOSTS_FIELDS
)
@database.run_in_session()
def list_switchmachines_hosts(session, lister, **filters):
"""List switch machines hosts."""
switch_machines = get_switch_machines_internal(
session, **filters
)
return _list_switch_machines_hosts(
session, lister, switch_machines, **filters
)
def add_switch_machines_internal( def add_switch_machines_internal(
@ -505,7 +598,7 @@ def add_switch_machine(session, creator, switch_id, mac, **kwargs):
return switch_machines[0] return switch_machines[0]
@utils.supported_filters() @utils.supported_filters(optional_support_keys=['find_machines'])
@database.run_in_session() @database.run_in_session()
@user_api.check_user_permission_in_session( @user_api.check_user_permission_in_session(
permission.PERMISSION_UPDATE_SWITCH_MACHINES permission.PERMISSION_UPDATE_SWITCH_MACHINES
@ -520,7 +613,7 @@ def poll_switch_machines(session, poller, switch_id, **kwargs):
(switch.ip, switch.credentials) (switch.ip, switch.credentials)
) )
return { return {
'status': 'find_machines action sent', 'status': 'action %s sent' % kwargs,
'details': { 'details': {
} }
} }

View File

@ -218,9 +218,14 @@ class UserWrapper(UserMixin):
@database.run_in_session() @database.run_in_session()
def get_user_object(session, email, **kwargs): def get_user_object(session, email, **kwargs):
user_dict = utils.get_db_object( user = utils.get_db_object(
session, models.User, email=email session, models.User, False, email=email
).to_dict() )
if not user:
raise exception.Unauthorized(
'%s unauthorized' % email
)
user_dict = user.to_dict()
user_dict.update(kwargs) user_dict.update(kwargs)
return UserWrapper(**user_dict) return UserWrapper(**user_dict)
@ -231,9 +236,13 @@ def get_user_object_from_token(session, token):
'ge': datetime.datetime.now() 'ge': datetime.datetime.now()
} }
user_token = utils.get_db_object( user_token = utils.get_db_object(
session, models.UserToken, session, models.UserToken, False,
token=token, expire_timestamp=expire_timestamp token=token, expire_timestamp=expire_timestamp
) )
if not user_token:
raise exception.Forbidden(
'invalid user token: %s' % token
)
user_dict = utils.get_db_object( user_dict = utils.get_db_object(
session, models.User, id=user_token.user_id session, models.User, id=user_token.user_id
).to_dict() ).to_dict()

View File

@ -81,7 +81,10 @@ def _between_condition(col_attr, value):
def model_filter(query, model, **filters): def model_filter(query, model, **filters):
for key, value in filters.items(): for key, value in filters.items():
col_attr = getattr(model, key) if hasattr(model, key):
col_attr = getattr(model, key)
else:
continue
if isinstance(value, list): if isinstance(value, list):
query = query.filter(col_attr.in_(value)) query = query.filter(col_attr.in_(value))
elif isinstance(value, dict): elif isinstance(value, dict):
@ -148,19 +151,24 @@ def model_filter(query, model, **filters):
return query return query
def wrap_to_dict(support_keys=[]): def wrap_to_dict(support_keys=[], **filters):
def decorator(func): def decorator(func):
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
return _wrapper_dict(func(*args, **kwargs), support_keys) return _wrapper_dict(
func(*args, **kwargs), support_keys, **filters
)
return wrapper return wrapper
return decorator return decorator
def _wrapper_dict(data, support_keys): def _wrapper_dict(data, support_keys, **filters):
"""Helper for warpping db object into dictionary.""" """Helper for warpping db object into dictionary."""
if isinstance(data, list): if isinstance(data, list):
return [_wrapper_dict(item, support_keys) for item in data] return [
_wrapper_dict(item, support_keys, **filters)
for item in data
]
if isinstance(data, models.HelperMixin): if isinstance(data, models.HelperMixin):
data = data.to_dict() data = data.to_dict()
if not isinstance(data, dict): if not isinstance(data, dict):
@ -170,18 +178,27 @@ def _wrapper_dict(data, support_keys):
info = {} info = {}
for key in support_keys: for key in support_keys:
if key in data: if key in data:
info[key] = data[key] if key in filters:
info[key] = _wrapper_dict(data[key], filters[key])
else:
info[key] = data[key]
return info return info
def supported_filters(support_keys=[], optional_support_keys=[]): def supported_filters(
support_keys=[],
optional_support_keys=[],
ignore_support_keys=[]
):
def decorator(func): def decorator(func):
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **filters): def wrapper(*args, **filters):
must_support_keys = set(support_keys) must_support_keys = set(support_keys)
all_support_keys = must_support_keys | set(optional_support_keys) all_support_keys = must_support_keys | set(optional_support_keys)
filter_keys = set(filters) filter_keys = set(filters)
unsupported_keys = filter_keys - all_support_keys unsupported_keys = (
filter_keys - all_support_keys - set(ignore_support_keys)
)
if unsupported_keys: if unsupported_keys:
raise exception.InvalidParameter( raise exception.InvalidParameter(
'filter keys %s are not supported' % str( 'filter keys %s are not supported' % str(
@ -195,7 +212,12 @@ def supported_filters(support_keys=[], optional_support_keys=[]):
list(missing_keys) list(missing_keys)
) )
) )
return func(*args, **filters) filtered_filters = dict([
(key, value)
for key, value in filters.items()
if key not in ignore_support_keys
])
return func(*args, **filtered_filters)
return wrapper return wrapper
return decorator return decorator
@ -252,14 +274,17 @@ def general_filter_callback(general_filter, obj):
return True return True
def filter_output(filter_callbacks, filters, obj): def filter_output(filter_callbacks, filters, obj, missing_ok=False):
for callback_key, callback_value in filter_callbacks.items(): for callback_key, callback_value in filter_callbacks.items():
if callback_key not in filters: if callback_key not in filters:
continue continue
if callback_key not in obj: if callback_key not in obj:
raise exception.InvalidResponse( if missing_ok:
'%s is not in %s' % (callback_key, obj) continue
) else:
raise exception.InvalidResponse(
'%s is not in %s' % (callback_key, obj)
)
if not callback_value( if not callback_value(
filters[callback_key], obj[callback_key] filters[callback_key], obj[callback_key]
): ):
@ -267,14 +292,16 @@ def filter_output(filter_callbacks, filters, obj):
return True return True
def output_filters(**filter_callbacks): def output_filters(missing_ok=False, **filter_callbacks):
def decorator(func): def decorator(func):
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **filters): def wrapper(*args, **filters):
filtered_obj_list = [] filtered_obj_list = []
obj_list = func(*args, **filters) obj_list = func(*args, **filters)
for obj in obj_list: for obj in obj_list:
if filter_output(filter_callbacks, filters, obj): if filter_output(
filter_callbacks, filters, obj, missing_ok
):
filtered_obj_list.append(obj) filtered_obj_list.append(obj)
return filtered_obj_list return filtered_obj_list
return wrapper return wrapper
@ -430,7 +457,7 @@ def del_db_objects(session, table, **filters):
model_query(session, table), table, **filters model_query(session, table), table, **filters
) )
db_objects = query.all() db_objects = query.all()
query.delete() query.delete(synchronize_session=False)
return db_objects return db_objects

View File

@ -108,10 +108,6 @@ class MetadataMixin(HelperMixin):
super(MetadataMixin, self).initialize() super(MetadataMixin, self).initialize()
def validate(self): def validate(self):
if not self.adapter:
raise exception.InvalidParameter(
'adapter is not set in os metadata %s' % self.id
)
super(MetadataMixin, self).validate() super(MetadataMixin, self).validate()
@property @property
@ -252,67 +248,6 @@ class FieldMixin(HelperMixin):
return dict_info return dict_info
class AdapterMixin(HelperMixin):
name = Column(String(80), unique=True)
@property
def root_metadatas(self):
return [
metadata for metadata in self.metadatas
if metadata.parent_id is None
]
@property
def adapter_installer(self):
if self.installer:
return self.installer
elif self.parent:
return self.parent.adapter_installer
else:
return None
@property
def installer_name(self):
installer = self.adapter_installer
if installer:
return installer.name
else:
return ''
@property
def installer_type(self):
installer = self.adapter_installer
if installer:
return installer.installer_type
else:
return None
@property
def installer_config(self):
installer = self.adapter_installer
if installer:
return installer.config
else:
return None
def metadata_dict(self):
dict_info = {}
if self.parent:
dict_info.update(self.parent.metadata_dict())
for metadata in self.root_metadatas:
dict_info.update(metadata.to_dict())
return dict_info
def to_dict(self):
dict_info = super(AdapterMixin, self).to_dict()
dict_info.update({
'installer_name': self.installer_name,
'installer_type': self.installer_type,
'installer_config': self.installer_config
})
return dict_info
class InstallerMixin(HelperMixin): class InstallerMixin(HelperMixin):
name = Column(String(80), unique=True) name = Column(String(80), unique=True)
installer_type = Column(String(80)) installer_type = Column(String(80))
@ -611,15 +546,12 @@ class Host(BASE, TimestampMixin, HelperMixin):
__tablename__ = 'host' __tablename__ = 'host'
name = Column(String(80), unique=True) name = Column(String(80), unique=True)
adapter_id = Column(Integer, ForeignKey('os_adapter.id')) os_id = Column(Integer, ForeignKey('os.id'))
config_step = Column(String(80), default='') config_step = Column(String(80), default='')
os_config = Column(JSONEncoded, default={}) os_config = Column(JSONEncoded, default={})
config_validated = Column(Boolean, default=False) config_validated = Column(Boolean, default=False)
deployed_os_config = Column(JSONEncoded, default={}) deployed_os_config = Column(JSONEncoded, default={})
os_id = Column( os_name = Column(String(80))
Integer,
ForeignKey('os.id')
)
creator_id = Column(Integer, ForeignKey('user.id')) creator_id = Column(Integer, ForeignKey('user.id'))
id = Column( id = Column(
Integer, Integer,
@ -686,32 +618,23 @@ class Host(BASE, TimestampMixin, HelperMixin):
super(Host, self).initialize() super(Host, self).initialize()
def validate(self): def validate(self):
adapter = self.adapter os = self.os
if not adapter: if not os:
raise exception.InvalidParameter( raise exception.InvalidParameter(
'adapter is not set in host %s' % self.id 'os is not set in host %s' % self.id
) )
if not self.os: if not os.deployable:
if adapter: raise exception.InvalidParameter(
self.os = adapter.adapter_os 'os %s is not deployable' % os.name
else: )
raise exception.InvalidParameter( self.os_name = os.name
'os is not set in host %s' % self.id creator = self.creator
) if not creator:
if not self.creator:
raise exception.InvalidParameter( raise exception.InvalidParameter(
'creator is not set in host %s' % self.id 'creator is not set in host %s' % self.id
) )
super(Host, self).validate() super(Host, self).validate()
@hybrid_property
def os_name(self):
os = self.os
if os:
return os.name
else:
return None
@hybrid_property @hybrid_property
def owner(self): def owner(self):
creator = self.creator creator = self.creator
@ -739,9 +662,12 @@ class Host(BASE, TimestampMixin, HelperMixin):
dict_info = self.machine.to_dict() dict_info = self.machine.to_dict()
dict_info.update(super(Host, self).to_dict()) dict_info.update(super(Host, self).to_dict())
dict_info.update({ dict_info.update({
'os_name': self.os_name,
'owner': self.owner, 'owner': self.owner,
'os_installed': self.os_installed, 'os_installed': self.os_installed,
'networks': [
host_network.to_dict()
for host_network in self.host_networks
]
}) })
return dict_info return dict_info
@ -810,14 +736,19 @@ class Cluster(BASE, TimestampMixin, HelperMixin):
reinstall_distributed_system = Column(Boolean, default=True) reinstall_distributed_system = Column(Boolean, default=True)
config_step = Column(String(80), default='') config_step = Column(String(80), default='')
os_id = Column(Integer, ForeignKey('os.id'), nullable=True) os_id = Column(Integer, ForeignKey('os.id'), nullable=True)
os_name = Column(String(80), nullable=True)
distributed_system_id = Column( distributed_system_id = Column(
Integer, ForeignKey('distributed_system.id'), Integer, ForeignKey('distributed_system.id'),
nullable=True nullable=True
) )
distributed_system_name = Column(
String(80), nullable=True
)
os_config = Column(JSONEncoded, default={}) os_config = Column(JSONEncoded, default={})
package_config = Column(JSONEncoded, default={}) package_config = Column(JSONEncoded, default={})
config_validated = Column(Boolean, default=False) config_validated = Column(Boolean, default=False)
adapter_id = Column(Integer, ForeignKey('adapter.id')) adapter_id = Column(Integer, ForeignKey('adapter.id'))
adapter_name = Column(String(80), nullable=True)
creator_id = Column(Integer, ForeignKey('user.id')) creator_id = Column(Integer, ForeignKey('user.id'))
clusterhosts = relationship( clusterhosts = relationship(
ClusterHost, ClusterHost,
@ -843,31 +774,52 @@ class Cluster(BASE, TimestampMixin, HelperMixin):
super(Cluster, self).initialize() super(Cluster, self).initialize()
def validate(self): def validate(self):
adapter = self.adapter
if not adapter:
raise exception.InvalidParameter(
'adapter is not set in cluster %s' % self.id
)
creator = self.creator creator = self.creator
if not creator: if not creator:
raise exception.InvalidParameter( raise exception.InvalidParameter(
'creator is not set in cluster %s' % self.id 'creator is not set in cluster %s' % self.id
) )
os = self.os os = self.os
if not os: if os:
os_adapter = adapter.os_adapter if not os.deployable:
if os_adapter: raise exception.InvalidParameter(
self.os = os_adapter.adapter_os 'os %s is not deployable' % os.name
else:
self.os = None
if not self.distributed_system:
package_adapter = adapter.package_adapter
if package_adapter:
self.distributed_system = (
package_adapter.adapter_distributed_system
) )
else: self.os_name = os.name
self.distributed_system = None else:
self.os_name = None
adapter = self.adapter
if adapter:
if not adapter.deployable:
raise exception.InvalidParameter(
'adapter %s is not deployable' % adapter.name
)
supported_os_ids = [
adapter_os.os.id for adapter_os in adapter.supported_oses
]
if os and os.id not in supported_os_ids:
raise exception.InvalidParameter(
'os %s is not supported' % os.name
)
self.adapter_name = adapter.name
distributed_system = (
adapter.adapter_distributed_system
)
self.distributed_system = distributed_system
if distributed_system:
if not distributed_system.deployable:
raise exception.InvalidParamerter(
'distributed system %s is not deployable' % (
distributed_system.name
)
)
self.distributed_system_name = (
distributed_system.name
)
else:
self.adapter_name = None
self.distributed_system = None
self.distributed_system_name = None
super(Cluster, self).validate() super(Cluster, self).validate()
@property @property
@ -914,22 +866,6 @@ class Cluster(BASE, TimestampMixin, HelperMixin):
else: else:
return None return None
@hybrid_property
def os_name(self):
os = self.os
if os:
return os.name
else:
return None
@hybrid_property
def distributed_system_name(self):
distributed_system = self.distributed_system
if distributed_system:
return distributed_system.name
else:
return None
@property @property
def distributed_system_installed(self): def distributed_system_installed(self):
state = self.state state = self.state
@ -948,8 +884,6 @@ class Cluster(BASE, TimestampMixin, HelperMixin):
def to_dict(self): def to_dict(self):
dict_info = super(Cluster, self).to_dict() dict_info = super(Cluster, self).to_dict()
dict_info.update({ dict_info.update({
'os_name': self.os_name,
'distributed_system_name': self.distributed_system_name,
'distributed_system_installed': self.distributed_system_installed, 'distributed_system_installed': self.distributed_system_installed,
'owner': self.owner, 'owner': self.owner,
}) })
@ -1192,10 +1126,18 @@ class SwitchMachine(BASE, HelperMixin, TimestampMixin):
def switch_ip_int(self): def switch_ip_int(self):
return self.switch.ip_int return self.switch.ip_int
@switch_ip_int.expression
def switch_ip_int(cls):
return Switch.ip_int
@hybrid_property @hybrid_property
def switch_vendor(self): def switch_vendor(self):
return self.switch.vendor return self.switch.vendor
@switch_vendor.expression
def switch_vendor(cls):
return Switch.vendor
@property @property
def patched_vlans(self): def patched_vlans(self):
return self.vlans return self.vlans
@ -1213,6 +1155,7 @@ class SwitchMachine(BASE, HelperMixin, TimestampMixin):
def to_dict(self): def to_dict(self):
dict_info = self.machine.to_dict() dict_info = self.machine.to_dict()
dict_info.update(super(SwitchMachine, self).to_dict()) dict_info.update(super(SwitchMachine, self).to_dict())
dict_info['switch_ip'] = self.switch.ip
return dict_info return dict_info
@ -1348,70 +1291,15 @@ class Switch(BASE, HelperMixin, TimestampMixin):
return dict_info return dict_info
class Adapter(BASE, HelperMixin):
"""Adpater table."""
__tablename__ = 'adapter'
id = Column(Integer, primary_key=True)
package_adapter_id = Column(
Integer,
ForeignKey(
'package_adapter.id', onupdate='CASCADE', ondelete='CASCADE'
),
nullable=True
)
os_adapter_id = Column(
Integer,
ForeignKey(
'os_adapter.id', onupdate='CASCADE', ondelete='CASCADE'
),
nullable=True
)
__table_args__ = (
UniqueConstraint(
'package_adapter_id', 'os_adapter_id', name='constraint'
),
)
clusters = relationship(
Cluster,
backref=backref('adapter')
)
def __init__(self, os_adapter_id, package_adapter_id, **kwargs):
self.os_adapter_id = os_adapter_id
self.package_adapter_id = package_adapter_id
super(Adapter, self).__init__(**kwargs)
def metadata_dict(self):
dict_info = {}
if self.os_adapter:
dict_info['os_config'] = self.os_adapter.metadata_dict()
if self.package_adapter:
dict_info['package_config'] = self.package_adapter.metadata_dict()
return dict_info
def to_dict(self):
dict_info = super(Adapter, self).to_dict()
os_adapter = self.os_adapter
if os_adapter:
dict_info['os_adapter'] = os_adapter.to_dict()
package_adapter = self.package_adapter
if package_adapter:
dict_info['package_adapter'] = package_adapter.to_dict()
return dict_info
class OSConfigMetadata(BASE, MetadataMixin): class OSConfigMetadata(BASE, MetadataMixin):
"""OS config metadata.""" """OS config metadata."""
__tablename__ = "os_config_metadata" __tablename__ = "os_config_metadata"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
adapter_id = Column( os_id = Column(
Integer, Integer,
ForeignKey( ForeignKey(
'os_adapter.id', onupdate='CASCADE', ondelete='CASCADE' 'os.id', onupdate='CASCADE', ondelete='CASCADE'
) )
) )
parent_id = Column( parent_id = Column(
@ -1432,13 +1320,20 @@ class OSConfigMetadata(BASE, MetadataMixin):
backref=backref('parent', remote_side=id) backref=backref('parent', remote_side=id)
) )
__table_args__ = ( __table_args__ = (
UniqueConstraint('path', 'adapter_id', name='constraint'), UniqueConstraint('path', 'os_id', name='constraint'),
) )
def __init__(self, name, **kwargs): def __init__(self, name, **kwargs):
self.name = name self.name = name
super(OSConfigMetadata, self).__init__(**kwargs) super(OSConfigMetadata, self).__init__(**kwargs)
def validate(self):
if not self.os:
raise exception.InvalidParameter(
'os is not set in os metadata %s' % self.id
)
super(OSConfigMetadata, self).validate()
class OSConfigField(BASE, FieldMixin): class OSConfigField(BASE, FieldMixin):
"""OS config fields.""" """OS config fields."""
@ -1455,108 +1350,37 @@ class OSConfigField(BASE, FieldMixin):
super(OSConfigField, self).__init__(**kwargs) super(OSConfigField, self).__init__(**kwargs)
class OSAdapter(BASE, AdapterMixin): class AdapterOS(BASE, HelperMixin):
"""OS adpater table.""" """Adapter OS table."""
__tablename__ = 'os_adapter' __tablename__ = 'adapter_os'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
parent_id = Column(
Integer,
ForeignKey('os_adapter.id', onupdate='CASCADE', ondelete='CASCADE'),
nullable=True
)
os_id = Column( os_id = Column(
Integer, Integer,
ForeignKey('os.id', onupdate='CASCADE', ondelete='CASCADE'), ForeignKey(
nullable=True 'os.id',
onupdate='CASCADE', ondelete='CASCADE'
)
) )
installer_id = Column( adapter_id = Column(
Integer, Integer,
ForeignKey('os_installer.id', onupdate='CASCADE', ondelete='CASCADE'), ForeignKey(
nullable=True 'adapter.id',
) onupdate='CASCADE', ondelete='CASCADE'
children = relationship( )
'OSAdapter',
passive_deletes=True, passive_updates=True,
backref=backref('parent', remote_side=id)
)
adapters = relationship(
Adapter,
passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan',
backref=backref('os_adapter')
)
metadatas = relationship(
OSConfigMetadata,
passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan',
backref=backref('adapter')
)
hosts = relationship(
Host,
backref=backref('adapter')
) )
__table_args__ = ( def __init__(self, os_id, adapter_id, **kwargs):
UniqueConstraint('os_id', 'installer_id', name='constraint'), self.os_id = os_id
) self.adapter_id = adapter_id
super(AdapterOS, self).__init__(**kwargs)
def __init__(self, name, **kwargs):
self.name = name
super(OSAdapter, self).__init__(**kwargs)
@property
def deployable(self):
os = self.adapter_os
installer = self.adapter_installer
if (
os and os.deployable and installer
):
return True
else:
return False
@property
def adapter_os(self):
os = self.os
if os:
return os
parent = self.parent
if parent:
return parent.adapter_os
else:
return None
@property
def os_name(self):
os = self.adapter_os
if os:
return os.name
else:
return ''
def to_dict(self): def to_dict(self):
dict_info = super(OSAdapter, self).to_dict() dict_info = self.os.to_dict()
dict_info['os_name'] = self.os_name dict_info.update(super(AdapterOS, self).to_dict())
return dict_info return dict_info
class OSInstaller(BASE, InstallerMixin):
"""OS installer table."""
__tablename__ = 'os_installer'
id = Column(Integer, primary_key=True)
adpaters = relationship(
OSAdapter,
passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan',
backref=backref('installer')
)
def __init__(self, name, **kwargs):
self.name = name
super(OSInstaller, self).__init__(**kwargs)
class OperatingSystem(BASE, HelperMixin): class OperatingSystem(BASE, HelperMixin):
"""OS table.""" """OS table."""
__tablename__ = 'os' __tablename__ = 'os'
@ -1569,8 +1393,9 @@ class OperatingSystem(BASE, HelperMixin):
) )
name = Column(String(80), unique=True) name = Column(String(80), unique=True)
deployable = Column(Boolean, default=False) deployable = Column(Boolean, default=False)
adapters = relationship(
OSAdapter, metadatas = relationship(
OSConfigMetadata,
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan', cascade='all, delete-orphan',
backref=backref('os') backref=backref('os')
@ -1588,24 +1413,45 @@ class OperatingSystem(BASE, HelperMixin):
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
backref=backref('parent', remote_side=id) backref=backref('parent', remote_side=id)
) )
supported_adapters = relationship(
AdapterOS,
passive_deletes=True, passive_updates=True,
backref=backref('os')
)
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
super(OperatingSystem, self).__init__() super(OperatingSystem, self).__init__()
@property
def root_metadatas(self):
return [
metadata for metadata in self.metadatas
if metadata.parent_id is None
]
class PackageAdapterRole(BASE, HelperMixin): def metadata_dict(self):
dict_info = {}
if self.parent:
dict_info.update(self.parent.metadata_dict())
for metadata in self.root_metadatas:
dict_info.update(metadata.to_dict())
return dict_info
class AdapterRole(BASE, HelperMixin):
"""Adapter's roles.""" """Adapter's roles."""
__tablename__ = "package_adapter_role" __tablename__ = "adapter_role"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
name = Column(String(80)) name = Column(String(80))
display_name = Column(String(80))
description = Column(Text) description = Column(Text)
optional = Column(Boolean) optional = Column(Boolean)
adapter_id = Column( adapter_id = Column(
Integer, Integer,
ForeignKey( ForeignKey(
'package_adapter.id', 'adapter.id',
onupdate='CASCADE', onupdate='CASCADE',
ondelete='CASCADE' ondelete='CASCADE'
) )
@ -1618,7 +1464,13 @@ class PackageAdapterRole(BASE, HelperMixin):
def __init__(self, name, adapter_id, **kwargs): def __init__(self, name, adapter_id, **kwargs):
self.name = name self.name = name
self.adapter_id = adapter_id self.adapter_id = adapter_id
super(PackageAdapterRole, self).__init__(**kwargs) super(AdapterRole, self).__init__(**kwargs)
def initialize(self):
if not self.description:
self.description = self.name
if not self.display_name:
self.display_name = self.name
class PackageConfigMetadata(BASE, MetadataMixin): class PackageConfigMetadata(BASE, MetadataMixin):
@ -1629,7 +1481,7 @@ class PackageConfigMetadata(BASE, MetadataMixin):
adapter_id = Column( adapter_id = Column(
Integer, Integer,
ForeignKey( ForeignKey(
'package_adapter.id', 'adapter.id',
onupdate='CASCADE', ondelete='CASCADE' onupdate='CASCADE', ondelete='CASCADE'
) )
) )
@ -1663,6 +1515,13 @@ class PackageConfigMetadata(BASE, MetadataMixin):
self.name = name self.name = name
super(PackageConfigMetadata, self).__init__(**kwargs) super(PackageConfigMetadata, self).__init__(**kwargs)
def validate(self):
if not self.adapter:
raise exception.InvalidParameter(
'adapter is not set in package metadata %s' % self.id
)
super(PackageConfigMetadata, self).validate()
class PackageConfigField(BASE, FieldMixin): class PackageConfigField(BASE, FieldMixin):
"""Adapter cofig metadata fields.""" """Adapter cofig metadata fields."""
@ -1679,16 +1538,17 @@ class PackageConfigField(BASE, FieldMixin):
super(PackageConfigField, self).__init__(**kwargs) super(PackageConfigField, self).__init__(**kwargs)
class PackageAdapter(BASE, AdapterMixin): class Adapter(BASE, HelperMixin):
"""Adapter table.""" """Adapter table."""
__tablename__ = 'package_adapter' __tablename__ = 'adapter'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
name = Column(String(80), unique=True) name = Column(String(80), unique=True)
display_name = Column(String(80))
parent_id = Column( parent_id = Column(
Integer, Integer,
ForeignKey( ForeignKey(
'package_adapter.id', 'adapter.id',
onupdate='CASCADE', ondelete='CASCADE' onupdate='CASCADE', ondelete='CASCADE'
), ),
nullable=True nullable=True
@ -1701,7 +1561,15 @@ class PackageAdapter(BASE, AdapterMixin):
), ),
nullable=True nullable=True
) )
installer_id = Column( os_installer_id = Column(
Integer,
ForeignKey(
'os_installer.id',
onupdate='CASCADE', ondelete='CASCADE'
),
nullable=True
)
package_installer_id = Column(
Integer, Integer,
ForeignKey( ForeignKey(
'package_installer.id', 'package_installer.id',
@ -1709,35 +1577,43 @@ class PackageAdapter(BASE, AdapterMixin):
), ),
nullable=True nullable=True
) )
supported_os_patterns = Column(JSONEncoded, nullable=True) deployable = Column(
Boolean, default=False
)
supported_oses = relationship(
AdapterOS,
passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan',
backref=backref('adapter')
)
roles = relationship( roles = relationship(
PackageAdapterRole, AdapterRole,
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan', cascade='all, delete-orphan',
backref=backref('adapter') backref=backref('adapter')
) )
children = relationship( children = relationship(
'PackageAdapter', 'Adapter',
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
backref=backref('parent', remote_side=id) backref=backref('parent', remote_side=id)
) )
adapters = relationship(
Adapter,
passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan',
backref=backref('package_adapter')
)
metadatas = relationship( metadatas = relationship(
PackageConfigMetadata, PackageConfigMetadata,
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan', cascade='all, delete-orphan',
backref=backref('adapter') backref=backref('adapter')
) )
clusters = relationship(
Cluster,
backref=backref('adapter')
)
__table_args__ = ( __table_args__ = (
UniqueConstraint( UniqueConstraint(
'distributed_system_id', 'distributed_system_id',
'installer_id', name='constraint' 'os_installer_id', 'package_installer_id', name='constraint'
), ),
) )
@ -1745,19 +1621,92 @@ class PackageAdapter(BASE, AdapterMixin):
self, name, **kwargs self, name, **kwargs
): ):
self.name = name self.name = name
super(PackageAdapter, self).__init__(**kwargs) super(Adapter, self).__init__(**kwargs)
def initialize(self):
if not self.display_name:
self.display_name = self.name
@property @property
def deployable(self): def root_metadatas(self):
distributed_system = self.adapter_distributed_system return [
installer = self.adapter_installer metadata for metadata in self.metadatas
if ( if metadata.parent_id is None
distributed_system and distributed_system.deployable and ]
installer
): def metadata_dict(self):
return True dict_info = {}
if self.parent:
dict_info.update(self.parent.metadata_dict())
for metadata in self.root_metadatas:
dict_info.update(metadata.to_dict())
return dict_info
@property
def adapter_package_installer(self):
if self.package_installer:
return self.package_installer
elif self.parent:
return self.parent.adapter_package_installer
else: else:
return False return None
@property
def adapter_os_installer(self):
if self.os_installer:
return self.os_installer
elif self.parent:
return self.parent.adapter_os_installer
else:
return None
@property
def package_installer_name(self):
installer = self.adapter_package_installer
if installer:
return installer.name
else:
return None
@property
def os_installer_name(self):
installer = self.adapter_os_installer
if installer:
return installer.name
else:
return None
@property
def package_installer_type(self):
installer = self.adapter_package_installer
if installer:
return installer.installer_type
else:
return None
@property
def os_installer_type(self):
installer = self.adapter_os_installer
if installer:
return installer.installer_type
else:
return None
@property
def package_installer_config(self):
installer = self.adapter_package_installer
if installer:
return installer.config
else:
return None
@property
def os_installer_config(self):
installer = self.adapter_os_installer
if installer:
return installer.config
else:
return None
@property @property
def adapter_distributed_system(self): def adapter_distributed_system(self):
@ -1776,16 +1725,16 @@ class PackageAdapter(BASE, AdapterMixin):
if distributed_system: if distributed_system:
return distributed_system.name return distributed_system.name
else: else:
return '' return None
@property @property
def adapter_supported_os_patterns(self): def adapter_supported_oses(self):
supported_os_patterns = self.supported_os_patterns supported_oses = self.supported_oses
if supported_os_patterns: if supported_oses:
return supported_os_patterns return supported_oses
parent = self.parent parent = self.parent
if parent: if parent:
return parent.adapter_supported_os_patterns return parent.adapter_supported_oses
else: else:
return [] return []
@ -1801,13 +1750,22 @@ class PackageAdapter(BASE, AdapterMixin):
return [] return []
def to_dict(self): def to_dict(self):
dict_info = super(PackageAdapter, self).to_dict() dict_info = super(Adapter, self).to_dict()
roles = [] adapter_roles = self.adapter_roles
for role in self.adapter_roles: supported_oses = self.adapter_supported_oses
roles.append(role.to_dict()) dict_info.update({
dict_info['roles'] = roles 'roles': [role.to_dict() for role in adapter_roles],
dict_info['supported_os_patterns'] = self.adapter_supported_os_patterns 'supported_oses': [
dict_info['distributed_system'] = self.distributed_system_name adapter_os.to_dict() for adapter_os in supported_oses
],
'distributed_system_name': self.distributed_system_name,
'os_installer_name': self.os_installer_name,
'os_installer_type': self.os_installer_type,
'os_installer_config': self.os_installer_config,
'package_installer_name': self.package_installer_name,
'package_installer_type': self.package_installer_type,
'package_installer_config': self.package_installer_config
})
return dict_info return dict_info
@ -1825,9 +1783,10 @@ class DistributedSystem(BASE, HelperMixin):
nullable=True nullable=True
) )
name = Column(String(80), unique=True) name = Column(String(80), unique=True)
deployable = Column(Boolean, default=False) deployable = Column(String(80), default=False)
adapters = relationship( adapters = relationship(
PackageAdapter, Adapter,
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan', cascade='all, delete-orphan',
backref=backref('distributed_system') backref=backref('distributed_system')
@ -1847,15 +1806,31 @@ class DistributedSystem(BASE, HelperMixin):
super(DistributedSystem, self).__init__() super(DistributedSystem, self).__init__()
class OSInstaller(BASE, InstallerMixin):
"""OS installer table."""
__tablename__ = 'os_installer'
id = Column(Integer, primary_key=True)
adpaters = relationship(
Adapter,
passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan',
backref=backref('os_installer')
)
def __init__(self, name, **kwargs):
self.name = name
super(OSInstaller, self).__init__(**kwargs)
class PackageInstaller(BASE, InstallerMixin): class PackageInstaller(BASE, InstallerMixin):
"""package installer table.""" """package installer table."""
__tablename__ = 'package_installer' __tablename__ = 'package_installer'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
adapters = relationship( adapters = relationship(
PackageAdapter, Adapter,
passive_deletes=True, passive_updates=True, passive_deletes=True, passive_updates=True,
cascade='all, delete-orphan', cascade='all, delete-orphan',
backref=backref('installer') backref=backref('package_installer')
) )
def __init__(self, name, **kwargs): def __init__(self, name, **kwargs):
@ -1868,6 +1843,7 @@ class Network(BASE, TimestampMixin, HelperMixin):
__tablename__ = 'network' __tablename__ = 'network'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
name = Column(String(80), unique=True)
subnet = Column(String(80), unique=True) subnet = Column(String(80), unique=True)
host_networks = relationship( host_networks = relationship(
@ -1882,10 +1858,14 @@ class Network(BASE, TimestampMixin, HelperMixin):
super(Network, self).__init__(**kwargs) super(Network, self).__init__(**kwargs)
def intialize(self): def intialize(self):
if not self.name:
self.name = self.subnet
super(Network, self).intialize()
def validate(self):
try: try:
netaddr.IPNetwork(self.subnet) netaddr.IPNetwork(self.subnet)
except Exception: except Exception:
raise exception.InvalidParameter( raise exception.InvalidParameter(
'subnet %s format is uncorrect' % self.subnet 'subnet %s format is uncorrect' % self.subnet
) )
super(Network, self).intialize()

View File

@ -18,25 +18,31 @@
""" """
import logging import logging
from celery.signals import celeryd_init
from celery.signals import setup_logging from celery.signals import setup_logging
from compass.actions import deploy from compass.actions import deploy
from compass.actions import poll_switch from compass.actions import poll_switch
from compass.actions import reinstall from compass.actions import reinstall
from compass.db.api import adapter_holder as adapter_api
from compass.db.api import database
from compass.db.api import metadata_holder as metadata_api
from compass.tasks.client import celery from compass.tasks.client import celery
from compass.utils import flags from compass.utils import flags
from compass.utils import logsetting from compass.utils import logsetting
from compass.utils import setting_wrapper as setting from compass.utils import setting_wrapper as setting
def tasks_setup_logging(**_): @celeryd_init.connect()
"""Setup logging options from compass setting.""" def global_celery_init(**_):
"""Initialization code."""
flags.init() flags.init()
flags.OPTIONS.logfile = setting.CELERY_LOGFILE flags.OPTIONS.logfile = setting.CELERY_LOGFILE
logsetting.init() logsetting.init()
database.init()
adapter_api.load_adapters()
setup_logging.connect(tasks_setup_logging) metadata_api.load_metadatas()
@celery.task(name='compass.tasks.pollswitch') @celery.task(name='compass.tasks.pollswitch')
@ -60,27 +66,51 @@ def pollswitch(ip_addr, credentials, req_obj='mac', oper='SCAN'):
logging.exception(error) logging.exception(error)
@celery.task(name='compass.tasks.deploy') @celery.task(name='compass.tasks.deploy_cluster')
def deploy_clusters(cluster_hosts): def deploy_cluster(cluster_id, clusterhost_ids):
"""Deploy the given cluster. """Deploy the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to deploy. :param cluster_hosts: the cluster and hosts of each cluster to deploy.
:type cluster_hosts: dict of int to list of int :type cluster_hosts: dict of int to list of int
""" """
try: pass
deploy.deploy(cluster_hosts)
except Exception as error:
logging.exception(error)
@celery.task(name='compass.tasks.reinstall') @celery.task(name='compass.tasks.reinstall_cluster')
def reinstall_clusters(cluster_hosts): def reinstall_cluster(cluster_id, clusterhost_ids):
"""reinstall the given cluster. """reinstall the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to reinstall. :param cluster_hosts: the cluster and hosts of each cluster to reinstall.
:type cluster_hosts: dict of int to list of int :type cluster_hosts: dict of int to list of int
""" """
try: pass
reinstall.reinstall(cluster_hosts)
except Exception as error:
logging.exception(error) @celery.task(name='compass.tasks.poweron_host')
def poweron_host(host_id):
"""Deploy the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to deploy.
:type cluster_hosts: dict of int to list of int
"""
pass
@celery.task(name='compass.tasks.poweroff_host')
def poweroff_host(host_id):
"""Deploy the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to deploy.
:type cluster_hosts: dict of int to list of int
"""
pass
@celery.task(name='compass.tasks.reset_host')
def reset_host(host_id):
"""Deploy the given cluster.
:param cluster_hosts: the cluster and hosts of each cluster to deploy.
:type cluster_hosts: dict of int to list of int
"""
pass

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import logging
import os import os
import unittest2 import unittest2
@ -144,9 +145,11 @@ class TestModelFilter(unittest2.TestCase):
expected, ret = self._filter_test_dict_util( expected, ret = self._filter_test_dict_util(
'gt', 'gt',
'update_clusterhost_state', 'update_clusterhost_state',
47, 48,
id=46 id=47
) )
print 'expected: %s' % expected
print 'ret: %s' % ret
self.assertTrue( self.assertTrue(
all(item in ret[0].items() for item in expected.items()) all(item in ret[0].items() for item in expected.items())
) )
@ -166,9 +169,11 @@ class TestModelFilter(unittest2.TestCase):
expected, ret = self._filter_test_dict_util( expected, ret = self._filter_test_dict_util(
'ge', 'ge',
'update_clusterhost_state', 'update_clusterhost_state',
47, 48,
id=47 id=48
) )
print 'expected: %s' % expected
print 'ret: %s' % ret
self.assertTrue( self.assertTrue(
all(item in ret[0].items() for item in expected.items()) all(item in ret[0].items() for item in expected.items())
) )
@ -387,7 +392,7 @@ class TestAddDbObject(unittest2.TestCase):
with database.session() as session: with database.session() as session:
db_objs = utils.add_db_object( db_objs = utils.add_db_object(
session, session,
models.PackageAdapterRole, models.AdapterRole,
True, True,
'test1', 'test1',
1, 1,

View File

@ -63,13 +63,12 @@ OS_INSTALLER_DIR = '/etc/compass/os_installer'
PACKAGE_INSTALLER_DIR = '/etc/compass/package_installer' PACKAGE_INSTALLER_DIR = '/etc/compass/package_installer'
OS_DIR = '/etc/compass/os' OS_DIR = '/etc/compass/os'
DISTRIBUTED_SYSTEM_DIR = '/etc/compass/distributed_system' DISTRIBUTED_SYSTEM_DIR = '/etc/compass/distributed_system'
OS_ADAPTER_DIR = '/etc/compass/os_adapter' ADAPTER_DIR = '/etc/compass/adapter'
PACKAGE_ADAPTER_DIR = '/etc/compass/package_adapter'
OS_METADATA_DIR = '/etc/compass/os_metadata' OS_METADATA_DIR = '/etc/compass/os_metadata'
PACKAGE_METADATA_DIR = '/etc/compass/package_metadata' PACKAGE_METADATA_DIR = '/etc/compass/package_metadata'
OS_FIELD_DIR = '/etc/compass/os_field' OS_FIELD_DIR = '/etc/compass/os_field'
PACKAGE_FIELD_DIR = '/etc/compass/package_field' PACKAGE_FIELD_DIR = '/etc/compass/package_field'
PACKAGE_ROLE_DIR = '/etc/compass/role' ADAPTER_ROLE_DIR = '/etc/compass/role'
VALIDATOR_DIR = '/etc/compass/validator' VALIDATOR_DIR = '/etc/compass/validator'
if ( if (
'COMPASS_IGNORE_SETTING' in os.environ and 'COMPASS_IGNORE_SETTING' in os.environ and

View File

@ -0,0 +1,7 @@
NAME = 'ceph(chef)'
DSPLAY_NAME = 'ceph(ceph)'
PARENT = 'ceph'
PACKAGE_INSTALLER = 'chef(icehouse)'
OS_INSTALLER = 'cobbler'
SUPPORTED_OS_PATTERNS = ['(?i)centos.*', '(?i)ubuntu.*']
DEPLOYABLE = True

View File

@ -0,0 +1,7 @@
NAME = 'openstack(chef)'
DISPLAY_NAME = 'openstack(chef)'
PARENT = 'openstack'
PACKAGE_INSTALLER = 'chef(icehouse)'
OS_INSTALLER = 'cobbler'
SUPPORTED_OS_PATTERNS = ['(?i)centos.*', '(?i)ubuntu.*']
DEPLOYABLE = True

View File

@ -1,2 +1 @@
NAME = 'general' NAME = 'general'
OS = 'general'

View File

@ -1,3 +1,4 @@
NAME = 'openstack' NAME = 'openstack'
PARENT = 'general' PARENT = 'general'
DISTRIBUTED_SYSTEM = 'openstack' DISTRIBUTED_SYSTEM = 'openstack'
SUPPORTED_OSES = ['CentOS6.5', 'Ubuntu12.04']

View File

@ -0,0 +1,5 @@
NAME = 'os_only'
PARENT = 'general'
OS_INSTALLER = 'cobbler'
SUPPORTED_OS_PATTERNS = ['(?i)centos.*', '(?i)ubuntu.*']
DEPLOYABLE = True

View File

@ -1,3 +0,0 @@
NAME = 'CentOS'
PARENT = 'general'
OS = 'CentOS'

View File

@ -1,3 +0,0 @@
NAME = 'CentOS(cobbler)'
PARENT = 'CentOS'
INSTALLER = 'cobbler'

View File

@ -1,3 +0,0 @@
NAME = 'CentOS6.5(cobbler)'
PARENT = 'CentOS(cobbler)'
OS = 'CentOS6.5'

View File

@ -1,3 +0,0 @@
NAME = 'Ubuntu(cobbler)'
PARENT = 'Ubuntu'
INSTALLER = 'cobbler'

View File

@ -1,3 +0,0 @@
NAME = 'Ubuntu12.04(cobbler)'
PARENT = 'Ubuntu(cobbler)'
OS = 'Ubuntu12.04'

View File

@ -1,3 +0,0 @@
NAME = 'Ubuntu'
PARENT = 'general'
OS = 'Ubuntu'

View File

@ -1,4 +1,4 @@
ADAPTER = 'general' OS = 'general'
METADATA = { METADATA = {
'general': { 'general': {
'_self': { '_self': {
@ -9,7 +9,6 @@ METADATA = {
'field': 'general', 'field': 'general',
'default_value': 'EN', 'default_value': 'EN',
'options': ['EN'], 'options': ['EN'],
'required_in_options': True
} }
}, },
'timezone': { 'timezone': {
@ -17,7 +16,6 @@ METADATA = {
'field': 'general', 'field': 'general',
'default_value': 'PDT', 'default_value': 'PDT',
'options': ['PDT'], 'options': ['PDT'],
'required_in_options': True
} }
}, },
'domain': { 'domain': {
@ -26,7 +24,6 @@ METADATA = {
'is_required' : True, 'is_required' : True,
'default_value': 'ods.com', 'default_value': 'ods.com',
'options': ['ods.com'], 'options': ['ods.com'],
'required_in_options': True
} }
}, },
'default_gateway': { 'default_gateway': {
@ -58,7 +55,6 @@ METADATA = {
'_self': { '_self': {
'required_in_whole_config': True, 'required_in_whole_config': True,
'options': ['/boot', 'swap', '/var', '/home'], 'options': ['/boot', 'swap', '/var', '/home'],
'required_in_options': True
}, },
'$partition': { '$partition': {
'_self': { '_self': {

View File

@ -1,4 +0,0 @@
NAME = 'ceph(chef)'
PARENT = 'ceph'
INSTALLER = 'chef(icehouse)'
SUPPORTED_OS_PATTERNS = ['(?i)centos.*', '(?i)ubuntu.*']

View File

@ -1,4 +0,0 @@
NAME = 'chef_openstack'
PARENT = 'openstack'
INSTALLER = 'chef(icehouse)'
SUPPORTED_OS_PATTERNS = ['(?i)centos.*', '(?i)ubuntu.*']

View File

@ -1,2 +0,0 @@
NAME = 'general'
DISTRIBUTED_SYSTEM = 'general'

View File

@ -1,30 +1,39 @@
ADAPTER_NAME = 'chef_openstack' ADAPTER_NAME = 'openstack(chef)'
ROLES = [{ ROLES = [{
'role': 'os-compute-worker', 'role': 'os-compute-worker',
'display_name': 'compute node',
'description': 'compute node' 'description': 'compute node'
}, { }, {
'role': 'os-network', 'role': 'os-network',
'display_name': 'network node',
'description': 'network node' 'description': 'network node'
}, { }, {
'role': 'os-block-storage-worker', 'role': 'os-block-storage-worker',
'display_name': 'storage node',
'description': 'storage node' 'description': 'storage node'
}, { }, {
'role': 'os-image', 'role': 'os-image',
'display_name': 'image node',
'description': 'image node' 'description': 'image node'
}, { }, {
'role': 'os-compute-vncproxy', 'role': 'os-compute-vncproxy',
'display_name': 'vnc proxy node',
'description': 'vnc proxy node' 'description': 'vnc proxy node'
}, { }, {
'role': 'os-controller', 'role': 'os-controller',
'display_name': 'controller node',
'description': 'controller node' 'description': 'controller node'
}, { }, {
'role': 'os-ops-messaging', 'role': 'os-ops-messaging',
'display_name': 'message queue node',
'description': 'message queue node' 'description': 'message queue node'
}, { }, {
'role': 'os-ops-database', 'role': 'os-ops-database',
'display_name': 'database node',
'description': 'database node' 'description': 'database node'
}, { }, {
'role': 'ha-proxy', 'role': 'ha-proxy',
'display_name': 'ha proxy node',
'description': 'ha proxy node', 'description': 'ha proxy node',
'optional': True 'optional': True
}] }]