diff options
Diffstat (limited to 'moonv4/moon_utilities/moon_utilities')
-rw-r--r-- | moonv4/moon_utilities/moon_utilities/__init__.py | 6 | ||||
-rw-r--r-- | moonv4/moon_utilities/moon_utilities/api.py | 28 | ||||
-rw-r--r-- | moonv4/moon_utilities/moon_utilities/exceptions.py | 505 | ||||
-rw-r--r-- | moonv4/moon_utilities/moon_utilities/misc.py | 47 | ||||
-rw-r--r-- | moonv4/moon_utilities/moon_utilities/options.py | 300 | ||||
-rw-r--r-- | moonv4/moon_utilities/moon_utilities/security_functions.py | 405 |
6 files changed, 1291 insertions, 0 deletions
diff --git a/moonv4/moon_utilities/moon_utilities/__init__.py b/moonv4/moon_utilities/moon_utilities/__init__.py new file mode 100644 index 00000000..903c6518 --- /dev/null +++ b/moonv4/moon_utilities/moon_utilities/__init__.py @@ -0,0 +1,6 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +__version__ = "0.1.0" diff --git a/moonv4/moon_utilities/moon_utilities/api.py b/moonv4/moon_utilities/moon_utilities/api.py new file mode 100644 index 00000000..8e80c21d --- /dev/null +++ b/moonv4/moon_utilities/moon_utilities/api.py @@ -0,0 +1,28 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +class APIList(object): + + API_LIST = () + + def __init__(self, api_list): + self.API_LIST = api_list + + def list_api(self, ctx): + api = dict() + for obj in self.API_LIST: + api[obj.__name__] = dict() + api[obj.__name__]["description"] = obj.__doc__.strip() if obj.__doc__ else "" + api[obj.__name__]["version"] = obj.__version__ + api[obj.__name__]["commands"] = dict() + for cmd in filter(lambda x: not x.startswith("__"), dir(obj)): + doc = eval("obj.{}.__doc__".format(cmd)) + if not doc: + doc = "" + api[obj.__name__]["commands"][cmd] = doc.strip() + return api + + diff --git a/moonv4/moon_utilities/moon_utilities/exceptions.py b/moonv4/moon_utilities/moon_utilities/exceptions.py new file mode 100644 index 00000000..f642fb57 --- /dev/null +++ b/moonv4/moon_utilities/moon_utilities/exceptions.py @@ -0,0 +1,505 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +from oslo_log import log as logging +from werkzeug.exceptions import HTTPException +LOG = logging.getLogger(__name__) +_ = str + + +class MoonErrorMetaClass(type): + + def __init__(cls, name, bases, dct): + super(MoonErrorMetaClass, cls).__init__(name, bases, dct) + cls.hierarchy += "/"+str(name) + + +class MoonError(HTTPException): + __metaclass__ = MoonErrorMetaClass + hierarchy = "" + description = _("There is an error requesting the Moon platform.") + code = 400 + title = 'Moon Error' + logger = "ERROR" + + def __init__(self, message="", status_code=None, payload=""): + if message: + self.description = message + if status_code: + self.code = status_code + self.payload = payload + super(MoonError, self).__init__() + + def __str__(self): + return "{}: {}".format(self.code, self.title) + + def __del__(self): + message = "{} ({}) {}".format(self.hierarchy, self.description, self.payload) + if self.logger == "ERROR": + try: + LOG.error(message) + except AttributeError: + LOG.error(message) + elif self.logger == "WARNING": + try: + LOG.warning(message) + except AttributeError: + LOG.warning(message) + elif self.logger == "CRITICAL": + try: + LOG.critical(message) + except AttributeError: + LOG.critical(message) + elif self.logger == "AUTHZ": + try: + LOG.authz(self.hierarchy) + LOG.error(message) + except AttributeError: + LOG.error(message) + else: + try: + LOG.info(message) + except AttributeError: + LOG.info(message) + + # def to_dict(self): + # rv = dict(self.payload or ()) + # rv['message'] = "{} ({})".format(self.hierarchy, self.description) + # rv['title'] = self.title + # rv['code'] = self.code + # return rv + + +# Exceptions for Tenant + +class TenantException(MoonError): + description = _("There is an error requesting this tenant.") + code = 400 + title = 'Tenant Error' + logger = "ERROR" + + +class TenantUnknown(TenantException): + description = _("The tenant is unknown.") + code = 400 + title = 'Tenant Unknown' + logger = "ERROR" + + +class TenantAddedNameExisting(TenantException): + description = _("The tenant name is existing.") + code = 400 + title = 'Added Tenant Name Existing' + logger = "ERROR" + + +class TenantNoIntraExtension(TenantException): + description = _("The tenant has not intra_extension.") + code = 400 + title = 'Tenant No Intra_Extension' + logger = "ERROR" + + +class TenantNoIntraAuthzExtension(TenantNoIntraExtension): + description = _("The tenant has not intra_admin_extension.") + code = 400 + title = 'Tenant No Intra_Admin_Extension' + logger = "ERROR" + +# Exceptions for IntraExtension + + +class IntraExtensionException(MoonError): + description = _("There is an error requesting this IntraExtension.") + code = 400 + title = 'Extension Error' + + +class IntraExtensionUnknown(IntraExtensionException): + description = _("The intra_extension is unknown.") + code = 400 + title = 'Intra Extension Unknown' + logger = "Error" + + +class ModelUnknown(MoonError): + description = _("The model is unknown.") + code = 400 + title = 'Model Unknown' + logger = "Error" + + +class ModelExisting(MoonError): + description = _("The model already exists.") + code = 409 + title = 'Model Error' + logger = "Error" + + +class RootExtensionUnknown(IntraExtensionUnknown): + description = _("The root_extension is unknown.") + code = 400 + title = 'Root Extension Unknown' + logger = "Error" + + +class RootPDPNotInitialized(IntraExtensionException): + description = _("The root_extension is not initialized.") + code = 400 + title = 'Root Extension Not Initialized' + logger = "Error" + + +class IntraExtensionCreationError(IntraExtensionException): + description = _("The arguments for the creation of this Extension were malformed.") + code = 400 + title = 'Intra Extension Creation Error' + + +# Authz exceptions + +class AuthzException(MoonError): + description = _("There is an authorization error requesting this IntraExtension.") + code = 403 + title = 'Authz Exception' + logger = "AUTHZ" + + +# Auth exceptions + +class AuthException(MoonError): + description = _("There is an authentication error requesting this API. " + "You must provide a valid token from Keystone.") + code = 401 + title = 'Auth Exception' + logger = "AUTHZ" + + +# Admin exceptions + +class AdminException(MoonError): + description = _("There is an error requesting this Authz IntraExtension.") + code = 400 + title = 'Authz Exception' + logger = "AUTHZ" + + +class AdminMetaData(AdminException): + code = 400 + title = 'Metadata Exception' + + +class AdminPerimeter(AdminException): + code = 400 + title = 'Perimeter Exception' + + +class AdminScope(AdminException): + code = 400 + title = 'Scope Exception' + + +class AdminAssignment(AdminException): + code = 400 + title = 'Assignment Exception' + + +class AdminMetaRule(AdminException): + code = 400 + title = 'Aggregation Algorithm Exception' + + +class AdminRule(AdminException): + code = 400 + title = 'Rule Exception' + + +class SubjectCategoryNameExisting(AdminMetaData): + description = _("The given subject category name already exists.") + code = 409 + title = 'Subject Category Name Existing' + logger = "ERROR" + + +class SubjectCategoryExisting(AdminMetaData): + description = _("The given subject category already exists.") + code = 409 + title = 'Subject Category Existing' + logger = "ERROR" + + +class ObjectCategoryNameExisting(AdminMetaData): + description = _("The given object category name already exists.") + code = 409 + title = 'Object Category Name Existing' + logger = "ERROR" + + +class ObjectCategoryExisting(AdminMetaData): + description = _("The given object category already exists.") + code = 409 + title = 'Object Category Existing' + logger = "ERROR" + + +class ActionCategoryNameExisting(AdminMetaData): + description = _("The given action category name already exists.") + code = 409 + title = 'Action Category Name Existing' + logger = "ERROR" + + +class ActionCategoryExisting(AdminMetaData): + description = _("The given action category already exists.") + code = 409 + title = 'Action Category Existing' + logger = "ERROR" + + +class SubjectCategoryUnknown(AdminMetaData): + description = _("The given subject category is unknown.") + code = 400 + title = 'Subject Category Unknown' + logger = "ERROR" + + +class ObjectCategoryUnknown(AdminMetaData): + description = _("The given object category is unknown.") + code = 400 + title = 'Object Category Unknown' + logger = "ERROR" + + +class ActionCategoryUnknown(AdminMetaData): + description = _("The given action category is unknown.") + code = 400 + title = 'Action Category Unknown' + logger = "ERROR" + + +class SubjectUnknown(AdminPerimeter): + description = _("The given subject is unknown.") + code = 400 + title = 'Subject Unknown' + logger = "ERROR" + + +class ObjectUnknown(AdminPerimeter): + description = _("The given object is unknown.") + code = 400 + title = 'Object Unknown' + logger = "ERROR" + + +class ActionUnknown(AdminPerimeter): + description = _("The given action is unknown.") + code = 400 + title = 'Action Unknown' + logger = "ERROR" + + +class SubjectNameExisting(AdminPerimeter): + description = _("The given subject name is existing.") + code = 400 + title = 'Subject Name Existing' + logger = "ERROR" + + +class ObjectNameExisting(AdminPerimeter): + description = _("The given object name is existing.") + code = 400 + title = 'Object Name Existing' + logger = "ERROR" + + +class ActionNameExisting(AdminPerimeter): + description = _("The given action name is existing.") + code = 400 + title = 'Action Name Existing' + logger = "ERROR" + + +class ObjectsWriteNoAuthorized(AdminPerimeter): + description = _("The modification on Objects is not authorized.") + code = 400 + title = 'Objects Write No Authorized' + logger = "AUTHZ" + + +class ActionsWriteNoAuthorized(AdminPerimeter): + description = _("The modification on Actions is not authorized.") + code = 400 + title = 'Actions Write No Authorized' + logger = "AUTHZ" + + +class SubjectScopeUnknown(AdminScope): + description = _("The given subject scope is unknown.") + code = 400 + title = 'Subject Scope Unknown' + logger = "ERROR" + + +class ObjectScopeUnknown(AdminScope): + description = _("The given object scope is unknown.") + code = 400 + title = 'Object Scope Unknown' + logger = "ERROR" + + +class ActionScopeUnknown(AdminScope): + description = _("The given action scope is unknown.") + code = 400 + title = 'Action Scope Unknown' + logger = "ERROR" + + +class SubjectScopeNameExisting(AdminScope): + description = _("The given subject scope name is existing.") + code = 400 + title = 'Subject Scope Name Existing' + logger = "ERROR" + + +class ObjectScopeNameExisting(AdminScope): + description = _("The given object scope name is existing.") + code = 400 + title = 'Object Scope Name Existing' + logger = "ERROR" + + +class ActionScopeNameExisting(AdminScope): + description = _("The given action scope name is existing.") + code = 400 + title = 'Action Scope Name Existing' + logger = "ERROR" + + +class SubjectAssignmentUnknown(AdminAssignment): + description = _("The given subject assignment value is unknown.") + code = 400 + title = 'Subject Assignment Unknown' + logger = "ERROR" + + +class ObjectAssignmentUnknown(AdminAssignment): + description = _("The given object assignment value is unknown.") + code = 400 + title = 'Object Assignment Unknown' + logger = "ERROR" + + +class ActionAssignmentUnknown(AdminAssignment): + description = _("The given action assignment value is unknown.") + code = 400 + title = 'Action Assignment Unknown' + logger = "ERROR" + + +class SubjectAssignmentExisting(AdminAssignment): + description = _("The given subject assignment value is existing.") + code = 400 + title = 'Subject Assignment Existing' + logger = "ERROR" + + +class ObjectAssignmentExisting(AdminAssignment): + description = _("The given object assignment value is existing.") + code = 400 + title = 'Object Assignment Existing' + logger = "ERROR" + + +class ActionAssignmentExisting(AdminAssignment): + description = _("The given action assignment value is existing.") + code = 400 + title = 'Action Assignment Existing' + logger = "ERROR" + + +class AggregationAlgorithmNotExisting(AdminMetaRule): + description = _("The given aggregation algorithm is not existing.") + code = 400 + title = 'Aggregation Algorithm Not Existing' + logger = "ERROR" + + +class AggregationAlgorithmUnknown(AdminMetaRule): + description = _("The given aggregation algorithm is unknown.") + code = 400 + title = 'Aggregation Algorithm Unknown' + logger = "ERROR" + + +class SubMetaRuleAlgorithmNotExisting(AdminMetaRule): + description = _("The given sub_meta_rule algorithm is unknown.") + code = 400 + title = 'Sub_meta_rule Algorithm Unknown' + logger = "ERROR" + + +class MetaRuleUnknown(AdminMetaRule): + description = _("The given sub meta rule is unknown.") + code = 400 + title = 'Sub Meta Rule Unknown' + logger = "ERROR" + + +class SubMetaRuleNameExisting(AdminMetaRule): + description = _("The sub meta rule name already exists.") + code = 400 + title = 'Sub Meta Rule Name Existing' + logger = "ERROR" + + +class MetaRuleExisting(AdminMetaRule): + description = _("The sub meta rule already exists.") + code = 400 + title = 'Sub Meta Rule Existing' + logger = "ERROR" + + +class RuleExisting(AdminRule): + description = _("The rule already exists.") + code = 400 + title = 'Rule Existing' + logger = "ERROR" + + +class RuleUnknown(AdminRule): + description = _("The rule for that request doesn't exist.") + code = 400 + title = 'Rule Unknown' + logger = "ERROR" + + +class KeystoneError(MoonError): + description = _("There is an error connecting to Keystone.") + code = 400 + title = 'Keystone error' + logger = "ERROR" + + +class KeystoneProjectError(KeystoneError): + description = _("There is an error retrieving projects from the Keystone service.") + code = 400 + title = 'Keystone project error' + logger = "ERROR" + + +class KeystoneUserError(KeystoneError): + description = _("There is an error retrieving users from the Keystone service.") + code = 400 + title = 'Keystone user error' + logger = "ERROR" + + +class KeystoneUserConflict(KeystoneUserError): + description = _("A user with that name already exist.") + code = 400 + title = 'Keystone user error' + logger = "ERROR" + + diff --git a/moonv4/moon_utilities/moon_utilities/misc.py b/moonv4/moon_utilities/moon_utilities/misc.py new file mode 100644 index 00000000..d13b4511 --- /dev/null +++ b/moonv4/moon_utilities/moon_utilities/misc.py @@ -0,0 +1,47 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +import os +import re +import types +import requests +from oslo_log import log as logging +from oslo_config import cfg +import oslo_messaging +from moon_utilities import exceptions +from oslo_config.cfg import ConfigOpts + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +def get_uuid_from_name(name, elements, **kwargs): + LOG.error("get_uuid_from_name {} {} {}".format(name, elements, kwargs)) + for element in elements: + if type(elements[element]) is dict and elements[element].get('name') == name: + if kwargs: + for args in kwargs: + if elements[element].get(args) != kwargs[args]: + LOG.error("get_uuid_from_name2 {} {} {}".format(args, elements[element].get(args), kwargs[args])) + return + else: + return element + else: + return element + + +def get_name_from_uuid(uuid, elements, **kwargs): + for element in elements: + if element == uuid: + if kwargs: + for args in kwargs: + if elements[element].get(args) != kwargs[args]: + return + else: + return elements[element].get('name') + else: + return elements[element].get('name') + diff --git a/moonv4/moon_utilities/moon_utilities/options.py b/moonv4/moon_utilities/moon_utilities/options.py new file mode 100644 index 00000000..8b8ccca4 --- /dev/null +++ b/moonv4/moon_utilities/moon_utilities/options.py @@ -0,0 +1,300 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + +import os +import sys +from oslo_config import cfg +from oslo_log import log as logging +from moon_utilities import __version__ + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + +__CWD__ = os.path.dirname(os.path.abspath(__file__)) + + +def configure(domain="moon", version=__version__, usage=""): + # FIXME (dthom): put DEBUG as default log level doesn't work + extra_log_level_defaults = [ + '{}=DEBUG'.format(__name__), + ] + # LOG.setLevel(logging.DEBUG) + logging.set_defaults( + default_log_levels=logging.get_default_log_levels() + extra_log_level_defaults) + + logging.register_options(CONF) + logging.setup(CONF, domain) + + CONF.register_opts(get_opts()) + + # rabbit_group = cfg.OptGroup(name='messenger', + # title='Messenger options') + # CONF.register_group(rabbit_group) + # CONF.register_opts(get_messenger_opts(), group="messenger") + + slave_group = cfg.OptGroup(name='slave', + title='Messenger options') + CONF.register_group(slave_group) + CONF.register_opts(get_slave_opts(), group="slave") + + database_group = cfg.OptGroup(name='database', + title='Database options') + CONF.register_group(database_group) + CONF.register_opts(get_database_opts(), group="database") + + database_configuration_group = cfg.OptGroup(name='database_configuration', + title='Database configuration options') + CONF.register_group(database_configuration_group) + CONF.register_opts(get_database_configuration_opts(), group="database_configuration") + + orchestrator_group = cfg.OptGroup(name='orchestrator', + title='Orchestrator options') + CONF.register_group(orchestrator_group) + CONF.register_opts(get_orchestrator_opts(), group="orchestrator") + + secrouter_group = cfg.OptGroup(name='security_router', + title='Security Router options') + CONF.register_group(secrouter_group) + CONF.register_opts(get_security_router_opts(), group="security_router") + + manager_group = cfg.OptGroup(name='security_manager', + title='Manager options') + CONF.register_group(manager_group) + CONF.register_opts(get_manager_opts(), group="security_manager") + + secpolicy_group = cfg.OptGroup(name='security_policy', + title='Security policy options') + CONF.register_group(secpolicy_group) + CONF.register_opts(get_security_policy_opts(), group="security_policy") + + secfunction_group = cfg.OptGroup(name='security_function', + title='Security function options') + CONF.register_group(secfunction_group) + CONF.register_opts(get_security_function_opts(), group="security_function") + + interface_group = cfg.OptGroup(name='interface', + title='Interface options') + CONF.register_group(interface_group) + CONF.register_opts(get_interface_opts(), group="interface") + + keystone_group = cfg.OptGroup(name='keystone', + title='Keystone options') + CONF.register_group(keystone_group) + CONF.register_opts(get_keystone_opts(), group="keystone") + + filename = "moon.conf" + for _filename in ( + "/etc/moon/{}", + "conf/{}", + "../conf/{}", + ): + try: + default_config_files = (_filename.format(filename), ) + CONF(args=sys.argv[1:], + project=domain, + # version=pbr.version.VersionInfo('keystone').version_string(), + version=version, + usage=usage, + default_config_files=default_config_files) + except cfg.ConfigFilesNotFoundError: + continue + else: + LOG.info("Using {} configuration file".format(_filename.format(filename))) + return _filename.format(filename) + + +def get_opts(): + return [ + cfg.StrOpt('proxy', + default="", + help='Proxy server to use'), + cfg.StrOpt('dist_dir', + default="", + help='Directory where the python packages can be found'), + cfg.StrOpt('plugin_dir', + default="", + help='Directory where the python plugins can be found'), + cfg.StrOpt('docker_url', + default="unix://var/run/docker.sock", + help='Docker URL to connect to.'), + cfg.StrOpt('policy_directory', + default="/etc/moon/policies", + help='Directory containing all the intra-extension templates'), + cfg.StrOpt('root_policy_directory', + default="/etc/moon/policies/policy_root", + help='Directory containing the Root intra-extension template'), + cfg.StrOpt('master', + default="", + help='URL of the Moon Master'), + cfg.StrOpt('master_login', + default="", + help='Login to log into the Moon Master'), + cfg.StrOpt('master_password', + default="", + help='Password for the Moon Master'), + ] + + +# def get_messenger_opts(): +# return [ +# cfg.StrOpt('host', +# default="0.0.0.0", +# help='RabbitMQ server name or IP.'), +# cfg.IntOpt('port', +# default=8800, +# help='RabbitMQ server port.'), +# ] + + +def get_orchestrator_opts(): + return [ + cfg.StrOpt('host', + default="127.0.0.1", + help='Host binding'), + cfg.IntOpt('port', + default=38000, + help='Port number of the server'), + ] + + +def get_slave_opts(): + return [ + cfg.StrOpt('slave_name', + default="", + help='name of the slave'), + cfg.StrOpt('master_url', + default="", + help='URL of the RabbitMQ bus of the Master, ' + 'example: master_url=rabbit://moon:p4sswOrd1@messenger:5672/moon'), + cfg.StrOpt('master_login', + default="", + help='login name of the master administrator, example: master_login=admin'), + cfg.StrOpt('master_password', + default="", + help='password of the master administrator, example: master_password=XXXXXXX'), + ] + + +def get_security_router_opts(): + return [ + cfg.StrOpt('container', + default="", + help='Name of the container to download (if empty build from scratch)'), + cfg.StrOpt('host', + default="127.0.0.1", + help='Host binding'), + cfg.IntOpt('port', + default=38001, + help='Port number of the server'), + ] + + +def get_manager_opts(): + return [ + cfg.StrOpt('container', + default="", + help='Name of the container to download (if empty build from scratch)'), + cfg.StrOpt('host', + default="127.0.0.1", + help='Host binding'), + cfg.IntOpt('port', + default=38001, + help='Port number of the server'), + ] + + +def get_security_policy_opts(): + return [ + cfg.StrOpt('container', + default="", + help='Name of the container to download (if empty build from scratch)'), + ] + + +def get_security_function_opts(): + return [ + cfg.StrOpt('container', + default="", + help='Name of the container to download (if empty build from scratch)'), + ] + + +def get_interface_opts(): + return [ + cfg.StrOpt('container', + default="", + help='Name of the container to download (if empty build from scratch)'), + cfg.StrOpt('host', + default="127.0.0.1", + help='Host binding'), + cfg.IntOpt('port', + default=38002, + help='Port number of the server'), + ] + + +def get_database_opts(): + return [ + cfg.StrOpt('url', + default="mysql+pymysql://moonuser:password@localhost/moon", + help='URL of the database'), + cfg.StrOpt('driver', + default="sql", + help='Driver binding'), + ] + + +def get_database_configuration_opts(): + return [ + cfg.StrOpt('url', + default="", + help='URL of the database'), + cfg.StrOpt('driver', + default="memory", + help='Driver binding'), + ] + + +def get_keystone_opts(): + return [ + cfg.StrOpt('url', + default="http://localhost:35357", + help='URL of the Keystone manager.'), + cfg.StrOpt('user', + default="admin", + help='Username of the Keystone manager.'), + cfg.StrOpt('password', + default="nomoresecrete", + help='Password of the Keystone manager.'), + cfg.StrOpt('project', + default="admin", + help='Project used to connect to the Keystone manager.'), + cfg.StrOpt('domain', + default="Default", + help='Default domain for the Keystone manager.'), + cfg.StrOpt('check_token', + default="true", + help='If true, yes or strict, always check Keystone tokens against the server'), + cfg.StrOpt('server_crt', + default="", + help='If using Keystone in HTTPS mode, give a certificate filename here'), + ] + +filename = configure() + + +def get_docker_template_dir(templatename="template.dockerfile"): + path = os.path.dirname(os.path.abspath(filename)) + PATHS = ( + path, + os.path.join(path, "dockers"), + "/etc/moon/" + "~/.moon/" + ) + for _path in PATHS: + if os.path.isfile(os.path.join(_path, templatename)): + return _path + raise Exception("Configuration error, cannot find docker template in {}".format(PATHS)) + diff --git a/moonv4/moon_utilities/moon_utilities/security_functions.py b/moonv4/moon_utilities/moon_utilities/security_functions.py new file mode 100644 index 00000000..2ad52a4c --- /dev/null +++ b/moonv4/moon_utilities/moon_utilities/security_functions.py @@ -0,0 +1,405 @@ +# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + +import copy +import re +import types +import requests +from uuid import uuid4 +from oslo_log import log as logging +from oslo_config import cfg +import oslo_messaging +from moon_utilities import exceptions +from oslo_config.cfg import ConfigOpts +# from moon_db.core import PDPManager, ModelManager, PolicyManager + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF + + +def filter_input(func_or_str): + + def __filter(string): + if string and type(string) is str: + return "".join(re.findall("[\w\- +]*", string)) + return string + + def __filter_dict(arg): + result = dict() + for key in arg.keys(): + if key == "email": + result["email"] = __filter_email(arg[key]) + elif key == "password": + result["password"] = arg['password'] + else: + result[key] = __filter(arg[key]) + return result + + def __filter_email(string): + if string and type(string) is str: + return "".join(re.findall("[\w@\._\- +]*", string)) + return string + + def wrapped(*args, **kwargs): + _args = [] + for arg in args: + if isinstance(arg, str): + arg = __filter(arg) + elif isinstance(arg, list): + arg = [__filter(item) for item in arg] + elif isinstance(arg, tuple): + arg = (__filter(item) for item in arg) + elif isinstance(arg, dict): + arg = __filter_dict(arg) + _args.append(arg) + for arg in kwargs: + if type(kwargs[arg]) is str: + kwargs[arg] = __filter(kwargs[arg]) + if isinstance(kwargs[arg], str): + kwargs[arg] = __filter(kwargs[arg]) + elif isinstance(kwargs[arg], list): + kwargs[arg] = [__filter(item) for item in kwargs[arg]] + elif isinstance(kwargs[arg], tuple): + kwargs[arg] = (__filter(item) for item in kwargs[arg]) + elif isinstance(kwargs[arg], dict): + kwargs[arg] = __filter_dict(kwargs[arg]) + return func_or_str(*_args, **kwargs) + + if isinstance(func_or_str, str): + return __filter(func_or_str) + if isinstance(func_or_str, list): + return [__filter(item) for item in func_or_str] + if isinstance(func_or_str, tuple): + return (__filter(item) for item in func_or_str) + if isinstance(func_or_str, dict): + return __filter_dict(func_or_str) + if isinstance(func_or_str, types.FunctionType): + return wrapped + return None + + +def enforce(action_names, object_name, **extra): + """Fake version of the enforce decorator""" + def wrapper_func(func): + def wrapper_args(*args, **kwargs): + # LOG.info("kwargs={}".format(kwargs)) + # kwargs['user_id'] = kwargs.pop('user_id', "admin") + # LOG.info("Calling enforce on {} with args={} kwargs={}".format(func.__name__, args, kwargs)) + return func(*args, **kwargs) + return wrapper_args + return wrapper_func + + +def login(user=None, password=None, domain=None, project=None, url=None): + if not user: + user = CONF.keystone.user + if not password: + password = CONF.keystone.password + if not domain: + domain = CONF.keystone.domain + if not project: + project = CONF.keystone.project + if not url: + url = CONF.keystone.url + headers = { + "Content-Type": "application/json" + } + data_auth = { + "auth": { + "identity": { + "methods": [ + "password" + ], + "password": { + "user": { + "domain": { + "id": domain + }, + "name": user, + "password": password + } + } + }, + "scope": { + "project": { + "domain": { + "id": domain + }, + "name": project + } + } + } + } + + req = requests.post("{}/auth/tokens".format(url), + json=data_auth, headers=headers, + verify=CONF.keystone.server_crt) + + if req.status_code in (200, 201, 204): + headers['X-Auth-Token'] = req.headers['X-Subject-Token'] + return headers + LOG.error(req.text) + raise exceptions.KeystoneError + + +def logout(headers, url=None): + if not url: + url = CONF.keystone.url + headers['X-Subject-Token'] = headers['X-Auth-Token'] + req = requests.delete("{}/auth/tokens".format(url), headers=headers, verify=CONF.keystone.server_crt) + if req.status_code in (200, 201, 204): + return + LOG.error(req.text) + raise exceptions.KeystoneError + +__transport_master = oslo_messaging.get_transport(cfg.CONF, CONF.slave.master_url) +__transport = oslo_messaging.get_transport(CONF) + + +def call(endpoint, ctx=None, method="get_status", **kwargs): + if not ctx: + ctx = dict() + if 'call_master' in ctx and ctx['call_master'] and CONF.slave.master_url: + transport = __transport_master + # LOG.info("Calling master {} on {}...".format(method, endpoint)) + else: + transport = __transport + # LOG.info("Calling {} on {}...".format(method, endpoint)) + target = oslo_messaging.Target(topic=endpoint, version='1.0') + client = oslo_messaging.RPCClient(transport, target) + return client.call(ctx, method, **kwargs) + + +class Context: + + def __init__(self, _keystone_project_id, _subject, _object, _action, _request_id): + from moon_db.core import PDPManager, ModelManager, PolicyManager + self.PolicyManager = PolicyManager + self.ModelManager = ModelManager + self.PDPManager = PDPManager + self.__keystone_project_id = _keystone_project_id + self.__pdp_id = None + self.__pdp_value = None + LOG.info("Context pdp={}".format(PDPManager.get_pdp("admin"))) + for _pdp_key, _pdp_value in PDPManager.get_pdp("admin").items(): + if _pdp_value["keystone_project_id"] == _keystone_project_id: + self.__pdp_id = _pdp_key + self.__pdp_value = copy.deepcopy(_pdp_value) + break + LOG.info("Context pdp_value={}".format(self.__pdp_value)) + self.__subject = _subject + self.__object = _object + self.__action = _action + self.__current_request = None + self.__request_id = _request_id + self.__index = 0 + self.__init_initial_request() + self.__headers = [] + policies = PolicyManager.get_policies("admin") + models = ModelManager.get_models("admin") + LOG.info("Context policies={}".format(policies)) + LOG.info("Context models={}".format(models)) + for policy_id in self.__pdp_value["security_pipeline"]: + model_id = policies[policy_id]["model_id"] + for meta_rule in models[model_id]["meta_rules"]: + self.__headers.append(meta_rule) + self.__meta_rules = ModelManager.get_meta_rules("admin") + LOG.info("Context meta_rules={}".format(self.__meta_rules)) + LOG.info("Context headers={}".format(self.__headers)) + # call("moon_manager", + # method="get_meta_rules", + # ctx={"id": self.__intra_extension_id, + # "user_id": "admin", + # "method": "get_sub_meta_rules"}, + # args={})["sub_meta_rules"] + # for key in self.__intra_extension["pdp_pipeline"]: + # LOG.info("__meta_rules={}".format(self.__meta_rules)) + # for meta_rule_key in self.__meta_rules: + # if self.__meta_rules[meta_rule_key]['name'] == key.split(":", maxsplit=1)[-1]: + # self.__headers.append({"name": self.__meta_rules[meta_rule_key]['name'], "id": meta_rule_key}) + # break + # else: + # LOG.warning("Cannot find meta_rule_key {}".format(key)) + self.__pdp_set = {} + self.__init_pdp_set() + + def __init_initial_request(self): + subjects = self.PolicyManager.get_subjects("admin", policy_id=None) + for _subject_id, _subject_dict in subjects.items(): + if _subject_dict["name"] == self.__subject: + self.__subject = _subject_id + break + else: + raise exceptions.SubjectUnknown("Cannot find subject {}".format(self.__subject)) + objects = self.PolicyManager.get_objects("admin", policy_id=None) + for _object_id, _object_dict in objects.items(): + if _object_dict["name"] == self.__object: + self.__object = _object_id + break + else: + raise exceptions.ObjectUnknown("Cannot find object {}".format(self.__object)) + actions = self.PolicyManager.get_actions("admin", policy_id=None) + for _action_id, _action_dict in actions.items(): + if _action_dict["name"] == self.__action: + self.__action = _action_id + break + else: + raise exceptions.ActionUnknown("Cannot find action {}".format(self.__action)) + self.__current_request = dict(self.initial_request) + + def __init_pdp_set(self): + for header in self.__headers: + self.__pdp_set[header] = dict() + self.__pdp_set[header]["meta_rules"] = self.__meta_rules[header] + self.__pdp_set[header]["target"] = self.__add_target() + # TODO (asteroide): the following information must be retrieve somewhere + self.__pdp_set[header]["instruction"] = list() + self.__pdp_set[header]["effect"] = "grant" + self.__pdp_set["effect"] = "grant" + + def __add_target(self): + result = dict() + _subject = self.__current_request["subject"] + _object = self.__current_request["object"] + _action = self.__current_request["action"] + categories = self.ModelManager.get_subject_categories("admin") + # TODO (asteroide): end the dev of that part + # for category in categories: + # result[category] = list() + # assignments = call("moon_secpolicy_{}".format(self.__intra_extension_id), + # method="get_subject_assignments", + # ctx={"id": self.__intra_extension_id, + # "sid": _subject, + # "scid": category, + # "user_id": "admin"}, + # args={})["subject_assignments"] + # result[category].extend(assignments[_subject][category]) + # categories = call("moon_secpolicy_{}".format(self.__intra_extension_id), + # method="get_object_categories", + # ctx={"id": self.__intra_extension_id, + # "user_id": "admin"}, + # args={})["object_categories"] + # for category in categories: + # result[category] = list() + # assignments = call("moon_secpolicy_{}".format(self.__intra_extension_id), + # method="get_object_assignments", + # ctx={"id": self.__intra_extension_id, + # "sid": _object, + # "scid": category, + # "user_id": "admin"}, + # args={})["object_assignments"] + # result[category].extend(assignments[_object][category]) + # categories = call("moon_secpolicy_{}".format(self.__intra_extension_id), + # method="get_action_categories", + # ctx={"id": self.__intra_extension_id, + # "user_id": "admin"}, + # args={})["action_categories"] + # for category in categories: + # result[category] = list() + # assignments = call("moon_secpolicy_{}".format(self.__intra_extension_id), + # method="get_action_assignments", + # ctx={"id": self.__intra_extension_id, + # "sid": _action, + # "scid": category, + # "user_id": "admin"}, + # args={})["action_assignments"] + # result[category].extend(assignments[_action][category]) + return result + + def __repr__(self): + return """PDP ID: {id} +current_request: {current_request} +request_id: {request_id} +index: {index} +headers: {headers} +pdp_set: {pdp_set} + """.format( + id=self.__pdp_id, + current_request=self.__current_request, + request_id=self.__request_id, + headers=self.__headers, + pdp_set=self.__pdp_set, + index=self.__index + ) + + def to_dict(self): + return { + "initial_request": copy.deepcopy(self.initial_request), + "current_request": copy.deepcopy(self.__current_request), + "headers": copy.deepcopy(self.__headers), + "index": copy.deepcopy(self.__index), + "pdp_set": copy.deepcopy(self.__pdp_set), + "request_id": copy.deepcopy(self.__request_id), + } + + @property + def initial_request(self): + return { + "subject": self.__subject, + "object": self.__object, + "action": self.__action, + } + + @initial_request.setter + def initial_request(self, value): + raise Exception("You are not allowed to update the initial_request") + + @initial_request.deleter + def initial_request(self): + raise Exception("You are not allowed to delete the initial_request") + + @property + def current_request(self): + if not self.__current_request: + self.__current_request = copy.deepcopy(self.initial_request) + return self.__current_request + + @current_request.setter + def current_request(self, value): + self.__current_request = copy.deepcopy(value) + # Note (asteroide): if the current request is modified, we must update the PDP Set. + self.__init_pdp_set() + + @current_request.deleter + def current_request(self): + self.__current_request = {} + self.__pdp_set = {} + + @property + def headers(self): + return self.__headers + + @headers.setter + def headers(self, headers): + self.__headers = headers + + @headers.deleter + def headers(self): + self.__headers = list() + + @property + def index(self): + return self.__index + + @index.setter + def index(self, index): + self.__index += 1 + + @index.deleter + def index(self): + self.__index = 0 + + @property + def pdp_set(self): + return self.__pdp_set + + @pdp_set.setter + def pdp_set(self, value): + raise Exception("You are not allowed to modify the pdp_set") + + @pdp_set.deleter + def pdp_set(self): + self.__pdp_set = {} |