てくなべ (tekunabe)

ansible / network automation / 学習メモ

Juniper 機器が検証できるリモートラボサービス「Juniper vLabs」の利用方法

■ はじめに: Juniper vLabs とは

Juniper vLabs とは、Juniper の仮想ネットワーク機器を検証用途でリモートから利用できる、無料のラボサービス(現在BETA版)です。非常にありがたいサービスです。

[2019/07/08 追記] Beta という表記がなくなったようです。

用意されたトポロジの中から、利用したトポロジを予約すると自分用に割り当てらます。割り当てられると、各機器にコンソールに入って操作できます。各機器にはグローバル IP アドレスが割り振られるため、手元の PC の SSH クライアントからも接続できます。

f:id:akira6592:20190101205402p:plain:w400
Juniper vLabsトポロジ表示画面

類似のサービスとしては、Cisco DevNet の Sandbox があります(参考: 日本語ブログ)。

この記事では、Juniper vLabs で利用できるトポロジや、各機器へのログイン(ブラウザ・SSH クライアント)までの簡単な利用手順をご紹介します。

(補足) 公式ドキュメント

英語ですが、公式ドキュメントに手順などがしっかり掲載されています。

動画

※ 本記事執筆時点では BETA サービスのため、大きな仕様変更などがされる場合があります。




■ 利用できるトポロジ

Juniper vLabs では、現在、以下のトポロジを利用できます。1台だけのトポロジもあれば、複数台組み上がったトポロジもあります。

Standalone

  • Standalone vMX
  • Standalone vSRX
  • Standalone vQFX Light
  • Standalone vRR

Routing

  • OSPF - Single-area
  • OSPF - Multi-area
  • IS-IS - Single-area
  • IS-IS - Multi-level/area
  • BGP - Multi-AS
  • BGP - Multi-AS with Route Reflection

Security

Automation

  • JET for Junos - Automation and Programmability Network Management, Telemetry, and Analytics

Network Management, Telemetry, and Analytics

  • Contrail HealthBot




■ 利用手順

Juniper vLabs サービスへのログイン

https://jlabs.juniper.net/vlabs/ から Juniper User ID でログインします。 アカウントがない場合は、このページを参照してください。


トポロジの選択・予約

ログインするとトポロジ一覧が表示されます。利用したトポロジの画像、または Launch をクリックします。 ここでは例として、OSPF - Single-area をクリックします。

トポロジ図のページが表示されます。この状態ではまだ予約されていません。

f:id:akira6592:20190101205402p:plain:w400
Juniper vLabsトポロジ表示画面

予約するために、ページ右上の Reverve ボタンをクリックします。

f:id:akira6592:20190101205643p:plain
RESERVE ボタンで予約開始
予約処理が開始されると Your Juniper vLab "OSPF - Single area" is being created のようなタイトルのメールが届きます。

スケジュールなどの項目を必要に応じて変更し、Reserve ボタンをクリックします。

f:id:akira6592:20190101205901p:plain
予約の詳細指定画面

予約処理中は、トポロジ画面右上が以下のような表示になります。予約処理完了までの残り時間目安が分かります。

f:id:akira6592:20190101205924p:plain
予約処理実行中
予約処理が完了すると以下のような表示になります。

f:id:akira6592:20190101205953p:plain
予約処理完了(利用可能状態)

同時に Your Juniper vLab "OSPF - Single area" is now available のようなタイトルの予約完了メールが届きます。本文には各機器へログインするユーザー名とパスワードが記載されています。

機器へのログイン

機器へログインする方法は、ブラウザ、SSHクライアントの2通りあります。

ブラウザでログイン

ログインしたい機器のアイコンにカーソルを近づけたときに表示される をクリックして SSH を選択します。

f:id:akira6592:20190101210125p:plain
ブラウザでログイン

別タブでブラウザ用のコンソール画面が jcluser ユーザーでログインされた状態で開きます。

f:id:akira6592:20190101210159p:plain
ブラウザでログインした状態

SSH クライアントでログイン

準備: 許可アクセス元 IP アドレスの設定

デフォルトでは外部からのアクセスは許可されていません。 そのため、手元の SSH クライアントでログインするには、まず許可アクセス元 IP アドレスの設定をする必要があります。

トポロジ画面上部の COMMANDS ボタンをクリックします。

f:id:akira6592:20190101210304p:plain:w300
COMMANDS ボタン

トポロジ画面右の Add Allowed Network Prefixes> ボタンをクリックします。

