vcloud-core 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.16.0 (2014-12-03)
2
+
3
+ Features:
4
+
5
+ - New `vlcoud-logout` command line utility to revoke session tokens.
6
+ - New `Vcloud::Core::Fog.logout` method to revoke session tokens.
7
+
1
8
  ## 0.15.0 (2014-11-26)
2
9
 
3
10
  Features:
data/bin/vcloud-logout ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'vcloud/core'
4
+
5
+ Vcloud::Core::LogoutCli.new(ARGV).run
data/jenkins_tests.sh CHANGED
@@ -32,6 +32,7 @@ rm -rf vcloud-tools-testing-config
32
32
  # Never log token to STDOUT.
33
33
  set +x
34
34
  eval $(printenv API_PASSWORD | bundle exec vcloud-login)
35
+ trap "bundle exec vcloud-logout" EXIT
35
36
 
36
37
  bundle exec rake
37
38
  bundle exec rake integration
data/lib/vcloud/core.rb CHANGED
@@ -13,6 +13,7 @@ require 'vcloud/core/vdc'
13
13
  require 'vcloud/core/edge_gateway'
14
14
  require 'vcloud/core/edge_gateway_interface'
15
15
  require 'vcloud/core/login_cli'
16
+ require 'vcloud/core/logout_cli'
16
17
  require 'vcloud/core/vm'
17
18
  require 'vcloud/core/vapp'
18
19
  require 'vcloud/core/vapp_template'
@@ -10,6 +10,21 @@ module Vcloud
10
10
  TOKEN_ENV_VAR_NAME = 'FOG_VCLOUD_TOKEN'
11
11
  FOG_CREDS_PASS_NAME = :vcloud_director_password
12
12
 
13
+ # Logout an existing vCloud session, rendering the token unusable.
14
+ # Requires a FOG_VCLOUD_TOKEN environment variable to be set.
15
+ #
16
+ # @return [Boolean] return true or raise an exception
17
+ def self.logout
18
+ unless ENV[TOKEN_ENV_VAR_NAME]
19
+ raise "#{TOKEN_ENV_VAR_NAME} environment variable is not set"
20
+ end
21
+
22
+ fsi = Vcloud::Core::Fog::ServiceInterface.new
23
+ fsi.logout
24
+
25
+ return true
26
+ end
27
+
13
28
  # Run any checks needed against the Fog credentials
14
29
  # currently only used to disallow plaintext passwords
15
30
  # in .fog files.
@@ -18,7 +18,8 @@ module Vcloud
18
18
  :put_vm, :get_edge_gateway, :get_network_complete, :delete_network, :post_create_org_vdc_network,
19
19
  :post_configure_edge_gateway_services, :get_vdc, :post_undeploy_vapp,
20
20
  :post_create_disk, :get_disk, :delete_disk, :post_attach_disk,
21
- :get_vms_disk_attached_to, :post_detach_disk, :put_product_sections
21
+ :get_vms_disk_attached_to, :post_detach_disk, :put_product_sections,
22
+ :logout
22
23
 
23
24
  #########################
24
25
  # FogFacade Inner class to represent a logic free facade over our interactions with Fog
@@ -40,6 +41,10 @@ module Vcloud
40
41
  @vcloud.get_current_session.body
41
42
  end
42
43
 
44
+ def logout
45
+ @vcloud.delete_logout
46
+ end
47
+
43
48
  def get_vapps_in_lease_from_query(options)
44
49
  @vcloud.get_vapps_in_lease_from_query(options).body
45
50
  end
@@ -0,0 +1,72 @@
1
+ require 'optparse'
2
+
3
+ module Vcloud
4
+ module Core
5
+ class LogoutCli
6
+
7
+ # Create a new instance of the CLI, parsing the arguments supplied
8
+ #
9
+ # @param argv_array [Array] The Array of ARGV arguments
10
+ # @return [Vcloud::Core::LogoutCLI]
11
+ def initialize(argv_array)
12
+ @usage_text = nil
13
+
14
+ parse(argv_array)
15
+ end
16
+
17
+ # Logout an existing vCloud session.
18
+ #
19
+ # @return [void]
20
+ def run
21
+ begin
22
+ Vcloud::Core::Fog.logout
23
+ rescue => e
24
+ $stderr.puts("#{e.class}: #{e.message}")
25
+ exit 1
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def parse(args)
32
+ opt_parser = OptionParser.new do |opts|
33
+ opts.banner = <<-EOS
34
+ Usage: #{$0} [options]
35
+
36
+ Utility for logging out of a vCloud session and preventing future use of the
37
+ session token. A `FOG_VCLOUD_TOKEN` environment variable, as provided by
38
+ `vcloud-login`, must be present.
39
+
40
+ EOS
41
+
42
+ opts.on("-h", "--help", "Print usage and exit") do
43
+ $stderr.puts opts
44
+ exit
45
+ end
46
+
47
+ opts.on("--version", "Display version and exit") do
48
+ puts Vcloud::Core::VERSION
49
+ exit
50
+ end
51
+ end
52
+
53
+ @usage_text = opt_parser.to_s
54
+ begin
55
+ opt_parser.parse!(args)
56
+ rescue OptionParser::InvalidOption => e
57
+ exit_error_usage(e)
58
+ end
59
+
60
+ if args.size > 0
61
+ exit_error_usage("too many arguments")
62
+ end
63
+ end
64
+
65
+ def exit_error_usage(error)
66
+ $stderr.puts "#{$0}: #{error}"
67
+ $stderr.puts @usage_text
68
+ exit 2
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  module Vcloud
2
2
  module Core
