knife-github 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [2013] [Sander Botman]
189
+ Copyright [yyyy] [name of copyright owner]
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -1,4 +1,40 @@
1
1
  knife-github
2
2
  ============
3
3
 
4
- Chef knife plugin to interact with the github enterprise appliance
4
+ Chef knife plugin to interact with the github enterprise appliance.
5
+
6
+ Attributes
7
+ ==========
8
+
9
+ You can configure the following attributes within your knife.rb
10
+
11
+ knife[:github_url] = 'https://github.company.lan'
12
+ knife[:github_organizations] = [ 'customer-cookbooks', 'central-cookbooks' ]
13
+ knife[:github_link] = 'ssh'
14
+ knife[:github_api_version] = 'v3'
15
+ knife[:github_cache] = 900
16
+ knife[:github_ssl_verify_mode] = 'verify_none'
17
+
18
+ ###### github_url
19
+ This will be the URL to your local github appliance.
20
+ Here you can also use the github.com address if you don't have an internal appliance.
21
+
22
+ ###### github_organizations
23
+ Here you specify the organizations that you want to taget when searching for cookbooks.
24
+ The first entry will have priority over the other entries.
25
+
26
+ ###### github_link \<optional\>
27
+ You can specify the link type that you would like to use to download your cookbooks, default is <tt>ssh</tt>.
28
+ Options are <tt>ssh</tt> <tt>git</tt> <tt>http</tt> <tt>https</tt> <tt>svn</tt>
29
+
30
+ ###### github_api_version \<optional\>
31
+ The current and default version of the api is <tt>v3</tt> but this will allow you to target older versions if needed.
32
+
33
+ ###### github_cache \<optional\>
34
+ This will be the lifetime of the cache files in seconds, default <tt>900</tt>. Cache files will be created into the: ~/.chef directory.
35
+ We use cache files to offload the api calls and increase the performance for additional executions.
36
+
37
+ ###### github_ssl_verify_mode \<optional\>
38
+ The plugin is using the underlying knife http implementation, hence it will have the same options to handle ssl.
39
+ Currently the options are: <tt>verify_peer</tt> <tt>verify_none</tt>
40
+
data/knife-github.gemspec CHANGED
@@ -18,5 +18,5 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- # s.add_dependency "chef", "~> 0.10.0"
21
+ s.add_dependency "chef", "~> 11.0.0"
22
22
  end