f:id:akira6592:20190101210413p:plain
許可アクセス元IPアドレスの設定 その1

つづいて、画面右側に表示される xxx で 許可したい IP アドレス(プレフィックス指定も可)を入力して、Runボタンをクリックします。

f:id:akira6592:20190101210512p:plain
許可アクセス元IPアドレスの設定 その2

なお、外部から見たときの、手元の PC のグローバル IP アドレスは ipconfig.io などで調べられます。

許可アクセス元 IP アドレスの設定が Running 状態を経て完了すると、以下のようにCompleted になります。

f:id:akira6592:20190101210634p:plain
完了

これで、手元の SSH クライアントでログインする準備ができました。

アクセス先 IP アドレス・ポートの確認とログイン

アクセス先 IP アドレス・ポート

アクセスしたい機器のアイコン付近の緑色の マークにカーソルを乗せると、SSH でアクセスするためのグローバル IP アドレスとポートが表示されます。(NETCONFなどのほかの方法の情報も表示されます。)

ユーザー名とパスワード

デフォルトで設定されているユーザー名とパスワードは、トポロジ予約処理完了時に送られる Your Juniper vLab "OSPF - Single area" is now available のようなタイトルののメール内に記載されています。

これらの情報を元にして、SSH クライアントでログインします。

終了

予約の時間がすぎると自動で環境が終了(シャットダウン)しますが、明示的に終了させることもできます。

f:id:akira6592:20190101211628p:plain
終了



■ まとめ

Juniper vLabs で利用できるトポロジや、各機器へのログイン(ブラウザ・SSH クライアント)までの簡単な利用手順をご紹介しました。

ネットワーク作業の自動化の検証をしたいときに、ネックになりやすいのがネットワーク機器の準備です。今回ご紹介した、Juniper vLabs や、Cisco DevNet の Sandboxなどのサービスでは、気軽に仮想ネットワーク機器の環境を用意できるので、活用できるのではないでしょうか。

netmiko と TextFSM を利用してネットワーク機器の show コマンド結果をパースする

■ はじめに

ネットワーク自動化 Python ライブラリ netmiko では、状態表示のための show コマンドや、設定変更のコマンドを実行できます。

TextFSM というパーサーと連携して、 show コマンド結果を パース して扱う事ができます。

f:id:akira6592:20181231134801p:plain:w500
パースされた Junos の show version 結果例

TextFSM では、特定の show コマンドに対して専用のテンプレート(正規表現によるパターン化)を用意して、パースさせます。 テンプレートは自作することもできますが、ntc-templates にあるものを利用するのが便利です。

Juniper Junos、Arista EOS、Cisco IOS/IOS-XR/NX OS などの代表的なコマンドに対応するテンプレートが、現在 250 以上あります。

もし、機器側が NETCONF や REST API に対応していれば、その方法でパースされた情報を取得するほうがスマートでしょうが、対応していないケースも多いと思います。

この記事では、ntc-templates に最近追加された Juniper の show vesrion コマンドに対応するものを利用して、このコマンド結果をパースしてみます。

参考

kooshin.hateblo.jp

想定環境

■ 環境の準備

  • netmiko のインストール
$ pip install netmiko
  • ntc-templates の TextFSM テンプレートをダウンロード
$ cd ~
$ git clone https://github.com/networktocode/ntc-templates.git

このパスにしておくことで、netmiko が自動的に TextFSM テンプレートを探しに行ってくれます。

■ Junos の show version をパースするサンプル

  • junos_version.py
from netmiko import Netmiko
import pprint

junos = {
    "host": "172.16.0.1",
    "username": "testuser",
    "password": "testpass9999",
    "device_type": "juniper_junos",
    "port": 38005   # デフォルトは 22
}

net_connect = Netmiko(**junos)  # 接続

output = net_connect.send_command("show version", use_textfsm=True) # TextFSMを利用するオプションを True に指定

pprint.pprint(output)  # 表示

net_connect.disconnect()  # 切断
  • 実行結果

以下のように、パースされ、key/value 形式になっていることが確認できます。

