blob: 4623eba4a5a2c4f29e8a177ed5e8ea550c1e7e51 [file] [log] [blame]
Alex Shatov1369bea2018-01-10 11:00:50 -05001# org.onap.dcae
2# ================================================================================
3# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
4# ================================================================================
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# ============LICENSE_END=========================================================
17#
18# ECOMP is a trademark and service mark of AT&T Intellectual Property.
19
Alex Shatovf53e5e72018-01-11 11:15:56 -050020"""policy-client communicates with policy-engine thru REST API"""
21
Alex Shatov1369bea2018-01-10 11:00:50 -050022import logging
23import json
24import re
25
26from .policy_consts import POLICY_ID, POLICY_VERSION, POLICY_NAME, POLICY_BODY, POLICY_CONFIG
27
28class PolicyUtils(object):
29 """policy-client utils"""
30 _logger = logging.getLogger("policy_handler.policy_utils")
31 _policy_name_ext = re.compile('[.][0-9]+[.][a-zA-Z]+$')
32
33 @staticmethod
34 def safe_json_parse(json_str):
35 """try parsing json without exception - returns the json_str back if fails"""
36 if not json_str:
37 return json_str
38 try:
39 return json.loads(json_str)
40 except (ValueError, TypeError) as err:
41 PolicyUtils._logger.warn("unexpected json %s: %s", str(json_str), str(err))
42 return json_str
43
44 @staticmethod
45 def extract_policy_id(policy_name):
46 """ policy_name = policy_id + "." + <version> + "." + <extension>
47 For instance,
48 policy_name = DCAE_alex.Config_alex_policy_number_1.3.xml
49 policy_id = DCAE_alex.Config_alex_policy_number_1
50 policy_scope = DCAE_alex
51 policy_class = Config
52 policy_version = 3
53 type = extension = xml
54 delimiter = "."
55 policy_class_delimiter = "_"
56 policy_name in PAP = DCAE_alex.alex_policy_number_1
57 """
58 if not policy_name:
59 return
60 return PolicyUtils._policy_name_ext.sub('', policy_name)
61
62 @staticmethod
63 def parse_policy_config(policy):
64 """try parsing the config in policy."""
65 if not policy:
66 return policy
67 config = policy.get(POLICY_BODY, {}).get(POLICY_CONFIG)
68 if config:
69 policy[POLICY_BODY][POLICY_CONFIG] = PolicyUtils.safe_json_parse(config)
70 return policy
71
72 @staticmethod
73 def convert_to_policy(policy_config):
74 """wrap policy_config received from policy-engine with policy_id."""
75 if not policy_config:
76 return
77 policy_name = policy_config.get(POLICY_NAME)
78 policy_version = policy_config.get(POLICY_VERSION)
79 if not policy_name or not policy_version:
80 return
81 policy_id = PolicyUtils.extract_policy_id(policy_name)
82 if not policy_id:
83 return
84 return {POLICY_ID:policy_id, POLICY_BODY:policy_config}
85
86 @staticmethod
87 def select_latest_policy(policy_configs, min_version_expected=None, ignore_policy_names=None):
88 """For some reason, the policy-engine returns all version of the policy_configs.
89 DCAE-Controller is only interested in the latest version
90 """
91 if not policy_configs:
92 return
93 latest_policy_config = {}
94 for policy_config in policy_configs:
95 policy_name = policy_config.get(POLICY_NAME)
96 policy_version = policy_config.get(POLICY_VERSION)
97 if not policy_name or not policy_version or not policy_version.isdigit():
98 continue
99 policy_version = int(policy_version)
100 if min_version_expected and policy_version < min_version_expected:
101 continue
102 if ignore_policy_names and policy_name in ignore_policy_names:
103 continue
104
105 if not latest_policy_config \
106 or int(latest_policy_config[POLICY_VERSION]) < policy_version:
107 latest_policy_config = policy_config
108
109 return PolicyUtils.parse_policy_config(PolicyUtils.convert_to_policy(latest_policy_config))
110
111 @staticmethod
112 def select_latest_policies(policy_configs):
113 """For some reason, the policy-engine returns all version of the policy_configs.
114 DCAE-Controller is only interested in the latest versions
115 """
116 if not policy_configs:
117 return {}
118 policies = {}
119 for policy_config in policy_configs:
120 policy = PolicyUtils.convert_to_policy(policy_config)
121 if not policy:
122 continue
123 policy_id = policy.get(POLICY_ID)
124 policy_version = policy.get(POLICY_BODY, {}).get(POLICY_VERSION)
125 if not policy_id or not policy_version or not policy_version.isdigit():
126 continue
127 if policy_id not in policies \
128 or int(policy_version) > int(policies[policy_id][POLICY_BODY][POLICY_VERSION]):
129 policies[policy_id] = policy
130
131 for policy_id in policies:
132 policies[policy_id] = PolicyUtils.parse_policy_config(policies[policy_id])
133
134 return policies