目次


クラウドをポケットに入れて持ち歩く

第 2 回 仮想マシンをオーダーして構成する

仮想サーバーをモバイル端末でオーダーして構成できるようにアプリケーションを拡張する

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: クラウドをポケットに入れて持ち歩く

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:クラウドをポケットに入れて持ち歩く

このシリーズの続きに乞うご期待。

この全 2 回からなる連載では、HTML5、CSS、および JavaScript/jQuery によるユーザー・インターフェースを介して SoftLayer サーバーを管理するためのアプリケーションの作成方法を学びます。第 1 回では、モバイル端末に仮想サーバーに関する情報を表示して管理する方法を説明します。第 2 回では、モバイル端末上でサーバーをオーダーして構成する方法を説明します。

製品パッケージ

SoftLayer では、そのオファリングを製品パッケージにまとめて提供しています。使用可能な製品パッケージについて調べるには、以下のコマンドで SoftLayer API を呼び出してください (以下のコマンドは、本来 1 行で入力するコマンドですが、読みやすくするために複数行で示されています)。

curl 'https://<user>:<api-token@api.softlayer.com/rest/v3/
SoftLayer_Product_Package/getAllObjects?objectMask=id;name'|json_reformat

このチュートリアルで必要となるのは、製品 ID 46 のクラウド・サーバーです。オブジェクト・マスクを使用することで、クラウド・サーバー製品パッケージに関する詳細な説明を取得することができます。

curl 'https://<user>:<api-token@api.softlayer.com/rest/v3/
   SoftLayer_Product_Package/46?objectMask=capacity;prices.id;categories'|json_reformat.

図 1 に、この製品パッケージの構造を示します。

図 1. 製品パッケージの構造

最上位レベルは、description などいくつかの属性を持つ「製品パッケージ (Product Package)」です。「カテゴリー (Category)」は、クラウド・サーバーのオプションと見なすことができます。典型的なオプションの例には、CPU、RAM、ディスク、そしてオペレーティング・システムやネットワーク・アドレス (インターフェース) などがあります。仮想ゲストには、オプションとして他の項目 (保険オプションや、監視オプションなど) を含めることもできます。

各カテゴリーには、そのオプションの選択肢を表す値のリストがあります。SoftLayer の REST API では、これらの値を「価格 (price)」と呼んでいます。例えば、「CPU」カテゴリーの値のリストには、「1 x 2 GHz コア」、「2 x 2 GHz コア」、「4 x 2 GHz コア」などがあります。「RAM」カテゴリーの場合は、「1 GB」、「2 GB」、「4 GB」などの値があります。これらの選択肢のそれぞれには、時間料金と月額料金が付記されています。

各価格には一意の価格 ID があり、この ID が特定のカテゴリーの特定の値を指しています。例えば、25 GB の SAN ディスクを識別する価格 ID は 2202 であり、CentOS 6.x - LAMP Install (32-bit) を識別する価格 ID は 13940 です。

サーバーは、カテゴリー (またはコンポーネント) のセットによって定義されており、それぞれのセットは具体的なオプションの選択肢に関連付けられています。カテゴリーの中には、値の選択肢をグループ化しているものもあります。例えば、オペレーティング・システムは「Centos」、「CloudLinux」、「Debian」、および「others (その他)」としてグループ化されています。

サンプル・モバイル・アプリケーションのページ・シーケンス

オーダー・プロセスまたはアップグレード・プロセスのページ・シーケンスは、以下のとおりです。

製品のオーダー・プロセス

「Cloud Computing Instance (クラウド・コンピューティング・インスタンス)」(SoftLayer での仮想マシンの呼称) をオーダーするには、SoftLayer_Container_Product_Order_Virtual_Guest データ型の必須属性に値を入力する必要があります。これらの属性には、以下のものがあります。

  • ホスト名
  • ドメイン名
  • 完全修飾ドメイン名
  • データ・センターの場所
  • サーバーの構成を説明する価格 ID のリスト

製品のアップグレード・プロセス

仮想サーバーをアップグレードする場合は、オーダー・プロセスよりも注意が必要になります。それは、SoftLayer API では構成の変更とメタデータの変更を区別するためです。構成の変更とは、仮想サーバーのコンポーネントに対する変更を意味します。一方、ホスト名などの変更は、メタデータの変更として分類されます。

クラウド・コンピューティング・インスタンスの構成を変更するには、以下に記載する SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade データ型の必須属性に値を入力する必要があります。

  • 仮想サーバー ID
  • 新しいサーバー構成を説明する価格 ID のリスト

