ニフクラ ブログ

ニフクラやクラウドの技術について、エンジニアが語るブログです。

ニフクラスクリプトが Ruby に対応しました! (利用可能ライブラリのご紹介)

こんにちは、ニフクラエンジニアの d:id:tily です。
ニフクラスクリプトは、サーバーの構築・運用を一切せずに、サーバーサイドのスクリプトが実行できる機能です。 いわゆるサーバーレスサービスと呼ばれているものです。
本日 4/18(水) より、このニフクラスクリプトでプログラミング言語 Ruby が利用可能となりました。

概要や基本的な使い方については上記ヘルプをご参照いただくとして、この記事ではニフクラスクリプトの Ruby で利用可能な gem ライブラリについて、いくつかピックアップしてご紹介したいと思います。

スクリプトの基本形

ヘルプにも記載がありますが、ニフクラスクリプトの Ruby は Rack 互換の call メソッドを実装することになります。
下記のように env を受け取って適切に処理し、ステータスコード・HTTP ヘッダ・ボディを返却します。

require "cgi"

def call(env)
  params = CGI.parse(env["QUERY_STRING"])
  name = params["name"][0]
  [200, {"Content-Type": "text/plain"}, ["hello, #{name}\n"]]
end

コントロールパネル(以降コンパネ)からスクリプトを登録し、Query に {"name": "tily"} を指定して実行すると、このように表示されます。

f:id:tily:20180412171808p:plain

rack gem でリクエスト・レスポンスを抽象化

「基本形」のままでは env に保存された GET クエリ情報を取得したり、自分で Rack 互換なレスポンスを返却しなければならなく、少し不便です。
rack gem に含まれる Rack::Request / Rack::Response クラスを利用して、よりスマートにリクエスト・レスポンス情報を扱ってみましょう

require "rack"

def call(env)
  req = Rack::Request.new(env)
  res = Rack::Response.new
  res["Content-Type"] = "text/plain"
  res.write("hello, #{req.params["name"]}\n")
  res.finish
end

このように node.js + express.js での req / res オブジェクトのような感覚でプログラムを書くことができます。

httparty gem で HTTP リクエストを送る

httparty gem を利用することで、簡単に HTTP リクエストを送ることができます。
ここではチャットツール Slack の API をたたいて、チャンネルにメッセージを送信する例をご紹介します。

require "rack"
require "httparty"

SLACK_ENDPOINT = "https://slack.com/api/chat.postMessage"
SLACK_TOKEN = "<SLACK の API トークン>"
SLACK_CHANNEL = "<メッセージ送信先の Slack チャンネル>"
SLACK_USERNAME = "<Slack ボット名>"

def call(env)
  req = Rack::Request.new(env)
  res = Rack::Response.new

  text = "hello, #{req.params["name"]}"
  slack_res = send_slack_message(text)

  res["Content-Type"] = "application/json"
  res.write(slack_res.body)
  res.finish
end

def send_slack_message(text)
  HTTParty.post(
    SLACK_ENDPOINT,
    query: {
      text: text,
      channel: SLACK_CHANNEL,
      token: SLACK_TOKEN,
      username: SLACK_USERNAME
    }
  )
end

コンパネから実行すると下記のように表示され、 f:id:tily:20180412172107p:plain

Slack 上にもメッセージが送信されていることが分かります。

f:id:tily:20180412172118p:plain

前にサーバー不要! タイマー+スクリプトで定期処理を自動化の記事でもご紹介しましたが、タイマーと組み合わせて利用すると、なんらかの情報を定期的にチャンネルにつぶやくボットが簡単に作れます。

nokogiri gem でスクレイピング

ニフクラスクリプトの Ruby では XML/HTML データを簡単に扱うことができる nokogori gem も利用可能です。
上記で紹介した httparty gem と組み合わせれば、

  • HTTP リクエストで任意のページを取得
  • 取得したページをパースして必要な情報を取得

といった処理を行うことができます。