@@ -0,0 +1,134 @@
1
+ #
2
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ # require 'chef/knife'
20
+
21
+ class Chef
22
+ class Knife
23
+ module GithubBase
24
+
25
+ def self.included(includer)
26
+ includer.class_eval do
27
+
28
+ deps do
29
+ require 'chef/mixin/shell_out'
30
+ end
31
+
32
+ option :github_url,
33
+ :long => "--github_url URL",
34
+ :description => "URL of the github enterprise appliance"
35
+
36
+ option :github_organizations,
37
+ :long => "--github_org ORG:ORG",
38
+ :description => "Lookup chef cookbooks in this colon-separated list of organizations",
39
+ :proc => lambda { |o| o.split(":") }
40
+
41
+ option :github_link,
42
+ :long => "--github_link TYPE",
43
+ :description => "Link type: ssh, http, git (dafault: ssh)"
44
+
45
+ option :github_api_version,
46
+ :long => "--github_api_ver VERSION",
47
+ :description => "Version number of the API (default: v3)"
48
+
49
+ option :github_ssl_verify_mode,
50
+ :long => "--github_ssl_verify_mode",
51
+ :description => "SSL verify mode: verify_peer, verify_none (default: verify_peer)",
52
+ :boolean => true
53
+
54
+ option :github_cache,
55
+ :long => "--github_cache MIN",
56
+ :description => "Max life-time for local cache files in minutes (default: 900)"
57
+
58
+ def validate_base_options
59
+ unless locate_config_value('github_url')
60
+ ui.error "Github URL not specified"
61
+ exit 1
62
+ end
63
+ unless locate_config_value('github_organizations')
64
+ ui.error "Github organization(s) not specified"
65
+ exit 1
66
+ end
67
+
68
+ @github_url = locate_config_value("github_url")
69
+ @github_organizations = locate_config_value("github_organizations")
70
+ @github_cache = (locate_config_value("github_cache") || 900).to_i
71
+ @github_link = locate_config_value("github_link") || 'ssh'
72
+ @github_api_version = locate_config_value("github_api_version") || 'v3'
73
+ @github_ssl_verify_mode = locate_config_value("github_ssl_verify_mode") || 'verify_peer'
74
+ end
75
+
76
+ def display_debug_info
77
+ Chef::Log.debug("github_url: " + @github_url.to_s)
78
+ Chef::Log.debug("github_org: " + @github_organizations.to_s)
79
+ Chef::Log.debug("github_api: " + @github_api_version.to_s)
80
+ Chef::Log.debug("github_link: " + @github_link.to_s)
81
+ Chef::Log.debug("github_cache: " + @github_cache.to_s)
82
+ Chef::Log.debug("github_ssl_mode: " + @github_ssl_verify_mode.to_s)
83
+ end
84
+
85
+ def locate_config_value(key)
86
+ key = key.to_sym
87
+ config[key] || Chef::Config[:knife][key]
88
+ end
89
+
90
+ def get_github_link(link)
91
+ git_link = case link
92
+ when 'ssh' then 'ssh_url'
93
+ when 'http' then 'clone_url'
94
+ when 'https' then 'clone_url'
95
+ when 'svn' then 'svn_url'
96
+ when 'html' then 'html_url'
97
+ when 'git' then 'git_url'
98
+ else 'ssh_url'
99
+ end
100
+ git_link
101
+ end
102
+
103
+ def send_request(url, params = {})
104
+ params['response'] = 'json'
105
+
106
+ params_arr = []
107
+ params.sort.each { |elem|
108
+ params_arr << elem[0].to_s + '=' + CGI.escape(elem[1].to_s).gsub('+', '%20').gsub(' ','%20')
109
+ }
110
+ data = params_arr.join('&')
111
+
112
+ github_url = "#{url}?#{data}"
113
+ # Chef::Log.debug("URL: #{github_url}")
114
+
115
+ uri = URI.parse(github_url)
116
+ req_body = Net::HTTP::Get.new(uri.request_uri)
117
+ request = Chef::REST::RESTRequest.new("GET", uri, req_body, headers={})
118
+
119
+ response = request.call
120
+
121
+ if !response.is_a?(Net::HTTPOK) then
122
+ puts "Error #{response.code}: #{response.message}"
123
+ puts JSON.pretty_generate(JSON.parse(response.body))
124
+ puts "URL: #{url}"
125
+ exit 1
126
+ end
127
+ json = JSON.parse(response.body)
128
+ end
129
+
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,244 @@
1
+ #
2
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+
21
+ class Chef
22
+ class Knife
23
+
24
+ class GithubCompare < Knife
25
+
26
+ deps do
27
+ require 'chef/knife/github_base'
28
+
29
+ include Chef::Knife::GithubBase
30
+ end
31
+
32
+ banner "knife github compare [COOKBOOK] (options)"
33
+ category "github"
34
+
35
+ option :fields,
36
+ :long => "--fields 'NAME, NAME'",
37
+ :description => "The fields to output, comma-separated"
38
+
39
+ option :noheader,
40
+ :long => "--noheader",
41
+ :description => "Removes header from output",
42
+ :boolean => true
43
+
44
+ option :all,
45
+ :short => "-a",
46
+ :long => "--all",
47
+ :description => "Get all cookbooks from github.",
48
+ :boolean => true
49
+
50
+ option :mismatch,
51
+ :short => "-m",
52
+ :long => "--mismatch",
53
+ :description => "Only show cookbooks where versions mismatch",
54
+ :boolean => true
55
+
56
+ def run
57
+ # extend Chef::Mixin::ShellOut
58
+ # validate base options from base module.
59
+ validate_base_options
60
+
61
+ # Display information if debug mode is on.
62
+ display_debug_info
63
+
64
+ # Gather all repo information from github.
65
+ get_all_repos = get_all_repos(@github_organizations.reverse)
66
+
67
+
68
+ # Get all chef cookbooks and versions (hopefully chef does the error handeling).
69
+ cb_and_ver = rest.get_rest("/cookbooks?num_version=1")
70
+
71
+
72
+ # Filter all repo information based on the tags that we can find
73
+ all_repos = {}
74
+ if config[:all]
75
+ get_all_repos.each { |k,v|
76
+ cookbook = k
77
+ cb_and_ver[k].nil? || cb_and_ver[k]['versions'].nil? ? version = "" : version = cb_and_ver[k]['versions'][0]['version']
78
+ ssh_url = v['ssh_url']
79
+ gh_tag = v['latest_tag']
80
+ all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'ssh_url' => ssh_url, 'latest_gh_tag' => gh_tag }
81
+ }
82
+ else
83
+ cb_and_ver.each { |k,v|
84
+ cookbook = k
85
+ version = v['versions'][0]['version']
86
+ get_all_repos[k].nil? || get_all_repos[k]['ssh_url'].nil? ? ssh_url = ui.color("ERROR: Cannot find cookbook!", :red) : ssh_url = get_all_repos[k]['ssh_url']
87
+ get_all_repos[k].nil? || get_all_repos[k]['latest_tag'].nil? ? gh_tag = ui.color("ERROR: No tags!", :red) : gh_tag = get_all_repos[k]['latest_tag']
88
+ all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'ssh_url' => ssh_url, 'latest_gh_tag' => gh_tag }
89
+ }
90
+ end
91
+
92
+
93
+ # Filter only on the cookbook name if its given on the command line
94
+ @cookbook_name = name_args.first unless name_args.empty?
95
+ if @cookbook_name
96
+ repos = all_repos.select { |k,v| v["name"] == @cookbook_name }
97
+ else
98
+ repos = all_repos
99
+ end
100
+
101
+
102
+ # Displaying information based on the fields and repos
103
+ if config[:fields]
104
+ object_list = []
105
+ config[:fields].split(',').each { |n| object_list << ui.color(("#{n}").strip, :bold) }
106
+ else
107
+ object_list = [
108
+ ui.color('Cookbook', :bold),
109
+ ui.color('Tag', :bold),
110
+ ui.color('Github', :bold),
111
+ ui.color('Tag', :bold)
112
+ ]
113
+ end
114
+
115
+ columns = object_list.count
116
+ object_list = [] if config[:noheader]
117
+
118
+ repos.each do |k,r|
119
+ if config[:fields]
120
+ config[:fields].downcase.split(',').each { |n| object_list << ((r[("#{n}").strip]).to_s || 'n/a') }
121
+ else
122
+ next if config[:mismatch] && (r['latest_gh_tag'] == r['latest_cb_tag'])
123
+ r['latest_gh_tag'] == r['latest_cb_tag'] ? color = :white : color = :yellow
124
+ color = :white if config[:all]
125
+
126
+ object_list << ui.color((r['name'] || 'n/a'), color)
127
+ object_list << ui.color((r['latest_cb_tag'] || 'n/a'), color)
128
+ object_list << ui.color((r['ssh_url'] || 'n/a'), color)
129
+ object_list << ui.color((r['latest_gh_tag'] || 'n/a'), color)
130
+ end
131
+ end
132
+
133
+ puts ui.list(object_list, :uneven_columns_across, columns)
134
+
135
+ end
136
+
137
+ def get_all_repos(orgs)
138
+ # Parse every org and merge all into one hash
139
+ repos = {}
140
+ orgs.each do |org|
141
+ get_repos(org).each { |repo| name = repo['name'] ; repos["#{name}"] = repo }
142
+ end
143
+ repos
144
+ end
145
+
146
+
147
+
148
+ def get_repos(org)
149
+ dns_name = get_dns_name(@github_url)
150
+ file_cache = "#{ENV['HOME']}/.chef/.#{dns_name.downcase}_#{org.downcase}.cache"
151
+ if File.exists?(file_cache)
152
+ Chef::Log.debug("#{org} cache is created: " + (Time.now - File.ctime(file_cache)).to_i.to_s + " seconds ago.")
153
+ if Time.now - File.ctime(file_cache) > @github_cache
154
+ # update cache file
155
+ create_cache_file(file_cache, org)
156
+ end
157
+ else
158
+ create_cache_file(file_cache, org)
159
+ end
160
+ # use cache files
161
+ JSON.parse(File.read(file_cache))
162
+ end
163
+
164
+ def create_cache_file(file_cache, org)
165
+ Chef::Log.debug("Updating the cache file: #{file_cache}")
166
+ result = get_repos_github(org)
167
+ File.open(file_cache, 'w') { |file| file.write(JSON.pretty_generate(result)) }
168
+ end
169
+
170
+
171
+
172
+ def get_repos_github(org)
173
+ # Get all repo's for the org from github
174
+ arr = []
175
+ page = 1
176
+ url = @github_url + "/api/" + @github_api_version + "/orgs/" + org + "/repos"
177
+ while true
178
+ params = { 'page' => page }
179
+ result = send_request(url, params)
180
+ break if result.nil? || result.count < 1
181
+ result.each { |key|
182
+ if key['tags_url']
183
+ tags = get_tags(key)
184
+ key['tags'] = tags unless tags.nil? || tags.empty?
185
+ key['latest_tag'] = tags.first['name'] unless tags.nil? || tags.empty?
186
+ arr << key
187
+ else
188
+ arr << key
189
+ end
190
+ }
191
+ page = page + 1
192
+ end
193
+ arr
194
+ end
195
+
196
+
197
+ def get_tags(repo)
198
+ tags = send_request(repo['tags_url'])
199
+ tags
200
+ end
201
+
202
+
203
+ def get_dns_name(url)
204
+ url = url.downcase.gsub("http://","") if url.downcase.start_with?("http://")
205
+ url = url.downcase.gsub("https://","") if url.downcase.start_with?("https://")
206
+ url
207
+ end
208
+
209
+
210
+ def send_request(url, params = {})
211
+ params['response'] = 'json'
212
+
213
+ params_arr = []
214
+ params.sort.each { |elem|
215
+ params_arr << elem[0].to_s + '=' + CGI.escape(elem[1].to_s).gsub('+', '%20').gsub(' ','%20')
216
+ }
217
+ data = params_arr.join('&')
218
+
219
+ if url.nil? || url.empty?
220
+ puts "Error: Please specify a valid Github URL."
221
+ exit 1
222
+ end
223
+
224
+ github_url = "#{url}?#{data}"
225
+ # Chef::Log.debug("URL: #{github_url}")
226
+
227
+ uri = URI.parse(github_url)
228
+ req_body = Net::HTTP::Get.new(uri.request_uri)
229
+ request = Chef::REST::RESTRequest.new("GET", uri, req_body, headers={})
230
+
231
+ response = request.call
232
+
233
+ if !response.is_a?(Net::HTTPOK) then
234
+ puts "Error #{response.code}: #{response.message}"
235
+ puts JSON.pretty_generate(JSON.parse(response.body))
236
+ puts "URL: #{url}"
237
+ exit 1
238
+ end
239
+ json = JSON.parse(response.body)
240
+ end
241
+
242
+ end
243
+ end
244
+ end
@@ -24,9 +24,11 @@ class Chef
24
24
  class GithubList < Knife
