てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Python] 2つファイルの内容をリストにして差分を表示する

はじめに

こちらの記事を拝見し、紹介されている Python のコードの別解を考えてみます。

fugulog.hatenablog.com

  • 動作確認環境

やっていること

背景はここでは割愛しますが、docker イメージ名がリスト化された2つのファイル

  • checklist.txt
  • imagelist.txt

があり、checklist.txt にあって、imagelist.txt にないイメージ名を画面に表示するものです。

たとえば、2つのファイルがそれぞれ

  • checklist.txt
image1
image2
image3
image4
image5
  • imagelist.txt
image1
image3
image5

という状態であれば、

image2
image4

と出力します。

元のコード

#checkimage.py

checklist = open("checklist.txt","r")
imagelist = open("imagelist.txt", "r")

checklists = []
imagelists = []

for line1 in checklist:
    checklists.append(line1)

for line2 in imagelist:
    imagelists.append(line2)

for check in checklists:
    if check not in imagelists:
        print(check.rstrip('\n'))

checklist.close()
imagelist.close()

わざわざ配列に入れる必要はないのかもしれませんが、そこは知識と時間不足でした、、 もしもっとスマートな書き方を知っている方は教えてください🙇‍♀️

とのことですので、私なりに4パターンほど考えたり、調べたりしました。


■ パターン1: ファイル読み込みを with で囲う

ファイルを暗黙的、かつ確実に close させるために openwith で囲うパターンです。 他は、元のコードと同じです。

checklists = []
imagelists = []

with open("checklist.txt", "r") as f:
  for line1 in f:
    checklists.append(line1)

with open("imagelist.txt", "r") as f:
  for line2 in f:
    imagelists.append(line2)

for check in checklists:
    if check not in imagelists:
        print(check.rstrip('\n'))


■ パターン2: リスト化に splitlines() を利用する

パターン1をベースにして、ファイル内容のリスト化に splitlines() を利用するパターンです。 受け取るリストの初期化と append が不要になります。また、改行区切りで split されるので、表示時の .rstrip('\n') も不要になるはず。

with open("checklist.txt", "r") as f:
    checklists = f.read().splitlines()

with open("imagelist.txt", "r") as f:
    imagelists = f.read().splitlines()

for check in checklists:
    if check not in imagelists:
        print(check)


■ パターン3: 差分を - で求める

パターン2をベースにして、差分を - で求めるパターンです。 比較する際のループが不要になります。ただし、セットに変換するので順番は維持されません。

with open("checklist.txt", "r") as f:
    checklists = f.read().splitlines()

with open("imagelist.txt", "r") as f:
    imagelists = f.read().splitlines()

diff = list(set(checklists) - set(imagelists))

for check in diff:
    print(check)


■ パターン4: 差分を filter で求める

パターン3でベースにして、順番を維持するやり方がないかと調べたところを以下のページが参考になりました。

lcjvEm - Online Python3 Interpreter & Debugging Tool - Ideone.com

(コメントに「重複も保持される」とありますが「順番も」のことだと思います)

差分を filter で求めるパターンです。

with open("checklist.txt", "r") as f:
    checklists = f.read().splitlines()

with open("imagelist.txt", "r") as f:
    imagelists = f.read().splitlines()

diff = list(filter(lambda x: x not in imagelists, checklists))  

for check in diff:
    print(check)


おわりに

表示の仕方を含めるともっといろいろな方法があると思います。

[200-901勉強記] 書籍 Understanding and Using APIs を読んだ

はじめに

Cisco Certified DevNet Associateの勉強の一環で以下の書籍を読みました。

目次

Chapter 1 Understanding and Using Data encoding formats (XML, JSON, and YAML)
Chapter 2 Parsing Data encoding formats in Python
Chapter 3 Construct a REST API request to accomplish a task given API documentation
Chapter 4 Describe common usage patterns related to webhooks
Chapter 5 Identify the constraints when consuming APIs
Chapter 6 Explain common HTTP response codes associated with REST APIs
Chapter 7 Troubleshoot a problem given the HTTP response code, request and API documentation
Chapter 8 Identify the parts of an HTTP response (response code, headers, body)
Chapter 9 Utilize common API authentication mechanisms: basic, custom token, and API keys
Chapter 10 Compare common API styles (REST, RPC, synchronous, and asynchronous)
Chapter 11 Construct a Python script that calls a REST API using the requests library
Chapter 12 Describe the device level APIs and dynamic interfaces for IOS XE and NX-OS
Chapter 13 Understanding Cisco DevNet resources
Chapter 14 Describe Edge and Cloud Computing Models

