てくなべ (tekunabe)

ansible / network automation / 学習メモ

[VS Code] アクティブなエディターのタブの背景色を変える tab.activeBackground

はじめに

VS Code のエディター部分でファイルを開くとタブ表示になりますが、いまアクティブ(開いている)なタブどれなのか色的に少しわかりにくなと感じていました。

アクティブなタブの背景色を変える方法を Twitter で教えていただいた(ありがとうございます!)のでこちらにも共有します。

変更前

私の環境では以下のような表示です。この場合 jmespath.yml がアクティブです。 これをもう少し際立たせたいと思います。

f:id:akira6592:20210523133631p:plain
どれを開いてるのかわかりにくかった

変更

setting.jsonworkbench.colorCustomizations 内で tab.activeBackground で背景色を指定します。

私の設定例

{
    "workbench.colorCustomizations": {
        "tab.activeBackground": "#666666cc",
    },
   // ...(略)...
}

色はお好みで変更してください。

変更後

こんな感じになります。

f:id:akira6592:20210523133556p:plain
アクティブなタブの背景色を薄くした

選ぶ様子。

他、workbench.colorCustomizations 配下の現在の設定を書き出すこともできるようです。おしえていただきありがとうございます。

ip コマンドの -j オプションで JSON 出力する

はじめに

コマンドの出力結果を機械的に抽出や加工したい場合、JSONなどの構造化データだと正規表現を書くことをぐっと減らせて便利です。

たまたま ip コマンドは -j または --json というオプションで json 出力できることを知りました。

-p オプションを併用すると、改行付きで表示されて見やすいです。

試した結果をまとめます。

IP アドレスの表示

(一部ダミーの値にしています)

JSON 出力

$ ip -j -p addr
[ {
        "ifindex": 1,
        "ifname": "lo",
        "flags": [ "LOOPBACK","UP","LOWER_UP" ],
        "mtu": 65536,
        "qdisc": "noqueue",
        "operstate": "UNKNOWN",
        "group": "default",
        "txqlen": 1000,
        "link_type": "loopback",
        "address": "00:00:00:00:00:00",
        "broadcast": "00:00:00:00:00:00",
        "addr_info": [ {
                "family": "inet",
                "local": "127.0.0.1",
                "prefixlen": 8,
                "scope": "host",
                "label": "lo",
                "valid_life_time": 4294967295,
                "preferred_life_time": 4294967295
            },{
                "family": "inet6",
                "local": "::1",
                "prefixlen": 128,
                "scope": "host",
                "valid_life_time": 4294967295,
                "preferred_life_time": 4294967295
            } ]
    },{
        "ifindex": 2,
        "ifname": "ens192",
        "flags": [ "BROADCAST","MULTICAST","UP","LOWER_UP" ],
        "mtu": 1500,
        "qdisc": "fq_codel",
        "operstate": "UP",
        "group": "default",
        "txqlen": 1000,
        "link_type": "ether",
        "address": "00:50:56:xx:xx:xx",
        "broadcast": "ff:ff:ff:ff:ff:ff",
        "addr_info": [ {
                "family": "inet",
                "local": "192.168.1.100",
                "prefixlen": 24,
                "broadcast": "192.168.1.255",
                "scope": "global",
                "dynamic": true,
                "noprefixroute": true,
                "label": "ens192",
                "valid_life_time": 67514,
                "preferred_life_time": 67514
            },{
                "family": "inet6",
                "local": "2001:db8::1",
                "prefixlen": 64,
                "scope": "global",
                "dynamic": true,
                "noprefixroute": true,
                "valid_life_time": 2591817,
                "preferred_life_time": 604617
            },{
                "family": "inet6",
                "local": "fe80::5686:4062:1:1",
                "prefixlen": 64,
                "scope": "link",
                "noprefixroute": true,
                "valid_life_time": 4294967295,
                "preferred_life_time": 4294967295
            } ]
    },{
        "ifindex": 3,
        "ifname": "virbr0",
        "flags": [ "NO-CARRIER","BROADCAST","MULTICAST","UP" ],
        "mtu": 1500,
        "qdisc": "noqueue",
        "operstate": "DOWN",
        "group": "default",
        "txqlen": 1000,
        "link_type": "ether",
        "address": "52:54:00:xx:xx:xx",
        "broadcast": "ff:ff:ff:ff:ff:ff",
        "addr_info": [ {
                "family": "inet",
                "local": "192.168.122.1",
                "prefixlen": 24,
                "broadcast": "192.168.122.255",
                "scope": "global",
                "label": "virbr0",
                "valid_life_time": 4294967295,
                "preferred_life_time": 4294967295
            } ]
    },{
        "ifindex": 4,
        "ifname": "virbr0-nic",
        "flags": [ "BROADCAST","MULTICAST" ],
        "mtu": 1500,
        "qdisc": "fq_codel",
        "master": "virbr0",
        "operstate": "DOWN",
        "group": "default",
        "txqlen": 1000,
        "link_type": "ether",
        "address": "52:54:00:xx:xx:xx",
        "broadcast": "ff:ff:ff:ff:ff:ff",
        "addr_info": [ ]
    } ]

