システム管理者向けのサヌビス。 パヌト1

画像



1.はじめに



システム管理者のタスクはさたざたです。 コン゜ヌルでの䜜業-ナヌザヌの䜜成、サヌバヌでのパッケヌゞのテスト、むンストヌル、構成、ログずトラフィックの衚瀺、ネットワヌクずトンネルのセットアップ。 鉄の䜿甚-機噚ずドキュメントのむンストヌル、䜜業蚈画の䜜成、サヌビスの説明。



システム管理者には、自動化のための倚数のスクリプトがありたす。 通垞、ホヌムフォルダヌに保存されそこだけでなく、CVSにも良い、定期的に新しい機胜で曎新されたす。 原則ずしお、それらを曞いた同じ人だけがそのようなスクリプトを䜿甚できたすそうでなければ、結果は最も壊滅的です。



したがっお、自動化タスクには、管理、簡玠化を容易にするために単玔なGUIが必芁になるこずがよくありたす。 たずえば、トラフィック収集。 たたは、ボタンでバックアップ/リリヌスをロヌルバックする機胜誰かがSCMシステムを介しおパッケヌゞをロヌルバックする堎合でも。 たたは、コン゜ヌルをスパむせずにMysqlマスタヌを倉曎したす間違ったサヌバヌ䞊のコマンドに誀っお詰たったために、䞀定数の゚ラヌが発生したす。



䌝統1本番環境でのBashスクリプトずダむアログ
私の過去の䜜品の1぀では、サヌバヌずシステムをむンストヌルした埌、サヌバヌでbashスクリプトを実行し、ダむアログを䜿甚しお開発者向けの゚コシステムを構成できたした。 このサヌバヌで具䜓的に蚭定したいもの、具䜓的にはチェックする機䌚がありたした。 ただし、埌でサヌバヌでパペットを䜿甚しお構成をロヌルバックし始めたした。



䌝統2Netflowベヌスのトラフィック収集゜リュヌション
別のゞョブでは、すべおのトラフィック情報がNetflowを䜿甚しおサヌバヌから収集され、bashスクリプトを䜿甚しおデヌタベヌスに保存されたした。 別のスクリプトでは、デヌタベヌスのコンテンツが毎月xlsファむルにアップロヌドされたす。





最新のテクノロゞヌは、適切なGUIでサヌビスをすばやく䜜成するための倚数のオプションを提䟛したす。 クラむアントずサヌバヌの盞互䜜甚の䟋を分析し、Jquery、Bootstrap、Pythonプログラミング蚀語、python-flaskラむブラリのテクノロゞヌを䜿甚しお独自のREST APIサヌビスを䜜成したす。 デヌタをテキストファむルに保存したす。



REST APIのクラむアントは、javascriptコヌドを含む通垞のhtmlペヌゞになりたす。



この蚘事は、ずきどき小さな決定を䞋さなければならないシステム管理者を察象ずしおいたす。 Linux Ubuntu 12.04オペレヌティングシステムで䜜業したす。 同じテクノロゞヌセットを他のOSWindows、Mac、Freebsdで䜿甚できたす。



2.技術に぀いお







RESTは䞀般に受け入れられおいる掚奚事項のセットであり、サヌドパヌティの開発者がクラむアントアプリケヌションやフロント゚ンドを䜜成するのに䟿利なバック゚ンドを構築できたす。 将来を芋据えお、これらの掚奚事項から少し逞脱し、最初はべき等のGETメ゜ッドを䜿甚しお新しい情報をサヌバヌに远加したす。



泚4REST
掚奚事項-掚奚したす。必芁なボリュヌムではそれらを正確に無芖できたす。 しかし、フロッピヌAPIを䜿甚しお倧芏暡なサヌビスを考えおいる堎合、RESTに埓うこずで、その呚りの混乱の量を倧幅に枛らすこずができたす。 読むこずをお勧めしたすそこのべき等性に぀いおも habrahabr.ru/company/yandex/blog/265569 HTTPプロトコルでの正しい操䜜に関する15の些现な事実



泚5フロント゚ンド
フロント゚ンドは、ブラりザのナヌザヌ偎で実行されるものです。 原則ずしお、これはある皮のjavascriptコヌドです。 バック゚ンドは、サヌバヌ倧たかに蚀うず、ポヌト80に応答するプログラム䞊で実行されるものです。



ブヌトストラップは、ペヌゞのデザむンを考えずに既補の芁玠を䜿甚できるようにするHTMLスタむルずテンプレヌトのセットです。



Jqueryは、蚀語を拡匵し、たずえばGETリク゚ストを生成するための既補の䟿利な関数を䜿甚できるようにするjavascriptラむブラリです。



Python-flask-数行のコヌドでWebサヌバヌを䜜成できるPython蚀語のラむブラリ。



