diff options
Diffstat (limited to 'conductor')
-rw-r--r-- | conductor/conductor/api/adapters/aaf/aaf_authentication.py | 115 | ||||
-rw-r--r-- | conductor/conductor/api/controllers/v1/plans.py | 6 | ||||
-rw-r--r-- | conductor/conductor/common/sms.py | 3 | ||||
-rw-r--r-- | conductor/conductor/data/plugins/inventory_provider/hpa_utils.py | 4 | ||||
-rw-r--r-- | conductor/conductor/data/service.py | 6 | ||||
-rw-r--r-- | conductor/conductor/opts.py | 2 | ||||
-rw-r--r-- | conductor/conductor/solver/service.py | 4 | ||||
-rw-r--r-- | conductor/pom.xml | 4 |
8 files changed, 94 insertions, 50 deletions
diff --git a/conductor/conductor/api/adapters/aaf/aaf_authentication.py b/conductor/conductor/api/adapters/aaf/aaf_authentication.py index e6b79d2..e088024 100644 --- a/conductor/conductor/api/adapters/aaf/aaf_authentication.py +++ b/conductor/conductor/api/adapters/aaf/aaf_authentication.py @@ -20,9 +20,11 @@ import base64 from datetime import datetime, timedelta import json +import os from conductor.common import rest from conductor.i18n import _LE, _LI +from conductor import __file__ as conductor_root from oslo_log import log LOG = log.getLogger(__name__) @@ -30,32 +32,46 @@ LOG = log.getLogger(__name__) from oslo_config import cfg CONF = cfg.CONF -# TBD - read values from conductor.conf AAF_OPTS = [ cfg.BoolOpt('is_aaf_enabled', - default=True, + default=False, help='is_aaf_enabled.'), cfg.IntOpt('aaf_cache_expiry_hrs', - default='3', + default='24', help='aaf_cache_expiry_hrs.'), cfg.StrOpt('aaf_url', - default='http://aaf-service:8100/authz/perms/user/', + default='https://aaf-service:8100/authz/perms/user/', help='aaf_url.'), + cfg.StrOpt('username', + default=None, + help='username.'), + cfg.StrOpt('password', + default=None, + help='pasword.'), + cfg.StrOpt('aaf_cert_file', + default=None, + help='aaf_cert_file.'), + cfg.StrOpt('aaf_cert_key_file', + default=None, + help='aaf_cert_key_file.'), + cfg.StrOpt('aaf_ca_bundle_file', + default="", + help='aaf_ca_bundle_file.'), cfg.IntOpt('aaf_retries', default='3', help='aaf_retries.'), cfg.IntOpt('aaf_timeout', default='100', help='aaf_timeout.'), - cfg.ListOpt('aaf_user_roles', - default=['{"type": "org.onap.oof","instance": "plans","action": "GET"}', - '{"type": "org.onap.oof","instance": "plans","action": "POST"}'], + cfg.StrOpt('aaf_conductor_user', + default=None, + help='aaf_conductor_user.'), + cfg.ListOpt('aaf_permissions', + default=['{"type": "org.onap.oof.access","instance": "*","action": "*"}'], help='aaf_user_roles.') ] -CONF.register_opts(AAF_OPTS, group='aaf_authentication') - -AUTHZ_PERMS_USER = '{}/authz/perms/user/{}' +CONF.register_opts(AAF_OPTS, group='aaf_api') EXPIRE_TIME = 'expire_time' @@ -64,11 +80,19 @@ perm_cache = {} def clear_cache(): perm_cache.clear() - def authenticate(uid, passwd): + aafUser = None + username = CONF.conductor_api.username + password = CONF.conductor_api.password + if username == uid and password == passwd: + aafUser = CONF.aaf_api.aaf_conductor_user + else: + LOG.debug("Error Authenticating the user {} ".format(uid)) + return False + try: - perms = get_aaf_permissions(uid, passwd) - return has_valid_role(perms) + perms = get_aaf_permissions(aafUser) + return has_valid_permissions(perms) except Exception as exp: LOG.error("Error Authenticating the user {} : {}: ".format(uid, exp)) pass @@ -80,22 +104,27 @@ return True if the user has valid permissions else return false """ -def has_valid_role(perms): - aaf_user_roles = CONF.aaf_authentication.aaf_user_roles - - permObj = json.loads(perms) - permList = permObj["perm"] - for user_role in aaf_user_roles: - role = json.loads(user_role) - userType = role["type"] - userInstance = role["instance"] - userAction = role["action"] - for perm in permList: - permType = perm["type"] - permInstance = perm["instance"] - permAction = perm["action"] +def has_valid_permissions(userPerms): + permissions = CONF.aaf_api.aaf_permissions + + LOG.info("Validate permisions: acquired permissions {} ".format(userPerms)) + LOG.info("Validate permisions: allowed permissions {} ".format(permissions)) + + userPermObj = json.loads(userPerms) + userPermList = userPermObj["perm"] + for perm in permissions: + permObj = json.loads(perm) + permType = permObj["type"] + permInstance = permObj["instance"] + permAction = permObj["action"] + for userPerm in userPermList: + userType = userPerm["type"] + userInstance = userPerm["instance"] + userAction = userPerm["action"] if userType == permType and userInstance == permInstance and \ (userAction == permAction or userAction == "*"): + # FS - trace + LOG.info("User has valid permissions ") return True return False @@ -104,35 +133,43 @@ Make the remote aaf api call if user is not in the cache. Return the perms """ -def get_aaf_permissions(uid, passwd): - key = base64.b64encode("{}_{}".format(uid, passwd), "ascii") - time_delta = timedelta(hours = CONF.aaf_authentication.aaf_cache_expiry_hrs) +def get_aaf_permissions(aafUser): + key = base64.b64encode("{}".format(aafUser), "ascii") + time_delta = timedelta(hours = CONF.aaf_api.aaf_cache_expiry_hrs) -# TBD - test cache logic perms = perm_cache.get(key) if perms and datetime.now() < perms.get(EXPIRE_TIME): LOG.debug("Returning cached value") return perms['roles'] LOG.debug("Invoking AAF authentication API") - response = remote_api(passwd, uid) + response = remote_api(aafUser) perms = {EXPIRE_TIME: datetime.now() + time_delta, 'roles': response} perm_cache[key] = perms return response -def remote_api(passwd, uid): - server_url = CONF.aaf_authentication.aaf_url.rstrip('/') + +""" +The remote api is the AAF service + +""" +def remote_api(aafUser): + server_url = CONF.aaf_api.aaf_url+aafUser + kwargs = { "server_url": server_url, - "retries": CONF.aaf_authentication.aaf_retries, - "username": uid, - "password": passwd, + "retries": CONF.aaf_api.aaf_retries, + "username": CONF.aaf_api.username, + "password": CONF.aaf_api.password, "log_debug": LOG.debug, - "read_timeout": CONF.aaf_authentication.aaf_timeout, + "read_timeout": CONF.aaf_api.aaf_timeout, + "cert_file": CONF.aaf_api.aaf_cert_file, + "cert_key_file": CONF.aaf_api.aaf_cert_key_file, + "ca_bundle_file": CONF.aaf_api.aaf_ca_bundle_file, } restReq = rest.REST(**kwargs) - headers = {"Accept": "application/json"} + headers = {"Accept": "application/Perms+json;q=1.0;charset=utf-8;version=2.1,application/json;q=1.0;version=2.1,*/*;q=1.0"} rkwargs = { "method": 'GET', "path": '', diff --git a/conductor/conductor/api/controllers/v1/plans.py b/conductor/conductor/api/controllers/v1/plans.py index b32caef..411686b 100644 --- a/conductor/conductor/api/controllers/v1/plans.py +++ b/conductor/conductor/api/controllers/v1/plans.py @@ -85,7 +85,7 @@ class PlansBaseController(object): def plans_get(self, plan_id=None): - auth_flag = CONF.conductor_api.basic_auth_secure or CONF.aaf_authentication.is_aaf_enabled + auth_flag = CONF.conductor_api.basic_auth_secure or CONF.aaf_api.is_aaf_enabled # TBD - is healthcheck properly supported? if plan_id == 'healthcheck' or \ @@ -291,7 +291,7 @@ class PlansController(PlansBaseController): if args and args['name']: LOG.info('Plan name: {}'.format(args['name'])) - auth_flag = CONF.conductor_api.basic_auth_secure or CONF.aaf_authentication.is_aaf_enabled + auth_flag = CONF.conductor_api.basic_auth_secure or CONF.aaf_api.is_aaf_enabled # Create the plan only when the basic authentication is disabled or pass the authenticaiton check if not auth_flag or \ @@ -360,7 +360,7 @@ def verify_user(authstr): retVal = False - if CONF.aaf_authentication.is_aaf_enabled: + if CONF.aaf_api.is_aaf_enabled: retVal = aaf_auth.authenticate(user_dict['username'], user_dict['password']) else: if username == user_dict['username'] and password == user_dict['password']: diff --git a/conductor/conductor/common/sms.py b/conductor/conductor/common/sms.py index c5eee3a..6e21392 100644 --- a/conductor/conductor/common/sms.py +++ b/conductor/conductor/common/sms.py @@ -111,6 +111,9 @@ def load_secrets(): config.set_override('aafns', secret_dict['music_api']['aafns'], 'music_api') config.set_override('username', secret_dict['sdnc']['username'], 'sdnc') config.set_override('password', secret_dict['sdnc']['password'], 'sdnc') + config.set_override('username', secret_dict['aaf_api']['username'], 'aaf_api') + config.set_override('password', secret_dict['aaf_api']['password'], 'aaf_api') + config.set_override('aaf_conductor_user', secret_dict['aaf_api']['aaf_conductor_user'], 'aaf_api') def delete_secrets(): diff --git a/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py b/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py index 26133bc..84d4c87 100644 --- a/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py +++ b/conductor/conductor/data/plugins/inventory_provider/hpa_utils.py @@ -272,9 +272,9 @@ class HpaMatchProvider(object): req_attr_key, flavor_cfa) if not flavor_feature_attr: flavor_flag = False - if not self._compare_attribute(flavor_feature_attr[0], + elif not self._compare_attribute(flavor_feature_attr[0], req_feature_attr): - flavor_flag = False + flavor_flag = False if not flavor_flag: continue else: diff --git a/conductor/conductor/data/service.py b/conductor/conductor/data/service.py index 07fc873..832b4f8 100644 --- a/conductor/conductor/data/service.py +++ b/conductor/conductor/data/service.py @@ -511,7 +511,9 @@ class DataEndpoint(object): candidate_list[i]["flavor_map"] = {} # Create flavor mapping for label_name to flavor flavor_name = flavor_info.get("flavor-name") + flavor_id = flavor_info.get("flavor-id") candidate_list[i]["flavor_map"][label_name] = flavor_name + candidate_list[i]["flavor_map"]["flavorId"] = flavor_id # Create directives if not exist already if not candidate_list[i].get("all_directives"): candidate_list[i]["all_directives"] = {} @@ -549,9 +551,11 @@ class DataEndpoint(object): directive= {"id": id, "type": type, "directives": ""} + flavor_id_attributes = {"attribute_name": "flavorId", "attribute_value": ""} for ele in directives: if "flavor_directives" in ele.get("type"): flag = True + ele.get("attributes").append(flavor_id_attributes) break else: flag = False @@ -727,4 +731,4 @@ class DataEndpoint(object): # 'note': 'do_something called!', # 'arg': str(arg), # } - # return {'response': res, 'error': False}
\ No newline at end of file + # return {'response': res, 'error': False} diff --git a/conductor/conductor/opts.py b/conductor/conductor/opts.py index 106de2d..d711a4e 100644 --- a/conductor/conductor/opts.py +++ b/conductor/conductor/opts.py @@ -75,7 +75,7 @@ def list_opts(): ('solver', conductor.solver.service.SOLVER_OPTS), ('reservation', conductor.reservation.service.reservation_OPTS), ('aaf_sms', conductor.common.sms.AAF_SMS_OPTS), - ('aaf_authentication', + ('aaf_api', conductor.api.adapters.aaf.aaf_authentication.AAF_OPTS), ('prometheus', conductor.common.prometheus_metrics.METRICS_OPTS), ] diff --git a/conductor/conductor/solver/service.py b/conductor/conductor/solver/service.py index 9d7f13b..8647e4b 100644 --- a/conductor/conductor/solver/service.py +++ b/conductor/conductor/solver/service.py @@ -739,11 +739,11 @@ class SolverService(cotyledon.Service): :param flavor_map: flavor map get :param directives: All the directives get from request ''' - flavor_label = flavor_map.keys() + keys = flavor_map.keys() for ele in directives.get("directives"): for item in ele.get("directives"): if "flavor_directives" in item.get("type"): for attr in item.get("attributes"): attr["attribute_value"] = flavor_map.get(attr["attribute_name"]) \ - if attr.get("attribute_name") in flavor_label else "" + if attr.get("attribute_name") in keys else "" return directives diff --git a/conductor/pom.xml b/conductor/pom.xml index bfcffd4..c1f04a4 100644 --- a/conductor/pom.xml +++ b/conductor/pom.xml @@ -21,13 +21,13 @@ <parent> <groupId>org.onap.optf.has</groupId> - <version>1.2.3-SNAPSHOT</version> + <version>1.2.5-SNAPSHOT</version> <artifactId>optf-has</artifactId> </parent> <groupId>org.onap.optf.has</groupId> <artifactId>optf-has-conductor</artifactId> - <version>1.2.3-SNAPSHOT</version> + <version>1.2.5-SNAPSHOT</version> <name>optf-has-conductor</name> <description>Homing Allocation Service/Conductor</description> |