2018年1月31日水曜日

mineo.jp のメールを Mac の mail.app で見る方法

概要

Mineo に登録すると mineo.jp ドメインのメールアドレスが 1 つもらえます
Mac の mail.app でも普通にメールの送受信ができるので設定方法を紹介します

環境

  • macOS 10.13.2
  • mail.app 11.2 (3445.5.20)

アカウントの追加を開く

mail.app を開いたら

メール -> 環境設定 -> アカウント

と進みます

mineo_mail1.png
左下に「+」があるので選択しましょう

mineo_mail2.png
その他のメールアカウントを選択して次に進みます

mineo.jp のアカウント情報を入力する

新規メールアカウント登録画面になるのでメールアドレスとパスワードを入力します
ここで入力するアドレスとパスワードは Mineo から払い出されたものを使いましょう
メールアカウントとパスワードは Mineo のマイページから「ご契約内容照会」で確認できます
mineo_mail3.png

一旦サインインしましょう
たぶんエラーになり受信メールサーバと送信メールサーバを設定する画面になるので入力していきます

  • アカウントの種類 -> IMAP
  • 受信用メールサーバ -> imaps.mineo.jp
  • 送信用メールサーバ -> smtps.mineo.jp

mineo_mail4.png

これで再度サインインするとメールサーバにログインできメールの送受信ができるようになります

動作確認

こんな感じでメールが表示されると思います
メールサーバ側に残っているメールのみ受信できるのでサーバから削除されているメールは受信できません
mineo_mail5.png

最後に

mail.app で mineo.jp のメールを受信する方法を紹介しました
IMAP と SMTP が設定できるメールソフトであれば何でも受信できると思います

2018年1月30日火曜日

Ruby で Amazon ECS (Advertising API) をサクっと使ってみる

概要

Amazon ECS (ECommerceService) はショッピングサイトの Amazon の情報を検索することができる API です
今回は Ruby から API をコールして商品情報を取得してみました

環境

  • macOS 10.13.2
  • Ruby 2.4.1p111
  • amazon-ecs 2.5.0

ライブラリインストール

  • bundle init
  • vim Gemfile
gem "amazon-ecs"
  • bundle install --path vendor

Nokogiri のインストールでこける場合は以下のコマンドを実行後、再度 bundle install してください

  • brew install libxml2
  • bundle config build.nokogiri --use-system-libraries --with-xml2-include=$(brew --prefix libxml2)/include/libxml2

必要な情報の取得

AWS のアクセスキー/シークレットアクセスキーおよび Amazon アソシエイト用のトラッキング ID を取得します

アクセスキーの取得

https://affiliate.amazon.co.jp/assoc_credentials/home にアクセスして「認証キーを管理する」を選択します
advertising_api1.png

すると AWS の認証画面になるので Amazon アソシエイトにログインした ID/PW でログインします
ログインが完了すると IAM と呼ばれる AWS のアカウントを管理する画面になるので、そこで「アクセスキー (アクセスキー ID とシークレットアクセスキー) 」を選択します
すでにキーがあればそれを使っても OK ですがない場合は作成してください
ここで表示されるアクセスキーとシークレットアクセスキーは忘れないようにしましょう
シークレットアクセスキーはこの画面からは確認できないので忘れると再発行する必要があります
advertising_api2.png

トラッキング ID の取得

トラッキング ID は商品したのがどのアカウントか紐付けるための情報です
Amazon アソシエイトにログインして上段のアカウントから「トラッキング ID の管理」を選択します
advertising_api3.png

するとトラッキング ID の一覧が表示されます
まだない場合は新規で作成すれば OK です
advertising_api4.png

サンプルコード

  • vim test_ecs.rb
require 'amazon/ecs'

Amazon::Ecs.configure do |options|
  options[:AWS_access_key_id] = 'your access key'
  options[:AWS_secret_key] = 'your secret key'
  options[:associate_tag] = 'traking ID'
end

res = Amazon::Ecs.item_search(
  'figma',
  :response_group => 'Large',
  :search_index => 'All',
  :country => 'jp'
)

res.items.each do |item|
  puts item
end
  • bundle exec ruby test_ecs.rb

すると XML がづらーっと表示されます
デフォルトだと 10 件分取得できるようです
例えばタイトルと価格を取得したい場合は以下のようにします

