From 2974f1e636ad9a307a57a7865d1e200fb320f87b Mon Sep 17 00:00:00 2001 From: Thanh Ha Date: Tue, 7 Jun 2016 16:10:53 -0400 Subject: [PATCH] Allow update to provide plugin_info via yaml Getting plugin info requires Administrator permissions. It seems the test command allows providing the plugin_info details via a yaml configuration file. This patch allows the same command to be passed to the update command to allow us to configure the plugin versions manually and not require administrator permissions. Additionally this patch adds a new command called get-plugins-info which can create the plugins_info.yaml file to pass to the plugin_info_path. See: http://lists.openstack.org/pipermail/openstack-infra/2016-June/004388.html Change-Id: I5a34979407d863a84f34afbf8f565081ec52190a Signed-off-by: Thanh Ha --- doc/source/execution.rst | 19 +++++++ doc/source/quick-start.rst | 12 ++++ .../cli/subcommand/get_plugins_info.py | 57 +++++++++++++++++++ jenkins_jobs/cli/subcommand/test.py | 2 +- jenkins_jobs/cli/subcommand/update.py | 7 +++ setup.cfg | 1 + 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 jenkins_jobs/cli/subcommand/get_plugins_info.py diff --git a/doc/source/execution.rst b/doc/source/execution.rst index 43a859372..1006e818b 100644 --- a/doc/source/execution.rst +++ b/doc/source/execution.rst @@ -313,6 +313,22 @@ To delete jobs/views that only have 'foo' in their name:: jenkins-jobs delete --path ./myjobs \*foo\* +Providing Plugins Info +^^^^^^^^^^^^^^^^^^^^^^ +With Jenkins LTS 1.651.1+ retrieving plugins info became a secure feature and +now requires Administrator rights to use [#f2]. This causes JJB to no longer be +able to work in situations where a user wants to publish jobs to Jenkins but is +not able to receive the Administrator permissions. In this case we can provide +a plugins_info.yaml file containing the plugin versions data needed by JJB to +parse the job templates. + +To generate a plugins info, using an account with Administrator rights: + + jenkins-jobs get-plugins-info -o plugins_info.yaml + +To run JJB update using the plugins_info.yaml: + + jenkins-jobs update -p plugins_info.yaml ./myjobs .. _command-reference: @@ -323,8 +339,11 @@ Command Reference .. program-output:: jenkins-jobs update --help .. program-output:: jenkins-jobs delete-all --help .. program-output:: jenkins-jobs delete --help +.. program-output:: jenkins-jobs get-plugins-info --help .. rubric:: Footnotes .. [#f1] The cache default location is at ``~/.cache/jenkins_jobs``, which can be overridden by setting the ``XDG_CACHE_HOME`` environment variable. +.. [#f2] Jenkins Security Advisory affecting plugins info retrieval + https://wiki.jenkins-ci.org/display/SECURITY/Jenkins+Security+Advisory+2016-05-11 diff --git a/doc/source/quick-start.rst b/doc/source/quick-start.rst index 6b1edba4e..64a3c38f5 100644 --- a/doc/source/quick-start.rst +++ b/doc/source/quick-start.rst @@ -80,6 +80,18 @@ To delete a job:: The above command deletes the job `simple` from the Jenkins master. +.. _use-case-5: + +Use Case 5: Providing plugins info +---------------------------------- + +To generate a plugins info, using an account with Administrator rights: + + jenkins-jobs get-plugins-info -o plugins_info.yaml + +To run JJB update using the plugins_info.yaml: + + jenkins-jobs update -p plugins_info.yaml ./myjobs Please refer to the jenkins-jobs :ref:`command-reference` and the diff --git a/jenkins_jobs/cli/subcommand/get_plugins_info.py b/jenkins_jobs/cli/subcommand/get_plugins_info.py new file mode 100644 index 000000000..748cbf6c9 --- /dev/null +++ b/jenkins_jobs/cli/subcommand/get_plugins_info.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# Copyright (C) 2017 Thanh Ha +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +import yaml + +from jenkins_jobs.builder import JenkinsManager +import jenkins_jobs.cli.subcommand.base as base + + +logger = logging.getLogger(__name__) + + +class GetPluginsInfoSubCommand(base.BaseSubCommand): + + def parse_args(self, subparser): + plugins_info = subparser.add_parser( + 'get-plugins-info', + help='get plugins info yaml by querying Jenkins server.') + + plugins_info.add_argument( + '-o', '--output-file', + default='plugins_info.yaml', + dest='plugins_info_file', + help='file to save output to.') + + def execute(self, options, jjb_config): + builder = JenkinsManager(jjb_config) + plugin_data = builder.jenkins.get_plugins_info() + plugins_info = [] + for plugin in plugin_data: + info = { + 'longName': str(plugin['longName']), + 'shortName': str(plugin['shortName']), + 'version': str(plugin['version']), + } + plugins_info.append(info) + + if options.plugins_info_file: + with open(options.plugins_info_file, 'w') as outfile: + outfile.write(yaml.dump(plugins_info)) + logger.info("Generated {} file".format(options.plugins_info_file)) + else: + print(yaml.dump(plugins_info)) diff --git a/jenkins_jobs/cli/subcommand/test.py b/jenkins_jobs/cli/subcommand/test.py index 3fe4b5b1e..ff31285e8 100644 --- a/jenkins_jobs/cli/subcommand/test.py +++ b/jenkins_jobs/cli/subcommand/test.py @@ -39,7 +39,7 @@ class TestSubCommand(update.UpdateSubCommand): default=False, help='use alternative output file layout using config.xml files') test.add_argument( - '-p', + '-p', '--plugin-info', dest='plugins_info_path', default=None, help='path to plugin info YAML file') diff --git a/jenkins_jobs/cli/subcommand/update.py b/jenkins_jobs/cli/subcommand/update.py index 03901c2f4..a7aefa54f 100644 --- a/jenkins_jobs/cli/subcommand/update.py +++ b/jenkins_jobs/cli/subcommand/update.py @@ -58,6 +58,13 @@ class UpdateSubCommand(base.BaseSubCommand): dest='delete_old', default=False, help='delete obsolete jobs') + update.add_argument( + '-p', '--plugin-info', + dest='plugins_info_path', + default=None, + help='path to plugin info YAML file. Can be used to provide ' + 'previously retrieved plugins info when connecting credentials ' + 'don\'t have permissions to query.') update.add_argument( '--workers', type=int, diff --git a/setup.cfg b/setup.cfg index eaeda0fcb..1d5a34aab 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,7 @@ jjb.cli.subcommands = test=jenkins_jobs.cli.subcommand.test:TestSubCommand delete=jenkins_jobs.cli.subcommand.delete:DeleteSubCommand delete-all=jenkins_jobs.cli.subcommand.delete_all:DeleteAllSubCommand + get-plugins-info=jenkins_jobs.cli.subcommand.get_plugins_info:GetPluginsInfoSubCommand jenkins_jobs.projects = externaljob=jenkins_jobs.modules.project_externaljob:ExternalJob flow=jenkins_jobs.modules.project_flow:Flow