1 # ================================================================================
2 # Copyright (c) 2019-2020 AT&T Intellectual Property. All rights reserved.
3 # ================================================================================
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 # ============LICENSE_END=========================================================
17 """REST for high-level information retrievals from Consul KVs"""
22 from otihandler.consul_client import ConsulClient
25 class CBSRest(object):
26 _logger = logging.getLogger("oti_handler.cbs_rest")
29 def get_value(key, default=None):
30 """Wrap ConsulClient.get_value() to ignore exceptions."""
34 data = ConsulClient.get_value(key)
35 except Exception as e:
42 """Wrap ConsulClient.get_kvs() to ignore exceptions."""
46 data = ConsulClient.get_kvs(key, trim_prefix=True)
47 except Exception as e:
55 def get_service_component(service_name):
56 """Get the fully-bound config for a service_name."""
58 return ConsulClient.get_service_component(service_name)
61 def get_service_component_all(service_name, service_location=None, policies_as_list=False):
62 """Get all Consul objects for a service_name."""
64 r_dict = ConsulClient.get_service_component_all(service_name, policies_as_list=policies_as_list)
65 if r_dict and r_dict.get('oti'):
66 r_dict['oti'] = CBSRest.get_oti(service_name, service_location=service_location)
70 def get_oti(service_name=None, vnf_type=None, vnf_id=None, service_location=None):
77 optional. The service component name assigned by dockerplugin to the component that is unique to the cloudify node instance and used in its Consul key(s).
79 optional, allows multiple values separated by commas. Gets DTI events for these vnf_type(s).
81 optional. Requires vnf_type also. Gets DTI event for this vnf_id.
82 service_location : string
83 optional, allows multiple values separated by commas. Filters DTI events with dcae_service_location in service_location.
84 If service_location is not provided, then defaults to dockerhost or k8s cluster master node service Consul TAGs if service_name is provided,
85 otherwise results are not location filtered.
90 Dictionary of DTI event(s).
91 If one vnf_type and vnf_id are both specified, then object returned will be just the one DTI event.
92 If one vnf_type is specified but not vnf_id, then DTI events will be keyed by vnf_id.
93 Otherwise the DTI events will be keyed by vnf_type, sub-keyed by vnf_id.
97 lc_vnf_type = vnf_type
99 lc_vnf_type = vnf_type.lower()
105 want_locs = service_location.split(',')
109 if not want_locs: # default to TAGs of container's dockerhost or k8s cluster master node
111 node_name = ConsulClient.lookup_service(service_name)[0].get("Node")
113 services = ConsulClient.lookup_node(node_name).get("Services")
115 for node_svc in list(services.keys()):
116 if "-component-dockerhost-" in node_svc or "_component_kubernetes_master" in node_svc:
117 want_locs = services[node_svc].get("Tags", [])
121 supported_types = ConsulClient.get_value(service_name + ":oti")
123 supported_types = [type.lower() for type in list(supported_types.keys())]
125 if lc_vnf_type: # If user specifies vnf_type(s), constrain to supported ones
126 for type in lc_vnf_type.split(','):
127 if type in supported_types:
128 give_types.append(type)
130 give_types = supported_types
131 if not give_types or (len(give_types) == 1 and give_types[0] == ''):
134 give_types = lc_vnf_type.split(',')
137 # If they specified only one vnf_type ...
138 if lc_vnf_type and ',' not in lc_vnf_type:
143 # get just one vnf_id
144 t_dict = CBSRest.get_value("oti_events/" + type + "/" + vnf_id, default=None)
146 event_loc = t_dict.get('dcae_service_location')
147 if not event_loc or not want_locs or event_loc in want_locs:
148 r_dict = copy.deepcopy(t_dict)
152 # get all DTI events of just one type, indexed by vnf_id
153 t_dict = CBSRest.get_kvs("oti_events/" + type + "/")
156 r_dict = copy.deepcopy(t_dict)
159 event_loc = t_dict[id].get('dcae_service_location')
160 if not event_loc or event_loc in want_locs:
161 r_dict[id] = copy.deepcopy(t_dict[id])
163 # If they did not specify either service_name or vnf_type (the only way give_types=[])
165 # get all DTI events, indexed by vnf_type then vnf_id
166 t_dict = CBSRest.get_kvs("oti_events/")
169 for id in t_dict[type]:
170 if not vnf_id or vnf_id == id:
172 event_loc = t_dict[type][id].get('dcae_service_location')
173 if not want_locs or not event_loc or event_loc in want_locs:
174 if type not in r_dict:
176 r_dict[type][id] = copy.deepcopy(t_dict[type][id])
178 # If they speclfied multiple vnf_types
180 # get all DTI events of give_types, indexed by vnf_type then vnf_id
181 for type in give_types:
182 t_dict = CBSRest.get_kvs("oti_events/" + type + "/")
185 if not vnf_id or vnf_id == id:
187 event_loc = t_dict[id].get('dcae_service_location')
188 if not want_locs or not event_loc or event_loc in want_locs:
189 if type not in r_dict:
191 r_dict[type][id] = copy.deepcopy(t_dict[id])
196 def get_policies(service_name, policy_id=None):
197 """Get one or all policies for a service_name."""
200 return ConsulClient.get_value(service_name + ":policies/items/" + policy_id)
202 return ConsulClient.get_kvs(service_name + ":policies/items/", trim_prefix=True)