jenkins-config-finder 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fb7b5cdfa0594c4c1f6ab50459e6e5dbb69fb06c
4
+ data.tar.gz: e4a89e1cb0fde86776c50e98a44d55ec0359ed40
5
+ SHA512:
6
+ metadata.gz: 1e1b771ed06e5cb11d1c355808c93f1e4a5da8385f12769077e01aa591bbdaffb33ab057aefba37542566a83c43391ab66c4bd43a25aeb34056a9e91300d646c
7
+ data.tar.gz: 33769b77f235c956e5ae9adad8ba8cdb491d970dd5d37f8a4879ae55599f2e14d81676182bc88f58711e908eeaba5e709811a7ef0853621f5b9803e2f2007726
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.8.7
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+
4
+ gem "jenkins_api_client"
5
+ gem "nokogiri"
6
+ gemspec
7
+
8
+ group :development, :test do
9
+ gem "simplecov"
10
+ gem "yard"
11
+ gem "rspec"
12
+ gem "webmock"
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Bradley, Dan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ Jenkins config finder.
2
+
3
+ Searches a jenkins server amongst all the jobs to find a supplied pattern.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ require "yard"
4
+ require 'yard/rake/yardoc_task'
5
+
6
+ YARD::Rake::YardocTask.new do |t|
7
+ t.files = ['lib/**/*.rb'] # optional
8
+ t.stats_options = ['--list-undoc'] # optional
9
+ end
10
+
11
+ RSpec::Core::RakeTask.new
12
+
13
+ task :default => :spec
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'jenkins_config_finder'
5
+
6
+ options = {}
7
+
8
+ optparse = OptionParser.new do |opts|
9
+ opts.banner = "Usage: jenkins-config-finder [options]"
10
+
11
+ opts.on("-u", "--username USERNAME", "Username") do |user|
12
+ options[:user] = user
13
+ end
14
+ opts.on("-p", "--password PASSWORD", "Password") do |password|
15
+ options[:password] = password
16
+ end
17
+ opts.on("-s", "--server URL", "URL of the Jenkins server") do |url|
18
+ options[:url] = url
19
+ end
20
+ opts.on("-x", "--xml-path PATH", "XML Path to search for i.e. //project//description") do |path|
21
+ options[:path] = path
22
+ end
23
+ opts.on("-n", "--node NODE", "NODE to print i.e. name") do |node|
24
+ options[:node] = node
25
+ end
26
+ end
27
+
28
+ begin
29
+ optparse.parse!
30
+ mandatory = [:url, :user, :password, :path]
31
+ missing = mandatory.select{ |param| options[param].nil? }
32
+ if not missing.empty?
33
+ puts "Missing options: #{missing.join(', ')}"
34
+ puts optparse
35
+ exit
36
+ end
37
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
38
+ puts $!.to_s
39
+ puts optparse
40
+ exit
41
+ end
42
+
43
+ JenkinsConfigFinder.connect(options[:url], options[:user], options[:password])
44
+ jenkins_config = JenkinsConfigFinder.find(options[:path], options[:node])
45
+
46
+ jenkins_config.each do |key, value|
47
+ puts "::::::::#{key}::::::::"
48
+ puts value
49
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "jenkins-config-finder"
7
+ spec.version = "0.1"
8
+ spec.authors = ["Bradley, Dan"]
9
+ spec.email = ["danb468@gmail.com"]
10
+ spec.summary = %q{Search configurations for all jenkins jobs}
11
+ spec.description = %q{Find configuration items across all jenkins jobs}
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.6"
21
+ spec.add_development_dependency "rake"
22
+ end
@@ -0,0 +1,81 @@
1
+
2
+ require 'jenkins_api_client'
3
+ require 'nokogiri'
4
+
5
+
6
+
7
+ module JenkinsConfigFinder
8
+
9
+ # Establishes a connection to the jenkins server
10
+ #
11
+ # ==== Attributes
12
+ # * +url+ A URL for a jenkins server
13
+ # * +user+ The username for jenkins
14
+ # * +password+ The password for the user
15
+ def self.connect(url, user, password)
16
+ @client = JenkinsApi::Client.new(:server_url => url,
17
+ :username => user,
18
+ :password => password,
19
+ :log_location => '/dev/null')
20
+
21
+ end
22
+
23
+ # Searches all jobs in the jenkins server looking for the supplied path
24
+ #
25
+ # ==== Attributes
26
+ #
27
+ # * +path+ An xpath node to search for
28
+ # * +node+ Returns a node matched under the path (Optional)
29
+ #
30
+ # ==== Examples
31
+ #
32
+ # # Find and return all projects descriptions
33
+ # JenkinsConfigFinder.find('project//description')
34
+ # # Find and return all git repositories urls
35
+ # JenkinsConfigFinder.find('@class:hudson.plugins.git.GitSCM', //hudson.plugins.git.UserRemoteConfig//url)
36
+ #
37
+ # ==== Returns
38
+ #
39
+ # * a hash of all the matching jenkins jobs as keys, and the value being the matched config
40
+ def self.find(path, node = nil)
41
+
42
+ jenkins_config = {}
43
+ jobs = @client.job.list(".*")
44
+
45
+ job = JenkinsApi::Client::Job.new(@client)
46
+ jobs.each do |j|
47
+ config = job.get_config(j)
48
+ config_obj = Nokogiri::XML(config)
49
+ if node.nil?
50
+ if config_obj.root.at_xpath(path)
51
+ jenkins_config[j] = config_obj.root.at_xpath("#{path}").content.to_s
52
+ end
53
+ else
54
+ if config_obj.root.at_xpath("#{path}//#{node}")
55
+ jenkins_config[j] = config_obj.root.at_xpath("#{path}//#{node}").content.to_s
56
+ end
57
+ end
58
+ if config_obj.root.at_xpath("//project//properties//hudson.plugins.promoted__builds.JobPropertyImpl")
59
+ promotion_name = config_obj.root.at_xpath("//project//properties//hudson.plugins.promoted__builds.JobPropertyImpl//activeProcessNames//string").content
60
+ begin
61
+ promotion_config = job.get_config("#{j}/promotion/process/#{promotion_name}")
62
+ rescue JenkinsApi::Exceptions::NotFound
63
+ promotion_config = nil
64
+ end
65
+
66
+ unless promotion_config.nil?
67
+ promotion_obj = Nokogiri::XML(promotion_config)
68
+ if node.nil? then
69
+ if promotion_obj.root.at_xpath(path)
70
+ jenkins_config["#{j}/#{promotion_name}"] = promotion_obj.root.at_xpath("#{path}").content.to_s
71
+ end
72
+ elsif promotion_obj.root.at_xpath("#{path}//#{node}")
73
+ jenkins_config["#{j}/#{promotion_name}"] = promotion_obj.root.at_xpath("#{path}//#{node}").content.to_s
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ return jenkins_config
80
+ end
81
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'pp'
3
+
4
+ describe JenkinsConfigFinder do
5
+ before do
6
+ stub_request(:any, "http://mock_user:mock_password@www.x.com/api/json").to_return(:body => %q|{ "jobs": [ { "name": "job1", "url": "http://www.x.com/job/job1", "color": "blue" }, { "name": "job2", "url": "http://www.x.com/job/job2", "color": "blue" } ] }|)
7
+ stub_request(:any, "http://mock_user:mock_password@www.x.com/job/job1/config.xml").to_return(:body => %q|<?xml version='1.0' encoding='UTF-8'?>
8
+ <project>
9
+ <description>MY_JOB_1</description>
10
+ </project>|)
11
+ stub_request(:any, "http://mock_user:mock_password@www.x.com/job/job2/config.xml").to_return(:body => %q|<?xml version='1.0' encoding='UTF-8'?>
12
+ <project>
13
+ <description>MY_JOB_2</description>
14
+ <properties>
15
+ <hudson.plugins.promoted__builds.JobPropertyImpl plugin="promoted-builds@2.18">
16
+ <activeProcessNames>
17
+ <string>push_test</string>
18
+ <activeProcessNames>
19
+ </hudson.plugins.promoted__builds.JobPropertyImpl>
20
+ <hudson.plugins.jacoco.JacocoPublisher plugin="jacoco@1.0.16">
21
+ <minimumMethodCoverage>0</minimumMethodCoverage>
22
+ </hudson.plugins.jacoco.JacocoPublisher>
23
+ </properties></project>|)
24
+ stub_request(:any, "http://mock_user:mock_password@www.x.com/job/job2/promotion/process/push_test/config.xml").to_return(:body => %q|<?xml version='1.0' encoding='UTF-8'?>
25
+ <hudson.plugins.promoted__builds.PromotionProcess plugin="promoted-builds@2.17">
26
+ <disabled>nope</disabled>
27
+ <buildSteps></buildSteps>
28
+ </hudson.plugins.promoted__builds.PromotionProcess>|)
29
+ end
30
+
31
+ describe "Connect" do
32
+ it "connects to jenkins" do
33
+ expect(
34
+ lambda do
35
+ JenkinsConfigFinder.connect('http://www.x.com', 'mock_user', 'mock_password')
36
+ end
37
+ ).not_to raise_error
38
+ end
39
+
40
+ it "searches jenkins" do
41
+ JenkinsConfigFinder.connect('http://www.x.com', 'mock_user', 'mock_password')
42
+ conf = JenkinsConfigFinder.find("//project//description")
43
+ conf.should include('job1' => 'MY_JOB_1')
44
+ end
45
+
46
+ it "searches jenkins with a node" do
47
+ JenkinsConfigFinder.connect('http://www.x.com', 'mock_user', 'mock_password')
48
+ conf = JenkinsConfigFinder.find("//hudson.plugins.jacoco.JacocoPublisher", "minimumMethodCoverage")
49
+ conf.should include('job2' => '0')
50
+ end
51
+
52
+ it "searches a promotion job" do
53
+ JenkinsConfigFinder.connect('http://www.x.com', 'mock_user', 'mock_password')
54
+ conf = JenkinsConfigFinder.find("//disabled")
55
+ conf.should include('job2/push_test' => 'nope')
56
+ end
57
+
58
+ it "searches a promotion job for a node" do
59
+ JenkinsConfigFinder.connect('http://www.x.com', 'mock_user', 'mock_password')
60
+ conf = JenkinsConfigFinder.find("//hudson.plugins.promoted__builds.PromotionProcess", "disabled")
61
+ conf.should include('job2/push_test' => 'nope')
62
+ end
63
+
64
+ it "searches for something not found" do
65
+ JenkinsConfigFinder.connect('http://www.x.com', 'mock_user', 'mock_password')
66
+ conf = JenkinsConfigFinder.find("//monkeys")
67
+ expect(conf).to be_empty
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,17 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'rspec'
5
+ require 'webmock/rspec'
6
+
7
+ require_relative '../lib/jenkins_config_finder'
8
+
9
+ RSpec.configure do |config|
10
+ config.expect_with :rspec do |c|
11
+ c.syntax = [:should, :expect]
12
+ end
13
+
14
+ config.mock_with :rspec do |c|
15
+ c.syntax = [:should, :expect]
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jenkins-config-finder
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Bradley, Dan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Find configuration items across all jenkins jobs
42
+ email:
43
+ - danb468@gmail.com
44
+ executables:
45
+ - jenkins-config-finder.rb
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".travis.yml"
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - bin/jenkins-config-finder.rb
57
+ - jenkins-config-finder.gemspec
58
+ - lib/jenkins_config_finder.rb
59
+ - spec/jenkins_config_finder_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: ''
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.2.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Search configurations for all jenkins jobs
85
+ test_files:
86
+ - spec/jenkins_config_finder_spec.rb
87
+ - spec/spec_helper.rb
88
+ has_rdoc: