Jenkins のフリースタイルジョブを Jenkins 上の URL を叩いて実行させる方法

URL への POST をジョブの発動トリガにしたい

Jenkins のフリースタイルジョブを、Jenkins 上の特定の URL を叩くことで実行したい場合の手順です。

大まかな流れ

  • CSRF対策 を有効にするか無効にするかで手順が異なる
    • よっぽどのことがない限り有効にすべきと思う
  • CSRF対策 を有効にした場合は Crumb を使って認証する
    • さらにユーザ名とパスワード(またはトークン)も一緒に送らないと認証に通らない
    • 叩くアドレスは http(s)://JENKINS/job/YOUR_JOB_NAME/build
      • jobbuild は定型
  • CSRF対策 を無効にした場合は自分で設定する token を使って認証する
    • token を知っている人全てが実行できる*1
    • 叩くアドレスは http(s)://JENKINS/job/YOUR_JOB_NAME/build?token=YOUR_TOKEN
      • jobbuild は定型

CSRF対策 を有効または無効にする方法

CSRF対策 を有効または無効にする方法は以下のとおりです。

1. 「グローバルセキュリティの設定」の設定画面に行く

Jenkins のトップ画面から「Jenkinsの管理」→「グローバルセキュリティの設定」とたどります。

f:id:gregminster:20180509144605p:plain

2. 「CSRF Protection」の項目を設定する

画面の中ほどに「CSRF Protection」という項目があり、その中に「CSRF対策」というチェック項目があります。ここにチェックを入れると CSRF対策 が有効になり、チェックを外すと CSRF対策 は無効になります。

f:id:gregminster:20180509144616p:plain

以下、CSRF対策 が有効か無効かで場合を分けて説明します。なお、フリースタイルジョブは作成済みとし、そのジョブの名前は YOUR_JOB_NAME とします。

CSRF対策 を有効にした場合

1. Crumb を取得する

Crumb とは Token のようなものです*2。まずはこいつを取得します。以下のコマンドを実行しましょう。PASSWORD_OR_TOKEN のところはパスワードでもトークンでも構いません*3

$ curl -u "USERNAME:PASSWORD_OR_TOKEN" 'http(s)://JENKINS/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'

実行して以下のように Jenkins-Crumb:12345678901234567890123456789012 と返ってくれば取得成功です。これが Crumb となります。

Jenkins-Crumb:12345678901234567890123456789012

2. Crumb をヘッダに設定してジョブ実行アドレスを叩く

「1.」で取得した Crumb をヘッダに設定して POST します。叩くアドレスは前述のように http(s)://JENKINS/job/YOUR_JOB_NAME/build です。したがってコマンドの実行としては以下のようになるでしょう。なお、ここでもユーザ名とパスワード(またはトークン)が必要になります。

$ curl -X POST -u "USERNAME:PASSWORD_OR_TOKEN" -H "Jenkins-Crumb:12345678901234567890123456789012" 'http(s)://JENKINS/job/YOUR_JOB_NAME/build'

成功した場合は何も返ってきません。失敗すると Error 403 No valid crumb was included in the request とか Error 401 Invalid password/token for user: USERNAME とかが返ってきます。成功した場合はジョブが叩かれて実行されたかどうかを Jenkins 上で確認するといいでしょう。

CSRF対策 を無効にした場合

CSRF対策 を無効にした場合は以下のとおりの手順を踏みます。

1. ジョブの設定画面の「ビルド・トリガ」で「リモートからビルド (例: スクリプトから)」を有効にする

ジョブの設定画面の中ほどに「ビルド・トリガ」という項目があります。そこにある「リモートからビルド (例: スクリプトから)」というチェック項目にチェックを入れます。

2. 任意の token を設定する

「1.」を有効にすると設定項目が展開されます。現れた「認証トークン」の項目を設定しましょう。認証トークンには任意の文字列を設定することができます。

f:id:gregminster:20180509144820p:plain

3. token を含んだ URL を POST で叩いてジョブを実行する

あとは「2.」で設定したトークンを含んだ URL を作ります。ここでトークンを YOUR_TOKEN としたと仮定します。すると以下のコマンドを叩くことでジョブが実行されます。

$ curl -X POST 'http(s)://JENKINS/job/YOUR_JOB_NAME/build?token=YOUR_TOKEN'

メソッドを POST にしますが、ヘッダの設定はありません。成功した場合は何も返ってきません。

補足

補足です。

CSRF対策 を有効にする場合の補足

  • 叩くアドレスは http(s)://JENKINS/job/YOUR_JOB_NAME/build になります
    • パラメータを付与する必要はありません
    • 任意のパラメータを付与することで、アクセス元などを区別することはできます
  • Crumb を生で書くことを避けるために環境変数を用いたりするとよいかと思います

CSRF対策 を無効にする場合の補足

  • CSRF対策 を無効にすると、Jenkins のナビゲーションバーで延々と赤く警告をされるので、やはり CSRF対策 は有効にするのがよと思います

f:id:gregminster:20180509144909p:plain

参考(というか答え)

https://support.cloudbees.com/hc/en-us/articles/219257077-CSRF-Protection-Explained

  • 一つ注意なのですが、上記ページ中では crumb のヘッダが .crumb:12345678901234567890123456789012 のように .crumb となっています*4
  • 正しくはリクエストしたときに返ってきたヘッダの名称ですので、それを用いましょう
    • 今回の場合では Jenkins-Crumb です。

余談

Jenkins職人 が必要になる理由がわかってきた気がします。

*1:できてしまう

*2:実はあまり詳しくは理解してない

*3:もちろんトークンが望ましい

*4:過去にそうだったときがあった?

Powered by はてなブログ