ba17d6594bd17b90b76dc9b33a15d758b74315af
[osm/MON.git] / osm_mon / collector / vnf_collectors / juju.py
1 # Copyright 2018 Whitestack, LLC
2 # *************************************************************
3
4 # This file is part of OSM Monitoring module
5 # All Rights Reserved to Whitestack, LLC
6
7 # Licensed under the Apache License, Version 2.0 (the "License"); you may
8 # not use this file except in compliance with the License. You may obtain
9 # a copy of the License at
10
11 # http://www.apache.org/licenses/LICENSE-2.0
12
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 # License for the specific language governing permissions and limitations
17 # under the License.
18
19 # For those usages not covered by the Apache License, Version 2.0 please
20 # contact: bdiaz@whitestack.com or glavado@whitestack.com
21 ##
22 import asyncio
23 import logging
24 from typing import List
25
26 from n2vc.n2vc_juju_conn import N2VCJujuConnector
27
28 from osm_mon.collector.metric import Metric
29 from osm_mon.collector.vnf_collectors.base import BaseCollector
30 from osm_mon.collector.vnf_metric import VnfMetric
31 from osm_mon.core.common_db import CommonDbClient
32 from osm_mon.core.config import Config
33 from osm_mon.core.exceptions import VcaDeploymentInfoNotFound
34
35 log = logging.getLogger(__name__)
36
37
38 class VCACollector(BaseCollector):
39 def __init__(self, config: Config):
40 super().__init__(config)
41 self.common_db = CommonDbClient(config)
42 self.loop = asyncio.get_event_loop()
43 host = config.get("vca", "host")
44 port = config.get("vca", "port") if "port" in config.conf["vca"] else 17070
45
46 # Backwards compatibility
47 if "cacert" in config.conf["vca"]:
48 ca_cert = config.conf["vca"].pop("cacert")
49 config.set("vca", "ca_cert", ca_cert)
50
51 if "pubkey" in config.conf["vca"]:
52 public_key = config.conf["vca"].pop("pubkey")
53 config.set("vca", "public_key", public_key)
54
55 if "apiproxy" in config.conf["vca"]:
56 api_proxy = config.conf["vca"].pop("apiproxy")
57 config.set("vca", "api_proxy", api_proxy)
58
59 self.n2vc = N2VCJujuConnector(
60 db=self.common_db.common_db,
61 fs=object(),
62 log=log,
63 loop=self.loop,
64 url="{}:{}".format(host, port),
65 username=config.get("vca", "user"),
66 vca_config=config.conf["vca"],
67 on_update_db=None,
68 )
69
70 def collect(self, vnfr: dict) -> List[Metric]:
71 nsr_id = vnfr["nsr-id-ref"]
72 vnf_member_index = vnfr["member-vnf-index-ref"]
73 vnfd = self.common_db.get_vnfd(vnfr["vnfd-id"])
74
75 # Populate extra tags for metrics
76 tags = {}
77 tags["ns_name"] = self.common_db.get_nsr(nsr_id)["name"]
78 if vnfr["_admin"]["projects_read"]:
79 tags["project_id"] = vnfr["_admin"]["projects_read"][0]
80 else:
81 tags["project_id"] = ""
82
83 metrics = []
84 for vdur in vnfr["vdur"]:
85 # This avoids errors when vdur records have not been completely filled
86 if "name" not in vdur:
87 continue
88 vdu = next(filter(lambda vdu: vdu["id"] == vdur["vdu-id-ref"], vnfd["vdu"]))
89 if "vdu-configuration" in vdu and "metrics" in vdu["vdu-configuration"]:
90 try:
91 vca_deployment_info = self.get_vca_deployment_info(
92 nsr_id,
93 vnf_member_index,
94 vdur["vdu-id-ref"],
95 vdur["count-index"],
96 )
97 except VcaDeploymentInfoNotFound as e:
98 log.warning(repr(e))
99 continue
100 measures = self.loop.run_until_complete(
101 self.n2vc.get_metrics(
102 vca_deployment_info["model"], vca_deployment_info["application"]
103 )
104 )
105 log.debug("Measures: %s", measures)
106 for measure_list in measures.values():
107 for measure in measure_list:
108 log.debug("Measure: %s", measure)
109 metric = VnfMetric(
110 nsr_id,
111 vnf_member_index,
112 vdur["name"],
113 measure["key"],
114 float(measure["value"]),
115 tags,
116 )
117 metrics.append(metric)
118 if "vnf-configuration" in vnfd and "metrics" in vnfd["vnf-configuration"]:
119 try:
120 vca_deployment_info = self.get_vca_deployment_info(
121 nsr_id, vnf_member_index
122 )
123 except VcaDeploymentInfoNotFound as e:
124 log.warning(repr(e))
125 return metrics
126 measures = self.loop.run_until_complete(
127 self.n2vc.get_metrics(
128 vca_deployment_info["model"], vca_deployment_info["application"]
129 )
130 )
131 # Search for Mgmt VDU name, needed to query Prometheus based on alarm tags
132 # TODO: check a better way to look for Mgmt VDU
133 for vdur in vnfr["vdur"]:
134 for interface in vdur["interfaces"]:
135 if "mgmt-vnf" in interface:
136 vdu_name = vdur["name"]
137 break
138 log.debug("Measures: %s", measures)
139 for measure_list in measures.values():
140 for measure in measure_list:
141 log.debug("Measure: %s", measure)
142 metric = VnfMetric(
143 nsr_id,
144 vnf_member_index,
145 vdu_name,
146 measure["key"],
147 float(measure["value"]),
148 tags,
149 )
150 metrics.append(metric)
151 return metrics
152
153 def get_vca_deployment_info(
154 self, nsr_id, vnf_member_index, vdu_id=None, vdu_count=0
155 ):
156 nsr = self.common_db.get_nsr(nsr_id)
157 for vca_deployment in nsr["_admin"]["deployed"]["VCA"]:
158 if vca_deployment:
159 if vdu_id is None:
160 if (
161 vca_deployment["member-vnf-index"] == vnf_member_index
162 and vca_deployment["vdu_id"] is None
163 ):
164 return vca_deployment
165 else:
166 if (
167 vca_deployment["member-vnf-index"] == vnf_member_index
168 and vca_deployment["vdu_id"] == vdu_id
169 and vca_deployment["vdu_count_index"] == vdu_count
170 ):
171 return vca_deployment
172 raise VcaDeploymentInfoNotFound(
173 "VCA deployment info for nsr_id {}, index {}, vdu_id {} and vdu_count_index {} not found.".format(
174 nsr_id, vnf_member_index, vdu_id, vdu_count
175 )
176 )