下記では、httparty でニフクラスクリプトの技術仕様ページを取得したあと、nokogiri で利用可能なモジュールの一覧を取得し、
さらに httparty で Slack チャンネルにつぶやくような処理を実現しています。

require "rack"
require "httparty"
require "nokogiri"

SLACK_ENDPOINT = "https://slack.com/api/chat.postMessage"
SLACK_TOKEN = "<SLACK の API トークン>"
SLACK_CHANNEL = "<メッセージ送信先の Slack チャンネル>"
SLACK_USERNAME = "<Slack ボット名>"
SCRIPT_SPEC_URL = "https://cloud.nifty.com/spec/script/"

def call(env)
  res = Rack::Response.new

  text = "Node modules available at NIFCLOUD Script:\n"
  node_modules = get_node_modules
  node_modules.each do |m|
    text << "* #{m}\n"
  end

  slack_res = send_slack_message(text)

  res["Content-Type"] = "application/json"
  res.write(slack_res.body)
  res.finish
end

def send_slack_message(text)
  HTTParty.post(
    SLACK_ENDPOINT,
    query: {
      text: text,
      channel: SLACK_CHANNEL,
      token: SLACK_TOKEN,
      username: SLACK_USERNAME
    }
  )
end

def get_node_modules()
  body = HTTParty.get(SCRIPT_SPEC_URL).body
  doc = Nokogiri::HTML(body.force_encoding("utf-8"))
  tds = doc.search("table.tbl-01 tr td[1]")
  tds.map {|td| td.text }
end

実行するとこのような感じで Slack にメッセージが送信されます。
これで、ニフクラスクリプトで利用可能なライブラリが増えたときに、すぐに気づくことができますね。

f:id:tily:20180412172208p:plain

なお、スクレイピングはサイト管理者に迷惑をかけないように注意して行うようにしましょう。

まとめ

以上、ニフクラスクリプトの Ruby で利用可能なライブラリについて、いくつかピックアップしてご紹介しました。
その他の利用可能ライブラリについては技術仕様のページをご参照ください。
興味を持たれた方は、ぜひRuby 対応のサーバーレスサービス、ニフクラスクリプトをお試しください! フィードバックもお待ちしております。

ニフクラ SDK for Python (Developer Preview) のご紹介

こんにちは、ニフクラエンジニアの d:id:tily です。
今回は、本日公開されたニフクラ SDK for Python (Developer Preview)について、簡単にご紹介いたします。

ニフクラ SDK for Python (Developer Preview) とは?

ニフクラ SDK for Python (Developer Preview) は、Python からニフクラ API を実行するための SDK です。
下記のような特徴があります。

  • ニフクラの複数サービスに対応 (Computing / RDB / NAS / Script)
  • 付属のデバッグ CLI でコマンドラインから動作確認が可能
  • AWS SDK JSON 互換によるデータ駆動の仕組みを採用

上記について詳しく見ていきましょう。

※なお、「Developer Preview」という名前の通り、実験段階の開発者プレビュー版です。いくつかご注意いただきたい点がございます。

  • 本番向けのクリティカルな用途では利用しないでください
  • 「指定できないリクエストパラメーターがある」「取得できないレスポンス項目がある」といった不具合は想定内のものです
  • 予告なく大幅な仕様を変更を行う可能性があります

ニフクラの複数サービスに対応

ニフクラ SDK for Python (Developer Preview)はニフクラの複数サービスの全 API (2017/11/13 時点) に対応しています。
現在対応しているサービスは下記の通りです。

  • ニフクラ Computing (サーバー・FW 等の操作 全 188 API)
  • ニフクラ RDB (DB サーバー等の操作 全 39 API)
  • ニフクラ NAS (NFS / CIFS 等の操作 全 12 API)
  • ニフクラ スクリプト (スクリプト実行 全 1 API)

これを使用することで、たとえば下記のように 1 つのライブラリで複数サービスを操作するようなプログラムを書くことが可能です。

import pprint

from nifcloud import session

pp = pprint.PrettyPrinter(indent=4)

