opsicle 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/opsicle/client.rb +3 -2
- data/lib/opsicle/config.rb +40 -33
- data/lib/opsicle/version.rb +1 -1
- data/spec/opsicle/config_spec.rb +11 -31
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 022fdb3799154ce60b7e5b84cd83142ca8644024
|
4
|
+
data.tar.gz: a12d87d36f1ad4e317cd96fd5cc03e990652ee27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaeab2fa154ddd9099e45a229f4e83f9f1335f3c2ee77fa30a9d53f9f50b8a2e83f05354acba47c95d225e55b86c36fbe6484d1d69187af4ddedf7fef8cee805
|
7
|
+
data.tar.gz: da9e1b62d77b28b76733000234a8193ed788ed2e7060e5d17796c9c81223c32dc00b37af5c262daacc49b36006da54ed27337fedc51cbe8f1d5dbdac9091cceb
|
data/lib/opsicle/client.rb
CHANGED
@@ -9,8 +9,9 @@ module Opsicle
|
|
9
9
|
def initialize(environment)
|
10
10
|
@config = Config.instance
|
11
11
|
@config.configure_aws_environment!(environment)
|
12
|
-
|
13
|
-
@
|
12
|
+
credentials = @config.aws_credentials
|
13
|
+
@opsworks = Aws::OpsWorks::Client.new(region: 'us-east-1', credentials: credentials)
|
14
|
+
@s3 = Aws::S3::Client.new(region: 'us-east-1', credentials: credentials)
|
14
15
|
end
|
15
16
|
|
16
17
|
def run_command(command, command_args={}, options={})
|
data/lib/opsicle/config.rb
CHANGED
@@ -3,7 +3,6 @@ require 'aws-sdk'
|
|
3
3
|
|
4
4
|
module Opsicle
|
5
5
|
class Config
|
6
|
-
FOG_CONFIG_PATH = '~/.fog'
|
7
6
|
OPSICLE_CONFIG_PATH = './.opsicle'
|
8
7
|
SESSION_DURATION = 3600
|
9
8
|
|
@@ -14,22 +13,7 @@ module Opsicle
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def aws_credentials
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def aws_config
|
21
|
-
return @aws_config if @aws_config
|
22
|
-
if fog_config[:mfa_serial_number]
|
23
|
-
creds = get_session.credentials
|
24
|
-
@aws_config = { access_key_id: creds.access_key_id, secret_access_key: creds.secret_access_key, session_token: creds.session_token }
|
25
|
-
else
|
26
|
-
@aws_config = { access_key_id: fog_config[:aws_access_key_id], secret_access_key: fog_config[:aws_secret_access_key] }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def fog_config
|
31
|
-
return @fog_config if @fog_config
|
32
|
-
@fog_config = load_config(File.expand_path(FOG_CONFIG_PATH))
|
16
|
+
authenticate_with_credentials
|
33
17
|
end
|
34
18
|
|
35
19
|
def opsworks_config
|
@@ -38,7 +22,7 @@ module Opsicle
|
|
38
22
|
|
39
23
|
def configure_aws_environment!(environment)
|
40
24
|
@environment = environment.to_sym
|
41
|
-
|
25
|
+
end
|
42
26
|
|
43
27
|
def load_config(file)
|
44
28
|
raise MissingConfig, "Missing configuration file: #{file} Run 'opsicle help'" unless File.exist?(file)
|
@@ -53,21 +37,6 @@ module Opsicle
|
|
53
37
|
@token = Output.ask("Enter MFA token: "){ |q| q.validate = /^\d{6}$/ }
|
54
38
|
end
|
55
39
|
|
56
|
-
def get_session
|
57
|
-
return @session if @session
|
58
|
-
sts = Aws::STS::Client.new(access_key_id: fog_config[:aws_access_key_id],
|
59
|
-
secret_access_key: fog_config[:aws_secret_access_key],
|
60
|
-
region: 'us-east-1')
|
61
|
-
@session = sts.get_session_token(duration_seconds: session_duration,
|
62
|
-
serial_number: fog_config[:mfa_serial_number],
|
63
|
-
token_code: get_mfa_token)
|
64
|
-
end
|
65
|
-
|
66
|
-
def session_duration
|
67
|
-
fog_config = load_config(File.expand_path(FOG_CONFIG_PATH))
|
68
|
-
fog_config[:session_duration] || SESSION_DURATION
|
69
|
-
end
|
70
|
-
|
71
40
|
# We want all ouf our YAML loaded keys to be symbols
|
72
41
|
# taken from http://devblog.avdi.org/2009/07/14/recursively-symbolize-keys/
|
73
42
|
def symbolize_keys(hash)
|
@@ -85,6 +54,44 @@ module Opsicle
|
|
85
54
|
}
|
86
55
|
end
|
87
56
|
|
57
|
+
def authenticate_with_credentials
|
58
|
+
credentials = Aws::SharedCredentials.new(profile_name: @environment.to_s)
|
59
|
+
|
60
|
+
unless credentials.set?
|
61
|
+
abort('Opsicle can no longer authenticate through your ~/.fog file. Please run `opsicle legacy-credential-converter` before proceeding.')
|
62
|
+
end
|
63
|
+
|
64
|
+
Aws.config.update({region: 'us-east-1', credentials: credentials})
|
65
|
+
|
66
|
+
iam = Aws::IAM::Client.new
|
67
|
+
|
68
|
+
# this will be an array of 0 or 1 because iam.list_mfa_devices.mfa_devices will only return 0 or 1 device per user;
|
69
|
+
# if user doesn't have MFA enabled, then this loop won't even execute
|
70
|
+
iam.list_mfa_devices.mfa_devices.each do |mfadevice|
|
71
|
+
mfa_serial_number = mfadevice.serial_number
|
72
|
+
get_mfa_token
|
73
|
+
session_credentials_hash = get_session(mfa_serial_number,
|
74
|
+
credentials.credentials.access_key_id,
|
75
|
+
credentials.credentials.secret_access_key).credentials
|
76
|
+
|
77
|
+
credentials = Aws::Credentials.new(session_credentials_hash.access_key_id,
|
78
|
+
session_credentials_hash.secret_access_key,
|
79
|
+
session_credentials_hash.session_token)
|
80
|
+
end
|
81
|
+
|
82
|
+
return credentials
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_session(mfa_serial_number, access_key_id, secret_access_key)
|
86
|
+
return @session if @session
|
87
|
+
sts = Aws::STS::Client.new(access_key_id: access_key_id,
|
88
|
+
secret_access_key: secret_access_key,
|
89
|
+
region: 'us-east-1')
|
90
|
+
@session = sts.get_session_token(duration_seconds: SESSION_DURATION,
|
91
|
+
serial_number: mfa_serial_number,
|
92
|
+
token_code: @token)
|
93
|
+
end
|
94
|
+
|
88
95
|
MissingConfig = Class.new(StandardError)
|
89
96
|
MissingEnvironment = Class.new(StandardError)
|
90
97
|
|
data/lib/opsicle/version.rb
CHANGED
data/spec/opsicle/config_spec.rb
CHANGED
@@ -6,27 +6,15 @@ module Opsicle
|
|
6
6
|
subject { Config.new }
|
7
7
|
context "with a valid config" do
|
8
8
|
before do
|
9
|
-
allow(File).to receive(:exist?).with(File.expand_path '~/.
|
9
|
+
allow(File).to receive(:exist?).with(File.expand_path '~/.aws/credentials').and_return(true)
|
10
10
|
allow(File).to receive(:exist?).with('./.opsicle').and_return(true)
|
11
|
-
allow(
|
12
|
-
allow(YAML).to receive(:load_file).with('./.opsicle').and_return({'derp' => { 'app_id' => 'app', 'stack_id' => 'stack'}})
|
11
|
+
allow(File).to receive(:exist?).and_return(true)
|
12
|
+
allow(YAML).to receive(:load_file).with('./.opsicle').and_return({'derp' => { 'app_id' => 'app', 'stack_id' => 'stack' }})
|
13
13
|
end
|
14
14
|
before :each do
|
15
15
|
subject.configure_aws_environment!('derp')
|
16
16
|
end
|
17
17
|
|
18
|
-
context "#aws_config" do
|
19
|
-
it "should contain access_key_id" do
|
20
|
-
expect(subject.aws_config).to have_key(:access_key_id)
|
21
|
-
expect(subject.aws_config).to eq({ :access_key_id => 'key', :secret_access_key => 'secret'})
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should contain secret_access_key" do
|
25
|
-
expect(subject.aws_config).to have_key(:secret_access_key)
|
26
|
-
expect(subject.aws_config).to eq({ :access_key_id => 'key', :secret_access_key => 'secret'})
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
18
|
context "#opsworks_config" do
|
31
19
|
it "should contain stack_id" do
|
32
20
|
expect(subject.opsworks_config).to have_key(:stack_id)
|
@@ -39,9 +27,14 @@ module Opsicle
|
|
39
27
|
|
40
28
|
context "#aws_credentials" do
|
41
29
|
it "should return aws credentials" do
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
mfa_devices = double('mfa_devices', mfa_devices: [])
|
31
|
+
client = double('iam_client', list_mfa_devices: mfa_devices)
|
32
|
+
allow(Aws::IAM::Client).to receive(:new).and_return(client)
|
33
|
+
coffee_types = {:coffee => "cappuccino", :beans => "arabica"}
|
34
|
+
allow(coffee_types).to receive('set?').and_return(true)
|
35
|
+
allow(Aws.config).to receive(:update).with({region: 'us-east-1', credentials: coffee_types})
|
36
|
+
allow(Aws::SharedCredentials).to receive(:new).and_return(coffee_types)
|
37
|
+
expect(subject.aws_credentials).to eq(coffee_types)
|
45
38
|
end
|
46
39
|
end
|
47
40
|
|
@@ -54,22 +47,9 @@ module Opsicle
|
|
54
47
|
|
55
48
|
context "missing configs" do
|
56
49
|
before do
|
57
|
-
allow(File).to receive(:exist?).with(File.expand_path '~/.fog').and_return(false)
|
58
50
|
allow(File).to receive(:exist?).with('./.opsicle').and_return(false)
|
59
51
|
end
|
60
52
|
|
61
|
-
context "#aws_config" do
|
62
|
-
it "should gracefully raise an exception if no .fog file was found" do
|
63
|
-
expect {subject.aws_config}.to raise_exception(Config::MissingConfig)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context "#fog_config" do
|
68
|
-
it "should gracefully raise an exception if no .fog file was found" do
|
69
|
-
expect {subject.aws_config}.to raise_exception(Config::MissingConfig)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
53
|
context "#opsworks_config" do
|
74
54
|
it "should gracefully raise an exception if no .fog file was found" do
|
75
55
|
expect {subject.opsworks_config}.to raise_exception(Config::MissingConfig)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opsicle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Fleener
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-07-
|
12
|
+
date: 2016-07-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|