Rso's Jotter

日々の開発の知見のメモやその他雑記

VPC内にあるAWS Elastic Search の kibanaをサクッと見たい時のメモ

掲題の対応をするためのメモを残しておきます。

とりあえず手っ取り早く見るためのものなので、ちゃんとした方法が他にもあって、 恒久的な方法としては全然向いていません。

前提

  • Elastic Search Service からインスタンスを立ち上げて、インスタンスはVPC内のPrivateな環境にある。
  • VPC内にSSHできる踏み台サーバがあって、インターネット -> 踏み台, 踏み台 -> ElasticSearchへの通信は空いている

上記のような環境がある時、SSHのポートフォーワーディングすればとりあえず見れるようになります。

手順

ElasticSearchのPrivate IPアドレスを得ます。

ここでは、踏み台サーバからping してみます。

 $ ping vpc-xxxxxxxxxxx.ap-northeast-1.es.amazonaws.com

 vpc-xxxxxxxxxxx.ap-northeast-1.es.amazonaws.com  (192.168.X.X) 56(84) bytes of data.

 -> 192.168.X.X が Private IP

SSH ポートフォワーディング して繋ぎます。

 $ ssh 踏み台サーバIP -L 8443:192.168.X.X:443

これで、 localhost:8443 が 192.168.X.X:443 へ転送されるようになります。

以下にアクセス

https://localhost:8443/_plugin/kibana

もちろん証明書のエラーは出ますが、見れることは見れます。

Kintoneを多少使ったので所感を書いておきます

自社の業務で一部Kintoneを使用していて、社内の事業転換に伴い、その業務が終了し、Kintoneもほぼほぼ役目を終えることになりました。

Kintone上で業務を2年ぐらい運用していましたが、そのなかでよいところ、つらいかゆいところなどをまとめておこうと思います。

Kintoneとは

f:id:rso:20191109222002p:plain

提供元のサイボウズはファストシステムと謳ってたりもしますが、いわゆるノンプログラミングシステムの一つで、ノンプログラミングシステムの中ではかなり学習コストが低い部類に入ると思います。

Kintoneではアプリと呼ばれる単位で管理、運用されますが、このアプリというのは、簡単に説明するのが難しいですが、1つのフォームとそれに関連するCRUDとデータストアがセットになったようなものです。 そしてこのアプリをマウス操作で簡単に作れる、という感じです。 私は自社の簡単な案件管理、見積作成、発注管理で一部Kintoneを使用していました。

Kintoneのよかったところ

GUI操作でさくっとフォームが作れる

これはKintoneの魅力の一つで、1つのフォームと簡単なマスタ参照で完結するものは、ちょっと慣れればプログラミング経験が無い人でもかんたんに作れます。プロトタイプの開発が早くできるだけでなく、一度作って運用に乗せれば、プログラミング経験が無い業務チームに運用を引き継げるということがとても良い利点です。

モバイルのビューも同時に作られる

モバイル対応しているので、作成したアプリを外出先など携帯でちょっと確認したい、という要望に応えられます。モバイルのビューが自動作られるのは良い点です。ただしサブテーブルなど、モバイルの表示適さない要素が多いと見づらくなります。

ユーザ管理、組織管理、アクセス制限, アクセス証跡 など一通り揃っている

システムを運用する上で必要な上記の権限制御などは、一通り揃っているので、特に不便はありませんでした。

Kintoneのつらいところ

アプリ間でのデータ連携が弱い

Kintoneは標準ではルックアップという他のアプリのデータを参照できる仕組みがあります。 これで事足りるような要件であればよいのですが、以下のようなときに辛さが出てきます。

  • データの参照元が更新されたとき、参照先のデータも更新したい(ルックアップでは参照時の値がコピーされるだけ)
  • 複数のアプリをまたがって複数の項目を取得したい(ルックアップを多段にすればできますが設定と運用がめんどくさくなります)

ルックアップでできないデータの更新はJavascriptを書けばできますが、プログラムの量が増えると後述の運用が大変になってきます。

実際、ルックアップ参照元が更新されて、参照元に更新が必要となった場合、データを一度CSVにエクスポートして更新してインポートし直すという作業を行っていました。

またデータの参照であればルックアップでなんとかできますが、アプリの更新結果を他のアプリに連携、というのは標準機能ではできません(Javascriptでカスタマイズすればいけます)

カスタマイズ用のプログラムを継続開発する仕組みが弱い

前述の問題でも挙げた、標準機能でできないことはJavaScriptでカスタマイズすればほぼほぼできるのですが、これに頼りすぎると運用保守が大変になります。

  • CI/CDのサポートが弱い。 コードを更新しても手動打鍵するという確認が通常なのでユニットテストを実行する仕組みがありません。やるとしたらpuppeteerを使って簡単なE2Eテストをデプロイ時に回すなどの仕組みを用意する必要があります。