res.items.each do |item|
  puts item.get('ItemAttributes/Title')
  puts item.get('ItemAttributes/ListPrice/Amount')
end

またアフィリエイトリンクを生成する場合は以下のようにするとできるようです

res.items.each do |item|
  puts item.get('DetailPageURL')
end

検索に関するオプション :response_group に関して指定できる値はこちらを参照してください
また、:search_index に関してはこちらを参照してください

503 You are submitting requests too quickly. Please retry your requests at a slower rate. 対応

これは単純にリクエストしすぎだよーというエラーになります
公式を見ると 1req/1sec まで OK とあるようですが、その間隔でリクエストすると当然のようにエラーになります
詳細な理由はわかりませんがエラーが発生する場合は 1 分ほどおいてからリクエストすると良いと思います

最後に

Ruby で Amazon Advertising API を試してみました
試すのは非常に簡単かなと思います
ただ頻繁に 503 エラーが発生するのでむしろ 503 エラーと格闘する時間のほうが長いかなと思います

参考サイト

2018年1月29日月曜日

VMware Admiral で API を使ってテンプレートを docker-compose.yml としてエクスポートする方法

概要

Admiral は作成したテンプレートをエクスポートできる機能があります
管理画面からはテンプレートの一覧でエクスポートボタンを押せば YAML ファイルがダウンロードできます
API でも取得することができたのでその方法を紹介します

環境

  • Ubuntu 16.04.3
  • Admiral v1.3.0

API でテンプレートを取得する

docker-compose.yml を取得する場合はこんな感じでコールします

  • curl -H 'localhost:8282/resources/composite-templates/?selfLink=/resources/composite-descriptions/877dd4190ad5dc75563935eeacdb0&format=docker'

877dd4190ad5dc75563935eeacdb0 の部分はテンプレートの ID を入力してください
これで以下のような YAML 情報がテキストで取得できます

---
version: "2"
services:
  web:
    image: "registry.hub.docker.com/library/nginx"
    restart: "no"

上記のテンプレートは nginx イメージで作成したコンテナ定義を 1 つ追加した場合の YAML になります
ちなみにユーザ認証を有効にした場合は x-xenon-auth-token ヘッダを付与してコールしてください

また最後の format=docker を外すとテンプレート自体の定義をエクスポートすることができます
エクスポートした定義は Admiral 上にインポートすることでテンプレートとして使うことができます

最後に

Admiral でテンプレートから docker-compose.yml をエクスポートする方法を紹介しました
結構便利な機能かなと思います
ただ docker-compose のバージョンが 2 までしか対応してないのでバージョン 3 以上に対応する場合は取得したあと自分でコンバートする必要があります

参考サイト

2018年1月26日金曜日

ruby の RestClient でクエリストリング中に配列を含める方法

概要

前回 curl を使ってクエリストリング中に配列を入れてサーバに送信しました
今回は ruby の RestClient を使って配列を送信してみました

環境

  • maxOS 10.13.2
  • Ruby 2.4.1p111
  • RestClient 1.8.0

curl

以下の curl でのリクエストを RestClient からもやってみたいと思います

リクエスト

  • curl 'localhost:4567/?Hoge[]=hoge1&Hoge[]=hoge2' --globoff

レスポンス

hoge1 hoge2

RestClient

RestClient でやる場合はこんな感じです

  • vim app.rb
require 'rest-client'

query = '/?Hoge[]=hoge1&Hoge[]=hoge2'
ret = RestClient.get "localhost:4567#{query}"

puts ret

これで curl と同じ結果を取得することができます
文字列でクエリストリングを作成して、それをそのまま URI 中に含めているだけです
文字列として扱うので若干面倒なケースもありますがシンプルな方法かなとは思います

params: を使って送信することもできるのですがハッシュで宣言する必要がありキーが重複してしまうため 1 つしか値を送信することができません

p = {
  :params => {
    'Hoge[]' => 'hoge1',
    'Hoge[]' => 'hoge2',
  }
}
ret = RestClient.get 'localhost:4567', p

これだと hoge2 だけしか送信してくれません

最後に

RestClient で配列を送信する方法を紹介しました
POST や PUT であればリクエストボディを設定できるのでそっちで配列なりを送信してあげれば OK です