$ python junos_version.py
[{'appid_services': '20180316.180938_builder_junos_174_r1_s2',
  'base_os_boot': '',
  'base_os_software_suite': '',
  'border_gateway_function_package': '',
  'crypto_software_suite': '',
  'hostname': 'vMX1',
  'idp_services': '20180316.180938_builder_junos_174_r1_s2',
  'junos_version': '17.4R1-S2.2',
  'kernel_software_suite': '',
  'lab_package': '',
  'model': 'vmx',
  'online_documentation': '20180316.180938_builder_junos_174_r1_s2',
  'other_device_properties': ['OS Kernel 64-bit  ',
                              'OS libs ',
                              'OS runtime ',
                              'OS time zone information ',
                              'network stack and utilities ',
                              'libs ',
                              'OS libs compat32 ',
                              'OS 32-bit compatibility ',
                              'libs compat32 ',
                              'runtime ',
                              'Packet Forwarding Engine Simulation Package ',
                              'py extensions ',
                              'py base ',
                              'OS vmguest ',
                              'OS crypto ',
                              'mx libs compat32 ',
                              'mx runtime ',
                              'common platform support ',
                              'mtx network modules ',
                              'modules ',
                              'mx modules ',
                              'mx libs ',
                              'mtx Data Plane Crypto Support ',
                              'daemons ',
                              'mx daemons ',
                              'Services URL Filter package ',
                              'Services TLB Service PIC package ',
                              'Services SOFTWIRE ',
                              'Services PCEF package ',
                              'Services Logging Report Framework package ',
                              'Services Deep Packet Inspection package ',
                              'Services IDS ',
                              'Services COS ',
                              'Extension Toolkit ',
                              'jfirmware ',
                              'jail runtime '],
  'other_properties_versions': ['20180127.fdc8dfc_builder_stable_11',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180127.fdc8dfc_builder_stable_11',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180316.180938_builder_junos_174_r1_s2',
                                '20180127.fdc8dfc_builder_stable_11'],
  'packet_forwarding_engine_support_m_t_ex_common': '',
  'packet_forwarding_engine_support_mx_common': '',
  'platform_software_suite': '',
  'py_base_i386': '',
  'qfabric_system_id': '',
  'routing_software_suite': '',
  'runtime_software_suite': '',
  'serial_number': '',
  'services_aacl_container_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_application_level_gateways': '20180316.180938_builder_junos_174_r1_s2',
  'services_captive_portal_content_delivery_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_crypto': '20180316.180938_builder_junos_174_r1_s2',
  'services_http_content_management_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_ipsec': '20180316.180938_builder_junos_174_r1_s2',
  'services_jflow_container_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_ll_pdf_container_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_mobile_subscriber_service_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_mobilenext_software_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_nat': '20180316.180938_builder_junos_174_r1_s2',
  'services_ptsp_container_package': '20180316.180938_builder_junos_174_r1_s2',
  'services_rpm': '20180316.180938_builder_junos_174_r1_s2',
  'services_ssl': '20180316.180938_builder_junos_174_r1_s2',
  'services_stateful_firewall': '20180316.180938_builder_junos_174_r1_s2',
  'voice_services_container_package': ''}]

補足

なお、以下のように TextFSM を利用しないように指定することもできます。

output = net_connect.send_command("show version", use_textfsm=False)

実行結果は、普通にターミナルでコマンドを実行したときと同じような形式になります。(key/valueにはならない)

パースしない実行結果(クリックして表示)