コードもKintoneにはJavaScriptを登録するインタフェースが用意されているだけなので、そのままではES6のコードは動きません。自前でWebpackなどでトランスパイルしてからアップロードという仕組みを用意する必要があります。 自分はGithubでmasterに取り込まれたらCircle CI でWebpackビルドして、それをS3にデプロイして、それをkintoneが読み込むという方法を使っていました。

いずれにせよ、プログラムを本格的に継続保守していくとなると、自前でCI/CD環境を用意したりする必要があり、このあたりは正直つらくなってきます。

まとめ

よかったところ、つらいところはまだまだ他にもいっぱいあるのですが、だらだらと長くなりそうなので、 主な部分だけ記載しました。良いところ、辛いところを勘案して思ったのは、

  • 簡単なシステムを簡単に作るのはすごく適しているし、運用も楽。
  • 簡単かどうかの基準は、単一のアプリで完結する仕様かどうか。複数アプリでの連携が必要なものは、kintoneで簡単にはできない。
  • JavaScriptカスタマイズを使えばかなり色々できるが、それを前提にしない。最小限に留める。

といったところです。利用者と調整できるのであれば、kintoneに乗るように業務ロジックの方を簡単にしてもらう方が良いかもしれません。 さくっと作れてプログラミング経験がなくても運用できる長所をうまく活用できれば、とても重宝すると思います。

Auth0 で API から Username/Password認証でのトークン発行手順

Auth0でAPIからトークンを発行する方法を調査していて、ちょっとだけ手間だったのでその内容をメモしておきます。

背景

開発中のプロダクトで認証はAuth0を使用しているのですが、今ではフロントエンドのNuxt.jsで動いているAuth module上でWebからの認証オンリーだったのですが、バッチ処理の用途で、プログラム経由でアクセストークン(JWT)を取得する必要が発生しました。

そこでAPI経由でアクセストークン取得の方法を調べました。

調査内容

リファレンスを見ると、この辺りを使えば行けるようです。

POST /oauth/token https://auth0.com/docs/api/authentication?http#resource-owner-password

  • リソースオーナーのID/Passwordでトークン取得可能
  • client_secretは不要(Application Settingがらみ以外)

実施内容

上記のリファレンスを元に、以下のクエリを実行しました。

 curl -XPOST -H "content-type: application/json" https://#{auth-domain}.auth0.com/oauth/token -d '{"grant_type": "password", "client_id": "xxxxxx", "username": "test@example.com", "password": "hogehoge"}'

すると以下のエラーが帰ってきました。

{"error":"server_error","error_description":"Authorization server not configured with default connection."}

ちょっとこの内容だとよくわからなかったのですが、Webで調べると以下の記事が見つかりました。

https://community.auth0.com/t/how-to-authorize-user-with-email-password-from-server-code/7239

どうやら、 Default Directory なるものの設定がいるようです。 あまりよくわかっていないですが、これは認証の際にどのデータソースを使用するか、というような項目ように見えます。

f:id:rso:20191101191339p:plain
Auth0のSetting

で、この値を何に設定するのかすぐにわからなかったのですが、 Connection -> Database 以下の データベース名を入力すれば大丈夫でした。 (デフォルトだと Username-Password-Authentication)

f:id:rso:20191101191357p:plain
Defaut Directoryにこれを指定したらいけた

こちらに設定後再度 /oauth/token APIデトークン発行を叩くと、無事トークンを発行できました。

その後そのトークンでAPIアクセスしましたが、今度はJWTのissuer (iss)が違うと言ってエラーになりました。これはAuth0でカスタムドメインを使用していたのが原因でした。トークン検証する側のカスタムドメインのAUTH0_DOMAINを使用していて、トークン生成はデフォルトドメインに対してアクセスしていたのがよくない原因でした。 両方ともカスタムドメインにアクセスし、無事トークン発行できました。

所感

前の少し思ったんですが、Auth0はすごい便利で、認証の手間を限りなくゼロにするという思想はすごく良いと思うのですが、 Default DirectoryやDefault Audience の設定などを要求されると、結局は認証の仕組みを理解しないとつまづくなと思いました。 何も理解せずに使えるサービスはないと思いますが、Auth0の利用者に要求される知識水準がどのあたりなのか、気になりました。 (そして私は、その要求水準を満たしていない..)

MySQLの外部キー制約の付与でハマったのでメモ

長らく投稿できていませんでしたが、MySQLの外部キー制約の付与で予想以上にハマってしまってので 備忘のためメモを残しておきます。

説明の簡略化のため、簡単なテーブル構造に置き換えて説明します。

状況

