Skip to content
Snippets Groups Projects
Commit 27297f40 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'feat/webui' into 'develop'

Add Grafana Dashboards to WebUI

See merge request teraflow-h2020/controller!77
parents f5a1a716 4cb1a369
No related branches found
No related tags found
1 merge request!54Release 2.0.0
#!/bin/bash
# Set the name of the Kubernetes namespace to deploy to.
K8S_NAMESPACE="tf-dev"
K8S_HOSTNAME="kubernetes-master"
export INFLUXDB_HOSTNAME=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
export INFLUXDB_PORT=$(kubectl get service influx-tests --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==8086)].nodePort}')
export INFLUXDB_USER=$(kubectl --namespace $K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_USER}' | base64 --decode)
export INFLUXDB_PASSWORD=$(kubectl --namespace $K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode)
export INFLUXDB_DATABASE=$(kubectl --namespace $K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode)
export INFLUXDB_URL="http://${INFLUXDB_HOSTNAME}:${INFLUXDB_PORT}"
export GRAFANA_HOSTNAME=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
export GRAFANA_PORT=$(kubectl get service webuiservice-public --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==3000)].nodePort}')
export GRAFANA_USERNAME="admin"
export GRAFANA_PASSWORD="admin123+"
export GRAFANA_URL="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}"
echo ${GRAFANA_URL}/api/datasources
# Create InfluxDB DataSource
# Ref: https://grafana.com/docs/grafana/latest/http_api/data_source/
curl -X POST -H "Content-Type: application/json" -d '{
"type" : "influxdb",
"name" : "InfluxDB",
"url" : "'"$INFLUXDB_URL"'",
"access" : "proxy",
"basicAuth": false,
"user" : "'"$INFLUXDB_USER"'",
"password" : "'"$INFLUXDB_PASSWORD"'",
"isDefault": true,
"database" : "'"$INFLUXDB_DATABASE"'"
}' ${GRAFANA_URL}/api/datasources
echo
# Create Monitoring Dashboard
# Ref: https://grafana.com/docs/grafana/latest/http_api/dashboard/
curl -X POST -H "Content-Type: application/json" \
-d '@src/webui/grafana_dashboard.json' \
${GRAFANA_URL}/api/dashboards/db
echo
......@@ -12,6 +12,10 @@ spec:
app: webuiservice
spec:
terminationGracePeriodSeconds: 5
securityContext:
fsGroup: 472
supplementalGroups:
- 0
containers:
- name: server
image: registry.gitlab.com/teraflow-h2020/controller/webui:latest
......@@ -40,6 +44,41 @@ spec:
limits:
cpu: 700m
memory: 1024Mi
- name: grafana
image: grafana/grafana:8.2.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: http-grafana
protocol: TCP
env:
- name: GF_SECURITY_ADMIN_PASSWORD
value: admin123+
readinessProbe:
failureThreshold: 3
httpGet:
path: /robots.txt
port: 3000
scheme: HTTP
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 3000
timeoutSeconds: 1
resources:
requests:
cpu: 250m
memory: 750Mi
limits:
cpu: 700m
memory: 1024Mi
---
apiVersion: v1
kind: Service
......@@ -70,4 +109,9 @@ spec:
port: 8004
targetPort: 8004
nodePort: 30800
- name: grafana
protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30300
---
......@@ -29,15 +29,18 @@ python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=p
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto device.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto service.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto monitoring.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
# rm proto/compute_pb2_grpc.py
rm proto/context_pb2_grpc.py
rm proto/device_pb2_grpc.py
rm proto/service_pb2_grpc.py
rm proto/monitoring_pb2_grpc.py
rm proto/kpi_sample_types_pb2_grpc.py
# sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/compute_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/device_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/service_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/monitoring_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
{"overwrite": true, "folderId": 0, "dashboard":
{
"id": null,
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": null,
"graphTooltip": 0,
"iteration": 1643919736138,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": null,
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "smooth",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "always",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byRegexp",
"options": ".* PACKETS_.*"
},
"properties": [
{
"id": "custom.axisPlacement",
"value": "left"
},
{
"id": "unit",
"value": "short"
},
{
"id": "custom.axisLabel",
"value": "Packets"
}
]
},
{
"matcher": {
"id": "byRegexp",
"options": ".* BYTES_.*"
},
"properties": [
{
"id": "custom.axisPlacement",
"value": "right"
},
{
"id": "unit",
"value": "decbytes"
},
{
"id": "custom.axisLabel",
"value": "Bytes"
}
]
}
]
},
"gridPos": {
"h": 19,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [
"first",
"min",
"mean",
"max",
"lastNotNull"
],
"displayMode": "table",
"placement": "right"
},
"tooltip": {
"mode": "multi"
}
},
"targets": [
{
"alias": "$tag_device_id $tag_endpoint_id $tag_kpi_sample_type",
"groupBy": [
{
"params": [
"device_id"
],
"type": "tag"
},
{
"params": [
"endpoint_id"
],
"type": "tag"
},
{
"params": [
"kpi_sample_type"
],
"type": "tag"
}
],
"measurement": "samples",
"orderByTime": "ASC",
"policy": "autogen",
"refId": "A",
"resultFormat": "time_series",
"select": [
[
{
"params": [
"kpi_value"
],
"type": "field"
}
]
],
"tags": [
{
"key": "device_id",
"operator": "=~",
"value": "/^$device_id$/"
},
{
"condition": "AND",
"key": "endpoint_id",
"operator": "=~",
"value": "/^$endpoint_id$/"
},
{
"condition": "AND",
"key": "kpi_sample_type",
"operator": "=~",
"value": "/^$kpi_sample_type$/"
}
]
}
],
"title": "L3 Monitoring Packets/Bytes Received/Sent",
"transformations": [],
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 32,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"allValue": null,
"current": {
"selected": true,
"text": [
"R1-INF"
],
"value": [
"R1-INF"
]
},
"datasource": null,
"definition": "SHOW TAG VALUES FROM samples WITH KEY=\"device_id\"",
"description": null,
"error": null,
"hide": 0,
"includeAll": true,
"label": "Device",
"multi": true,
"name": "device_id",
"options": [],
"query": "SHOW TAG VALUES FROM samples WITH KEY=\"device_id\"",
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
},
{
"allValue": null,
"current": {
"selected": true,
"text": [
"EP100"
],
"value": [
"EP100"
]
},
"datasource": null,
"definition": "SHOW TAG VALUES FROM samples WITH KEY=\"endpoint_id\" WHERE \"device_id\"=~/^$device_id$/",
"description": null,
"error": null,
"hide": 0,
"includeAll": true,
"label": "EndPoint",
"multi": true,
"name": "endpoint_id",
"options": [],
"query": "SHOW TAG VALUES FROM samples WITH KEY=\"endpoint_id\" WHERE \"device_id\"=~/^$device_id$/",
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
},
{
"allValue": null,
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"datasource": null,
"definition": "SHOW TAG VALUES FROM samples WITH KEY=\"kpi_sample_type\"",
"description": null,
"error": null,
"hide": 0,
"includeAll": true,
"label": "Kpi Sample Type",
"multi": true,
"name": "kpi_sample_type",
"options": [],
"query": "SHOW TAG VALUES FROM samples WITH KEY=\"kpi_sample_type\"",
"refresh": 2,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
}
]
},
"time": {
"from": "now-5m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "L3 Monitoring",
"uid": "5d_I5W-nz",
"version": 2
}
}
This diff is collapsed.
......@@ -12,6 +12,7 @@ _sym_db = _symbol_database.Default()
from . import context_pb2 as context__pb2
from . import monitoring_pb2 as monitoring__pb2
DESCRIPTOR = _descriptor.FileDescriptor(
......@@ -20,14 +21,77 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x0c\x64\x65vice.proto\x12\x06\x64\x65vice\x1a\rcontext.proto2\xf0\x01\n\rDeviceService\x12\x31\n\tAddDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x37\n\x0f\x43onfigureDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0c\x44\x65leteDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12>\n\x10GetInitialConfig\x12\x11.context.DeviceId\x1a\x15.context.DeviceConfig\"\x00\x62\x06proto3'
serialized_pb=b'\n\x0c\x64\x65vice.proto\x12\x06\x64\x65vice\x1a\rcontext.proto\x1a\x10monitoring.proto\"\xa4\x01\n\x12MonitoringSettings\x12!\n\x06kpi_id\x18\x01 \x01(\x0b\x32\x11.monitoring.KpiId\x12\x31\n\x0ekpi_descriptor\x18\x02 \x01(\x0b\x32\x19.monitoring.KpiDescriptor\x12\x1b\n\x13sampling_duration_s\x18\x03 \x01(\x02\x12\x1b\n\x13sampling_interval_s\x18\x04 \x01(\x02\x32\xb2\x02\n\rDeviceService\x12\x31\n\tAddDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x37\n\x0f\x43onfigureDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0c\x44\x65leteDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12>\n\x10GetInitialConfig\x12\x11.context.DeviceId\x1a\x15.context.DeviceConfig\"\x00\x12@\n\x10MonitorDeviceKpi\x12\x1a.device.MonitoringSettings\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
,
dependencies=[context__pb2.DESCRIPTOR,])
dependencies=[context__pb2.DESCRIPTOR,monitoring__pb2.DESCRIPTOR,])
_MONITORINGSETTINGS = _descriptor.Descriptor(
name='MonitoringSettings',
full_name='device.MonitoringSettings',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='kpi_id', full_name='device.MonitoringSettings.kpi_id', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='kpi_descriptor', full_name='device.MonitoringSettings.kpi_descriptor', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='sampling_duration_s', full_name='device.MonitoringSettings.sampling_duration_s', index=2,
number=3, type=2, cpp_type=6, label=1,
has_default_value=False, default_value=float(0),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='sampling_interval_s', full_name='device.MonitoringSettings.sampling_interval_s', index=3,
number=4, type=2, cpp_type=6, label=1,
has_default_value=False, default_value=float(0),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=58,
serialized_end=222,
)
_MONITORINGSETTINGS.fields_by_name['kpi_id'].message_type = monitoring__pb2._KPIID
_MONITORINGSETTINGS.fields_by_name['kpi_descriptor'].message_type = monitoring__pb2._KPIDESCRIPTOR
DESCRIPTOR.message_types_by_name['MonitoringSettings'] = _MONITORINGSETTINGS
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
MonitoringSettings = _reflection.GeneratedProtocolMessageType('MonitoringSettings', (_message.Message,), {
'DESCRIPTOR' : _MONITORINGSETTINGS,
'__module__' : 'device_pb2'
# @@protoc_insertion_point(class_scope:device.MonitoringSettings)
})
_sym_db.RegisterMessage(MonitoringSettings)
_DEVICESERVICE = _descriptor.ServiceDescriptor(
......@@ -37,8 +101,8 @@ _DEVICESERVICE = _descriptor.ServiceDescriptor(
index=0,
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_start=40,
serialized_end=280,
serialized_start=225,
serialized_end=531,
methods=[
_descriptor.MethodDescriptor(
name='AddDevice',
......@@ -80,6 +144,16 @@ _DEVICESERVICE = _descriptor.ServiceDescriptor(
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
_descriptor.MethodDescriptor(
name='MonitorDeviceKpi',
full_name='device.DeviceService.MonitorDeviceKpi',
index=4,
containing_service=None,
input_type=_MONITORINGSETTINGS,
output_type=context__pb2._EMPTY,
serialized_options=None,
create_key=_descriptor._internal_create_key,
),
])
_sym_db.RegisterServiceDescriptor(_DEVICESERVICE)
......
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: kpi_sample_types.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='kpi_sample_types.proto',
package='kpi_sample_types',
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3'
)
_KPISAMPLETYPE = _descriptor.EnumDescriptor(
name='KpiSampleType',
full_name='kpi_sample_types.KpiSampleType',
filename=None,
file=DESCRIPTOR,
create_key=_descriptor._internal_create_key,
values=[
_descriptor.EnumValueDescriptor(
name='KPISAMPLETYPE_UNKNOWN', index=0, number=0,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
_descriptor.EnumValueDescriptor(
name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202,
serialized_options=None,
type=None,
create_key=_descriptor._internal_create_key),
],
containing_type=None,
serialized_options=None,
serialized_start=45,
serialized_end=235,
)
_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE)
KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE)
KPISAMPLETYPE_UNKNOWN = 0
KPISAMPLETYPE_PACKETS_TRANSMITTED = 101
KPISAMPLETYPE_PACKETS_RECEIVED = 102
KPISAMPLETYPE_BYTES_TRANSMITTED = 201
KPISAMPLETYPE_BYTES_RECEIVED = 202
DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
# @@protoc_insertion_point(module_scope)
This diff is collapsed.
flask
flask-wtf
flask-healthz
flask-unittest
grpcio
grpcio-health-checking
prometheus-client
pytest
pytest-benchmark
lorem-text
coverage
Flask==2.0.1
Flask-WTF==1.0.0
flask-healthz==0.0.3
flask-unittest==0.1.2
grpcio==1.43.0
grpcio-health-checking==1.43.0
protobuf==3.17.3
prometheus-client==0.11.0
pytest==6.2.5
pytest-benchmark==3.4.1
lorem-text==2.1
coverage==6.3
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment