diff --git a/src/tngcli/cli.py b/src/tngcli/cli.py index e5421d7..38a110d 100644 --- a/src/tngcli/cli.py +++ b/src/tngcli/cli.py @@ -195,9 +195,12 @@ def dispatch(args): #monitor subcommand elif args.subparser_name == 'monitor': - sel_args = [args.target_list, args.service_list, args.metric_list, - args.vnf_uuid, args.vdu_uuid, args.metric_name, - args.vnv_tests, args.service_uuid, args.remove_service] + sel_args = [args.target_add, args.target_list, args.service_list, + args.metric_list, args.vnf_uuid, args.vdu_uuid, + args.metric_name, args.vnv_tests, args.service_uuid, + args.remove_service, args.target_name,args.target_endpoint, + args.target_type, args.target_path] + arg_sum = len([x for x in sel_args if x]) if arg_sum == 0: msg = "Missing arguments for tng-cli monitor. " \ @@ -205,7 +208,7 @@ def dispatch(args): print(msg) exit(1) - if arg_sum > 3: + if arg_sum > 5: msg = "Too many arguments for subcommand monitor. " \ "Type tng-cli monitor -h" print(msg) @@ -245,6 +248,20 @@ def dispatch(args): form_print(mes, order) exit(not res) + if args.target_add: + if (not args.target_name) or (not args.target_path) or (not args.target_endpoint) or (not args.target_path): + msg = "arguments missing " \ + "Type tng-cli monitor -tga -h" + print(msg) + exit(1) + res, mes = tnglib.add_prometheus_targets(args.target_name, + args.target_endpoint, + args.target_type, + args.target_path) + order = ['target', 'endpoint'] + form_print(mes, order) + exit(not res) + if args.service_list: res, mes = tnglib.get_services(args.service_list) order = ['vnf_uuid', 'vdu_uuid'] @@ -1327,7 +1344,48 @@ def parse_args(args): required=False, default=False, help='Only with --attach. Attach policy to an sla') + # monitoring sub arguments + help_mes = 'Add monitoring endpoint. Only with --target-name --target-type --target-endpoint, --target-path' + parser_mon.add_argument('-tra', + '--target-add', + action='store_true', + required=False, + default=False, + help=help_mes) + + help_mes = 'Only with --target-add' + parser_mon.add_argument('-url', + '--target-endpoint', + metavar='TARGET ENDPOINT', + required=False, + default=False, + help=help_mes) + + help_mes = 'Only with --target-add' + parser_mon.add_argument('-nm', + '--target-name', + metavar='TARGET NAME', + required=False, + default=False, + help=help_mes) + + help_mes = 'Only with --target-add' + parser_mon.add_argument('-tp', + '--target-type', + metavar='TARGET TYPE', + required=False, + default=False, + help=help_mes) + + help_mes = 'Only with --target-add' + parser_mon.add_argument('-pth', + '--target-path', + metavar='TARGET PATH', + required=False, + default=False, + help=help_mes) + help_mes = 'Get list of monitoring endpoints' parser_mon.add_argument('-trl', '--target-list', diff --git a/src/tnglib/monitor.py b/src/tnglib/monitor.py index a07bdf8..12fee32 100644 --- a/src/tnglib/monitor.py +++ b/src/tnglib/monitor.py @@ -40,6 +40,78 @@ LOG = logging.getLogger(__name__) +def add_prometheus_targets(name, endpoint, type, path): + """Adds a new monitoring endpoint. + k8s ex. monitor -tra --target-name test1 --target-type k8s --target-endpoint 10.200.16.2:30090 --target-path /federate + Exporter ex. monitor -tra --target-name test1 --target-type exporter --target-endpoint 145.20.146.2:9091 --target-path /metrics + + :param name: name of the monitored VIM. + :param endpoint: monitoring endpoint (:). + :param type: type of exporter ('k8s' or 'exporter'). + :param path: url's path ('/federate' or 'metrics'). + :returns: A list. [0] is a bool with the result. [1] is a list of + dictionaries. Each dictionary contains a target. + """ + # get current list of targets + resp = requests.get(env.monitor_api + '/prometheus/targets', + timeout=env.timeout, + headers=env.header) + + if resp.status_code != 200: + LOG.debug("Request returned with " + (str(resp.status_code))) + error = resp.text + return False, error + + templates = json.loads(resp.text) + + if type == 'k8s': + trg = {'honor_labels':True,'job_name':name,'metrics_path':path, + 'params':{'match[]':["{job='kubernetes-cadvisor'}", + "{job='kubernetes-nodes'}", + "{job='kubernetes-pods'}", + "{job='pushgateway'}"]}, + 'scrape_interval':'10s','scrape_timeout':'10s', + 'static_configs':[{'targets':[endpoint]}]} + elif type == 'exporter': + trg = {'job_name': name, 'metrics_path':path, + 'scrape_interval':"5s", + 'scrape_timeout': "5s", + 'static_configs': [{'targets': [endpoint]}]} + else: + LOG.debug("Provide exporter type (k8s/exporter)") + error = "Unsupported exporter type (k8s/exporter)" + return False, error + + found = False + if 'targets' in templates: + i = 0 + for t in templates['targets']: + if 'job_name' in t: + if ':' in t['job_name']: + trg_name = t['job_name'].split(':')[0] + else: + trg_name = t['job_name'] + if trg_name == name: + templates['targets'][i] = trg + found = True + break + i =i + 1 + + if not found: + templates['targets'].append(trg) + + resp = requests.post(env.monitor_api + '/prometheus/targets', + json=templates, + timeout=env.timeout, + headers=env.header) + + if resp.status_code != 200: + LOG.debug("Request returned with " + (str(resp.status_code))) + error = resp.text + return False, error + + return True, get_prometheus_targets()[1] + def get_prometheus_targets(): """Returns all the monitoring targets from Prometheus server. @@ -74,6 +146,8 @@ def get_prometheus_targets(): for e in trg['targets']: if not first_trg: trg_name = ' ' + if ':' in trg_name: + trg_name = trg_name.split(':')[0] dic = {'target': trg_name, 'endpoint': e} first_trg = True LOG.debug(str(dic))