vcloud-core 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +13 -0
- data/README.md +1 -35
- data/bin/vcloud-login +5 -0
- data/jenkins.sh +2 -11
- data/jenkins_integration_tests.sh +3 -10
- data/jenkins_tests.sh +37 -0
- data/lib/vcloud/core.rb +1 -0
- data/lib/vcloud/core/login_cli.rb +84 -0
- data/lib/vcloud/core/version.rb +1 -1
- data/lib/vcloud/fog.rb +34 -0
- data/lib/vcloud/fog/login.rb +38 -0
- data/spec/integration/fog/login_manual.rb +47 -0
- data/spec/integration/fog/login_spec.rb +30 -0
- data/spec/vcloud/core/login_cli_spec.rb +147 -0
- data/spec/vcloud/core/query_cli_spec.rb +2 -2
- data/spec/vcloud/fog/login_spec.rb +48 -0
- data/spec/vcloud/fog_spec.rb +30 -0
- data/vcloud-core.gemspec +1 -0
- metadata +34 -4
- data/tools/fog_credentials.rb +0 -17
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 0.7.0 (2014-07-28)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- New vcloud-login tool for fetching session tokens without the need to
|
6
|
+
store your password in a plaintext FOG_RC file.
|
7
|
+
|
8
|
+
Deprecated:
|
9
|
+
|
10
|
+
- Deprecate the use of :vcloud_director_password in a plaintext FOG_RC
|
11
|
+
file. A warning will be printed to STDERR at load time. Please use
|
12
|
+
vcloud-login instead.
|
13
|
+
|
1
14
|
## 0.6.0 (2014-07-14)
|
2
15
|
|
3
16
|
API changes:
|
data/README.md
CHANGED
@@ -20,41 +20,7 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Credentials
|
22
22
|
|
23
|
-
|
24
|
-
credentials that allow it to talk to a vCloud Director environment.
|
25
|
-
|
26
|
-
1. Create a '.fog' file in your home directory.
|
27
|
-
|
28
|
-
For example:
|
29
|
-
|
30
|
-
test_credentials:
|
31
|
-
vcloud_director_host: 'host.api.example.com'
|
32
|
-
vcloud_director_username: 'username@org_name'
|
33
|
-
vcloud_director_password: ''
|
34
|
-
|
35
|
-
2. Obtain a session token. First, curl the API:
|
36
|
-
|
37
|
-
curl -D- -d '' \
|
38
|
-
-H 'Accept: application/*+xml;version=5.1' -u '<username>@<org_name>' \
|
39
|
-
https://<host.api.example.com>/api/sessions
|
40
|
-
|
41
|
-
This will prompt for your password.
|
42
|
-
|
43
|
-
From the headers returned, the value of the `x-vcloud-authorization` header is your
|
44
|
-
session token, and this will be valid for 30 minutes idle - any activity will extend
|
45
|
-
its life by another 30 minutes.
|
46
|
-
|
47
|
-
3. Specify your credentials and session token at the beginning of the command. For example:
|
48
|
-
|
49
|
-
FOG_CREDENTIAL=test_credentials \
|
50
|
-
FOG_VCLOUD_TOKEN=AAAABBBBBCCCCCCDDDDDDEEEEEEFFFFF= \
|
51
|
-
vcloud-query
|
52
|
-
|
53
|
-
You may find it easier to export one or both of the values as environment variables.
|
54
|
-
|
55
|
-
**NB** It is also possible to sidestep the need for the session token by saving your
|
56
|
-
password in the fog file. This is **not recommended**.
|
57
|
-
|
23
|
+
Please see the [vcloud-tools usage documentation](http://gds-operations.github.io/vcloud-tools/usage/).
|
58
24
|
|
59
25
|
## vCloud Query
|
60
26
|
|
data/bin/vcloud-login
ADDED
data/jenkins.sh
CHANGED
@@ -1,14 +1,5 @@
|
|
1
|
-
#!/bin/bash
|
1
|
+
#!/bin/bash
|
2
2
|
set -e
|
3
3
|
|
4
|
-
|
5
|
-
bundle install --path "${HOME}/bundles/${JOB_NAME}"
|
6
|
-
|
7
|
-
# Obtain the integration test parameters
|
8
|
-
git clone git@github.gds:gds/vcloud-tools-testing-config.git
|
9
|
-
mv vcloud-tools-testing-config/vcloud_tools_testing_config.yaml spec/integration/
|
10
|
-
rm -rf vcloud-tools-testing-config
|
11
|
-
|
12
|
-
bundle exec rake
|
13
|
-
RUBYOPT="-r ./tools/fog_credentials" bundle exec rake integration
|
4
|
+
./jenkins_tests.sh
|
14
5
|
bundle exec rake publish_gem
|
@@ -1,12 +1,5 @@
|
|
1
|
-
#!/bin/bash
|
1
|
+
#!/bin/bash
|
2
2
|
set -e
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# Obtain the integration test parameters
|
8
|
-
git clone git@github.gds:gds/vcloud-tools-testing-config.git
|
9
|
-
mv vcloud-tools-testing-config/vcloud_tools_testing_config.yaml spec/integration/
|
10
|
-
rm -rf vcloud-tools-testing-config
|
11
|
-
|
12
|
-
RUBYOPT="-r ./tools/fog_credentials" bundle exec rake integration
|
4
|
+
# FIXME: Change the Carrenza job to use the following script directly.
|
5
|
+
./jenkins_tests.sh
|
data/jenkins_tests.sh
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -eu
|
3
|
+
|
4
|
+
function cleanup {
|
5
|
+
rm $FOG_RC
|
6
|
+
}
|
7
|
+
|
8
|
+
# Override default of ~/.fog and delete afterwards.
|
9
|
+
export FOG_RC=$(mktemp /tmp/vcloud_fog_rc.XXXXXXXXXX)
|
10
|
+
trap cleanup EXIT
|
11
|
+
|
12
|
+
cat <<EOF >${FOG_RC}
|
13
|
+
${FOG_CREDENTIAL}:
|
14
|
+
vcloud_director_host: '${API_HOST}'
|
15
|
+
vcloud_director_username: '${API_USERNAME}'
|
16
|
+
vcloud_director_password: ''
|
17
|
+
EOF
|
18
|
+
|
19
|
+
git clean -ffdx
|
20
|
+
|
21
|
+
# We wish to force using a version of ruby installed with rbenv, because the version of ruby shipped with
|
22
|
+
# Ubuntu 12.04 has a bug we hit in Psych when loading YAML files.
|
23
|
+
export RBENV_VERSION="1.9.3"
|
24
|
+
|
25
|
+
bundle install --path "${HOME}/bundles/${JOB_NAME}" --shebang="/usr/bin/env ruby"
|
26
|
+
|
27
|
+
# Obtain the integration test parameters
|
28
|
+
git clone git@github.gds:gds/vcloud-tools-testing-config.git
|
29
|
+
mv vcloud-tools-testing-config/vcloud_tools_testing_config.yaml spec/integration/
|
30
|
+
rm -rf vcloud-tools-testing-config
|
31
|
+
|
32
|
+
# Never log token to STDOUT.
|
33
|
+
set +x
|
34
|
+
eval $(printenv API_PASSWORD | bundle exec vcloud-login)
|
35
|
+
|
36
|
+
bundle exec rake
|
37
|
+
bundle exec rake integration
|
data/lib/vcloud/core.rb
CHANGED
@@ -11,6 +11,7 @@ require 'vcloud/core/compute_metadata'
|
|
11
11
|
require 'vcloud/core/vdc'
|
12
12
|
require 'vcloud/core/edge_gateway'
|
13
13
|
require 'vcloud/core/edge_gateway_interface'
|
14
|
+
require 'vcloud/core/login_cli'
|
14
15
|
require 'vcloud/core/vm'
|
15
16
|
require 'vcloud/core/vapp'
|
16
17
|
require 'vcloud/core/vapp_template'
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'highline'
|
3
|
+
|
4
|
+
module Vcloud
|
5
|
+
module Core
|
6
|
+
class LoginCli
|
7
|
+
def initialize(argv_array)
|
8
|
+
@usage_text = nil
|
9
|
+
|
10
|
+
parse(argv_array)
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
begin
|
15
|
+
pass = read_pass
|
16
|
+
puts Vcloud::Fog::Login.token_export(pass)
|
17
|
+
rescue => e
|
18
|
+
$stderr.puts(e)
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse(args)
|
26
|
+
opt_parser = OptionParser.new do |opts|
|
27
|
+
opts.banner = <<-EOS
|
28
|
+
Usage: #{$0} [options]
|
29
|
+
|
30
|
+
Utility for obtaining a Fog vCloud Director session token. It will output a
|
31
|
+
shell `export` command that can be consumed with:
|
32
|
+
|
33
|
+
eval $(FOG_CREDENTIAL=example #{$0})
|
34
|
+
|
35
|
+
It requires a Fog credentials file (e.g. `~/.fog`) with the host and user
|
36
|
+
set, but the password set to an empty string. The password can either be
|
37
|
+
entered interactively or piped in, for example from an environment variable:
|
38
|
+
|
39
|
+
printenv PASSWORD_VAR | FOG_CREDENTIAL=example #{$0}
|
40
|
+
|
41
|
+
EOS
|
42
|
+
|
43
|
+
opts.on("-h", "--help", "Print usage and exit") do
|
44
|
+
$stderr.puts opts
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("--version", "Display version and exit") do
|
49
|
+
puts Vcloud::Core::VERSION
|
50
|
+
exit
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
@usage_text = opt_parser.to_s
|
55
|
+
begin
|
56
|
+
opt_parser.parse!(args)
|
57
|
+
rescue OptionParser::InvalidOption => e
|
58
|
+
exit_error_usage(e)
|
59
|
+
end
|
60
|
+
|
61
|
+
if args.size > 0
|
62
|
+
exit_error_usage("too many arguments")
|
63
|
+
elsif args.size == 1
|
64
|
+
@type = args.first
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def read_pass
|
69
|
+
hl = HighLine.new($stdin, $stderr)
|
70
|
+
if STDIN.tty?
|
71
|
+
hl.ask("vCloud password: ") { |q| q.echo = "*" }
|
72
|
+
else
|
73
|
+
hl.ask("Reading password from pipe..")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def exit_error_usage(error)
|
78
|
+
$stderr.puts "#{$0}: #{error}"
|
79
|
+
$stderr.puts @usage_text
|
80
|
+
exit 2
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/vcloud/core/version.rb
CHANGED
data/lib/vcloud/fog.rb
CHANGED
@@ -1,5 +1,39 @@
|
|
1
1
|
require 'fog'
|
2
2
|
require 'vcloud/fog/content_types'
|
3
|
+
require 'vcloud/fog/login'
|
3
4
|
require 'vcloud/fog/relation'
|
4
5
|
require 'vcloud/fog/service_interface'
|
5
6
|
require 'vcloud/fog/model_interface'
|
7
|
+
|
8
|
+
module Vcloud
|
9
|
+
module Fog
|
10
|
+
TOKEN_ENV_VAR_NAME = 'FOG_VCLOUD_TOKEN'
|
11
|
+
FOG_CREDS_PASS_NAME = :vcloud_director_password
|
12
|
+
|
13
|
+
def self.check_credentials
|
14
|
+
pass = fog_credentials_pass
|
15
|
+
unless pass.nil? or pass.empty?
|
16
|
+
warn <<EOF
|
17
|
+
[WARNING] Storing :vcloud_director_password in your plaintext FOG_RC file is
|
18
|
+
insecure. Future releases of vcloud-core (and tools that depend on
|
19
|
+
it) will prevent you from doing this. Please use vcloud-login to
|
20
|
+
get a session token instead.
|
21
|
+
EOF
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.fog_credentials_pass
|
26
|
+
begin
|
27
|
+
pass = ::Fog.credentials[FOG_CREDS_PASS_NAME]
|
28
|
+
rescue ::Fog::Errors::LoadError
|
29
|
+
# Assume no password if Fog has been unable to load creds.
|
30
|
+
# Suppresses a noisy error about missing credentials.
|
31
|
+
pass = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
pass
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Vcloud::Fog.check_credentials
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module Vcloud
|
4
|
+
module Fog
|
5
|
+
module Login
|
6
|
+
class << self
|
7
|
+
def token(pass)
|
8
|
+
check_plaintext_pass
|
9
|
+
token = get_token(pass)
|
10
|
+
|
11
|
+
return token
|
12
|
+
end
|
13
|
+
|
14
|
+
def token_export(*args)
|
15
|
+
return "export #{Vcloud::Fog::TOKEN_ENV_VAR_NAME}=#{token(*args)}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def check_plaintext_pass
|
21
|
+
pass = Vcloud::Fog::fog_credentials_pass
|
22
|
+
unless pass.nil? || pass.empty?
|
23
|
+
raise "Found plaintext #{Vcloud::Fog::FOG_CREDS_PASS_NAME} entry. Please set it to an empty string"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_token(pass)
|
28
|
+
ENV.delete(Vcloud::Fog::TOKEN_ENV_VAR_NAME)
|
29
|
+
vcloud = ::Fog::Compute::VcloudDirector.new({
|
30
|
+
Vcloud::Fog::FOG_CREDS_PASS_NAME => pass,
|
31
|
+
})
|
32
|
+
|
33
|
+
return vcloud.vcloud_token
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# These tests, which confirm that the Fog internals are performing a login
|
4
|
+
# and returning a new token, are not run automatically because they conflict
|
5
|
+
# with the use of vcloud-login in CI. Because we're using vcloud-login all
|
6
|
+
# of our tests should fail if the behaviour of Fog changes. However these
|
7
|
+
# may came in useful when debugging such a scenario.
|
8
|
+
|
9
|
+
describe Vcloud::Fog::Login do
|
10
|
+
let!(:mock_env) { ENV.clone }
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
stub_const('ENV', mock_env)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#token" do
|
17
|
+
context "fog credentials without password" do
|
18
|
+
let(:token_length) { 44 }
|
19
|
+
let(:env_var_name) { 'FOG_VCLOUD_TOKEN' }
|
20
|
+
let!(:mock_fog_creds) { ::Fog.credentials.clone }
|
21
|
+
|
22
|
+
before(:each) do
|
23
|
+
@real_password = mock_fog_creds.delete(:vcloud_director_password)
|
24
|
+
allow(::Fog).to receive(:credentials).and_return(mock_fog_creds)
|
25
|
+
end
|
26
|
+
|
27
|
+
context "environment variable VCLOUD_FOG_TOKEN not set" do
|
28
|
+
it "should login and return a token" do
|
29
|
+
mock_env.delete(env_var_name)
|
30
|
+
token = subject.token(@real_password)
|
31
|
+
expect(token.size).to eq(token_length)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "environment variable VCLOUD_FOG_TOKEN is set" do
|
36
|
+
let(:old_token) { 'mekmitasdigoat' }
|
37
|
+
|
38
|
+
it "should login and return a token, ignoring the existing token" do
|
39
|
+
mock_env[env_var_name] = old_token
|
40
|
+
new_token = subject.token(@real_password)
|
41
|
+
expect(new_token).to_not eq(old_token)
|
42
|
+
expect(new_token.size).to eq(token_length)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vcloud::Fog::Login do
|
4
|
+
let!(:mock_env) { ENV.clone }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
stub_const('ENV', mock_env)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#token" do
|
11
|
+
context "unable to load credentials" do
|
12
|
+
it "should raise an exception succinctly listing the missing credentials" do
|
13
|
+
mock_env.clear
|
14
|
+
::Fog.credential = 'null'
|
15
|
+
::Fog.credentials_path = '/dev/null'
|
16
|
+
|
17
|
+
# This test is known to fail with a TypeError due to a bug in Ruby 1.9.3 that
|
18
|
+
# has since been fixed. See https://github.com/gds-operations/vcloud-core/pull/100
|
19
|
+
expect { ::Fog.credentials['doesnotexist'] }.to raise_error(
|
20
|
+
Fog::Errors::LoadError,
|
21
|
+
/^Missing Credentials\n/
|
22
|
+
)
|
23
|
+
expect { subject.token(@real_password) }.to raise_error(
|
24
|
+
ArgumentError,
|
25
|
+
/^Missing required arguments: vcloud_director_.*$/
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class LoginCommandRun
|
4
|
+
attr_accessor :stdout, :stderr, :exitstatus
|
5
|
+
|
6
|
+
def initialize(args, stdin=nil)
|
7
|
+
out = StringIO.new
|
8
|
+
err = StringIO.new
|
9
|
+
|
10
|
+
if stdin
|
11
|
+
$stdin = StringIO.new
|
12
|
+
$stdin << stdin
|
13
|
+
$stdin.rewind
|
14
|
+
end
|
15
|
+
$stdout = out
|
16
|
+
$stderr = err
|
17
|
+
|
18
|
+
begin
|
19
|
+
Vcloud::Core::LoginCli.new(args).run
|
20
|
+
@exitstatus = 0
|
21
|
+
rescue SystemExit => e
|
22
|
+
# Capture exit(n) value.
|
23
|
+
@exitstatus = e.status
|
24
|
+
end
|
25
|
+
|
26
|
+
@stdout = out.string.strip
|
27
|
+
@stderr = err.string.strip
|
28
|
+
|
29
|
+
if stdin
|
30
|
+
$stdin = STDIN
|
31
|
+
end
|
32
|
+
$stdout = STDOUT
|
33
|
+
$stderr = STDERR
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe Vcloud::Core::LoginCli do
|
38
|
+
let(:stdin) { nil }
|
39
|
+
subject { LoginCommandRun.new(args, stdin) }
|
40
|
+
|
41
|
+
describe "normal usage" do
|
42
|
+
context "when given no arguments and a password on stdin" do
|
43
|
+
let(:args) { %w{} }
|
44
|
+
let(:pass) { 'supersekret' }
|
45
|
+
let(:stdin) { pass }
|
46
|
+
|
47
|
+
context "interactive tty" do
|
48
|
+
before(:each) do
|
49
|
+
expect(STDIN).to receive(:tty?).and_return(true)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should prompt on stderr so that stdout can be scripted and mask password input" do
|
53
|
+
expect(Vcloud::Fog::Login).to receive(:token_export).with(pass)
|
54
|
+
expect(subject.stderr).to eq("vCloud password: " + "*" * pass.size)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "non-interactive tty" do
|
59
|
+
before(:each) do
|
60
|
+
expect(STDIN).to receive(:tty?).and_return(false)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should write stderr message to say that it's reading from pipe and not echo any input" do
|
64
|
+
expect(Vcloud::Fog::Login).to receive(:token_export).with(pass)
|
65
|
+
expect(subject.stderr).to eq("Reading password from pipe..")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when asked to display version" do
|
71
|
+
let(:args) { %w{--version} }
|
72
|
+
|
73
|
+
it "should not call Login" do
|
74
|
+
expect(Vcloud::Fog::Login).not_to receive(:token_export)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should print version and exit normally" do
|
78
|
+
expect(subject.stdout).to eq(Vcloud::Core::VERSION)
|
79
|
+
expect(subject.exitstatus).to eq(0)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when asked to display help" do
|
84
|
+
let(:args) { %w{--help} }
|
85
|
+
|
86
|
+
it "should not call Login" do
|
87
|
+
expect(Vcloud::Fog::Login).not_to receive(:token_export)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should print usage and exit normally" do
|
91
|
+
expect(subject.stderr).to match(/\AUsage: \S+ \[options\]\n/)
|
92
|
+
expect(subject.exitstatus).to eq(0)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "incorrect usage" do
|
98
|
+
shared_examples "print usage and exit abnormally" do |error|
|
99
|
+
it "should not call Login" do
|
100
|
+
expect(Vcloud::Fog::Login).not_to receive(:token_export)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should print error message and usage" do
|
104
|
+
expect(subject.stderr).to match(/\A\S+: #{error}\nUsage: \S+/)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should exit abnormally for incorrect usage" do
|
108
|
+
expect(subject.exitstatus).to eq(2)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when given more than one argument" do
|
113
|
+
let(:args) { %w{an_extra_arg} }
|
114
|
+
|
115
|
+
it_behaves_like "print usage and exit abnormally", "too many arguments"
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when given an unrecognised argument" do
|
119
|
+
let(:args) { %w{--this-is-garbage} }
|
120
|
+
|
121
|
+
it_behaves_like "print usage and exit abnormally", "invalid option: --this-is-garbage"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "error handling" do
|
126
|
+
context "when underlying code raises an exception" do
|
127
|
+
let(:args) { %w{} }
|
128
|
+
# We have to pass a string here to prevent highline blowing up. This
|
129
|
+
# appears to be related to swapping out $stdin for StringIO and can't
|
130
|
+
# be reproduced by normal CLI use.
|
131
|
+
let(:pass) { 'some string' }
|
132
|
+
let(:stdin) { pass }
|
133
|
+
let(:exception_string) { 'something went horribly wrong' }
|
134
|
+
|
135
|
+
it "should print error without backtrace and exit abnormally" do
|
136
|
+
expect(Vcloud::Fog::Login).to receive(:token_export).
|
137
|
+
and_raise(exception_string)
|
138
|
+
if STDIN.tty?
|
139
|
+
expect(subject.stderr).to eq("vCloud password: #{'*' * pass.size}\n#{exception_string}")
|
140
|
+
else
|
141
|
+
expect(subject.stderr).to eq("Reading password from pipe..\n#{exception_string}")
|
142
|
+
end
|
143
|
+
expect(subject.exitstatus).to eq(1)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class QueryCommandRun
|
4
4
|
attr_accessor :stdout, :stderr, :exitstatus
|
5
5
|
|
6
6
|
def initialize(args)
|
@@ -27,7 +27,7 @@ class CommandRun
|
|
27
27
|
end
|
28
28
|
|
29
29
|
describe Vcloud::Core::QueryCli do
|
30
|
-
subject {
|
30
|
+
subject { QueryCommandRun.new(args) }
|
31
31
|
let(:mock_query) {
|
32
32
|
double(:query, :run => true)
|
33
33
|
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
describe Vcloud::Fog::Login do
|
5
|
+
describe "#token" do
|
6
|
+
it "should return the output from get_token" do
|
7
|
+
expect(subject).to receive(:check_plaintext_pass)
|
8
|
+
expect(subject).to receive(:get_token).and_return('mekmitasdigoat')
|
9
|
+
expect(subject.token('supersekret')).to eq("mekmitasdigoat")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#token_export" do
|
14
|
+
it "should call #token with pass arg and return shell export string" do
|
15
|
+
expect(subject).to receive(:token).with('supersekret').and_return('mekmitasdigoat')
|
16
|
+
expect(subject.token_export("supersekret")).to eq("export FOG_VCLOUD_TOKEN=mekmitasdigoat")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#check_plaintext_pass" do
|
21
|
+
context "vcloud_director_password not set" do
|
22
|
+
it "should not raise an exception" do
|
23
|
+
expect(Vcloud::Fog).to receive(:fog_credentials_pass).and_return(nil)
|
24
|
+
expect(subject).to receive(:get_token)
|
25
|
+
expect { subject.token('supersekret') }.not_to raise_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "vcloud_director_password empty string" do
|
30
|
+
it "should not raise an exception" do
|
31
|
+
expect(Vcloud::Fog).to receive(:fog_credentials_pass).and_return('')
|
32
|
+
expect(subject).to receive(:get_token)
|
33
|
+
expect { subject.token('supersekret') }.not_to raise_error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "vcloud_director_password non-empty string" do
|
38
|
+
it "should raise an exception" do
|
39
|
+
expect(Vcloud::Fog).to receive(:fog_credentials_pass).and_return('supersekret')
|
40
|
+
expect(subject).to_not receive(:get_token)
|
41
|
+
expect { subject.token('supersekret') }.to raise_error(
|
42
|
+
RuntimeError,
|
43
|
+
"Found plaintext vcloud_director_password entry. Please set it to an empty string"
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vcloud::Fog do
|
4
|
+
describe "fog_credentials_pass" do
|
5
|
+
let(:subject) { Vcloud::Fog::fog_credentials_pass }
|
6
|
+
|
7
|
+
context "vcloud_director_password not set" do
|
8
|
+
it "should return nil" do
|
9
|
+
expect(::Fog).to receive(:credentials).and_return({})
|
10
|
+
expect(subject).to eq(nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "vcloud_director_password set" do
|
15
|
+
it "should return string" do
|
16
|
+
expect(::Fog).to receive(:credentials).and_return({
|
17
|
+
:vcloud_director_password => 'supersekret',
|
18
|
+
})
|
19
|
+
expect(subject).to eq('supersekret')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "Fog LoadError" do
|
24
|
+
it "should suppress exception and return nil" do
|
25
|
+
expect(::Fog).to receive(:credentials).and_raise(::Fog::Errors::LoadError)
|
26
|
+
expect(subject).to eq(nil)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/vcloud-core.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
|
25
25
|
s.add_runtime_dependency 'fog', '>= 1.22.0'
|
26
26
|
s.add_runtime_dependency 'mustache'
|
27
|
+
s.add_runtime_dependency 'highline'
|
27
28
|
s.add_development_dependency 'gem_publisher', '1.2.0'
|
28
29
|
s.add_development_dependency 'pry'
|
29
30
|
s.add_development_dependency 'rake'
|
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.
|
4
|
+
version: 0.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-07-
|
12
|
+
date: 2014-07-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fog
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: highline
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: gem_publisher
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,6 +176,7 @@ description: Core tools for interacting with VMware vCloud Director. Includes VC
|
|
160
176
|
email:
|
161
177
|
- anna.shipman@digital.cabinet-office.gov.uk
|
162
178
|
executables:
|
179
|
+
- vcloud-login
|
163
180
|
- vcloud-query
|
164
181
|
extensions: []
|
165
182
|
extra_rdoc_files: []
|
@@ -172,9 +189,11 @@ files:
|
|
172
189
|
- LICENSE.txt
|
173
190
|
- README.md
|
174
191
|
- Rakefile
|
192
|
+
- bin/vcloud-login
|
175
193
|
- bin/vcloud-query
|
176
194
|
- jenkins.sh
|
177
195
|
- jenkins_integration_tests.sh
|
196
|
+
- jenkins_tests.sh
|
178
197
|
- lib/vcloud/core.rb
|
179
198
|
- lib/vcloud/core/compute_metadata.rb
|
180
199
|
- lib/vcloud/core/config_loader.rb
|
@@ -182,6 +201,7 @@ files:
|
|
182
201
|
- lib/vcloud/core/edge_gateway.rb
|
183
202
|
- lib/vcloud/core/edge_gateway_interface.rb
|
184
203
|
- lib/vcloud/core/entity.rb
|
204
|
+
- lib/vcloud/core/login_cli.rb
|
185
205
|
- lib/vcloud/core/metadata_helper.rb
|
186
206
|
- lib/vcloud/core/org_vdc_network.rb
|
187
207
|
- lib/vcloud/core/query.rb
|
@@ -194,6 +214,7 @@ files:
|
|
194
214
|
- lib/vcloud/core/vm.rb
|
195
215
|
- lib/vcloud/fog.rb
|
196
216
|
- lib/vcloud/fog/content_types.rb
|
217
|
+
- lib/vcloud/fog/login.rb
|
197
218
|
- lib/vcloud/fog/model_interface.rb
|
198
219
|
- lib/vcloud/fog/relation.rb
|
199
220
|
- lib/vcloud/fog/service_interface.rb
|
@@ -203,6 +224,8 @@ files:
|
|
203
224
|
- spec/integration/core/vapp_spec.rb
|
204
225
|
- spec/integration/core/vdc_spec.rb
|
205
226
|
- spec/integration/core/vm_spec.rb
|
227
|
+
- spec/integration/fog/login_manual.rb
|
228
|
+
- spec/integration/fog/login_spec.rb
|
206
229
|
- spec/integration/vcloud_tools_testing_config.yaml.template
|
207
230
|
- spec/spec_helper.rb
|
208
231
|
- spec/support/integration_helper.rb
|
@@ -219,6 +242,7 @@ files:
|
|
219
242
|
- spec/vcloud/core/data/working_with_defaults.yaml
|
220
243
|
- spec/vcloud/core/edge_gateway_interface_spec.rb
|
221
244
|
- spec/vcloud/core/edge_gateway_spec.rb
|
245
|
+
- spec/vcloud/core/login_cli_spec.rb
|
222
246
|
- spec/vcloud/core/metadata_helper_spec.rb
|
223
247
|
- spec/vcloud/core/org_vdc_network_spec.rb
|
224
248
|
- spec/vcloud/core/query_cli_spec.rb
|
@@ -229,8 +253,9 @@ files:
|
|
229
253
|
- spec/vcloud/core/vdc_spec.rb
|
230
254
|
- spec/vcloud/core/vm_spec.rb
|
231
255
|
- spec/vcloud/fog/fog_model_interface_spec.rb
|
256
|
+
- spec/vcloud/fog/login_spec.rb
|
232
257
|
- spec/vcloud/fog/service_interface_spec.rb
|
233
|
-
-
|
258
|
+
- spec/vcloud/fog_spec.rb
|
234
259
|
- vcloud-core.gemspec
|
235
260
|
homepage: http://github.com/gds-operations/vcloud-core
|
236
261
|
licenses:
|
@@ -253,7 +278,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
253
278
|
version: '0'
|
254
279
|
segments:
|
255
280
|
- 0
|
256
|
-
hash:
|
281
|
+
hash: 622735401989777949
|
257
282
|
requirements: []
|
258
283
|
rubyforge_project:
|
259
284
|
rubygems_version: 1.8.23
|
@@ -267,6 +292,8 @@ test_files:
|
|
267
292
|
- spec/integration/core/vapp_spec.rb
|
268
293
|
- spec/integration/core/vdc_spec.rb
|
269
294
|
- spec/integration/core/vm_spec.rb
|
295
|
+
- spec/integration/fog/login_manual.rb
|
296
|
+
- spec/integration/fog/login_spec.rb
|
270
297
|
- spec/integration/vcloud_tools_testing_config.yaml.template
|
271
298
|
- spec/spec_helper.rb
|
272
299
|
- spec/support/integration_helper.rb
|
@@ -283,6 +310,7 @@ test_files:
|
|
283
310
|
- spec/vcloud/core/data/working_with_defaults.yaml
|
284
311
|
- spec/vcloud/core/edge_gateway_interface_spec.rb
|
285
312
|
- spec/vcloud/core/edge_gateway_spec.rb
|
313
|
+
- spec/vcloud/core/login_cli_spec.rb
|
286
314
|
- spec/vcloud/core/metadata_helper_spec.rb
|
287
315
|
- spec/vcloud/core/org_vdc_network_spec.rb
|
288
316
|
- spec/vcloud/core/query_cli_spec.rb
|
@@ -293,4 +321,6 @@ test_files:
|
|
293
321
|
- spec/vcloud/core/vdc_spec.rb
|
294
322
|
- spec/vcloud/core/vm_spec.rb
|
295
323
|
- spec/vcloud/fog/fog_model_interface_spec.rb
|
324
|
+
- spec/vcloud/fog/login_spec.rb
|
296
325
|
- spec/vcloud/fog/service_interface_spec.rb
|
326
|
+
- spec/vcloud/fog_spec.rb
|
data/tools/fog_credentials.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# Initialiser for getting vCloud credentials into Fog from Jenkins build
|
2
|
-
# parameters, without needing to write them to disk. To be used with:
|
3
|
-
#
|
4
|
-
# RUBYOPT="-r ./tools/fog_credentials" bundle exec integration
|
5
|
-
#
|
6
|
-
# Replace with FOG_VCLOUD_TOKEN support when we have a tool:
|
7
|
-
#
|
8
|
-
# https://www.pivotaltracker.com/story/show/68989754
|
9
|
-
#
|
10
|
-
require 'bundler/setup'
|
11
|
-
require 'fog'
|
12
|
-
|
13
|
-
Fog.credentials = {
|
14
|
-
:vcloud_director_host => ENV['API_HOST'],
|
15
|
-
:vcloud_director_username => ENV['API_USERNAME'],
|
16
|
-
:vcloud_director_password => ENV['API_PASSWORD'],
|
17
|
-
}
|