Amazonページから引用

内容

基本的には、FullStackNetworker のオンライン学習コース「All-in-One Cisco DevNet Associate (DEVASC 200-901 V1.0) Certification」の「Understanding and Using APIs」の章と同じような感じでした。

以下の内容が加えられていました

  • NETCONFの概要とサンプルコード
  • RESTCONFの概要とサンプルコード
  • クラウドVM、コンテナの概要
  • Cisco DevNet の紹介

All-in-One Cisco DevNet Associate (DEVASC 200-901 V1.0) Certification」のほうはまだ学習途中なのですが、全部終われば、書籍の内容はカバーできるのかもしれません。

特典

Amazon のページ上には

Each purchase comes with a complimentary access to a DevNet Associate Quiz on FullStackNetworker.com.

と、クイズへのアクセス権が付いてくると書いてあります。 実際の手配としては「Amazon の注文番号を添えてメールを送ってね」とPrece に説明があります。

[200-901勉強記] Cisco DevNet Associate (DEVASC 200-901) の勉強をはじめました

はじめに

2020/02/24 に始まる、Cisco DevNet Associate (DEVASC 200-901) の勉強をはじめした

試験情報リンクまとめ tekunabe.hatenablog.jp

今後のブログでも、勉強途中のトピックを書いていきたいと思います。

当面の学習コンテンツ

公式のガイドは、2020年6月とまだ先です。

そこで、まずは以下のコンテンツから入ろうかと思います。有料です。

Full Stack Networker

文章、サンプルコード中心。 www.fullstacknetworker.com

今はこれをやっています。

CBT Nugget

動画中心(文字起こしあり)。アプリあもってスマホでも学習も可能。 www.cbtnuggets.com

とりあえず申し込み

ピアソン VUE ですでに申し込みができます。 言語選択画面はなく、現在は英語のみのようです。

f:id:akira6592:20191229201733p:plain
締め切り駆動

[Ansible] Hackey でイルミネーションをつくる

はじめに

Hackeyという、カギをひねると HTTP をしゃべる機器があります。

cerevo.com

この機器のもう一つの機能として、内蔵の5色の LED を光らせるというものがあります。 HTTP GET を叩いて光らせるので、curl でも何でもいいのですが、たまたま手元にあった Ansible から叩くことにします。


Hackey 側の設定

Hackey の管理画面で、光らせたい色の設定を行います。それぞれに URL が発行されます。

f:id:akira6592:20191224215457p:plain
LED 通知の設定


Playbook

uri モジュールを利用します。デフォルトのメソッドは GET です。

vars で各色を光らせる URL を定義して、loop で回しています。本当は無限に回したかったのですが、分からなかったのでリストを * 9999 で引き伸ばしています。

pause でループを回す秒数を指定します。

- hosts: localhost
  gather_facts: no
  connection: local

  tasks:
    - name: illumination
      uri:
        url: "{{ item.url }}"
      loop: "{{ color_list * 9999 }}"
      loop_control:
        pause: 1
        label: "{{ item.color }}"

  vars:
    color_list:
      - color: green
        url: http://hackey-app.cerevo.com/api/v1/blink/xxx_dummy1_xxx
      - color: orange
        url: http://hackey-app.cerevo.com/api/v1/blink/xxx_dummy2_xxx
      - color: purple
        url: http://hackey-app.cerevo.com/api/v1/blink/xxx_dummy3_xxx
      - color: red
        url: http://hackey-app.cerevo.com/api/v1/blink/xxx_dummy4_xxx
      - color: blue
        url: http://hackey-app.cerevo.com/api/v1/blink/xxx_dummy5_xxx


実行結果