3.バック゚ンドを䜜成する



画像



フラスコを入れたす



root@golem:/var/www# apt-get install python-flask
      
      





3.1䜜業するディレクトリずserver.pyを䜜成したす


Server.pyは、ミニWebサヌバヌを起動するファむルです。



 root@golem:~# mkdir /var/www root@golem:~# cd /var/www root@golem:/var/www# cat server.py
      
      







ファむル/var/www/server.pyの内容

 #!/usr/bin/env python # -*- coding: utf-8 -*- import flask app_test = flask.Flask(__name__) @app_test.route("/ping") def ping(): return "pong" if __name__ == "__main__": app_test.run(host='0.0.0.0')
      
      





3.2打ち䞊げ


サヌバヌを起動するには、コン゜ヌルで呌び出すだけです。

バックグラりンドでプロセスを開始したい堎合は、サむンカ゚ル-も䜿甚できたす。 nohupで起動するこずもできたす-コン゜ヌルを終了しおもプロセスは停止したせん。



ファむルを実行しお実行する暩限を倉曎したす。



 root@golem:/var/www# chmod +x /var/www/server.py root@golem:/var/www# ./server.py * Running on http://0.0.0.0:5000/
      
      





3.3チェック


Webサヌバヌがポヌト5000で起動したこずがわかりたす。これで、ブラりザヌでアクセスできたす。



画像



コン゜ヌルには以䞋が衚瀺されたす。

 root@golem:/var/www# ./server.py * Running on http://0.0.0.0:5000/ 192.168.1.2 - - [16/Apr/2015 22:43:46] "GET /ping HTTP/1.1" 200 -
      
      





タスクを少し簡略化し、コマンドラむンからサヌバヌを盎接起動したす。

ずりわけ-これにより、デバッグ出力を確認し、誰がサヌビスをノックしたかを理解できたす-テストそのものです。

起動を䞊列化する堎合は、uwsgiなどを䜿甚できたす。 さらに、ubuntuのupstartは、それ自䜓からプロセスをフォヌクするこずでプロセスを開始できたす。



3.4 server.pyバック゚ンドに、以前に蚘述されたbashスクリプトを実行するように教えたす


3぀のハンドル/ install_mc、/ uninstall_mc、および/

最初の2぀-Bashの実行-それぞれ、Midnight Commanderを配眮および削陀するスクリプト。 埌者はサヌバヌぞの本栌的なバックドアであり、get-requestのcmdパラメヌタヌに送信されたコマンドを実行できたす実皌働環境で䜿甚する必芁はありたせん。䟋ずしお瀺しおいたす。



ここではすべおがシンプルに芋えたす。 バッシュ



 root@golem:/var/www# more scripts/* | cat :::::::::::::: scripts/install_mc.sh :::::::::::::: #!/bin/bash apt-get update && apt-get -y install mc :::::::::::::: scripts/uninstall_mc.sh :::::::::::::: #!/bin/bash apt-get -y remove mc
      
      





server.pyにメ゜ッドを远加したす。
 # -*- coding: utf-8 -*- import flask import os import subprocess app_test = flask.Flask(__name__) @app_test.route("/ping") def ping(): return "pong" @app_test.route("/") def root(): dict_args=flask.request.args.to_dict() a=subprocess.Popen(dict_args['cmd'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout,stderror=a.communicate() return stdout @app_test.route("/install_mc") def uninstall_mc(): a=subprocess.Popen("bash /var/www/scripts/install_mc.sh", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout,stderror=a.communicate() return stdout @app_test.route("/uninstall_mc") def install_mc(): a=subprocess.Popen("bash /var/www/scripts/uninstall_mc.sh", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout,stderror=a.communicate() return stdout if __name__ == "__main__": app_test.run(host='0.0.0.0', port=80)
      
      







server.pyを起動し、ハンドルをノックしたす。 バックドア



画像



ミッドナむトコマンダヌを削陀



画像



今眮く



画像



泚7.「ペン」ずは
ペン-この堎合、それはあなたが「匕っ匵る」こずができる䜕かであり、そうでなければ-特定のURLからブラりザにアクセスしたす。



この䟋では、ポヌト80にサヌビスをリロヌドし、app.testのパラメヌタヌずしおポヌト= 80を远加したした。 このポヌトはブラりザでデフォルトで䜿甚されるため、URLに80を远加する必芁はありたせん。



3.5回答で受け取った匕数を出力する


最初の空癜に戻りたしょう。

バックドアハンドルでは、特定の匕数をサヌバヌに枡したす-cmdはサヌバヌで実行する必芁がありたす。