3
- VERSION = '0.15.0'
3
+ VERSION = '0.16.0'
4
4
  end
5
5
  end
@@ -42,10 +42,17 @@ describe Vcloud::Core::Fog::Login do
42
42
  let(:envvar_password) { 'API_PASSWORD' }
43
43
 
44
44
  before(:each) do
45
+ @temp_token = nil
45
46
  @real_password = ENV[envvar_password]
46
47
  stub_const('ENV', {})
47
48
  end
48
49
 
50
+ after(:each) do
51
+ stub_const('ENV', { envvar_token => @temp_token })
52
+ fsi = Vcloud::Core::Fog::ServiceInterface.new
53
+ fsi.logout
54
+ end
55
+
49
56
  context "environment variable VCLOUD_FOG_TOKEN not set" do
50
57
  it "should login and return a token" do
51
58
  unless @real_password
@@ -53,8 +60,8 @@ describe Vcloud::Core::Fog::Login do
53
60
  end
54
61
 
55
62
  expect(ENV).not_to have_key(envvar_token)
56
- token = subject.token(@real_password)
57
- expect(token.size).to eq(token_length)
63
+ @temp_token = subject.token(@real_password)
64
+ expect(@temp_token.size).to eq(token_length)
58
65
  end
59
66
  end
60
67
 
@@ -67,9 +74,9 @@ describe Vcloud::Core::Fog::Login do
67
74
  end
68
75
 
69
76
  ENV[envvar_token] = old_token
70
- new_token = subject.token(@real_password)
71
- expect(new_token).to_not eq(old_token)
72
- expect(new_token.size).to eq(token_length)
77
+ @temp_token = subject.token(@real_password)
78
+ expect(@temp_token).to_not eq(old_token)
79
+ expect(@temp_token.size).to eq(token_length)
73
80
  end
74
81
  end
75
82
  end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vcloud::Core::Fog do