$ ansible-playbook -i losthost, illumination.yml 

PLAY [localhost] *************************************************************************************************************

TASK [illumination] **********************************************************************************************************
ok: [localhost] => (item=green)
ok: [localhost] => (item=orange)
ok: [localhost] => (item=purple)
ok: [localhost] => (item=red)
ok: [localhost] => (item=blue)
ok: [localhost] => (item=green)
ok: [localhost] => (item=orange)
ok: [localhost] => (item=purple)
...(略)...


さいごに

ありがとうございました。

参考

カギをひねる方の使いみち

f:id:akira6592:20171217111404p:plain:w400
www.youtube.com

[Ansible] 指定した文字数以内に文字を切り詰める truncate フィルター

はじめに

Ansible が内部で利用しているテンプレートエンジンの Jinja2 には、指定した文字数以内に切り詰める truncate フィルターがあります。

Ansible の filter のドキュメントページ には載っていないので知らなかったのですが、Jinja2 のリファレンスを眺めていたらたまたま見つけたので試してみます。

ほぼ、リファレンスの例をなぞるかたちです。


基本的な切り詰め

最初のオプションに、省略記号(デフォルト ...)を含めて何文字にするかを指定します。 ただし、デフォルトでは単語の途中では切り詰めずに、切のいいところで短めに切り詰めます。

    - name: truncate
      debug:
        msg: "{{ 'This is kingyo.' | truncate(9) }}"

結果

ok: [localhost] => {
    "msg": "This..."  
}

結果としては、This... という7文字になりました。


単語の途中でも切り詰める

2番目のオプションで、単語の途中でも切り詰めるかどうかを指定します。デフォルトは False です。

    - name: truncate
      debug:
        msg: "{{ 'This is kingyo.' | truncate(9, True) }}"

結果

ok: [localhost] => {
    "msg": "This i..."
}

結果としては、This i... という9文字になりました。isi で切れています。


省略記号を変更する

    - name: truncate
      debug:
        msg: "{{ 'This is kingyo.' | truncate(9, False, '..(略)..') }}"

結果

ok: [localhost] => {
    "msg": "Th..(略).."
}

結果としては、Th..(略).. という9文字になりました。指定した省略記号の文字数もちゃんと考慮されるようです。


番外編: スライスする

省略記号なし、単語判断なしの切り詰めで良ければ、Python のスライスでよさそうです。

    - name: truncate
      debug:
        msg: "{{ 'This is kingyo.'[:9] }}"

結果

***
ok: [localhost] => {
    "msg": "This is k"
}

[Ansible] Python の str.format() のようなことをする

はじめに

Ansible ではテンプレートエンジンとして Jinja2 を利用しています。 Jinja2 書式内で、Pythonstr.format()のようなことをする方法を2つ紹介します。

  • 検証環境

方法1: .format() メソッドを利用する

Pythonstr.format() を呼び出すような方法です。

  • Playbook 抜粋
    - name: bracket only
      debug:
        msg: "{{ 'Hello, {}!'.format('Kingyo') }}"
        # 結果
        # "Hello, Kingyo!"

    - name: number
      debug:
        msg: "{{ 'Hello, {0}!'.format('Kingyo') }}"
        # 結果
        # "Hello, Kingyo!"
      
    - name: keyword
      debug:
        msg: "{{ '{greeting}, {name}!'.format(greeting='Hello', name='Kingyo') }}"
        # 結果
        # "Hello, Kingyo!"

方法2: format フィルターを利用する

Jinja2 の組み込みフィルターの format フィルターを利用する方法です。

    - name: filter test
      debug:
        msg: "{{ 'Hello, %s' | format('Kingyo!') }}"
        # 結果
        # "Hello, Kingyo!"

なお、format フィルターでは、以下のように {} は利用できません。

    - name: filter test
      debug:
        msg: "{{ 'Hello, {}!' | format('Kingyo') }}" 
        # 結果
        # エラー

補足

いずれも、Ansible の フィルターのドキュメントには掲載されていない方法ですが、掲載されていなくても Jinja2 自体の機能が使えるので、こんなこともできますね、ということです。 現在 Ansible の devel バージョンのドキュメントには以下の記載があります。