print("########## Computing DescribeInstances の実行")
computing = session.get_session().create_client(
    "computing", region_name="jp-east-1"
)
res = computing.describe_instances()
pp.pprint(res)

print("########## RDB DescribeDBSecurityGroups の実行")
rdb = session.get_session().create_client(
    "rdb", region_name="jp-east-1"
)
res = rdb.describe_db_security_groups()
pp.pprint(res)

print("########## NAS DescribeNASInstances の実行")
nas = session.get_session().create_client(
    "nas", region_name="jp-east-1"
)
res = nas.describe_nas_instances()
pp.pprint(res)

print("########## Script ExecuteScript の実行")
script = session.get_session().create_client(
    "script"
)
res = script.execute_script(
    ScriptIdentifier="test.js", Method="GET"
)
pp.pprint(res)

また、上記スクリプトの実行方法については GitHub の README を、詳しいドキュメントについてはこちらをそれぞれご参照ください。

デバッグ用 CLI でコマンドラインから実行

nifcloud モジュールには、nifcloud-debugcli という名前のコマンドが付属しています。
簡易的な CLI となっており、コマンドラインから手軽に SDK を利用した API リクエストを実行することができます。
使い方は下記の通りです。(こちらも内部的には awscli を利用しています。)

## API キーとデフォルトリージョンの設定
$ export AWS_ACCESS_KEY_ID=<Your NIFCLOUD Access Key ID>
$ export AWS_SECRET_ACCESS_KEY=<Your NIFCLOUD Secret Access Key>
$ export AWS_DEFAULT_REGION=jp-east-1

## 利用可能なサービスの一覧を表示
$ nifcloud-debugcli help

## 指定されたサービスで利用可能な API の一覧を表示
$ nifcloud-debugcli computing help

## 指定されたアクションで利用可能なパラメーターの一覧を表示
$ nifcloud-debugcli computing create-key-pair help

## 実際にコマンドを実行 (下記は料金が発生しない SSH キー作成の API を実行しています)
$ nifcloud-debugcli computing create-key-pair --key-name foobar123 --password foobar123

AWS SDK JSON 互換によるデータ駆動の仕組み

ニフクラ SDK for Python (Developer Preview) は、AWS の各プログラミング言語 のSDK がサポートしているデータ駆動の仕組みに沿った形で作成されています。
たとえば botocore (AWS の Python SDK) には下記のように API リクエスト用の各種 JSON が同梱されていますが、

上記と同様の JSON を独自に用意し、botocore モジュールに渡すことでニフクラの API を実行することが可能になっています。

これにより、メンテナンスコストを最小限に抑え、SDK が API 自体のバージョンアップに迅速に対応していけると考えています。

まとめ

Python からニフクラ複数サービスの API を実行可能な、ニフクラ SDK for Python (Developer Preview) について簡単にご紹介しました。

今後は SDK 自体の品質を高めつつ、Computing / RDB / NAS / Script 以外のサービスに対応したり、 同じ JSON データを利用してPython 以外の言語に対応したりといったエンハンスを検討しております。

ご興味を持たれた方は、ぜひ一度 ニフクラ SDK for Python (Developer Preview) をお試しください! そして、GitHub の issue 等でフィードバックをいただけると非常にうれしいです。

NICを追加してみた(追加NIC機能)

コンピューティングのサービスに新たに加わった追加NICを使うと、サーバーにNICを追加することができます(名前のまんまですね)。これまではグローバルに1つ、プライベートに1つしかNICを使うことができなかったので、より複雑なネットワーク接続ができるサーバーを作ることができます。

追加NICにはいくつか制限がありますが、注意すべき点は以下の点でしょう。

  • ゾーンあたりの追加NICは40まで 
  • サーバーあたりの追加NICは6まで 
  • 同一のプライベートネットワークに追加NICを2つ以上接続できない 
  • IPアドレスの割り当ては通常のプライベートと同様 

特に4点目は作業効率を考えると、ルーター+DHCPサーバーの設定がほぼ必須になります。設定方法については以下の記事を参考に設定を行ってください。

