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.
29 func basicVespaConf() VESAgentConfiguration {
30 var vespaconf = VESAgentConfiguration{
33 Event: EventConfiguration{
34 VNFName: "vespa-demo", // XXX
35 ReportingEntityID: "1af5bfa9-40b4-4522-b045-40e54f0310f", // XXX
38 NfcNamingCodes: []NfcNamingCode{
41 Vnfcs: []string{"lr-ope-0", "lr-ope-1", "lr-ope-2"},
45 Vnfcs: []string{"lr-pro-0", "lr-pro-1"},
48 RetryInterval: time.Second * 5,
51 Measurement: MeasurementConfiguration{
52 DomainAbbreviation: "Mvfs",
53 MaxBufferingDuration: time.Hour,
54 Prometheus: PrometheusConfig{
55 Timeout: time.Second * 30,
56 KeepAlive: time.Second * 30,
58 DefaultValues: &MetricRule{
59 VMIDLabel: "'{{.labels.instance}}'",
68 type AppMetricsStruct struct {
71 // xxx add labels here
74 type AppMetrics map[string]AppMetricsStruct
76 // Parses the metrics data from an array of bytes, which is expected to contain a JSON
77 // array with structs of the following format:
82 // { "name": "...", "objectName": "...", "objectInstamce": "..." },
87 func parseMetricsFromXAppDescriptor(descriptor []byte, appMetrics AppMetrics) AppMetrics {
88 var desc []map[string]interface{}
89 json.Unmarshal(descriptor, &desc)
91 for _, app := range desc {
92 config, config_ok := app["config"]
94 metrics, metrics_ok := config.(map[string]interface{})["metrics"]
96 parseMetricsRules(metrics.([]interface{}), appMetrics)
103 // Parses the metrics data from an array of interfaces, which are expected to be maps
104 // of the following format:
105 // { "name": xxx, "objectName": yyy, "objectInstance": zzz }
106 // Entries, which do not have all the necessary fields, are ignored.
107 func parseMetricsRules(metricsMap []interface{}, appMetrics AppMetrics) AppMetrics {
108 for _, element := range metricsMap {
109 name, name_ok := element.(map[string]interface{})["name"].(string)
111 _, already_found := appMetrics[name]
112 objectName, objectName_ok := element.(map[string]interface{})["objectName"].(string)
113 objectInstance, objectInstance_ok := element.(map[string]interface{})["objectInstance"].(string)
114 if !already_found && objectName_ok && objectInstance_ok {
115 appMetrics[name] = AppMetricsStruct{objectName, objectInstance}
116 logger.Info("parsed counter %s %s %s", name, objectName, objectInstance)
119 logger.Info("skipped duplicate counter %s", name)
126 func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) {
127 appMetrics := make(AppMetrics)
128 parseMetricsFromXAppDescriptor(xAppConfig, appMetrics)
130 makeRule := func(expr string, obj_name string, obj_instance string) MetricRule {
132 Target: "AdditionalObjects",
134 ObjectInstance: obj_instance,
135 ObjectName: obj_name,
138 Name: "ricComponentName",
139 Expr: "'{{.labels.kubernetes_name}}'",
144 var metricsMap map[string][]interface{}
145 json.Unmarshal(xAppConfig, &metricsMap)
146 metrics := parseMetricsRules(metricsMap["metrics"], appMetrics)
148 vespaconf.Measurement.Prometheus.Rules.Metrics = make([]MetricRule, 0, len(metrics))
149 for key, value := range metrics {
150 vespaconf.Measurement.Prometheus.Rules.Metrics = append(vespaconf.Measurement.Prometheus.Rules.Metrics, makeRule(key, value.ObjectName, value.ObjectInstance))
152 if len(vespaconf.Measurement.Prometheus.Rules.Metrics) == 0 {
153 logger.Info("vespa config with empty metrics")
157 func getCollectorConfiguration(vespaconf *VESAgentConfiguration) {
158 vespaconf.PrimaryCollector.User = os.Getenv("VESMGR_PRICOLLECTOR_USER")
159 vespaconf.PrimaryCollector.Password = os.Getenv("VESMGR_PRICOLLECTOR_PASSWORD")
160 vespaconf.PrimaryCollector.PassPhrase = os.Getenv("VESMGR_PRICOLLECTOR_PASSPHRASE")
161 vespaconf.PrimaryCollector.FQDN = os.Getenv("VESMGR_PRICOLLECTOR_ADDR")
162 vespaconf.PrimaryCollector.ServerRoot = os.Getenv("VESMGR_PRICOLLECTOR_SERVERROOT")
163 vespaconf.PrimaryCollector.Topic = os.Getenv("VESMGR_PRICOLLECTOR_TOPIC")
164 port_str := os.Getenv("VESMGR_PRICOLLECTOR_PORT")
166 vespaconf.PrimaryCollector.Port = 8443
168 port, _ := strconv.Atoi(port_str)
169 vespaconf.PrimaryCollector.Port = port
171 secure_str := os.Getenv("VESMGR_PRICOLLECTOR_SECURE")
172 if secure_str == "true" {
173 vespaconf.PrimaryCollector.Secure = true
175 vespaconf.PrimaryCollector.Secure = false
179 func createVespaConfig(writer io.Writer, xAppStatus []byte) {
180 vespaconf := basicVespaConf()
181 getRules(&vespaconf, xAppStatus)
182 getCollectorConfiguration(&vespaconf)
183 err := yaml.NewEncoder(writer).Encode(vespaconf)
185 logger.Error("Cannot write vespa conf file: %s", err.Error())