通常出力(比較用)

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:50:56:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic noprefixroute ens192
       valid_lft 67528sec preferred_lft 67528sec
    inet6 2001:db8::1/64 scope global dynamic noprefixroute 
       valid_lft 2591832sec preferred_lft 604632sec
    inet6 fe80::5686:4062:1:1/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:xx:xx:xx brd ff:ff:ff:ff:ff:ff

ルーティングテープルの表示

JSON 出力

$ ip -j -p route
[ {
        "dst": "default",
        "gateway": "192.168.1.1",
        "dev": "ens192",
        "protocol": "dhcp",
        "metric": 100,
        "flags": [ ]
    },{
        "dst": "192.168.1.0/24",
        "dev": "ens192",
        "protocol": "kernel",
        "scope": "link",
        "prefsrc": "192.168.1.100",
        "metric": 100,
        "flags": [ ]
    },{
        "dst": "192.168.122.0/24",
        "dev": "virbr0",
        "protocol": "kernel",
        "scope": "link",
        "prefsrc": "192.168.122.1",
        "flags": [ "linkdown" ]
    } ]

通常出力(比較用)

$ ip route
default via 192.168.1.1 dev ens192 proto dhcp metric 100 
192.168.1.0/24 dev ens192 proto kernel scope link src 192.168.1.100 metric 100 
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown 

おわりに

他のコマンド、ツールも意外と標準でJSON出力できるということもありそうです。

今一度ヘルプを見るといいかもしれません。

参考

標準機能ではないですが、主要コマンドのパーサーとして jc というものもあります。

github.com

[Ansible] 「つまずき Ansible 【Part34】ansible-core 2.11.0 の changelog を眺める」ふりかえり

はじめに

2021/05/01 に、YouTube Live で「つまずき Ansible 【Part34】ansible-core 2.11.0 の changelog を眺める」という配信をしました。

connpass.com

今回は、先日リリースされた ansible-core 2.11.0 の changelog の中で個人的に気になったところをピックアップしました。

changelog

https://github.com/ansible/ansible/blob/stable-2.11/changelogs/CHANGELOG-v2.11.rst#v2-11-0


動画

youtu.be

※21:41 頃の「複数の collection で、routing 先が変更」のとき「ansible-core のコアの話というより ansible 4 の話」と言っていますが、lib/ansible/config/ansible_builtin_runtime.yml の修正なので ansible-core の話です。失礼しました。

ansible-core 2.11.x の位置づけ

スクラップからいろいろ

ベータ段階からたまに changelog を見ていたので、都度メモっておいた Zenn のスクラップをベースにお話しました。

zenn.dev

(個人的にはこのような使い方にスクラップがマッチしていました)


Part35にむけて

