chef-etcd 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c69d2d4c07991326c2d287ca17b05437eef96f29
4
+ data.tar.gz: ff90b8aacc2d44b871fb44326b08c082e81c8a59
5
+ SHA512:
6
+ metadata.gz: 83dbf5d4c8382784d1a7ae4255461f14b2684c9710b3c1e85f01d8bef7517e77278638354636732b1ce473a3669442b93a264fe3b93aefe9ca2d68207047e6a6
7
+ data.tar.gz: 133d27451007a7c48ad99b3aa5fa2db93ede8959aaa27cecc0d552b2e9f84a32f6856f97ef5ac899eb11c09daf298acbe48d54829184e9973422956b85239fff
@@ -0,0 +1,17 @@
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
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ranjib Dey
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.
@@ -0,0 +1,85 @@
1
+ # Chef::Etcd
2
+
3
+ Provides chef resource/provider to access etcd key value pairs and report/event handlers to publish chef run data into etcd.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'chef-etcd'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install chef-etcd
18
+
19
+ ## Usage
20
+
21
+ 1. ```require``` the chef-etcd library in your client config (knife.rb/solo.rb/client.rb) and set ```Chef::Config[:etcd]``` to an existing [etcd](https://github.com/coreos/etcd) node.
22
+
23
+ ```ruby
24
+ require 'chef/etcd'
25
+ node_name 'something'
26
+ etcd_host = '192.168.122.1'
27
+ Chef::Config[:etcd]= {host:etcd_host}
28
+ ```
29
+
30
+ 2. you can use the resource/provider to get/set etcd keys
31
+
32
+ ```ruby
33
+ etcd "/test/recipe/set" do
34
+ action :set
35
+ value Time.now.to_s
36
+ end
37
+
38
+ etcd "/test/recipe/delete" do
39
+ action :set
40
+ value Time.now.to_s
41
+ end
42
+
43
+ etcd "/test/recipe/delete" do
44
+ action :delete
45
+ value Time.now.to_s
46
+ end
47
+
48
+ etcd "/test/recipe/test_and_set" do
49
+ action :set
50
+ value "0"
51
+ end
52
+
53
+ etcd "/test/recipe/test_and_set" do
54
+ action :test_and_set
55
+ value Time.now.to_s
56
+ prev_value "0"
57
+ end
58
+
59
+ etcd "/test/recipe/watch" do
60
+ action :set
61
+ value Time.now.to_s
62
+ end
63
+
64
+ Chef::Log.warn("This will halt the recipe, and you have to update the recipe from outside or do some thread foo here")
65
+ etcd "/test/recipe/watch" do
66
+ action :watch
67
+ value Time.now.to_s
68
+ end
69
+
70
+ ```
71
+ 3. To publish node data using the report handler, or to monitor realtime chef resource convergence(event handler), add following configurations to your client.rb/solo.rb
72
+
73
+ ```ruby
74
+ event_handlers [Chef::EventDispatch::Etcd.new(host: etcd_host)]
75
+ report_handlers << Chef::Handler::EtcdReport.new(host: etcd_host)
76
+
77
+ ```
78
+
79
+ ## Contributing
80
+
81
+ 1. Fork it
82
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
83
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
84
+ 4. Push to the branch (`git push origin my-new-feature`)
85
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chef/etcd/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "chef-etcd"
8
+ spec.version = Chef::Etcd::VERSION
9
+ spec.authors = ["Ranjib Dey"]
10
+ spec.email = ["dey.ranjib@gmail.com"]
11
+ spec.description = %q{Etcd-Chef bindings}
12
+ spec.summary = %q{Provides chef resource, provider, handlers for etcd}
13
+ spec.homepage = "https://github.com/ranjib/chef-etcd"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "etcd"
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,5 @@
1
+ require "chef/etcd/version"
2
+ require 'chef/resource/etcd'
3
+ require 'chef/provider/etcd'
4
+ require 'chef/handler/etcd_report'
5
+ require 'chef/handler/etcd_event'
@@ -0,0 +1,5 @@
1
+ module Chef
2
+ module Etcd
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,253 @@
1
+ require 'chef/event_dispatch/base'
2
+ require 'etcd'
3
+
4
+ class Chef
5
+ module EventDispatch
6
+ class Etcd < Chef::EventDispatch::Base
7
+
8
+ attr_reader :etcd
9
+
10
+ def initialize(options={})
11
+ etcd_host = options[:host] || '127.0.0.1'
12
+ etcd_port = options[:port] || 4001
13
+ @etcd = ::Etcd.client(host: etcd_host, port: etcd_port)
14
+ @global_ttl = options[:global_ttl] || 600
15
+ @ttls = options[:ttls] || {}
16
+ end
17
+
18
+ def get_ttl(m)
19
+ if @ttls.has_key?(m)
20
+ @ttls[m]
21
+ else
22
+ @global_ttl
23
+ end
24
+ end
25
+
26
+ def name_space
27
+ '/nodes/' + Chef::Config[:node_name] + '/chef'
28
+ end
29
+
30
+ def etcd_set(m, k, v=nil) # m = method
31
+ key= name_space + k
32
+ value = v || m
33
+ ttl = get_ttl(m)
34
+ etcd.set(key, value, ttl)
35
+ end
36
+
37
+ def set_sub_status(m)
38
+ etcd_set(m, '/sub_status')
39
+ end
40
+
41
+ def run_start(version)
42
+ etcd_set(__method__, '/status', 'running')
43
+ etcd_set(__method__, '/version', version)
44
+ end
45
+
46
+ def run_completed(node)
47
+ etcd_set(__method__, '/status', 'completed')
48
+ end
49
+
50
+ def run_failed(exception)
51
+ etcd_set(__method__, '/status', 'failed')
52
+ end
53
+
54
+ def run_started(run_status)
55
+ set_sub_status(__method__)
56
+ end
57
+
58
+
59
+ def ohai_completed(node)
60
+ set_sub_status(__method__)
61
+ end
62
+
63
+ def skipping_registration(node_name, config)
64
+ set_sub_status(__method__)
65
+ end
66
+
67
+ def registration_start(node_name, config)
68
+ set_sub_status(__method__)
69
+ end
70
+
71
+ def registration_completed
72
+ set_sub_status(__method__)
73
+ end
74
+
75
+ def registration_failed(node_name, exception, config)
76
+ set_sub_status(__method__)
77
+ end
78
+
79
+ def node_load_start(node_name, config)
80
+ set_sub_status(__method__)
81
+ end
82
+
83
+ def node_load_failed(node_name, exception, config)
84
+ set_sub_status(__method__)
85
+ end
86
+
87
+ def run_list_expand_failed(node, exception)
88
+ set_sub_status(__method__)
89
+ end
90
+
91
+ def node_load_completed(node, expanded_run_list, config)
92
+ set_sub_status(__method__)
93
+ end
94
+
95
+ def cookbook_resolution_start(expanded_run_list)
96
+ set_sub_status(__method__)
97
+ end
98
+
99
+ def cookbook_resolution_failed(expanded_run_list, exception)
100
+ set_sub_status(__method__)
101
+ end
102
+
103
+ def cookbook_resolution_complete(cookbook_collection)
104
+ set_sub_status(__method__)
105
+ end
106
+
107
+ def cookbook_clean_start
108
+ set_sub_status(__method__)
109
+ end
110
+
111
+ def cookbook_clean_complete
112
+ set_sub_status(__method__)
113
+ end
114
+
115
+ def cookbook_sync_start(cookbook_count)
116
+ set_sub_status(__method__)
117
+ end
118
+
119
+ def cookbook_sync_failed(cookbooks, exception)
120
+ set_sub_status(__method__)
121
+ end
122
+
123
+ def cookbook_sync_complete
124
+ set_sub_status(__method__)
125
+ end
126
+
127
+ def library_load_start(file_count)
128
+ set_sub_status(__method__)
129
+ end
130
+
131
+ def library_file_load_failed(path, exception)
132
+ set_sub_status(__method__)
133
+ end
134
+
135
+ def library_load_complete
136
+ set_sub_status(__method__)
137
+ end
138
+
139
+ def lwrp_load_start(lwrp_file_count)
140
+ set_sub_status(__method__)
141
+ end
142
+
143
+ def lwrp_file_load_failed(path, exception)
144
+ set_sub_status(__method__)
145
+ end
146
+
147
+ def lwrp_load_complete
148
+ set_sub_status(__method__)
149
+ end
150
+
151
+ def attribute_load_start(attribute_file_count)
152
+ set_sub_status(__method__)
153
+ end
154
+
155
+ def attribute_file_load_failed(path, exception)
156
+ set_sub_status(__method__)
157
+ end
158
+
159
+ def attribute_load_complete
160
+ set_sub_status(__method__)
161
+ end
162
+
163
+ def definition_load_start(definition_file_count)
164
+ set_sub_status(__method__)
165
+ end
166
+
167
+ def definition_file_load_failed(path, exception)
168
+ set_sub_status(__method__)
169
+ end
170
+
171
+ def definition_load_complete
172
+ set_sub_status(__method__)
173
+ end
174
+
175
+ def recipe_load_start(recipe_count)
176
+ set_sub_status(__method__)
177
+ end
178
+
179
+ def recipe_file_load_failed(path, exception)
180
+ set_sub_status(__method__)
181
+ end
182
+
183
+ def recipe_not_found(exception)
184
+ set_sub_status(__method__)
185
+ end
186
+
187
+ def recipe_load_complete
188
+ set_sub_status(__method__)
189
+ end
190
+
191
+ def converge_start(run_context)
192
+ set_sub_status(__method__)
193
+ end
194
+
195
+ def converge_complete
196
+ set_sub_status(__method__)
197
+ end
198
+
199
+ def resource_action_start(resource, action, notification_type=nil, notifier=nil)
200
+ etcd_set(__method__, '/resource_state', 'action_start')
201
+ etcd_set(__method__, '/resource_name', resource.to_s)
202
+ etcd_set(__method__, '/resource_action', action.to_s)
203
+ end
204
+
205
+ def resource_failed(resource, action, exception)
206
+ etcd_set(__method__, '/resource_state', 'failed')
207
+ etcd_set(__method__, '/resource_name', resource.to_s)
208
+ etcd_set(__method__, '/resource_action', action.to_s)
209
+ end
210
+
211
+ def resource_completed(resource)
212
+ etcd_set(__method__, '/resource_state', 'completed')
213
+ etcd_set(__method__, '/resource_name', resource.to_s)
214
+ end
215
+
216
+ def resource_skipped(resource, action, conditional)
217
+ etcd_set(__method__, '/resource_state', 'skipped')
218
+ etcd_set(__method__, '/resource_name', resource.to_s)
219
+ etcd_set(__method__, '/resource_action', action.to_s)
220
+ end
221
+
222
+ def resource_bypassed(resource, action, current_resource)
223
+ etcd_set(__method__, '/resource_state', 'bypassed')
224
+ etcd_set(__method__, '/resource_name', resource.to_s)
225
+ etcd_set(__method__, '/resource_action', action.to_s)
226
+ end
227
+
228
+ def resource_up_to_date(resource, action)
229
+ etcd_set(__method__, '/resource_state', 'converged')
230
+ etcd_set(__method__, '/resource_name', resource.to_s)
231
+ etcd_set(__method__, '/resource_action', action.to_s)
232
+ end
233
+
234
+
235
+ def resource_updated(resource, action)
236
+ etcd_set(__method__, '/resource_state', 'updated')
237
+ etcd_set(__method__, '/resource_name', resource.to_s)
238
+ etcd_set(__method__, '/resource_action', action.to_s)
239
+ end
240
+
241
+ def handlers_start(handler_count)
242
+ set_sub_status(__method__)
243
+ end
244
+
245
+ def handlers_completed
246
+ set_sub_status(__method__)
247
+ end
248
+
249
+ def msg(message)
250
+ end
251
+ end
252
+ end
253
+ end
@@ -0,0 +1,23 @@
1
+ require 'chef/handler'
2
+ require 'etcd'
3
+ require 'json'
4
+
5
+ class Chef
6
+ class Handler
7
+ class EtcdReport < Chef::Handler
8
+
9
+ attr_reader :etcd
10
+
11
+ def initialize(options={})
12
+ @etcd = ::Etcd.client(options)
13
+ end
14
+
15
+ def report
16
+ if success?
17
+ data = {total: all_resources.size, updated: updated_resources.size, time: elapsed_time}
18
+ @etcd.set('/nodes/'+Chef::Config[:node_name]+'/chef/report',JSON.dump(data)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,104 @@
1
+ require 'chef/provider'
2
+ require 'etcd'
3
+
4
+
5
+
6
+ class Chef
7
+ class Provider
8
+ class Etcd < Chef::Provider
9
+
10
+ def initialize(new_resource, run_context)
11
+ super(new_resource, run_context)
12
+ end
13
+
14
+ def load_current_resource
15
+ @current_resource ||= Chef::Resource::Etcd.new(new_resource.name)
16
+ if key_exist?
17
+ @current_resource.value(current_value)
18
+ end
19
+ @current_resource
20
+ end
21
+
22
+ def whyrun_supported?
23
+ true
24
+ end
25
+
26
+ def config
27
+ @config ||= Chef::Config[:etcd]
28
+ end
29
+
30
+ def etcd
31
+ @etcd ||= ::Etcd.client(config)
32
+ end
33
+
34
+
35
+ def key_exist?
36
+ exist = true
37
+ begin
38
+ etcd.get(new_resource.key)
39
+ rescue Net::HTTPServerException => e
40
+ exist = false
41
+ end
42
+ exist
43
+ end
44
+
45
+ def current_value
46
+ if key_exist?
47
+ etcd.get(new_resource.key).value
48
+ else
49
+ nil
50
+ end
51
+ end
52
+
53
+ def action_set
54
+ if @current_resource.value == new_resource.value
55
+ Chef::Log.debug(" etcd #{new_resource.key} is in sync")
56
+ else
57
+ converge_by "will set value of key #{new_resource.key}" do
58
+ etcd.set(new_resource.key, new_resource.value)
59
+ new_resource.updated_by_last_action(true)
60
+ end
61
+ end
62
+ end
63
+ def action_get
64
+ converge_by "will set value of key #{new_resource.key}" do
65
+ if key_exist?
66
+ current_value
67
+ else
68
+ nil
69
+ end
70
+ new_resource.updated_by_last_action(true)
71
+ end
72
+ end
73
+
74
+ def action_test_and_set
75
+ begin
76
+ etcd.test_and_set(new_resource.key, new_resource.value, new_resource.prev_value, new_resource.ttl)
77
+ rescue Net::HTTPServerException => e
78
+ converge_by "will not be able test_and_set value of key #{new_resource.key}" do
79
+ new_resource.updated_by_last_action(true)
80
+ end
81
+ end
82
+ end
83
+
84
+ def action_watch
85
+ converge_bey "will wait for update from etcd key #{new_resource.key}" do
86
+ etcd.watch(new_resource.key)
87
+ new_resource.updated_by_last_action(true)
88
+ end
89
+ end
90
+
91
+ def action_delete
92
+ if key_exist?
93
+ converge_by "will delete etcd key #{new_resource.key}" do
94
+ etcd.delete(new_resource.key)
95
+ new_resource.updated_by_last_action(true)
96
+ end
97
+ else
98
+ Chef::Log.debug("etcd key #{new_resource.key} does not exist")
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,40 @@
1
+ require 'chef/resource'
2
+
3
+ class Chef
4
+ class Resource
5
+
6
+ class Etcd < Chef::Resource
7
+
8
+ identity_attr :key
9
+ state_attrs :value
10
+ provides :etcd
11
+
12
+ def initialize(name, run_context=nil)
13
+ super
14
+ @resource_name = :etcd
15
+ @action = [:set]
16
+ @allowed_actions.push(:test_and_set, :delete, :get, :wait, :set)
17
+ @key = name
18
+ @value = nil
19
+ @prev_value = nil
20
+ @ttl = nil
21
+ end
22
+
23
+ def key(arg=nil)
24
+ set_or_return(:key, arg, :kind_of => String)
25
+ end
26
+
27
+ def value(arg=nil)
28
+ set_or_return(:value, arg, :kind_of => String)
29
+ end
30
+
31
+ def prev_value(arg=nil)
32
+ set_or_return(:prev_value, arg, :kind_of => String)
33
+ end
34
+
35
+ def ttl(arg=nil)
36
+ set_or_return(:ttl, arg, :kind_of => String)
37
+ end
38
+ end
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chef-etcd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ranjib Dey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: etcd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Etcd-Chef bindings
56
+ email:
57
+ - dey.ranjib@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - chef-etcd.gemspec
68
+ - lib/chef/etcd.rb
69
+ - lib/chef/etcd/version.rb
70
+ - lib/chef/handler/etcd_event.rb
71
+ - lib/chef/handler/etcd_report.rb
72
+ - lib/chef/provider/etcd.rb
73
+ - lib/chef/resource/etcd.rb
74
+ homepage: https://github.com/ranjib/chef-etcd
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.0.3
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Provides chef resource, provider, handlers for etcd
98
+ test_files: []