knife-server 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,19 @@
1
- ## 0.1.1.dev (unreleased)
1
+ ## 0.2.1.dev (unreleased)
2
+
3
+
4
+ ## 0.2.0 (July 3, 2012)
5
+
6
+ ### Bug fixes
7
+
8
+ * Issue [#2](https://github.com/fnichol/knife-server/issues/2): Improve
9
+ documentation to clarify `knife server bootstrap` is not a proper
10
+ subcommand. ([@fnichol][])
11
+
12
+ ### New features
13
+
14
+ * Add `knife server backup` subcommand to backup data components (nodes,
15
+ roles, environments, data bags) to the workstation's file system.
16
+ ([@fnichol][])
2
17
 
3
18
 
4
19
  ## 0.1.0 (June 23, 2012)
data/README.md CHANGED
@@ -10,7 +10,8 @@ Follow the [installation](#installation) instructions, then you are ready
10
10
  to create your very own Chef Server running Ubuntu on Amazon's EC2 service:
11
11
 
12
12
  ```bash
13
- $ knife server bootstrap ec2 --ssh-user ubuntu --node-name chefapalooza.example.com
13
+ $ knife server bootstrap ec2 --ssh-user ubuntu \
14
+ --node-name chefapalooza.example.com
14
15
  ```
15
16
 
16
17
  See [below](#subcommands) for more details.
@@ -37,6 +38,26 @@ $ gem install knife-server
37
38
 
38
39
  ### <a name="installation-knife"></a> knife.rb Setup
39
40
 
41
+ When creating a Chef Server the validation key and admin client key will
42
+ be installed on your workstation. Therefore, several knife configuration
43
+ options are required (descriptions courtesy of the [Chef wiki][wiki_knife]):
44
+
45
+ * `node_name`: User or client identity (i.e., name) to use for authenticating
46
+ requests to the Chef Server.
47
+ * `client_key`: Private key file to authenticate to the Chef server.
48
+ Corresponds to the -k or --key option
49
+ * `validation_key`: Specifies the private key file to use when bootstrapping
50
+ new hosts. See knife-client(1) for more information about the validation
51
+ client.
52
+
53
+ For example:
54
+
55
+ ```ruby
56
+ node_name "gramsay"
57
+ client_key "#{ENV['HOME']}/.chef.d/gramsay.pem"
58
+ validation_key "#{ENV['HOME']}/.chef.d/chef-validator.pem"
59
+ ```
60
+
40
61
  Most options can be passed to the knife subcommands explicitly but this
41
62
  quickly becomes tiring, repetitive, and error-prone. A better solution is to
42
63
  add some of the common configuration to your `~/.chef/knife.rb` or your
@@ -55,7 +76,7 @@ from the [chef-bootstrap-repo][chef_bootstrap_repo] project?
55
76
 
56
77
  ## <a name="subcommands"></a> Subcommands
57
78
 
58
- ### <a name="knife-server-bootstrap"></a> knife server bootstrap
79
+ ### <a name="knife-server-bootstrap"></a> knife server bootstrap (Common Options)
59
80
 
60
81
  These subcommands will install and configure an Open Source Chef Server on
61
82
  several different clouds/environments. The high level step taken are as
@@ -79,6 +100,9 @@ follows:
79
100
  already exists at that path a backup copy will be made in the same
80
101
  directory.
81
102
 
103
+ **Note** `knife server bootstrap` can not be invoked directly; a subcommand
104
+ must be selected which determines the provisioning strategy.
105
+
82
106
  #### Common Configuration
83
107
 
84
108
  ##### --node-name NAME (-N)
@@ -221,17 +245,60 @@ The size of the EBS volume in GB, for EBS-backed instances.
221
245
 
222
246
  Do not delete EBS volumn on instance termination.
223
247
 
248
+ ### <a name="knife-server-backup"></a> knife server backup
249
+
250
+ Pulls Chef data primitives from a Chef Server as JSON for backup. Backups can
251
+ be taken of:
252
+
253
+ * nodes
254
+ * roles
255
+ * environments
256
+ * data bags
257
+
258
+ #### Configuration
259
+
260
+ ##### COMPONENT[ COMPONENT ...]
261
+
262
+ The following component types are valid:
263
+
264
+ * `nodes`
265
+ * `roles`
266
+ * `environments`
267
+ * `data_bags` (note the underscore character)
268
+
269
+ When no component types are specified, all will be selected for backup.
270
+ This is equivalent to invoking:
271
+
272
+ knife server backup nodes roles environments data_bags
273
+
274
+ ##### --backup-dir DIR (-D)
275
+
276
+ The directory to host backup files. A sub-directory for each data primitive
277
+ type will be created. For example if the `backup-dir` was `/backups/chef`
278
+ then all all node JSON representations would be written to
279
+ `/backups/chef/nodes` and data bag JSON representations would be written to
280
+ `/backups/chef/data_bags`.
281
+
282
+ The default uses the `:file_backup_path` configuration option, the
283
+ `:chef_server_url` and the current time to construct a unique directory
284
+ (within a second). For example, if the time was "2012-04-01 08:47:11 UTC", and
285
+ given the following configuration (in **knife.rb**):
286
+
287
+ file_backup_path = "/var/chef/backups"
288
+ chef_server_url = "https://api.opscode.com/organizations/coolinc"
289
+
290
+ then a backup directory of
291
+ `/var/chef/backups/api.opscode.com_20120401T084711-0000` would be created.
292
+
224
293
  ## <a name="roadmap"></a> Roadmap
225
294
 
226
295
  * Support for other platforms (alternative bootstrap templates)
227
296
  * Support for Rackspace provisioning (use knife-rackspace gem)
228
297
  * Support for standalone server provisioning
229
- * knife server backup {nodes,roles,environments,data bags,all}
230
298
  * knife server backup backed by s3 (fog api)
231
- * knife server backup backed by local filesystem
232
299
  * knife server restore {nodes,roles,environments,data bags,all}
233
300
  * knife server restore from s3 archive (fog api)
234
- * knife server restore from by local filesystem
301
+ * knife server restore from local filesystem
235
302
 
236
303
  ## <a name="development"></a> Development
237
304
 
@@ -265,3 +332,4 @@ Apache License, Version 2.0 (see [LICENSE][license])
265
332
  [chef_bootstrap_knife_rb]: https://github.com/fnichol/chef-bootstrap-repo/blob/master/.chef/knife.rb
266
333
  [chef_bootstrap_repo]: https://github.com/fnichol/chef-bootstrap-repo/
267
334
  [knife-ec2]: https://github.com/opscode/knife-ec2
335
+ [wiki_knife]: http://wiki.opscode.com/display/chef/Knife#Knife-Knifeconfiguration
@@ -22,4 +22,5 @@ Gem::Specification.new do |gem|
22
22
 
23
23
  gem.add_development_dependency "rspec", "~> 2.10"
24
24
  gem.add_development_dependency "fakefs", "~> 0.4.0"
25
+ gem.add_development_dependency "timecop", "~> 0.3.5"
25
26
  end
@@ -0,0 +1,109 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+ require 'chef/node'
21
+ require 'fileutils'
22
+ require 'uri'
23
+
24
+ class Chef
25
+ class Knife
26
+ class ServerBackup < Knife
27
+
28
+ banner "knife server backup COMPONENT[ COMPONENT ...] (options)"
29
+
30
+ option :backup_dir,
31
+ :short => "-D DIR",
32
+ :long => "--backup-dir DIR",
33
+ :description => "The directory to host backup files"
34
+
35
+ def run
36
+ validate!
37
+ components = name_args.empty? ? COMPONENTS.keys : name_args
38
+
39
+ Array(components).each { |component| backup_component(component) }
40
+ end
41
+
42
+ def backup_dir
43
+ @backup_dir ||= config[:backup_dir] || begin
44
+ server_host = URI.parse(Chef::Config[:chef_server_url]).host
45
+ time = Time.now.utc.strftime("%Y%m%dT%H%M%S-0000")
46
+ base_dir = config[:backup_dir] || Chef::Config[:file_backup_path]
47
+
48
+ ::File.join(base_dir, "#{server_host}_#{time}")
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ COMPONENTS = {
55
+ "nodes" => { :singular => "node", :klass => Chef::Node },
56
+ "roles" => { :singular => "role", :klass => Chef::Role },
57
+ "environments" => { :singular => "environment", :klass => Chef::Environment },
58
+ "data_bags" => { :singular => "data_bag", :klass => Chef::DataBag },
59
+ }
60
+
61
+ def validate!
62
+ bad_names = name_args.reject { |c| COMPONENTS.keys.include?(c) }
63
+ unless bad_names.empty?
64
+ ui.error "Component types #{bad_names.inspect} are not valid."
65
+ exit 1
66
+ end
67
+ end
68
+
69
+ def backup_component(component)
70
+ c = COMPONENTS[component]
71
+ dir_path = ::File.join(backup_dir, component)
72
+ ui.msg "Creating #{c[:singular]} backups in #{dir_path}"
73
+ FileUtils.mkdir_p(dir_path)
74
+
75
+ Array(c[:klass].list).each do |name, url|
76
+ next if component == "environments" && name == "_default"
77
+
78
+ case component
79
+ when "data_bags"
80
+ write_data_bag_items(name, dir_path, c)
81
+ else
82
+ write_component(name, dir_path, c)
83
+ end
84
+ end
85
+ end
86
+
87
+ def write_component(name, dir_path, c)
88
+ obj = c[:klass].load(name)
89
+ ui.msg "Backing up #{c[:singular]}[#{name}]"
90
+ ::File.open(::File.join(dir_path, "#{name}.json"), "wb") do |f|
91
+ f.write(obj.to_json)
92
+ end
93
+ end
94
+
95
+ def write_data_bag_items(name, dir_path, c)
96
+ item_path = ::File.join(dir_path, name)
97
+ FileUtils.mkdir_p(item_path)
98
+
99
+ Array(c[:klass].load(name)).each do |item_name, url|
100
+ obj = Chef::DataBagItem.load(name, item_name)
101
+ ui.msg "Backing up #{c[:singular]}[#{name}][#{item_name}]"
102
+ ::File.open(::File.join(item_path, "#{item_name}.json"), "wb") do |f|
103
+ f.write(obj.to_json)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'chef/knife'
2
20
  require 'knife/server/ec2_security_group'
3
21
  require 'knife/server/ssh'
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require "knife/server/version"
2
20
 
3
21
  module Knife
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'fileutils'
2
20
 
3
21
  module Knife
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  module Knife
2
20
  module Server
3
21
  class Ec2SecurityGroup
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'net/ssh'
2
20
 
3
21
  module Knife
@@ -1,5 +1,23 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  module Knife
2
20
  module Server
3
- VERSION = "0.1.0"
21
+ VERSION = "0.2.0"
4
22
  end
5
23
  end
@@ -0,0 +1,242 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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/server_backup'
20
+ require 'fakefs/spec_helpers'
21
+ require 'timecop'
22
+
23
+ describe Chef::Knife::ServerBackup do
24
+ include FakeFS::SpecHelpers
25
+
26
+ before do
27
+ Chef::Log.logger = Logger.new(StringIO.new)
28
+ @knife = Chef::Knife::ServerBackup.new
29
+ @stdout = StringIO.new
30
+ @knife.ui.stub!(:stdout).and_return(@stdout)
31
+ @knife.ui.stub(:msg)
32
+ @stderr = StringIO.new
33
+ @knife.ui.stub!(:stderr).and_return(@stderr)
34
+ @knife.config[:backup_dir] = "/baks"
35
+
36
+ Chef::Config[:chef_server_url] = "https://chef.example.com:9876"
37
+ end
38
+
39
+ describe "configuration" do
40
+ before do
41
+ Chef::Config[:_spec_file_backup_path] = Chef::Config[:file_backup_path]
42
+ end
43
+
44
+ after do
45
+ Chef::Config[:file_backup_path] = Chef::Config[:_spec_file_backup_path]
46
+ end
47
+
48
+ it "defaults the backup dir to <backup_dir>/<server_name>_<time>" do
49
+ Timecop.freeze(Time.utc(2012, 1, 2, 3, 4, 5)) do
50
+ @knife.config[:backup_dir] = nil
51
+ Chef::Config[:file_backup_path] = "/da/bomb"
52
+
53
+ @knife.backup_dir.should eq(
54
+ "/da/bomb/chef.example.com_20120102T030405-0000")
55
+ end
56
+ end
57
+ end
58
+
59
+ describe "#run" do
60
+ let(:node_list) { Hash["mynode" => "http://pancakes/nodes/mynode"] }
61
+ let(:role_list) { Hash["myrole" => "http://pancakes/roles/myrole"] }
62
+ let(:env_list) { Hash["myenv" => "http://pancakes/envs/myenv"] }
63
+ let(:data_bag_list) { Hash["mybag" => "http://pancakes/bags/mybag"] }
64
+ let(:data_bag_item_list) { Hash["myitem" => "http://p/bags/mybag/myitem"] }
65
+
66
+ before do
67
+ Chef::Node.stub(:list) { node_list }
68
+ Chef::Node.stub(:load).with("mynode") { stub_node("mynode") }
69
+ Chef::Role.stub(:list) { role_list }
70
+ Chef::Role.stub(:load).with("myrole") { stub_role("myrole") }
71
+ Chef::Environment.stub(:list) { env_list }
72
+ Chef::Environment.stub(:load).with("myenv") { stub_env("myenv") }
73
+ Chef::DataBag.stub(:list) { data_bag_list }
74
+ Chef::DataBag.stub(:load).with("mybag") { data_bag_item_list }
75
+ Chef::DataBagItem.stub(:load).
76
+ with("mybag", "myitem") { stub_bag_item("mybag", "myitem")}
77
+ end
78
+
79
+ it "exits if component type is invalid" do
80
+ @knife.name_args = %w{nodes toasterovens}
81
+
82
+ lambda { @knife.run }.should raise_error SystemExit
83
+ end
84
+
85
+ context "for nodes" do
86
+ before { @knife.name_args = %w{nodes} }
87
+
88
+ it "creates the backup nodes dir" do
89
+ @knife.run
90
+
91
+ File.directory?(["/baks", "nodes"].join("/")).should be_true
92
+ end
93
+
94
+ it "sends a message to the ui" do
95
+ @knife.ui.should_receive(:msg).with(/mynode/)
96
+
97
+ @knife.run
98
+ end
99
+
100
+ it "writes out each node to a json file" do
101
+ @knife.run
102
+ json_str = File.open("/baks/nodes/mynode.json", "rb") { |f| f.read }
103
+ json = JSON.parse(json_str, :create_additions => false)
104
+
105
+ json["name"].should eq("mynode")
106
+ end
107
+ end
108
+
109
+ context "for roles" do
110
+ before { @knife.name_args = %w{roles} }
111
+
112
+ it "creates the backup roles dir" do
113
+ @knife.run
114
+
115
+ File.directory?(["/baks", "roles"].join("/")).should be_true
116
+ end
117
+
118
+ it "sends a message to the ui" do
119
+ @knife.ui.should_receive(:msg).with(/myrole/)
120
+
121
+ @knife.run
122
+ end
123
+
124
+ it "writes out each role to a json file" do
125
+ @knife.run
126
+ json_str = File.open("/baks/roles/myrole.json", "rb") { |f| f.read }
127
+ json = JSON.parse(json_str, :create_additions => false)
128
+
129
+ json["name"].should eq("myrole")
130
+ end
131
+ end
132
+
133
+ context "for environments" do
134
+ before { @knife.name_args = %w{environments} }
135
+
136
+ it "creates the backup environments dir" do
137
+ @knife.run
138
+
139
+ File.directory?(["/baks", "environments"].join("/")).should be_true
140
+ end
141
+
142
+ it "sends a message to the ui" do
143
+ @knife.ui.should_receive(:msg).with(/myenv/)
144
+
145
+ @knife.run
146
+ end
147
+
148
+ it "writes out each environment to a json file" do
149
+ @knife.run
150
+ json_str = File.open("/baks/environments/myenv.json", "rb") { |f| f.read }
151
+ json = JSON.parse(json_str, :create_additions => false)
152
+
153
+ json["name"].should eq("myenv")
154
+ end
155
+
156
+ it "skips the _default environment" do
157
+ Chef::Environment.stub(:list) { Hash["_default" => "http://url"] }
158
+ Chef::Environment.stub(:load).with("_default") { stub_env("_default") }
159
+ @knife.run
160
+
161
+ File.exists?("/baks/environments/_default.json").should_not be_true
162
+ end
163
+ end
164
+
165
+ context "for data_bags" do
166
+ before { @knife.name_args = %w{data_bags} }
167
+
168
+ it "creates the backup data_bags dir" do
169
+ @knife.run
170
+
171
+ File.directory?(["/baks", "data_bags"].join("/")).should be_true
172
+ end
173
+
174
+ it "sends messages to the ui" do
175
+ @knife.ui.should_receive(:msg).with(/myitem/)
176
+
177
+ @knife.run
178
+ end
179
+
180
+ it "writes out each data bag item to a json file" do
181
+ @knife.run
182
+ json_str = File.open("/baks/data_bags/mybag/myitem.json", "rb") { |f| f.read }
183
+ json = JSON.parse(json_str, :create_additions => false)
184
+
185
+ json["name"].should eq("data_bag_item_mybag_myitem")
186
+ end
187
+ end
188
+
189
+ context "for all" do
190
+ it "writes a node file" do
191
+ @knife.run
192
+
193
+ File.exists?("/baks/nodes/mynode.json").should be_true
194
+ end
195
+
196
+ it "writes a role file" do
197
+ @knife.run
198
+
199
+ File.exists?("/baks/roles/myrole.json").should be_true
200
+ end
201
+
202
+ it "writes an environment file" do
203
+ @knife.run
204
+
205
+ File.exists?("/baks/environments/myenv.json").should be_true
206
+ end
207
+
208
+ it "writes a data bag item file" do
209
+ @knife.run
210
+
211
+ File.exists?("/baks/data_bags/mybag/myitem.json").should be_true
212
+ end
213
+ end
214
+ end
215
+
216
+ private
217
+
218
+ def stub_node(name)
219
+ n = Chef::Node.new
220
+ n.name(name)
221
+ n
222
+ end
223
+
224
+ def stub_role(name)
225
+ r = Chef::Role.new
226
+ r.name(name)
227
+ r
228
+ end
229
+
230
+ def stub_env(name)
231
+ e = Chef::Environment.new
232
+ e.name(name)
233
+ e
234
+ end
235
+
236
+ def stub_bag_item(bag, name)
237
+ d = Chef::DataBagItem.new
238
+ d.data_bag(bag)
239
+ d.raw_data[:id] = name
240
+ d
241
+ end
242
+ end
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'chef/knife/server_bootstrap_ec2'
2
20
  require 'chef/knife/ec2_server_create'
3
21
  require 'fog'
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'knife/server/credentials'
2
20
  require 'fakefs/spec_helpers'
3
21
 
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'knife/server/ec2_security_group'
2
20
 
3
21
  describe Knife::Server::Ec2SecurityGroup do
@@ -1,3 +1,21 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
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
+
1
19
  require 'knife/server/ssh'
2
20
 
3
21
  describe Knife::Server::SSH do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-24 00:00:00.000000000 Z
12
+ date: 2012-07-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
16
- requirement: &70204688690820 !ruby/object:Gem::Requirement
16
+ requirement: &2156639540 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.3'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70204688690820
24
+ version_requirements: *2156639540
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: net-ssh
27
- requirement: &70204688690400 !ruby/object:Gem::Requirement
27
+ requirement: &2156638860 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70204688690400
35
+ version_requirements: *2156638860
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: chef
38
- requirement: &70204688689840 !ruby/object:Gem::Requirement
38
+ requirement: &2156637980 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.10.10
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70204688689840
46
+ version_requirements: *2156637980
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: knife-ec2
49
- requirement: &70204688688960 !ruby/object:Gem::Requirement
49
+ requirement: &2156637180 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.5.12
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70204688688960
57
+ version_requirements: *2156637180
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &70204688688400 !ruby/object:Gem::Requirement
60
+ requirement: &2156636480 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '2.10'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70204688688400
68
+ version_requirements: *2156636480
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: fakefs
71
- requirement: &70204688687760 !ruby/object:Gem::Requirement
71
+ requirement: &2156635860 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,7 +76,18 @@ dependencies:
76
76
  version: 0.4.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70204688687760
79
+ version_requirements: *2156635860
80
+ - !ruby/object:Gem::Dependency
81
+ name: timecop
82
+ requirement: &2156635340 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: 0.3.5
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2156635340
80
91
  description: Chef Knife plugin to bootstrap Chef Servers
81
92
  email:
82
93
  - fnichol@nichol.ca
@@ -94,12 +105,14 @@ files:
94
105
  - Rakefile
95
106
  - knife-server.gemspec
96
107
  - lib/chef/knife/bootstrap/chef-server-debian.erb
108
+ - lib/chef/knife/server_backup.rb
97
109
  - lib/chef/knife/server_bootstrap_ec2.rb
98
110
  - lib/knife-server.rb
99
111
  - lib/knife/server/credentials.rb
100
112
  - lib/knife/server/ec2_security_group.rb
101
113
  - lib/knife/server/ssh.rb
102
114
  - lib/knife/server/version.rb
115
+ - spec/chef/knife/server_backup_spec.rb
103
116
  - spec/chef/knife/server_bootstrap_ec2_spec.rb
104
117
  - spec/knife/server/credientials_spec.rb
105
118
  - spec/knife/server/ec2_security_group_spec.rb
@@ -129,6 +142,7 @@ signing_key:
129
142
  specification_version: 3
130
143
  summary: Chef Knife plugin to bootstrap Chef Servers
131
144
  test_files:
145
+ - spec/chef/knife/server_backup_spec.rb
132
146
  - spec/chef/knife/server_bootstrap_ec2_spec.rb
133
147
  - spec/knife/server/credientials_spec.rb
134
148
  - spec/knife/server/ec2_security_group_spec.rb