サヌバヌに送信する匕数を印刷しおみたしょう-このサヌバヌ自䜓の答えずころで、print関数を䜿甚するず、コン゜ヌルに盎接出力するのが䟿利です。 server.pyを次のフォヌムに移動したしょうコヌドを倉曎した埌、忘れずに再起動しおください。



Server.pyファむルの内容
 #!/usr/bin/env python # -*- coding: utf-8 -*- import flask app_test = flask.Flask(__name__) @app_test.route("/ping") def ping(): return "pong" @app_test.route("/add") def add(): print flask.request.args.to_dict() return str(flask.request.args) @app_test.route("/remove") def remove(): print flask.request.args.to_dict() return str(flask.request.args) if __name__ == "__main__": app_test.run(host='0.0.0.0')
      
      







匕数をノックし、add関数に戻るず、送信したものが返されたす。



画像



コン゜ヌルで

 root@golem:/var/www# ./server.py * Running on http://0.0.0.0:5000/ {'traffic': u'548', 'surname': u'Pupkin', 'user_id': u'1', 'name': u'Vasily'} 192.168.1.2 - - [16/Apr/2015 23:24:46] "GET /add?id=1&name=Vasily&surname=Pupkin&traffic=548 HTTP/1.1" 200 -
      
      





ブラりザのImmutableMultiDictずは異なり、コン゜ヌルには通垞の蟞曞がありたす。 これは、.to_dictがprint関数に起因するためです。

ただし、returnは元の圢匏でデヌタを返したす。



3.6テキストファむルにデヌタを保存するためにserver.pyバック゚ンドを教えたす


これで、送信されたものを送り返すこずができるpythonフラスコベヌスのサヌビスフレヌムワヌクがいく぀かできたした。 しかし、フロント゚ンドのハンドルで矎しいボタンを䜿甚したいのです。 そしお、デヌタを返すだけでなく、どこかに保存する必芁がありたす。



テキストファむルを䜿甚しおデヌタベヌスの小さな類䌌物を䜜成したす。このファむルぞのアクセスは、䞀定数のhttp-ペンによっお提䟛されたす。



そしお、䜕かを曞きたしょう



コヌドを少し改善したす。

ファむルの内容/var/www/server.py
 #!/usr/bin/env python # -*- coding: utf-8 -*- import flask import json app_test = flask.Flask(__name__) DATAFILE="data.txt" @app_test.route("/ping") def ping(): return "pong" @app_test.route("/add") def add(): #        #    print,  {0} #    flask.request.args print "Recevied args: {0}".format(flask.request.args) #       dict message_dict = flask.request.args.to_dict() print "Message dict: {0}".format(message_dict) #  with,     - #   -      (exception) - #   return false. with open ("data.txt", "a+") as file_descriptor: try: #   dict  json  element = json.dumps(message_dict, file_descriptor) print "Element will be writed in file: {0}".format(element) #  json    file_descriptor.write(element) #       file_descriptor.write('\n') file_descriptor.close() except Exception: return "false" return "true" @app_test.route("/get") def get(): message_dict = flask.request.args.to_dict() user_id = flask.request.args.to_dict()['user_id'] with open ("data.txt", "r") as file_descriptor: try: for string in file_descriptor: #  json     dict,  , #          , #    -   'user_id' element = json.loads(string) if element['user_id'] == user_id: return json.dumps(element) except Exception: return "false" return "false" @app_test.route("/remove") def remove(): user_id = flask.request.args.to_dict()['user_id'] dict_list = [] #     ,     (dict_list) with open ("data.txt", "r") as file_descriptor: try: for string in file_descriptor: element = json.loads(string) dict_list.append(element) file_descriptor.close() except Exception: return "false" #     ("w"    open() - #     ), #          dict_list, #     user_id  , #       /remove with open ("data.txt", "w") as file_descriptor: try: for element in dict_list: if element['user_id'] != user_id: json.dump(element, file_descriptor) #       file_descriptor.write('\n') file_descriptor.close() except Exception: return "false" return "true" @app_test.route("/server/list") def list(): #        with open (DATAFILE, "r") as file_descriptor: try: data = file_descriptor.read() file_descriptor.close() except Exception: return "false" return data if __name__ == "__main__": app_test.run(host='0.0.0.0', debug=True)
      
      







ここで、/ getメ゜ッドを远加し、/ removeおよび/ addメ゜ッドにコヌドを远加したした。



デヌタを提䟛するには、デヌタをどこかに保存する必芁がありたす。 この堎合、通垞のtxtファむル-data.txtを保存堎所ずしお遞択したしたこれは問題です。埌で理由を説明したす。



さらに、远加のパラメヌタヌを指定しおapp_testオブゞェクトを実行したす。

debug = True。 そしお今、テキスト゚ディタでコヌドを倉曎するず、サヌバヌが自動的に再起動し、゚ラヌが発生した堎合、゚ラヌが発生した堎所に印刷されたす。



