From 808b634e339731edea4ba0856b6e542ab36396ff Mon Sep 17 00:00:00 2001 From: Ryabin Sergey Date: Sun, 24 Sep 2023 00:20:34 +0200 Subject: [PATCH 1/3] Fix typo in jinja2 variable name and parametrize exchange name --- templates/rabbitmq/create_exchange.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/rabbitmq/create_exchange.sh b/templates/rabbitmq/create_exchange.sh index 2daeacf..76678fb 100644 --- a/templates/rabbitmq/create_exchange.sh +++ b/templates/rabbitmq/create_exchange.sh @@ -4,8 +4,8 @@ RABBITMQ_ENDPOINT=`minikube ip`:{{ p.rabbitmq_manage_node_port }} {% if "rabbitmq_exchanges" in p %} -{% for exhcnage_name, exchange in p.rabbitmq_exchanges.items() %} -kubectl -n {{ p.rabbitmq_namespace }} exec {{ p.rabbitmq_release_name }}-0 -ti -- curl -i -u {{ p.rabbitmq_user }}:{{ p.rabbitmq_password }} -H "Content-type: application/json" -XPUT -d'{{ exchange | to_json }}' localhost:15672/api/exchanges/%2f/io-context +{% for exchange_name, exchange in p.rabbitmq_exchanges.items() %} +kubectl -n {{ p.rabbitmq_namespace }} exec {{ p.rabbitmq_release_name }}-0 -ti -- curl -i -u {{ p.rabbitmq_user }}:{{ p.rabbitmq_password }} -H "Content-type: application/json" -XPUT -d'{{ exchange | to_json }}' localhost:15672/api/exchanges/%2f/{{ exchange_name }} {% endfor %} {# for exhcnage_name, exchange in rabbitmq_exchanges.items() #} {% endif %} From 78b3ab5114f75bcd780bc4161f1751e4cd1dc7e1 Mon Sep 17 00:00:00 2001 From: Ryabin Sergey Date: Sun, 24 Sep 2023 00:20:50 +0200 Subject: [PATCH 2/3] Add new rabbitmq io-document queue --- inventory/classes/rabbitmq/common.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/inventory/classes/rabbitmq/common.yml b/inventory/classes/rabbitmq/common.yml index e8b7e3a..b4b0bdb 100644 --- a/inventory/classes/rabbitmq/common.yml +++ b/inventory/classes/rabbitmq/common.yml @@ -4,6 +4,9 @@ parameters: io-context: type: fanout durable: true + io-document: + type: fanout + durable: true rabbitmq_version: 3.12.4 rabbitmq_user: user rabbitmq_password: password From d2da96ab566167b774997e9986c42ab9329f10a4 Mon Sep 17 00:00:00 2001 From: Ryabin Sergey Date: Sun, 24 Sep 2023 18:25:16 +0200 Subject: [PATCH 3/3] Add simple object parser using textfsm for kubectl get pods output --- files/textfsm/parser_output.py | 116 +++++++++++++++++++++++++++++++++ files/textfsm/requirements.txt | 6 ++ files/textfsm/template.txt | 10 +++ 3 files changed, 132 insertions(+) create mode 100644 files/textfsm/parser_output.py create mode 100644 files/textfsm/requirements.txt create mode 100644 files/textfsm/template.txt diff --git a/files/textfsm/parser_output.py b/files/textfsm/parser_output.py new file mode 100644 index 0000000..cd363df --- /dev/null +++ b/files/textfsm/parser_output.py @@ -0,0 +1,116 @@ +import sys +import textfsm +import pprint +import json +from tabulate import tabulate +import io +from neo4j import GraphDatabase +import grpc +import freeplane_pb2 +import freeplane_pb2_grpc +import pika +import pprint + +template = sys.argv[1] +output_file = sys.argv[2] + +rabbitmq_url = "amqp://user:password@192.168.49.2:30466/%2f" +neo4j_url = "bolt://192.168.49.2:31237" +neo4j_username = 'neo4j' +neo4j_password = 'password' + +exchange_name = "io-document" + +connection = pika.BlockingConnection(pika.URLParameters(rabbitmq_url)) +rabbitmq_channel = connection.channel() + +result = rabbitmq_channel.queue_declare(queue="", exclusive=True) +queue_name = result.method.queue + +rabbitmq_channel.queue_bind(exchange=exchange_name, queue=queue_name) + +grpc_channel = grpc.insecure_channel('localhost:50051') +fp = freeplane_pb2_grpc.FreeplaneStub(grpc_channel) + +def do_textfsm(stdout): + print(stdout) + with open(template) as f: + re_table = textfsm.TextFSM(io.StringIO(f.read())) + header = re_table.header + result = re_table.ParseText(stdout) + # pprint.pprint(json.dumps(result)) + print(json.dumps({"header": header, "result": result})) + #print(tabulate(result, headers=header)) + return header, result + +class IoContextDocument: + __io_document = {} + __host = "" + __tmux_session_name = "" + __tmux_pane_id = "" + + def getUniqSessionId(self): + return 'mindwm-{hostname}-{tmux_session_name}-{tmux_pane_id}'.format( + hostname = self.getHost(), + tmux_session_name = self.getTmuxSessionName(), + tmux_pane_id = self.getTmuxPaneId() + ) + + def getHost(self): + return self.__io_document['host'] + + def getTmuxSessionName(self): + return self.__io_document['metadata']['tmux']['session_name'] + + def getTmuxPaneId(self): + return self.__io_document['metadata']['tmux']['pane_id'] + + def getPS1Start(self): + # fix for the new pane + ps1 = self.__io_document['message']['ps1_start'] + if ps1 == '': + ps1 = self.__io_document['message']['ps1_end'] + + return ps1 + + def getPS1End(self): + return self.__io_document['message']['ps1_end'] + + + def getInput(self): + return self.__io_document['message']['input'] + + def getOutput(self): + return self.__io_document['message']['output'] + + def __init__(self, document): + self.__io_document = document + pprint.pprint(document) + print(f"IoContextDocument: {self.getHost()}->{self.getTmuxSessionName()}") + +def fpDrawTable(fp_node_id, header, table_body): + for item in table_body: + fp_node = fp.CreateChild(freeplane_pb2.CreateChildRequest(name=item[0], parent_node_id = fp_node_id)) + name = item[0] + for i in range(1, len(item)): + fp.NodeAttributeAdd(freeplane_pb2.NodeAttributeAddRequest(node_id=fp_node.node_id, attribute_name=header[i], attribute_value=item[i])) + print(f"{header[i]}: {item[i]}\n") + + + +def callback(ch, method, properties, body): + data = json.loads(body.decode()) + io_context_document = IoContextDocument(data) + original_string = io_context_document.getOutput() + + lines = original_string.splitlines() + non_empty_lines = [line for line in lines if line.strip()] + result_string = "\n".join(non_empty_lines) + + header, result = do_textfsm(result_string) + fpDrawTable(data['_fp_node_id'], header, result) + +rabbitmq_channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True) +print("Waiting for messages. To exit, press Ctrl+C") +rabbitmq_channel.start_consuming() + diff --git a/files/textfsm/requirements.txt b/files/textfsm/requirements.txt new file mode 100644 index 0000000..396143c --- /dev/null +++ b/files/textfsm/requirements.txt @@ -0,0 +1,6 @@ +pika +neo4j +grpcio +protobuf +textfsm +tabulate diff --git a/files/textfsm/template.txt b/files/textfsm/template.txt new file mode 100644 index 0000000..cca8e99 --- /dev/null +++ b/files/textfsm/template.txt @@ -0,0 +1,10 @@ +Value Key POD_NAME ([^ ]+) +Value Required NOT_READY ([0-9]) +Value Required TOTAL ([0-9]) +Value Required STATUS (\S+) +Value Required RESTARTS ([0-9]+) +Value Required AGE ([0-9]+[a-z]) + +Start + ^${POD_NAME}\s+${NOT_READY}/${TOTAL}\s+${STATUS}\s+${RESTARTS} \([0-9a-z]+ ago\)\s+${AGE} -> Continue.Record +