chef-monitor 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/chef-logmon CHANGED
@@ -16,7 +16,7 @@
16
16
  # See the License for the specific language governing permissions and
17
17
  # limitations under the License.
18
18
 
19
- require "chef_monitor"
19
+ require "chef_logmon"
20
20
  require 'rubygems'
21
21
  require 'file-tail'
22
22
  require 'bunny'
@@ -24,9 +24,12 @@ require 'json'
24
24
  require 'daemons'
25
25
 
26
26
  config=nil
27
+ debug=false
28
+
27
29
  opt=0
28
30
  ARGV.each do |arg|
29
31
  config = ARGV[opt+1] if arg == "-C" || arg == "--config"
32
+ debug = true if arg == "--debug"
30
33
  opt+=1
31
34
  end
32
35
 
@@ -47,6 +50,7 @@ MQSERVER = Monitor::Config[:mq_server]
47
50
  MQQUEUE = Monitor::Config[:mq_queue]
48
51
  MON_FILE = Monitor::Config[:mon_file]
49
52
  CHEF_URL = Monitor::Config[:chef_url]
53
+ DEBUG = debug
50
54
 
51
55
  @options = {
52
56
  :log_output => true,
data/bin/chef-worker CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ #!/opt/chef/embedded/bin/ruby
2
3
  #
3
4
  # Author:: Sander Botman (<sander.botman@gmail.com>)
4
5
  # Copyright:: Copyright (c) 2014 Sander Botman.
@@ -15,17 +16,21 @@
15
16
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
17
  # See the License for the specific language governing permissions and
17
18
  # limitations under the License.
18
-
19
- require "chef_monitor"
19
+ # $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
20
+ require "chef_worker"
20
21
  require 'rubygems'
21
22
  require 'bunny'
22
23
  require 'json'
23
24
  require 'daemons'
24
25
 
25
26
  config=nil
27
+ populate=nil
28
+ debug=false
26
29
  opt=0
27
30
  ARGV.each do |arg|
28
31
  config = ARGV[opt+1] if arg == "-C" || arg == "--config"
32
+ populate = ARGV[opt+1] if arg == "-O"
33
+ debug = true if arg == "--debug"
29
34
  opt+=1
30
35
  end
31
36
 
@@ -42,10 +47,12 @@ else
42
47
  end
43
48
  end
44
49
 
45
- MQSERVER = Monitor::Config[:mq_server]
46
- MQQUEUE = Monitor::Config[:mq_queue]
47
- DOWNLOAD_PATH = Monitor::Config[:download_path]
48
- CHEF_URL = Monitor::Config[:chef_url]
50
+ ALLOWED_OBJECTS = ['users', 'cookbooks','roles','environments','clients','nodes','groups','data']
51
+ DOWNLOAD_PATH = Monitor::Config[:download_path]
52
+ MQSERVER = Monitor::Config[:mq_server]
53
+ MQQUEUE = Monitor::Config[:mq_queue]
54
+ CHEF_URL = Monitor::Config[:chef_url]
55
+ DEBUG = debug
49
56
  Chef::Config[:node_name] = Monitor::Config[:node_name]
50
57
  Chef::Config[:client_key] = Monitor::Config[:client_key]
51
58
 
@@ -56,6 +63,26 @@ Chef::Config[:client_key] = Monitor::Config[:client_key]
56
63
  :log_dir => Monitor::Config[:log_dir]
57
64
  }
58
65
 
66
+ unless populate.nil?
67
+ Chef::Config[:chef_server_url] = CHEF_URL + "/organizations/#{populate}"
68
+ ALLOWED_OBJECTS.each do |object|
69
+ data = {}
70
+ data['object'] = object
71
+ data['action'] = 'POST'
72
+ data['org'] = populate
73
+ data['time'] = Time.now
74
+ data['user'] = 'chef-worker'
75
+ data['server'] = ENV['HOSTNAME']
76
+ pop = Monitor::Item.new(data)
77
+ obj = Monitor::ItemList.new(data)
78
+ obj.each do |item|
79
+ item.download(DOWNLOAD_PATH)
80
+ end
81
+ pop.commit_nohook(DOWNLOAD_PATH)
82
+ end
83
+ exit 0
84
+ end
85
+
59
86
  Daemons.run_proc('chef-worker', @options) do
60
87
  worker = Monitor::Worker.new
61
88
  worker.run()
@@ -0,0 +1,20 @@
1
+ #
2
+ # Author:: Sander Botman (<sander.botman@gmail.com>)
3
+ # Copyright:: Copyright (c) 2014 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
+ require "chef_monitor/log"
19
+ require "chef_monitor/config"
20
+ require "chef_monitor/logmon"
@@ -43,13 +43,12 @@ class Monitor
43
43
  attr_reader :organization