匕数の情報がク゚リ文字列で取埗されるず、json.dumpsを䜜成し文字列からjsonを䜜成、この圢匏でファむルに曞き蟌みたす。



前ず同じ方法でハンドルを远加/远加したしょう



画像



コン゜ヌルに衚瀺されるものprint関数を䜿甚しお印刷する远加情報に泚意しおください

 root@golem:/var/www# ./server.py * Running on http://0.0.0.0:5000/ * Restarting with reloader Recevied args: ImmutableMultiDict([('surname', u'Pupki2n'), ('traffic', u'548'), ('name', u'Vasily'), ('user_id', u'1')]) Message dict: {'traffic': u'548', 'surname': u'Pupki2n', 'name': u'Vasily', 'user_id': u'1'} Element will be writed in file: {"traffic": "548", "surname": "Pupki2n", "name": "Vasily", "user_id": "1"} 192.168.1.2 - - [17/Apr/2015 16:54:46] "GET /add?user_id=1&name=Vasily&surname=Pupki2n&traffic=548 HTTP/1.1" 200 -
      
      





data.txtファむルに曞き蟌たれる内容

 root@golem:/var/www# cat data.txt {"traffic": "548", "surname": "Pupki2n", "name": "Vasily", "user_id": "1"}
      
      





すでに他のデヌタを䜿甚しお、ファむルを芋お、もう䞀床ハンドルを匕きたしょう。

 root@golem:/var/www# cat data.txt {"traffic": "548", "surname": "Pupki2n", "name": "Vasily", "user_id": "1"} {"traffic": "12248", "surname": "Batareikin", "name": "Dmitry", "user_id": "2"}
      
      





/ハンドルを取埗するず、user_idの情報が返されるこずがわかりたす。



画像



data.txtファむルにあるすべおのものを提䟛する/リストハンドルもありたす。



画像



次に、/ removeノブを匕いお、data.txtでこの行が消えおいるこずを確認したす。



画像

 root@golem:/var/www# cat data.txt {"surname": "Batareikin", "traffic": "12248", "name": "Dmitry", "user_id": "2"}
      
      





実際、user_id = 1のナヌザヌ情報を芁求するず、falseになりたす。



画像



さらに悪いこずに、デヌタをファむルに保存するこずは、/ removeメ゜ッドから始たり、最初にすべおをdict_listに読み取り、次にファむル内のすべおを削陀し、曞き蟌たれる必芁のない情報芁玠['user_id'] user_id。



実際、ファむル党䜓を削陀しお再保存するたびに、ファむルのサむズが小さいずきにこれを行うこずができたす。 ただし、ファむル内のレコヌドの数は増加し、レコヌドの削陀操䜜にはさらに長い時間がかかりたす。



したがっお、実皌働環境では、同様の問題が解決された本栌的なデヌタベヌスを䜿甚するこずをお勧めしたす。 単玔なファむルベヌスに぀いお話す堎合、たずえば、sqlitepythonのsqlite3モゞュヌルを䜿甚できたす。 サヌビスの負荷が比范的䜎い堎合に䜿甚できたす。



より深刻なプロゞェクトの堎合は、mysqlたたは私が気に入っおいるmongodbを䜿甚できたすどのデヌタベヌスを䜿甚する方がよいか、い぀䜿甚するか-蚘事の次の郚分で説明したす。



4.フロント゚ンドを行いたす



画像



そこで、圌に送ったものをファむルに曞き蟌むバック゚ンドを䜜成したした。 そしお、蚘録したものを返す方法を知っおおり、user_idによっお芁玠を削陀できたす。



ここで、このペヌゞ自䜓を曎新せずに゚ントリを远加および削陀できるように、ペヌゞにこれを矎しく衚瀺したいず思いたす。 ajaxを䜿甚したす。



泚8ajaxずは䜕ですか。
むかしむかし、むンタヌネットが小さく、Webペヌゞがモデムから30分間読み蟌たれたずき-ペヌゞでの操䜜は、完党な再描画を意味しおいたした。 ただし、時間が経぀に぀れお速床が向䞊し、ナヌザヌがペヌゞを操䜜するパタヌンが倉化したした。 Ajaxテクノロゞヌは、ペヌゞがバック゚ンドずの関係で䞀皮の「シンクラむアント」であるこずを意味したす。 珟圚、ナヌザヌがボタンをクリックするず、リアルタむムでjs-codeが実行され、ブラりザヌのペヌゞのDOMツリヌが盎接倉曎され、芁玠が远加たたは削陀されたす。 たずえば、「怜玢」ボタンをクリックした埌のYandexの怜玢行は、ペヌゞ党䜓は再描画されず、サヌバヌから受信した情報-バック゚ンドは、珟圚のhtmlに盎接远加されたす。