今回は GET + クエリストリングの場合に配列を送信する方法を紹介しました

2018年1月25日木曜日

VMware Admiral で docker-compose 的なことをしてみる

概要

VMware Admiral には docker-compose 的なことを実現するためにテンプレートという機能があります
今回はテンプレートを使った複数コンテナの起動方法を紹介します

環境

  • Ubuntu 16.04.3
  • docker 17.12.0-ce
  • Admiral v1.3.0

プロジェクトの作成

Admiral にはデフォルトで「default-project」というプロジェクトが用意されています
今回はそのプロジェクトを使って薦めます
なので、プロジェクトは必要であれば作成してください

作成の仕方は

管理 -> プロジェクト -> プロジェクトの追加

から新規でプロジェクトを作成できます

クラスタの登録

次にクラスタを登録しましょう
クラスタの登録には docker host or VCH が必要になります
今回は事前に Ubuntu 上に docker をインストールし tcp でのリモートコントロールを有効にしました

追加するには左メニューから

インフラストラクチャ -> クラスタ -> 新規

から追加できます
admiral_docker_compose1.png

テンプレートの登録

とりあえず空のテンプレートを作成しましょう
左メニューから

ライブラリ -> テンプレート -> テンプレートの作成

で好きな名前を入力しましょう
とりあえずこれで作成できれば OK です
admiral_docker_compose2.png

コンテナ定義の追加

テンプレートが作成できたらその中にコンテナ定義を追加していきましょう
docker-compose 的なことがしたいのでコンテナ定義はそれぞれのコンテナ分作成します
そして今回は redis + golang で書かれた Web アプリを作成したいと思います

redis

まずは redis イメージを使ってコンテナ定義を追加します
作成したテンプレート tpl1 を選択して「コンテナ追加」を選択しましょう
admiral_docker_compose3.png

次のイメージの選択です
Admiral ではデフォルトで DockerHub で公開されているイメージを検索することができます
「redis」で検索すると公式の redis イメージが表示されるのでそれを選択しましょう
admiral_docker_compose4.png

すると更にコンテナ定義の詳細を設定する画面になります
ここは所謂 docker-compose.yml に定義する link や volume、環境変数などを設定する画面になります
redis の定義では 1 つだけ設定を追加します

ネットワーク -> ホスト名

に「redis」と入力しましょう
これを設定することで別のコンテナからホスト名 redis で参照することができるようになります
admiral_docker_compose5.png

あとは「追加」すれば OK です

memo

今度は golang の Web アプリのコンテナ定義を追加します
先ほどと同様にコンテナの追加を選択しましょう
admiral_docker_compose6.png

イメージはこれを使います
該当のイメージを検索して選択しましょう
admiral_docker_compose7.png

そしてコンテナ定義の詳細設定です
まず先ほど作成した redis とリンクさせます

基本 -> リンク-> サービス

で事前に作成しておいた redis 定義を選択します
ちなみにタグですが今回のイメージに ver_golang があるのでこれを選択します
admiral_docker_compose8.png

次のコンテナホスト上で LISTEN するポートを設定します

ネットワーク -> ポートバインド

でホストポートを 80 番にしコンテナポートを 8080 番にします
Web アプリ側はホスト名の設定は不要です
admiral_docker_compose9.png

更に環境変数を設定します
今回の Web アプリは redis の URI を環境変数で設定できるので、そのための環境変数を設定します

環境 -> 環境変数

で名前に REDIS_URL を入力し値に redis://redis:6379/0 と入力します
admiral_docker_compose10.png
これで Web アプリ側の設定は完了です
「追加」で定義を作成しましょう

プロビジョニングする

tpl1 を選択すると作成した 2 つの定義があると思います
このページの右上にプロビジョニングがあるので選択してみましょう
すると作成したコンテナ定義の情報を元にクラスタ上にコンテナを作成してくれます
admiral_docker_compose11.png

動作確認

しばらくするとプロビジョニングが完了します
左メニューのコンテナを選択するとプロビジョニングしたコンテナの一覧が表示されます
admiral_agent はクラスタとして追加したホスト上に必ず作成されるコンテナになります
admiral_docker_compose12.png

