From 7d0d82d0ccbab30432a2566caa02a48fcbcf16a0 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Wed, 12 Dec 2012 02:33:42 +0000 Subject: [PATCH] Add script to sync jenkins role setting This is related with http://reviews.cloudfoundry.org/#/c/12321/. Running this script could sync the current admins and role setting to deployment manifest. Change-Id: I5f2389d92f999dc8de2be622720654e13abcddbc --- sync_jenkins_jobs/sync_jenkins_common.rb | 42 ++++++++++ sync_jenkins_jobs/sync_jenkins_jobs.rb | 38 +-------- sync_jenkins_jobs/sync_jenkins_roles.rb | 100 +++++++++++++++++++++++ 3 files changed, 143 insertions(+), 37 deletions(-) create mode 100644 sync_jenkins_jobs/sync_jenkins_common.rb create mode 100644 sync_jenkins_jobs/sync_jenkins_roles.rb diff --git a/sync_jenkins_jobs/sync_jenkins_common.rb b/sync_jenkins_jobs/sync_jenkins_common.rb new file mode 100644 index 0000000..680d796 --- /dev/null +++ b/sync_jenkins_jobs/sync_jenkins_common.rb @@ -0,0 +1,42 @@ +require "logger" +require "optparse" +require "set" +require "tmpdir" +require "yaml" + +def system!(logger, cmd) + logger.info("+ #{cmd}") + unless system(cmd) + raise "Failed executing '#{cmd}'" + end + + true +end + +def parse_jenkins_ip(manifest_path) + manifest = YAML.load_file(manifest_path) + unless jobs = manifest["jobs"] + raise "No jobs found in manifest" + end + + jenkins_job = jobs.select {|j| j["name"] == "jenkins"}.first + unless jenkins_job + raise "Jenkins job not found in manifest" + end + + unless networks = jenkins_job["networks"] + raise "No networks found for jenkins" + end + + nets = Set.new(%w[jenkins default]) + net = networks.select {|n| nets.include?(n["name"]) }.first + unless net + raise "No network found" + end + + unless ips = net["static_ips"] + raise "No static ips found in jenkins default network" + end + + ips.first +end diff --git a/sync_jenkins_jobs/sync_jenkins_jobs.rb b/sync_jenkins_jobs/sync_jenkins_jobs.rb index b396524..dbe3ac0 100644 --- a/sync_jenkins_jobs/sync_jenkins_jobs.rb +++ b/sync_jenkins_jobs/sync_jenkins_jobs.rb @@ -3,43 +3,7 @@ require "set" require "tmpdir" require "yaml" - -def system!(logger, cmd) - logger.info("+ #{cmd}") - unless system(cmd) - raise "Failed executing '#{cmd}'" - end - - true -end - -def parse_jenkins_ip(manifest_path) - manifest = YAML.load_file(manifest_path) - unless jobs = manifest["jobs"] - raise "No jobs found in manifest" - end - - jenkins_job = jobs.select {|j| j["name"] == "jenkins"}.first - unless jenkins_job - raise "Jenkins job not found in manifest" - end - - unless networks = jenkins_job["networks"] - raise "No networks found for jenkins" - end - - nets = Set.new(%w[jenkins default]) - net = networks.select {|n| nets.include?(n["name"]) }.first - unless net - raise "No network found" - end - - unless ips = net["static_ips"] - raise "No static ips found in jenkins default network" - end - - ips.first -end +require File.expand_path(File.dirname(__FILE__) + '/sync_jenkins_common.rb') def rsync_live_configs(logger, jenkins_ip) job_dir = Dir.mktmpdir diff --git a/sync_jenkins_jobs/sync_jenkins_roles.rb b/sync_jenkins_jobs/sync_jenkins_roles.rb new file mode 100644 index 0000000..8cc7a03 --- /dev/null +++ b/sync_jenkins_jobs/sync_jenkins_roles.rb @@ -0,0 +1,100 @@ +require "logger" +require "optparse" +require "set" +require "tmpdir" +require "yaml" +require 'rexml/document' +include REXML + +require File.expand_path(File.dirname(__FILE__) + '/sync_jenkins_common.rb') + +ADMIN_MEMBER_PATH = "hudson/authorizationStrategy/roleMap[@type='globalRoles']/role[@name='admin']/assignedSIDs/sid" +ROLE_PATH = "hudson/authorizationStrategy/roleMap[@type='projectRoles']/role" + +def fetch_jenkins_config(logger, jenkins_ip) + jenkins_config_dir = Dir.mktmpdir + config_local_copy = File.expand_path("config.xml", jenkins_config_dir) + cmd = ["rsync -e ssh -az ", + "vcap@#{jenkins_ip}:/var/vcap/store/jenkins/config.xml", + config_local_copy].join(" ") + system!(logger, cmd) + config_local_copy +end + +def sync_role_info(logger, manifest_path, jenkins_config) + manifest = YAML.load_file(manifest_path) + config_xml = Document.new(File.new(jenkins_config)) + + # sync admin members + admins = Array.new + config_xml.each_element(ADMIN_MEMBER_PATH){ |admin| + admins.push(admin.text) + } + manifest['properties']['jenkins']['admins'] = admins + + # sync roles + role_setting = Array.new + config_xml.each_element(ROLE_PATH){ |role| + members = Array.new + role.each_element("assignedSIDs/sid"){ |member| + members.push(member.text) + } + role_setting.push({'name' => role.attributes['name'], 'regex' => role.attributes['pattern'], 'members' => members.join(",") }) + } + manifest['properties']['jenkins']['views'] = role_setting + + # save updated manifest yaml + File.open(manifest_path, 'w') do |out| + YAML.dump(manifest, out) + end + + # remove trailing blankspace generated by YAML.dump + system!(logger, "sed -i 's/[ \t]*$//' #{manifest_path}") +end + + +opts = { + :verbose => false, +} + +opt_parser = OptionParser.new do |op| + op.banner = "Synchronize live Jenkins job configs with a release repo\n\n" + + op.on("-v", "--verbose", "Print debugging information") do + opts[:verbose] = true + end + +end +opt_parser.parse!(ARGV) + +unless ARGV.length == 1 + puts "Usage: sync_jenkins_roles.rb [/path/to/deployment_manifest]" + puts + puts opt_parser.help + exit 1 +end + +logger = Logger.new(STDOUT) +if opts[:verbose] + logger.level = Logger::DEBUG +else + logger.level = Logger::INFO +end + +manifest_path = ARGV[0] + +begin + jenkins_ip = parse_jenkins_ip(manifest_path) + logger.info("Found jenkins ip: #{jenkins_ip}") + + jenkins_config = fetch_jenkins_config(logger, jenkins_ip) + logger.info("Fetch jenkins config") + + sync_role_info(logger, manifest_path, jenkins_config) + logger.info("Synchronizing role information") + + logger.info("Done") +rescue => e + logger.error(e.to_s) + logger.debug(e.backtrace.join("\n")) if e.backtrace +end