以下のネタを検討中です。気が向いたものをやります。 connpass申込時のアンケートでいただいたものも含めています。

  • connection: local ななにか
  • Windows
  • cli_parse モジュール(Part15 の続き)
  • モジュールのテスト
  • Tower / AWX
  • role と Playbook のリポジトリ分割と読み込み
  • AWXとの共存を念頭に入れたDirectory構成

[Ansible] 親サブネットから利用可能な子サブネットを求める ipsubnet フィルター

はじめに

Ansible には、IP アドレスを扱うための様々なフィルターがあります。

docs.ansible.com

その中に ipsubnet というフィルターがあります。

このフィルターにはいくつか機能があり、例えば「10.0.0.0/24」内で /25 で区切ったときの N 番目のサブネットは何か求められます。

この記事では簡単な例でご紹介します。

  • 動作確認環境
    • Ansible 2.9.19

書式

 ipsubnet(親サブネット, 何番目) 

サンプルPlaybook

サンプルのPlaybookと出力例をコメントで記載します。

---
- hosts: localhost
  gather_facts: false

  tasks:
    - name: subnet manipulation
      debug:
        msg:
          # 以下は /24 の最初を求めるので "10.0.0.0/24"
          - "{{ '10.0.0.0/24' | ipsubnet(24, 0) }}"
          # 以下は /25 の最初を求めるので "10.0.0.0/25"
          - "{{ '10.0.0.0/24' | ipsubnet(25, 0) }}"
          # 以下は /25 のインデックス1を求めるので "10.0.0.128/25"
          - "{{ '10.0.0.0/24' | ipsubnet(25, 1) }}"
          # 以下は /25 のインデックス2を求めるので false、つまり範囲外
          - "{{ '10.0.0.0/24' | ipsubnet(25, 2) }}"
          # 以下は /25 を求めるので 10.0.0.240/28
          - "{{ '10.0.0.0/24' | ipsubnet(28, -1) }}"

おわりに

自前で計算しようとすると以外と手間な気がするので、このようなフィルターがあるのは助かります。

カラビナでラックのケーブルを整線する

はじめに

自宅にいくつかネットワーク機器があり、家具であるメタルラックを利用しています。

だんだんとケーブルの本数も増えてくると、きれいに整線したくなってきます。

データセンターのようなきちんとした場所であれば、ケーブルマネジメントのような専用の部品を使うところです。

www.panduit.com

ですが、ここは一般的な自宅です。本格的なものほどではなくとも、それなりにできないかと考えています。

100円ショップをふらついているときにふと目にはいったカラビナが使えるのではと思い、試してみました。思いの外よい感じでしたのでご紹介します。

カラビナケーブリング

こんな感じです。

f:id:akira6592:20210425111905p:plain
ケーブルを下に流す

f:id:akira6592:20210425112306p:plain
上に流す
かんたんにケーブルを着脱でき、ほどよい束ね感もあります。これは 2個で100円のものです。

サイズは少し余裕を持ったもののほうが良いかもしれません。


■ その他の方法

カラビナ以外の方法を比較のためにご紹介します。

面ファスナー

こちらは別の用途でよく使っていますが、リング状にすると同じようにケーブルを整線できます。

f:id:akira6592:20210425111955p:plain
面ファスナー
安上がりなのが一番のメリットでしょうか。

着脱の際、剥がしたりくっつけたりするのが少し手間なのと、他のケーブルが一緒にとれてしまわないよう、少し気をつける必要があります。

カードリンク

カードリンク(単語帳などを束ねるもの)も良さそうです。@ipv6labsさん、ご紹介ありがとうございます。

f:id:akira6592:20210425113609p:plain
カードリンク

手元には直径3cm位のものしかありませんでしたが、もう少し大きいものがいいかもしれません。安上がりなのと、見た目がスッキリしてるのがいいですね。

S字フック

これは少し辛いです。着脱は楽ですが、その分つられて他のケーブルが脱線しやすいです。