25
25
 
26
26
  deps do
27
- require 'chef/mixin/shell_out'
28
- end
27
+ require 'chef/knife/github_base'
29
28
 
29
+ include Chef::Knife::GithubBase
30
+ end
31
+
30
32
  banner "knife github list [COOKBOOK] (options)"
31
33
  category "github"
32
34
 
@@ -34,6 +36,11 @@ class Chef
34
36
  :long => "--fields 'NAME, NAME'",
35
37
  :description => "The fields to output, comma-separated"
36
38
 
39
+ option :fieldlist,
40
+ :long => "--fieldlist",
41
+ :description => "The available fields to output/filter",
42
+ :boolean => true
43
+
37
44
  option :noheader,
38
45
  :long => "--noheader",
39
46
  :description => "Removes header from output",
@@ -45,75 +52,49 @@ class Chef
45
52
  :description => "Get all cookbooks from github.",
46
53
  :boolean => true
47
54
 
48
- option :mismatch,
49
- :short => "-m",
50
- :long => "--mismatch",
51
- :description => "Only show cookbooks where versions mismatch",
52
- :boolean => true
53
-
54
- option :github_organizations,
55
- :long => "--github-org ORG:ORG",
56
- :description => "Lookup chef cookbooks in this colon-separated list of organizations",
57
- :proc => lambda { |o| o.split(":") }
58
-
59
- option :github_api_version,
60
- :long => "--github-api_ver VERSION",
61
- :description => "Version number of the API (default is: v3)"
62
-
63
- option :github_url,
64
- :long => "--github-url URL",
65
- :description => "URL of the github enterprise appliance"
66
-
67
- option :github_no_ssl_verify,
68
- :long => "--github-no_ssl_verify",
69
- :description => "Disable ssl verify on the url if https is used.",
70
- :boolean => true
71
-
72
- option :github_cache,
73
- :long => "--github-cache MIN",
74
- :description => "Max life-time for local cache file in minutes."
75
-
76
55
  def run