これで、サーバーのオーダー・プロセスのコーディングに取り掛かることができます。

独自のサーバーを作成する

実行可能な項目が表示されたページから、オーダー・プロセス用の新規 jQuery Mobile ページにリンクするには、製品パッケージの定義を取得する必要があります。このアクションには時間がかかるため、最初のオーダー・ページには、データを取得中であることを通知する静的テキストが表示されます。

サーバーの構成には 2 つのページがあります。最初のページには仮想サーバーのカテゴリーのリストが表示され、2 番目のページで、特定のカテゴリーのいずれかの値を選択するという形です。サーバーを構成するには、この 2 つのページ間を交互に切り替える必要があります。

この 2 つのページによって currentConfiguration と呼ばれるオブジェクトが作成されます。このオブジェクトのメンバー名は、製品パッケージの categoryCode となり、アプリケーション・ユーザーが選択した価格オブジェクトが値として関連付けられます。アプリケーション・ユーザーが前のページに戻らずに値を選択するごとに、次のステージとしてその時点までの選択内容が検証されます。検証結果が正常だった場合、ユーザーはその新規サーバーのオーダーを確定することができます。

カテゴリーの選択ページ

製品パッケージが正常に取得されると、カテゴリーのリストが作成されます。ただし、API から提供されるカテゴリーを表示するには、いくつかの準備作業が必要になります。

カテゴリーの数は比較的多い一方、モバイル端末の表示スペースは限られているため、カテゴリーのオーダーをしたり、カテゴリーの区分けをしたりするための適切な方法を見つけなければなりません。製品パッケージには packageConfigurations というメンバーが含まれています。カテゴリーを構造化するには、この配列の最初の要素を使用します。

まず、packageConfigurationsorderStep メンバーを基準にカテゴリーのリストをオーダーします。同じ orderStep が 2 つある場合は、sort メンバーを使用して、カテゴリーのオーダーをさらに具体的に確定します。リスト 1 を参照してください。

リスト 1. JavaScript: パッケージのソート・アルゴリズム
package.categories.sort(function (a, b) { 
   var s = (a.packageConfigurations[0].orderStepId - b.packageConfigurations[0].orderStepId); 
   if (s != 0) return s; 
   return (a.packageConfigurations[0].sort - b.packageConfigurations[0].sort); 
});

2 番目の基準として、カテゴリーを Mandatory グループと Optional グループに分けます。リスト 2 に、カテゴリーのページ・コードを記載します。

リスト 2. HTML: カテゴリー・ページ
<div id="ciap-change-server-categories-main" role="main" class="ui-content">
   <div data-role="collapsible" data-mini="true">
      <h3>Mandatory</h3>
      <ul id="ciap-change-server-categories-mandatory-list" data-role="listview" ></ul>
   </div>
   <hr/>
   <div data-role="collapsible" data-mini="true">
      <h3>Optional</h3>
      <p><ul id="ciap-change-server-categories-optional-list" data-role="listview" ></ul></p>
   </div>
</div>

それぞれのカテゴリーは、isRequired 属性に基づいて、対応するリストに追加されます (リスト 3 を参照)

リスト 3. JavaScript: カテゴリーに応じた <select> を入力する
var mlist = $('#ciap-change-server-categories-mandatory-list');
var olist = $('#ciap-change-server-categories-optional-list');
for (i in package.categories) {
   var name = package.categories[i].name;
   if (package.categories[i].packageConfigurations[0].isRequired) {
      var h="<li><a href='#' onclick='ciap.onConfigItem(" + i + ")'>" + name + "</a></li>";
      mlist.append(h);
   } else {
      olist.append(h);
   }
}

リスト要素をクリックまたは押すと、onConfigItemメソッドが呼び出されます。この場合、カテゴリーのインデックスが引数になります。このページはまだ、currentConfigration オブジェクトを変更しないので、画面は図 2 と図 3 に示すような表示になります。

図 2. カテゴリーの選択: 「Mandatory (必須)」および「Optional (オプション)」カテゴリー
図 3. カテゴリーの選択: 「Mandatory (必須)」カテゴリー

項目値の選択ページ

このページは、選択されたカテゴリーに含まれる prices 配列構造に基づいて作成されます。選択可能なオプションはリストとして提供されます。リストの値としては、stringfy() メソッドによって price オブジェクトを JSON の文字列に変換して得られた optval が表示されます。この配列構造を使用すると、<select>.val() メソッドによって必要なすべての情報を取得して、currentConfiguration オブジェクトを作成するのが簡単になります。

