Class: Opsicle::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/opsicle/config.rb

Constant Summary collapse

OPSICLE_CONFIG_PATH =
'./.opsicle'
SESSION_DURATION =
3600
MissingConfig =
Class.new(StandardError)
MissingEnvironment =
Class.new(StandardError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#environmentObject (readonly)

Returns the value of attribute environment.



9
10
11
# File 'lib/opsicle/config.rb', line 9

def environment
  @environment
end

Class Method Details

.instanceObject



11
12
13
# File 'lib/opsicle/config.rb', line 11

def self.instance
  @instance ||= new
end

Instance Method Details

#authenticate_with_credentialsObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/opsicle/config.rb', line 65

def authenticate_with_credentials
  profile_name = opsworks_config[:profile_name] || @environment.to_s
  begin
    credentials = Aws::SharedCredentials.new(profile_name: profile_name)
  rescue Aws::Errors::NoSuchProfileError
    if ENV['AWS_SESSION_TOKEN']
      Output.say('AWS profile not found; falling back to environment credentials', :debug)
    else
      raise Aws::Errors::NoSuchProfileError, "AWS profile #{profile_name} not found"
    end
  end
  region = opsworks_region

  if !credentials.nil? && !credentials.set?
    abort('Opsicle can no longer authenticate through your ~/.fog file. Please run `opsicle legacy-credential-converter` before proceeding.')
  end

  aws_opts = {region: region}
  aws_opts[:credentials] = credentials unless credentials.nil?
  Aws.config.update aws_opts

  iam = Aws::IAM::Client.new

  # 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;
  # if user doesn't have MFA enabled, then this loop won't even execute
  if mfa_required
    iam.list_mfa_devices.mfa_devices.each do |mfadevice|
      mfa_serial_number = mfadevice.serial_number
      get_mfa_token
      session_credentials_hash = get_session(mfa_serial_number,
                                             credentials.credentials.access_key_id,
                                             credentials.credentials.secret_access_key).credentials

      credentials = Aws::Credentials.new(session_credentials_hash.access_key_id,
                                                 session_credentials_hash.secret_access_key,
                                                 session_credentials_hash.session_token)
    end
  end

  return credentials
end

#aws_credentialsObject



15
16
17
# File 'lib/opsicle/config.rb', line 15

def aws_credentials
  authenticate_with_credentials
end

#configure_aws_environment!(environment) ⇒ Object



27
28
29
# File 'lib/opsicle/config.rb', line 27

def configure_aws_environment!(environment)
  @environment = environment.to_sym
end

#get_mfa_tokenObject



43
44
45
46
# File 'lib/opsicle/config.rb', line 43

def get_mfa_token
  return @token if @token
  @token = Output.ask("Enter MFA token: "){ |q|  q.validate = /^\d{6}$/ }
end

#get_session(mfa_serial_number, access_key_id, secret_access_key) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/opsicle/config.rb', line 107

def get_session(mfa_serial_number, access_key_id, secret_access_key)
  return @session if @session
  sts = Aws::STS::Client.new(access_key_id: access_key_id,
                             secret_access_key: secret_access_key,
                             region: 'us-east-1')
  @session = sts.get_session_token(duration_seconds: SESSION_DURATION,
                                   serial_number: mfa_serial_number,
                                   token_code: @token)
end

#load_config(file) ⇒ Object

Raises:



31
32
33
34
35
36
37
# File 'lib/opsicle/config.rb', line 31

def load_config(file)
  raise MissingConfig, "Missing configuration file: #{file}  Run 'opsicle help'" unless File.exist?(file)
  env_config = symbolize_keys(YAML.load_file(file))[environment] rescue {}
  raise MissingEnvironment, "Configuration for the \'#{environment}\' environment could not be found in #{file}" unless env_config != nil

  env_config
end

#mfa_requiredObject



39
40
41
# File 'lib/opsicle/config.rb', line 39

def mfa_required
  return opsworks_config[:mfa_required] || $use_mfa
end

#opsworks_configObject



19
20
21
# File 'lib/opsicle/config.rb', line 19

def opsworks_config
  @opsworks_config ||= load_config(OPSICLE_CONFIG_PATH)
end

#opsworks_regionObject



23
24
25
# File 'lib/opsicle/config.rb', line 23

def opsworks_region
  opsworks_config[:region] || "us-east-1"
end

#symbolize_keys(hash) ⇒ Object

We want all ouf our YAML loaded keys to be symbols taken from devblog.avdi.org/2009/07/14/recursively-symbolize-keys/



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/opsicle/config.rb', line 50

def symbolize_keys(hash)
  hash.inject({}){|result, (key, value)|
    new_key = case key
              when String then key.to_sym
              else key
              end
    new_value = case value
                when Hash then symbolize_keys(value)
                else value
                end
    result[new_key] = new_value
    result
  }
end