認証・認可制御している Jenkins CLI で get-job や update-job の時だけ "No such job" と言われちゃう場合

この前エントリにブログ書いてなさすぎるから、12月は1人アドベントカレンダーやるかーと書いて、気付くと 12/10 になっていました。進捗全然ダメです。
最近、慣れない Jenkins 氏と久しぶりに戯れているのですが、昨日勉強したメモについて残しておきます。
ちなみに環境は、 Jenkins 1.640 / Java 7 でございます。

前提

前提として、Jenkinsの検証環境では、ユーザ単位での認証に加えて、ジョブに対する認可制御を加えています。
開発ユーザは、このジョブ(ビルド)を編集したり実行できるけど、オペレータユーザは実行しかできない、匿名ユーザはジョブの存在自体も見えない、とか、そういう感じ。
で、そういう環境で、Jenkins CLIからジョブの更新などを行おうとすると、指定したユーザの認証がうまく通っていそうにも関わらず、ジョブが無いとエラーが返されるというケース。

状況

具体的には以下のような感じ。

$ java -jar /usr/local/bin/jenkins-cli.jar -s http://localhost:8080/ list-jobs
hudson.security.AccessDeniedException2: anonymous には、全体/Read パーミッションがありません。

ジョブ一覧を取得するべく、上記のようにユーザ情報を記述しないと、匿名ユーザからのアクセスとなって、情報が取得できない感じ。認証・認可の制御をかけているので、これは想定通り。

$ java -jar /usr/local/bin/jenkins-cli.jar -s http://localhost:8080/ list-jobs --username user --password pass
test-job01
test-job02
test-job03

適切なユーザ情報をこんな感じで指定すると、ジョブ一覧が取得できる。よって認証はうまくいっているように見える。
で、問題はここから。

$ java -jar /usr/local/bin/jenkins-cli.jar -s http://localhost:8080/ get-job test-job01 --username user --password pass
No such job 'test-job01'
java -jar jenkins-cli.jar get-job JOB [--username VAL] [--password VAL] [--password-file VAL]
ジョブ定義XMLを標準出力に出力します。
JOB                 : Name of the job
--username VAL      : User name to authenticate yourself to Jenkins
--password VAL      : Password for authentication. Note that passing a
                      password in arguments is insecure.
--password-file VAL : File that contains the password

get-job や update-job を実行すると、この通り、そんなジョブは無いと怒られる。しかし、上記のジョブ一覧で取得した通り、ジョブは確かに存在する。
で、切り分けるべく色々やってみると、匿名ユーザ(Anonymous)の認可制御で、ジョブに "READ" パーミッションを付けてあげると、下記のようにジョブ内容が出力された。

$ java -jar /usr/local/bin/jenkins-cli.jar -s http://localhost:8080/ get-job test-job01 --username user --password pass
<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description>ジョブのテストだよ</description>

  ・・・・・ 省略 ・・・・・


ちなみに、ユーザ情報を渡してあげないと、匿名ユーザ扱いとなり、パーミッションが無いとエラーの文言が変わります。
よって、get-jobやupdate-jobは、認証段階の前に、ジョブが存在するかどうかを匿名ユーザ(Anonymous)で事前チェックするような挙動になっていると思われる。(ソースコードは読んでいないので推測)

解決

はい。ドキュメントにちゃんと書いてありました。

1.576 and later
Whenever the CLI tries to to connect to the Jenkins server, it offers the before mentioned SSH keys. When the user has those keys but don't want use them to authenticate, preventing being prompted by the key's password, it's possible to use the -noKeyAuth argument. This way the CLI will never try to use the SSH keys available.

1.419 and later
If your Jenkins requires authentication, you should set up public key authentication. Login from the web UI and go to http://yourserver.com/me/configure, then set your public keys in the designated text area. When connecting to the server, the CLI will look for ~/.ssh/identity, ~/.ssh/id_dsa, ~/.ssh/id_rsa and use those to authenticate itself against the server. Alternatively, the -i option can be used to explicitly specify the location of the private key.

認証を使いたい場合は、SSH鍵を使いましょう、と。
というわけで、Jenkinsのユーザ管理画面で、公開鍵の設定を行った上で、下記のような感じで "-i" オプションで秘密鍵を指定して実行すると、何の問題もなく get-job や update-job が出力されました。

$ java -jar /usr/local/bin/jenkins-cli.jar -s http://localhost:8080/ -i ~/.ssh/id_rsa get-job test-job01
<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description>ジョブのテストだよ</description>

・・・・・ 省略 ・・・・・

ちなみに、公開鍵の設定は、Jenkinsの [Jenkinsの管理] → [ユーザの管理] → [設定したいユーザ] → [設定] → [SSH Public Keys] のところで設定できます。

まとめ

ドキュメント嫁。以上。
それでは!=͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞(๑•̀д•́


改訂新版Jenkins実践入門 ――ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)

改訂新版Jenkins実践入門 ――ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)