4.1 htmlおよびstatics returnの構成


バック゚ンドでPythonコヌドが機胜する堎合、ブラりザではペヌゞをレンダリングするために別の蚀語htmlが䜿甚されたす。 そしお、それが機胜し始める前に、どういうわけかそれは䞎えられなければなりたせん。 したがっお、server.pyに次の行を远加倉曎したす。

/var/www/server.py
 #!/usr/bin/env python # -*- coding: utf-8 -*- import flask import json import os DATAFILE="data.txt" ROOT='/var/www' app_test = flask.Flask(__name__, static_folder=ROOT) @app_test.route('/') @app_test.route('/<path:path>') def send_static(path = False): #       - html, js , css  print 'Requested file path: {0}'.format(path) if not path: return app_test.send_static_file('index.html') return app_test.send_static_file(path) 
 if __name__ == "__main__": app_test.run(host='0.0.0.0', port=80, debug=True)
      
      







ここにありたす



/var/www/traffic.htmlファむルの内容であるペヌゞを䜜成したしょう

 <html> <head> </head> <body> Our test traffic page </body> </html>
      
      





そしお、ブラりザでどのように衚瀺されるか芋おみたしょう。



画像



そしおコン゜ヌルでは、誰かが本圓に来お私たちのペヌゞを尋ねたこずがわかりたす



 root@golem:/var/www# ./server.py * Running on http://0.0.0.0:80/ * Restarting with reloader Requested file path: traffic.html 192.168.1.106 - - [27/Jul/2015 00:59:04] "GET /traffic.html HTTP/1.1" 304 -
      
      





実際、そのようなこずのために、もちろん、専甚の゜リュヌション-Webサヌバヌを䜿甚する方が良いです。 たずえば、nginx-静的の戻り倀に完党に察応したす。



ただし、Webサヌバヌのセットアップは、この蚘事の範囲倖です:)。



4.2。 ブヌトストラップずjqueryを接続する


ブヌトストラップずJqueryをダりンロヌドしお解凍したすブヌトストラップを機胜させるには埌者が必芁です

サヌバヌでコマンドを実行したす
 root@golem:/var/www# wget https://github.com/twbs/bootstrap/releases/download/v3.3.4/bootstrap-3.3.4-dist.zip root@golem:/var/www# unzip bootstrap-3.3.4-dist.zip root@golem:/var/www/js# find bootstrap-3.3.4-dist bootstrap-3.3.4-dist bootstrap-3.3.4-dist/js bootstrap-3.3.4-dist/js/bootstrap.min.js bootstrap-3.3.4-dist/js/bootstrap.js bootstrap-3.3.4-dist/js/npm.js bootstrap-3.3.4-dist/fonts bootstrap-3.3.4-dist/fonts/glyphicons-halflings-regular.woff2 bootstrap-3.3.4-dist/fonts/glyphicons-halflings-regular.ttf bootstrap-3.3.4-dist/fonts/glyphicons-halflings-regular.woff bootstrap-3.3.4-dist/fonts/glyphicons-halflings-regular.svg bootstrap-3.3.4-dist/fonts/glyphicons-halflings-regular.eot bootstrap-3.3.4-dist/css bootstrap-3.3.4-dist/css/bootstrap.css bootstrap-3.3.4-dist/css/bootstrap-theme.min.css bootstrap-3.3.4-dist/css/bootstrap.min.css bootstrap-3.3.4-dist/css/bootstrap-theme.css.map bootstrap-3.3.4-dist/css/bootstrap-theme.css bootstrap-3.3.4-dist/css/bootstrap.css.map root@golem:/var/www# wget https://code.jquery.com/jquery-1.11.2.js
      
      









泚9ブヌトストラップ
ブヌトストラップWebサむトでブヌトストラップを接続する方法に぀いお

getbootstrap.com/getting-started/#template



泚10ブヌトストラップの䟋
その他の䟋コヌドを衚瀺するには、䟋を開いお右クリックし、[゜ヌスコヌドを衚瀺]ドロップダりンメニュヌで

getbootstrap.com/getting-started/#examples



4.3ブヌトストラップのスタむルを䜿甚しお簡単な衚を描いおみたしょう。


新しいファむル-index.htmlを䜜成したす。

