Jenkinsに登録されているJob設定のインポート・エクスポート(CSRF対策)

Jenkinsに登録されているジョブを別のjenkinsサーバーに移行した時に調べた内容をメモしておきます。
Jenkins 2.221で試しました。


ジョブのエクスポート



操作にはcurlを使用します。

$ curl -so [出力ファイル名] --user '[ユーザー名]:[パスワード]' [jenkinsサーバー]/[job名]/config.xml



ユーザー:admin
パスワード:P@ssw0rd
Jenkinsサーバー:http://192.168.1.101:8080
上記の「sample_job」というジョブの情報を「config.xml」というファイル名で保存するには以下のようになります。


$ curl -so config.xml --user 'admin:P@ssw0rd' http://192.168.1.101:8080/job/sample_job/config.xml



以下のようなconfig.xmlが取得できます。


  1. <?xml version='1.1' encoding='UTF-8'?>
  2. <project>
  3. <description>sample job</description>
  4. <keepDependencies>false</keepDependencies>
  5. <properties/>
  6. <scm class="hudson.scm.NullSCM"/>
  7. <canRoam>true</canRoam>
  8. <disabled>false</disabled>
  9. <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  10. <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  11. <triggers>
  12.     <hudson.triggers.TimerTrigger>
  13.      <spec>H 5 * * * </spec>
  14.     </hudson.triggers.TimerTrigger>
  15. </triggers>
  16. <concurrentBuild>false</concurrentBuild>
  17. <builders>
  18.     <hudson.tasks.Shell>
  19.      <command>echo hello world</command>
  20.     </hudson.tasks.Shell>
  21. </builders>
  22. <publishers/>
  23. <buildWrappers/>
  24. </project>






ジョブのインポート(CSRF対策なし)



ジョブのインポートは
Jenkinsの管理 - グローバルセキュリティの設定 - CSRF対策
こちらのチェックが有効になっているか否かで対応が変わります。

a17_01.png

まず、CSRF対策がOFFになっている、もしくはOFFにできる場合
ジョブの新規作成+設定ファイルのインポートを行うには以下のコマンドを実行します。

$ curl --user '[ユーザー名]:[パスワード]' -s -XPOST '[jenkinsサーバー]/createItem?name=[ジョブの名称]' --data-binary @[設定ファイル名] -H "Content-Type:text/xml"



さきほどエクスポートしたジョブを「new_job」という名前でインポートするには以下のようなコマンドになります。

$ curl --user 'admin:P@ssw0rd' -s -XPOST 'http://192.168.1.101:8080/createItem?name=new_job' --data-binary @config.xml -H "Content-Type:text/xml"



既存のジョブに対して設定ファイルを反映するには以下のコマンドを実行します。

$ curl --user '[ユーザー名]:[パスワード]' -s -XPOST '[jenkinsサーバー]/job/[ジョブの名称]/config.xml' --data-binary @[設定ファイル名] -H "Content-Type:text/xml"



既に存在する「exists_job」の内容をさきほどエクスポートした内容で上書きするには以下のようなコマンドになります。

$ curl --user 'admin:P@ssw0rd' -s -XPOST 'http://192.168.1.101:8080/job/exists_job/config.xml' --data-binary @config.xml -H "Content-Type:text/xml"






ジョブのインポート(CSRF対策あり)



続いて、
Jenkinsの管理 - グローバルセキュリティの設定 - CSRF対策
こちらのチェックが有効になっている場合のコマンドです。

上記のインポートを実行すると

Error 403 No valid crumb was included in the request


という内容とともにエラーになります。

必要となるCSRFのキーは以下のコマンドで取得できます。

$ curl --user '[ユーザー名]:[パスワード]' -s '[jenkinsサーバー]/crumbIssuer/api/xml'



実際のコマンドの実行結果は以下のとおり。


$ curl --user 'admin:P@ssw0rd' -s 'http://192.168.1.101:8080/crumbIssuer/api/xml'



  1. <defaultCrumbIssuer _class='hudson.security.csrf.DefaultCrumbIssuer'>
  2.     <crumb>2f152535f636660f0a946f39ee1ec57091154ee857ff2a755a197358d2bf337d</crumb>
  3.     <crumbRequestField>Jenkins-Crumb</crumbRequestField>
  4. </defaultCrumbIssuer>



ここで得られる「crumb」の値を送信ヘッダーに設定すれば良いはずですが、

Jenkins-Crumb: 2f152535f636660f0a946f39ee1ec57091154ee857ff2a755a197358d2bf337d



コマンドを実行すると

$ curl --user 'admin:P@ssw0rd' -s -XPOST 'http://192.168.1.101:8080/createItem?name=new_job' --data-binary @config.xml -H "Content-Type:text/xml" -H "Jenkins-Crumb: 2f152535f636660f0a946f39ee1ec57091154ee857ff2a755a197358d2bf337d"



同様のエラーとなります。

Error 403 No valid crumb was included in the request




これ、随分悩んだのですがこちらがヒントになりました。
POST API calls '403 No valid crumb was included in the request'

CSRFのキーを取得するコマンドを実行すると、毎回値が異なることに気が付きます。
これ、セッションに情報を持つようでcurlで実行する場合はcookieを有効にする必要があります。

xpathを利用してCRUMBという環境変数に使用するヘッダーを作成します。

$ CRUMB=$(curl --silent --cookie-jar /tmp/cookies--user '[ユーザー名]:[パスワード]' -s '[jenkinsサーバー]/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')



実際の実行結果

$ CRUMB=$(curl --silent --cookie-jar /tmp/cookies -u 'admin:P@ssw0rd' 'http://192.168.1.101:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')



これで使用するヘッダーが準備できました

$ echo $CRUMB
Jenkins-Crumb:7d633463b2204b6eef65ddb4c0ac7e8ce4f0f59ebea3d2f031a971e43a3db076



得られたヘッダーを設定してジョブの新規作成を実行

$ curl --cookie /tmp/cookies --user '[ユーザー名]:[パスワード]' -s -XPOST '[jenkinsサーバー]/createItem?name=[ジョブの名称]' --data-binary @[設定ファイル名] -H "Content-Type:text/xml" -H $CRUMB



さきほどエクスポートしたジョブを「new_job」という名前でインポートするには以下のようなコマンドになります。

$ curl --cookie /tmp/cookies --user 'admin:P@ssw0rd' -s -XPOST 'http://192.168.1.101:8080/createItem?name=new_job' --data-binary @config.xml -H "Content-Type:text/xml" -H "$CRUMB"




同様に、既存のジョブに対して設定ファイルを反映するには以下のコマンドを実行します。

$ curl --cookie /tmp/cookies -u '[ユーザー名]:[パスワード]' [jenkinsサーバー]/job/[ジョブの名称]/config.xml --data-binary @[設定ファイル名] -H $CRUMB -H "Content-Type:text/xml"



既に存在する「exists_job」の内容をさきほどエクスポートした内容で上書きするには以下のようなコマンドになります。

$ curl --cookie /tmp/cookies -u 'admin:P@ssw0rd' http://192.168.1.101:8080/job/exists_job/config.xml --data-binary @config.xml -H $CRUMB -H "Content-Type:text/xml"






【参考URL】
Jenkinsのジョブ設定をExport/Importする
Jenkins APIを通してジョブを登録する
POST API calls '403 No valid crumb was included in the request'

関連記事

コメント

非公開コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