From 2b3d24bd5b513a5842adb9250b1840f9047a6d55 Mon Sep 17 00:00:00 2001 From: Alex Shatov Date: Fri, 2 Mar 2018 13:46:11 -0500 Subject: 2.2.0 onap-dcae-dcaepolicy-lib - refactoring - removed the following obsolete and unused features = removed policy apply_order parsing = removed policy sorting = removed policy config merge into app-config = removed tracking fields in app-config affected by policies = removed getting config from config.content on microservice = removed org.onap.dcae from license text - simplified the logic flow without policy sorting and without getting policy configs - removed the option to pass the policy configs to plugins = only passing the policy bodies to be included into the policy-notification message - refactoring to reduce function complexity according to sonar - reduced the unit tests to match the new code - coverage is 80% Change-Id: I47729683a45a647b7510edeb85bc018fc7bb8200 Signed-off-by: Alex Shatov Issue-ID: DCAEGEN2-347 --- onap-dcae-dcaepolicy-lib/LICENSE.txt | 2 - onap-dcae-dcaepolicy-lib/README.md | 49 +-- .../onap_dcae_dcaepolicy_lib/__init__.py | 1 - .../onap_dcae_dcaepolicy_lib/dcae_policy.py | 461 ++++----------------- .../onap_dcae_dcaepolicy_lib/policies_output.py | 1 - .../onap_dcae_dcaepolicy_lib/utils.py | 121 ------ onap-dcae-dcaepolicy-lib/pom.xml | 2 +- onap-dcae-dcaepolicy-lib/setup.py | 3 +- onap-dcae-dcaepolicy-lib/tests/__init__.py | 1 - onap-dcae-dcaepolicy-lib/tests/log_ctx.py | 1 - .../tests/mock_cloudify_ctx.py | 2 - onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py | 352 ++-------------- 12 files changed, 128 insertions(+), 868 deletions(-) delete mode 100644 onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/utils.py diff --git a/onap-dcae-dcaepolicy-lib/LICENSE.txt b/onap-dcae-dcaepolicy-lib/LICENSE.txt index c9b8eab..0b6ac42 100644 --- a/onap-dcae-dcaepolicy-lib/LICENSE.txt +++ b/onap-dcae-dcaepolicy-lib/LICENSE.txt @@ -1,6 +1,4 @@ ============LICENSE_START======================================================= -org.onap.dcae -================================================================================ Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/onap-dcae-dcaepolicy-lib/README.md b/onap-dcae-dcaepolicy-lib/README.md index 221cc24..b46f0b1 100644 --- a/onap-dcae-dcaepolicy-lib/README.md +++ b/onap-dcae-dcaepolicy-lib/README.md @@ -71,23 +71,15 @@ APPLICATION_CONFIG = "application_config" SERVICE_COMPONENT_NAME = "service_component_name" @operation -@Policies.gather_policies_to_node +@Policies.gather_policies_to_node() def node_configure(**kwargs): - """decorate with @Policies.gather_policies_to_node on policy consumer node to + """decorate with @Policies.gather_policies_to_node() on policy consumer node to prepopulate runtime_properties[POLICIES] """ - app_config = None - if APPLICATION_CONFIG in ctx.node.properties: - # dockerized blueprint puts the app config into property application_config - app_config = ctx.node.properties.get(APPLICATION_CONFIG) - else: - # CDAP components expect that in property app_config - app_config = ctx.node.properties.get("app_config") - - app_config = Policies.shallow_merge_policies_into(app_config) + app_config = ctx.node.properties.get(APPLICATION_CONFIG) + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - ctx.logger.info("example: applied policy_configs to property app_config: {0}" \ - .format(json.dumps(app_config))) + ctx.logger.info("app_config: {0}".format(json.dumps(app_config))) if SERVICE_COMPONENT_NAME in ctx.instance.runtime_properties: ctx.logger.info("saving app_config({0}) to consul under key={1}" \ @@ -95,16 +87,6 @@ def node_configure(**kwargs): ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME])) DiscoveryClient.put_kv(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME], app_config) - # alternative 1 - use the list of policy configs from policies in runtime_properties - policy_configs = Policies.get_policy_configs() - if policy_configs: - ctx.logger.warn("TBD: apply policy_configs: {0}".format(json.dumps(policy_configs))) - - # alternative 2 - use the policies dict by policy_id from runtime_properties - if POLICIES in ctx.instance.runtime_properties: - policies = ctx.instance.runtime_properties[POLICIES] - ctx.logger.warn("TBD: apply policies: {0}".format(json.dumps(policies))) - ctx.logger.info("deploying the demo component: {0}...".format(ctx.node.id)) demo_app = DemoApp(ctx.node.id) demo_app.start() @@ -133,25 +115,13 @@ APPLICATION_CONFIG = "application_config" SERVICE_COMPONENT_NAME = "service_component_name" @operation -@Policies.update_policies_on_node(configs_only=True) -def policy_update(updated_policies, **kwargs): +@Policies.update_policies_on_node() +def policy_update(updated_policies, removed_policies=None, policies=None, **kwargs): """decorate with @Policies.update_policies_on_node() to update runtime_properties[POLICIES] :updated_policies: contains the list of changed policy-configs when configs_only=True (default). Use configs_only=False to bring the full policy objects in :updated_policies:. """ - app_config = DiscoveryClient.get_value(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME]) - - # This is how to merge the policies into app_config object - app_config = Policies.shallow_merge_policies_into(app_config) - - ctx.logger.info("merged updated_policies {0} into app_config {1}" - .format(json.dumps(updated_policies), json.dumps(app_config))) - - ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - - DiscoveryClient.put_kv(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME], app_config) - # example how to notify the dockerized component about the policy change notify_app_through_script = True if notify_app_through_script: @@ -159,9 +129,10 @@ def policy_update(updated_policies, **kwargs): .format(json.dumps(updated_policies), json.dumps(app_config))) demo_app = DemoApp(ctx.node.id) demo_app.notify_app_through_script( - POLICY_MESSAGE_TYPE, + "policies", updated_policies=updated_policies, - application_config=app_config + removed_policies=removed_policies, + policies=policies ) ``` diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py index 547b16f..f8a2498 100644 --- a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py @@ -1,4 +1,3 @@ -# org.onap.dcae # ================================================================================ # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py index b064157..5a3a0b2 100644 --- a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py @@ -1,4 +1,3 @@ -# org.onap.dcae # ================================================================================ # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ @@ -29,26 +28,18 @@ from cloudify.context import NODE_INSTANCE from cloudify.exceptions import NonRecoverableError from .policies_output import PoliciesOutput -from .utils import Utils POLICIES = 'policies' POLICY_FILTERS = 'policy_filters' POLICIES_FILTERED = 'policies_filtered' -POLICY_APPLY_ORDER = 'policy_apply_order' -POLICY_APPLY_ORDER_CLAUSE = 'policy_apply_order_clause' -POLICY_DEFAULTED_FIELDS = 'policy_defaulted_fields' POLICY_ID = 'policy_id' POLICY_BODY = 'policy_body' POLICY_VERSION = "policyVersion" POLICY_CONFIG = 'config' -POLICY_CONFIG_CONTENT = 'content' -APPLICATION_CONFIG = 'application_config' + POLICY_FILTER = 'policy_filter' POLICY_FILTER_ID = 'policy_filter_id' -POLICY_TYPE = 'policyType' -POLICY_TYPE_MICROSERVICE = 'MicroService' -POLICY_CONFIG_MS = "Config_MS_" POLICY_PERSISTENT = 'policy_persistent' DCAE_POLICY_TYPE = 'dcae.nodes.policy' @@ -69,168 +60,68 @@ class Policies(object): Policies._removed_policies = {} @staticmethod - def _get_config_from_policy(policy): - """returns the config field from policy object""" - policy_body = (policy or {}).get(POLICY_BODY) - if not policy_body: + def _set_policies(policies): + """store the :policies: in :runtime_properties[POLICIES]:""" + if not policies: + if POLICIES in ctx.instance.runtime_properties: + del ctx.instance.runtime_properties[POLICIES] return - policy_config = policy_body.get(POLICY_CONFIG) - policy_type = policy_body.get(POLICY_TYPE) - if not policy_type: - policy_id = policy.get(POLICY_ID) - if policy_id: - policy_type_pos = policy_id.rfind(".") + 1 - if policy_type_pos and policy_id.startswith(POLICY_CONFIG_MS, policy_type_pos): - policy_type = POLICY_TYPE_MICROSERVICE - - if policy_type == POLICY_TYPE_MICROSERVICE and isinstance(policy_config, dict): - return policy_config.get(POLICY_CONFIG_CONTENT) - - return policy_config + ctx.instance.runtime_properties[POLICIES] = policies @staticmethod - def _store_policy_apply_order_clause(policy_apply_order_path): - """ - Find the field :policy_apply_order_path: that is provided as an optional parameter - to gather_policies_to_node decorator. - - Parse the field-pathes found in the :policy_apply_order_path: field. - - Store the result into :runtime_properties[POLICY_APPLY_ORDER_CLAUSE]: - - Example: - policy_apply_order_path = "docker_config:policy:apply_order" - will take the list of field-pathes from the field - properties: - docker_config: - policy: - apply_order: - """ - if not policy_apply_order_path: - return - - policy_apply_order_clause = Utils.get_field_value( - dict(ctx.node.properties), - policy_apply_order_path - ) - - if not policy_apply_order_clause: - ctx.logger.warn("not found policy_apply_order_path: {0} in node.properties" - .format(policy_apply_order_path)) - return - - ctx.instance.runtime_properties[POLICY_APPLY_ORDER_CLAUSE] = policy_apply_order_clause + def _add_policy(policy_id, policy, policy_persistent, policies): + """only add the latest version of policy to policies""" + prev_policy = policies.get(policy_id) + prev_policy_persistent = (prev_policy or {}).get(POLICY_PERSISTENT) + + if not prev_policy \ + or (policy_persistent and not prev_policy_persistent) \ + or (policy_persistent == prev_policy_persistent and policy.get(POLICY_BODY)): + policy = deepcopy(policy) + policy[POLICY_PERSISTENT] = policy_persistent + policies[policy_id] = policy @staticmethod - def _set_policy_apply_order(policies): - """ - Calculates, sorts and stores the policy_apply_order for policies. - - Sorting is done based on the list of field-pathes - specified in :runtime_properties[POLICY_APPLY_ORDER_CLAUSE]: - - The apply_order field is expected to be formatted as the list of strings. - Each string can contain the path to the field inside the policy_body object - with the same delimiter of ":" (semicolon). - To convert the field to decimal, use ::number suffix after the field name. - To specify the descending order, add "desc" after the whitespace. - - Example: - apply_order = ["matchingConditions:priority::number desc", - "config:foo desc nulls-last", "config:db_client"] - - this will return the policies starting with the highest decimal value in "priority" - field inside the "matchingConditions". - Then the policies with the same "priority" values will be sorted in descending order - by the string value in the field "foo" found inside the "config". - Then the policies with the same "priority" and "foo" values will be sorted - by the string value in the field "db_client" found inside the "config". - Then the policies with the same "priority" and "foo" and "db_client" field values will - further be always sorted by "policy_id" - no need to specify that in apply_order. - Sorting by policy_id insures the uniqueness and predictability of the policy apply_order. - - An invalid field-path will result in the value of None that brings this record upfront. - """ - policy_apply_order = [policy_id - for (policy_id, policy) in policies.iteritems() - if Policies._get_config_from_policy(policy)] - - if not policy_apply_order: - ctx.instance.runtime_properties[POLICY_APPLY_ORDER] = policy_apply_order - return - - policy_apply_order.sort() - - policy_apply_order_clause = ctx.instance.runtime_properties.get(POLICY_APPLY_ORDER_CLAUSE) - if not policy_apply_order_clause: - ctx.instance.runtime_properties[POLICY_APPLY_ORDER] = policy_apply_order + def _gather_policy(target, policies): + """adds the policy from dcae.nodes.policy node to policies""" + if DCAE_POLICY_TYPE not in target.node.type_hierarchy: return + policy_id = target.node.properties.get(POLICY_ID) + if not policy_id: + return True + policy = deepcopy(dict(target.node.properties)) + policy_body = target.instance.runtime_properties.get(POLICY_BODY) + if policy_body: + policy[POLICY_BODY] = policy_body - if not isinstance(policy_apply_order_clause, list): - policy_apply_order_clause = [policy_apply_order_clause] - - for clause_item in reversed(policy_apply_order_clause): - f_path, f_type, desc, n_last = Utils.parse_clause_item(clause_item) - - if not f_path: - continue - - policy_apply_order.sort( - key=lambda policy_id, fpath=f_path, ftype=f_type, reverse=desc, nulls_last=n_last: - Utils.key_with_none_in_sort( - reverse, nulls_last, - Utils.get_field_value( - policies.get(policy_id, {}).get(POLICY_BODY, {}), - fpath, - field_type=ftype - ) - ), reverse=desc - ) - - ctx.instance.runtime_properties[POLICY_APPLY_ORDER] = policy_apply_order + Policies._add_policy(policy_id, policy, True, policies) + return True @staticmethod - def _set_policy_defaulted_fields(policies): - """ - Keeps track and stores the dict of field names of removed policies into - :runtime_properties[POLICY_DEFAULTED_FIELDS]: - """ - policy_defaulted_fields = ctx.instance.runtime_properties.get(POLICY_DEFAULTED_FIELDS, {}) - policy_defaulted_fields.update( - (field_name, True) - for policy in Policies._removed_policies.itervalues() - for field_name in Policies._get_config_from_policy(policy) or {} - ) - if policies: - for policy in policies.itervalues(): - for field_name in Policies._get_config_from_policy(policy) or {}: - if field_name in policy_defaulted_fields: - del policy_defaulted_fields[field_name] - - ctx.instance.runtime_properties[POLICY_DEFAULTED_FIELDS] = policy_defaulted_fields - - @staticmethod - def _set_policies(policies): - """ - store the :policies: in :runtime_properties[POLICIES]: - - and build an index on policies into :runtime_properties[POLICY_APPLY_ORDER]: - - and keep track of fields from previously :removed: policy-configs in - :runtime_properties[POLICY_DEFAULTED_FIELDS]: to reset them to default values - on merging the policies into config - """ - Policies._set_policy_defaulted_fields(policies) - if not policies: - if POLICIES in ctx.instance.runtime_properties: - del ctx.instance.runtime_properties[POLICIES] - if POLICY_APPLY_ORDER in ctx.instance.runtime_properties: - del ctx.instance.runtime_properties[POLICY_APPLY_ORDER] + def _gather_policies(target, policies, policy_filters): + """adds the policies and policy-filter from dcae.nodes.policies node to policies""" + if DCAE_POLICIES_TYPE not in target.node.type_hierarchy: return - ctx.instance.runtime_properties[POLICIES] = policies - Policies._set_policy_apply_order(policies) + property_policy_filter = target.node.properties.get(POLICY_FILTER) + if property_policy_filter: + policy_filter = dict( + (k, v) for (k, v) in dict(property_policy_filter).iteritems() + if v or isinstance(v, (int, float)) + ) + if policy_filter: + policy_filters[target.instance.id] = { + POLICY_FILTER_ID : target.instance.id, + POLICY_FILTER : deepcopy(policy_filter) + } + + filtered_policies = target.instance.runtime_properties.get(POLICIES_FILTERED) + if not filtered_policies or not isinstance(filtered_policies, dict): + return True + for (policy_id, policy) in filtered_policies.iteritems(): + Policies._add_policy(policy_id, policy, False, policies) + return True @staticmethod def _get_policy_bodies_dict(policies): @@ -243,7 +134,7 @@ class Policies(object): ) @staticmethod - def gather_policies_to_node(policy_apply_order_path=None): + def gather_policies_to_node(): """ decorate with @Policies.gather_policies_to_node() to gather the policies from dcae.nodes.policy nodes this node depends on. @@ -251,65 +142,12 @@ class Policies(object): Places the policies into runtime_properties["policies"]. Stores :policies data in consul-kv - - Call Policies.calc_latest_application_config() to apply policies onto application_config. """ def gather_policies_decorator(func): """the decorator""" if not func: return - def add_policy(policy_id, policy, policy_persistent, policies): - """only add the latest version of policy to policies""" - prev_policy = policies.get(policy_id) - prev_policy_persistent = (prev_policy or {}).get(POLICY_PERSISTENT) - - if not prev_policy \ - or (policy_persistent and not prev_policy_persistent) \ - or (policy_persistent == prev_policy_persistent and policy.get(POLICY_BODY)): - policy = deepcopy(policy) - policy[POLICY_PERSISTENT] = policy_persistent - policies[policy_id] = policy - - def gather_policy(target, policies): - """adds the policy from dcae.nodes.policy node to policies""" - if DCAE_POLICY_TYPE not in target.node.type_hierarchy: - return - policy_id = target.node.properties.get(POLICY_ID) - if not policy_id: - return True - policy = deepcopy(dict(target.node.properties)) - policy_body = target.instance.runtime_properties.get(POLICY_BODY) - if policy_body: - policy[POLICY_BODY] = policy_body - - add_policy(policy_id, policy, True, policies) - return True - - def gather_policies(target, policies, policy_filters): - """adds the policies and policy-filter from dcae.nodes.policies node to policies""" - if DCAE_POLICIES_TYPE not in target.node.type_hierarchy: - return - - property_policy_filter = target.node.properties.get(POLICY_FILTER) - if property_policy_filter: - policy_filter = dict( - (k, v) for (k, v) in dict(property_policy_filter).iteritems() - if v or isinstance(v, (int, float)) - ) - if policy_filter: - policy_filters[target.instance.id] = { - POLICY_FILTER_ID : target.instance.id, - POLICY_FILTER : deepcopy(policy_filter) - } - - filtered_policies = target.instance.runtime_properties.get(POLICIES_FILTERED) - if not filtered_policies or not isinstance(filtered_policies, dict): - return True - for (policy_id, policy) in filtered_policies.iteritems(): - add_policy(policy_id, policy, False, policies) - return True - @wraps(func) def wrapper(*args, **kwargs): """gather and save the policies from dcae.nodes.policy nodes this node related to""" @@ -319,13 +157,11 @@ class Policies(object): policies_outputted = False policy_bodies = [] try: - Policies._store_policy_apply_order_clause(policy_apply_order_path) - policies = {} policy_filters = {} for rel in ctx.instance.relationships: - _ = gather_policy(rel.target, policies) \ - or gather_policies(rel.target, policies, policy_filters) + _ = Policies._gather_policy(rel.target, policies) \ + or Policies._gather_policies(rel.target, policies, policy_filters) Policies._set_policies(policies) if policy_filters: @@ -357,8 +193,7 @@ class Policies(object): Policies._init() if not updated_policies and not removed_policies and not added_policies: - ctx.logger.error( - "update_policies_on_ctx - no updated, added, or removed policies received") + ctx.logger.error("update_policies_on_ctx - no updated, added, or removed policies received") return updated_policies = updated_policies or [] @@ -432,20 +267,21 @@ class Policies(object): PoliciesOutput.store_policies(ACTION_UPDATED, policy_bodies) @staticmethod - def update_policies_on_node(configs_only=False): + def update_policies_on_node(): """ - decorate each policy_update operation with @Policies.update_policies_on_node to + decorate each policy_update operation with @Policies.update_policies_on_node() to filter out the updated_policies to only what applies to the current node instance, update runtime_properties["policies"] updates :policies data in consul-kv - :configs_only: - set to True if expect to see only the config in updated_policies - instead of the whole policy_body object (False) - Passes through the filtered list of updated_policies that apply to the current node instance - :updated_policies: contains the list of changed policy-configs when configs_only=True. + :updated_policies: contains the list of changed policy_bodies + + :removed_policies: contains the list of removed policy_bodies + + :policies: contains the list of current policy_bodies """ def update_policies_decorator(func): """actual decorator""" @@ -453,10 +289,7 @@ class Policies(object): return @wraps(func) - def wrapper(updated_policies=None, - added_policies=None, - removed_policies=None, - **kwargs): + def wrapper(updated_policies=None, added_policies=None, removed_policies=None, **kwargs): """update matching policies on the node""" if ctx.type != NODE_INSTANCE: raise NonRecoverableError("can only invoke update_policies_on_node on node") @@ -464,24 +297,13 @@ class Policies(object): try: Policies._update_policies(updated_policies, added_policies, removed_policies) - updated_policies = deepcopy(Policies._get_ordered_policies( + updated_policies = Policies.get_policy_bodies( selected_policies=Policies._updated_policies - )) - removed_policies = deepcopy(Policies._removed_policies.values()) - - if configs_only: - updated_policies = Utils.remove_empties( - [Policies._get_config_from_policy(policy) - for policy in updated_policies] - ) - removed_policies = [Policies._get_config_from_policy(policy) - for policy in removed_policies] - else: - updated_policies = Utils.remove_empties( - [policy.get(POLICY_BODY) for policy in updated_policies] - ) - removed_policies = [policy.get(POLICY_BODY) - for policy in removed_policies] + ) + + removed_policies = Policies.get_policy_bodies( + selected_policies=Policies._removed_policies + ) except Exception as ex: error = "Failed to update the policies {0}".format(str(ex)) @@ -489,18 +311,17 @@ class Policies(object): raise NonRecoverableError(error) if updated_policies or removed_policies: - return func( - updated_policies, - removed_policies=removed_policies, - policies=Policies.get_policy_bodies(), - **kwargs) + return func(updated_policies, + removed_policies=removed_policies, + policies=Policies.get_policy_bodies(), + **kwargs) return wrapper return update_policies_decorator @staticmethod def cleanup_policies_on_node(func): """ - decorate each policy_update operation with @Policies.cleanup_policies_on_node to + decorate each delete operation with @Policies.cleanup_policies_on_node to remove :policies data in consul-kv """ if not func: @@ -508,128 +329,24 @@ class Policies(object): @wraps(func) def wrapper(**kwargs): - """cleanup policies in consul-kv""" - if ctx.type != NODE_INSTANCE: - raise NonRecoverableError("can only invoke cleanup_policies_on_node on node") - - try: - PoliciesOutput.delete_policies() - except Exception as ex: - error = "Failed to cleanup policies in consul-kv {0}".format(str(ex)) - ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) + """remove policies in consul-kv""" + if ctx.type == NODE_INSTANCE: + try: + PoliciesOutput.delete_policies() + except Exception as ex: + error = "Failed to cleanup policies in consul-kv {0}".format(str(ex)) + ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) return func(**kwargs) return wrapper @staticmethod - def _get_ordered_policies(selected_policies=None): - """returns the ordered list of selected policies from the runtime policies""" - policies = ctx.instance.runtime_properties.get(POLICIES) - apply_order = ctx.instance.runtime_properties.get(POLICY_APPLY_ORDER) - if not policies or not apply_order: - return [] - - if selected_policies is None: - return [policies[policy_id] for policy_id in apply_order] - - if not selected_policies: - return [] - - return [policies[policy_id] for policy_id in apply_order if policy_id in selected_policies] + def get_policy_bodies(selected_policies=None): + """returns the list of policy_body objects if policy_body exists""" + if isinstance(selected_policies, dict): + return deepcopy([policy.get(POLICY_BODY) + for policy in selected_policies.values() if policy.get(POLICY_BODY)]) - @staticmethod - def get_policy_configs(): - """returns the ordered list of policy configs from the runtime policies""" - if ctx.type != NODE_INSTANCE: - return [] - - ordered_policies = Policies._get_ordered_policies() - return Utils.remove_empties( - [Policies._get_config_from_policy(policy) - for policy in ordered_policies] - ) - - @staticmethod - def get_policy_bodies(): - """returns the ordered list of policy_body objects if policy_body exists""" - return [policy.get(POLICY_BODY) - for policy in Policies._get_ordered_policies() - if policy.get(POLICY_BODY)] - - @staticmethod - def shallow_merge_policies_into(config, default_config=None): - """ - shallow merge the :policy configs: (dict) into :config: that is expected to be a dict. - - the fields listed in :runtime_properties[POLICY_DEFAULTED_FIELDS]: - that where ever changed by policy-configs are initially reset to default values - found in :default_config: or :node.properties[APPLICATION_CONFIG]: - on merging the policies into config - """ - if config is None: - config = {} - - policy_configs = Policies.get_policy_configs() - - if not config or not isinstance(config, dict): - ctx.logger.warn("unexpected config {0} to merge the policy_configs {1} into" \ - .format(json.dumps(config), json.dumps(policy_configs or []))) - return config - - defaulted_fields = ctx.instance.runtime_properties.get(POLICY_DEFAULTED_FIELDS) - if defaulted_fields: - if default_config is None or not isinstance(default_config, dict): - default_config = dict(ctx.node.properties.get(APPLICATION_CONFIG, {})) - ctx.logger.info("using default_config from node.properties[{0}]: {1}" - .format(APPLICATION_CONFIG, json.dumps(default_config))) - if default_config and isinstance(default_config, dict): - for defaulted_field in defaulted_fields: - if defaulted_field in default_config and defaulted_field in config: - config[defaulted_field] = deepcopy(default_config.get(defaulted_field)) - - ctx.logger.info("inited config {0} on {1} {2} from {3}" - .format(json.dumps(config), - POLICY_DEFAULTED_FIELDS, - json.dumps(defaulted_fields), - json.dumps(default_config))) - - if not policy_configs: - ctx.logger.warn("no policies to merge to config {0}".format(json.dumps(config))) - return config - - for policy_config in policy_configs: - if not isinstance(policy_config, dict): - ctx.logger.warn("skipped unexpected format of policy_config {0} for config: {1}" \ - .format(json.dumps(policy_config), json.dumps(config))) - continue - - ctx.logger.info("applying policy_config {0} to config {1}" \ - .format(json.dumps(policy_config), json.dumps(config))) - for (policy_key, policy_value) in policy_config.iteritems(): - if policy_key not in config or policy_value is None: - ctx.logger.warn("skipped unexpected policy({0}, {1}) for config: {2}" \ - .format(policy_key, json.dumps(policy_value), json.dumps(config))) - continue - config[policy_key] = deepcopy(policy_value) - - return config - - @staticmethod - def calc_latest_application_config(application_config_name=None): - """ - shallow merge the policy configs (dict) into config that is expected to be a dict - - if :application_config_name: is not provided, - the runtime property :application_config: on the node instance is used as initial config - """ - if not application_config_name: - application_config_name = APPLICATION_CONFIG - - config = deepcopy(dict(ctx.instance.runtime_properties.get(application_config_name, {}))) - if not config: - config = deepcopy(dict(ctx.node.properties.get(application_config_name, {}))) - - ctx.logger.info("going to merge policies over {0}: {1}" \ - .format(application_config_name, json.dumps(config))) - - return Policies.shallow_merge_policies_into(config) + policies = ctx.instance.runtime_properties.get(POLICIES, {}) + return deepcopy([policy.get(POLICY_BODY) + for policy in policies.values() if policy.get(POLICY_BODY)]) diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py index 7a1a8e8..dd82f5b 100644 --- a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py @@ -1,4 +1,3 @@ -# org.onap.dcae # ================================================================================ # Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/utils.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/utils.py deleted file mode 100644 index 7f12347..0000000 --- a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/utils.py +++ /dev/null @@ -1,121 +0,0 @@ -# org.onap.dcae -# ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. -# ================================================================================ -# 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. -# ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - -"""generic utils to be used by dcae_policy decorators for the policy lifecycle in cloudify""" - -from copy import deepcopy -from decimal import Decimal, DecimalException - -FIELD_NAME_DELIMITER = ":" -FIELD_TYPE_DELIMITER = "::" -FIELD_TYPE_NUMBER = "number" -KEYWORD_DESC = "desc" -KEYWORD_NULLS_LAST = "nulls-last" - -class Utils(object): - """generic static class used for policy operations""" - - @staticmethod - def remove_empties(any_list): - """returns the any_list without empty elements""" - return [element for element in any_list or [] if element] - - @staticmethod - def get_field_value(parent, field_path, field_type=None): - """ - Find and return the field :field_path: under :parent: - - Optionally, converts the field value to field_type. - - Parser of the :field_path: is using the delimiter ":" (semicolon) - - Example: - parent = ctx.node.properties - field_path = "docker_config:policy:apply_order" - - will return the value of the apply_order field under the ctx.node.properties in - - properties: - docker_config: - policy: - apply_order - """ - if not parent or not field_path or not isinstance(parent, dict): - return - - field_path = Utils.remove_empties([ - path.strip() for path in field_path.split(FIELD_NAME_DELIMITER) - ]) - - if not field_path: - return - - field_value = None - field_idx = len(field_path) - 1 - for (idx, field_name) in enumerate(field_path): - parent = parent.get(field_name) - if idx == field_idx: - field_value = deepcopy(parent) - if field_type in [FIELD_TYPE_NUMBER] and isinstance(field_value, (str, unicode)): - try: - field_value = Decimal(field_value) - except DecimalException: - pass - elif not parent or not isinstance(parent, dict): - return - return field_value - - @staticmethod - def parse_clause_item(clause_item): - """ - Parses: the :clause_item: in policy_apply_order_clause - and returns (field_path, field_type, reverse, nulls_last) - - delimiters: are whitespaces, "::" - - nulls-first is the default sorting order - - :clause_item: format is [:: ] [desc] [nulls-last] - - Examples: "config:db_client" versus "config:foo desc" versus - "matchingConditions:priority::number desc nulls-last" - """ - field_path = field_type = desc = nulls_last = None - - if not clause_item or not isinstance(clause_item, (str, unicode)): - return field_path, field_type, bool(desc), bool(nulls_last) - - for idx, token in enumerate(clause_item.split()): - if idx == 0: - split_for_type = token.split(FIELD_TYPE_DELIMITER) - field_path = split_for_type[0] - field_type = split_for_type[1] if len(split_for_type) > 1 else None - elif token == KEYWORD_DESC: - desc = True - elif token == KEYWORD_NULLS_LAST: - nulls_last = True - return field_path, field_type, bool(desc), bool(nulls_last) - - @staticmethod - def key_with_none_in_sort(reverse, nulls_last, value): - """ - constructs tuple for proper placement of None values (last versus first) - in the sorted list of values regardless of the :reverse: - """ - return reverse == nulls_last or value is None, value diff --git a/onap-dcae-dcaepolicy-lib/pom.xml b/onap-dcae-dcaepolicy-lib/pom.xml index f89b157..a60d848 100644 --- a/onap-dcae-dcaepolicy-lib/pom.xml +++ b/onap-dcae-dcaepolicy-lib/pom.xml @@ -28,7 +28,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. org.onap.dcaegen2.utils onap-dcae-dcaepolicy-lib dcaegen2-utils-onap-dcae-dcaepolicy-lib - 2.1.0-SNAPSHOT + 2.2.0-SNAPSHOT http://maven.apache.org diff --git a/onap-dcae-dcaepolicy-lib/setup.py b/onap-dcae-dcaepolicy-lib/setup.py index 8a82d16..eed69f0 100644 --- a/onap-dcae-dcaepolicy-lib/setup.py +++ b/onap-dcae-dcaepolicy-lib/setup.py @@ -1,4 +1,3 @@ -# org.onap.dcae # ================================================================================ # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ @@ -24,7 +23,7 @@ from setuptools import setup, find_packages setup( name='onap-dcae-dcaepolicy-lib', description='lib of policy decorators to be used by cloudify plugins of dcae controller', - version="2.1.0", + version="2.2.0", author='Alex Shatov', author_email="alexs@att.com", license='Apache 2', diff --git a/onap-dcae-dcaepolicy-lib/tests/__init__.py b/onap-dcae-dcaepolicy-lib/tests/__init__.py index f5c50fd..6c84c78 100644 --- a/onap-dcae-dcaepolicy-lib/tests/__init__.py +++ b/onap-dcae-dcaepolicy-lib/tests/__init__.py @@ -1,4 +1,3 @@ -# org.onap.dcae # ================================================================================ # Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ diff --git a/onap-dcae-dcaepolicy-lib/tests/log_ctx.py b/onap-dcae-dcaepolicy-lib/tests/log_ctx.py index 51d3c67..0d82687 100644 --- a/onap-dcae-dcaepolicy-lib/tests/log_ctx.py +++ b/onap-dcae-dcaepolicy-lib/tests/log_ctx.py @@ -1,4 +1,3 @@ -# org.onap.dcae # ================================================================================ # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ diff --git a/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py b/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py index 54feb64..50aa46e 100644 --- a/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py +++ b/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py @@ -1,6 +1,4 @@ # ============LICENSE_START======================================================= -# org.onap.dcae -# ================================================================================ # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py b/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py index 4af4855..81958f0 100644 --- a/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py +++ b/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py @@ -1,6 +1,4 @@ # ============LICENSE_START======================================================= -# org.onap.dcae -# ================================================================================ # Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -33,7 +31,6 @@ from cloudify.state import current_ctx from onap_dcae_dcaepolicy_lib import dcae_policy from onap_dcae_dcaepolicy_lib.dcae_policy import Policies -from onap_dcae_dcaepolicy_lib.utils import Utils from tests.log_ctx import CtxLogger from tests.mock_cloudify_ctx import (TARGET_NODE_ID, TARGET_NODE_NAME, MockCloudifyContextFull) @@ -43,9 +40,6 @@ POLICY_VERSION = "policyVersion" POLICY_NAME = "policyName" POLICY_BODY = 'policy_body' POLICY_CONFIG = 'config' -DOCKER_CONFIG = "docker_config" -POLICY = "policy" -APPLY_ORDER = "apply_order" MONKEYED_POLICY_ID = 'monkeyed.Config_peach' MONKEYED_POLICY_ID_2 = 'monkeyed.Config_peach_2' @@ -172,18 +166,20 @@ class MonkeyedNode(object): runtime_properties=runtime_properties ) +def get_app_config(): + """just get the config""" + config = copy.deepcopy(dict(ctx.instance.runtime_properties.get(APPLICATION_CONFIG, {}))) + if not config: + config = copy.deepcopy(dict(ctx.node.properties.get(APPLICATION_CONFIG, {}))) + return config + def operation_node_configure(**kwargs): """do the node-configure operation""" ctx.logger.info("operation_node_configure kwargs: {0}".format(kwargs)) - app_config = Policies.calc_latest_application_config() + app_config = get_app_config() ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - ctx.logger.info("applied policy_configs to property app_config: {0}" \ - .format(json.dumps(app_config))) - - policy_configs = Policies.get_policy_configs() - if policy_configs: - ctx.logger.warn("TBD: apply policy_configs: {0}".format(json.dumps(policy_configs))) + ctx.logger.info("property app_config: {0}".format(json.dumps(app_config))) @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='exe_task') @Policies.gather_policies_to_node() @@ -192,7 +188,7 @@ def node_configure_default_order(**kwargs): operation_node_configure(**kwargs) @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='exe_task') -@Policies.gather_policies_to_node(policy_apply_order_path="docker_config:policy:apply_order") +@Policies.gather_policies_to_node() def node_configure(**kwargs): """decorate with @Policies.gather_policies_to_node on policy consumer node to bring all policies to runtime_properties["policies"] @@ -200,113 +196,57 @@ def node_configure(**kwargs): operation_node_configure(**kwargs) @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='exe_task') -@Policies.gather_policies_to_node(policy_apply_order_path="docker_config:junk:junk") +@Policies.gather_policies_to_node() def node_configure_wrong_order_path(**kwargs): """wrong data in param policy_apply_order_path""" operation_node_configure(**kwargs) @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='exe_task') -@Policies.gather_policies_to_node(policy_apply_order_path=" ") +@Policies.gather_policies_to_node() def node_configure_empty_order_path(**kwargs): """wrong data in param policy_apply_order_path""" operation_node_configure(**kwargs) @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='execute_operation') -@Policies.update_policies_on_node(configs_only=True) +@Policies.update_policies_on_node() def policy_update(updated_policies, removed_policies=None, **kwargs): """decorate with @Policies.update_policies_on_node() to update runtime_properties["policies"] :updated_policies: contains the list of changed policy-configs when configs_only=True (default). - Use configs_only=False to bring the full policy objects in :updated_policies:. - - Use :Policies.shallow_merge_policies_into(): to merge the updated_policies into app_config """ # This is how to merge the policies into default app_config object # (runtime_properties[APPLICATION_CONFIG] = application_config) - app_config = Policies.calc_latest_application_config() - - ctx.logger.info("merged updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) + app_config = get_app_config() + ctx.logger.info("app_config {0}".format(json.dumps(app_config))) ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='execute_operation') -@Policies.update_policies_on_node(configs_only=False) +@Policies.update_policies_on_node() def policy_update_not_only_config(updated_policies, removed_policies=None, **kwargs): """decorate with @Policies.update_policies_on_node() to update runtime_properties["policies"] :updated_policies: contains the list of changed policy-configs when configs_only=True (default). - Use configs_only=False to bring the full policy objects in :updated_policies:. - - Use :Policies.shallow_merge_policies_into(): to merge the updated_policies into app_config """ # This is how to merge the policies into default app_config object # (runtime_properties[APPLICATION_CONFIG] = application_config) - app_config = Policies.calc_latest_application_config() - - ctx.logger.info("merged updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) + app_config = get_app_config() + ctx.logger.info("app_config {0}".format(json.dumps(app_config))) ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='execute_operation') -@Policies.update_policies_on_node(configs_only=False) -def policy_update_many_calcs(updated_policies, removed_policies=None, **kwargs): +@Policies.update_policies_on_node() +def policy_update_many_calcs(updated_policies, removed_policies=None, policies=None, **kwargs): """decorate with @Policies.update_policies_on_node() to update runtime_properties["policies"] :updated_policies: contains the list of changed policy-configs when configs_only=True (default). - Use configs_only=False to bring the full policy objects in :updated_policies:. - - Use :Policies.shallow_merge_policies_into(): to merge the updated_policies into app_config """ - # This is how to merge the policies into default app_config object - # (runtime_properties[APPLICATION_CONFIG] = application_config) - app_config = Policies.calc_latest_application_config() - - ctx.logger.info("merged updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) + app_config = get_app_config() + ctx.logger.info("app_config {0}".format(json.dumps(app_config))) ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - app_config = Policies.calc_latest_application_config(APPLICATION_CONFIG) - ctx.logger.info("merged again updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) - - app_config = Policies.calc_latest_application_config(APPLICATION_CONFIG) - ctx.logger.info("merged again updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) - - app_config = Policies.shallow_merge_policies_into(None) - ctx.logger.info("merged to empty updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) - - app_config = ctx.instance.runtime_properties[APPLICATION_CONFIG] - app_config = Policies.shallow_merge_policies_into(app_config, default_config={}) - ctx.logger.info( - "merged with empty defaults updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) - - app_config = ctx.instance.runtime_properties[APPLICATION_CONFIG] - app_config = Policies.shallow_merge_policies_into(app_config, - default_config={"unexpected":"foo"}) - ctx.logger.info( - "merged with unexpected defaults updated_policies {0}, removed_policies {1} into config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) - - app_config = ctx.instance.runtime_properties[APPLICATION_CONFIG] - app_config = Policies.shallow_merge_policies_into(app_config) - ctx.logger.info("merged 3rd time updated_policies {0}, removed_policies {1} into app_config {2}" - .format(json.dumps(updated_policies), json.dumps(removed_policies), - json.dumps(app_config))) - class CurrentCtx(object): """cloudify context""" _node_ms = None @@ -492,12 +432,7 @@ class CurrentCtx(object): CurrentCtx._node_ms = MonkeyedNode( 'test_ms_id', 'test_ms_name', "ms.nodes.type", - {DOCKER_CONFIG: {POLICY: { - APPLY_ORDER: [ - "matchingConditions:priority::number desc", - "config:db_client nulls-last", - "config:policy_updated_to_ver"]}}, - APPLICATION_CONFIG: MonkeyedPolicyBody.create_policy_body( + {APPLICATION_CONFIG: MonkeyedPolicyBody.create_policy_body( "no_policy", db_port="123", weather="snow")[POLICY_CONFIG] }, relationships @@ -510,31 +445,6 @@ class CurrentCtx(object): """reset context""" current_ctx.set(CurrentCtx._node_ms.ctx) -def test_utils(): - """test utils""" - field_value = Utils.get_field_value( - { - "before":"bubu", - "pre":{"field":"hehe"}, - "hello":{"field":"haha"}, - "post":{"field":"hmmm"}, - "after":"bebe" - }, - "hello:field") - assert field_value == "haha" - - field_value = Utils.get_field_value(None, None) - assert field_value is None - - field_value = Utils.get_field_value({"hello":{"field":"haha"}}, "wrong_root:field") - assert field_value is None - - field_value = Utils.get_field_value({"hello":{"field":None}}, "hello:field") - assert field_value is None - - field_value = Utils.get_field_value({"hello":{"field":None}}, "hello:field::number") - assert field_value is None - def cfy_ctx(include_bad=True, include_good=True): """test and safely clean up""" def cfy_ctx_decorator(func): @@ -570,12 +480,6 @@ def test_gather_policies_to_node(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_2] - @cfy_ctx(include_bad=True) def test_policies_wrong_order(): """test gather_policies_to_node""" @@ -588,12 +492,6 @@ def test_policies_wrong_order(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_2] - @cfy_ctx(include_bad=True) def test_policies_empty_order(): """test gather_policies_to_node""" @@ -606,56 +504,6 @@ def test_policies_empty_order(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_2] - -@cfy_ctx(include_bad=True) -def test_policies_damaged_order(): - """test gather_policies_to_node""" - ctx.node.properties[DOCKER_CONFIG][POLICY][APPLY_ORDER] = " " - - runtime_properties = ctx.instance.runtime_properties - ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) - - node_configure() - - ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) - - assert dcae_policy.POLICIES in runtime_properties - policies = runtime_properties[dcae_policy.POLICIES] - ctx.logger.info("policies: {0}".format(json.dumps(policies))) - - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_2] - -@cfy_ctx(include_bad=True) -def test_policies_bad_order(): - """test gather_policies_to_node""" - ctx.node.properties[DOCKER_CONFIG][POLICY][APPLY_ORDER] = [" ", "", "ha he", "hu::mu dah"] - - runtime_properties = ctx.instance.runtime_properties - ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) - - node_configure() - - ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) - - assert dcae_policy.POLICIES in runtime_properties - policies = runtime_properties[dcae_policy.POLICIES] - ctx.logger.info("policies: {0}".format(json.dumps(policies))) - - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_2] - @cfy_ctx(include_bad=True) def test_policies_to_node(): """test gather_policies_to_node""" @@ -668,12 +516,6 @@ def test_policies_to_node(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - assert MONKEYED_POLICY_ID in policies expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID, priority="1") policy = policies[MONKEYED_POLICY_ID] @@ -718,12 +560,6 @@ def test_update_policies(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, False, priority="1") @@ -743,7 +579,6 @@ def test_update_policies(): ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) assert MONKEYED_POLICY_ID_M not in policies - # assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID_M]) is None assert MONKEYED_POLICY_ID_M_2 in policies policy = policies[MONKEYED_POLICY_ID_M_2] @@ -773,12 +608,6 @@ def test_update_policies(): assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_M_2] - @cfy_ctx(include_bad=True) def test_update_not_only_config(): """test policy_update""" @@ -791,12 +620,6 @@ def test_update_not_only_config(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, False, priority="1") @@ -816,7 +639,6 @@ def test_update_not_only_config(): ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) assert MONKEYED_POLICY_ID_M not in policies - # assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID_M]) is None assert MONKEYED_POLICY_ID_M_2 in policies policy = policies[MONKEYED_POLICY_ID_M_2] @@ -846,12 +668,6 @@ def test_update_not_only_config(): assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_M_2] - @cfy_ctx(include_bad=True) def test_update_policies_not(): """test policy_update - ignore all policies with junk params""" @@ -867,15 +683,8 @@ def test_update_policies_not(): ctx.logger.info("policies: {0}".format(json.dumps(policies))) ctx.logger.info("app_config: {0}".format(json.dumps(app_config))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - expected_policies = copy.deepcopy(policies) expected_app_config = copy.deepcopy(app_config) - expected_policy_apply_order = copy.deepcopy(policy_apply_order) existing_policy = MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID, priority="1") damaged_policy = MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_2) @@ -914,11 +723,6 @@ def test_update_policies_not(): assert MonkeyedPolicyBody.is_the_same_dict(app_config, expected_app_config) assert MonkeyedPolicyBody.is_the_same_dict(expected_app_config, app_config) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == expected_policy_apply_order - @cfy_ctx(include_bad=True) def test_update_many_calcs(): """test policy_update""" @@ -931,12 +735,6 @@ def test_update_many_calcs(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, False, priority="1") @@ -956,7 +754,6 @@ def test_update_many_calcs(): ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) assert MONKEYED_POLICY_ID_M not in policies - # assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID_M]) is None assert MONKEYED_POLICY_ID_M_2 in policies policy = policies[MONKEYED_POLICY_ID_M_2] @@ -986,12 +783,6 @@ def test_update_many_calcs(): assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID, MONKEYED_POLICY_ID_M_2] - @cfy_ctx(include_bad=True) def test_remove_all_policies(): """test policy_update - remove all policies""" @@ -1011,18 +802,7 @@ def test_remove_all_policies(): ctx.logger.info("removed: {0}".format(remove_policy_ids)) ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) assert dcae_policy.POLICIES in runtime_properties - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - assert runtime_properties[dcae_policy.POLICY_APPLY_ORDER] == [] - assert dcae_policy.POLICY_DEFAULTED_FIELDS in runtime_properties - assert Policies.get_policy_configs() == [] - - defaulted_fields = runtime_properties[dcae_policy.POLICY_DEFAULTED_FIELDS] - expected_defaulted_fields = dict( - (k, True) - for k in MonkeyedPolicyBody.create_policy_body(MONKEYED_POLICY_ID)[POLICY_CONFIG] - ) - assert MonkeyedPolicyBody.is_the_same_dict(defaulted_fields, expected_defaulted_fields) - assert MonkeyedPolicyBody.is_the_same_dict(expected_defaulted_fields, defaulted_fields) + assert Policies.get_policy_bodies() == [] assert APPLICATION_CONFIG in runtime_properties assert APPLICATION_CONFIG in ctx.node.properties @@ -1052,18 +832,7 @@ def test_remove_all_policies_twice(): ctx.logger.info("removed: {0}".format(remove_policy_ids)) ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) assert dcae_policy.POLICIES in runtime_properties - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - assert runtime_properties[dcae_policy.POLICY_APPLY_ORDER] == [] - assert dcae_policy.POLICY_DEFAULTED_FIELDS in runtime_properties - assert Policies.get_policy_configs() == [] - - defaulted_fields = runtime_properties[dcae_policy.POLICY_DEFAULTED_FIELDS] - expected_defaulted_fields = dict( - (k, True) - for k in MonkeyedPolicyBody.create_policy_body(MONKEYED_POLICY_ID)[POLICY_CONFIG] - ) - assert MonkeyedPolicyBody.is_the_same_dict(defaulted_fields, expected_defaulted_fields) - assert MonkeyedPolicyBody.is_the_same_dict(expected_defaulted_fields, defaulted_fields) + assert Policies.get_policy_bodies() == [] assert APPLICATION_CONFIG in runtime_properties assert APPLICATION_CONFIG in ctx.node.properties @@ -1085,12 +854,6 @@ def test_remove_then_update(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - remove_policy_ids = policies.keys() policy_update(updated_policies=None, added_policies=None, removed_policies=remove_policy_ids) @@ -1127,15 +890,7 @@ def test_remove_then_update(): assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) assert MONKEYED_POLICY_ID in policies - assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID]) is None - assert MONKEYED_POLICY_ID_B in policies - assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID_B]) is None - - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_M_2] @cfy_ctx(include_bad=True) def test_remove_update_many_calcs(): @@ -1149,12 +904,6 @@ def test_remove_update_many_calcs(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - remove_policy_ids = policies.keys() policy_update_many_calcs(updated_policies=None, added_policies=None, @@ -1164,22 +913,6 @@ def test_remove_update_many_calcs(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [] - - assert dcae_policy.POLICY_DEFAULTED_FIELDS in runtime_properties - assert Policies.get_policy_configs() == [] - - defaulted_fields = runtime_properties[dcae_policy.POLICY_DEFAULTED_FIELDS] - expected_defaulted_fields = dict( - (k, True) - for k in MonkeyedPolicyBody.create_policy_body(MONKEYED_POLICY_ID)[POLICY_CONFIG] - ) - assert MonkeyedPolicyBody.is_the_same_dict(defaulted_fields, expected_defaulted_fields) - assert MonkeyedPolicyBody.is_the_same_dict(expected_defaulted_fields, defaulted_fields) - updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, False, priority="1") @@ -1213,15 +946,7 @@ def test_remove_update_many_calcs(): assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) assert MONKEYED_POLICY_ID in policies - assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID]) is None - assert MONKEYED_POLICY_ID_B in policies - assert Policies._get_config_from_policy(policies[MONKEYED_POLICY_ID_B]) is None - - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_M_2] @cfy_ctx(include_bad=True) def test_bad_update_many_calcs(): @@ -1235,12 +960,6 @@ def test_bad_update_many_calcs(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_M, MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID] - damaged_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") damaged_policy[POLICY_BODY][POLICY_CONFIG] = ["damaged config"] @@ -1293,12 +1012,6 @@ def test_bad_update_many_calcs(): assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [ - MONKEYED_POLICY_ID_2, MONKEYED_POLICY_ID_B, MONKEYED_POLICY_ID_M_2, MONKEYED_POLICY_ID] - @cfy_ctx(include_bad=True, include_good=False) def test_bad_policies(): """test bad policy nodes""" @@ -1311,11 +1024,6 @@ def test_bad_policies(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - assert policy_apply_order == [] - @cfy_ctx(include_bad=True, include_good=False) def test_wrong_ctx_node_configure(): """test wrong ctx""" @@ -1333,9 +1041,9 @@ def test_wrong_ctx_node_configure(): @cfy_ctx(include_bad=True, include_good=False) def test_wrong_ctx_policy_update(): """test wrong ctx""" + no_policies = Policies.get_policy_bodies() current_ctx.set(ctx.instance.relationships[0]) ctx_type = ctx.type - no_policy_configs = Policies.get_policy_configs() with pytest.raises(NonRecoverableError) as excinfo: policy_update(updated_policies=None, added_policies=None, removed_policies=None) @@ -1343,7 +1051,7 @@ def test_wrong_ctx_policy_update(): CurrentCtx.reset() ctx.logger.info("{0} not a node boom: {1}".format(ctx_type, str(excinfo.value))) assert ctx_type == 'cloudify.relationships.depends_on' - assert no_policy_configs == [] + assert no_policies == [] assert str(excinfo.value) == "can only invoke update_policies_on_node on node" def test_defenses_on_decorators(): @@ -1414,16 +1122,10 @@ def test_defenses_on_set_policies(): policies = runtime_properties[dcae_policy.POLICIES] ctx.logger.info("policies: {0}".format(json.dumps(policies))) - assert dcae_policy.POLICY_APPLY_ORDER in runtime_properties - policy_apply_order = runtime_properties[dcae_policy.POLICY_APPLY_ORDER] - ctx.logger.info("policy_apply_order: {0}".format(json.dumps(policy_apply_order))) - Policies._set_policies({}) assert dcae_policy.POLICIES not in runtime_properties - assert dcae_policy.POLICY_APPLY_ORDER not in runtime_properties Policies._set_policies({}) assert dcae_policy.POLICIES not in runtime_properties - assert dcae_policy.POLICY_APPLY_ORDER not in runtime_properties -- cgit 1.2.3-korg