This page documents mainly Ansible-specific filters, but you can use any of the standard filters shipped with Jinja2 - see builtin filters in the official Jinja2 template documentation. You can also use Python methods to manipulate variables.

[Ansible] 新バージョンの Ansible が出るときにどこで情報を得ればよいか


これは Ansible Advent Calendar 2019 の22日目の記事です。


■ はじめに

Ansible は年に1〜2回ほどバージョンアップを重ねています。毎回大量のモジュールが追加されたり、様々な機能追加や変更がなされています。

個人的にはどのような変化があるのか気になるので、調べて試して以下のようにまとめてきました。

この記事では、新しいバージョンの Ansible が登場した(する)際に、私がどこを見て情報を得えてきたかご紹介します。


【目次】


■ 【Porting Guides】バージョンアップ時の注意点は?

docs.ansible.com

Porting Guidesには、各バージョンへアップデート(移行: Proting)する際の注意点などがまとめられています。

具体的には以下のようなものです。

  • 代表的な新モジュールや新機能
  • 仕様変更
  • Deprecated(非推奨)になるモジュールや機能
  • 削除されたモジュールや機能

CHANGELOG を確認する時間がなかったり、ざっくりした変更を知りたい場合には、Porting Guides が適していると思います。

Ansible 2.9 の例: Ansible 2.9 Porting Guide


■ 【公式ブログ】 特に注目な新機能は?

www.ansible.com

THE INSIDE PLAYBOOKRed Hat 社による、Ansible の公式ブログです。

マイナーバージョンアップ(2.8 から 2.9、など)がある前後は、特定の新機能にフォーカスをあてた記事が投稿されることあります。詳細に解説されるため、注意深く読むようにしています。

ただし、サンプルの Playbook のインデントが誤っていることがしばしばあります。サンプルを試してうまく行かないときはインデントを疑うと良いです。

(利用されている CMS のコードブロック機能と YAML の相性があまり良くないようです。)


■ 【CHANGELOG】 具体的で詳細な変更点は?

(リンクは Ansible 2.9 の例) github.com

CHANGELOG には、変更点が細かく掲載されています。

ただ私の感覚としては、CHANGELOG の文言だけでは、何のことを指しているのか、どういう経緯なのかが分からないことがあります。

ここでは少し掘り下げて、CHANGELOG の文言から変更の概要と詳細を方法をご紹介します。

(予備知識) CHANGELOG の作られ方

具体的な CHANGELOG の追い方の説明の前に、CHANGELOG の作られ方について説明します。 作られ方が分かると追い方が分かるようになります。

新モジュール、新プラグイン以外の Pull Request (以下、PR) には、CHANGELOG のフラグメント(かけら)も一緒に含まれます。 そして、リリース時にフラグメントがマージされて、1つの CHANGELOG ファイルにまとめまれます。

つまり、CHANGELOG の文言を頼りにしてフラグメントを特定することで、対応する PR が分かります。 中には親切に CHANGELOG の文言の中に PR や Issue 番号が含まれていることもあります。

PR が分かれば、元になっている Issue、具体的なコードの diff、テストコードなども分かります。

f:id:akira6592:20191217175647p:plain
CHANGELOGのフラグメントがマージされる

以下、具体的な例を元に CHANGELOG の追い方を説明します。

なお、操作説明の都合上 GitHub の画面を利用しますが、VS Code などの GitHub と連携できるエディタを利用して、同等の操作をしていただいても大丈夫です。 また、今回は少ないヒントから追うことを想定して回りくどい追い方をしています。もし、CHANGELOG の文言に PR 番号が含まれていたり、PR を直接検索したりして、元の PR 見つかるのであれば、それはそれでOKです。

CHANGELOG の追い方

(1) 追いたいバージョンの CHANGELOG を表示する

Ansible のリポジトリchangelogs ディレクトリを開きます。

追いたいバージョンのブランチ を選択します。Ansible 2.9 であれば stable-2.9 を選択します。

f:id:akira6592:20191217175741p:plain
changelogs ディレクトリの表示とブランチの選択

