Python Jenkins API

Jenkins-python-api


前言

Jenkins作为最流行的自动化流程的核心工具,我们使用它自带的web-ui完全可以满足日常的构建及发布工作,但是如果需要和其他系统做集成就必须二次开发或者通过API方式进行交互了。

Jenkins介绍及相关

参考资料

python版本的API调用

目前python版本的API主要有两个第三方包

  1. JenkinsApi
  1. Python Jenkins

API示例

JenkinsAPi模块

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "shuke"
# Date: 2018/1/17

from jenkinsapi.jenkins import Jenkins
from jenkinsapi.build import Build


def get_server_instance():
    jenkins_url = 'http://127.0.0.1:8080/'
    server = Jenkins(jenkins_url, username='admin', password='admin123')
    return server


server = get_server_instance()

# 1. 版本
print(server.version)
'''
2.101
'''

# 2. 所有的job列表
print(server.keys())
print(server.get_jobs_list())
'''
['ansible-playbook', 'my-github']
'''

# 3. 全局信息查看
server.pprint()
'''
{'_class': 'hudson.model.Hudson',
 'jobs': [{'_class': 'hudson.model.FreeStyleProject',
           'color': 'blue',
           'name': 'ansible-playbook',
           'url': 'http://127.0.0.1:8080/job/ansible-playbook/'},
          {'_class': 'hudson.model.FreeStyleProject',
           'color': 'disabled',
           'name': 'my-github',
           'url': 'http://127.0.0.1:8080/job/my-github/'}]}
'''

# 3. 指定job的config.xml配置
print("my-github job config:\n", server['my-github'].get_config())
'''
my-github job config:
 <?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.coravy.hudson.plugins.github.GithubProjectProperty plugin="github@1.28.1">
      <projectUrl>https://github.com/shuke163/CustAdmin.git/</projectUrl>
      <displayName>Admin</displayName>
    </com.coravy.hudson.plugins.github.GithubProjectProperty>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>-1</daysToKeep>
        <numToKeep>5</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
        <hudson.model.ChoiceParameterDefinition>
          <name>ip</name>
          <description>ip</description>
          <choices class="java.util.Arrays$ArrayList">
            <a class="string-array">
              <string>127.0.0.1</string>
            </a>
          </choices>
        </hudson.model.ChoiceParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
  </properties>
  <scm class="hudson.scm.NullSCM"/>
  <canRoam>true</canRoam>
  <disabled>true</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.tasks.Shell>
      <command>echo $ip</command>
    </hudson.tasks.Shell>
  </builders>
  <publishers/>
  <buildWrappers/>
</project>
'''

# 4. 得到的是一个包含所有jobs的生成器对象
print(server.get_jobs())
'''
['ansible-playbook', 'my-github']
'''

# 5. 所有的job描述
for job_name, job_instance in server.get_jobs():
    print('Job Name:%s' % (job_instance.name))
    print('Job Description:%s' % (job_instance.get_description()))
    print('Is Job running:%s' % (job_instance.is_running()))
    print('Is Job enabled:%s' % (job_instance.is_enabled()))
'''
Job Name:ansible-playbook
Job Description:ansible playbook
Is Job running:False
Is Job enabled:True
Job Name:my-github
Job Description:
Is Job running:False
Is Job enabled:True
'''

# 6. Disable/Enable a Jenkins Job
job_name = 'my-github'
if (server.has_job(job_name)):
    job_instance = server.get_job(job_name)
    job_instance.disable()
    print('Name:%s,Is Job Enabled ?:%s' % (job_name, job_instance.is_enabled()))
'''
Name:my-github,Is Job Enabled ?:False
'''

# 7. CURD Job
server.create_job()
server.delete_job('ansible-playbook')
server.copy_job('my-job', 'new-my-job')
server.rename_job('my-github', 'new-my-github')

# 8. Get Plugin details
for plugin in server.get_plugins().values():
    print("Short Name:%s" % (plugin.shortName))
    print("Long Name:%s" % (plugin.longName))
    print("Version:%s" % (plugin.version))
    print("URL:%s" % (plugin.url))
    print("Active:%s" % (plugin.active))
    print("Enabled:%s" % (plugin.enabled))
'''
Short Name:jsch
Long Name:Jenkins JSch dependency plugin
Version:0.1.54.1
URL:http://wiki.jenkins-ci.org/display/JENKINS/JSch+plugin
Active:True
Enabled:True
Short Name:ws-cleanup
Long Name:Jenkins Workspace Cleanup Plugin
Version:0.34
URL:http://wiki.jenkins-ci.org/display/JENKINS/Workspace+Cleanup+Plugin
Active:True
Enabled:True
......
'''


