ssh_config形式のファイルからVulsのconfig.tomlを生成するコマンドを作った

今、脆弱性検出ツールでかなりアツいVulsですが、対象のリモートホストへの接続のためにはTOML形式の設定ファイルが必要です。

なんかssh_configに似ているなーと思ったので、作ってみました。

github.com

Usage

まずはインストール。

$ gem install ssh_config_to_vuls_config

インストールすると sc2vc というコマンドが使えるようになるので、あとはSTDINにssh_config形式のファイルをかませるだけです。

$ cat ~/.ssh/config | sc2vc > vuls_config.toml

あれ?なんか koma に使い方が似ていますね。

というわけで

本家のREADMEにも載せてもらえました!嬉しい!

https://github.com/future-architect/vuls#related-projects

エージェントレスでプラットフォームのインベントリ情報を取得するツールkomaを作った

Ansibleにはsetup module、Chefにはohai、Puppetにはfacterというプラットフォームのインベントリ情報を取得するライブラリや機構があります。

ただ、リモートホストのインベントリ情報を取得したいときに、ohaiやfacterはリモートホスト側にインストールが必要だったり、setup moduleは単体で使いにくかったりするので、

「気軽にエージェントレスでプラットフォームのインベントリ情報を取得できるようにしたいなー」

ということでkomaというgemを作りました。

github.com

Installation

$ gem install koma

Usage

まず、公開鍵認証でSSH接続できるリモートホストを用意します。

例えば、

$ ssh k1low@example.com

でログインできるようなホストですね。

で、そのssh コマンドを koma ssh に変えて実行します。

$ koma ssh k1low@example.com

そうすると、インベントリ情報をJSON形式でSTDOUTに出力します。

さらに複数のホストのインベントリ情報を一気に取得したい場合はカンマ区切りで指定できます。

$ koma ssh example.com,k1low@example.jp
{
  "example.com": {
    ...
  },
  "example.jp": {
    ...
  }
}

取得できるインベントリ情報

取得できるインベントリ情報はkoma keysで確認できます(リモートホストディストリビューションによって取得できる情報にはばらつきがあります)。

$ koma keys
memory
ec2 (disabled)
hostname
domain
fqdn
platform
platform_version
filesystem
cpu
virtualization
kernel
block_device
package
user
group
service

インベントリ情報を指定したいときは --key オプションで指定可能です。

$ koma ssh k1low@example.com --key cpu,kernel

(disabled) になっている ec2 などは --enable-ec2 オプションで有効になります。

Pro Tip: ssh_config形式でリモートホストを指定する

komaはssh_config形式のSTDINを入力とすることができます。

$ cat <<EOF > ssh_config_tmp
Host example_com
  User k1low
  Hostname example.com
  PreferredAuthentications publickey
  IdentityFile /path/to/example_rsa

Host example_jp
  User someone
  Hostname example.jp
  PreferredAuthentications publickey
  IdentityFile /path/to/more/example_jp_rsa
EOF

$ cat ssh_config_tmp | koma ssh --key platform,platform_version

ssh_config形式がいけるということは、

$ vagrant ssh-config | koma ssh --key cpu,kernel

みたいに、Vagrantのサーバのインベントリ情報を取得したり、

$ sconb dump example_* | sconb restore | koma ssh --key platform,platform_version

みたいに、sconb~/.ssh/config をフィルタリングしてインベントリ情報を取得できたりします。

というわけで、エージェントレスが好きな皆様におかれましては是非ご利用ください。

以下余談

komaRuby製なのですが、awspecと同様にFukuoka.rbで作りました。

もともと「エージェントレスでohai」みたいなツールはずっと欲しかったのです。

ふとFukuoka.rbのSlackチャンネルでつぶやいたら、うずらさん が反応してくれてやる気になり、ひとりで作ろうとして途方に暮れていたら、やまださん が「Specinfraに Specinfra::HostInventory という求めている機能がある」というところを教えてもらって、一緒にSpecinfraを読んで、プロトタイプまで一気に作ることができました。

