ConoHa PHPからAPIでDNSドメインとレコードを追加


# 概要
ConoHaのDNSに、APIからドメインの追加とレコードの追加します。
APIはPHPから呼び出します。

# 経緯
ConoHaのDNSに新規にドメインを追加する際、Google Apps の MXレコードをすべて登録したかったのですが、ConoHaコントロールパネルから一つずつ登録するのは手間でした。
そのためAPIを使って一括で登録できるようにしてみました。

# APIでトークンを取得
APIを利用する際は必ずトークンを取得する必要があります。

```php
/**
 * トークン取得
 * @param string $options
 */
function getToken($options = null)
{
	$url = API_IDENTITY_SERVICE . "/tokens";

	$headers = array(
		"Accept: application/json"
	);

	$req_data = array(
		"auth" => array(
			"passwordCredentials" => array(
				"username" => API_USERNAME,
				"password" => API_PASSWORD
			),
			"tenantId" => API_TENANT_ID
		)
	);

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($req_data));
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	$res_json =  curl_exec($ch);
	$res_data = json_decode($res_json);
	curl_close($ch);

	return $res_data;
}

// トークン取得
$tokens = getToken();
$token = $tokens->access->token->id;
```

# APIでドメインを追加

```php
/**
 * ドメイン生成
 * @param unknown $token
 * @param unknown $domain
 * @param string $options
 * @return mixed
 */
function createDomain($token, $domain, $options = null)
{
	$url = API_DNS_SERVICE . "/v1/domains";

	$headers = array(
		"Accept: application/json",
		"Content-Type: application/json",
		"X-Auth-Token: {$token}"
	);

	$req_data = array(
		"name" => $domain["name"],
		"ttl" => 3600,
		"email" => $domain["email"],
		"gslb" => 0
	);

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($req_data));
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	$res_json =  curl_exec($ch);
	$res_data = json_decode($res_json);
	curl_close($ch);

	return $res_data;
}

// 登録するドメイン
$reg_domain_names = array(
	array("name" => "example.com.", "email" => "dummy@example.com")
);

foreach ($reg_domain_names as $reg_domain_name) {
	// ドメイン登録
	$domain = array(
		"name" => $reg_domain_name["name"],
		"email" => $reg_domain_name["email"]
	);
	$res = createDomain($token, $domain);
}
```
# APIでレコードを追加

先ほどドメイン登録したAPIのレスポンスで、登録したドメインのIDが取得できるので、それを使ってレコードを追加していきます。

```php
/**
 * ドメインレコード登録
 * @param unknown $token
 * @param unknown $id
 * @param unknown $record
 * @param string $options
 * @return mixed
 */
function createRecord($token, $id, $record, $options = null)
{
	$url = API_DNS_SERVICE . "/v1/domains/{$id}/records";

	$headers = array(
		"Accept: application/json",
		"Content-Type: application/json",
		"X-Auth-Token: {$token}"
	);

	$req_data = array(
		"name" => $record["name"],
		"type" => $record["type"],
		"data" => $record["data"]
	);

	if (isset($record["priority"])) {
		$req_data["priority"] = $record["priority"];
	}

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($req_data));
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	$res_json =  curl_exec($ch);
	$res_data = json_decode($res_json);
	curl_close($ch);

	return $res_data;
}

// 登録するレコード
$reg_records = array(
	array("name" => null, "type" => "MX", "data" => "ASPMX.L.GOOGLE.COM.", "priority" => 1),
	array("name" => null, "type" => "MX", "data" => "ALT1.ASPMX.L.GOOGLE.COM.", "priority" => 5),
	array("name" => null, "type" => "MX", "data" => "ALT2.ASPMX.L.GOOGLE.COM.", "priority" => 5),
	array("name" => null, "type" => "MX", "data" => "ALT3.ASPMX.L.GOOGLE.COM.", "priority" => 10),
	array("name" => null, "type" => "MX", "data" => "ALT4.ASPMX.L.GOOGLE.COM.", "priority" => 10)
);

foreach ($reg_domain_names as $reg_domain_name) {
	// ドメイン登録
	$domain = array(
		"name" => $reg_domain_name["name"],
		"email" => $reg_domain_name["email"]
	);
	$res = createDomain($token, $domain);

	$id = $res->id;

	// レコード登録
	foreach ($reg_records as $reg_record) {
		if (!$reg_record["name"]) {
			$reg_record["name"] = $reg_domain_name["name"];
		}
		$res = createRecord($token, $id, $reg_record);
	}
}
```

# 確認

ConoHaコントロールパネルで登録したDNSが表示されていればOKです。
NSレコードの設定が終わっていればdigコマンド等で確認します。

```bash
$ dig example.com mx

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> example.com mx
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14439
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 10

;; QUESTION SECTION:
;example.com.               IN      MX

;; ANSWER SECTION:
example.com.        3600    IN      MX      5 alt1.aspmx.l.google.com.
example.com.        3600    IN      MX      10 alt3.aspmx.l.google.com.
example.com.        3600    IN      MX      1 aspmx.l.google.com.
example.com.        3600    IN      MX      10 alt4.aspmx.l.google.com.
example.com.        3600    IN      MX      5 alt2.aspmx.l.google.com.

;; ADDITIONAL SECTION:
alt1.aspmx.l.google.com. 0      IN      A       74.125.25.26
alt1.aspmx.l.google.com. 0      IN      AAAA    2607:f8b0:400e:c03::1a
alt3.aspmx.l.google.com. 0      IN      A       74.125.193.27
alt3.aspmx.l.google.com. 0      IN      AAAA    2607:f8b0:4002:c07::1a
aspmx.l.google.com.     0       IN      A       64.233.188.27
aspmx.l.google.com.     0       IN      AAAA    2404:6800:4008:c05::1b
alt4.aspmx.l.google.com. 0      IN      A       173.194.219.27
alt4.aspmx.l.google.com. 0      IN      AAAA    2607:f8b0:4002:c08::1b
alt2.aspmx.l.google.com. 0      IN      A       64.233.169.26
alt2.aspmx.l.google.com. 0      IN      AAAA    2607:f8b0:4001:c05::1b

;; Query time: 318 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Sun Sep 27 18:53:14 2015
;; MSG SIZE  rcvd: 371
```

# サンプルプログラム
GitHubにて公開しています。
https://github.com/yubaxp/sample/blob/master/php/conoha_dns.php