作者:Melisha Dsouza 翻譯:吳金笛 校對:國相潔
本文約3000字,建議閱讀10+分鐘。
本文是建立聊天機器人實現網路運營的簡單教程。
在本教程中,我們將瞭解如何利用聊天機器人來協助網路運營。隨著我們向智慧化運營邁進,另一個需要關註的領域是移動性。用一個指令碼來進行配置,修複甚至故障檢修是很好的,但它仍然需要有人在場來監督,啟動甚至執行這些程式或指令碼。
Nokia’s MIKA 是一個很好的聊天機器人例子,操作人員可以用它來進行網路故障排除和修複。根據 Nokia’s blog,MIKA會根據此單個網路的實際情況給出一個警報優先順序資訊,並將當前的情況與該網路和其他網路過去事件的整個服務歷史進行比較,以確定當前問題的最佳解決方案。
Nokia’s MIKA
https://networks.nokia.com/services/digital-assistant-as-a-service
Nokia’s blog
https://www.nokia.com/blog/chatting-bots-home-work
讓我們建立一個聊天機器人來協助網路運營。對於這個用例,我們將使用一個被廣泛使用的聊天應用程式Slack。參考Splunk的智慧資料分析能力,我們將看到一些使用者與聊天機器人的互動,從而對環境有一些瞭解。
本教程摘自AbhishekRatan撰寫的名為《Practical Network Automation – SecondEdition》的書。 這本書將向您介紹網路自動化的基本概念,並幫助您提高你的資料中心的穩健性和安全性。
可以在GitHub中找到本教程的程式碼:
Github連結:
https://github.com/PacktPublishing/Practical-Network-Automation-Second-Edition/tree/master/Chapter0
在我們部署web框架時,我們將利用相同的框架與Slack聊天機器人進行互動,後者又將與Splunk進行互動。它還可以直接與網路裝置互動,所以我們可以發起一些複雜的聊天,例如在需要時從Slack重啟路由器。這最終為工程師提供了移動性,工程師可以在任何地方(甚至是手機)處理任務,而不必被固定在某個地點或辦公室。
要建立聊天機器人,以下是基本步驟:
1. 在Slack上建立一個工作區(或帳戶):
2. 在你的工作區建立一個應用程式(在我們的例子中,我們建立了一個叫做mybot的應用程式):
3. 以下是關於該應用程式的基本資訊(App ID 和Client ID可以與唯一標識此應用程式的其他資訊一起使用):
4. 為此應用程式新增bot功能:
5. 新增事件訂閱並對映到將要釋出訊息的外部API。
事件訂閱是指某人在聊天中鍵入對聊天機器人的取用,然後使用該聊天機器人與聊天中被輸入的資料呼叫這個API:
這裡,一個關鍵的步驟是,一旦我們輸入了接受聊天訊息的URL,就需要從Slack驗證這個特定的URL。驗證就是API端點以字串或JSON的格式傳回,與從Slack傳送的響應相同的響應。如果我們收到相同的響應,Slack確認該端點是可信的並將其標記為已驗證。這是一個一次性的過程,並且API URL中的任何更改都將導致此步驟的重覆。
以下是Ops API框架中響應特定查詢的Python程式碼:
1. import falcon
2. import json
3. def on_get(self,req,resp):
4. # Handles GET request
5. resp.status=falcon.HTTP_200 # Default status
6. resp.body=json.dumps({“Server is Up!”})
7. def on_post(self,req,resp):
8. # Handles POST Request
9. print(“In post”)
10. data=req.bounded_stream.read()
11. try:
12. # Authenticating end point to Slack
13. data=json.loads(data)[“challenge”]
14. # Default status
15. resp.status=falcon.HTTP_200
16. # Send challenge string back as response
17. resp.body=data
18. except:
19. # URL already verified
20. resp.status=falcon.HTTP_200
21. resp.body=””
這將驗證,如果從Slack發出一個”challenge”,它將傳回相同的”challenge”,這個值確認該端點是Slack頻道傳送聊天資料的正確端點。
6. 安裝此應用程式(或聊天機器人)到任何頻道(這類似於在群聊中新增使用者):
響應特定聊天資訊的核心API框架程式碼執行以下操作:
-
確認任何傳送到Slack的資訊在三秒內響應200次。如果沒有這樣,Slack報告:endpoint not reachable.
-
確保任何從聊天機器人(不是來自任何真實使用者)發出的資訊不作為回覆資訊再次被髮回。這可能會造成迴圈,因為從聊天機器人傳送的訊息將被視為Slack聊天中的新訊息,然後它將被再次傳送到URL。這最終會使聊天無法使用,從而導致聊天中出現重覆的訊息。
-
使用將被髮送回Slack的令牌對響應進行身份驗證,以確保來自Slack的響應來自經過身份驗證的源。
程式碼如下:
1. import falcon
2. import json
3. import requests
4. import base64
5. from splunkquery import run
6. from splunk_alexa import alexa
7. from channel import channel_connect,set_data
8. class Bot_BECJ82A3V():
9. def on_get(self,req,resp):
10. # Handles GET request
11. resp.status=falcon.HTTP_200 # Default status
12. resp.body=json.dumps({“Server is Up!”})
13. def on_post(self,req,resp):
14. # Handles POST Request
15. print(“In post”)
16. data=req.bounded_stream.read()
17. try:
18. bot_id=json.loads(data)[“event”][“bot_id”]
19. if bot_id==“BECJ82A3V”:
20. print(“Ignore message from same bot”)
21. resp.status=falcon.HTTP_200
22. resp.body=””
23. return
24. except:
25. print(“Life goes on. . .”)
26. try:
27. # Authenticating end point to Slack
28. data=json.loads(data)[“challenge”]
29. # Default status
30. resp.status=falcon.HTTP_200
31. # Send challenge string back as response
32. resp.body=data
33. except:
34. # URL already verified
35. resp.status=falcon.HTTP_200
36. resp.body=””
37. print(data)
38. data=json.loads(data)
39. #Get the channel and data information
40. channel=data[“event”][“channel”]
41. text=data[“event”][“text”]
42. # Authenticate Agent to access Slack endpoint
43. token=“xoxp-xxxxxx”
44. # Set parameters
45. print(type(data))
46. print(text)
47. set_data(channel,token,resp)
48. # Process request and connect to slack channel
49. channel_connect(text)
50. return
51.# falcon.API instance , callable from gunicorn
52.app= falcon.API()
53.# instantiate helloWorld class
54.Bot3V=Bot_BECJ82A3V()
55.# map URL to helloWorld class
56.app.add_route(“/slack”,Bot3V)
-
執行頻道互動響應
此程式碼解釋聊天頻道中使用chat-bot執行的特定聊天。此外,這將使用對特定使用者或頻道ID的響應,以及對Slack API 的身份驗證令牌進行響應。
Slack API:
https://slack.com/api/chat.postMessag
這保證Slack聊天的訊息或回覆顯示在其起源的特定頻道上。作為示例,我們將使用聊天對特定值進行加密或解密。
例如,如果我們寫入encrypt username[:]password,它將傳回一個利用base64值加密的字串。
類似地,如果我們寫入decrypt, 聊天機器人會傳回一個加密字串解密後的字串。
程式碼如下:
1. import json
2. import requests
3. import base64
4. from splunk_alexa import alexa
5. channl=””
6. token=””
7. resp=””
8. def set_data(Channel,Token,Response):
9. global channl,token,resp
10. channl=Channel
11. token=Token
12. resp=Response
13.def send_data(text):
14.global channl,token,res
15.print(channl)
16.resp = requests.post(“https://slack.com/api/chat.postMessage”,data=‘{“channel”:”‘+channl+‘”,”text”:”‘+text+‘”}’,essay-headers={“Content-type”: “application/json”,“Authorization”: “Bearer “+token},verify=False)
17.
18.def channel_connect(text):
19.global channl,token,resp
20.try:
21.print(text)
22.arg=text.split(‘ ‘)
23.print(str(arg))
24.path=arg[0].lower()
25.print(path in [“decode”,“encode”])
26.if path in [“decode”,“encode”]:
27.print(“deecode api”)
28.else:
29.result=alexa(arg,resp)
30.text=””
31.try:
32.for i in result:
33.print(i)
34.print(str(i.values()))
35.for j in i.values():
36.print(j)
37.text=text+‘ ‘+j
38.#print(j)
39.if text==”” or text==None:
40.text=“None”
41.send_data(text)
42.return
43.except:
44.text=“None”
45.send_data(text)
46.return
47.decode=arg[1]
48.except:
49.print(“Please enter a string to decode”)
50.text=” argument cannot be empty”
51.send_data(text)
52.return
53.deencode(arg,text)
54.
55.def deencode(arg,text):
56.global channl,token,resp
57.decode=arg[1]
58.if arg[1]==‘–help’:
59.#print(“Sinput”)
60.text=“encode/decode “
61.send_data(text)
62.return
63.if arg[0].lower()==“encode”:
64.encoded=base64.b64encode(str.encode(decode))
65.if ‘[:]’ in decode:
66.text=“Encoded string: “+encoded.decode(‘utf-8’)
67.send_data(text)
68.return
69.else:
70.text=“sample string format username[:]password”
71.send_data(text)
72.return
73.try:
74.creds=base64.b64decode(decode)
75.creds=creds.decode(“utf-8”)
76.except:
77.print(“problem while decoding String”)
78.text=“Error decoding the string. Check your encoded string.”
79.send_data(text)
80.return
81.if ‘[:]’ in str(creds):
82.print(“[:] substring exists in the decoded base64 credentials”)
83.# split based on the first match of “[:]”
84.credentials = str(creds).split(‘[:]’,1)
85.username = str(credentials[0])
86.password = str(credentials[1])
87.status = ‘success’
88.else:
89.text=“encoded string is not in standard format, use username[:]password”
90.send_data(text)
91.print(“the encoded base64 is not in standard format username[:]password”)
92.username = “Invalid”
93.password = “Invalid”
94.status = ‘failed’
95.temp_dict = {}
96.temp_dict[‘output’] = {‘username’:username,‘password’:password}
97.temp_dict[‘status’] = status
98.temp_dict[‘identifier’] = “”
99.temp_dict[‘type’] = “”
100.#result.append(temp_dict)
101.print(temp_dict)
102.text=” “+username+” “+password
103.send_data(text)
104.print(resp.text)
105.print(resp.status_code)
106.return
此程式碼查詢Splunk實體以查詢與聊天機器人的特定聊天。聊天會請求當前關閉的任何一個管理介面(Loopback45)。 此外,在聊天中,使用者可以查詢所有具有up管理介面的路由器。 此英語響應將被轉換為Splunk查詢,並根據Splunk的響應將狀態傳回到Slack聊天。
讓我們看看對Slack聊天執行操作來響應結果的程式碼:
1. from splunkquery import run
2. def alexa(data,resp):
3. try:
4. string=data.split(‘ ‘)
5. except:
6. string=data
7. search=‘ ‘.join(string[0:-1])
8. param=string[-1]
9. print(“param”+param)
10. match_dict={0:“routers management interface”,1:“routers management loopback”}
11. for no in range(2):
12. print(match_dict[no].split(‘ ‘))
13. print(search.split(‘ ‘))
14. test=list(map(lambda x:x in search.split(‘ ‘),match_dict[no].split(‘ ‘)))
15. print(test)
16. print(no)
17. if False in test:
18. pass
19. else:
20. if no in [0,1]:
21. if param.lower()==“up”:
22. query=“search%20index%3D%22main%22%20earliest%3D0%20%7C%20dedup%20interface_name%2Crouter_name%20%7C%20where%20interface_name%3D%22Loopback45%22%20%20and%20interface_status%3D%22up%22%20%7C%20table%20router_name”
23. elif param.lower()==“down”:
24. query=“search%20index%3D%22main%22%20earliest%3D0%20%7C%20dedup%20interface_name%2Crouter_name%20%7C%20where%20interface_name%3D%22Loopback45%22%20%20and%20interface_status%21%3D%22up%22%20%7C%20table%20router_name”
25. else:
26. return “None”
27. result=run(query,resp)
28. return result
下麵的Splunk查詢來獲取狀態:
-
對於UP介面——“查詢”如下:
index=”main”earliest=0 | dedup interface_name,router_name | whereinterface_name=”Loopback45″ and interface_status=”up” |table router_name
-
對於DOWN介面(除此以外的任何狀態)——“查詢”如下:
index=”main”earliest=0 | dedup interface_name,router_name | whereinterface_name=”Loopback45″ and interface_status!=”up” |table router_name
讓我們看看與聊天機器人聊天的最後結果以及根據聊天記錄發回的響應。
編碼/解碼示例如下:
正如我們所見,我們發送了一個帶有encode abhishek[:]password123 資訊的聊天。此聊天作為POST請求傳送到API,後者又將其加密到base64並新增到Encoded string: 之後被傳回。在下一個聊天中,我們使用decode選項傳入相同的字串。這將透過解碼來自API函式的資訊進行響應,並且用使用者名稱abhishek和密碼password123來響應Slack聊天。
讓我們看一看Splunk查詢聊天的示例:
在此查詢中,我們關閉了rtr1上的Loopback45介面。透過Python指令碼,在我們對這些介面預定的發現過程中,資料位於Splunk中。當查詢到哪個管理介面(Loopback45)關閉時,它將用rtr1響應。Slack聊天將“On which routers the management interface is down”傳遞給API,在收到有效載荷時,後者將執行Splunk查詢以獲取統計資訊。傳回值(在本例中為rtr1)將作為聊天中的響應資訊被傳回。
類似地,“On which routers the management interface is down”的反向查詢將查詢Splunk並最終共享rtr2, rtr3, 和rtr4的響應(因為所有這些路由器上的介面都是UP)。
此聊天用例可以被擴充套件,以確保使用簡單聊天來進行完整的端到端故障排除。使用各種後端功能可以構建從問題的基本識別到複雜任務的大量案例,例如基於已識別情況的修複。
總結
在本教程中,我們實現了一些真實的用例,並研究了使用chatbot執行故障排除的技術。這些用例使我們深入瞭解了執行智慧修複以及進行大規模審查,這是當前環境中的關鍵挑戰。
要學習如何利用Python的強大功能,毫無困難地自動化你的網路,請檢視我們的書:《Practical Network Automation – Second Edition》。
原文標題:
Creating a chatbot to assist in network operations [Tutorial]
原文連結:
https://hub.packtpub.com/creating-a-chatbot-to-assist-in-network-operations-tutorial/
譯者簡介:吳金笛,雪城大學電腦科學碩士一年級在讀。迎難而上是我最舒服的狀態,動心忍性,曾益我所不能。我的標的是做個早睡早起的Cool Girl。
「完」