プライベートLANにDHCPサーバーを作成する 

http://blog.pfs.nifcloud.com/privatelan_build_dhcpserver

追加NICの詳細は以下のページをご覧ください。

https://cloud.nifty.com/service/nic.htm

追加NICを利用する手順は以下の通りです。

  1. プライベートLAN+DHCPサーバーを準備する
  2. サーバーを作成する
  3. 追加NICを作成する
  4. 追加NICをサーバーに設定する

ここでは、手順1と2は省略します。

追加NICの作成

追加NICの作成は、コントローラーの「コンピューティング」から行います。

左側のメニューから「追加NIC」を選択します。「追加NIC作成」ボタンをクリックすると作成が行えます。追加NICを作成したいゾーンを選択し、そのゾーンにあらかじめ作成されているプライベートLANと、IPアドレスの割り当て方法を選択します。IPアドレスの割り当て方法は、サーバーにデフォルトで設定されているNICと同様です。動作の詳細については、前述した「プライベートLANにDHCPサーバーを作成する」のブログを参考にしてください。

f:id:sameshima_fjct:20171206153526p:plain 追加NICの作成画面

f:id:sameshima_fjct:20171206153549p:plain 追加NICのリスト画面

追加NICをサーバーに設定

作成した追加NICをサーバーに設定し、利用可能な状態にします。

起動中のサーバーに追加NICを割り当てることもできますが、サーバーの再起動が発生します。設定時に「再起動しない」という選択肢が増えています。以前からニフクラの中の人に「ネットワーク設定を変更すると絶対に再起動がかかるのは使いにくい」と言っておいた甲斐があったのでしょうか。地味ですが嬉しい変更ですね。

f:id:sameshima_fjct:20171206153556p:plain 追加NICの設定画面

サーバーを再起動すると、追加NICが使えるようになっています。

f:id:sameshima_fjct:20171206153630p:plain サーバーで3つのNICが動作している様子

f:id:sameshima_fjct:20171206155312p:plain 2つのプライベートLANに接続されている様子

ログインして確認

ログインして確認すると、以下のようにネットワークインターフェイスが3つになっています。

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether e8:17:fc:0a:d5:14 brd ff:ff:ff:ff:ff:ff inet 157.112.xxx.xxx/23 brd 157.112.107.255 scope global dynamic ens160

3: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether e8:17:fc:0a:6e:b6 brd ff:ff:ff:ff:ff:ff inet 10.132.2.184/18 brd 10.132.63.255 scope global dynamic ens192

4: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether e8:17:fc:0a:a1:8d brd ff:ff:ff:ff:ff:ff inet 192.168.0.2/24 brd 192.168.0.255 scope global dynamic ens224

これで2つのプライベートLANに跨がったサーバーなどを作ることができるようになりました。是非お試しください。

プライベートLANにDHCPサーバーを作成する

今回はニフティクラウドのプライベートLANにDHCPサーバーを用意して、サーバーに対するIPアドレスの割当を容易にする方法を解説します。

プライベートLANにDHCPサーバーが無いと、プライベートLANに接続したインターフェースのIPアドレスをゲストOSで手動設定する必要があります。プライベートLANに接続するサーバーの台数が多い場合、DHCPサーバーを用意する方がはるかに効率が良くなります。

続きを読む

【イベント】「ニフクラ エンジニア ミートアップ(交流会) 第四回」を開催(2017/10/11)

こんにちは、ニフティクラウドブログ編集部です。

毎回ご好評いただいている、エンジニア交流会のご案内です。

 「エンジニアにしか判らない悩みがある」  「他のエンジニアと技術交流をしてみたい」  「ニフティクラウドをもっと使いこなしたい」  「ニフティクラウドの中の人と話してみたい」

こういった方にぜひお越しいただきたいイベントです。 このブログのメインライターであり、OSC(オープンソースカンファレンス)の主催者でもある 日本仮想化技術株式会社の宮原徹氏がコーディネーターを務める、 エンジニアによるエンジニアのための交流会です。

続きを読む