(なお、本リポジトリはデフォルトでは devel ブランチが指定されています。devel は開発中のブランチであるため、まだ CHANGELOG は1つにマージされていません。)

特定のバージョンの CHANGELOG が表示されたら、追いたい CHANGELOG の文言を決めます。

ここでは、Ansible 2.9.0 の CHANGELOG の以下の文言を追うことにします。(だいぶ親切に書かれていますが)

Add new option to default standard out callback plugin, ANSIBLE_CHECK_MODE_MARKERS, which adds check mode markers (DRY RUN, CHECK_MODE) to the output when running in check mode. It is off by default.

(2) CHANGELOG フラグメントを特定する

先ほど決めた CHANGELOG の文言の一部を利用して、CHANGELOG フラグメントを特定します。

フラグメントの一覧は changelogs/fragments ディレクトリ内にあります。Ansible 2.9 の場合はこちらです。

f:id:akira6592:20191217175845p:plain
CHANGELOG フラグメントの一覧

フラグメントの一覧内を、今回追っているCHANGELOG の文言の一部 check_mode で検索します。以下のファイルが見つかります。

f:id:akira6592:20191217175930p:plain
フラグメントの特定

見つかったフラグメントを開き、目的の CHANGELOG フラグメントであることを確認します。

f:id:akira6592:20191217180459p:plain
フラグメントの中身

ここまでで、CHANGELOG フラグメントを特定できました。

(3) 元の PR を特定する

先ほど特定した フラグメントの History ボタンをクリックしてコミット履歴を表示します。

f:id:akira6592:20191217180532p:plain
History をクリック

表示されたコミット履歴のメッセージをクリックします。

f:id:akira6592:20191217180603p:plain
メッセージをクリック

表示された画面を、上にスクロールすると該当 PR へのリンクがあるので、クリックします。

f:id:akira6592:20191217180634p:plain
PR 番号のクリック

f:id:akira6592:20191217180659p:plain
特定できたPR 画面

ここまでで、元の PR を特定できました。PR のやり取りや、トリガーとなった issue(この例では "fixes #48787" とあり)を確認することで、修正の経緯などを知ることができます。

続いて、さらに詳しく知るべく、コードレベルで確認します。

(4) 修正されたコードなどを確認する

先ほど特定した PR の Files changed をクリックすると、この PR 内で修正されたコードの一覧を表示します。

f:id:akira6592:20191217180728p:plain
Files Changed のクリック

f:id:akira6592:20191217180820p:plain
修正ファイルの一覧
この修正されたコードの一覧でかなり詳細を知ることができます。

分かることをいくつかピックアップします。

少々長くなりましたが、以上が CHANGELOG から具体的で詳細な変更点を追う方法でした。

なお、ここで例として追った本機能の使い方については、別途以下の記事にまとめています。

[Ansible] check モードの実行ログに [CHECK MODE] という印をつける方法 - てくなべ (tekunabe)


■ 【ROADMAP】 次のバージョンはいつリリース予定?

docs.ansible.com

ROADMAPには、次バージョンの Ansible がいつ頃、どのような段階でリリースされる予定かが掲載されています。 掲載されるバージョンの単位は、Ansible 2.8、2.9・・のようなマイナーバージョンです。

なお、latest バージョンのドキュメントには、開発中の次のバージョン ROADMAP が載らないので devel バージョンで確認します。

docs.ansible.com

f:id:akira6592:20191217181233p:plain
ドキュメントのバージョン切り替え


■ 【番外編】 もっと普段から情報を追うためには

私が見逃しているだけかもしれませんが、CHANGELOG に載らない変更がなされることもあります(例 PR #59153)。

日常的に新聞を読むように開発状況を追っていくためには、以下の情報


まとめ

新しいバージョンの Ansible が登場した(する)際に、私がどこを見て情報を得えてきたかご紹介しました。

情報源 概要
Porting Guides バージョンアップ時の注意点
公式ブログ 特に注目の機能
CHANGELOG (リンクは Ansible 2.9 の例) 具体的で詳細な変更点
ROADMAP 次のバージョンのリリース予定

Ansible でどのような機能が追加、修正されたかを追う方法として参考になれば幸いです。