オブジェクトの継承


序文

この文書ではオブジェクト継承とテンプレートベースオブジェクト定義について説明したいと思います。

テンプレートベースの設定データのサポートを追加しようと思った一番のモチベーションの1つには、 他のオブジェクト定義からさまざまなプロパティをオブジェクト定義に簡単に継承させることが出来るように したかったということです。オブジェクトプロパティの継承はNagiosが設定ファイルを処理するときに再帰的に処理されます。

もしこのドキュメントを読んでも再帰と継承の働き方について理解できないままであれば、ディストリビューション内にあるサンプルのテンプレートベース設定ファイルを見ると良いでしょう。さらにサンプルファイルが理解の助けにならなければE-Mailで理解できない箇所の詳細nagios-usersメーリングリストに投げてください。

基本

全オブジェクト定義内に再帰・継承に影響のある3つの変数があります。それらは以下の通りです・・・。

	define someobjecttype{
		object-specific variables ...
		name		template_name
		use		name_of_template_to_use
		register	[0/1]
		}

最初の変数はnameです。単純に他のオブジェクト定義から参照される"テンプレート"の名前です。したがってオブジェクトのプロパティ/値を継承することが出来ます。テンプレート名は同じタイプのオブジェクトの中で一意のものでなくてはなりません。つまりホスト定義のテンプレート名に、"hosttemplate"という名前は複数設定できません。

2つ目の変数はuseです。これはプロパティ/変数を受け継ぎたいテンプレートオブジェクトの名称です。ここで指定した名称は他のオブジェクトのテンプレート名のように決定しなくてはなりません(name変数を使用します)。

3つ目の変数はresisterです。この変数はNagiosでこのテンプレートが"レジスト"されるべきかどうかを示すために使用します。デフォルトでは、全オブジェクト定義はレジストされます。もしあるオブジェクト定義をテンプレートとして使いたい場合は、レジストしないようにします(後に例を挙げます)。設定する値は次の通り:0 = オブジェクト定義として登録しない、1 = オブジェクト定義として登録する(デフォルト)。

ローカル変数 vs. 継承された変数

継承について理解するための1つの重要なことは、"ローカル"オブジェクト変数がテンプレートオブジェクトに定義された変数より常に優先されるということです。次に挙げる2つのホスト定義の例を見てみましょう(すべての必要な変数が表示されているわけではありません):

	define host{
		host_name		bighost1
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	5
		name			hosttemplate1
		}

	define host{
		host_name		bighost2
		max_check_attempts	3
		use			hosttemplate1
		}

ホストbighost1用の定義はテンプレート名、hosttemplate1 が定義されていることに注意してください。ホストbighost2の定義は、そのテンプレートオブジェクトとしてbighost1の定義を使用しています。このデータをNagiosが処理したら、ホストbighost2の定義の結果は、次の定義と同等になるでしょう:

	define host{
		host_name		bighost2
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	3
		}

check_commandnotification_options変数が(ホストbighost1で使用されている)テンプレートオブジェクトから継承されている事が分かるでしょう。しかしながらhost_namemax_check_attempts変数はテンプレートオブジェクトから継承されていません。というのは、それらはローカルで定義されているからです。つまり、ローカルで定義された値は通常テンプレートオブジェクトから継承される値を上書きします。実にわかりやすいコンセプトです。

継承の連鎖

オブジェクトは、テンプレートオブジェクトの複数のレベルからのプロパティ/変数を継承することができます。以下に例を挙げます:

	define host{
		host_name		bighost1
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	5
		name			hosttemplate1
		}

	define host{
		host_name		bighost2
		max_check_attempts	3
		use			hosttemplate1
		name			hosttemplate2
		}

	define host{
		host_name		bighost3
		use			hosttemplate2
		}

ホストbighost3の定義はホストbighost1から継承されている変数を含むホストbighost2から変数を継承されていることに注意してください。Nagiosがこの設定データを処理すると、結果的に次のホスト定義と同じようになります:

	define host{
		host_name		bighost1
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	5
		}

	define host{
		host_name		bighost2
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	3
		}

	define host{
		host_name		bighost3
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	3
		}

継承できるレベルの"深さ"には制限がありませんが、メンテナンス性という意味で各自で数レベルに制限したほうが良いでしょう。

不完全なテンプレート定義の使用

他のオブジェクト定義に不完全なオブジェクト定義をテンプレートとして使用することが可能です。"不完全な"定義とはオブジェクト定義内でそれがオブジェクトとして必要なすべての変数を設定していないという意味です。テンプレートとして不完全な定義を使用すると言うことは奇妙に思えるかも知れませんが、実際には使用することを推奨しています。それはなぜか?それは、不完全な定義が他のすべてのオブジェクト定義のデフォルトとして使用することができるかも知れないからです。次に例を見てみましょう:

	define host{
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	5
		name			generichosttemplate
		register			0
		}

	define host{
		host_name		bighost1
		address			192.168.1.3
		use			generichosthosttemplate
		}

	define host{
		host_name		bighost2
		address			192.168.1.4
		use			generichosthosttemplate
		}

1つ目のホスト定義はhost_name変数が無いため不完全な定義になっていることに注目してください。このホスト定義を総括的なテンプレートとして使用したいのでhost_nameは設定する必要がありません。Nagiosに通常のホストとして登録しないようにするために、register変数を0にしています。

ホスト bighost1bighost2の定義は総括的なホスト定義の変数を引き継いでいます。唯一上書きしている値はaddress変数です。これが意味しているのは、両ホストともhost_nameaddress変数を除いてすべてのプロパティを使用していると言うことです。この例の設定データをNagiosが処理したら、ホスト定義の結果は次のものと同等になります。

	define host{
		host_name		bighost1
		address			192.168.1.3
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	5
		}

	define host{
		host_name		bighost2
		address			192.168.1.4
		check_command		check-host-alive
		notification_options	d,u,r
		max_check_attempts	5
		}

少なくとも、デフォルト値の設定のためにテンプレート定義を使うことは設定に必要なキータイプ回数をかなり少なくすることができます。同様に多数のホストのデフォルト値を変更したい場合に頭を悩ますことも無くなりますよ。