77
- extend Chef::Mixin::ShellOut
78
-
79
- config[:github_url] ? @github_url = config[:github_url] : @github_url = Chef::Config[:github_url]
80
- config[:github_api_version] ? @github_api_version = config[:github_api_version] : @github_api_version = Chef::Config[:github_api_version] || "v3"
81
- config[:github_no_ssl_verify] ? @github_no_ssl_verify = config[:github_no_ssl_verify] : @github_no_ssl_verify = Chef::Config[:github_no_ssl_verify] || false
82
- config[:github_organizations] ? @github_organizations = config[:github_organizations] : @github_organizations = Chef::Config[:github_organizations]
83
- config[:github_cache] ? @github_cache = config[:github_cache] : @github_cache = Chef::Config[:github_cache] || 900
84
56
 
85
- display_debug_info!
57
+ # validate base options from base module.
58
+ validate_base_options
86
59
 
60
+ # Display information if debug mode is on.
61
+ display_debug_info
87
62
 
88
-
89
- # Gather all repo information from github
63
+ # Gather all repo information from github.
90
64
  get_all_repos = get_all_repos(@github_organizations.reverse)
91
65
 
92
66
 
93
- # Get all chef cookbooks and versions (hopefully chef does the error handeling)
67
+ # Get all chef cookbooks and versions (hopefully chef does the error handeling).
94
68
  cb_and_ver = rest.get_rest("/cookbooks?num_version=1")
