Feature 10239: Distributed VCA
[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 on_update_db=None,
65 )
66
67 def collect(self, vnfr: dict) -> List[Metric]:
68 nsr_id = vnfr["nsr-id-ref"]
69 vnf_member_index = vnfr["member-vnf-index-ref"]
70 vnfd = self.common_db.get_vnfd(vnfr["vnfd-id"])
71
72 # Populate extra tags for metrics
73 tags = {}
74 tags["ns_name"] = self.common_db.get_nsr(nsr_id)["name"]
75 if vnfr["_admin"]["projects_read"]:
76 tags["project_id"] = vnfr["_admin"]["projects_read"][0]
77 else:
78 tags["project_id"] = ""
79
80 metrics = []
81 for vdur in vnfr["vdur"]:
82 # This avoids errors when vdur records have not been completely filled
83 if "name" not in vdur:
84 continue
85 vdu = next(filter(lambda vdu: vdu["id"] == vdur["vdu-id-ref"], vnfd["vdu"]))
86 if "vdu-configuration" in vdu and "metrics" in vdu["vdu-configuration"]:
87 try:
88 vca_deployment_info = self.get_vca_deployment_info(
89 nsr_id,
90 vnf_member_index,
91 vdur["vdu-id-ref"],
92 vdur["count-index"],
93 )
94 except VcaDeploymentInfoNotFound as e:
95 log.warning(repr(e))
96 continue
97 measures = self.loop.run_until_complete(
98 self.n2vc.get_metrics(
99 vca_deployment_info["model"],
100 vca_deployment_info["application"],
101 vca_id=vnfr.get("vca-id"),
102 )
103 )
104 log.debug("Measures: %s", measures)
105 for measure_list in measures.values():
106 for measure in measure_list:
107 log.debug("Measure: %s", measure)
108 metric = VnfMetric(
109 nsr_id,
110 vnf_member_index,
111 vdur["name"],
112 measure["key"],
113 float(measure["value"]),
114 tags,
115 )
116 metrics.append(metric)
117 if "vnf-configuration" in vnfd and "metrics" in vnfd["vnf-configuration"]:
118 try:
119 vca_deployment_info = self.get_vca_deployment_info(
120 nsr_id, vnf_member_index
121 )
122 except VcaDeploymentInfoNotFound as e:
123 log.warning(repr(e))
124 return metrics
125 measures = self.loop.run_until_complete(
126 self.n2vc.get_metrics(
127 vca_deployment_info["model"], vca_deployment_info["application"]
128 )
129 )
130 # Search for Mgmt VDU name, needed to query Prometheus based on alarm tags
131 # TODO: check a better way to look for Mgmt VDU
132 for vdur in vnfr["vdur"]:
133 for interface in vdur["interfaces"]:
134 if "mgmt-vnf" in interface:
135 vdu_name = vdur["name"]
136 break
137 log.debug("Measures: %s", measures)
138 for measure_list in measures.values():
139 for measure in measure_list:
140 log.debug("Measure: %s", measure)
141 metric = VnfMetric(
142 nsr_id,
143 vnf_member_index,
144 vdu_name,
145 measure["key"],
146 float(measure["value"]),
147 tags,
148 )
149 metrics.append(metric)
150 return metrics
151
152 def get_vca_deployment_info(
153 self, nsr_id, vnf_member_index, vdu_id=None, vdu_count=0
154 ):
155 nsr = self.common_db.get_nsr(nsr_id)
156 for vca_deployment in nsr["_admin"]["deployed"]["VCA"]:
157 if vca_deployment:
158 if vdu_id is None:
159 if (
160 vca_deployment["member-vnf-index"] == vnf_member_index
161 and vca_deployment["vdu_id"] is None
162 ):
163 return vca_deployment
164 else:
165 if (
166 vca_deployment["member-vnf-index"] == vnf_member_index
167 and vca_deployment["vdu_id"] == vdu_id
168 and vca_deployment["vdu_count_index"] == vdu_count
169 ):
170 return vca_deployment
171 raise VcaDeploymentInfoNotFound(
172 "VCA deployment info for nsr_id {}, index {}, vdu_id {} and vdu_count_index {} not found.".format(
173 nsr_id, vnf_member_index, vdu_id, vdu_count
174 )
175 )