2 * Copyright (c) 2019 AT&T Intellectual Property.
3 * Copyright (c) 2018-2019 Nokia.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
32 const defaultReportingEntityID = "00000000-0000-0000-0000-000000000000"
33 const defaultVNFName = "Vespa"
35 func readSystemUUID() string {
36 data, err := ioutil.ReadFile("/sys/class/dmi/id/product_uuid")
38 return defaultReportingEntityID
40 return strings.TrimSpace(string(data))
43 func getVNFName() string {
44 VNFName := os.Getenv("VESMGR_VNFNAME")
51 func basicVespaConf() VESAgentConfiguration {
52 var vespaconf = VESAgentConfiguration{
55 Event: EventConfiguration{
56 VNFName: getVNFName(),
57 ReportingEntityName: "Vespa",
58 ReportingEntityID: readSystemUUID(),
61 NfcNamingCodes: []NfcNamingCode{
64 Vnfcs: []string{"lr-ope-0", "lr-ope-1", "lr-ope-2"},
68 Vnfcs: []string{"lr-pro-0", "lr-pro-1"},
71 RetryInterval: time.Second * 5,
74 Measurement: MeasurementConfiguration{
75 // Domain abbreviation has to be set to “Mvfs” for VES 5.3,
76 // and to “Measurement” for later VES interface versions.
77 DomainAbbreviation: "Mvfs",
78 MaxBufferingDuration: time.Hour,
79 Prometheus: PrometheusConfig{
80 Timeout: time.Second * 30,
81 KeepAlive: time.Second * 30,
83 DefaultValues: &MetricRule{
84 VMIDLabel: "'{{.labels.instance}}'",
93 // AppMetricsStruct contains xapplication metrics definition
94 type AppMetricsStruct struct {
99 // AppMetrics contains metrics definitions for all Xapps
100 type AppMetrics map[string]AppMetricsStruct
102 // Parses the metrics data from an array of bytes, which is expected to contain a JSON
103 // array with structs of the following format:
108 // { "name": "...", "objectName": "...", "objectInstamce": "..." },
113 func parseMetricsFromXAppDescriptor(descriptor []byte, appMetrics AppMetrics) AppMetrics {
114 var desc []map[string]interface{}
115 json.Unmarshal(descriptor, &desc)
117 for _, app := range desc {
118 config, configOk := app["config"]
120 metrics, metricsOk := config.(map[string]interface{})["metrics"]
122 parseMetricsRules(metrics.([]interface{}), appMetrics)
129 // Parses the metrics data from an array of interfaces, which are expected to be maps
130 // of the following format:
131 // { "name": xxx, "objectName": yyy, "objectInstance": zzz }
132 // Entries, which do not have all the necessary fields, are ignored.
133 func parseMetricsRules(metricsMap []interface{}, appMetrics AppMetrics) AppMetrics {
134 for _, element := range metricsMap {
135 name, nameOk := element.(map[string]interface{})["name"].(string)
137 _, alreadyFound := appMetrics[name]
138 objectName, objectNameOk := element.(map[string]interface{})["objectName"].(string)
139 objectInstance, objectInstanceOk := element.(map[string]interface{})["objectInstance"].(string)
140 if !alreadyFound && objectNameOk && objectInstanceOk {
141 appMetrics[name] = AppMetricsStruct{objectName, objectInstance}
142 logger.Info("parsed counter %s %s %s", name, objectName, objectInstance)
145 logger.Info("skipped duplicate counter %s", name)
152 func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) {
153 appMetrics := make(AppMetrics)
154 parseMetricsFromXAppDescriptor(xAppConfig, appMetrics)
156 makeRule := func(expr string, objName string, objInstance string) MetricRule {
158 Target: "AdditionalObjects",
160 ObjectInstance: objInstance,
164 Name: "ricComponentName",
165 Expr: "'{{.labels.kubernetes_name}}'",
170 var metricsMap map[string][]interface{}
171 json.Unmarshal(xAppConfig, &metricsMap)
172 metrics := parseMetricsRules(metricsMap["metrics"], appMetrics)
174 vespaconf.Measurement.Prometheus.Rules.Metrics = make([]MetricRule, 0, len(metrics))
175 for key, value := range metrics {
176 vespaconf.Measurement.Prometheus.Rules.Metrics = append(vespaconf.Measurement.Prometheus.Rules.Metrics, makeRule(key, value.ObjectName, value.ObjectInstance))
178 if len(vespaconf.Measurement.Prometheus.Rules.Metrics) == 0 {
179 logger.Info("vespa config with empty metrics")
183 func getCollectorConfiguration(vespaconf *VESAgentConfiguration) {
184 vespaconf.PrimaryCollector.User = os.Getenv("VESMGR_PRICOLLECTOR_USER")
185 vespaconf.PrimaryCollector.Password = os.Getenv("VESMGR_PRICOLLECTOR_PASSWORD")
186 vespaconf.PrimaryCollector.PassPhrase = os.Getenv("VESMGR_PRICOLLECTOR_PASSPHRASE")
187 vespaconf.PrimaryCollector.FQDN = os.Getenv("VESMGR_PRICOLLECTOR_ADDR")
188 vespaconf.PrimaryCollector.ServerRoot = os.Getenv("VESMGR_PRICOLLECTOR_SERVERROOT")
189 vespaconf.PrimaryCollector.Topic = os.Getenv("VESMGR_PRICOLLECTOR_TOPIC")
190 portStr := os.Getenv("VESMGR_PRICOLLECTOR_PORT")
192 vespaconf.PrimaryCollector.Port = 8443
194 port, _ := strconv.Atoi(portStr)
195 vespaconf.PrimaryCollector.Port = port
197 secureStr := os.Getenv("VESMGR_PRICOLLECTOR_SECURE")
198 if secureStr == "true" {
199 vespaconf.PrimaryCollector.Secure = true
201 vespaconf.PrimaryCollector.Secure = false
205 func createVespaConfig(writer io.Writer, xAppStatus []byte) {
206 vespaconf := basicVespaConf()
207 getRules(&vespaconf, xAppStatus)
208 getCollectorConfiguration(&vespaconf)
209 err := yaml.NewEncoder(writer).Encode(vespaconf)
211 logger.Error("Cannot write vespa conf file: %s", err.Error())