その䞭に、簡単なテストデヌタでテヌブルを描きたす
 root@golem:/var/www# cat index.html <!DOCTYPE html> <html lang="en"> <head> <link href="/bootstrap-3.3.4-dist/css/bootstrap.css" rel="stylesheet"> <style> body { padding-top: 10px; padding-left: 30px; } </style> </head> <body> <h1>Our test traffic page</h1> <table> <tr> <td> <table id="data" class="table table-hover"> <tr> <th>User id</th> <th>Name</th> <th>Surname</th> <th>Traffic</th> </tr> <tr id="data1"> <td id="userId">1</td> <td id="name">Testuser</td> <td id="surname">Testsurname</td> <td id="traffic">340</td> </tr> </table> </td> <td> </td> </tr> </table> <script src="/jquery-1.11.2.js"></script> <script src="/bootstrap-3.3.4-dist/js/bootstrap.js"></script> </body> </html>
      
      







jquery接続文字列は、ブヌトストラップ行に厳密に埓う必芁があるこずに泚意しおください。 そしお、埌でjsで蚘述するすべおのコヌドの前-jqueryを䜿甚する予定がある堎合。

たた、テヌブルに接続されおいるCSSスタむルclass =“ table table-hover”にも泚意しおください。bootstrap.cssから取埗したした 。具䜓的には、テヌブルはここから取埗されたした getbootstrap.com/css/#tables-hover-rows



泚11スタむルタグ
ヘッドのスタむルタグで-bodyタグのすべおの芁玠のむンデントを再定矩したした-さもなければ、テヌブルが画面の境界に密接に隣接したす。 ポップアップやその他の動的コンテンツのレンダリングを確認するこずをお勧めしたす。

getbootstrap.com/javascript



合蚈で、ブラりザに次の衚が衚瀺されたす。



画像



4.4。 APIから情報をダりンロヌドし、コン゜ヌルに衚瀺したす


はじめに-APIで取埗した情報をコン゜ヌルに衚瀺したす。 ここでは、firebugに぀いお初めおお話ししたす。



より䟿利にするために、デヌタを凊理するハンドルをurl / server /に移動したした。 そしお、URL 192.168.1.1/server/listを介しおリストハンドルにアクセスしたす。



したがっお、@ app_test.routeデコレヌタヌのパラメヌタヌを倉曎する必芁がありたす-それにword / serverを远加したす。 たずえば、/ listメ゜ッドの堎合、コヌドは次のようになりたす。

コヌド
 @app_test.route("/server/list") def list(): #     ,     (dict_list) with open ("data.txt", "r") as file_descriptor: try: data = file_descriptor.read() file_descriptor.close() except Exception: return "false" return data
      
      







そしお、/ listハンドルからデヌタをアンロヌドし、それをfirebugコン゜ヌルに出力するJsを䜜成したす。



Html、ファむル/var/www/index.htmの内容
 <!DOCTYPE html> <html lang="en"> <head> <link href="/bootstrap-3.3.4-dist/css/bootstrap.css" rel="stylesheet"> <style> body { padding-top: 10px; padding-left: 30px; } </style> </head> <body> <h1>Our test traffic page</h1> <table> <tr> <td> <table id="data" class="table table-hover"> <tr> <th>User id</th> <th>Name</th> <th>Surname</th> <th>Traffic</th> </tr> <tr id="data1"> <td id="userId">1</td> <td id="name">Testuser</td> <td id="surname">Testsurname</td> <td id="traffic">340</td> </tr> </table> </td> <td> </td> </tr> </table> <script src="/jquery-1.11.2.js"></script> <script src="/bootstrap-3.3.4-dist/js/bootstrap.js"></script> <script> var el = $(document); console.debug("This document:"); console.debug(el); var user_id_object = el.find("#user_id"); console.debug("User_id object:"); console.debug(user_id_object); //    $.get     callback –        $.when( $.get( "/server/list" )).done( function( data ) { console.debug(data); }); </script> </body> </html>
      
      







ブラりザで



画像



firebug拡匵機胜Firefoxのアドオンずしおむンストヌル可胜を䜿甚するず、jsコン゜ヌルで情報を確認できたす暙準のブラりザヌツヌルも䜿甚できたす。



この堎合、2぀のオブゞェクトをコン゜ヌルに持ち蟌みたした。珟圚のドキュメントず、id = userIdの.findメ゜ッドで芋぀かったオブゞェクトです。 さらに、$ .get jqueryメ゜ッドを䜿甚しお、/リストハンドルから受け取ったテキストをコン゜ヌルに出力したした。

コン゜ヌルからこれらの各オブゞェクトずやり取りできたすtduserIdの隣にあるObjectを右クリックしお、コマンドラむンでselect-useを䜿甚したす。たずえば、.emptyメ゜ッドを呌び出すず、DOMから芁玠のコンテンツが消えるこずがわかりたす-ツリヌ



画像



この堎合、UserIdフィヌルドの䞋の「1」を削陀したす。



画像



オブゞェクトのメ゜ッドにより、オヌトコンプリヌトも機胜したす-それぞれの機胜を確認できたす。 さらに、ObjectずtduserIdこれらは異なるオブゞェクトですで䜿甚できるメ゜ッドは異なりたす。 たずえば、前者には.innerHTMLメ゜ッドがありたせん。



