compass-core/compass/db/api/metadata_holder.py

353 lines
11 KiB
Python

# Copyright 2014 Huawei Technologies Co. Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Metadata related object holder."""
import logging
from compass.db.api import database
from compass.db.api import metadata as metadata_api
from compass.db.api import permission
from compass.db.api import user as user_api
from compass.db.api import utils
from compass.db import exception
from compass.db import models
from compass.utils import setting_wrapper as setting
from compass.utils import util
RESP_METADATA_FIELDS = [
'os_config', 'package_config', 'flavor_config'
]
RESP_FLAVORS_FIELDS = [
'id', 'name', 'display_name', 'template', 'roles'
]
@database.run_in_session()
def load_metadatas(session):
load_os_metadatas_internal(session)
load_package_metadatas_internal(session)
load_flavor_metadatas_internal(session)
def load_os_metadatas_internal(session):
global OS_METADATA_MAPPING
logging.info('load os metadatas into memory')
OS_METADATA_MAPPING = metadata_api.get_os_metadatas_internal(session)
def load_package_metadatas_internal(session):
global PACKAGE_METADATA_MAPPING
logging.info('load package metadatas into memory')
PACKAGE_METADATA_MAPPING = (
metadata_api.get_package_metadatas_internal(session)
)
def load_flavor_metadatas_internal(session):
global FLAVOR_METADATA_MAPPING
logging.info('load flavor metadatas into memory')
FLAVOR_METADATA_MAPPING = (
metadata_api.get_flavor_metadatas_internal(session)
)
OS_METADATA_MAPPING = {}
PACKAGE_METADATA_MAPPING = {}
FLAVOR_METADATA_MAPPING = {}
def _validate_config(
config, id, id_name, metadata_mapping, whole_check, **kwargs
):
if id not in metadata_mapping:
raise exception.InvalidParameter(
'%s id %s is not found in metadata mapping' % (id_name, id)
)
metadatas = metadata_mapping[id]
metadata_api.validate_config_internal(
config, metadatas, whole_check, **kwargs
)
def validate_os_config(
session, config, os_id, whole_check=False, **kwargs
):
if not OS_METADATA_MAPPING:
load_os_metadatas_internal(session)
_validate_config(
config, os_id, 'os', OS_METADATA_MAPPING,
whole_check, session=session, **kwargs
)
def validate_package_config(
session, config, adapter_id, whole_check=False, **kwargs
):
if not PACKAGE_METADATA_MAPPING:
load_package_metadatas_internal(session)
_validate_config(
config, adapter_id, 'adapter', PACKAGE_METADATA_MAPPING,
whole_check, session=session, **kwargs
)
def validate_flavor_config(
session, config, flavor_id, whole_check=False, **kwargs
):
if not FLAVOR_METADATA_MAPPING:
load_flavor_metadatas_internal(session)
_validate_config(
config, flavor_id, 'flavor', FLAVOR_METADATA_MAPPING,
whole_check, session=session, **kwargs
)
def _filter_metadata(metadata, **kwargs):
if not isinstance(metadata, dict):
return metadata
filtered_metadata = {}
for key, value in metadata.items():
if key == '_self':
filtered_metadata[key] = {
'name': value['name'],
'description': value.get('description', None),
'default_value': value.get('default_value', None),
'is_required': value.get('is_required', False),
'required_in_whole_config': value.get(
'required_in_whole_config', False),
'js_validator': value.get('js_validator', None),
'options': value.get('options', None),
'required_in_options': value.get(
'required_in_options', False),
'field_type': value.get(
'field_type_data', 'str'),
'display_type': value.get('display_type', None),
'mapping_to': value.get('mapping_to', None)
}
else:
filtered_metadata[key] = _filter_metadata(value, **kwargs)
return filtered_metadata
def get_package_metadata_internal(session, adapter_id):
"""get package metadata internal."""
if not PACKAGE_METADATA_MAPPING:
load_package_metadatas_internal(session)
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], session=session
)
@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_package_metadata(adapter_id, user=None, session=None, **kwargs):
return {
'package_config': get_package_metadata_internal(session, adapter_id)
}
def get_flavor_metadata_internal(session, flavor_id):
"""get flavor metadata internal."""
if not FLAVOR_METADATA_MAPPING:
load_flavor_metadatas_internal(session)
if flavor_id not in FLAVOR_METADATA_MAPPING:
raise exception.RecordNotExists(
'flavor %s does not exist' % flavor_id
)
return _filter_metadata(
FLAVOR_METADATA_MAPPING[flavor_id], session=session
)
@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_flavor_metadata(flavor_id, user=None, session=None, **kwargs):
return {
'flavor_config': get_flavor_metadata_internal(session, flavor_id)
}
@utils.supported_filters([])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_METADATAS
)
@utils.wrap_to_dict(RESP_FLAVORS_FIELDS)
def list_flavors(user=None, session=None, **filters):
"""List flavors."""
return utils.list_db_objects(
session, models.AdapterFlavor, **filters
)
@utils.supported_filters([])
@database.run_in_session()
@user_api.check_user_permission_in_session(
permission.PERMISSION_LIST_METADATAS
)
@utils.wrap_to_dict(RESP_FLAVORS_FIELDS)
def get_flavor(flavor_id, user=None, session=None, **kwargs):
"""Get flavor."""
return utils.get_db_object(
session, models.AdapterFlavor, id=flavor_id
)
def get_os_metadata_internal(session, os_id):
"""get os metadata internal."""
if not OS_METADATA_MAPPING:
load_os_metadatas_internal(session)
if os_id not in OS_METADATA_MAPPING:
raise exception.RecordNotExists(
'os %s does not exist' % os_id
)
return _filter_metadata(
OS_METADATA_MAPPING[os_id], session=session
)
@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_os_metadata(os_id, user=None, session=None, **kwargs):
"""get os metadatas."""
return {'os_config': get_os_metadata_internal(session, os_id)}
def get_ui_metadata(metadata, config):
"""convert os_metadata to ui os_metadata."""
result_config = {}
result_config[config['mapped_name']] = []
for mapped_child in config['mapped_children']:
data_dict = {}
for config_key, config_value in mapped_child.items():
for key, value in config_value.items():
if 'data' == key:
result_data = []
_get_data(metadata[config_key], value, result_data)
data_dict['data'] = result_data
else:
data_dict[key] = value
result_config[config['mapped_name']].append(data_dict)
return result_config
def _get_data(metadata, config, result_data):
data_dict = {}
for key, config_value in config.items():
if isinstance(config_value, dict) and key != 'content_data':
if key in metadata.keys():
_get_data(metadata[key], config_value, result_data)
else:
_get_data(metadata, config_value, result_data)
elif isinstance(config_value, list):
option_list = []
for item in config_value:
if isinstance(item, dict):
option_list.append(item)
data_dict[key] = option_list
else:
if isinstance(metadata['_self'][item], bool):
data_dict[item] = str(metadata['_self'][item]).lower()
else:
data_dict[item] = metadata['_self'][item]
else:
data_dict[key] = config_value
if data_dict:
result_data.append(data_dict)
return result_data
@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_package_os_metadata(
adapter_id, os_id,
user=None, session=None, **kwargs
):
from compass.db.api import adapter_holder as adapter_api
adapter = adapter_api.get_adapter_internal(session, adapter_id)
os_ids = [os['os_id'] for os in adapter['supported_oses']]
if os_id not in os_ids:
raise exception.InvalidParameter(
'os %s is not in the supported os list of adapter %s' % (
os_id, adapter_id
)
)
metadatas = {}
metadatas['os_config'] = get_os_metadata_internal(
session, os_id
)
metadatas['package_config'] = get_package_metadata_internal(
session, adapter_id
)
return metadatas
def _autofill_config(
config, id, id_name, metadata_mapping, **kwargs
):
if id not in metadata_mapping:
raise exception.InvalidParameter(
'%s id %s is not found in metadata mapping' % (id_name, id)
)
metadatas = metadata_mapping[id]
logging.debug(
'auto fill %s config %s by params %s',
id_name, config, kwargs
)
return metadata_api.autofill_config_internal(
config, metadatas, **kwargs
)
def autofill_os_config(
session, config, os_id, **kwargs
):
if not OS_METADATA_MAPPING:
load_os_metadatas_internal(session)
return _autofill_config(
config, os_id, 'os', OS_METADATA_MAPPING, session=session, **kwargs
)
def autofill_package_config(
session, config, adapter_id, **kwargs
):
if not PACKAGE_METADATA_MAPPING:
load_package_metadatas_internal(session)
return _autofill_config(
config, adapter_id, 'adapter', PACKAGE_METADATA_MAPPING,
session=session, **kwargs
)