# 9. 从已完成的构建中获取版本信息
def getSCMInfroFromLatestGoodBuild(url, jobName, username='admin', password='admin123'):
    J = Jenkins(url, username, password)
    job = J[jobName]
    lgb = job.get_last_good_build()
    return lgb.get_revision()


version = getSCMInfroFromLatestGoodBuild("http://127.0.0.1:8080/", 'ansible-playbook')
print(version)
'''
21c2b6ff6c842a86969f36f75424e17ae27eae68
'''

# 10. 其他
print(server.__dict__)
'''
{'username': 'admin', 'password': 'admin123', 'requester': <jenkinsapi.utils.requester.Requester object at 0x103423710>, 'lazy': False, 'jobs_container': None, '_data': {'_class': 'hudson.model.Hudson', 'jobs': [{'_class': 'hudson.model.FreeStyleProject', 'name': 'ansible-playbook', 'url': 'http://127.0.0.1:8080/job/ansible-playbook/', 'color': 'blue'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'my-github', 'url': 'http://127.0.0.1:8080/job/my-github/', 'color': 'disabled'}]}, 'baseurl': 'http://127.0.0.1:8080'}
'''

jobs = server.__dict__['_data']['jobs']
print(server.resolve_job_folders(jobs))
'''
[{'_class': 'hudson.model.FreeStyleProject', 'name': 'ansible-playbook', 'url': 'http://127.0.0.1:8080/job/ansible-playbook/', 'color': 'blue'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'my-github', 'url': 'http://127.0.0.1:8080/job/my-github/', 'color': 'disabled'}]
'''

# baseurl
print(server.baseurl)
'''
http://127.0.0.1:8080
'''

# username
print(server.username)
'''
admin
'''

# password
print(server.password)
'''
admin123
'''

# 判断job是否存在
print(server.has_job('prod-java'))
'''
False
'''

print(server.get_queue())
'''
http://127.0.0.1:8080/queue
'''

# 查看试图
print(server.views.keys())
'''
['My View', 'all', 'myview']
'''

# 删除试图
server.delete_view_by_url('http://127.0.0.1:8080/view/testview/')

# 获取最后一次构建
print(server['ansible-playbook'].get_last_good_build())
'''
ansible-playbook #27
'''

# BUILD构建相关
# 1. 构建(方式一)
params = {'Branch': 'oriin/master', 'host': '192.168.1.100'}
ret = server.build_job('ansible-playbook', params)
print(ret)

# 方式二
job = server['ansible-playbook']
run_job = job.invoke(build_params=params)
number = run_job.__dict__['_data']['executable']['number']
build_url = run_job.__dict__['_data']['executable']['url']
print("第%d次构建: %s" % (number, build_url))
'''
第40次构建: http://127.0.0.1:8080/job/ansible-playbook/40/
'''

# 结果查询
# 1. 方式一
job = server.get_job('ansible-playbook')
print(job.__dict__['_data']['builds'])
url = job.__dict__['_data']['lastBuild']['url']
number = job.__dict__['_data']['lastBuild']['number']
obj = Build(url, number, job)

# 2. 方式二
job = server['ansible-playbook']
url = job.__dict__['_data']['lastBuild']['url']
number = job.__dict__['_data']['lastBuild']['number']
obj = Build(url, number, job)