$ python junos_version.py
('\n'
 'Hostname: vMX1\n'
 'Model: vmx\n'
 'Junos: 17.4R1-S2.2\n'
 'JUNOS OS Kernel 64-bit  [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS OS libs [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS OS runtime [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS OS time zone information [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS network stack and utilities [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS libs [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS OS libs compat32 [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS OS 32-bit compatibility [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS libs compat32 [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS runtime [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Packet Forwarding Engine Simulation Package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS py extensions [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS py base [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS OS vmguest [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS OS crypto [20180127.fdc8dfc_builder_stable_11]\n'
 'JUNOS mx libs compat32 [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS mx runtime [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS common platform support [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS mtx network modules [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS modules [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS mx modules [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS mx libs [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS mtx Data Plane Crypto Support '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS daemons [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS mx daemons [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services URL Filter package [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services TLB Service PIC package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services SSL [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services SOFTWIRE [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Stateful Firewall [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services RPM [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services PTSP Container package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services PCEF package [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services NAT [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Mobile Subscriber Service Container package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services MobileNext Software package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Logging Report Framework package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services LL-PDF Container package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Jflow Container package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Deep Packet Inspection package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services IPSec [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services IDS [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS IDP Services [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services HTTP Content Management package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Crypto [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Captive Portal and Content Delivery Container package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services COS [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS AppId Services [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services Application Level Gateways '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Services AACL Container package '
 '[20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Extension Toolkit [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS jfirmware [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS Online Documentation [20180316.180938_builder_junos_174_r1_s2]\n'
 'JUNOS jail runtime [20180127.fdc8dfc_builder_stable_11]\n')


■ まとめ

ネットワーク自動化 Python ライブラリ netmiko と TextFSM を利用して、Junos の show version コマンドの結果をパースしてみました。

[ntc-templates には他にも250以上のテンプレート]https://github.com/networktocode/ntc-templates/tree/master/templatesがありますので、利用したいものがあるか探しててはいかがでしょうか。

github.com

GitHub 対応オンライン IDE「GitPod」の Docker 環境をカスタマイズする

■ GitPod とは

GitPod は GitHubリポジトリを扱えるブラウザIDEです。わざわざ手元に git clone するほどでもないけれど、GitHub 標準のエディタでは寂しい時ときに便利です。無料プランで毎月100時間利用できます。

www.gitpod.io

www.ksakae1216.com

GitPod では、Docker コンテナで動作するターミナル(ワークスペース)も利用できます。 デフォルトのイメージをそのまま利用するだけでなく、起動時に任意のコマンドを実行したり、別のイメージを指定するなどしてカスタマイズもできます。

この記事ではこれらのカスタマイズ方法についてかんたんに説明します。

■ 設定ファイルは .gitpod.yml

GitPod で起動するコンテナに対する設定は、リポジトリトップに .gitpod.yml というファイルを配置して行います。

起動時にコマンドを実行する

.gitpod.yml に以下のような指定をすると、起動時に任意をコマンドを実行できます。ここでは、pip install ansible を実行する指定をしています。

tasks:
  - command: "pip install ansible"

f:id:akira6592:20181230115456p:plain
指定したコマンドがターミナル起動時に自動実行される

command 以外にも initbefore でもコマンドが実行できるようです。詳細は以下の公式ドキュメントを参照してください。

Start Tasks - Gitpod Documentation

別のイメージを指定する

.gitpod.yml に以下のような指定をすると、別のコンテナイメージを利用できます。ここでは、python:3.7 を指定しています。

image: python:3.7

f:id:akira6592:20181230115525p:plain
指定したイメージのコンテナが起動した
(補足)現在、デフォルトのイメージでは Python 3.6.6 です。

詳細 Docker Image - Gitpod Documentation

gp init コマンドで .gitpod.yml を作成する

ターミナル内で gp init というコマンドで対話的に項目に答えていくと、.gitpod.yml を作成できます。

f:id:akira6592:20181230114900p:plain
gp init コマンド

f:id:akira6592:20181230114924p:plain
各項目に答えていく

■ おわりに

今回ご紹介したカスタマイズ方法の他にも、Dockerfile を指定したりportを exposeしたりもできます。

詳細は、GitPod公式ドキュメントの Configuring Workspaces を参照して下さい。

[Python] venv で作成した仮想環境を --clear オプションで初期状態にクリアする

--clear オプションでクリア

venv には、作成した仮想環境を初期状態にクリアする--clearオプションがあります。

  • python -m venv --help によるヘルプ表示抜粋
  --clear               Delete the contents of the environment directory if it
                        already exists, before environment creation.

activate している状態であれば、いったん deactivate したうえで、以下のように実行します。

python -m venv --clear 対象の仮想環境ディレクトリ

pythonpython3 など、各環境に読み替えてください。


お試し

新しく仮想環境を作成し、パッケージをインストールし、クリアしたらそのパッケージがないことを確認します。 Python 3.7.1 で試しています。

$ python3 -m venv testenv             # 仮想環境 testenv の作成
$ source testenv/bin/activate         # 仮想環境 testenv の有効化
(testenv) $ pip install netmiko       # パッケージ(ここでは netmiko)のインストール
Collecting netmiko
  Using cached https://files.pythonhosted.org/packages/83/a7/2d77f332ecf44909e70002cb20dbabfe8bd7bb1c552b67a2a75349fe1598/netmiko-2.3.0.tar.gz
(...略...)
(testenv) $ pip list | grep netmiko   # あることを確認
netmiko      2.3.0                    # ある
(...略...)
(testenv) $ deactivate                # いったん仮想環境を抜ける
$ python3 -m venv --clear testenv     # --clear で初期状態にクリア
$ source testenv/bin/activate         # 再度、仮想環境 testenv の有効化
(testenv) $ pip list | grep netmiko   # ないことを確認
(testenv) $                           # ない


参考

venv --- 仮想環境の作成

いままで、初期状態にクリアするときはディレクトリを一旦削除して同じ名前の仮想環境を作り直していたのですが、以下の本の「Chapter 03 Python プロジェクトの構成とパッケージ作成」で、venv の --clear オプションで一発で初期化できることを知りました。

Pythonプロフェッショナルプログラミング 第3版

Pythonプロフェッショナルプログラミング 第3版

[Azure] Azure Functions 2.0 の Function を VS Code でローカルデバッグしてから Azure へ発行する

■ はじめに

Azure Functions は、Azure のサーバーレスサービスです。2018年9月に Azure Functions 2.0 が一般提供 (GA)されました。

azure.microsoft.com

C#JavaScriptPython(プレビュー)などの言語に対応していて、ローカルでのデバッグも可能です。 VS CodeAzure Fucntions 拡張を利用すると、ローカルのデバッグから Azure への発行までの一連の作業を VS Code 内で完結できます。

この記事では、VS Code で HTTP トリガーで起動する Function を C# で作成、ローカルでデバッグし、Azure への発行まで試したことをまとめます。

基本的には「Visual Studio Code を使用した初めての関数の作成」の流れに沿っています。

環境


■ Azure Functions 拡張機能のインストール

Azure Fucntions 拡張をインストールします。

f:id:akira6592:20181229131212p:plain
Azure Functions 拡張のインストール

このとき、VS Code から Azure へのログインをサポートする拡張 Azure Accountも同時にインストールされます。

インストールした拡張を反映させるため、VS Code を再起動します。

アクティビティーバー(左のバー)に、Azure のアイコンが表れます。

f:id:akira6592:20181229131331p:plain
アクティビティバーに Azure アイコンが表示される


■ ローカルでの Function の作成とデバッグ

ローカルでの Function の作成とデバッグまでの流れです。

Azure Functions プロジェクトの作成

Azure プロジェクト作成ボタンをクリックします。

f:id:akira6592:20181229131609p:plain
プロジェクト作成ボタン

プロジェクトディレクトリを選択します。ここでは空のディレクトリを用意して選択します。

f:id:akira6592:20181229131726p:plain
プロジェクトを選択

言語は C# を選択します。

f:id:akira6592:20181229131821p:plain
C# を選択

いくつかのファイルが生成されます。

f:id:akira6592:20181229132014p:plain
生成されるファイル

Function の作成

Function 作成ボタンをクリックします。

f:id:akira6592:20181229140158p:plain
Function の新規作成"

プロジェクトディレクトリを選択します。

f:id:akira6592:20181229132149p:plain
プロジェクトディレクトリの選択

HTTPTrigger を選択します。

f:id:akira6592:20181229132316p:plain
HttpTrigger を選択

Function 名と namespace はここではデフォルトのままにしまま、アクセス権は Anonymous を選択します。

f:id:akira6592:20181229132435p:plain
Function 名指定

f:id:akira6592:20181229132533p:plain
namespace の指定

f:id:akira6592:20181229140303p:plain
アクセス権の指定

このような C# のプログラムテンプレートが作成されます。

f:id:akira6592:20181229132610p:plain
生成されたテンプレートコード


ローカルデバッグ

Azure 上で実行する前に、ローカルで実行、デバッグしてみます。

そのまま実行

F5 キーでデバッグを開始します。

しばらくすると、統合ターミナルに HTTP トリガーとなるローカルの URL が表示されます。

f:id:akira6592:20181229132751p:plain
Function URL の表示

ひとまず、そのまま開いてみます。このようなメッセージになります。

f:id:akira6592:20181229132903p:plain
クエリストリングなしの場合

メッセージやコードを見れ分かるのではが、 name というクエリストリング が必要のようなので

http://localhost:7071/api/HttpTriggerCSharp?name=kingyo

で開き直します。

今度は正常なメッセージが表示されます。

f:id:akira6592:20181229135036p:plain
クエリストリングありの場合

ここまでで、ごく基本的なローカルでの Function 実行を確認できました。

ブレークポイントの設定と変数の書き換え

せっかく VS Code を利用しているので、今度はブレークポイントの設定や変数の書き換えを試してみます。

先程の実行状態まま、以下の行にブレークポイントを設定します。

string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

f:id:akira6592:20181229133154p:plain
ブレークポイントの設定

先程 http://localhost:7071/api/HttpTriggerCSharp?name=kingyo を開いたブラウザ画面をリロードします。

ブレークポイントを設定した箇所で処理が一時停止しています。ブラウザのほうは、読み込み中のままになります。

f:id:akira6592:20181229133242p:plain
ブレークポイントで一時停止中

VS Codeデバッグペインの変数を確認する クエリストリングで指定した name の値が、コード内の namekingyo という値で入っていることが確認できます。

f:id:akira6592:20181229133403p:plain
変数 name の確認

ここでは、この変数 name の値を kingyo!!!に書き換えてみます。

f:id:akira6592:20181229133425p:plain
変数 name の値の変更

F5 キーか、以下のボタンで処理を続けます。

f:id:akira6592:20181229133508p:plain
処理の続行

ブラウザの読み込みが完了し、Hello, Kingyo!!! と表示されます。VS Code で書き換えた値が反映されていることが確認できます。

f:id:akira6592:20181229133533p:plain
変数書き換え後の表示

以下のアイコンで切断します。

f:id:akira6592:20181229133618p:plain
切断

ここまでで、VS Code によるローカルでの Function のデバッグを確認できました。

■ Azure への発行

いままではローカルでの実行でした。今度は、Azure へ発行してみます。

Azure へのログイン、発行方法はVisual Studio Code を使用した初めての関数の作成」の「Azure へのサインイン」から「Azure にプロジェクトを発行する」までの手順のとおりです。

発行が完了すると、以下のように右下に各種完了メッセージが表示されます。

f:id:akira6592:20181229134008p:plain
Function URL の表示

View Output をクリックすると「出力」画面に切り替わり、HTTP Trigger の URL が表示されています。

f:id:akira6592:20181229134146p:plain
発行の完了

このURL に、ローカルで実行したときと同じようにクエリストリング ?name=kingyoを末尾に付けて、ブラウザで開きます。

f:id:akira6592:20181229134308p:plain
Azure に発行した Function の実行

無事に、Azure に発行した Function も実行できました。


■ まとめ

VS Code を利用して、Azure Functions のローカルでデバックと Azure への発行の流れを簡単に確認できました。 使い慣れているエディタを利用できる点と、発行までできる点は便利だと思いました。

[VS Code] デフォルトで読み込む venv/virtualenv 環境のパス

■ はじめに

VisualStudio Code (以下、VS Code)は Python の仮想環境 venv/vitualenv にも対応しています。特に設定で指定しなくても特定のディレクトリ配下の仮想環境を読み込みます。この記事ではそのパスの確認をします。

環境


デフォルトで読み込まれるパス

以下の 4 箇所です。

参考

デフォルト設定

 // Folders in your home directory to look into for virtual environments.
  "python.venvFolders": [
    "envs",
    ".pyenv",
    ".direnv"
  ]

Where the extension looks for environments

Virtual environments located directly under the workspace (project) folder.

お試し

実際に読み込まれることを試してみます。

仮想環境の作成

まず、対応する 4つの仮想環境をを作ります。

$ python3 -m venv ~/envs/envs01
$ python3 -m venv ~/.pyenv/pyenv01
$ python3 -m venv ~/.direnv/direnv01
$ python3 -m venv .venv               # ワークスペースディレクトリ上

確認

VS Codeワークスペースディレクトリ( .env を含むディレクトリ)を開きます。

次に、⌘ command + ⇧ shift + P コマンドパレットを開き、Python: インタープリターを選択 を選択します。

f:id:akira6592:20181228221702p:plain:w450
コマンドパレット

以下のように、4 つの環境が認識されてていることが確認できます。

f:id:akira6592:20181228221725p:plain:w450
インタープリターの選択
ここでは、代表して envs01 を選択します。

左下の 使用インタプリターの表示で envs01 が選択されていることが確認できます。

f:id:akira6592:20181228222248p:plain
仮想環境 envs01 が適用状態

この状態で統合ターミナルを起動すると、自動で該当の activate コマンドが実行され、仮想環境に入った状態になります。

f:id:akira6592:20181228222449p:plain
自動で activate される

デバッグ時もこの仮想環境で実行されます。


まとめ

VS Code がデフォルトで読み込む Python の仮想環境のパスを確認しました。 もちろん setting.jsonpython.venvPath で明示的に指定しても良いですが、なるべく設定を変更したくない場合は、デフォルトで読み込まれるパスを活用すると良いと思います。

[Python] pyenv と pipenv による python 仮想環境を構築する(CentOS 7 ほぼ初期状態から)


■ はじめに

Python の仮想環境は、いままで virtualenv/venv のみ利用していたのですが 「2018年のPythonプロジェクトのはじめかた」という記事を見て、pyenv や pipenv 試してみようと思いました。

この記事では、準備、仮想環境の作成と復元を試したときの手順を記載します。 (自分向けメモの意味合いが強いため説明が雑で申し訳ないです。)

今回前提とする環境

pyenv / pipenv とは

  • pyenv は 複数のバージョンの Python を管理するツール。
  • pipenv は 複数のバージョンの Python とパッケージのまとめて管理するツール。pyenv とも連携可能。 Pipefile を使うのが特徴。


環境の準備

pip の準備

インストール

公式ドキュメントの Installing with get-pip.py のインストール方法を参考にインストールします。

$ curl https://bootstrap.pypa.io/get-pip.py | sudo python
(...略...)
Successfully installed pip-18.1 setuptools-40.6.3 wheel-0.32.3

確認

$ pip --version
pip 18.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)


pyenv の準備

インストール

pyenv/pyenv リポジトリの READMME.md にある Basic GitHub Checkout のインストール方法を参考にインストールします。

pyenv のインストールには git が必要なため予めインストールします。

$ yum install git
(...略...)

Installed:
  git.x86_64 0:1.8.3.1-20.el7

Dependency Installed:
  perl-Error.noarch 1:0.17020-2.el7        perl-Git.noarch 0:1.8.3.1-20.el7        perl-TermReadKey.x86_64 0:2.30-20.el7

Complete!

ここから pyenv 本編です。

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
$ exec "$SHELL" -l

確認

$ pyenv --version
pyenv 1.2.8
$ pyenv install --list
Available versions:
(...略...)
  3.6.5
  3.6.6
  3.6.7
  3.6.8
  3.7.0
  3.7-dev
  3.7.1
  3.7.2
(...略...)

その他必要なパッケージインストール

$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel

上記は、あとで pipenv --python x.x.x コマンドを実行したときに、

zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1

というエラーに遭遇して、「CentOS7にPython3(Anaconda3)をインストール」という記事で知った対処方法です。 pyenv 公式 Wiki にの FAQ の Suggested build environmentに記載があります。(今回はCentOS/Fedora 21 and belowのケースを選択)


pipenv の準備

インストール

$ sudo pip install pipenv
Collecting pipenv
(...略...)
Successfully installed certifi-2018.11.29 enum34-1.1.6 pipenv-2018.11.26 typing-3.6.6 virtualenv-16.1.0 virtualenv-clone-0.4.0

確認

$ pipenv --version 3.6.7
pipenv, version 2018.11.26

ここまでで基本的な準備は終わります。




■ 仮想環境の作成

準備ができたので、特定の Python のバージョンとパッケージをインストールした仮想環境を作ってみます。

プロジェクトディレクトリの作成

mkdir mypj
cd mypj

使用する Python バージョンの選択

今回は、 3.6.7 を指定します。

$ pipenv --python 3.6.7
Warning: Python 3.6.7 was not found on your system...
Would you like us to install CPython 3.6.7 with pyenv? [Y/n]: y
Error: invalid input
Would you like us to install CPython 3.6.7 with pyenv? [Y/n]:
Installing CPython 3.6.7 with pyenv (this may take a few minutes)...
✔ Success!
Downloading Python-3.6.7.tar.xz...
-> https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz
Installing Python-3.6.7...
Installed Python-3.6.7 to /home/vagrant/.pyenv/versions/3.6.7


Creating a virtualenv for this project...
Pipfile: /home/vagrant/Pipfile
Using /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6 (3.6.7) to create virtualenv...
⠸ Creating virtual environment...Using base prefix '/home/vagrant/.pyenv/versions/3.6.7'
New python executable in /home/vagrant/.local/share/virtualenvs/vagrant-G6U0N2py/bin/python3.6
Also creating executable in /home/vagrant/.local/share/virtualenvs/vagrant-G6U0N2py/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6

✔ Successfully created virtual environment!
Virtualenv location: /home/vagrant/.local/share/virtualenvs/vagrant-G6U0N2py
Creating a Pipfile for this project...

このときに Pipfile というファイルが作成されます。

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.6"

python_version = "3.6" という指定なので、細かいバージョンの指定にはなっていません。別途、python_full_version = "3.6.7" のような指定方法もあるようです。

パッケージの追加

ここでは、netmiko というネットワーク機器を操作するパッケージをインストールしてみます。

$ pipenv install netmiko
Creating a virtualenv for this project...
Pipfile: /home/vagrant/mypj/Pipfile
Using /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6 (3.6.7) to create virtualenv...
⠧ Creating virtual environment...Using base prefix '/home/vagrant/.pyenv/versions/3.6.7'
New python executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python3.6
Also creating executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/vagrant/.pyenv/versions/3.6.7/bin/python3.6

✔ Successfully created virtual environment!
Virtualenv location: /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX
Installing netmiko...
Adding netmiko to Pipfile's [packages]...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
✔ Success!
Updated Pipfile.lock (153fc2)!
Installing dependencies from Pipfile.lock (153fc2)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 15/15 — 00:00:07
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
$

Pipfile[packages]netmiko が追加されます。(抜粋)

[packages]
netmiko = "*"

また、 Pipfile.lock というファイルが作成されます。

{
    "_meta": {
        "hash": {
            "sha256": "57158d2b8971d66a6434756fc9620915aa380f83e94ff9871202f22643153fc2"
        },
        "pipfile-spec": 6,
        "requires": {
            "python_version": "3.6"
        },
        "sources": [
(...略...)

作成された仮想環境に入る

先ほどと同じく、Pipfile たちがあるディレクトリで、 pipenv shell コマンドを実行すると、仮想環境に入れます。

$ pipenv shell
Launching subshell in virtual environment...
$  . /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/activate
(mypj) $
(mypj) $ python --version
Python 3.6.7
(mypj) $ pip list | grep netmiko
netmiko      2.3.0

指定したとおり、 Python 3.6.7 の環境で、netmiko がインストールされていることが確認できました。

仮想環境から抜けるために deactivate コマンドを実行します。

(mypj) $ deactivate




■ 別マシンで仮想環境の復元

先程作成された、 Pipifile と、Pipfile.lock ファイルを理想して、別マシンで仮想環境(今回は Python 3.6.7 と netmiko)を復元してみます。 pip、pyenv、pipenv は、別マシンでも準備済みとします。

プロジェクトディレクトリの作成

$ mkdir mypj
$ cd mypj

Pipfile のコピー

何かしらの方法で、Pipifile と、Pipfile.lock をコピーしてきます。

仮想環境の復元

pipenv sync コマンドで復元します。

$ pipenv sync
Warning: Python 3.6 was not found on your system...
Would you like us to install CPython 3.6.8 with pyenv? [Y/n]: y
Error: invalid input
Would you like us to install CPython 3.6.8 with pyenv? [Y/n]:
Installing CPython 3.6.8 with pyenv (this may take a few minutes)...
✔ Success!
Downloading Python-3.6.8.tar.xz...
-> https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz
Installing Python-3.6.8...
Installed Python-3.6.8 to /home/vagrant/.pyenv/versions/3.6.8


Creating a virtualenv for this project...
Pipfile: /home/vagrant/mypj/Pipfile
Using /home/vagrant/.pyenv/versions/3.6.8/bin/python3 (3.6.8) to create virtualenv...
⠋ Creating virtual environment...Using base prefix '/home/vagrant/.pyenv/versions/3.6.8'
New python executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python3
Also creating executable in /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/vagrant/.pyenv/versions/3.6.8/bin/python3

✔ Successfully created virtual environment!
Virtualenv location: /home/vagrant/.local/share/virtualenvs/mypj-4hRg6SsX
Installing dependencies from Pipfile.lock (153fc2)...
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 15/15 — 00:00:20
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
All dependencies are now up-to-date!

Pipfile 内での Python バージョンの指定が python_version = "3.6" だったためか、仮想環境作成時の 3.6.7 ではななく、 3.6.8 がインストールされました。

続いて、復元された仮想環境に入って、Python のバージョンと netmiko が入っていいることを確認します。

(mypj) $ python --version
Python 3.6.8
(mypj) $ pip list | grep netmiko
netmiko      2.3.0
(mypj) $ deactivate


■ まとめ

pyenv、pipenv を利用して、Python のバージョンと利用するパッケージをまとめ管理する仮想環境の定義ができました。 仮想環境の分け方はこの他にも、virtualevn/venv でのみで分ける、VMごと分ける、コンテナごと分けるなどの方法もありますが、必要に応じて使い分けができればと思います。

(おまけ)コピペ用

「環境の準備」の一連のコマンドをコピペだけで実行できるようにしたものです。

# pip
curl https://bootstrap.pypa.io/get-pip.py | sudo python

# git
sudo yum -y install git

# pyenv
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
exec "$SHELL" -l
sudo yum -y install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel

# pipenv
sudo pip install pipenv

参考

qiita.com

qiita.com

msh5.hatenablog.jp