IBM Cloud IAM対応のためのtips

# はじめに
現在IBM Cloud上のWatson APIは認証方式が順次IAM方式に移行されつつあります。
しかし、その場合どうすればいいかの情報が少ないです。。。
その対策としての自分用の備忘録を投稿しておきます。
中身はFAQ形式で書いていきたいと思います。

(2018-09-06 FAQ追記)

# コマンドラインが使えないけれどどうすればいいの
従来のCFコマンドの代替となるのは ``ibmcloud`` コマンドです。
ダウンロードは[ibm cloud download](https://console.bluemix.net/docs/cli/reference/ibmcloud/download_cli.html#install_use)から行って下さい。

#  ibmcloudコマンドのオプションは
ログインは 

```$ ibmcloud login```

で行います。
この他のオプションは

```$ ibmcloud help```

で確認して下さい。

(2018-08-17追記)
CFコマンドとの対応表を作ってみました。
[チートシート ibmcloud vs CF コマンド対応表](https://qiita.com/makaishi2/items/cd9caf36336c71a67f25)

# IAM方式で作ったWatsonサービスをCloud Foundryのアプリケーションとバインドできない
何を隠そう、私が一番悩んだのがこのことです。
これが最善の方法かどうかは不明ですが、とりあえず見つかった対応策がこちら。

まず、次のコマンドで、Watsonサービスの名称を確認します。

```
$ ibmcloud resource service-instances
名前                            場所       状態     タイプ             タグ   
Cloud Object Storage-gj         global     active   service_instance      
COS-20180322-1                  global     active   service_instance      
watson-vision-combined-sh       us-south   active   service_instance      
Watson Studio-ng                us-south   active   service_instance      
ibmanalyticsengine-tz           us-south   active   service_instance      
pm-20-fs                        us-south   active   service_instance      
language-translator-if          us-south   active   service_instance      
```

例えばこの中の``pm-20-fs``をCloud Foundryアプリから利用したい場合、以下のエイリアス定義を行います。

```
$ ibmcloud resource service-alias-create  pm-20-fs --instance-name pm-20-fs
```

これで、例えば次のような cf servicesコマンドで作ったサービスがちゃんと見えるようになります。

```
$ cf services
名前                             サービス                         プラン                           バインド済みアプリ                                  最後の操作
(途中略)
pm-20-dm                         pm-20                            lite
pm-20-fs                         pm-20                            lite 
```

あとは、いつものように ``cf bind-service``コマンドで、Cloud Foundry アプリと作ったサービス(pm-20-fs)のバインドを行うことが可能です。

# APIを呼び出すときのCredentailsはどうなるの
アプリケーションからWatson APIを呼び出すときは、developers-cloudのライブラリを利用することをお勧めします。そうすることで、認証に関する実装のややこしいところは隠蔽されて、次のように簡単な変更で済むようになります。

インスタンスを生成する際、従来の引数は**version**, **username**, **password**だったのですが、IAM方式の場合、これが**version**, **iam_apikey**に変わります。
(後者は通常エンドポイントURLもデフォルトから変更になるので、これもセットと考えていい)

## Node.jsの場合

### 従来

```
var DiscoveryV1 = require('watson-developer-cloud/discovery/v1');

var discovery = new DiscoveryV1({
    version: '<version_date>',
    username: '<username>',
    password: '<password>'
  });
```

### IAM対応版

```
var DiscoveryV1 = require('watson-developer-cloud/discovery/v1');

const discovery = new DiscoveryV1({
    version: '<version-date>',
    url: '<service_url>',
    iam_apikey: '<iam_api_key>'
});
```

## Pythonの場合

### 従来

```
from watson_developer_cloud import DiscoveryV1

discovery = DiscoveryV1(version='2017-10-16', 
      username='<username>', 
      password='<password>')
```

### IAM対応版

```
from watson_developer_cloud import DiscoveryV1

discovery = DiscoveryV1(version='2017-10-16',
                        iam_api_key='<iam_api_key>')
```

# Node-REDから使う場合はどうしたらいいか
上で説明した(**username**, **password**)から(**iam_apikey**, **endpoint_url**)にcredential用パラメータのセットが変わるという考えは同じです。
画面については、別記事 [IBM Cloudの基本 -サービスの作成から資格情報の取得まで-](https://qiita.com/makaishi2/items/43622db769d6a7e9b560) に載せましたので、こちらを参照して下さい。

# curlコマンドから使う場合はどうしたらいいか
今回の変更に伴い、内部的には
* APIキーからトークンを発行
* トークンを引数に本当のAPIを呼び出す
ということが行われるようになりました。
上に説明したようにライブラリやNode-RED経由でアクセスすると、この挙動の違いはわからないのですが、curlコマンドの場合はもろに影響してしまいます。
頑張ればできなくはないのですが、IAMサービスに対してはcurlコマンドは極力使わないことがお勧めです。
私も、昨年はcurlコマンドでテストということを結構行っていましたが、今はテストはすべてWatson Sudio上のJupyter Notebook + Python3で実行するようにしています。

# どのサービスがIAM化されているの？
現在移行中なので、日々変化していきますが、2018-09-06時点での調査結果は以下の通りです。
(Watsonサービスに限定)

**米国東部**: 全サービスIAM化済みです。
**シドニー**: NLCを除いてIAM化済みです。

**Knowledge Catalog, Knowledge Studio, Machine Learning, VR, Watson Studio**
全サイトでIAM化済みです。

**Language Translator**: 英国を除いてIAM化済みです。