というわけでkomaは実はただの Specinfra::HostInventory の薄いラッパーです(一気に信頼度が上がった感。

とはいえ、 Specinfra::HostInventory を拡張しているところがあるので(user group package serviceのインベントリ情報。主にRedHat系しか作っていない)、最終的に拡張部分をSpecinfraに取り込んでもらうところまで頑張ろうと思っています(komaはそのためのユースケースでもある)。

Fukuoka.rb、最近仕事が忙しくて行けてないので、また消え去り認定されないようにまた参加したい。

PHPカンファレンス福岡2016に参加してきました | "ドキュメントを支える技術"

phpcon.fukuoka.jp

PHPカンファレンス福岡2016に運営メンバーとして参加しつつ、発表もしてきました。

あと、Fusicとしてゴールドスポンサーとして協賛させてもらいました!

ドキュメント=紙という話しをしました

ドキュメントというのは印刷が必要な時があって、すぐにOfficeを開くのもいいけれども、そのまえにプログラムで楽ができないか考えてみよう。そして、PHPは意外にも印刷へのアプローチに有効だよ。という話をしたかったのでした。

発表後、Excel系の話題( k1low/xlsxti.mefra.me )に感想が集中したのが予想外でした。皆さんも苦労しているんですね。。。

個人的には実は koma が1番の力作なので、また別エントリで紹介したいと思います。

運営の話し

ここらへんは他の人に譲ります。ちなみに運営も印刷係でした。紙づいています。

スポンサーの話し

いろいろ嬉しいこともあったのですが、会社としては「スポンサーして良かった」ということに決着していることをここに報告しておきます。

というわけで

皆さんお疲れ様でした!!!

CakePHP3にステートマシンなEnumの仕組みを組み込むStatefulEnumを作った

k1low.hatenablog.com

と、CakePHP3にEnumの仕組みを組み込んだのですが、

さらに、ActiveRecord::Enumにステートマシンの仕組みを組み込むgemが

github.com

「これは便利そう!!!全ての機能をポートするのは難しそうだけど、Enumで管理されているフィールドにステートマシンの制約を組み込むくらいはできるかも。」

ということで作ってみました。

github.com

使い方

基本的には https://github.com/k1LoW/property-enum と合わせて使ってもらうことを想定していますが、特に制限はありません。

<?php
class BugsTable extends Table
{
    const STATUS_UNASSIGNED = 'unassigned';
    const STATUS_ASSIGNED = 'assigned';
    const STATUS_RESOLVED = 'resolved';
    const STATUS_CLOSED = 'closed';

    public $transitions = [
        'status' => [
            'assign' => [
                'from' => self::STATUS_UNASSIGNED,
                'to' => self::STATUS_ASSIGNED
            ],
            'resolve' => [
                [self::STATUS_ASSIGNED, self::STATUS_UNASSIGNED], // from
                self::STATUS_RESOLVED // to
            ],
            'close' => [
                [self::STATUS_ASSIGNED, self::STATUS_UNASSIGNED, self::STATUS_RESOLVED],
                self::STATUS_CLOSED
            ],
        ]
    ];

    public function initialize(array $config)
    {
        $this->primaryKey('id');
        $this->addBehavior('StatefulEnum.StatefulEnum');
    }
}

上記のように $transitions を設定することでフィールドのBugsTable.statusのステートマシンの仕組みを組み込みます。 amatsuda/stateful_enumtransition の制約だけを実現した形になります(メソッドまではない)。

これだけでもシンプルにステートマシンを定義できるので便利かと。

というわけで

機能追加のプルリクなどお待ちしております。

CakePHP3でもActiveRecord::Enumを使いたいので、CakeDC/EnumベースでPropertyEnumを作った

k1low.hatenablog.com

CakePHP2では GitHub - k1LoW/Enumm: Enumm: Enum(model) plugin for CakePHP を作って使っていたのですが、CakePHP3では動きません。

CakePHP3で使える同じようなPluginを探して、CakeDC/Enum を見つけたのですが、CONSTベースとConfigureベース、データベースのテーブルベースしかありませんでした。

というわけで、Enummと同じようにプロパティベースで動くようにCakeDC/Enumにストラテジを追加する形でPropertyEnumを作りました。

github.com

使い方

Tableに $enums プロパティを設定して、 ['strategy' => 'property'] することでCakeDC/Enumの他のストラテジと同じように利用可能です。

<?php

class ArticlesTable extends Table
{
    public $enums = [
        'status' => [
            'public' = 'Published';
            'draft' = 'Drafted';
            'archive' = 'Archived';
        ],
    ];

    public function initialize(array $config)
    {
        $this->addBehavior('PropertyEnum.Enum', ['lists' => [
            'status' => [
                'strategy' => 'property',
            ]
        ]]);
    }
}

AutoSetComponent

Enummの時と同様に $enums をViewに自動でsetしたいときは PropertyEnum\AutoSetComponent を読み込むことで可能です。

<?php
namespace App\Controller;

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('PropertyEnum.AutoSet');
    }
}

というわけで

CakePHP3でも気楽にEmunを使えるようになりました。

CakePHP3でもバリデーションをパターンでまとめられるようにPatternableValidatorを作った

CakePHP3になって、CakePHP2では MultivalidatableBehavior などで実現していたバリデーションのルールセットの切り替えがコア機能に入りました。これはうれしい。

ただ、Kagasawa-sanが作っていたcakeplus/ValidationPatternsBehavior.php で実現していたバリデーションのパターンの設定はコア機能ではできなかったので作ってみました。

github.com

Before

<?php
namespace App\Model\Table;

class UsersTable extends AppTable
{
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->allowEmpty('username')
            ->add('username', 'minLength4', [
                'rule' => ['minLength', 4],
                'message' => __('Validation Error: minLength4'),
            ])
            ->add('username', 'maxLength10', [
                'rule' => ['maxLength', 10],
                'message' => __('Validation Error: maxLength10'),
            ]);

        $validator
            ->allowEmpty('password');
    }
}

After

<?php
namespace App\Model\Table;

class UsersTable extends AppTable
{
    public function validationDefault(Validator $validator)
    {
        $validator
            ->addPattern('id', ['integer', 'allowEmptyWhenCreate']);

        $validator
            ->addPattern('username', ['allowEmpty', 'username_length']);

        $validator
            ->appPattern('password', ['allowEmpty']);
    }
}

非常にスッキリしますね。

使い方

AppTableなどで、以下のように_validatorClassを変更して、あとはcakeplus/ValidationPatternsBehavior.phpと同じように、バリデーションのパターンを登録していけばOKです。

<?php
namespace App\Model\Table;

class AppTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);
        $this->_validatorClass = '\PatternedValidator\Validation\Validator';
        \PatternedValidator\Validation\Validator::$validationPatterns = [
            'username_length' => [
                'minLength4' => [
                    'rule' => ['minLength', 4],
                    'message' => __('Validation Error: minLength4'),
                ],
                'maxLength10' => [
                    'rule' => ['maxLength', 10],
                    'message' => __('Validation Error: maxLength10'),
                ]
            ],
        ];
    }
}

これで多くなりがちなバリデーションライフもバッチリです。

というわけで、私のCakePHP3 Plugin生活、スタートです!