JenkinsのジョブをAPIから登録したい要件があったので、調べて見ました。
環境構築
Jenkins コンテナの起動とセットアップ
Docker を使って Jenkins コンテナを起動します。(latestを指定していますが、確認した時のJenkinsのバージョンは2.60.3でした)
version: '2'
services:
jenkins:
restart: always
image: jenkins:latest
environment:
- JENKINS_OPTS=--prefix=/jenkins
volumes:
- ./data/jenkins/jenkins:/var/jenkins_home
ports:
- "13080:8080"
$ docker-compose up -d
$ docker ps | grep jenkins
b8f18f187de9 jenkins:latest "/bin/tini -- /usr/l…" 3 hours ago Up 3 hours 50000/tcp, 0.0.0.0:13080->8080/tcp jenkins_jenkins_1
コンテナが起動したので、 http://localhost:13080/jenkins/ にアクセスします。
/var/jenkins_home/secrets/initialAdminPassword
の内容を入力するよう、求められるので、以下のように確認します。
$ docker exec -it b8f18f187de9 bash
jenkins@b8f18f187de9:/$ cat /var/jenkins_home/secrets/initialAdminPassword
fcaed6cf3b5d4439b3cf0d65c3a5e878
その後、セットアップウィザードに従い、各種プラグインをインストールします。
ジョブ作成
適当にジョブを作成します。
ここでは echo "Hello, Jenkins!"
するだけの「hello template」というジョブを作成することにします
Jenkins APIへのアクセス
How to create a job using the REST API and cURL? – CloudBees Support を参考に一つ一つ確認していきます。
APIトークンの取得
Jenkins APIを利用するためには、APIトークンが必要です。Jenkinsにログイン後、右上のユーザー名 > 設定をクリックし、APIトークンを表示します。すると、以下のように、User ID と API トークンを取得できます。
User ID: admin
API トークン: 34285bf2ae047ea8ae6c2b5b795be623
ジョブ一覧を取得する
/api/json
にアクセスすると json 形式でジョブの情報が得られました。また、BASIC認証が掛かっているので、上記の User ID と API トークンをユーザー名、パスワードとして認証します。
$ curl --user 'admin:34285bf2ae047ea8ae6c2b5b795be623' -s http://localhost:13080/jenkins/api/json | jq -r ".jobs[]"
{
"_class": "hudson.model.FreeStyleProject",
"name": "hello template",
"url": "http://localhost:13080/jenkins/job/hello%20template/",
"color": "blue"
}
ジョブ単体の情報を取得する
/job/{JOB名}/api/json
にアクセスするとジョブ単体の情報が得られます。
$ curl --user 'admin:34285bf2ae047ea8ae6c2b5b795be623' -s http://localhost:13080/jenkins/job/hello%20template/api/json|jq
{
"_class": "hudson.model.FreeStyleProject",
"actions": [
{},
{},
{
"_class": "com.cloudbees.plugins.credentials.ViewCredentialsAction"
}
],
"description": "",
"displayName": "hello template",
"displayNameOrNull": null,
"fullDisplayName": "hello template",
"fullName": "hello template",
(以下略)
ジョブの設定を取得する
このジョブの設定を取得し、 mylocalconfig.xml
というファイルに出力します。
$ curl --user 'admin:34285bf2ae047ea8ae6c2b5b795be623' -s http://localhost:13080/jenkins/job/hello%20template/config.xml -o mylocalconfig.xml
以下のような内容のファイルが出力されました。
<?xml version='1.0' encoding='UTF-8'?>
<project>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>echo "Chao, Jenkins!"</command>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
ジョブを登録する
/createItem
からジョブを登録できるのですが、その前に CSRF対策として CRUMB(トークン?) を取得しておきます。(CSRF対策を無効化することもできますが、当然脆弱になりますのでお勧めしません)
CRUMB=$(curl --user 'admin:34285bf2ae047ea8ae6c2b5b795be623' -s 'http://localhost:13080/jenkins/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
$ echo $CRUMB
Jenkins-Crumb:2a9e2016ee523dd2ea1c7d8a262509fe
では、 mylocalconfig.xml
の内容を yourJobName
という名前でジョブを作成します。
$ curl --user 'admin:34285bf2ae047ea8ae6c2b5b795be623' -s -XPOST 'http://localhost:13080/jenkins/createItem?name=yourJobName' --data-binary @mylocalconfig.xml -H "$CRUMB" -H "Content-Type:text/xml"
GUIからジョブが無事に登録できたことが確認できました。
ちなみに、CRUMBを指定しないと、以下のようなエラーになります。
Error 403 No valid crumb was included in the request