memo 側のコンテナを選択するとアプリの URL にアクセスできるのでちゃんとアプリが起動しているか確認してみましょう
admiral_docker_compose13.png

ちなみに追加したクラスタ内のコンテナホストで docker ps を実行するとちゃんとコンテナが起動していることがわかります

CONTAINER ID        IMAGE                        COMMAND                  CREATED              STATUS              PORTS                     NAMES
c9be7f0cff40        kakakikikeke/memo:latest     "/bin/sh -c 'bundle …"   About a minute ago   Up About a minute   0.0.0.0:80->8080/tcp      memo-mcm410-65242387561
e4107fe01381        redis:latest                 "docker-entrypoint.s…"   4 minutes ago        Up 4 minutes        0.0.0.0:32769->6379/tcp   redis-mcm409-65242385176
cad21f08519f        vmware/admiral_agent:1.3.0   "/bin/bash /entrypoi…"   2 hours ago          Up 2 hours          0.0.0.0:32768->4200/tcp   admiral_agent

最後に

VMware Admiral で docker-compose のように複数のコンテナを一度に立ち上げて Web アプリを構築してみました
docker-compose.yml の情報を Admiral に移植するだけなので、すでに docker-compose で動作するものがあれば簡単に Admiral 上で動かすことができると思います

Admiral ではイメージのビルドまでは行えないので作成したイメージは今回のように事前に Dockerhub で公開しておきましょう

いきなりこっちで docker-compose の定義を作成することも可能ですが、まずは手元で docker-compose.yml を作成して Admiral に移植すると良いと思います

Admiral を使うメリットしては

  • コンテナがダウンしたときに自動で新しいコンテナを作成してくれる
  • 最低起動コンテナ数を指定することができ、その数までは自動でスケールアウトしてくれる
  • コンテナホストを追加すれば swarm のようなクラスタが簡単に組める

あたりかなと思います

2018年1月23日火曜日

Sinatra で 500 エラーをハンドリングする方法

概要

前回 not_found を使ってルーティングしていないパスのエラーハンドリングをしました
今回は予期しないエラーが発生したときにすべてのエラーをハンドリングすることができる方法を紹介します

環境

  • macOS 10.13.2
  • Ruby 2.4.1p111
  • Sinatra 2.0.0

サンプルコード

  • vim error.rb
require 'sinatra'
set :show_exceptions, false

get '/' do
  raise
end

error do
  'error'
end

これでアクセスするとクライアント側にはステータスコード 500 で error という文字列だけが返ります
サーバ側には Ruby のエラースタックトレースが表示されます
set :show_exceptions, false これを指定しないとクライアント側にもエラースタックトレースが表示されてしまい本来返却したいレスポンスボディにならないので必ず設定してください

サンプルコード2

  • vim error2.rb
require 'sinatra'
require './my_class.rb'

set :show_exceptions, false

get '/' do
  mc = MyClass.new
  mc.error
end

error do
  'error'
end
  • vim my_class.rb
class MyClass
  def error
    a = nil
    a.each {}
  end
end

MyClass では必ずエラーが発生します
これを Sinatra のコントローラ側でコールしてもちゃんと error が拾ってくれます

最後に

Sinatra で 500 エラーをハンドリングしてみました
とりあえずこれを入れておけば Ruby のエラースタックトレースが返ることはなくなると思います

参考サイト

2018年1月21日日曜日

Sinatra でリクエストヘッダを取得する方法

概要

ボディやクエリストリングは params で取得できます
ヘッダは少し変わった方法でアクセスするのでやり方を紹介します

環境

  • macOS 10.13.2
  • Ruby 2.4.1p111
  • Sinatra 2.0.0

取得方法

  • vim app.rb
require 'sinatra'

get '/' do
  headers = request.env.select { |k, v| k.start_with?('HTTP_') }
  headers.each do |k, v|
    puts "#{k} -> #{v}"
  end
  'ok'
end

こんな感じです
request.env にいろいろと突っ込まれておりその中の HTTP_ から始まる変数がヘッダ情報になります
試しにこれで動かしてヘッダを適当に付与してみると付与したヘッダが出力されると思います

もともとは Sinatra は Rack ベースで作られているのでそれの Rack::Request を使って取得している感じです