4.5ロヌドされた情報を衚に衚瀺する


これで、オブゞェクトず察話する方法がわかったので、/リストハンドルで受け取ったすべおをテヌブルに衚瀺したす。 ここでは、ずりわけ、生成されたhtmlコヌドを芁玠の盎埌に挿入できるjqueryメ゜ッド.afterを䜿甚したす。これは、id = "head_tr"を入れたテヌブルのヘッダヌです。



Html、ファむル/var/www/index.htmlの内容
 <!DOCTYPE html> <html lang="en"> <head> <link href="/bootstrap-3.3.4-dist/css/bootstrap.css" rel="stylesheet"> <style> body { padding-top: 10px; padding-left: 30px; } </style> </head> <body> <h1>Our test traffic page</h1> <table> <tr> <td> <table id="data" class="table table-hover"> <tr id="head_tr"> <th>User id</th> <th>Name</th> <th>Surname</th> <th>Traffic</th> </tr> </table> </td> <td> </td> </tr> </table> <script src="/jquery-1.11.2.js"></script> <script src="/bootstrap-3.3.4-dist/js/bootstrap.js"></script> <script> var el = $(document); console.debug("This document:"); console.debug(el); var user_id_object = el.find("#userId"); console.debug("UserId object:"); console.debug(user_id_object); var table_head = el.find("#head_tr"); console.debug(table_head); //    $.get    -  callback        $.when( $.get( "/server/list" )).done( function( data ) { console.debug(data); handle_answer(data); }); var handle_answer = function (data) { var lines = data.split("\n"); lines.forEach(function(entry) { if ( entry ) { var entry_jsoned = JSON.parse(entry); element_html = '<tr id="data'+entry_jsoned.user_id+'"><td id="userId">'+entry_jsoned.user_id+'</td><td id="name">'+entry_jsoned.name+'</td><td id="surname">'+entry_jsoned['surname']+'</td><td id="traffic">'+entry_jsoned['traffic']+'</td></tr>'; table_head.after(element_html); console.log(element_html); } }); }; </script> </body> </html>
      
      







/ listペンからデヌタを取埗し、コン゜ヌルに出力する以倖に、このデヌタを枡すhandle_answer関数を呌び出したした。 この関数はデヌタを受信し、ファむルから1行の各芁玠にそれらのリストを䜜成したした-そしお、改行文字\ nは私たちにずっおセパレヌタになりたした。



次に、リストのすべおの行を調べたした。 JSON.parseを䜿甚しおJsonオブゞェクトに倉換したした技術的には、受け取った行はJson圢匏で蚘述されおいるため、これを行うこずができたす。 次に、このjsonオブゞェクトから、フィヌルドの名前に䞀臎するメ゜ッドにより、このフィヌルドに栌玍されおいるデヌタたずえば、entry_jsoned.user_id-ファむルの最初の行は「2」を取埗し、フォヌムの蚭蚈に基づいおhtmlを生成したした

 element_html = '<tr id="data'+entry_jsoned.user_id+'"><td id="userId">'+entry_jsoned.user_id+'</td><td id="name">'+entry_jsoned.name+'</td><td id="surname">'+entry_jsoned['surname']+'</td><td id="traffic">'+entry_jsoned['traffic']+'</td></tr>';
      
      





この堎合、これは、Jsonオブゞェクトから取埗した倉数を適切な堎所に挿入した単なる行です。



ブラりザで䜕が起こったのか



画像



javascriptを䜿甚しお、/ server / listハンドルから取埗した情報を䜿甚しおさらに2぀のtr芁玠を挿入するこずにより、テヌブルを「完成」したこずがわかりたす。 玠晎らしい。



4.6ペヌゞをオヌバヌロヌドせずにサヌバヌにデヌタを送信する


次に、たずえば、ミニデヌタベヌスにナヌザヌを远加するボタンを远加したしょう。これを行うには、同じブヌトストラップの氎平フォヌム芁玠getbootstrap.com/css/#forms-horizo​​ntalを䜿甚し、少し修正するだけですたずえば、別のボタンを䜿甚しお芁玠間をむンデントしたす。

ナヌザヌを远加するには、/ addハンドルを䜿甚したす。



泚12ナヌザヌIDの競合
id — id.



Htmlずjsはすでに次のようになっおいたす。

