vcloud-core 0.15.0 → 0.16.0

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.
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