knife-ec2 0.18.2 → 0.19.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.expeditor/config.yml +13 -16
- data/.github/CODEOWNERS +4 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- data/.gitignore +0 -1
- data/.rspec +2 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +10 -17
- data/CHANGELOG.md +29 -7
- data/DOC_CHANGES.md +2 -12
- data/Gemfile +26 -2
- data/README.md +72 -75
- data/RELEASE_NOTES.md +10 -0
- data/Rakefile +25 -26
- data/VERSION +1 -1
- data/knife-ec2.gemspec +13 -20
- data/lib/chef/knife/ec2_ami_list.rb +31 -34
- data/lib/chef/knife/ec2_base.rb +137 -94
- data/lib/chef/knife/ec2_flavor_list.rb +12 -13
- data/lib/chef/knife/ec2_server_create.rb +440 -461
- data/lib/chef/knife/ec2_server_delete.rb +43 -41
- data/lib/chef/knife/ec2_server_list.rb +31 -28
- data/lib/chef/knife/s3_source.rb +22 -3
- data/lib/knife-ec2/version.rb +2 -2
- data/spec/spec_helper.rb +10 -11
- data/spec/unit/ec2_ami_list_spec.rb +297 -297
- data/spec/unit/ec2_flavor_list_spec.rb +18 -18
- data/spec/unit/ec2_server_create_spec.rb +952 -951
- data/spec/unit/ec2_server_delete_spec.rb +60 -61
- data/spec/unit/ec2_server_list_spec.rb +28 -28
- data/spec/unit/s3_source_deps_spec.rb +7 -7
- data/spec/unit/s3_source_spec.rb +17 -17
- metadata +26 -79
- data/CONTRIBUTING.md +0 -245
data/RELEASE_NOTES.md
CHANGED
@@ -7,6 +7,16 @@ Example Note:
|
|
7
7
|
Details about the thing that changed that needs to get included in the Release Notes in markdown.
|
8
8
|
-->
|
9
9
|
|
10
|
+
# knife-ec2 0.19.X release notes:
|
11
|
+
|
12
|
+
Support for Ruby 2.2 and Chef 12.X has been removed as both are now end of life. This gem now requires Ruby 2.3 (Chef 13) or later, which ships in all supported releases of Chef-DK.
|
13
|
+
|
14
|
+
The long ago deprecated `--distro` and `--template_file` flags for `knife ec2 server create` have been removed. These were no longer used by knife bootstrap so this should have zero impact on knife-ec2 users.
|
15
|
+
|
16
|
+
The fog-aws gem dependency has been loosened to allow fog-aws 1.0-3.X instead of just 1.X. This adds new instance types to `knife ec2 flavor list` and adds support for additional regions and availability zones previously not supported.
|
17
|
+
|
18
|
+
The credentials section fo the readme has been updated to recommend users use Amazon's credentials and configuration files instead of passing keys on the CLI or adding them to the knife.rb file. This is Amazon's recommended method of storing credentials and support for storing credentials in knife.rb may be removed in a future release in order to remove 3rd party credentials from Chef configuration files.
|
19
|
+
|
10
20
|
# knife-ec2 0.18.0 release notes:
|
11
21
|
In this release we have added separate features for tagging EC2 instances in AWS and Chef. Option `--aws-tag` is used for tagging the node in AWS and option `--chef-tag` is used for tagging the node in Chef. Subsequently the `--tag-node-in-chef` and `--tags` are now deprecated.
|
12
22
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# Author:: Adam Jacob (<adam@chef.io>)
|
3
3
|
# Author:: Daniel DeLeo (<dan@chef.io>)
|
4
4
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
5
|
-
# Copyright:: Copyright (c) 2008-
|
5
|
+
# Copyright:: Copyright (c) 2008-2018 Chef Software, Inc.
|
6
6
|
# License:: Apache License, Version 2.0
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -18,39 +18,38 @@
|
|
18
18
|
# limitations under the License.
|
19
19
|
#
|
20
20
|
|
21
|
-
require
|
21
|
+
require "bundler/gem_tasks"
|
22
|
+
require "rspec/core/rake_task"
|
23
|
+
|
24
|
+
task default: [:style, :spec]
|
25
|
+
|
22
26
|
Bundler::GemHelper.install_tasks
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
desc "Run specs"
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
30
|
+
spec.pattern = "spec/**/*_spec.rb"
|
31
|
+
end
|
27
32
|
|
28
33
|
begin
|
29
|
-
require
|
30
|
-
require
|
31
|
-
|
32
|
-
|
33
|
-
rdoc.title = 'Chef Ruby API Documentation'
|
34
|
-
rdoc.main = 'README.rdoc'
|
35
|
-
rdoc.options << '--fmt' << 'shtml' # explictly set shtml generator
|
36
|
-
rdoc.template = 'direct' # lighter template
|
37
|
-
rdoc.rdoc_files.include('README.rdoc', 'LICENSE', 'spec/tiny_server.rb', 'lib/**/*.rb')
|
38
|
-
rdoc.rdoc_dir = 'rdoc'
|
34
|
+
require "chefstyle"
|
35
|
+
require "rubocop/rake_task"
|
36
|
+
RuboCop::RakeTask.new(:style) do |task|
|
37
|
+
task.options += ["--display-cop-names", "--no-color"]
|
39
38
|
end
|
40
39
|
rescue LoadError
|
41
|
-
puts
|
40
|
+
puts "chefstyle/rubocop is not available. bundle install first to make sure all dependencies are installed."
|
42
41
|
end
|
43
42
|
|
44
43
|
begin
|
45
|
-
require
|
46
|
-
|
47
|
-
task :default => :spec
|
48
|
-
|
49
|
-
desc 'Run all specs in spec directory'
|
50
|
-
RSpec::Core::RakeTask.new(:spec) do |t|
|
51
|
-
t.pattern = 'spec/unit/**/*_spec.rb'
|
52
|
-
end
|
53
|
-
|
44
|
+
require "yard"
|
45
|
+
YARD::Rake::YardocTask.new(:docs)
|
54
46
|
rescue LoadError
|
55
|
-
|
47
|
+
puts "yard is not available. bundle install first to make sure all dependencies are installed."
|
48
|
+
end
|
49
|
+
|
50
|
+
task :console do
|
51
|
+
require "irb"
|
52
|
+
require "irb/completion"
|
53
|
+
ARGV.clear
|
54
|
+
IRB.start
|
56
55
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.19.10
|
data/knife-ec2.gemspec
CHANGED
@@ -1,30 +1,23 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
$LOAD_PATH.push File.expand_path(
|
3
|
-
require
|
2
|
+
$LOAD_PATH.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "knife-ec2/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
6
|
+
s.name = "knife-ec2"
|
7
7
|
s.version = Knife::Ec2::VERSION
|
8
|
-
s.authors = [
|
9
|
-
s.email = [
|
10
|
-
s.homepage =
|
11
|
-
s.summary = "EC2 Support for Chef's Knife Command"
|
8
|
+
s.authors = ["Adam Jacob", "Seth Chisamore"]
|
9
|
+
s.email = ["adam@chef.io", "schisamo@chef.io"]
|
10
|
+
s.homepage = "https://github.com/chef/knife-ec2"
|
11
|
+
s.summary = "Amazon EC2 Support for Chef's Knife Command"
|
12
12
|
s.description = s.summary
|
13
|
-
s.license =
|
13
|
+
s.license = "Apache-2.0"
|
14
14
|
|
15
15
|
s.files = `git ls-files`.split("\n")
|
16
|
-
s.test_files = `git ls-files
|
17
|
-
s.
|
18
|
-
s.required_ruby_version = ">= 2.2.2"
|
16
|
+
s.test_files = `git ls-files spec/*`.split("\n")
|
17
|
+
s.required_ruby_version = ">= 2.3"
|
19
18
|
|
20
|
-
s.add_dependency
|
21
|
-
s.add_dependency
|
22
|
-
s.add_dependency 'knife-windows', '~> 1.0'
|
19
|
+
s.add_dependency "fog-aws", ">= 1", "< 4"
|
20
|
+
s.add_dependency "knife-windows", "~> 1.0"
|
23
21
|
|
24
|
-
s.
|
25
|
-
s.add_development_dependency 'rspec', '~> 3.0'
|
26
|
-
s.add_development_dependency 'rake'
|
27
|
-
s.add_development_dependency 'sdoc', '~> 0.3'
|
28
|
-
|
29
|
-
s.require_paths = ['lib']
|
22
|
+
s.require_paths = ["lib"]
|
30
23
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Piyush Awasthi (<piyush.awasthi@msystechnologies.com>)
|
3
|
-
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
3
|
+
# Copyright:: Copyright (c) 2017-2018 Chef Software, Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -15,48 +15,45 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
|
18
|
-
|
19
18
|
require "chef/knife/ec2_base"
|
20
19
|
|
21
20
|
class Chef
|
22
21
|
class Knife
|
22
|
+
# == Overview
|
23
|
+
#
|
24
|
+
# This file provides the facility to display AMI list.
|
25
|
+
#
|
26
|
+
# == Owner
|
27
|
+
# By default owner is aws-marketplace but you can specify following owner with the help of -o or --owner
|
28
|
+
# * self => Displays the list of AMIs created by the user
|
29
|
+
# * aws-marketplace => Displays all AMIs form trusted vendors like Ubuntu, Microsoft, SAP, Zend as well as many open source offering
|
30
|
+
# * micosoft => Displays only Microsoft vendor AMIs
|
31
|
+
#
|
32
|
+
# == Platform
|
33
|
+
# By default all platform AMI's will display but you can filter your response
|
34
|
+
# by specify the platform using -p or --platform
|
35
|
+
# * Valid Platform => ubuntu, debian, centos, fedora, rhel, nginx, turnkey, jumpbox, coreos, cisco
|
36
|
+
#
|
37
|
+
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImages.html]
|
23
38
|
class Ec2AmiList < Knife
|
24
|
-
|
25
|
-
# == Overview
|
26
|
-
#
|
27
|
-
# This file provides the facility to display AMI list.
|
28
|
-
#
|
29
|
-
# == Owner
|
30
|
-
# By default owner is aws-marketplace but you can specify following owner with the help of -o or --owner
|
31
|
-
# * self => Displays the list of AMIs created by the user
|
32
|
-
# * aws-marketplace => Displays all AMIs form trusted vendors like Ubuntu, Microsoft, SAP, Zend as well as many open source offering
|
33
|
-
# * micosoft => Displays only Microsoft vendor AMIs
|
34
|
-
#
|
35
|
-
# == Platform
|
36
|
-
# By default all platform AMI's will display but you can filter your response
|
37
|
-
# by specify the platform using -p or --platform
|
38
|
-
# * Valid Platform => ubuntu, debian, centos, fedora, rhel, nginx, turnkey, jumpbox, coreos, cisco
|
39
|
-
#
|
40
|
-
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImages.html]
|
41
|
-
|
42
39
|
include Knife::Ec2Base
|
43
40
|
|
44
41
|
banner "knife ec2 ami list (options)"
|
45
42
|
|
46
43
|
option :platform,
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
44
|
+
short: "-p PLATFORM",
|
45
|
+
long: "--platform PLATFORM",
|
46
|
+
description: "Platform of the server. Allowed values are windows, ubuntu, debian, centos, fedora, rhel, nginx, turnkey, jumpbox, coreos, cisco, amazon, nessus"
|
50
47
|
|
51
48
|
option :owner,
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
49
|
+
short: "-o OWNER",
|
50
|
+
long: "--owner OWNER",
|
51
|
+
description: "The AMI owner (self, aws-marketplace, microsoft). Default is aws-marketplace"
|
55
52
|
|
56
53
|
option :search,
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
54
|
+
short: "-s SEARCH",
|
55
|
+
long: "--search SEARCH",
|
56
|
+
description: "Filter AMIs list as per search keywords."
|
60
57
|
|
61
58
|
def run
|
62
59
|
$stdout.sync = true
|
@@ -76,7 +73,7 @@ class Chef
|
|
76
73
|
output_column_count = server_list.length
|
77
74
|
begin
|
78
75
|
owner = locate_config_value(:owner) || "aws-marketplace"
|
79
|
-
servers = connection.describe_images({"Owner"=>"#{owner}"}) # aws-marketplace, microsoft
|
76
|
+
servers = connection.describe_images({ "Owner" => "#{owner}" }) # aws-marketplace, microsoft
|
80
77
|
rescue Exception => api_error
|
81
78
|
raise api_error
|
82
79
|
end
|
@@ -84,9 +81,9 @@ class Chef
|
|
84
81
|
servers.body["imagesSet"].each do |server|
|
85
82
|
server["platform"] = find_server_platform(server["name"]) unless server["platform"]
|
86
83
|
|
87
|
-
if
|
84
|
+
if locate_config_value(:platform) && locate_config_value(:search)
|
88
85
|
locate_config_value(:search).downcase!
|
89
|
-
if
|
86
|
+
if server["description"] && server["platform"] == locate_config_value(:platform) && server["description"].downcase.include?(locate_config_value(:search))
|
90
87
|
server_list += get_server_list(server)
|
91
88
|
end
|
92
89
|
elsif locate_config_value(:platform)
|
@@ -95,7 +92,7 @@ class Chef
|
|
95
92
|
end
|
96
93
|
elsif locate_config_value(:search)
|
97
94
|
locate_config_value(:search).downcase!
|
98
|
-
if
|
95
|
+
if server["description"] && server["description"].downcase.include?(locate_config_value(:search))
|
99
96
|
server_list += get_server_list(server)
|
100
97
|
end
|
101
98
|
else
|
@@ -105,7 +102,7 @@ class Chef
|
|
105
102
|
puts ui.list(server_list, :uneven_columns_across, output_column_count)
|
106
103
|
end
|
107
104
|
|
108
|
-
|
105
|
+
private
|
109
106
|
|
110
107
|
def get_server_list(server)
|
111
108
|
server_list = []
|
data/lib/chef/knife/ec2_base.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Seth Chisamore (<schisamo@chef.io>)
|
3
|
-
# Copyright:: Copyright (c) 2011-
|
3
|
+
# Copyright:: Copyright (c) 2011-2018 Chef Software, Inc.
|
4
4
|
# License:: Apache License, Version 2.0
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -16,75 +16,74 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require
|
19
|
+
require "chef/knife"
|
20
20
|
|
21
21
|
class Chef
|
22
22
|
class Knife
|
23
23
|
module Ec2Base
|
24
24
|
|
25
|
-
# :
|
26
|
-
# Would prefer to do this in a rational way, but can't be done b/c of
|
27
|
-
# Mixlib::CLI's design :(
|
25
|
+
# @todo Would prefer to do this in a rational way, but can't be done b/c of Mixlib::CLI's design :(
|
28
26
|
def self.included(includer)
|
29
27
|
includer.class_eval do
|
30
28
|
|
31
29
|
deps do
|
32
|
-
require
|
33
|
-
require
|
34
|
-
require
|
30
|
+
require "fog/aws"
|
31
|
+
require "chef/json_compat"
|
32
|
+
require "chef/util/path_helper"
|
35
33
|
end
|
36
34
|
|
37
35
|
option :aws_credential_file,
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
36
|
+
long: "--aws-credential-file FILE",
|
37
|
+
description: "File containing AWS credentials as used by the AWS Command Line Interface.",
|
38
|
+
proc: Proc.new { |key| Chef::Config[:knife][:aws_credential_file] = key }
|
41
39
|
|
42
40
|
option :aws_config_file,
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
41
|
+
long: "--aws-config-file FILE",
|
42
|
+
description: "File containing AWS configurations as used by the AWS Command Line Interface.",
|
43
|
+
proc: Proc.new { |key| Chef::Config[:knife][:aws_config_file] = key }
|
46
44
|
|
47
45
|
option :aws_profile,
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
46
|
+
long: "--aws-profile PROFILE",
|
47
|
+
description: "AWS profile, from AWS credential file and AWS config file, to use",
|
48
|
+
default: "default",
|
49
|
+
proc: Proc.new { |key| Chef::Config[:knife][:aws_profile] = key }
|
52
50
|
|
53
51
|
option :aws_access_key_id,
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
52
|
+
short: "-A ID",
|
53
|
+
long: "--aws-access-key-id KEY",
|
54
|
+
description: "Your AWS Access Key ID",
|
55
|
+
proc: Proc.new { |key| Chef::Config[:knife][:aws_access_key_id] = key }
|
58
56
|
|
59
57
|
option :aws_secret_access_key,
|
60
|
-
:
|
61
|
-
:
|
62
|
-
:
|
63
|
-
:
|
58
|
+
short: "-K SECRET",
|
59
|
+
long: "--aws-secret-access-key SECRET",
|
60
|
+
description: "Your AWS API Secret Access Key",
|
61
|
+
proc: Proc.new { |key| Chef::Config[:knife][:aws_secret_access_key] = key }
|
64
62
|
|
65
63
|
option :aws_session_token,
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
64
|
+
long: "--aws-session-token TOKEN",
|
65
|
+
description: "Your AWS Session Token, for use with AWS STS Federation or Session Tokens",
|
66
|
+
proc: Proc.new { |key| Chef::Config[:knife][:aws_session_token] = key }
|
69
67
|
|
70
68
|
option :region,
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
69
|
+
long: "--region REGION",
|
70
|
+
description: "Your AWS region",
|
71
|
+
proc: Proc.new { |key| Chef::Config[:knife][:region] = key }
|
74
72
|
|
75
73
|
option :use_iam_profile,
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
79
|
-
:
|
80
|
-
:
|
74
|
+
long: "--use-iam-profile",
|
75
|
+
description: "Use IAM profile assigned to current machine",
|
76
|
+
boolean: true,
|
77
|
+
default: false,
|
78
|
+
proc: Proc.new { |key| Chef::Config[:knife][:use_iam_profile] = key }
|
81
79
|
end
|
82
80
|
end
|
83
81
|
|
82
|
+
# @return [Fog::Compute]
|
84
83
|
def connection
|
85
84
|
connection_settings = {
|
86
|
-
:
|
87
|
-
:
|
85
|
+
provider: "AWS",
|
86
|
+
region: locate_config_value(:region),
|
88
87
|
}
|
89
88
|
|
90
89
|
if locate_config_value(:use_iam_profile)
|
@@ -99,81 +98,54 @@ class Chef
|
|
99
98
|
end
|
100
99
|
end
|
101
100
|
|
101
|
+
# @return [String]
|
102
102
|
def locate_config_value(key)
|
103
103
|
key = key.to_sym
|
104
104
|
config[key] || Chef::Config[:knife][key]
|
105
105
|
end
|
106
106
|
|
107
|
-
def msg_pair(label, value, color
|
107
|
+
def msg_pair(label, value, color = :cyan)
|
108
108
|
if value && !value.to_s.empty?
|
109
109
|
ui.info("#{ui.color(label, color)}: #{value}")
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
+
# @return [Boolean]
|
113
114
|
def is_image_windows?
|
114
115
|
image_info = connection.images.get(@server.image_id)
|
115
|
-
|
116
|
+
image_info.platform == "windows"
|
116
117
|
end
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
else
|
133
|
-
raise ArgumentError, "The provided --aws-profile '#{profile}' is invalid."
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
119
|
+
# validate the config options that were passed since some of them cannot be used together
|
120
|
+
# also validate the aws configuration file contents if present
|
121
|
+
def validate!(keys = [:aws_access_key_id, :aws_secret_access_key])
|
122
|
+
errors = [] # track all errors so we report on all of them
|
123
|
+
|
124
|
+
validate_aws_config_file! if locate_config_value(:aws_config_file)
|
125
|
+
|
126
|
+
unless locate_config_value(:use_iam_profile) # skip config file / key validation if we're using iam profile
|
127
|
+
# validate the creds file if:
|
128
|
+
# aws keys have not been passed in config / CLI and the default cred file location does exist
|
129
|
+
# OR
|
130
|
+
# the user passed aws_credential_file
|
131
|
+
if (Chef::Config[:knife].keys & [:aws_access_key_id, :aws_secret_access_key]).empty? && aws_cred_file_location ||
|
132
|
+
locate_config_value(:aws_credential_file)
|
137
133
|
|
138
|
-
unless locate_config_value(:use_iam_profile)
|
139
|
-
if locate_config_value(:aws_credential_file)
|
140
134
|
unless (Chef::Config[:knife].keys & [:aws_access_key_id, :aws_secret_access_key]).empty?
|
141
135
|
errors << "Either provide a credentials file or the access key and secret keys but not both."
|
142
136
|
end
|
143
|
-
|
144
|
-
|
145
|
-
# AWSSecretKey=somethingsomethingcomplete
|
146
|
-
# OR
|
147
|
-
# [default]
|
148
|
-
# aws_access_key_id = somethingsomethingdarkside
|
149
|
-
# aws_secret_access_key = somethingsomethingdarkside
|
150
|
-
|
151
|
-
aws_creds = ini_parse(File.read(locate_config_value(:aws_credential_file)))
|
152
|
-
profile = locate_config_value(:aws_profile)
|
153
|
-
|
154
|
-
entries = if aws_creds.values.first.has_key?("AWSAccessKeyId")
|
155
|
-
aws_creds.values.first
|
156
|
-
else
|
157
|
-
aws_creds[profile]
|
158
|
-
end
|
159
|
-
|
160
|
-
if entries
|
161
|
-
Chef::Config[:knife][:aws_access_key_id] = entries['AWSAccessKeyId'] || entries['aws_access_key_id']
|
162
|
-
Chef::Config[:knife][:aws_secret_access_key] = entries['AWSSecretKey'] || entries['aws_secret_access_key']
|
163
|
-
Chef::Config[:knife][:aws_session_token] = entries['AWSSessionToken'] || entries['aws_session_token']
|
164
|
-
else
|
165
|
-
raise ArgumentError, "The provided --aws-profile '#{profile}' is invalid."
|
166
|
-
end
|
137
|
+
|
138
|
+
validate_aws_credential_file!
|
167
139
|
end
|
168
140
|
|
169
141
|
keys.each do |k|
|
170
|
-
pretty_key = k.to_s.
|
142
|
+
pretty_key = k.to_s.tr("_", " ").gsub(/\w+/) { |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize }
|
171
143
|
if Chef::Config[:knife][k].nil?
|
172
144
|
errors << "You did not provide a valid '#{pretty_key}' value."
|
173
145
|
end
|
174
146
|
end
|
175
147
|
|
176
|
-
if errors.each{|e| ui.error(e)}.any?
|
148
|
+
if errors.each { |e| ui.error(e) }.any?
|
177
149
|
exit 1
|
178
150
|
end
|
179
151
|
end
|
@@ -193,12 +165,27 @@ class Chef
|
|
193
165
|
|
194
166
|
end
|
195
167
|
|
168
|
+
# the path to the aws credentials file.
|
169
|
+
# if passed via cli config use that
|
170
|
+
# if default location exists on disk fallback to that
|
171
|
+
# @return [String, nil] location to aws credentials file or nil if none exists
|
172
|
+
def aws_cred_file_location
|
173
|
+
@cred_file ||= begin
|
174
|
+
if !locate_config_value(:aws_credential_file).nil?
|
175
|
+
locate_config_value(:aws_credential_file)
|
176
|
+
else
|
177
|
+
Chef::Util::PathHelper.home(".aws", "credentials") if ::File.exist?(Chef::Util::PathHelper.home(".aws", "credentials"))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [String]
|
196
183
|
def iam_name_from_profile(profile)
|
197
184
|
# The IAM profile object only contains the name as part of the arn
|
198
|
-
if profile && profile.key?(
|
199
|
-
name = profile[
|
185
|
+
if profile && profile.key?("arn")
|
186
|
+
name = profile["arn"].split("/")[-1]
|
200
187
|
end
|
201
|
-
name ||=
|
188
|
+
name ||= ""
|
202
189
|
end
|
203
190
|
|
204
191
|
def ini_parse(file)
|
@@ -221,22 +208,78 @@ class Chef
|
|
221
208
|
end
|
222
209
|
|
223
210
|
# All valid platforms
|
211
|
+
# @return [Array]
|
224
212
|
def valid_platforms
|
225
|
-
|
213
|
+
%w{windows ubuntu debian centos fedora rhel nginx turnkey jumpbox coreos cisco amazon nessus}
|
226
214
|
end
|
227
215
|
|
228
216
|
# Get the platform from server name
|
217
|
+
# @return [String]
|
229
218
|
def find_server_platform(server_name)
|
230
219
|
get_platform = valid_platforms.select { |name| server_name.downcase.include?(name) }
|
231
|
-
|
220
|
+
get_platform.first
|
232
221
|
end
|
233
222
|
|
234
|
-
|
235
223
|
# Custom Warning
|
236
224
|
def custom_warnings!
|
237
225
|
if !config[:region] && Chef::Config[:knife][:region].nil?
|
238
226
|
ui.warn "No region was specified in knife.rb or as an argument. The default region, us-east-1, will be used:"
|
239
227
|
end
|
240
228
|
end
|
229
|
+
|
230
|
+
private
|
231
|
+
|
232
|
+
# validate the contents of the aws configuration file
|
233
|
+
# @return [void]
|
234
|
+
def validate_aws_config_file!
|
235
|
+
config_file = locate_config_value(:aws_config_file)
|
236
|
+
raise ArgumentError, "The provided --aws_config_file (#{config_file}) cannot be found on disk." unless File.exist?(config_file)
|
237
|
+
|
238
|
+
aws_config = ini_parse(File.read(config_file))
|
239
|
+
profile = if locate_config_value(:aws_profile) == "default"
|
240
|
+
"default"
|
241
|
+
else
|
242
|
+
"profile #{locate_config_value(:aws_profile)}"
|
243
|
+
end
|
244
|
+
|
245
|
+
unless aws_config.values.empty?
|
246
|
+
if aws_config[profile]
|
247
|
+
Chef::Config[:knife][:region] = aws_config[profile]["region"]
|
248
|
+
else
|
249
|
+
raise ArgumentError, "The provided --aws-profile '#{profile}' is invalid."
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# validate the contents of the aws credentials file
|
255
|
+
# @return [void]
|
256
|
+
def validate_aws_credential_file!
|
257
|
+
raise ArgumentError, "The provided --aws_credential_file (#{aws_cred_file_location}) cannot be found on disk." unless File.exist?(aws_cred_file_location)
|
258
|
+
|
259
|
+
# File format:
|
260
|
+
# AWSAccessKeyId=somethingsomethingdarkside
|
261
|
+
# AWSSecretKey=somethingsomethingcomplete
|
262
|
+
# OR
|
263
|
+
# [default]
|
264
|
+
# aws_access_key_id = somethingsomethingdarkside
|
265
|
+
# aws_secret_access_key = somethingsomethingdarkside
|
266
|
+
|
267
|
+
aws_creds = ini_parse(File.read(aws_cred_file_location))
|
268
|
+
profile = locate_config_value(:aws_profile)
|
269
|
+
|
270
|
+
entries = if aws_creds.values.first.key?("AWSAccessKeyId")
|
271
|
+
aws_creds.values.first
|
272
|
+
else
|
273
|
+
aws_creds[profile]
|
274
|
+
end
|
275
|
+
|
276
|
+
if entries
|
277
|
+
Chef::Config[:knife][:aws_access_key_id] = entries["AWSAccessKeyId"] || entries["aws_access_key_id"]
|
278
|
+
Chef::Config[:knife][:aws_secret_access_key] = entries["AWSSecretKey"] || entries["aws_secret_access_key"]
|
279
|
+
Chef::Config[:knife][:aws_session_token] = entries["AWSSessionToken"] || entries["aws_session_token"]
|
280
|
+
else
|
281
|
+
raise ArgumentError, "The provided --aws-profile '#{profile}' is invalid."
|
282
|
+
end
|
283
|
+
end
|
241
284
|
end
|
242
285
|
end
|