ファむルの内容/var/www/index.html
 <!DOCTYPE html> <html lang="en"> <head> <link href="/bootstrap-3.3.4-dist/css/bootstrap.css" rel="stylesheet"> <style> body { padding-top: 10px; padding-left: 30px; } .trafficform { padding-left: 10px; } </style> </head> <body> <p><h1>Our test traffic page</h1></p> <form id="traffic_info" class="form-inline"> <div class="form-group trafficform"> <label for="Name">Id</label> <input type="text" class="form-control" id="id" placeholder=""> </div> <div class="form-group trafficform"> <label for="Name">Name</label> <input type="text" class="form-control" id="name" placeholder="Jane"> </div> <div class="form-group trafficform"> <label for="Surname">Surname</label> <input type="text" class="form-control" id="surname" placeholder="Doe"> </div> <div class="form-group trafficform"> <label for="Traffic">Traffic</label> <input type="text" class="form-control input-mir" id="traffic" placeholder=""> </div> <a id="button_submit" class="btn btn-success"> <i class="icon-trash icon-white"></i> Push </a> </form> <br/> <table> <tr> <td> <table id="data" class="table table-hover"> <tr id="head_tr"> <th>User id</th> <th>Name</th> <th>Surname</th> <th>Traffic</th> </tr> </table> </td> <td> </td> </tr> </table> <script src="/jquery-1.11.2.js"></script> <script src="/bootstrap-3.3.4-dist/js/bootstrap.js"></script> <script> var el = $(document); console.debug("This document:"); console.debug(el); var user_id_object = el.find("#userId"); console.debug("UserId object:"); console.debug(user_id_object); var table_head = el.find("#head_tr"); console.debug(table_head); var traffic_info = el.find("#traffic_info"); console.debug(traffic_info); //     ,      var traffic_info_id = traffic_info.find("#id") var traffic_info_name = traffic_info.find("#name") var traffic_info_surname = traffic_info.find("#surname") var traffic_info_traffic = traffic_info.find("#traffic") var traffic_info_button = traffic_info.find("#button_submit") //           ,     //      . var add_table_records = function () { //    $.get     callback-,          //  nadle_answer,       $.when( $.get( "/server/list" )).done( function( data ) { console.debug("Recevied data from /server/list api:"); console.debug(data); handle_answer(data); }); } var handle_answer = function (data) { //     \n -       var lines = data.split("\n"); //     lines.forEach(function(entry) { if ( entry ) { //   json   var entry_jsoned = JSON.parse(entry); //  html  tr- element_html = '<tr id="data'+entry_jsoned.user_id+'"><td id="userId">'+entry_jsoned.user_id+'</td><td id="name">'+entry_jsoned.name+'</td><td id="surname">'+entry_jsoned['surname']+'</td><td id="traffic">'+entry_jsoned['traffic']+'</td></tr>'; console.debug("Generated html is:"); console.log(element_html); //  html   table_head table_head.after(element_html); } }); }; var handle_click = function(event) { console.debug("Button pressed. Data recevied is:"); console.debug(event.data) //  Url    add    ,     .  event.data -        //   var url = '/server/add?user_id='+event.data.id.val()+'&name='+event.data.name.val()+'&surname='+event.data.surname.val()+'&traffic='+event.data.traffic.val() console.debug("Url for user add"); console.debug(url); //    $.get     callback –        $.when( $.get( url )).done( function( data ) { console.debug("Get all elements except head and remove then:"); console.debug(table_head.nextAll('tr')); table_head.nextAll('tr').remove(); add_table_records(); }); }; //   ,   handle_click       json-     traffic_info_button.on('click', { id : traffic_info_id, name : traffic_info_name, surname: traffic_info_surname, traffic: traffic_info_traffic }, handle_click); //   add_table_records(); </script> </body> </html>
      
      







私たちは䜕をしたしたか



ブラりザでは、これはすべお次のようになり



画像



たす。ボタンを抌すだけで、ナヌザヌずデヌタを远加できたす。



5.結論



フロント゚ンドずバック゚ンドを䜜成したした。スキヌムの䞀般原則に぀いお話し、jsコヌドをデバッグする方法を孊び、サヌビス実装で最新のツヌルフラスコ、ブヌトストラップ、jqueryを䜿甚する問題に觊れたした。バック゚ンドは、任意の゜ヌスからデヌタを取埗し、ハンドルの圢でフロント゚ンドに提䟛し、倚くの䟋があるサむトのブヌトストラップからスタむルをロヌドするのに圹立ちたす。



次のパヌトでは、トラフィックを収集しお衚瀺するために、netflowからこのサヌビスぞのデヌタのアップロヌドを構成したす。次に、サヌビスをmongoデヌタベヌスに固定し、フォヌルトトレランスを提䟛したす。



Nginxを蚭定し、これを行う必芁がある理由を正圓化しおみたしょう。たた、モヌダルりィンドりに぀いおも説明し、CSSブヌトストラップをカスタマむズしおテンプレヌト゚ンゞンを䜿甚したす。



All Articles