# 全局信息
print(obj.pprint())
'''
{'_class': 'hudson.model.FreeStyleBuild',
 'actions': [{'_class': 'hudson.model.ParametersAction',
              'parameters': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterValue',
                              'name': 'Branch',
                              'value': 'oriin/master'},
                             {'_class': 'hudson.model.StringParameterValue',
                              'name': 'host',
                              'value': '192.168.1.100'}]},
             {'_class': 'hudson.model.CauseAction',
              'causes': [{'_class': 'hudson.model.Cause$UserIdCause',
                          'shortDescription': 'Started by user 管理员',
                          'userId': 'admin',
                          'userName': '管理员'}]},
             {},
             ......
'''
print(obj.get_result_url())
'''
http://127.0.0.1:8080/job/ansible-playbook/40/testReport/api/python
'''
print(obj.is_running())
'''
False
'''
print(obj.stop())
'''
True
'''
print(obj.is_good())
'''
True
'''
print(obj.get_number())
print(obj.buildno)
'''
40
'''
print(obj.get_status())
'''
SUCCESS
'''
print(obj.get_revision())
'''
21c2b6ff6c842a86969f36f75424e17ae27eae68
'''
print(obj.get_revision_branch())
'''
[{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]
'''
print(obj.get_console())
'''
Started by user 管��
[EnvInject] - Loading node environment variables.
Building in workspace /Users/zhao/data/workspace/workspace/ansible-playbook
 > /usr/local/bin/git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > /usr/local/bin/git config remote.origin.url git@git.icbc.net:ansible-roles/zff.ansible.git # timeout=10
Fetching upstream changes from git@git.icbc.net:ansible-roles/zff.ansible.git
 > /usr/local/bin/git --version # timeout=10
using GIT_SSH to set credentials deploy key
 > /usr/local/bin/git fetch --tags --progress git@git.icbc.net:ansible-roles/zff.ansible.git +refs/heads/*:refs/remotes/origin/*
 > /usr/local/bin/git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > /usr/local/bin/git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 21c2b6ff6c842a86969f36f75424e17ae27eae68 (refs/remotes/origin/master)
 > /usr/local/bin/git config core.sparsecheckout # timeout=10
 > /usr/local/bin/git checkout -f 21c2b6ff6c842a86969f36f75424e17ae27eae68
Commit message: "update tomcat root mode"
 > /usr/local/bin/git rev-list --no-walk 21c2b6ff6c842a86969f36f75424e17ae27eae68 # timeout=10
[ansible-playbook] $ /bin/sh -xe /Users/Shared/Jenkins/tmp/jenkins280834745018509074.sh
+ echo 192.168.1.100
192.168.1.100
+ echo test
test
+ echo http://127.0.0.1:8080/job/ansible-playbook/40/
http://127.0.0.1:8080/job/ansible-playbook/40/
+ echo 40
40
+ echo jenkins-ansible-playbook-40
jenkins-ansible-playbook-40
Recording fingerprints
Finished: SUCCESS
'''

