ConoHaのSafari機能拡張を作ってみた


## ConoHa

[ConoHaはGMOの提供するVPSサービスです。](https://www.conoha.jp/referral/?token=6IpeNJWhys7SWe5_lqoE1ADW4scMpMwY0tt8Yb9yHZHjRVpNGxw-NVP)すべてストレージはSSD、課金も時間単位で、月額の場合でもCPU1GBで900円〜なので、円安もありDigitalOceanを使うよりオススメでは！と勝手に思っています。また、オブジェクトストレージ、DB、メールがVPSとは別に構成できるのも特徴です。

[APIを使ってFirefoxアドオンを作ってみた](https://www.conoha.jp/conoben/archives/10061)

この記事に刺激され、Safariの機能拡張なら前に少しやった事があるのでやってみようと思ってしまったのでした。

## まずは出来上がりから

![safari-conoha.png](https://qiita-image-store.s3.amazonaws.com/0/14768/cd9d233b-233d-c864-77f3-81abec4cb7b8.png "safari-conoha.png")

デザインは元のアドオンと同じです。

ソースコードは以下においておきます。
https://github.com/bellx2/safari-conohavps


バイナリー版（署名済み）は以下の場所からダウンロードできます。
https://github.com/bellx2/safari-conohavps/releases/download/v1.5/Conoha.safariextz

※ダウンロードしたファイルを開くとインストールできます。

## 解説

### まずは解析

[ConoHa My VPS - Firefox Addon](https://github.com/ysworks/furefox-addon_conoha-my-vps)

Firefox Addon-SDKを使っているので見た目「なんじゃこりゃ？」と思ったのですが、じーっと見ているとなんとなく理解できました。

まずは、pannel.htmlをベースに始めます。micro-template.jsのテンプレート埋め込んでいる模様。コードはmain.jsとpannel.jsにあり、pannel.jsはテンプレートへの適用部分が入っているので、この辺りも一気にmain.jsに統合する方向で決定。

Firefoxアドオン関連をコメントアウトしてとりあえずHTMLが表示される状態から、ちょこちょこ変更していきます。

細かい部分はAPIドキュメントをみながら研究。
https://www.conoha.jp/docs/

### Popoverの起動

popoverページを指定するとボタンを表示するだけで呼ばれてしまうようなので、EventListenerを設定してボタンが押された時に動くようにします。

```
safari.application.addEventListener("popover", popoverHandler, true);

function popoverHandler(event){
	...ここにメインの処理。toke→情報取得→更新...
}
```

### APIユーザーとパスワードの記録

Firefox版はフォームを使っていますが、Safariの機能拡張の設定パネルを使った方がお手軽なのでそちらにします。

![Settings.png](https://qiita-image-store.s3.amazonaws.com/0/14768/3b897c87-5e41-c48d-ce69-81f2afbe4d33.png "Settings.png")

設定項目を追加するとキー名称で値が取得できます。

```
apiUserName = safari.extension.settings.apiUserName;
apiPassword = safari.extension.settings.apiPassword;
```

セットはSafari→環境設定→機能拡張→ConoHaから設定します。

※「セキュリティ保護された設定」でうまく値が取得できないようだったので調査中です。

### JQueryでTokenの取得

JQuery.ajaxのpostで取得するように書き換えます。

```
    $.ajax({
        type:"post",
        url:"https://identity." + region + ".conoha.io/v2.0/tokens",
        data:JSON.stringify({ auth: { passwordCredentials: { username: apiUserName, password: apiPassword }, tenantName: tenantId } }),
        contentType : "application/JSON",
        dataType: "JSON",
        success: function(data){
            token[region] = data.access.token;
            onSuccess();
        },
        error: function(response){
            showAuthError();
        }
    });
```

参考：[ConoHa API トークン発行](https://www.conoha.jp/docs/identity-post_tokens.html)

### サーバー詳細の取得

JQuery.ajaxのgetで取得します。X-Auth-Tokenをヘッダーに含めます。

```
    $.ajax({
        type:"get",
        url: "https://compute." + region + ".conoha.io/v2/" + token[region].tenant.id + "/servers/detail",
        contentType : "application/JSON",
        headers: {"Accept": "application/json", "X-Auth-Token": token[region].id},
        dataType: "JSON",
        success: function(data){
            vpsList(data,region);
        },
        error: function(response){
            if(response.status == 401){
                GetToken(region, function(){
                    GetServers(region, ++retry);
                });
            }else{
                showAuthError();
            }
        }
    });
```

参考：[ConoHa API VM一覧詳細取得](https://www.conoha.jp/docs/compute-get_vms_detail.html)

こんな要領で書き換えていきます....。

ついでなので、再起動/停止をできるようにコードを追加しました。また、VMのステータス情報の表示も追加してみました。

```
    $.ajax({
        type:"post",
        url: "https://compute." + region + ".conoha.io/v2/" + token[region].tenant.id + "/servers/" + uuid + "/action",
        headers: {"Accept": "application/json", "X-Auth-Token": token[region].id},
        data: '{ "reboot": { "type": "SOFT" } }',
        contentType : "application/JSON",
        dataType: "JSON",
        statusCode: {
            202: function(){
                alert("再起動します");
            },
            401: function(){
                GetToken(region, function(){
                    DoServerAction(region, uuid, type, ++retry);
                });                
            }
        }
	});
```

再起動はこのような感じ。成功時のレスポンスコードが200ではなく202で返ってくるので、statusCodeで振り分ける感じにしてみました。

参考：[ConoHa API VM一再起動](https://www.conoha.jp/docs/compute-reboot_vm.html)

### コード署名

SafariにインストールするにはAppleの開発者証明書が必要です。ADCに入っていればFreeメンバーでも作れたと思います。

### その他気づいた部分

+ Safari Popoverはhtmlが「targert="_blank"」になっていると飛ばない
+ Popoverの背景色のデフォルトが灰色

## ごにょごにょ

### 気が向いたらToDo

+ セキュリティ保護された領域のデータ保存/取得
+ 電源操作時の確認ダイアログ
+ VM操作無効時のレイアウトの空白
+ Alertダイアログをなんとかする
+ ステータスの「シャットダウン中」の取得
+ レスポンスコード対応（現在は全部認証エラー）
+ Safari機能拡張ライブラリーへ登録

### リンクについて

[ConoHa](https://www.conoha.jp/referral/?token=6IpeNJWhys7SWe5_lqoE1ADW4scMpMwY0tt8Yb9yHZHjRVpNGxw-NVP)へのリンクは「お友達紹介」用コードが含まれています。新規登録の場合は1000円分のクーポンが付与されるそうですので、ご活用ください。