95
69
 
96
-
70
+ # Get the github link
71
+ git_link = get_github_link(@github_link)
72
+
73
+
97
74
  # Filter all repo information based on the tags that we can find
75
+ if config[:fields] || config[:fieldlist]
76
+ all_repos = get_all_repos
77
+ config[:fields] = "name" if config[:fields].nil? || config[:fields].empty?
78
+ else
98
79
  all_repos = {}
99
80
  if config[:all]
100
81
  get_all_repos.each { |k,v|
101
82
  cookbook = k
102
83
  cb_and_ver[k].nil? || cb_and_ver[k]['versions'].nil? ? version = "" : version = cb_and_ver[k]['versions'][0]['version']
103
- ssh_url = v['ssh_url']
84
+ gh_url = v["#{git_link}"]
104
85
  gh_tag = v['latest_tag']
105
- all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'ssh_url' => ssh_url, 'latest_gh_tag' => gh_tag }
86
+ all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'git_url' => gh_url, 'latest_gh_tag' => gh_tag }
106
87
  }
107
88
  else
108
89
  cb_and_ver.each { |k,v|
109
90
  cookbook = k
110
91
  version = v['versions'][0]['version']
111
- get_all_repos[k].nil? || get_all_repos[k]['ssh_url'].nil? ? ssh_url = ui.color("ERROR: Cannot find cookbook!", :red) : ssh_url = get_all_repos[k]['ssh_url']
92
+ get_all_repos[k].nil? || get_all_repos[k]["#{git_link}"].nil? ? gh_url = ui.color("ERROR: Cannot find cookbook!", :red) : gh_url = get_all_repos[k]["#{git_link}"]
112
93
  get_all_repos[k].nil? || get_all_repos[k]['latest_tag'].nil? ? gh_tag = ui.color("ERROR: No tags!", :red) : gh_tag = get_all_repos[k]['latest_tag']
113
- all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'ssh_url' => ssh_url, 'latest_gh_tag' => gh_tag }
94
+ all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'git_url' => gh_url, 'latest_gh_tag' => gh_tag }
114
95
  }