print(obj.get_causes())
'''
[{'_class': 'hudson.model.Cause$UserIdCause', 'shortDescription': 'Started by user 管理员', 'userId': 'admin', 'userName': '管理员'}]
'''
print(obj.get_params())
'''
{'Branch': 'oriin/master', 'host': '192.168.1.100'}
'''
print(obj.get_env_vars())
'''
{'BUILD_CAUSE': 'MANUALTRIGGER', 'BUILD_CAUSE_MANUALTRIGGER': 'true', 'BUILD_DISPLAY_NAME': '#40', 'BUILD_ID': '40', 'BUILD_NUMBER': '40', 'BUILD_TAG': 'jenkins-ansible-playbook-40', 'BUILD_URL': 'http://127.0.0.1:8080/job/ansible-playbook/40/', 'Branch': 'oriin/master', 'EXECUTOR_NUMBER': '1', 'HUDSON_HOME': '/Users/zhao/data/workspace', 'HUDSON_SERVER_COOKIE': '5634a2d507063d61', 'HUDSON_URL': 'http://127.0.0.1:8080/', 'JENKINS_HOME': '/Users/zhao/data/workspace', 'JENKINS_SERVER_COOKIE': '5634a2d507063d61', 'JENKINS_URL': 'http://127.0.0.1:8080/', 'JOB_BASE_NAME': 'ansible-playbook', 'JOB_NAME': 'ansible-playbook', 'JOB_URL': 'http://127.0.0.1:8080/job/ansible-playbook/', 'NODE_LABELS': 'master', 'NODE_NAME': 'master', 'ROOT_BUILD_CAUSE': 'MANUALTRIGGER', 'ROOT_BUILD_CAUSE_MANUALTRIGGER': 'true', 'RUN_CHANGES_DISPLAY_URL': 'http://127.0.0.1:8080/job/ansible-playbook/40/display/redirect?page=changes', 'RUN_DISPLAY_URL': 'http://127.0.0.1:8080/job/ansible-playbook/40/display/redirect', 'TEST_ARGS': 'test', 'host': '192.168.1.100'}
'''
print(obj.job)
'''
ansible-playbook
'''
print(obj.get_data('http://127.0.0.1:8080/job/ansible-playbook/40/api/python/?pretty=true'))
{'_class': 'hudson.model.FreeStyleBuild', 'actions': [{'_class': 'hudson.model.ParametersAction', 'parameters': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterValue', 'name': 'Branch', 'value': 'oriin/master'}, {'_class': 'hudson.model.StringParameterValue', 'name': 'host', 'value': '192.168.1.100'}]}, {'_class': 'hudson.model.CauseAction', 'causes': [{'_class': 'hudson.model.Cause$UserIdCause', 'shortDescription': 'Started by user 管理员', 'userId': 'admin', 'userName': '管理员'}]}, {}, {'_class': 'hudson.plugins.git.util.BuildData', 'buildsByBranchName': {'refs/remotes/origin/master': {'_class': 'hudson.plugins.git.util.Build', 'buildNumber': 40, 'buildResult': None, 'marked': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}, 'revision': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}}}, 'lastBuiltRevision': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}, 'remoteUrls': ['git@git.idbc.net:ansible-roles/zff.ansible.git'], 'scmName': ''}, {'_class': 'hudson.plugins.git.GitTagAction'}, {}, {}, {}, {}, {}], 'artifacts': [], 'building': False, 'description': None, 'displayName': '#40', 'duration': 735, 'estimatedDuration': 897, 'executor': None, 'fullDisplayName': 'ansible-playbook #40', 'id': '40', 'keepLog': False, 'number': 40, 'queueId': 21, 'result': 'SUCCESS', 'timestamp': 1516172959444, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/40/', 'builtOn': '', 'changeSet': {'_class': 'hudson.plugins.git.GitChangeSetList', 'items': [], 'kind': 'git'}, 'culprits': []}

Some API

This module is a collection of helpful, high-level functions for automating common tasks. Many of these functions were designed to be exposed to the command-line, hence they have simple string arguments.

from jenkinsapi import api as API
server = get_server_instance()
jobs = server.get_jobs_list()

# 1. 等待所有job执行完成
ret = API.block_until_complete('http://127.0.0.1:8080/', jobs, username='admin', password='admin123', ssl_verify=False)
print(ret)
'''
Waiting for jobs "ansible-playbook" to complete. Will wait another 12000s
'''

# 2. job 构建的完整名称
ret = API.get_build('http://127.0.0.1:8080/', 'ansible-playbook', 66, username='admin', password='admin123',
                    ssl_verify=False)
print(ret)
'''
ansible-playbook #66
'''

# 3. 最后一次构建
ret = API.get_latest_build('http://127.0.0.1:8080/', 'ansible-playbook', username='admin', password='admin123',
                           ssl_verify=False)
print(ret)
'''
ansible-playbook #66
'''

# 4. 最后一次完整构建
ret = API.get_latest_complete_build('http://127.0.0.1:8080/', 'ansible-playbook', username='admin', password='admin123',
                                    ssl_verify=False)
print(ret)
'''
ansible-playbook #66
'''

# 5. 查询试图信息
ret = API.get_nested_view_from_url('http://127.0.0.1:8080/view/myview/', username='admin', password='admin123',
                                   ssl_verify=False)
print(ret.get_config_xml_url())
'''
http://127.0.0.1:8080/view/myview/config.xml
'''
print(ret.get_job_dict())
'''
{'ansible-playbook': 'http://127.0.0.1:8080/job/ansible-playbook/', 'my-github': 'http://127.0.0.1:8080/job/my-github/'}
'''
print(ret.pprint())
'''
{'_class': 'hudson.model.ListView',
 'description': '测试试图',
 'jobs': [{'_class': 'hudson.model.FreeStyleProject',
           'color': 'blue',
           'name': 'ansible-playbook',
           'url': 'http://127.0.0.1:8080/job/ansible-playbook/'},
          {'_class': 'hudson.model.FreeStyleProject',
           'color': 'disabled',
           'name': 'my-github',
           'url': 'http://127.0.0.1:8080/job/my-github/'}],
 'name': 'myview',
 'property': [],
 'url': 'http://127.0.0.1:8080/view/myview/'}
None
'''
print(ret.get_config())
'''
<?xml version="1.0" encoding="UTF-8"?>
<hudson.model.ListView>
  <name>myview</name>
  <description>测试试图</description>
  <filterExecutors>false</filterExecutors>
  <filterQueue>false</filterQueue>
  <properties class="hudson.model.View$PropertyList"/>
  <jobNames>
    <comparator class="hudson.util.CaseInsensitiveComparator"/>
    <string>ansible-playbook</string>
    <string>my-github</string>
  </jobNames>
  <jobFilters/>
  <columns>
    <hudson.views.StatusColumn/>
    <hudson.views.WeatherColumn/>
    <hudson.views.JobColumn/>
    <hudson.views.LastSuccessColumn/>
    <hudson.views.LastDurationColumn/>
    <hudson.views.BuildButtonColumn/>
    <hudson.plugins.git.GitBranchSpecifierColumn plugin="git@3.7.0"/>
  </columns>
  <recurse>false</recurse>
</hudson.model.ListView>
'''

# 6. 类似与get_nested_view_from_url函数
ret = API.get_view_from_url('http://127.0.0.1:8080/view/myview/', username='admin', password='admin123',
                            ssl_verify=False)
print(ret.get_job_dict())
'''
{'ansible-playbook': 'http://127.0.0.1:8080/job/ansible-playbook/', 'my-github': 'http://127.0.0.1:8080/job/my-github/'}
'''
print(ret.get_config_xml_url())
'''
http://127.0.0.1:8080/view/myview/config.xml
'''

Python-Jenkins模块

Working with Jenkins Jobs

This is an example showing how to create, configure and delete Jenkins jobs.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "shuke"
# Date: 2018/1/17


import jenkins

server = jenkins.Jenkins('http://127.0.0.1:8080', username="admin", password="admin123")
params = {'Branch': 'oriin/master', 'host': '192.168.1.110'}

# server对象
# Jenkins的job数量
print(server.jobs_count())
'''
2
'''

# Jenkins-web-ui
print(server.server)
'''
http://127.0.0.1:8080/
'''

# 所有的job信息
all_jobs_li = server.get_all_jobs()
for item in all_jobs_li:
    print('name: %s' % item['name'], 'URL: ', item['url'])
'''
name: ansible-playbook URL:  http://127.0.0.1:8080/job/ansible-playbook/
name: my-github URL:  http://127.0.0.1:8080/job/my-github/
'''

# 账户信息描述
print(server.get_whoami())
'''
{'_class': 'hudson.model.User', 'absoluteUrl': 'http://127.0.0.1:8080/user/admin', 'description': '本地测试', 'fullName': '管理员', 'id': 'admin', 'property': [{'_class': 'jenkins.security.ApiTokenProperty'}, {'_class': 'com.cloudbees.plugins.credentials.UserCredentialsProvider$UserCredentialsProperty'}, {'_class': 'hudson.tasks.Mailer$UserProperty', 'address': 'admin@163.com'}, {'_class': 'hudson.plugins.emailext.watching.EmailExtWatchAction$UserProperty', 'triggers': []}, {'_class': 'jenkins.security.LastGrantedAuthoritiesProperty'}, {'_class': 'org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty'}, {'_class': 'hudson.model.PaneStatusProperties'}, {'_class': 'org.jenkinsci.main.modules.cli.auth.ssh.UserPropertyImpl'}, {'_class': 'hudson.security.HudsonPrivateSecurityRealm$Details'}, {'_class': 'hudson.model.MyViewsProperty'}, {'_class': 'hudson.search.UserSearchProperty', 'insensitiveSearch': True}, {'_class': 'hudson.plugins.favorite.user.FavoriteUserProperty'}]}
'''

# auth
print(server.auth)
'''
b'Basic YWRtaW46YWRtaW4xMjM='
'''

# DEBUG Job信息
print(server.debug_job_info('ansible-playbook'))
'''
_class hudson.model.FreeStyleProject
actions [{'_class': 'hudson.model.ParametersDefinitionProperty', 'parameterDefinitions': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterDefinition', 'defaultParameterValue': None, 'description': '分支', 'name': 'Branch', 'type': 'PT_BRANCH'}, {'_class': 'hudson.model.StringParameterDefinition', 'defaultParameterValue': {'_class': 'hudson.model.StringParameterValue', 'value': '127.0.0.1,127.0.0.2,127.0.0.1'}, 'description': '本机', 'name': 'host', 'type': 'StringParameterDefinition'}]}, {}, {}, {}, {}, {'_class': 'com.cloudbees.plugins.credentials.ViewCredentialsAction'}]
description ansible playbook
displayName ansible-playbook
displayNameOrNull None
fullDisplayName ansible-playbook
fullName ansible-playbook
name ansible-playbook
url http://127.0.0.1:8080/job/ansible-playbook/
buildable True
......
'''

####### CURD Job #######

# Job是否存在
print(server.job_exists('my-api'))
'''
True or None
'''

# 获取所有的Job
print(server.get_jobs())
'''
[{'_class': 'hudson.model.FreeStyleProject', 'name': 'ansible-playbook', 'url': 'http://127.0.0.1:8080/job/ansible-playbook/', 'color': 'aborted', 'fullname': 'ansible-playbook'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'my-api', 'url': 'http://127.0.0.1:8080/job/my-api/', 'color': 'notbuilt', 'fullname': 'my-api'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'my-github', 'url': 'http://127.0.0.1:8080/job/my-github/', 'color': 'disabled', 'fullname': 'my-github'}]
'''

# 创建Job
server.create_job('API', jenkins.RECONFIG_XML)

# 删除Job
server.delete_job('my-api')

# 复制job
server.copy_job('my-github', 'copy-my-github')

# enable job
server.enable_job('copy-my-github')

# 禁用Job
server.disable_job('copy-my-github')

# 重新配置Job
server.reconfig_job('copy-my-github', jenkins.RECONFIG_XML)

# 重命名Job
server.rename_job('API', 'my-api')

# 触发Job运行
# 触发Job(方式一)
server.build_job_url('ansible-playbook', parameters=params)
'''
http://127.0.0.1:8080/job/ansible-playbook/buildWithParameters?Branch=oriin%2Fmaster&host=192.168.1.110
'''
# 触发Job(方式二)
server.build_job('ansible-playbook', parameters=params)

# 查看指定构建编号的输出
print(server.get_build_console_output('ansible-playbook', 41))
'''
Started by user 管理员
[EnvInject] - Loading node environment variables.
Building in workspace /Users/zhao/data/workspace/workspace/ansible-playbook
 > /usr/local/bin/git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > /usr/local/bin/git config remote.origin.url git@git.icbc.net:ansible-roles/zff.ansible.git # timeout=10
Fetching upstream changes from git@git.icbc.net:ansible-roles/zff.ansible.git
 > /usr/local/bin/git --version # timeout=10
using GIT_SSH to set credentials deploy key
 > /usr/local/bin/git fetch --tags --progress git@git.icbc.net:ansible-roles/zff.ansible.git +refs/heads/*:refs/remotes/origin/*
 > /usr/local/bin/git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > /usr/local/bin/git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 21c2b6ff6c842a86969f36f75424e17ae27eae68 (refs/remotes/origin/master)
 > /usr/local/bin/git config core.sparsecheckout # timeout=10
 > /usr/local/bin/git checkout -f 21c2b6ff6c842a86969f36f75424e17ae27eae68
Commit message: "update tomcat root mode"
 > /usr/local/bin/git rev-list --no-walk 21c2b6ff6c842a86969f36f75424e17ae27eae68 # timeout=10
[ansible-playbook] $ /bin/sh -xe /Users/Shared/Jenkins/tmp/jenkins5080034200775659821.sh
+ echo 192.168.1.110
192.168.1.110
+ echo test
test
+ echo http://127.0.0.1:8080/job/ansible-playbook/41/
http://127.0.0.1:8080/job/ansible-playbook/41/
+ echo 41
41
+ echo jenkins-ansible-playbook-41
jenkins-ansible-playbook-41
Finished: SUCCESS
'''

# 下一次构建编号,步长为5
next_bn = server.get_job_info('ansible-playbook')['nextBuildNumber']
server.set_next_build_number('ansible-playbook', next_bn + 5)

# 指定编号的构建Job信息
print(server.get_build_info('ansible-playbook', 48))
'''
{'_class': 'hudson.model.FreeStyleBuild', 'actions': [{'_class': 'hudson.model.ParametersAction', 'parameters': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterValue', 'name': 'Branch', 'value': 'oriin/master'}, {'_class': 'hudson.model.StringParameterValue', 'name': 'host', 'value': '192.168.1.110'}]}, {'_class': 'hudson.model.CauseAction', 'causes': [{'_class': 'hudson.model.Cause$UserIdCause', 'shortDescription': 'Started by user 管理员', 'userId': 'admin', 'userName': '管理员'}]}, {}, {'_class': 'hudson.plugins.git.util.BuildData', 'buildsByBranchName': {'refs/remotes/origin/master': {'_class': 'hudson.plugins.git.util.Build', 'buildNumber': 48, 'buildResult': None, 'marked': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}, 'revision': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}}}, 'lastBuiltRevision': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}, 'remoteUrls': ['git@git.icbc.net:ansible-roles/zff.ansible.git'], 'scmName': ''}, {'_class': 'hudson.plugins.git.GitTagAction'}, {}, {}, {}, {}], 'artifacts': [], 'building': False, 'description': None, 'displayName': '#48', 'duration': 1861, 'estimatedDuration': 4305, 'executor': None, 'fullDisplayName': 'ansible-playbook #48', 'id': '48', 'keepLog': False, 'number': 48, 'queueId': 24, 'result': 'SUCCESS', 'timestamp': 1516185645519, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/48/', 'builtOn': '', 'changeSet': {'_class': 'hudson.plugins.git.GitChangeSetList', 'items': [], 'kind': 'git'}, 'culprits': []}
'''

# 获取正在运行的Job,一般结合build_job方法一起使用
print(server.get_running_builds())
'''
[{'name': 'ansible-playbook', 'number': 57, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/57/', 'node': '(master)', 'executor': 1}]
'''

# 终止指定编号的Job
server.stop_build('ansible-playbook', 62)

# 获取Job名称
print(server.get_job_name('ansible-playbook'))
'''
ansible-playbook
'''

# 断言Job是否存在
print(server.assert_job_exists('ansible-playbook'))
'''
存在则返回None,不存在则抛出错误信息
'''

# 该Job所有的相关信息
print(server.get_job_info('ansible-playbook'))
'''
{'_class': 'hudson.model.FreeStyleProject', 'actions': [{'_class': 'hudson.model.ParametersDefinitionProperty', 'parameterDefinitions': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterDefinition', 'defaultParameterValue': None, 'description': '分支', 'name': 'Branch', 'type': 'PT_BRANCH'}, {'_class': 'hudson.model.StringParameterDefinition', 'defaultParameterValue': {'_class': 'hudson.model.StringParameterValue', 'value': '127.0.0.1,127.0.0.2,127.0.0.1'}, 'description': '本机', 'name': 'host', 'type': 'StringParameterDefinition'}]}, {}, {}, {}, {}, {}, {'_class': 'com.cloudbees.plugins.credentials.ViewCredentialsAction'}], 'description': 'ansible playbook', 'displayName': 'ansible-playbook', 'displayNameOrNull': None, 'fullDisplayName': 'ansible-playbook', 'fullName': 'ansible-playbook', 'name': 'ansible-playbook', 'url': 'http://127.0.0.1:8080/job/ansible-playbook/', 'buildable': True, 'builds': [{'_class': 'hudson.model.FreeStyleBuild', 'number': 62, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/62/'}, {'_class': 'hudson.model.FreeStyleBuild', 'number': 61, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/61/'}, {'_class': 'hudson.model.FreeStyleBuild', 'number': 60, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/60/'}, {'_class': 'hudson.model.FreeStyleBuild', 'number': 59, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/59/'}, {'_class': 'hudson.model.FreeStyleBuild', 'number': 58, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/58/'}], 'color': 'aborted', 'firstBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 58, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/58/'}, 'healthReport': [{'description': 'Build stability: No recent builds failed.', 'iconClassName': 'icon-health-80plus', 'iconUrl': 'health-80plus.png', 'score': 100}], 'inQueue': False, 'keepDependencies': False, 'lastBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 62, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/62/'}, 'lastCompletedBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 62, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/62/'}, 'lastFailedBuild': None, 'lastStableBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 61, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/61/'}, 'lastSuccessfulBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 61, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/61/'}, 'lastUnstableBuild': None, 'lastUnsuccessfulBuild': {'_class': 'hudson.model.FreeStyleBuild', 'number': 62, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/62/'}, 'nextBuildNumber': 63, 'property': [{'_class': 'jenkins.model.BuildDiscarderProperty'}, {'_class': 'hudson.model.ParametersDefinitionProperty', 'parameterDefinitions': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterDefinition', 'defaultParameterValue': None, 'description': '分支', 'name': 'Branch', 'type': 'PT_BRANCH'}, {'_class': 'hudson.model.StringParameterDefinition', 'defaultParameterValue': {'_class': 'hudson.model.StringParameterValue', 'name': 'host', 'value': '127.0.0.1,127.0.0.2,127.0.0.1'}, 'description': '本机', 'name': 'host', 'type': 'StringParameterDefinition'}]}], 'queueItem': None, 'concurrentBuild': False, 'downstreamProjects': [], 'labelExpression': None, 'scm': {'_class': 'hudson.plugins.git.GitSCM'}, 'upstreamProjects': []}
'''

# 查看该试图下所有的Job
print(server.get_jobs('myview'))
'''
[{'_class': 'hudson.model.FreeStyleProject', 'name': 'ansible-playbook', 'url': 'http://127.0.0.1:8080/job/ansible-playbook/', 'color': 'aborted', 'fullname': 'ansible-playbook'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'my-api', 'url': 'http://127.0.0.1:8080/job/my-api/', 'color': 'notbuilt', 'fullname': 'my-api'}, {'_class': 'hudson.model.FreeStyleProject', 'name': 'my-github', 'url': 'http://127.0.0.1:8080/job/my-github/', 'color': 'disabled', 'fullname': 'my-github'}]
'''

# 正则匹配获取Job信息
# print(server.get_job_info_regex('^my'))
'''
Job相关信息
....
'''

# 获取最后一次构建的Job信息
# build a parameterized job
# requires creating and configuring the ansible-playbook job to accept 'param1' & 'param2'
job_name = "ansible-playbook"
server.build_job(job_name, {'Branch': 'oriin/master', 'host': '192.168.1.110'})
last_build_number = server.get_job_info(job_name)['lastCompletedBuild']['number']
build_info = server.get_build_info(job_name, last_build_number)
print(build_info)
'''
{'_class': 'hudson.model.FreeStyleBuild', 'actions': [{'_class': 'hudson.model.ParametersAction', 'parameters': [{'_class': 'net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterValue', 'name': 'Branch', 'value': 'origin/master'}, {'_class': 'hudson.model.StringParameterValue', 'name': 'host', 'value': '127.0.0.1,127.0.0.2,127.0.0.105'}]}, {'_class': 'hudson.model.CauseAction', 'causes': [{'_class': 'hudson.model.Cause$UserIdCause', 'shortDescription': 'Started by user 管理员', 'userId': 'admin', 'userName': '管理员'}]}, {}, {'_class': 'hudson.plugins.git.util.BuildData', 'buildsByBranchName': {'refs/remotes/origin/master': {'_class': 'hudson.plugins.git.util.Build', 'buildNumber': 62, 'buildResult': None, 'marked': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}, 'revision': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}}}, 'lastBuiltRevision': {'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'branch': [{'SHA1': '21c2b6ff6c842a86969f36f75424e17ae27eae68', 'name': 'refs/remotes/origin/master'}]}, 'remoteUrls': ['git@git.icbc.net:ansible-roles/zff.ansible.git'], 'scmName': ''}, {'_class': 'hudson.plugins.git.GitTagAction'}, {}, {'_class': 'jenkins.model.InterruptedBuildAction'}, {}, {}, {}], 'artifacts': [], 'building': False, 'description': None, 'displayName': '#62', 'duration': 7069, 'estimatedDuration': 7681, 'executor': None, 'fullDisplayName': 'ansible-playbook #62', 'id': '62', 'keepLog': False, 'number': 62, 'queueId': 33, 'result': 'ABORTED', 'timestamp': 1516186369042, 'url': 'http://127.0.0.1:8080/job/ansible-playbook/62/', 'builtOn': '', 'changeSet': {'_class': 'hudson.plugins.git.GitChangeSetList', 'items': [], 'kind': 'git'}, 'culprits': []}
'''

# shutdown jenkins
server.quiet_down()

Working with Jenkins Views

This is an example showing how to create, configure and delete Jenkins views.

# 试图相关
print(server.get_views())
'''
[{'_class': 'hudson.model.AllView', 'name': 'all', 'url': 'http://127.0.0.1:8080/'}, {'_class': 'hudson.model.ListView', 'name': 'myview', 'url': 'http://127.0.0.1:8080/view/myview/'}]
'''

# CURD VIEW
server.view_exists()
server.create_view('EMPTY', jenkins.EMPTY_VIEW_CONFIG_XML)
views = server.get_views()
server.delete_view('EMPTY')
server.reconfig_view('newview',jenkins.EMPTY_VIEW_CONFIG_XML)
server.get_view_name('EMPTY')
view_config = server.get_view_config('EMPTY')
# 获取试图下所有的job
print(server._get_view_jobs('myview'))

# 试图配置信息
print(server.get_view_config('myview'))
'''
<?xml version="1.0" encoding="UTF-8"?>
<hudson.model.ListView>
  <name>myview</name>
  <description>测试试图</description>
  <filterExecutors>false</filterExecutors>
  <filterQueue>false</filterQueue>
  <properties class="hudson.model.View$PropertyList"/>
  <jobNames>
    <comparator class="hudson.util.CaseInsensitiveComparator"/>
    <string>ansible-playbook</string>
    <string>my-github</string>
  </jobNames>
  <jobFilters/>
  <columns>
    <hudson.views.StatusColumn/>
    <hudson.views.WeatherColumn/>
    <hudson.views.JobColumn/>
    <hudson.views.LastSuccessColumn/>
    <hudson.views.LastDurationColumn/>
    <hudson.views.BuildButtonColumn/>
    <hudson.plugins.git.GitBranchSpecifierColumn plugin="git@3.7.0"/>
  </columns>
  <recurse>false</recurse>
</hudson.model.ListView>
'''

总结

建议使用Python-Jenkins模块,相对JenkinsApi而言,模块封装的更好。接口调用更方便,更容易上手,模块内容不是很多,可以自己研读源码进行二次开发,方便与其他系统集成,更好的落地DevOps方案的实施;