このアプリケーションでは、ナビゲーションを容易にするために、パッケージ製品でのグループをそのまま使用しますが、jQuery Mobile を使用して、HTML <option> タグのリスト内に仕切りを挿入することができます。

値を必要としないカテゴリーの場合、オプション・リストの先頭に、価格 ID を -1 に設定した none 値を追加します (リスト 4 および 5 を参照)。こうしなかった場合には、アプリケーション・ユーザーは何かを選択せずにページから抜けることができなくなります (-1 の ID 値は、後で currentConfig から要素を削除するために使用します)。

リスト 4. HTML: カテゴリーの値を対象とした <select>
<div id="ciap-change-server-items-page" data-role='page'>
   <div id="ciap-change-server-items-main" role="main" class="ui-content">
      <labelid='ciap-change-server-items-label'>Select your option
      <select id="ciap-change-server-items-select"></select>
      </label>
   </div>
</div>
リスト 5. JavaScript: カテゴリー値に応じた <select> を入力する
var cat = currentPackage.categories[id];
   var categoryCode = cat.categoryCode;
   var html = cat.packageConfigurations[0].isRequired ?
               "" : "<option value='{\"id\": -1}'>none</option>";
   for (var g in cat.groups) {
      var grp = cat.groups[g];
      if (grp.title || false) {
         html += "<optgroup label='" + grp.title + "'>";
      }
      for (p in grp.prices) {
         var price = grp.prices[p];
         var hr = price.hourlyRecurringFee || 0;
         var mth = price.recurringFee || -0;
         var txt = price.item.description + " $" + hr + "/hr $" + mth + "/mth";
         var id = price.id;
         price.categoryCode = categoryCode;
         var optval = JSON.stringify(price); //.replace(/\"/g, "'");;
         html += "<option value='" + optval + "'>" + txt + "</option>";
      }
      if (grp.title || false) {
      html += "</optgroup>";
   }
}
select.html(html).selectmenu('refresh');

図 4 に、カテゴリーの値 (価格項目) が取り込まれたリストを示します。

図 4. 値の選択: ディスク・ストレージ

ユーザー・インターフェースが更新されたら、アプリケーション・ユーザーはいずれかのオプションを選択することができます。図 5 を参照してください。

図 5. 値の選択: オペレーティング・システム

アプリケーション・ユーザーが値を選択すると、変更リスナー onConfigSelect が呼び出されて、currentConfiguration オブジェクトに変更が加えられます (リスト 6 を参照)。

リスト 6. JavaScript: カテゴリー値の変更を処理する
var select = $('#ciap-change-server-items-select');
var val = select.val(); // json string with category and price id
var selection = JSON.parse(val);
if (selection.id > 0) {
   currentConfiguration[selection.categoryCode] = selection;
} else {
   delete currentConfiguration[selection.categoryCode];
}
thiz.updateSummary();

上記のコードで、値が -1 の価格 ID が関与してきます。ユーザーが none を選択した場合、それに関連付けられたエントリーを currentConfig オブジェクトから削除しなければならないためです。

変更リスナー onConfigSelect が終了する直前に、ユーザーにサマリーが表示されます。したがって、アプリケーション・ユーザーは自分が何を購入しようとしているのかを常に把握することができます。

オーダーを把握する

構成フェーズにいる間は、オーダーした項目のサマリーと価格が表示されるため、アプリケーション・ユーザーはオーダーを把握することができます。オーダーした項目のサマリーは単純なテーブルになっています。最初の行に項目名が示され、2 行目と 3 行目には時間料金と月額料金が示されます (リスト 7 を参照)。

リスト 7. HTML: 構成サマリー・テーブルの定義
<label> Summary of your order
   <table style="font-size:x-small; widtH:100%;" >
      <thead>
         <th>Description</th>
         <th>Hourly Rate</th>
         <th>Monthly Rate</th>
      </thead>
      <tbody id='ciap-config-yourconfig'>
      <tbody>
   </table>
</label>

構成サマリーを作成するコードは currentConfiguration のメンバーを繰り返し処理して、関連する値を抽出します。リスト 8 を参照してください。

リスト 8. JavaScript: 構成サマリーを作成するコード
var summary = $('#ciap-config-yourconfig');
var i;
var toth = 0,totm = 0;
var html = "";
var template = "<tr>"+
         "<td style='text-align:left;'>{conf.item.description}</td>"+
         "<td style='text-align:right;'>${conf.hourlyRecurringFee}</td>"+
         "<td style='text-align:right;'>${conf.recurringFee}</td>"+
      "</tr>\n";
   for (i in currentConfiguration) {
      var conf = currentConfiguration[i];
      if (conf.recurringFee != 0 || conf.hourlyRecurringFee != 0 || true) {
      html += template.replace(/{[^}][^}]*}/g, function (s) {
         var e = s.replace(/[{}]/g, "");
         eval("r=" + e + "||''");
         return r;
      });
   }
   toth += 1 * (conf.hourlyRecurringFee || 0);
   totm += 1 * (conf.recurringFee || 0);
}
html += "<tr>"+
   "<td><b>total</b></td>"+
   "<td style='text-align:right;'>$" + toth + "</td>"+
   "<td style='text-align:right;'>$" + totm + "<//td>"+
   "</tr>";
summary.html(html);

場所とホスト名

新規サーバーの場所、ホスト名、ドメイン名の情報は、製品パッケージには含まれていないため、これらの項目を定義するための最後の構成ページを追加する必要があります。

これらの項目を処理するのは簡単で、データ・センターをオプションとして設定した HTML <select> タグを使用するだけのことです。データ・センターのリストは、アプリケーション初期化の一環として、アプリケーションの起動中に一度ロードされます。リスト 9 を参照してください。

リスト 9. HTML: データ・センターの場所とホスト名
<div role="main" class="ui-content" data-theme='a'>
   <div id='ciap-server-location-name'>
      <label> Location <select name="Location" id='ciap-order-location'/></label>
      <label>Hostname
         <input type="text" name="Hostname" id='ciap-order-hostname'/>
      </label>
      <label>Domainname
         <input type="text" name="Domainname" id='ciap-order-domainname'/>
      </label>
   </div>
</div>

for (i in thiz.datacenters) {
   var c = thiz.datacenters[i];
   html += "<option value='" + c.id + "'>" + c.longName + "</option>";
}

上記のコードにより、図 6 に示すような表示になります。

図 6. 場所とホスト名の指定

オーダーの検証および発行

SoftLayer API では、最終的なオーダーを発行する前に、オーダーを検証できるようになっています。それには、場所/ホスト名/ドメイン名の選択ページに、「Verify (検証)」ボタンを配置してください。「Verify (検証)」ボタンを押すと、onConfiguration メソッドが呼び出されます。このメソッドは、4 つのステップで SoftLayer_Container_Product_Order_Virtual_Guest を作成します。これらのステップは、以下のとおりです。

  • prices 配列を生成します。配列の各要素は、価格 ID を記述する JSON オブジェクトです (価格 ID は、仮想サーバーの構成項目を一意に定義することを思い出してください)。
  • 仮想ゲストの配列を作成します。この配列は、オーダーされたサーバーごとに 1 つの配列要素を格納します。配列要素には、ホスト名、ドメイン名、完全修飾ドメイン名からなる JSON オブジェクトが含まれます。
  • SoftLayer_Container_Product_Order_Virtual_Guest を作成し、有効なオーダーの必須メンバーを取り込みます。
  • 必須パラメーター MAINTANANCE_WINDOW を過去の日付にハード・コーディングします。こうすることで基本的に、オーダーが直ちに実行されます。

一例として、リスト 10 を参照してください。

リスト 10. JavaScript: オーダー・オブジェクトを作成する
var prices = [];
for (var i in currentConfiguration) {
   if (currentConfiguration[i].id) prices.push({
      "id" : currentConfiguration[i].id
   });
}
var vguest = new Array; ;
if (currentServer) {
   vguest.push({
      'id' : currentServer.id
   });
} else {
   vguest.push({
      'hostname' : $('#ciap-order-hostname').val(),
      'domain' : $('#ciap-order-domainname').val(),
      'fullyQualifiedDomainName' : $('#ciap-order-hostname').val() + "." + 
               $('#ciap-order-domainname').val()
   });

}
var order = {
   "properties" : [{
      "name" : "MAINTENANCE_WINDOW",
      "value" : "20000101"
   }],
   "packageId" : currentPackage.id,
   "complexType" : "SoftLayer_Container_Product_Order_Virtual_Guest",
   "virtualGuests" : vguest,
   "prices" : prices
};
var loc=$('#ciap-order-location').val();
if (loc) order.location=loc;