115
96
  end
116
-
97
+ end
117
98
 
118
99
  # Filter only on the cookbook name if its given on the command line
119
100
  @cookbook_name = name_args.first unless name_args.empty?
@@ -123,7 +104,6 @@ class Chef
123
104
  repos = all_repos
124
105
  end
125
106
 
126
-
127
107
  # Displaying information based on the fields and repos
128
108
  if config[:fields]
129
109
  object_list = []
@@ -131,9 +111,7 @@ class Chef
131
111
  else
132
112
  object_list = [
133
113
  ui.color('Cookbook', :bold),
134
- ui.color('Tag', :bold),
135
- ui.color('Github', :bold),
136
- ui.color('Tag', :bold)
114
+ ui.color('Github', :bold)
137
115
  ]
138
116
  end
139
117
 
@@ -144,23 +122,45 @@ class Chef
144
122
  if config[:fields]
145
123
  config[:fields].downcase.split(',').each { |n| object_list << ((r[("#{n}").strip]).to_s || 'n/a') }
146
124
  else
147
- next if config[:mismatch] && (r['latest_gh_tag'] == r['latest_cb_tag'])
148
- r['latest_gh_tag'] == r['latest_cb_tag'] ? color = :white : color = :yellow
149
- color = :white if config[:all]
150
-
151
- object_list << ui.color((r['name'] || 'n/a'), color)
152
- object_list << ui.color((r['latest_cb_tag'] || 'n/a'), color)
153
- object_list << ui.color((r['ssh_url'] || 'n/a'), color)
154
- object_list << ui.color((r['latest_gh_tag'] || 'n/a'), color)
125
+ object_list << (r['name'] || 'n/a')
126
+ object_list << (r['git_url'] || 'n/a')
155
127
  end
156
128
  end
157
129
 
158
130
  puts ui.list(object_list, :uneven_columns_across, columns)
159
-
131
+ list_object_fields(repos) if locate_config_value(:fieldlist)
160
132
  end
161
-
162
133
 