44
44
 
45
45
  def download(path)
46
- case self.object
47
- when 'data', 'roles', 'clients', 'environments', 'nodes'
48
- r = download_object(path)
49
- when 'cookbooks'
46
+
47
+ if @object == "cookbooks"
50
48
  r = download_cookbook(path)
49
+ else
50
+ r = download_object(path)
51
51
  end
52
-
53
52
 
54
53
  (@version.nil? || @version.empty?) ? object = [@organization, @object, @name].join('/') : object = [@organization, @object, @name, @version].join('/')
55
54
 
@@ -71,8 +70,8 @@ class Monitor
71
70
  items << @organization
72
71
  items << @object
73
72
  if @name
74
- filename=@name + ".json" if [ "nodes", "clients", "roles", "environments" ].include?(@object)
75
-
73
+ filename=@name + ".json"
74
+
76
75
  if @object == "cookbooks"
77
76
  (@version.nil? || @version.empty?) ? filename=@name : filename=@name + "-" + @version
78
77
  end
@@ -83,37 +82,62 @@ class Monitor
83
82
 
84
83
  items << filename
85
84
  end
86
-
87
85
  file = items.join("/")
88
- unless file.nil?
89
- FileUtils.rm_rf(file)
90
- (@version.nil? || @version.empty?) ? object = [@organization, @object, @name].join('/') : object = [@organization, @object, @name, @version].join('/')
91
- Monitor::Log.new("Deleted : " + object, 'INFO')
92
- return true
86
+ delete_file(file)
87
+ end
88
+
89
+ def delete_file(file)
90
+ FileUtils.rm_rf(file)
91
+ Monitor::Log.new("Deleted : " + file, 'INFO')
92
+ true
93
+ end
94
+
95
+ def get_item_json(object)
96
+ begin
97
+ item = rest.get_rest(object)
98
+ result = JSON.pretty_generate(item)
99
+ rescue
100
+ return nil
93
101
  end
94
- return false
102
+ return result
95
103
  end
96
104
 
97
105
  def commit(path)