f:id:akira6592:20210425112038p:plain
S字フック
また、写真のようにケーブルを下に流す分にはまだいいのですが、上に流すときには使えません、

比較

主観による比較です。

方法 着脱のしやすさ  ホールド感 コスパ 見た目のスッキリ感
カラビナ
面ファスナー
カードリンク
S字フック

あれ、あとから教えていただいた、カードリンクが結構よい・・・?

[GitLab] CI が成功しないと Merge できないようにする

はじめに

GitLab には GitLab CI という機能があり、git push のような更新のタイミングで CI を実行できます。

デフォルトでは、マージリクエストの画面で CI の成功/失敗に関わらず Merge ボタンが押せます。

柔軟といえば柔軟ですが、厳密にしたい場合は少し不安が残るかもしれません。

そこで、この記事では CI が成功しないと Merge できないようにする設定を紹介します。

  • 動作確認環境
    • gitlab.com (GitLab Enterprise Edition 13.11.0-pre)

デフォルトでは CI 失敗時でも Merge 可

比較のため、デフォルトの挙動を説明します。

以下のように、CI に失敗しても Merge ボタン自体は押せるようになっています。

f:id:akira6592:20210420222627p:plain
デフォルトではCI失敗時でも Merge できる

CI が成功しないと Merge できないようにする

CI が成功しないと Merge できないようにするには設定変更が必要です。

設定変更

プロジェクトの Setting > General 画面を開きます。

f:id:akira6592:20210420222709p:plain:w300
Setting > General

Merge requests セクションの Expand をクリックして設定項目を開きます。

f:id:akira6592:20210420222744p:plain
Merge requests セクションの Expand

Pipelines must succeed にチェックを入れて、Save change をクリックします。

f:id:akira6592:20210420222831p:plain
Pipelines must succeed にチェック

これで設定変更は完了です。

動作確認

以下のように、CI 失敗次は Merge ボタンが押せないようになります。

f:id:akira6592:20210420222907p:plain
CI 失敗時は Merge できないようになった

参考

docs.gitlab.com

[Python] システムワイドのパッケージを利用できるように venv を作成するオプション --system-site-packages

はじめに

venv はデフォルトでは、システムワイド(グローバル、OSレベル)な Python 環境を参照しません。

venv 作成時に --system-site-packages オプションを参照するようになります。 これにより、venv にないパッケージでもシステムワイドに入っていれば venv から使えるようになります(個人的には使ったことありませんが)。

デフォルトの場合と--system-site-packages オプション不可時の挙動をそれぞれ確認します。

  • 動作確認環境: Python 3.6.8

デフォルト

特に特別なオプションを指定せずに venv を作成します。 システムワイドにのみ paramiko をイントールした状態で、paramiko を import しようとするとエラーになります、

[admin@gitlab ~]$ python3 -m venv venv1
[admin@gitlab ~]$ source venv1/bin/activate
(myvenv) [admin@gitlab ~]$ 
(myvenv) [admin@gitlab ~]$ python -c "import paramiko"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'paramiko'

--system-site-packages オプション付加

--system-site-packages オプションを付加して venv を作成します。

今度は paramiko が import できました。

[admin@gitlab ~]$ python3 -m venv venv2 --system-site-packages
[admin@gitlab ~]$ source venv2/bin/activate
(venv2) [admin@gitlab ~]$ python -c "import paramiko"
(venv2) [admin@gitlab ~]$ 

参考

知ったきっかけ

--system-site-packages オプションは、Software Design 2021年2月号の連載「Ansible問題解決マップ」の 「Ansibleの実行環境」で知りました。

著者の@saito_hidekiさん、ありがとうございました。

パスやバージョンもあわせて確認

ありがとうございます。

(venv2) [admin@gitlab ~]$ python -c "import paramiko; print(paramiko.__file__); print(paramiko.__version__)"
/usr/local/lib/python3.6/site-packages/paramiko/__init__.py
2.7.2