134
+ def list_object_fields(object)
135
+ # pp object
136
+ # return
137
+ exit 1 if object.nil? || object.empty?
138
+ object_fields = [
139
+ ui.color('Key', :bold),
140
+ ui.color('Type', :bold),
141
+ ui.color('Value', :bold)
142
+ ]
143
+
144
+ object.first.each do |n|
145
+ if n.class == Hash
146
+ n.keys.each do |k,v|
147
+ object_fields << ui.color(k, :yellow, :bold)
148
+ object_fields << n[k].class.to_s
149
+ if n[k].kind_of?(Array)
150
+ object_fields << '<Array>'
151
+ elsif n[k].kind_of?(Hash)
152
+ object_fields << '<Hash>'
153
+ else
154
+ object_fields << ("#{n[k]}").strip.to_s
155
+ end
156
+ end
157
+ end
158
+ end
163
159
 
160
+ puts "\n"
161
+ puts ui.list(object_fields, :uneven_columns_across, 3)
162
+ end
163
+
164
164
  def get_all_repos(orgs)
165
165
  # Parse every org and merge all into one hash
166
166
  repos = {}
@@ -170,8 +170,6 @@ class Chef
170
170
  repos
171
171
  end
172
172
 
173
-
174
-
175
173
  def get_repos(org)
176
174
  dns_name = get_dns_name(@github_url)
177
175
  file_cache = "#{ENV['HOME']}/.chef/.#{dns_name.downcase}_#{org.downcase}.cache"
@@ -228,50 +226,9 @@ class Chef
228
226
 
229
227
 
230
228
  def get_dns_name(url)
231
- dns = url.downcase.gsub("http://","") if url.downcase.start_with?("http://")
232
- dns = url.downcase.gsub("https://","") if url.downcase.start_with?("https://")
233
- dns
234
- end
235
-
236
-
237
- def send_request(url, params = {})
238
- params['response'] = 'json'
239
-
240
- params_arr = []
241
- params.sort.each { |elem|
242
- params_arr << elem[0].to_s + '=' + CGI.escape(elem[1].to_s).gsub('+', '%20').gsub(' ','%20')
243
- }
244
- data = params_arr.join('&')
245
-
246
- if url.nil? || url.empty?
247
- puts "Error: Please specify a valid Github URL."
248
- exit 1
249
- end
250
-
251
- github_url = "#{url}?#{data}"
252
- # Chef::Log.debug("URL: #{github_url}")
253
-
254
- uri = URI.parse(github_url)
255
- req_body = Net::HTTP::Get.new(uri.request_uri)
256
- request = Chef::REST::RESTRequest.new("GET", uri, req_body, headers={})
257
-
258
- response = request.call
259
-
260
- if !response.is_a?(Net::HTTPOK) then
261
- puts "Error #{response.code}: #{response.message}"
262
- puts JSON.pretty_generate(JSON.parse(response.body))
263
- puts "URL: #{url}"
264
- exit 1
265
- end
266
- json = JSON.parse(response.body)
267
- end
268
-
269
- def display_debug_info!
270
- Chef::Log.debug("github_url: " + @github_url)
271
- Chef::Log.debug("github_ssl: false") if @github_no_ssl_verify
272
- Chef::Log.debug("github_api: " + @github_api_version)
273
- Chef::Log.debug("github_org: " + @github_organizations.to_s)
274
- Chef::Log.debug("github_cache: " + @github_cache.to_s)
229
+ url = url.downcase.gsub("http://","") if url.downcase.start_with?("http://")
230
+ url = url.downcase.gsub("https://","") if url.downcase.start_with?("https://")
231
+ url
275
232
  end
276
233
 
277
234
  end
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Github
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-11 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-10-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: chef
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 11.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 11.0.0
14
30
  description: Github interaction support for Chef's Knife Command
15
31
  email:
16
32
  - sbotman@schubergphilis.com
@@ -23,6 +39,8 @@ files:
23
39
  - LICENSE
24
40
  - README.md
25
41
  - knife-github.gemspec
42
+ - lib/chef/knife/github_base.rb
43
+ - lib/chef/knife/github_compare.rb
26
44
  - lib/chef/knife/github_list.rb
27
45
  - lib/knife-github/version.rb
28
46
  homepage: https://github.com/schubergphilis/knife-github