summaryrefslogtreecommitdiffstats
path: root/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py
diff options
context:
space:
mode:
Diffstat (limited to 'onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py')
-rw-r--r--onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py138
1 files changed, 103 insertions, 35 deletions
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 e4c5cea..b064157 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
@@ -20,14 +20,15 @@
"""dcae_policy contains decorators for the policy lifecycle in cloudify"""
import json
+import traceback
from copy import deepcopy
from functools import wraps
-import traceback
from cloudify import ctx
from cloudify.context import NODE_INSTANCE
from cloudify.exceptions import NonRecoverableError
+from .policies_output import PoliciesOutput
from .utils import Utils
POLICIES = 'policies'
@@ -47,12 +48,14 @@ POLICY_FILTER = 'policy_filter'
POLICY_FILTER_ID = 'policy_filter_id'
POLICY_TYPE = 'policyType'
POLICY_TYPE_MICROSERVICE = 'MicroService'
-POLICY_CONFIG_MS = "Config_MS"
+POLICY_CONFIG_MS = "Config_MS_"
POLICY_PERSISTENT = 'policy_persistent'
DCAE_POLICY_TYPE = 'dcae.nodes.policy'
DCAE_POLICIES_TYPE = 'dcae.nodes.policies'
-POLICY_MESSAGE_TYPE = 'policy'
+
+ACTION_GATHERED = "gathered"
+ACTION_UPDATED = "updated"
class Policies(object):
"""static class for policy operations"""
@@ -195,15 +198,15 @@ class Policies(object):
"""
policy_defaulted_fields = ctx.instance.runtime_properties.get(POLICY_DEFAULTED_FIELDS, {})
policy_defaulted_fields.update(
- (k, True)
+ (field_name, True)
for policy in Policies._removed_policies.itervalues()
- for k in Policies._get_config_from_policy(policy) or {}
+ for field_name in Policies._get_config_from_policy(policy) or {}
)
if policies:
for policy in policies.itervalues():
- for k in Policies._get_config_from_policy(policy) or {}:
- if k in policy_defaulted_fields:
- del policy_defaulted_fields[k]
+ 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
@@ -230,13 +233,25 @@ class Policies(object):
Policies._set_policy_apply_order(policies)
@staticmethod
+ def _get_policy_bodies_dict(policies):
+ """returns a dict of policy_id -> policy_body if policy_body exists"""
+ if not policies:
+ return {}
+
+ return dict((policy_id, policy.get(POLICY_BODY))
+ for policy_id, policy in policies.iteritems() if policy.get(POLICY_BODY)
+ )
+
+ @staticmethod
def gather_policies_to_node(policy_apply_order_path=None):
"""
- decorate with @Policies.gather_policies_to_node to
+ decorate with @Policies.gather_policies_to_node() to
gather the policies from dcae.nodes.policy nodes this node depends on.
Places the policies into runtime_properties["policies"].
+ Stores <scn>:policies data in consul-kv
+
Call Policies.calc_latest_application_config() to apply policies onto application_config.
"""
def gather_policies_decorator(func):
@@ -301,6 +316,8 @@ class Policies(object):
if ctx.type != NODE_INSTANCE:
raise NonRecoverableError("can only invoke gather_policies_to_node on node")
+ policies_outputted = False
+ policy_bodies = []
try:
Policies._store_policy_apply_order_clause(policy_apply_order_path)
@@ -313,12 +330,21 @@ class Policies(object):
Policies._set_policies(policies)
if policy_filters:
ctx.instance.runtime_properties[POLICY_FILTERS] = policy_filters
+
+ policy_bodies = Policies._get_policy_bodies_dict(policies)
+ if policy_bodies:
+ policies_outputted = PoliciesOutput.store_policies(ACTION_GATHERED, policy_bodies)
except Exception as ex:
error = "Failed to set the policies {0}".format(str(ex))
ctx.logger.error("{0}: {1}".format(error, traceback.format_exc()))
raise NonRecoverableError(error)
- return func(*args, **kwargs)
+ func_result = func(*args, **kwargs)
+
+ if not policies_outputted and policy_bodies:
+ PoliciesOutput.store_policies(ACTION_GATHERED, policy_bodies)
+
+ return func_result
return wrapper
return gather_policies_decorator
@@ -349,19 +375,17 @@ class Policies(object):
for policy_id in removed_policies:
removed_policy = policies.get(policy_id)
- if removed_policy:
+ if removed_policy and POLICY_BODY in removed_policy:
Policies._removed_policies[policy_id] = deepcopy(removed_policy)
- if not removed_policy.get(POLICY_PERSISTENT):
- del policies[policy_id]
- elif POLICY_BODY in removed_policy:
+ if removed_policy.get(POLICY_PERSISTENT):
del policies[policy_id][POLICY_BODY]
+ else:
+ del policies[policy_id]
- new_policies = dict((p_id, policy)
+ new_policies = dict((policy_id, policy)
for policy_filter_id in policy_filters
- for (p_id, policy) in added_policies
- .get(policy_filter_id, {})
- .get(POLICIES, {})
- .iteritems())
+ for (policy_id, policy) in added_policies.get(policy_filter_id, {})
+ .get(POLICIES, {}).iteritems())
ctx.logger.info("new_policies: {0}".format(json.dumps(new_policies)))
@@ -373,13 +397,17 @@ class Policies(object):
continue
updated_policies.append(policy)
- skipped = {"ignored" : [], "unexpected" : [], "same" : []}
+ skipped = {"ignored": [], "unexpected": [], "same": [], "duplicate": []}
for policy in updated_policies:
policy_id = policy.get(POLICY_ID)
if not policy_id or policy_id not in policies:
skipped["ignored"].append(policy)
continue
+ if policy_id in Policies._updated_policies:
+ skipped["duplicate"].append(policy)
+ continue
+
updated_policy_body = policy.get(POLICY_BODY, {})
updated_policy_version = updated_policy_body.get(POLICY_VERSION)
if not updated_policy_version or POLICY_CONFIG not in updated_policy_body:
@@ -395,20 +423,25 @@ class Policies(object):
policies[policy_id][POLICY_BODY] = updated_policy_body
Policies._updated_policies[policy_id] = policy
- if skipped["same"] or skipped["ignored"] or skipped["unexpected"]:
- ctx.logger.info("skipped policies: {0}".format(json.dumps(skipped)))
+ if skipped["same"] or skipped["ignored"] or skipped["unexpected"] or skipped["duplicate"]:
+ ctx.logger.info("skipped updates on policies: {0}".format(json.dumps(skipped)))
if Policies._updated_policies or Policies._removed_policies:
Policies._set_policies(policies)
+ policy_bodies = Policies._get_policy_bodies_dict(policies)
+ PoliciesOutput.store_policies(ACTION_UPDATED, policy_bodies)
@staticmethod
- def update_policies_on_node(configs_only=True):
- """decorate each policy_update operation with @Policies.update_policies_on_node to
+ def update_policies_on_node(configs_only=False):
+ """
+ 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 <scn>: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 object (False)
+ instead of the whole policy_body object (False)
Passes through the filtered list of updated_policies that apply to the current node instance
@@ -439,10 +472,16 @@ class Policies(object):
if configs_only:
updated_policies = Utils.remove_empties(
[Policies._get_config_from_policy(policy)
- for policy in updated_policies or []]
+ for policy in updated_policies]
)
removed_policies = [Policies._get_config_from_policy(policy)
- for policy in removed_policies or []]
+ 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]
except Exception as ex:
error = "Failed to update the policies {0}".format(str(ex))
@@ -450,16 +489,41 @@ class Policies(object):
raise NonRecoverableError(error)
if updated_policies or removed_policies:
- return func(updated_policies, removed_policies=removed_policies, **kwargs)
+ return func(
+ updated_policies,
+ removed_policies=removed_policies,
+ policies=Policies.get_policy_bodies(),
+ **kwargs)
return wrapper
return update_policies_decorator
@staticmethod
- def _get_ordered_policies(selected_policies=None):
+ def cleanup_policies_on_node(func):
"""
- returns the ordered list of selected policies from the runtime policies
- ordered by policy_id values
+ decorate each policy_update operation with @Policies.cleanup_policies_on_node to
+ remove <scn>:policies data in consul-kv
"""
+ if not func:
+ return
+
+ @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()))
+
+ 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:
@@ -475,10 +539,7 @@ class Policies(object):
@staticmethod
def get_policy_configs():
- """
- returns the list of policy configs from the runtime policies
- ordered by policy_id values
- """
+ """returns the ordered list of policy configs from the runtime policies"""
if ctx.type != NODE_INSTANCE:
return []
@@ -489,6 +550,13 @@ class Policies(object):
)
@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.