API 'maintenance.get' のバグらしき挙動について [2.0.x]

ややこしくて申し訳ありませんが、バグとして報告したいと思います
#本家バグデータベースへ報告したかったのですが、うまく表現できそうになかったため
#こちらへ投稿します。
#本家へ伝達いただければ、ありがたいです

発見したバージョン:2.0.9 (2.0.11 でも同コードだったので、おそらく改善されていないと思われます)
コンポーネント:frontend

api maintenance.get で、特定グループID、もしくは 特定ホストIDのリストを用いて絞込を掛けようとした場合
返却されるリスト内の各項目の、[groups] / [hosts] が空リストとなってしまうようです →★★★不具合★★★

また、グループで絞った場合とホストで絞った場合、グループ・ホストの両方で絞った場合の
返却リスト内容の差異について、疑問があります →★★★疑問点★★★

・前提条件:以下のようなメンテナンス設定が存在する時
メンテナンス1:group A (groupid=15) に対するメンテナンス
メンテナンス2:group B (groupid=16) に対するメンテナンス
メンテナンス3:host A (hostid=266) に対するメンテナンス (host A は group A に所属)

・実行結果
maintenance.get に、'selectGroups'='refer'、'selectHosts'='refer'を指定して API実行
maintenance.get に、'selectGroups'='extend'、'selectHosts'='extend'を指定して API実行
  →3件すべてがリストとして戻ってくる。
   戻り値の各項目内:
    メンテ1、メンテ2:
      'hosts' 要素:元データのとおり空リスト。
      'groups' 要素:対象グループに関するデータが意図したとおりに入っている
    メンテ3:
      'hosts' 要素:対象ホストに関するデータが意図したとおりに入っている
      'groups' 要素:元データのとおり空リスト。

maintenance.get に、'selectGroups'='refer'、'selectHosts'='refer'、'groupids'=[15]を指定して API実行
maintenance.get に、'selectGroups'='extend'、'selectHosts'='extend'、'groupids'=[15]を指定して API実行
  →メンテ1、メンテ3の2件がリストとして戻ってくる
   メンテ3が返ってくるのは hostAが groupAの所属ホストだからか?→★★★疑問点★★★
   戻り値の各項目内:
    メンテ1:
      'hosts' 要素:元データのとおり空リスト。
      'groups' 要素:空のリストとなってしまっている。戻り値から対象の特定不能 →★★★不具合★★★
    メンテ3:
      'hosts' 要素:対象ホストに関するデータが意図したとおりに入っている
      'groups' 要素:元データのとおり空リスト。

maintenance.get に、'selectGroups'='refer'、'selectHosts'='refer'、'hostids'=[266]を指定して API実行
maintenance.get に、'selectGroups'='extend'、'selectHosts'='extend'、'hostids'=[266]を指定して API実行
  →メンテ3のみ、1件がリストとして戻ってくる
   メンテ1が返ってこないのは、指定した hostA はgroupA の所属ホストだが、それも探せと指定されたわけではないからか?→★★★疑問点★★★
   戻り値の各項目内:
    メンテ3:
      'hosts' 要素:空のリストとなってしまっている。戻り値から対象の特定不能 →★★★不具合★★★
      'groups' 要素:元データのとおり空リスト。

maintenance.get に、'selectGroups'='refer'、'selectHosts'='refer'、'groupids'=[15]、'hostids'=[266]を指定して API実行
maintenance.get に、'selectGroups'='extend'、'selectHosts'='extend'、'groupids'=[15]、'hostids'=[266]を指定して API実行
  →メンテ1、メンテ3の2件がリストとして戻ってくる
   戻り値の各項目内:
    メンテ1:
      'hosts' 要素:元データのとおり空リスト。
      'groups' 要素:空のリストとなってしまっている。戻り値から対象の特定不能 →★★★不具合★★★
    メンテ3:
      'hosts' 要素:空のリストとなってしまっている。戻り値から対象の特定不能 →★★★不具合★★★
      'groups' 要素:元データのとおり空リスト。

★★★不具合★★★について
これらより、'selectHosts' / 'selectGroups' と 'hostids' / 'groupids' の指定状況が絡む不具合と判断して調べてみたところ
CMaintenance.php内:210行目付近

  // groupids
  if (!is_null($options['groupids'])) {
    $options['selectGroups'] = 1;
  }
  // hostids
  if (!is_null($options['hostids'])) {
    $options['selectHosts'] = 1;
  }

というコードを発見
これは、おそらく、以下のようにしないといけないのではないでしょうか?

  if (!is_null($options['groupids'])) {
   if (is_null($options['selectGroups'])) {
    $options['selectGroups'] = API_OUTPUT_REFER;
   }
  }
  if (!is_null($options['hostids'])) {
   if (is_null($options['selectHosts'])) {
    $options['selectHosts'] = API_OUTPUT_REFER;
   }
  }

selectGroups / selectHosts は「1」という値はその後の処理で正常に扱われません
「もし指定されていたら、指定内容を尊重、されていなかったら、デフォルト値としてreferを指定」
という動作が良いのではないかと思った次第です

★★★疑問点★★★
ホストグループ指定のみで絞り込んだ場合には、当該グループが対象とされているメンテナンス情報だけでなく、
当該グループに所属しているホスト単体に対して設定されているメンテナンス情報も、検索結果に含まれるようです
それに対して、
ホスト指定のみで絞り込んだ場合には、当該ホストが対象とされているメンテナンス情報のみが返され、
当該ホストが所属しているホストグループ単体に対して設定されているメンテナンス情報は、検索結果に含まれません

グループを指定した場合に、そのグループ内のホスト単体に対して設定されているメンテナンス情報が
「この【ホストに対する設定】も、検索条件として指定されたホストグループの一部ホストに影響を与える設定だから‥」
という理由でリストに返されるのならば
ホストを指定した場合に、そのホストが所属しているグループ単体に対して設定されているメンテナンス情報が
「この【グループに対する設定】も、検索条件として指定されたホストにも影響を与える設定だから‥」
という理由で含まれるべきだと思います

どちらかが過大に含んでしまっているか、過小に除外してしまっているか、だと思うのですが‥。

以上2点
よろしくお願いします

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー fripper の写真

frontend 部分の php コードを 2.0.11 のものへ更新して、同試験を実施してみましたが、
同じ結果となりました

2.0.9/2.0.11 の双方で発生している問題となります

ユーザー fripper の写真

>> これは、おそらく、以下のようにしないといけないのではないでしょうか?
の部分に記載したパッチを、2.0.11 のソースコード CMaintenance.php に対して適用したうえで試験したところ、

テスト結果(4種類)の中で
「空のリストとなってしまっている。戻り値から対象の特定不能 →★★★不具合★★★」
としてコメントさせて頂いていた 'hosts' / 'groups' の各々について、
意図したとおり、値がセットされて返ってくることまで確認できました

「★★★疑問点★★★」として挙げさせて頂いていた
検索条件から結果への抽出条件の挙動については、本家の方々の「実装方針・想定仕様」にもよると思いますので
現状、詳細な原因調査やパッチ作成等は実施していません