knife-rackspace 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,90 @@
1
+ require 'integration_spec_helper'
2
+ require 'fog'
3
+ require 'knife/dsl'
4
+ require 'chef/knife/rackspace_server_create'
5
+ # include Chef::Knife::DSL
6
+
7
+ [:v1, :v2].each do |api|
8
+ describe api do
9
+ before(:each) do
10
+ Chef::Config[:knife][:rackspace_version] = api.to_s #v2 by default
11
+
12
+ Chef::Knife::Bootstrap.any_instance.stub(:run)
13
+ Chef::Knife::RackspaceServerCreate.any_instance.stub(:tcp_test_ssh).with(anything).and_return(true)
14
+ end
15
+
16
+ it 'should list server flavors', :vcr do
17
+ stdout, stderr, status = knife_capture('rackspace flavor list')
18
+ status.should be(0), "Non-zero exit code.\n#{stdout}\n#{stderr}"
19
+
20
+ expected_output = {
21
+ :v1 => """
22
+ ID Name Architecture RAM Disk
23
+ 1 256 server 64-bit 256 10 GB
24
+ 2 512 server 64-bit 512 20 GB
25
+ 3 1GB server 64-bit 1024 40 GB
26
+ 4 2GB server 64-bit 2048 80 GB
27
+ 5 4GB server 64-bit 4096 160 GB
28
+ 6 8GB server 64-bit 8192 320 GB
29
+ 7 15.5GB server 64-bit 15872 620 GB
30
+ 8 30GB server 64-bit 30720 1200 GB
31
+ """,
32
+ :v2 => """
33
+ ID Name VCPUs RAM Disk
34
+ 2 512MB Standard Instance 1 512 20 GB
35
+ 3 1GB Standard Instance 1 1024 40 GB
36
+ 4 2GB Standard Instance 2 2048 80 GB
37
+ 5 4GB Standard Instance 2 4096 160 GB
38
+ 6 8GB Standard Instance 4 8192 320 GB
39
+ 7 15GB Standard Instance 6 15360 620 GB
40
+ 8 30GB Standard Instance 8 30720 1200 GB
41
+ """}
42
+ stdout = ANSI.unansi stdout
43
+ stdout.should match_output(expected_output[api])
44
+ end
45
+
46
+ it 'should list images', :vcr do
47
+ sample_image = {
48
+ :v1 => 'Ubuntu 12.04 LTS',
49
+ :v2 => 'Ubuntu 12.04 LTS (Precise Pangolin)'
50
+ }
51
+
52
+ stdout, stderr, status = knife_capture('rackspace image list')
53
+ status.should be(0), "Non-zero exit code.\n#{stdout}\n#{stderr}"
54
+ stdout = clean_output(stdout)
55
+ stdout.should match /^ID\s*Name\s*$/
56
+ stdout.should include sample_image[api]
57
+ end
58
+
59
+ it 'should manage servers', :vcr do
60
+ pending "The test works, but I'm in the process of cleaning up sensitive data in the cassettes"
61
+
62
+ image = {
63
+ :v1 => '112',
64
+ :v2 => 'e4dbdba7-b2a4-4ee5-8e8f-4595b6d694ce'
65
+ }
66
+ flavor = 2
67
+ server_list.should_not include 'test-node'
68
+
69
+ args = %W{rackspace server create -I #{image[api]} -f #{flavor} -N test-node -S test-server}
70
+ stdout, stderr, status = knife_capture(args)
71
+ status.should be(0), "Non-zero exit code.\n#{stdout}\n#{stderr}"
72
+ instance_data = capture_instance_data(stdout, {
73
+ :name => 'Name',
74
+ :instance_id => 'Instance ID',
75
+ :public_ip => 'Public IP Address',
76
+ :private_ip => 'Private IP Address'
77
+ })
78
+
79
+ # Wanted to assert active state, but got build during test
80
+ server_list.should match /#{instance_data[:instance_id]}\s*#{instance_data[:name]}\s*#{instance_data[:public_ip]}\s*#{instance_data[:private_ip]}\s*#{flavor}\s*#{image}/
81
+
82
+ args = %W{rackspace server delete #{instance_data[:instance_id]} -y}
83
+ stdout, stderr, status = knife_capture(args)
84
+ status.should be(0), "Non-zero exit code.\n#{stdout}\n#{stderr}"
85
+
86
+ # Need to deal with deleting vs deleted states before we can check this
87
+ # server_list.should_not match /#{instance_data[:instance_id]}\s*#{instance_data[:name]}\s*#{instance_data[:public_ip]}\s*#{instance_data[:private_ip]}\s*#{flavor}\s*#{image}/
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,134 @@
1
+ require 'spec_helper'
2
+ require 'vcr'
3
+ require 'ansi/code'
4
+ require 'ansi/diff'
5
+
6
+ Chef::Config[:knife][:rackspace_api_username] = "#{ENV['OS_USERNAME']}"
7
+ Chef::Config[:knife][:rackspace_api_key] = "#{ENV['OS_PASSWORD']}"
8
+ Chef::Config[:knife][:ssl_verify_peer] = false
9
+ # Chef::Config[:knife][:rackspace_version] = "#{ENV['RS_VERSION']}"
10
+
11
+ VCR.configure do |c|
12
+ c.cassette_library_dir = 'spec/cassettes'
13
+ c.hook_into :excon
14
+ c.configure_rspec_metadata!
15
+
16
+ # Sensitive data
17
+ c.filter_sensitive_data('_RAX_USERNAME_') { Chef::Config[:knife][:rackspace_api_username] }
18
+ c.filter_sensitive_data('_RAX_PASSWORD_') { Chef::Config[:knife][:rackspace_api_key] }
19
+ c.filter_sensitive_data('_CDN-TENANT-NAME_') { ENV['RS_CDN_TENANT_NAME'] }
20
+ c.filter_sensitive_data('000000') { ENV['RS_TENANT_ID'] }
21
+
22
+ c.before_record do |interaction|
23
+ # Sensitive data
24
+ filter_headers(interaction, /X-\w*-Token/, '_ONE-TIME-TOKEN_')
25
+
26
+ # Transient data (trying to avoid unnecessary cassette churn)
27
+ filter_headers(interaction, 'X-Compute-Request-Id', '_COMPUTE-REQUEST-ID_')
28
+ filter_headers(interaction, 'X-Varnish', '_VARNISH-REQUEST-ID_')
29
+
30
+ # Throw away build state - just makes server.wait_for loops really long during replay
31
+ begin
32
+ json = JSON.parse(interaction.response.body)
33
+ if json['server']['status'] == 'BUILD'
34
+ # Ignoring interaction because server is in BUILD state
35
+ interaction.ignore!
36
+ end
37
+ rescue
38
+ end
39
+ end
40
+
41
+ c.before_playback do | interaction |
42
+ interaction.filter!('_TENANT-ID_', '0000000')
43
+ end
44
+
45
+ c.default_cassette_options = {
46
+ # :record => :none,
47
+ # Ignores cache busting parameters.
48
+ :match_requests_on => [:host, :path]
49
+ }
50
+ c.default_cassette_options.merge!({:record => :all}) if ENV['INTEGRATION_TESTS'] == 'live'
51
+ end
52
+
53
+ def filter_headers(interaction, pattern, placeholder)
54
+ [interaction.request.headers, interaction.response.headers].each do | headers |
55
+ sensitive_tokens = headers.select{|key| key.to_s.match(pattern)}
56
+ sensitive_tokens.each do |key, value|
57
+ headers[key] = placeholder
58
+ end
59
+ end
60
+ end
61
+
62
+ RSpec.configure do |c|
63
+ # so we can use :vcr rather than :vcr => true;
64
+ # in RSpec 3 this will no longer be necessary.
65
+ c.treat_symbols_as_metadata_keys_with_true_values = true
66
+ end
67
+
68
+ def clean_output(output)
69
+ output = ANSI.unansi(output)
70
+ output.gsub!(/\s+$/,'')
71
+ output.gsub!("\e[0G", '')
72
+ output
73
+ end
74
+
75
+ RSpec::Matchers.define :match_output do |expected_output|
76
+ match do |actual_output|
77
+ clean_output(actual_output) == expected_output.strip
78
+ end
79
+ # Nice when it works, but has ANSI::Diff has some bugs that prevent it from showing any output
80
+ failure_message_for_should do |actual_output|
81
+ puts clean_output(actual_output)
82
+ puts
83
+ puts expected_output
84
+ # output = clean_output actual_output
85
+ # ANSI::Diff.new(output, expected_output)
86
+ end
87
+ description do
88
+ 'Compare actual and expected output, ignoring ansi color and trailing whitespace'
89
+ end
90
+ end
91
+
92
+ def server_list
93
+ stdout, stderr, status = knife_capture('rackspace server list')
94
+ status == 0 ? stdout : stderr
95
+ end
96
+
97
+ def capture_instance_data(stdout, labels = {})
98
+ result = {}
99
+ labels.each do | key, label |
100
+ result[key] = clean_output(stdout).match(/^#{label}: (.*)$/)[1]
101
+ end
102
+ result
103
+ end
104
+
105
+ # Ideally this belongs in knife-dsl, but it causes a scoping conflict with knife.rb.
106
+ # See https://github.com/chef-workflow/knife-dsl/issues/2
107
+ def knife_capture(command, args=[], input=nil)
108
+ null = Gem.win_platform? ? File.open('NUL:', 'r') : File.open('/dev/null', 'r')
109
+
110
+ if defined? Pry
111
+ Pry.config.input = STDIN
112
+ Pry.config.output = STDOUT
113
+ end
114
+
115
+ warn = $VERBOSE
116
+ $VERBOSE = nil
117
+ old_stderr, old_stdout, old_stdin = $stderr, $stdout, $stdin
118
+
119
+ $stderr = StringIO.new('', 'r+')
120
+ $stdout = StringIO.new('', 'r+')
121
+ $stdin = input ? StringIO.new(input, 'r') : null
122
+ $VERBOSE = warn
123
+
124
+ status = Chef::Knife::DSL::Support.run_knife(command, args)
125
+ return $stdout.string, $stderr.string, status
126
+ ensure
127
+ warn = $VERBOSE
128
+ $VERBOSE = nil
129
+ $stderr = old_stderr
130
+ $stdout = old_stdout
131
+ $stdin = old_stdin
132
+ $VERBOSE = warn
133
+ null.close
134
+ end
@@ -0,0 +1,3 @@
1
+ $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'chef/knife/bootstrap'
3
+ require 'chef/knife/rackspace_base'
metadata CHANGED
@@ -1,69 +1,144 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: knife-rackspace
3
- version: !ruby/object:Gem::Version
4
- hash: 3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 6
9
- - 2
10
- version: 0.6.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Adam Jacob
14
9
  - Seth Chisamore
15
10
  - Matt Ray
16
11
  autorequire:
17
12
  bindir: bin
18
13
  cert_chain: []
19
-
20
- date: 2012-10-16 00:00:00 Z
21
- dependencies:
22
- - !ruby/object:Gem::Dependency
14
+ date: 2013-06-07 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
23
17
  name: fog
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: '1.6'
24
+ type: :runtime
24
25
  prerelease: false
25
- requirement: &id001 !ruby/object:Gem::Requirement
26
+ version_requirements: !ruby/object:Gem::Requirement
26
27
  none: false
27
- requirements:
28
+ requirements:
28
29
  - - ~>
29
- - !ruby/object:Gem::Version
30
- hash: 3
31
- segments:
32
- - 1
33
- - 6
34
- version: "1.6"
30
+ - !ruby/object:Gem::Version
31
+ version: '1.6'
32
+ - !ruby/object:Gem::Dependency
33
+ name: knife-windows
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
35
40
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: chef
39
41
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
42
+ version_requirements: !ruby/object:Gem::Requirement
41
43
  none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 35
46
- segments:
47
- - 0
48
- - 10
49
- - 10
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: chef
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
50
55
  version: 0.10.10
51
56
  type: :runtime
52
- version_requirements: *id002
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: 0.10.10
64
+ - !ruby/object:Gem::Dependency
65
+ name: rspec
66
+ requirement: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ type: :development
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: vcr
82
+ requirement: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: ansi
98
+ requirement: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rake
114
+ requirement: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
53
128
  description: Rackspace Support for Chef's Knife Command
54
- email:
129
+ email:
55
130
  - adam@opscode.com
56
131
  - schisamo@opscode.com
57
132
  - matt@opscode.com
58
133
  executables: []
59
-
60
134
  extensions: []
61
-
62
- extra_rdoc_files:
135
+ extra_rdoc_files:
63
136
  - README.rdoc
64
137
  - LICENSE
65
- files:
138
+ files:
139
+ - .chef/knife.rb
66
140
  - .gitignore
141
+ - .travis.yml
67
142
  - CHANGELOG.md
68
143
  - Gemfile
69
144
  - LICENSE
@@ -73,42 +148,49 @@ files:
73
148
  - lib/chef/knife/rackspace_base.rb
74
149
  - lib/chef/knife/rackspace_flavor_list.rb
75
150
  - lib/chef/knife/rackspace_image_list.rb
151
+ - lib/chef/knife/rackspace_network_create.rb
152
+ - lib/chef/knife/rackspace_network_delete.rb
153
+ - lib/chef/knife/rackspace_network_list.rb
76
154
  - lib/chef/knife/rackspace_server_create.rb
77
155
  - lib/chef/knife/rackspace_server_delete.rb
78
156
  - lib/chef/knife/rackspace_server_list.rb
79
157
  - lib/knife-rackspace/version.rb
158
+ - spec/cassettes/v1/should_list_images.yml
159
+ - spec/cassettes/v1/should_list_server_flavors.yml
160
+ - spec/cassettes/v2/should_list_images.yml
161
+ - spec/cassettes/v2/should_list_server_flavors.yml
162
+ - spec/integration/integration_spec.rb
163
+ - spec/integration_spec_helper.rb
164
+ - spec/spec_helper.rb
80
165
  homepage: http://wiki.opscode.com/display/chef
81
166
  licenses: []
82
-
83
167
  post_install_message:
84
168
  rdoc_options: []
85
-
86
- require_paths:
169
+ require_paths:
87
170
  - lib
88
- required_ruby_version: !ruby/object:Gem::Requirement
171
+ required_ruby_version: !ruby/object:Gem::Requirement
89
172
  none: false
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- hash: 3
94
- segments:
95
- - 0
96
- version: "0"
97
- required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ! '>='
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
178
  none: false
99
- requirements:
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- hash: 3
103
- segments:
104
- - 0
105
- version: "0"
179
+ requirements:
180
+ - - ! '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
106
183
  requirements: []
107
-
108
184
  rubyforge_project:
109
- rubygems_version: 1.8.10
185
+ rubygems_version: 1.8.25
110
186
  signing_key:
111
187
  specification_version: 3
112
188
  summary: Rackspace Support for Chef's Knife Command
113
- test_files: []
114
-
189
+ test_files:
190
+ - spec/cassettes/v1/should_list_images.yml
191
+ - spec/cassettes/v1/should_list_server_flavors.yml
192
+ - spec/cassettes/v2/should_list_images.yml
193
+ - spec/cassettes/v2/should_list_server_flavors.yml
194
+ - spec/integration/integration_spec.rb
195
+ - spec/integration_spec_helper.rb
196
+ - spec/spec_helper.rb