4
+ describe "#logout" do
5
+ let(:subject) { Vcloud::Core::Fog.logout }
6
+
7
+ let(:envvar_token) { 'FOG_VCLOUD_TOKEN' }
8
+ let(:envvar_password) { 'API_PASSWORD' }
9
+
10
+ context "with a valid token" do
11
+ before(:each) do
12
+ @real_password = ENV[envvar_password]
13
+ unless @real_password
14
+ pending "Password not available from environment variable #{envvar_password}"
15
+ end
16
+
17
+ stub_const('ENV', {})
18
+ temp_token = Vcloud::Core::Fog::Login.token(@real_password)
19
+ ENV[envvar_token] = temp_token
20
+ end
21
+
22
+ it "should invalidate a previously working session" do
23
+ fsi = Vcloud::Core::Fog::ServiceInterface.new
24
+ expect(fsi.session).to include(:user, :org)
25
+
26
+ expect(subject).to eq(true)
27
+ # logout appears to sometimes be slightly asynchronous and doesn't
28
+ # provide a task that we can monitor the progress of.
29
+ sleep(1)
30
+
31
+ fsi = Vcloud::Core::Fog::ServiceInterface.new
32
+ expect{ fsi.session }.to raise_error(
33
+ Fog::Compute::VcloudDirector::Forbidden, "Access is forbidden"
34
+ )
35
+ end
36
+ end
37
+
38
+ context "with an invalid token" do
39
+ before(:each) do
40
+ stub_const('ENV', { envvar_token => 'invalid' })
41
+ end
42
+
43
+ it "should raise an exception from Fog" do
44
+ expect{ subject }.to raise_error(
45
+ Fog::Compute::VcloudDirector::Forbidden, "Access is forbidden"
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,6 +1,24 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Vcloud::Core::Fog do
4
+ describe "logout" do
5
+ let(:subject) { Vcloud::Core::Fog::logout }
6
+ let(:envvar_token) { 'FOG_VCLOUD_TOKEN' }
7
+
8
+ context "token environment variable not set" do
9
+ before(:each) do
10
+ stub_const('ENV', {})
11
+ end
12
+
13
+ it "should raise an error" do
14
+ expect(Vcloud::Core::Fog::ServiceInterface).not_to receive(:new)
15
+ expect { subject }.to raise_error(
16
+ RuntimeError, "FOG_VCLOUD_TOKEN environment variable is not set"
17
+ )
18
+ end
19
+ end
20
+ end
21
+
4
22
  describe "fog_credentials_pass" do
5
23
  let(:subject) { Vcloud::Core::Fog::fog_credentials_pass }
6
24
 
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ class LogoutCommandRun
4
+ attr_accessor :stdout, :stderr, :exitstatus
5
+
6
+ def initialize(args)
7
+ out = StringIO.new
8
+ err = StringIO.new
9
+
10
+ $stdout = out
11
+ $stderr = err
12
+
13
+ begin
14
+ Vcloud::Core::LogoutCli.new(args).run
15
+ @exitstatus = 0
16
+ rescue SystemExit => e
17
+ # Capture exit(n) value.
18
+ @exitstatus = e.status
19
+ end
20
+
21
+ @stdout = out.string.strip
22
+ @stderr = err.string.strip
23
+
24
+ $stdout = STDOUT
25
+ $stderr = STDERR
26
+ end
27
+ end
28
+
29
+ describe Vcloud::Core::LogoutCli do
30
+ subject { LogoutCommandRun.new(args) }
31
+
32
+ describe "normal usage" do
33
+ context "when given no arguments" do
34
+ let(:args) { %w{} }
35
+
36
+ it "should " do
37
+ expect(Vcloud::Core::Fog).to receive(:logout).and_return({})
38
+ expect(subject.stderr).to eq("")
39
+ expect(subject.exitstatus).to eq(0)
40
+ end
41
+ end
42
+
43
+ context "when asked to display version" do
44
+ let(:args) { %w{--version} }
45
+
46
+ it "should not call Logout" do
47
+ expect(Vcloud::Core::Fog).not_to receive(:logout)
48
+ end
49
+
50
+ it "should print version and exit normally" do
51
+ expect(subject.stdout).to eq(Vcloud::Core::VERSION)
52
+ expect(subject.exitstatus).to eq(0)
53
+ end
54
+ end
55
+
56
+ context "when asked to display help" do
57
+ let(:args) { %w{--help} }
58
+
59
+ it "should not call Logout" do
60
+ expect(Vcloud::Core::Fog).not_to receive(:logout)
61
+ end
62
+
63
+ it "should print usage and exit normally" do
64
+ expect(subject.stderr).to match(/\AUsage: \S+ \[options\]\n/)
65
+ expect(subject.exitstatus).to eq(0)
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "incorrect usage" do
71
+ shared_examples "print usage and exit abnormally" do |error|
72
+ it "should not call Logout" do
73
+ expect(Vcloud::Core::Fog).not_to receive(:logout)
74
+ end
75
+
76
+ it "should print error message and usage" do
77
+ expect(subject.stderr).to match(/\A\S+: #{error}\nUsage: \S+/)
78
+ end
79
+
80
+ it "should exit abnormally for incorrect usage" do
81
+ expect(subject.exitstatus).to eq(2)
82
+ end
83
+ end
84
+
85
+ context "when given more than one argument" do
86
+ let(:args) { %w{an_extra_arg} }
87
+
88
+ it_behaves_like "print usage and exit abnormally", "too many arguments"
89
+ end
90
+
91
+ context "when given an unrecognised argument" do
92
+ let(:args) { %w{--this-is-garbage} }
93
+
94
+ it_behaves_like "print usage and exit abnormally", "invalid option: --this-is-garbage"
95
+ end
96
+ end
97
+
98
+ describe "error handling" do
99
+ context "when underlying code raises an exception" do
100
+ let(:args) { %w{} }
101
+ let(:exception) { RuntimeError.new('something went horribly wrong') }
102
+
103
+ it "should print error without backtrace and exit abnormally" do
104
+ expect(Vcloud::Core::Fog).to receive(:logout).and_raise(exception)
105
+ expect(subject.stderr).to eq("RuntimeError: something went horribly wrong")
106
+ expect(subject.exitstatus).to eq(1)
107
+ end
108
+ end
109
+ end
110
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vcloud-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.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: 2014-11-27 00:00:00.000000000 Z
12
+ date: 2014-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
16
- requirement: &17329660 !ruby/object:Gem::Requirement
16
+ requirement: &13600400 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.25.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *17329660
24
+ version_requirements: *13600400
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mustache
27
- requirement: &17329280 !ruby/object:Gem::Requirement
27
+ requirement: &13195100 !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: *17329280
35
+ version_requirements: *13195100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: highline
38
- requirement: &17328820 !ruby/object:Gem::Requirement
38
+ requirement: &13191240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *17328820
46
+ version_requirements: *13191240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: gem_publisher
49
- requirement: &17328320 !ruby/object:Gem::Requirement
49
+ requirement: &13189080 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - =
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.2.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *17328320
57
+ version_requirements: *13189080
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: pry
60
- requirement: &17327900 !ruby/object:Gem::Requirement
60
+ requirement: &13314900 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *17327900
68
+ version_requirements: *13314900
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
- requirement: &17327440 !ruby/object:Gem::Requirement
71
+ requirement: &13311520 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *17327440
79
+ version_requirements: *13311520
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &17326940 !ruby/object:Gem::Requirement
82
+ requirement: &13266620 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 2.14.1
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *17326940
90
+ version_requirements: *13266620
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rubocop
93
- requirement: &17326440 !ruby/object:Gem::Requirement
93
+ requirement: &13658140 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 0.23.0
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *17326440
101
+ version_requirements: *13658140
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: simplecov
104
- requirement: &17325980 !ruby/object:Gem::Requirement
104
+ requirement: &13655200 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 0.7.1
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *17325980
112
+ version_requirements: *13655200
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: vcloud-tools-tester
115
- requirement: &17325520 !ruby/object:Gem::Requirement
115
+ requirement: &13653640 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
@@ -120,13 +120,14 @@ dependencies:
120
120
  version: 0.2.0
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *17325520
123
+ version_requirements: *13653640
124
124
  description: Core tools for interacting with VMware vCloud Director. Includes VCloud
125
125
  Query, a light wrapper round the vCloud Query API.
126
126
  email:
127
127
  - anna.shipman@digital.cabinet-office.gov.uk
128
128
  executables:
129
129
  - vcloud-login
130
+ - vcloud-logout
130
131
  - vcloud-query
131
132
  extensions: []
132
133
  extra_rdoc_files: []
@@ -140,6 +141,7 @@ files:
140
141
  - README.md
141
142
  - Rakefile
142
143
  - bin/vcloud-login
144
+ - bin/vcloud-logout
143
145
  - bin/vcloud-query
144
146
  - jenkins.sh
145
147
  - jenkins_tests.sh
@@ -158,6 +160,7 @@ files:
158
160
  - lib/vcloud/core/fog/service_interface.rb
159
161
  - lib/vcloud/core/independent_disk.rb
160
162
  - lib/vcloud/core/login_cli.rb
163
+ - lib/vcloud/core/logout_cli.rb
161
164
  - lib/vcloud/core/metadata_helper.rb
162
165
  - lib/vcloud/core/org_vdc_network.rb
163
166
  - lib/vcloud/core/query.rb
@@ -171,6 +174,7 @@ files:
171
174
  - spec/integration/README.md
172
175
  - spec/integration/core/edge_gateway_spec.rb
173
176
  - spec/integration/core/fog/login_spec.rb
177
+ - spec/integration/core/fog_spec.rb
174
178
  - spec/integration/core/independent_disk_spec.rb
175
179
  - spec/integration/core/query_runner_spec.rb
176
180
  - spec/integration/core/vapp_spec.rb
@@ -198,6 +202,7 @@ files:
198
202
  - spec/vcloud/core/fog_spec.rb
199
203
  - spec/vcloud/core/independent_disk_spec.rb
200
204
  - spec/vcloud/core/login_cli_spec.rb
205
+ - spec/vcloud/core/logout_cli_spec.rb
201
206
  - spec/vcloud/core/metadata_helper_spec.rb
202
207
  - spec/vcloud/core/org_vdc_network_spec.rb
203
208
  - spec/vcloud/core/query_cli_spec.rb
@@ -229,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
234
  version: '0'
230
235
  segments:
231
236
  - 0
232
- hash: 760204335874509684
237
+ hash: -1936108381695817520
233
238
  requirements: []
234
239
  rubyforge_project:
235
240
  rubygems_version: 1.8.11
@@ -240,6 +245,7 @@ test_files:
240
245
  - spec/integration/README.md
241
246
  - spec/integration/core/edge_gateway_spec.rb
242
247
  - spec/integration/core/fog/login_spec.rb
248
+ - spec/integration/core/fog_spec.rb
243
249
  - spec/integration/core/independent_disk_spec.rb
244
250
  - spec/integration/core/query_runner_spec.rb
245
251
  - spec/integration/core/vapp_spec.rb
@@ -267,6 +273,7 @@ test_files:
267
273
  - spec/vcloud/core/fog_spec.rb
268
274
  - spec/vcloud/core/independent_disk_spec.rb
269
275
  - spec/vcloud/core/login_cli_spec.rb
276
+ - spec/vcloud/core/logout_cli_spec.rb
270
277
  - spec/vcloud/core/metadata_helper_spec.rb
271
278
  - spec/vcloud/core/org_vdc_network_spec.rb
272
279
  - spec/vcloud/core/query_cli_spec.rb