以下のような2つのテーブルがあったとします。

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| organizations  |
| users          |
+----------------+

それぞれ、Stringのuuid をPrimary keyとしてもち、 usersはorganization_id を持てるようにしたいとします。

mysql> desc users;
+-----------------+--------------+------+-----+---------+-------+
| Field           | Type         | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| uuid            | varchar(255) | NO   | PRI | NULL    |       |
| name            | varchar(255) | YES  |     | NULL    |       |
| organization_id | varchar(255) | YES  |     | NULL    |       |
+-----------------+--------------+------+-----+---------+-------+

mysql> desc organizations;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| name  | varchar(255) | YES  |     | NULL    |       |
| uuid  | varchar(255) | NO   | PRI | NULL    |       |
+-------+--------------+------+-----+---------+-------+

外部キー制約をつけるため、以下のSQLを実行しました

ALTER TABLE users ADD CONSTRAINT fk_test_1 FOREIGN KEY(organization_id) REFERENCES organization(uuid);

ところが、以下のようにエラーが出てしまい、失敗しました。

 ERROR 1215 (HY000): Cannot add foreign key constraint

organizatons.uuid も users.organization_id も同じ varchar(255) なのに 何で失敗するんだ...!と 数時間悩んでしまいました。

結局、show create table で構造を見たら解決しました。

mysql> show create table users;
| users | CREATE TABLE `users` (
  `uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `organization_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
mysql> show create table organizations;
| organizations | CREATE TABLE `organizations` (
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `uuid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

なんと、charset が異なっていたのです。ですので、 同じカラムとして見なされず、外部キー制約でエラーとなっていたのでした。

背景

実はこれ、Railsのマイグレーション時に発生したエラーで、開発環境は今までオッケーでしたが、構築中の別環境のマイグレーションでのみ発生しておりました。Rails は 5系のどこかからデフォルトで utf8mb4を使用するようになっており、Railsのバージョンアップに起因してDefault charset も変わってしまったのが原因です。しかしその場ですぐ影響が出ず、異なる文字コードのテーブル間で外部キー制約を貼ろうとしたタイミングでエラー発生しました。

詳しい人から見たらすぐにわかる事象かもしれないですが、エラーメッセージからなかなか原因に行き着かず、結構悩んでしまったので、メモとして残しておきます。

2019年 Ethereum の Dapps開発を始める際の参考サイトまとめ

2019年8月時点において、EthereumのDappsの開発をやってみようとしたのですが、 その時に調べた内容や、参考にしたサイトや用語、コードなどをまとめておきます。

情報収集

Ethereum入門

CryptoZombies

  • Ethereumのコントラクトの開発言語であるSolidityのチュートリアル。 cryptozombies.io

Ethereum Pet shop (Truffleチュートリアル)

  • 自分のローカル環境でチェーンの構築やデプロイ、Web3JSを使用した実行まで学べます。 www.trufflesuite.com

Ethereum Pet shop 日本語訳

用語整理

以下が分かりやすくまとめられています。 qiita.com

上記の内容と重複しますがここでも少し記載します。

solidity

Ethereum の高水準開発言語。JavaScriptライクな記法となっています。

Truffle

スマートコントラクトの開発、テスト、デプロイ用フレームワークです。 このフレームワーク上でSolidityで書かれたコントラクトをコンパイル、デプロイできます。

環境構築

truffle インストール

 $ npm install -g truffle
 $ truffle version
Truffle v5.0.34 (core: 5.0.34)
Solidity v0.5.8 (solc-js)
Node v11.14.0
Web3.js v1.2.1

ganache

ローカルでEthereumチェーンの開発環境を立てたり、ローカルチェーン状での コントラクトの状況を確認できるツール。インストーラからインストールします。 www.trufflesuite.com

Metamask

イーサリアムのウォレット。chromeやFirefoxのPluginとしてインストールするタイプ。 ここに開発用のアカウントをインポートして使用します。 addons.mozilla.org

参考コード

Tuffle + Web3jsをしてフロントはNuxt.jsを使用しているコード

GitHub - Matsushin/dapps-nuxt-vote

Truffle で ERC721トークンの発行しているコード

GitHub - chuckbergeron/etherplate: 🔗 Use this to make your next Ethereum DApp w/ React (& Router), Redux, Bulma & OpenZeppelin ERC721

ただしこれらは2019/08現時点でライブラリ側に多くのBreaking chageがあるので、そのままでは動かず..

Nuxt.js + テスト用のコントラクトを実行するデモアプリケーション

フロントをNuxt.jsで実装したサンプルコントラクトアプリケーション。 文字列を書き込んで読み出すサンプルです。

GitHub - rsooo/nuxt-truffle-sample-app: Sample Application using Nuxt.js and Truffle