98
- current_dir = Dir.pwd
99
- commit_dir = File.join(path, @organization, @object)
100
- Dir.chdir(commit_dir)
101
- @version ? object = [@organization, @object, @name, @version].join('/') : object = [@organization, @object, @name].join('/')
102
- text = "User : " + @user + "\nObject : " + @object + "\nAction : " + @action + "\nLog Time : " + @time
103
- domain = %x(git config hooks.emaildomain)
104
- domain = "@" + domain unless domain[0,1] == "@"
105
- username = @name
106
- useremail = @name + domain
107
- %x(git config hooks.username #{username} )
108
- %x(git config hooks.useremail #{useremail} )
109
- %x(git add .)
110
- %x(git commit -am \"#{text}\")
111
- Dir.chdir(current_dir)
112
- return true
106
+ current_dir = Dir.pwd
107
+ commit_dir = File.join(path, @organization, @object)
108
+ Dir.chdir(commit_dir)
109
+ @version ? object = [@organization, @object, @name, @version].join('/') : object = [@organization, @object, @name].join('/')
110
+ text = "User : " + @user + "\nObject : " + object + "\nAction : " + @action + "\nLog Time : " + @time
111
+ domain = %x(git config hooks.emaildomain) || "acme.com"
112
+ domain = "@" + domain unless domain[0,1] == "@"
113
+ username = @user
114
+ useremail = @user + domain
115
+ %x(git config hooks.username #{username} )
116
+ %x(git config hooks.useremail #{useremail} )
117
+ %x(git add .)
118
+ %x(git commit -am \"#{text}\")
119
+ Dir.chdir(current_dir)
120
+ end
121
+
122
+ def commit_nohook(path)
123
+ current_dir = Dir.pwd
124
+ commit_dir = File.join(path, @organization, @object)
125
+ Dir.chdir(commit_dir)
126
+ %x(git config hooks.exclude true)
127
+ %x(git add .)
128
+ %x(git commit -am \"no hook executed on this commit\")
129
+ Dir.chdir(current_dir)
113
130
  end
114
-
131
+
115
132
  private
116
-
133
+
134
+ def rest
135
+ @rest ||= begin
136
+ require 'chef/rest'
137
+ Chef::REST.new(Chef::Config[:chef_server_url])
138
+ end
139
+ end
140
+
117
141
  def download_cookbook(path)
118
142
  begin
119
143
  args = ['cookbook', 'download', @name ]
@@ -133,26 +157,14 @@ class Monitor
133
157
  end
134
158
 
135
159
  def download_object(path)
136
- file = File.join(path, @organization, @object, @name + '.json' )
137
- begin
138
- case @object
139
- when 'roles'
140
- data = JSON.pretty_generate(Chef::Role.load(@name))
141
- when 'nodes'
142
- data = JSON.pretty_generate(Chef::Node.load(@name))
143
- when 'environments'
144
- data = JSON.pretty_generate(Chef::Environment.load(@name))
145
- when 'clients'
146
- data = JSON.pretty_generate(Chef::ApiClient.load(@name))
147
- when 'data'
148
- data = JSON.pretty_generate(Chef::DataBagItem.load(@name, @version))
149
- file = File.join(path, @organization, @object, @name, @version + '.json' )
150
- end
160
+ args = [ @object, @name ]
161
+ args.push(@version) if @version
162
+ item = args.join('/')
163
+ file = File.join(path, @organization, item + '.json' )
164
+ data = get_item_json(item)
165
+ unless data.nil?
151
166
  FileUtils.mkdir_p(File.dirname(file)) unless File.directory?(File.dirname(file))
152
167
  File.open(file, 'w') {|f| f.write(data)}
153
- self.path = File.dirname(file)
154
- rescue Exception => e
155
- return e
156
168
  end
157
169
  return true
158
170
  end
@@ -16,7 +16,6 @@
16
16
  # limitations under the License.
17
17
 
18
18
  require 'chef/client'
19
- require 'chef_monitor/log'
20
19
  require 'chef_monitor/item'
21
20
 
22
21
  class Monitor
@@ -24,152 +23,90 @@ class Monitor
24
23
 
25
24
  def initialize(data)
26
25
  @name = data['name']
27
- @time = data['time'].freeze
28
- @user = data['user'].freeze
29
- @object = data['object'].freeze
30
- @server = data['server'].freeze
31
- @action = data['action'].freeze
26
+ @time = data['time']
27
+ @user = data['user']
28
+ @object = data['object']
29
+ @server = data['server']
30
+ @action = data['action']
32
31
  @version = data['version'] unless data['version'].nil? || data['version'].empty?
33
- @organization = data['org'].freeze
32
+ @organization = data['org']
33
+ check_sub_items()
34
34
  end
35
35
 
36
- attr_reader :name
37
- attr_reader :time
38
- attr_reader :user
39
- attr_reader :object
40
- attr_reader :action
41
- attr_reader :version
42
- attr_reader :organization
43
-
44
- def get_items()
45
- name = @name
46
- object = @object
47
- version = @version
48
-
49
- list = []
50
- items = []
51
- if object.nil? || object.empty?
52
- objects = [ "roles", "nodes", "environments", "clients", "cookbooks", "data" ]
36
+ private
37
+
38
+ def check_sub_items()
39
+ if @object == "cookbooks" || @object == "data"
40
+ if @name.nil? || @name.empty?
41
+ add_sub_items(@object)
42
+ elsif @version.nil? || @version.empty?
43
+ add_sub_items(@object, @name)
44
+ else
45
+ add_item(@object, @name, @version)
46
+ end
47
+ elsif @name.nil? || @name.empty?
48
+ add_sub_items(@object)
53
49
  else
54
- objects = [ object ]
50
+ add_item(@object, @name)
55
51
  end
56
-
57
- objects.each do |object|
58
- if object == "data"
59
- if name.nil? || name.empty?
60
- names = get_names(object)
61
- names.each {|itemname| list += get_item(object, itemname)}
52
+ end
53
+
54
+ def add_sub_items(object, name=nil)
55
+ items = get_sub_items(object, name)
56
+ items.each do |item|
57
+ res = item.split('/')
58
+ add_item(res[0], res[1], res[2])
59
+ end
60
+ end
61
+
62
+ def get_sub_items(object, name=nil)
63
+ col = []
64
+ target = [ object, name ].join('/')
65
+ items = get_rest_item(target)
66
+ items.each do |item,value|
67
+ if object == "data" || object == "cookbooks"
68
+ if name.nil?
69
+ col += get_sub_items(object, item)
62
70
  else
63
- list += get_item(object, name)
71
+ col.push([object, name, item].join('/')) if object == "data"
72
+ value['versions'].each {|ver| col << sub_item_parse(ver['url'])} if object == "cookbooks"
64
73
  end
74
+ elsif object == "users"
75
+ item.each { |k| k.each {|sv| col << "users/" + sv['username'] unless sv['username'].nil? }} unless name
65
76
  else
66
- if name.nil? || name.empty?
67
- list += get_item(object)
68
- else
69
- return [ create_item(object, name) ]
70
- end
77
+ col << sub_item_parse(value) unless name
71
78
  end
72
79
  end
80
+ return col
81
+ end
73
82
 
74
- list.each do |item|
75
- url = item['url'].split('/')
76
- items << create_item(url[5], url[6], url[7])
77
- end
78
- return items
83
+ def sub_item_parse(str)
84
+ str.gsub!(Chef::Config[:chef_server_url],"")
85
+ str[1..-1] if str[0] == '/'
79
86
  end
80
-
81
- def get_names(object)
82
- names = []
83
- result = get_item(object)
84
- result.each do |item|
85
- url = item['url'].split('/')
86
- names << url[6]
87
+
88
+ def get_rest_item(target)
89
+ begin
90
+ result = rest.get_rest(target)
91
+ rescue
92
+ return []
87
93
  end
88
- return names.uniq
89
- end
94
+ return result
95
+ end
90
96
 
91
- def create_item(object, name, version=nil)
97
+ def add_item(object, name, version=nil)
92
98
  data = {}
93
99
  data['time'] = @time
94
100
  data['user'] = @user
95
101
  data['action'] = @action
96
102
  data['server'] = @server
97
103
  data['org'] = @organization
98
- data['name'] = name
99
104
  data['object'] = object
105
+ data['name'] = name
100
106
  data['version'] = version unless version.nil?
101
- Monitor::Item.new(data)
107
+ self << Monitor::Item.new(data)
102
108
  end
103
109
 
104
- def parse_data(object, data)
105
- data = JSON[data].to_hash unless data.class == Hash
106
- items = []
107
- data.each do |key,val|
108
- item = {}
109
- item['object'] = object
110
- item['url'] = val
111
- items << item
112
- end
113
- items
114
- end
115
-
116
- def get_item(object=nil, name=nil)
117
- objects = []
118
- begin
119
- case object
120
- when 'roles'
121
- json = JSON[Chef::Role.list]
122
- objects = parse_data("role", json)
123
- when 'nodes'
124
- json = JSON[Chef::Node.list]
125
- objects = parse_data("node", json)
126
- when 'environments'
127
- json = JSON[Chef::Environment.list]
128
- objects = parse_data("environment", json)
129
- when 'clients'
130
- json = JSON[Chef::ApiClient.list]
131
- objects = parse_data("client", json)
132
- when 'data'
133
- if name
134
- json = JSON[Chef::DataBag.load(name)]
135
- items = JSON[json].to_hash
136
- items.each do |key,val|
137
- item = {}
138
- item['object'] = 'data_bag'
139
- item['url'] = val
140
- objects << item
141
- end
142
- else
143
- json = JSON[Chef::DataBag.list]
144
- items = JSON[json].to_hash
145
- items.each do |key,val|
146
- objects += get_item(object, key)
147
- end
148
- end
149
- when 'cookbooks'
150
- json = JSON[rest.get_rest("/cookbooks?num_versions=all")]
151
- items = JSON[json].to_hash
152
- items.each do |key,val|
153
- val['versions'].each do |version|
154
- item = {}
155
- item['object'] = 'cookbook'
156
- item['url'] = version['url']
157
- objects << item
158
- end
159
- end
160
- end
161
- rescue Exception => e
162
- @version ? object = [@organization, @object, @name, @version].join('/') : object = [@organization, @object, @name].join('/')
163
- if e.respond_to?("message")
164
- Monitor::Log.new(e.message + ' with object: ' + object , 'ERROR')
165
- else
166
- Monitor::Log.new('Error while downloading object: ' + object , 'ERROR')
167
- end
168
- return []
169
- end
170
- return objects
171
- end
172
-
173
110
  def rest
174
111
  @rest ||= begin
175
112
  require 'chef/rest'
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Monitor
19
19
  class Log
20
-
20
+
21
21
  def initialize(text, type='INFO')
22
22
  case type.downcase
23
23
  when "INFO".downcase
@@ -26,6 +26,8 @@ class Monitor
26
26
  puts "[" + Time.now.iso8601 + "] WARN: " + text
27
27
  when "ERROR".downcase
28
28
  puts "[" + Time.now.iso8601 + "] ERROR: " + text
29
+ when "DEBUG".downcase
30
+ puts "[" + Time.now.iso8601 + "] DEBUG: " + text if DEBUG
29
31
  else
30
32
  puts "[" + Time.now.iso8601 + "] UNKNOWN: " + text
31
33
  end
@@ -16,6 +16,6 @@
16
16
  # limitations under the License.
17
17
 
18
18
  class Monitor
19
- VERSION = "0.1.0"
19
+ VERSION = "0.1.2"
20
20
  MAJOR, MINOR, TINY = VERSION.split('.')
21
21
  end
@@ -15,9 +15,9 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+
18
19
  class Monitor
19
20
  class Worker
20
-
21
21
  def run
22
22
  conn = Bunny.new(:hostname => MQSERVER)
23
23
  conn.start
@@ -30,37 +30,32 @@ class Monitor
30
30
  q.subscribe(:ack => true, :block => true) do |delivery_info, properties, body|
31
31
  if properties[:content_type] =~ /.*json/
32
32
  data = JSON.parse(body).to_hash
33
-
34
- if data['object'].nil? || data['object'].empty?
35
- log_obj = data['org']
36
- elsif data['name'].nil? || data['name'].empty?
37
- log_obj = [ data['org'], data['object'] ].join('/')
38
- elsif data['version'].nil? || data['version'].empty?
39
- log_obj = [ data['org'], data['object'], data['name'] ].join('/')
40
- else
41
- log_obj = [ data['org'], data['object'], data['name'], data['version'] ].join('/')
42
- end
43
- Monitor::Log.new("Receiving : #{log_obj} action: #{data['action']}", "INFO")
44
-
33
+ Monitor::Log.new("Receiving : #{data}", "DEBUG")
34
+ data['object'] = nil unless ALLOWED_OBJECTS.include?(data['object'])
35
+
45
36
  unless data['object'].nil? || !File.directory?((File.join(DOWNLOAD_PATH, data['org'])))
46
37
  Chef::Config[:chef_server_url] = CHEF_URL + "/organizations/#{data['org']}"
47
38
 
48
- Monitor::Item.new(data).delete(DOWNLOAD_PATH)
49
-
50
- list_obj = Monitor::ItemList.new(data)
51
- list_items = list_obj.get_items()
52
-
53
- if data['action'] == "PUT" || data['action'] == "POST" || data['action'] == "DELETE"
54
- list_items.each do |item|
55
- if item.download(DOWNLOAD_PATH)
56
- item.commit(DOWNLOAD_PATH)
57
- else
58
- Monitor::Log.new("Could not download #{log_obj}", "ERROR")
39
+ obj = Monitor::Item.new(data)
40
+ if data['action'] == "DELETE"
41
+ obj.delete(DOWNLOAD_PATH)
42
+ else
43
+ items = Monitor::ItemList.new(data)
44
+
45
+ items.each do |item|
46
+ if data['action'] == "PUT"
47
+ item.download(DOWNLOAD_PATH)
48
+ end
49
+
50
+ if data['action'] == "POST"
51
+ item.delete(DOWNLOAD_PATH)
52
+ item.download(DOWNLOAD_PATH)
59
53
  end
60
54
  end
61
55
  end
56
+ obj.commit(DOWNLOAD_PATH)
62
57
  else
63
- Monitor::Log.new("Ignoring : #{log_obj}", "INFO")
58
+ Monitor::Log.new("Ignoring : #{data}", "DEBUG")
64
59
  end
65
60
  else
66
61
  Monitor::Log.new("Unknown : #{body}", "ERROR")
@@ -16,8 +16,6 @@
16
16
  # limitations under the License.
17
17
 
18
18
  require "chef_monitor/log"
19
- require "chef_monitor/item"
20
19
  require "chef_monitor/itemlist"
21
20
  require "chef_monitor/config"
22
21
  require "chef_monitor/worker"
23
- require "chef_monitor/logmon"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-04 00:00:00.000000000 Z
12
+ date: 2014-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bunny
@@ -92,7 +92,7 @@ files:
92
92
  - bin/chef-logmon
93
93
  - bin/chef-worker
94
94
  - chef-monitor.gemspec
95
- - lib/chef_monitor.rb
95
+ - lib/chef_logmon.rb
96
96
  - lib/chef_monitor/config.rb
97
97
  - lib/chef_monitor/item.rb
98
98
  - lib/chef_monitor/itemlist.rb
@@ -100,6 +100,7 @@ files:
100
100
  - lib/chef_monitor/logmon.rb
101
101
  - lib/chef_monitor/version.rb
102
102
  - lib/chef_monitor/worker.rb
103
+ - lib/chef_worker.rb
103
104
  homepage: https://github.com/schubergphilis/chef-monitor
104
105
  licenses:
105
106
  - Apache 2.0