SoftLayer API で verifyOrder を呼び出します。検証結果に問題がなかった場合、finalizeConfiguration メソッドが呼び出されて、最終構成ページが表示されます。その構成をアプリケーション・ユーザーが承認する場合、オーダーを発行します。図 7 を参照してください。

図 7. 発注前の最終確認

サーバーの構成プロセス

ほとんどのところ、サーバーの構成プロセスはサーバーのオーダー・ステップと同じステップからなります。パターンに従うために変更が必要なコードは数行だけです。

それらの数少ない変更の 1 つは、サーバーの詳細ビューに、サーバーを構成するためのボタンを追加することです。このボタンをアクティブにすると、prepareConfigure メソッドが呼び出されます (リスト 11 を参照)。

リスト 11. HTML: サーバーの構成用のボタンを追加する
<fieldset data-role="controlgroup" data-type="horizontal" style='text-align:center;'>
   <input type="submit" id="ciap-server-function-pause"  data-icon="minus"   title="Pause"
         onclick="ciap.onServermanagement(this, 'pause')" function="pause
   <input type="submit" id="ciap-server-function-resume" data-icon="plus"    title="Resume"
         onclick="ciap.onServermanagement(this, 'resume')" function="resume">
	<input type="submit" id="ciap-server-function-config" data-icon="bullets" title="Configure"			onclick="ciap.prepareConfigure()" function="configure">
   <input type="submit" id="ciap-server-function-delete" data-icon="delete"  title="Destroy"
         onclick="ciap.onServermanagement(this, 'deleteObject')" function="finally destroy">
</fieldset >

サマリーを表示できるようにするには、実際のサーバー構成とその実際の価格が必要です。SoftLayer_Virtual_Guest サービスの getOrderTemplate メソッドは、実際の構成を取り込んだ製品テンプレートを返します。このメソッドはそこで見つかった値を引数に取って、currentConfiguration を作成します (リスト 12 を参照)。

リスト 12. JavaScript: 既存のサーバーの currentConfiguration を作成する
currentConfiguration = {};
for (var i in ordertemplate.prices) {
   var p=ordertemplate.prices[i];
   var catCode = p.item.itemCategory.categoryCode;
   var hr = p.hourlyRecurringFee;
   var mth=p.recurringFee;
   currentConfiguration[catCode]={ "recurringFee": mth, "hourlyRecurringFee": hr, "item": p.item };
}

構成プロセスは、最終的なオーダーを作成する前までは、オーダー・プロセスと同じです。

このアプリケーションでは、ユーザーがサーバーのホスト名やその他のメタデータに変更を加えることはできません。そのため、既存のサーバーが構成済みの場合は、場所とホスト名の入力フィールドと選択フィールドは非表示にされます (図 8 を参照)。

図 8. サーバーをアップグレードする場合は非表示にされる場所とホスト名

アップグレード・オブジェクトの型は SoftLayer_Container_Product_Order_Virtual_Guest_Upgrade であり、この型はオーダー構造の complexType メンバー内の値として反映されます。

"complexType" : "SoftLayer_Container_Product_Order_Virtual_Guest" + (currentServer ? "_Upgrade" : ""),

新規オーダーの場合は、オーダー・オブジェクトにホスト名/ドメイン名を含める必要があります。既存のサーバーの場合は、サーバー ID を指定する必要があります。リスト 13 を参照してください。

リスト 13. JavaScript: サーバーをアップグレードする場合のオーダー・オブジェクト内の変更
if (currentServer) {
   vguest.push({
   'id' : currentServer.id
   });
} else {
   vguest.push({
      'hostname' : $('#ciap-order-hostname').val(),
      'domain' : $('#ciap-order-domainname').val(),
      'fullyQualifiedDomainName' : $('#ciap-order-hostname').val() + "." + 
               $('#ciap-order-domainname').val()
   });
}

まとめ

SoftLayer API からのデータを使用して、モバイル端末上で SoftLayer API クラウド・サーバーを表示および管理するためのアプリケーションを作成する方法は、第 1 回で学びました。そして、今回のチュートリアルでは、新規サーバーをオーダーして構成する方法を学びました。作成したアプリケーションは、HTML5、CSS、JavaScript/jQuery をベースとしています。このアプリケーションは、皆さんそれぞれのニーズに合わせて拡張することができます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Mobile development, Cloud computing
ArticleID=995239
ArticleTitle=クラウドをポケットに入れて持ち歩く: 第 2 回 仮想マシンをオーダーして構成する
publish-date=01222015