aws-ec2 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4c5bf33bed4b038a859606fca1faf595e8fca5455f3ae4e3c07f3c2329d7c3b
4
- data.tar.gz: f57b5c4305db3141a8f8dd1c540669ed2d666403df7d05af6a3ddb36f1d79280
3
+ metadata.gz: 9b159b7648562e89bf4552a9f42b81ebdda0fca33d979c7f5ae6a5ef38f29ca7
4
+ data.tar.gz: f3a261914d4442d75af1afd00f9ee7e1dd4e6bf2d155168ddc80b1fcbe2d8e61
5
5
  SHA512:
6
- metadata.gz: 0ab78f966ab1614ebe690b16f04d9e053803df832103542686d7697cc60af3e81ea341af447bb42c9fc181b599ac2cfdf268f665138441662a72d683e2da74bb
7
- data.tar.gz: 787504de7fb53ae1c7656a420cbede3ae3c44844d21315b488ebd9fe6e005b06256800a6fd03d219ecd28f7e4c50192b9faad59e5ae9be1c6bf99a06d347058f
6
+ metadata.gz: e6f2c2ccfe42c46ce64049ec6b04bb1bad648a252e6a7f071829cd4f8f52d97b4372a0c7889c6ead9726bc0d4b0f27acb9fc64bc8948e1f5f7c52ac2e3d63f8d
7
+ data.tar.gz: d82ba0ed306f5024fb262d018fd9fe7a76b8a25ff242cc1a5a4c78d4edf122eb3b444625c45d256eaaf84d1be17ddd6ac7885c8eb0297b8c7f0b5c7b13ce8572
data/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.4.0]
7
+ - aws-ec2 ami command
8
+ - create: add --source-ami options
9
+ - compile_scripts command
10
+ - custom helper support
11
+ - dotenv support
12
+ - hook support
13
+ - latest_ami helper
14
+ - partial support
15
+ - starter specs: spec for ami
16
+ - remove aws-ec2 spot command
17
+ - remove aws-ec2 userdata command, sanity rspec passing
18
+
6
19
  ## [0.3.0]
7
20
  - Do not merge profile to default profile. This was pretty confusing usage.
8
21
  - Add --ami option which result in automatically creating an ami at the end of
data/Gemfile.lock CHANGED
@@ -1,88 +1,120 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aws_ec2 (0.0.1)
4
+ aws-ec2 (0.3.0)
5
+ activesupport
6
+ aws-sdk-ec2
5
7
  colorize
8
+ dotenv
6
9
  hashie
7
10
  thor
8
11
 
9
12
  GEM
10
13
  remote: https://rubygems.org/
11
14
  specs:
12
- celluloid (0.16.0)
13
- timers (~> 4.0.0)
14
- codeclimate-test-reporter (0.4.4)
15
- simplecov (>= 0.7.1, < 1.0.0)
16
- coderay (1.1.0)
17
- colorize (0.7.5)
18
- diff-lcs (1.2.5)
15
+ activesupport (5.1.4)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (~> 0.7)
18
+ minitest (~> 5.1)
19
+ tzinfo (~> 1.1)
20
+ aws-partitions (1.57.0)
21
+ aws-sdk-core (3.14.0)
22
+ aws-partitions (~> 1.0)
23
+ aws-sigv4 (~> 1.0)
24
+ jmespath (~> 1.0)
25
+ aws-sdk-ec2 (1.25.0)
26
+ aws-sdk-core (~> 3)
27
+ aws-sigv4 (~> 1.0)
28
+ aws-sigv4 (1.0.2)
29
+ byebug (9.1.0)
30
+ codeclimate-test-reporter (1.0.8)
31
+ simplecov (<= 0.13)
32
+ coderay (1.1.2)
33
+ colorize (0.8.1)
34
+ concurrent-ruby (1.0.5)
35
+ diff-lcs (1.3)
19
36
  docile (1.1.5)
20
- ffi (1.9.6)
37
+ dotenv (2.2.1)
38
+ ffi (1.9.18)
21
39
  formatador (0.2.5)
22
- guard (2.10.5)
40
+ guard (2.14.2)
23
41
  formatador (>= 0.2.4)
24
- listen (~> 2.7)
25
- lumberjack (~> 1.0)
42
+ listen (>= 2.7, < 4.0)
43
+ lumberjack (>= 1.0.12, < 2.0)
26
44
  nenv (~> 0.1)
45
+ notiffany (~> 0.0)
27
46
  pry (>= 0.9.12)
47
+ shellany (~> 0.0)
28
48
  thor (>= 0.18.1)
29
49
  guard-bundler (2.1.0)
30
50
  bundler (~> 1.0)
31
51
  guard (~> 2.2)
32
52
  guard-compat (~> 1.1)
33
- guard-compat (1.2.0)
34
- guard-rspec (4.5.0)
53
+ guard-compat (1.2.1)
54
+ guard-rspec (4.7.3)
35
55
  guard (~> 2.1)
36
56
  guard-compat (~> 1.1)
37
57
  rspec (>= 2.99.0, < 4.0)
38
- hashie (3.3.2)
39
- hitimes (1.2.2)
40
- listen (2.8.4)
41
- celluloid (>= 0.15.2)
42
- rb-fsevent (>= 0.9.3)
43
- rb-inotify (>= 0.9)
44
- lumberjack (1.0.9)
45
- method_source (0.8.2)
46
- multi_json (1.10.1)
47
- nenv (0.1.1)
48
- pry (0.10.1)
58
+ hashie (3.5.7)
59
+ i18n (0.9.3)
60
+ concurrent-ruby (~> 1.0)
61
+ jmespath (1.3.1)
62
+ json (2.1.0)
63
+ listen (3.1.5)
64
+ rb-fsevent (~> 0.9, >= 0.9.4)
65
+ rb-inotify (~> 0.9, >= 0.9.7)
66
+ ruby_dep (~> 1.2)
67
+ lumberjack (1.0.12)
68
+ method_source (0.9.0)
69
+ minitest (5.11.3)
70
+ nenv (0.3.0)
71
+ notiffany (0.1.1)
72
+ nenv (~> 0.1)
73
+ shellany (~> 0.0)
74
+ pry (0.11.3)
49
75
  coderay (~> 1.1.0)
50
- method_source (~> 0.8.1)
51
- slop (~> 3.4)
52
- rake (10.4.2)
53
- rb-fsevent (0.9.4)
54
- rb-inotify (0.9.5)
55
- ffi (>= 0.5.0)
56
- rspec (3.1.0)
57
- rspec-core (~> 3.1.0)
58
- rspec-expectations (~> 3.1.0)
59
- rspec-mocks (~> 3.1.0)
60
- rspec-core (3.1.7)
61
- rspec-support (~> 3.1.0)
62
- rspec-expectations (3.1.2)
76
+ method_source (~> 0.9.0)
77
+ rake (12.3.0)
78
+ rb-fsevent (0.10.2)
79
+ rb-inotify (0.9.10)
80
+ ffi (>= 0.5.0, < 2)
81
+ rspec (3.7.0)
82
+ rspec-core (~> 3.7.0)
83
+ rspec-expectations (~> 3.7.0)
84
+ rspec-mocks (~> 3.7.0)
85
+ rspec-core (3.7.1)
86
+ rspec-support (~> 3.7.0)
87
+ rspec-expectations (3.7.0)
88
+ diff-lcs (>= 1.2.0, < 2.0)
89
+ rspec-support (~> 3.7.0)
90
+ rspec-mocks (3.7.0)
63
91
  diff-lcs (>= 1.2.0, < 2.0)
64
- rspec-support (~> 3.1.0)
65
- rspec-mocks (3.1.3)
66
- rspec-support (~> 3.1.0)
67
- rspec-support (3.1.2)
68
- simplecov (0.9.1)
92
+ rspec-support (~> 3.7.0)
93
+ rspec-support (3.7.0)
94
+ ruby_dep (1.5.0)
95
+ shellany (0.0.1)
96
+ simplecov (0.13.0)
69
97
  docile (~> 1.1.0)
70
- multi_json (~> 1.0)
71
- simplecov-html (~> 0.8.0)
72
- simplecov-html (0.8.0)
73
- slop (3.6.0)
74
- thor (0.19.1)
75
- timers (4.0.1)
76
- hitimes
98
+ json (>= 1.8, < 3)
99
+ simplecov-html (~> 0.10.0)
100
+ simplecov-html (0.10.2)
101
+ thor (0.20.0)
102
+ thread_safe (0.3.6)
103
+ tzinfo (1.2.4)
104
+ thread_safe (~> 0.1)
77
105
 
78
106
  PLATFORMS
79
107
  ruby
80
108
 
81
109
  DEPENDENCIES
82
- bundler (~> 1.3)
110
+ aws-ec2!
111
+ bundler
112
+ byebug
83
113
  codeclimate-test-reporter
84
114
  guard
85
115
  guard-bundler
86
116
  guard-rspec
87
117
  rake
88
- aws_ec2!
118
+
119
+ BUNDLED WITH
120
+ 1.16.1
data/README.md CHANGED
@@ -31,9 +31,9 @@ aws-ec2 create myserver
31
31
 
32
32
  ## User-Data
33
33
 
34
- You can provide user-data script to customize the server upon launch. The user-data scripts are under the profiles/user-data folder.
34
+ You can provide user-data script to customize the server upon launch. The user-data scripts are under the app/user-data folder.
35
35
 
36
- * profiles/user-data/myserver.yml
36
+ * app/user-data/myserver.yml
37
37
 
38
38
  The user-data script is generated on the machine that is running the aws-ec2 command. If this is your local macosx machine, then the context is your local macosx machine is available. To see the generated user-data script, you can use the `aws userdata NAME`. Example:
39
39
 
@@ -47,7 +47,7 @@ You can set a config file and define variables in there that are available to in
47
47
 
48
48
  ## Noop mode
49
49
 
50
- You can do a test run with the `--noop` flag. This will print out what settings will be used to launch the instance.
50
+ You can do a test run with the `--noop` flag. This will print out what settings will be used to launch the instance. This is a good way to inspect the generated user-data script.
51
51
 
52
52
  ```sh
53
53
  aws-ec2 create myserver --profile myserver --noop
@@ -65,7 +65,6 @@ Spot instance support natively supported by the AWS run_instances command. Simp
65
65
  ```sh
66
66
  aws-ec2 create help
67
67
  aws-ec2 userdata help
68
- aws-ec2 spot help
69
68
  aws-ec2 help # general help
70
69
  ```
71
70
 
data/aws-ec2.gemspec CHANGED
@@ -22,6 +22,9 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency "thor"
23
23
  spec.add_dependency "hashie"
24
24
  spec.add_dependency "colorize"
25
+ spec.add_dependency "dotenv"
26
+ spec.add_dependency "activesupport"
27
+ spec.add_dependency "aws-sdk-ec2"
25
28
 
26
29
  spec.add_development_dependency "bundler"
27
30
  spec.add_development_dependency "byebug"
data/lib/aws-ec2.rb CHANGED
@@ -7,14 +7,17 @@ module AwsEc2
7
7
  autoload :Command, "aws_ec2/command"
8
8
  autoload :CLI, "aws_ec2/cli"
9
9
  autoload :AwsServices, "aws_ec2/aws_services"
10
- autoload :Util, "aws_ec2/util"
11
10
  autoload :Create, "aws_ec2/create"
12
- autoload :Spot, "aws_ec2/spot"
13
- autoload :TemplateHelper, "aws_ec2/template_helper"
14
- autoload :UserData, "aws_ec2/user_data"
15
11
  autoload :Ami, "aws_ec2/ami"
12
+ autoload :TemplateHelper, "aws_ec2/template_helper"
13
+ autoload :Script, "aws_ec2/script"
16
14
  autoload :Config, "aws_ec2/config"
17
15
  autoload :Core, "aws_ec2/core"
16
+ autoload :Dotenv, "aws_ec2/dotenv"
17
+ autoload :Hook, "aws_ec2/hook"
18
+ autoload :CompileScripts, "aws_ec2/compile_scripts"
18
19
 
19
20
  extend Core
20
21
  end
22
+
23
+ AwsEc2::Dotenv.load!
data/lib/aws_ec2/ami.rb CHANGED
@@ -1,15 +1,14 @@
1
1
  module AwsEc2
2
2
  class Ami
3
- def initialize(ami_name)
4
- @ami_name = ami_name
3
+ def initialize(options)
4
+ @options = options.clone
5
5
  end
6
6
 
7
- def user_data_snippet
8
- region = `aws configure get region`.strip rescue 'us-east-1'
9
- # the shebang line is here in case there's currently an
10
- # empty user-data script. If there is not, then it wont hurt.
11
- template = IO.read(File.expand_path("../scripts/ami_creation.sh", __FILE__))
12
- ERB.new(template, nil, "-").result(binding)
7
+ def run
8
+ # Delegates to the Create command.
9
+ # So we just have to set up the option for it.
10
+ @options[:ami_name] = @options[:name]
11
+ Create.new(@options).run
13
12
  end
14
13
  end
15
14
  end
data/lib/aws_ec2/cli.rb CHANGED
@@ -5,23 +5,25 @@ module AwsEc2
5
5
  class_option :profile, desc: "profile name to use"
6
6
 
7
7
  desc "create NAME", "create ec2 instance"
8
- option :ami, desc: "ami name, if specified an ami will be created at the end of user data"
9
8
  long_desc Help.text(:create)
9
+ option :ami_name, desc: "when specified, an ami creation script is appended to the user-data script"
10
+ option :auto_terminate, type: :boolean, default: false, desc: "automatically terminate the instance at the end of user-data"
11
+ option :source_ami, desc: "override the source image_id in profile"
10
12
  def create(name)
11
13
  Create.new(options.merge(name: name)).run
12
14
  end
13
15
 
14
- desc "spot NAME", "create spot ec2 instance"
15
- long_desc Help.text(:spot)
16
- def spot(name)
17
- Spot.new(options.merge(name: name)).run
16
+ desc "ami NAME", "launches instance and uses it create AMI"
17
+ long_desc Help.text(:ami)
18
+ option :auto_terminate, type: :boolean, default: true, desc: "automatically terminate the instance at the end of user-data"
19
+ def ami(name)
20
+ Ami.new(options.merge(name: name)).run
18
21
  end
19
22
 
20
- desc "userdata NAME", "displays generated userdata script"
21
- option :ami, desc: "ami name, if specified an ami will be created at the end of user data"
22
- long_desc Help.text(:user_data)
23
- def userdata(name)
24
- UserData.new(options.merge(name: name)).run
23
+ desc "compile_scripts", "compiles app/scripts into tmp/app/scripts"
24
+ long_desc Help.text(:compile_scripts)
25
+ def compile_scripts
26
+ CompileScripts.new(options).compile
25
27
  end
26
28
  end
27
29
  end
@@ -1,5 +1,18 @@
1
1
  require "thor"
2
2
 
3
+ # Override thor's long_desc identation behavior
4
+ # https://github.com/erikhuda/thor/issues/398
5
+ class Thor
6
+ module Shell
7
+ class Basic
8
+ def print_wrapped(message, options = {})
9
+ message = "\n#{message}" unless message[0] == "\n"
10
+ stdout.puts message
11
+ end
12
+ end
13
+ end
14
+ end
15
+
3
16
  module AwsEc2
4
17
  class Command < Thor
5
18
  class << self
@@ -0,0 +1,30 @@
1
+ require 'fileutils'
2
+
3
+ module AwsEc2
4
+ class CompileScripts
5
+ include TemplateHelper
6
+ BUILD_ROOT = "tmp"
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def compile
13
+ puts "Compiling app/scripts to..."
14
+ clean
15
+ Dir.glob("#{AwsEc2.root}/app/scripts/**/*").each do |path|
16
+ next if File.directory?(path)
17
+ result = erb_result(path)
18
+ tmp_path = path.sub(%r{.*/app/}, "#{BUILD_ROOT}/app/")
19
+ puts " #{tmp_path}"
20
+ FileUtils.mkdir_p(File.dirname(tmp_path))
21
+ IO.write(tmp_path, result)
22
+ end
23
+ puts "Compiled app/scripts."
24
+ end
25
+
26
+ def clean
27
+ FileUtils.rm_rf(BUILD_ROOT)
28
+ end
29
+ end
30
+ end
data/lib/aws_ec2/core.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'pathname'
2
+
1
3
  module AwsEc2
2
4
  module Core
3
5
  @@config = nil
@@ -10,7 +12,8 @@ module AwsEc2
10
12
  end
11
13
 
12
14
  def root
13
- ENV['AWS_EC2_ROOT'] || '.'
15
+ path = ENV['AWS_EC2_ROOT'] || '.'
16
+ Pathname.new(path)
14
17
  end
15
18
  end
16
19
  end
@@ -3,8 +3,8 @@ require 'active_support/core_ext/hash'
3
3
 
4
4
  module AwsEc2
5
5
  class Create
6
+ autoload :Params, "aws_ec2/create/params"
6
7
  include AwsServices
7
- include Util
8
8
 
9
9
  def initialize(options)
10
10
  @options = options
@@ -18,6 +18,7 @@ module AwsEc2
18
18
  return
19
19
  end
20
20
 
21
+ Hook.run(:before_run_instances, @options)
21
22
  resp = ec2.run_instances(params)
22
23
  puts "EC2 instance #{@options[:name]} created! 🎉"
23
24
  puts "Visit https://console.aws.amazon.com/ec2/home to check on the status"
@@ -25,89 +26,7 @@ module AwsEc2
25
26
 
26
27
  # params are main derived from profile files
27
28
  def params
28
- params = load_profiles(profile_name)
29
- decorate_params(params)
30
- normalize_launch_template(params).deep_symbolize_keys
31
- end
32
-
33
- def decorate_params(params)
34
- upsert_name_tag(params)
35
- params
36
- end
37
-
38
- # Adds instance ec2 tag if not already provided
39
- def upsert_name_tag(params)
40
- specs = params["tag_specifications"] || []
41
-
42
- # insert an empty spec placeholder if one not found
43
- spec = specs.find do |s|
44
- s["resource_type"] == "instance"
45
- end
46
- unless spec
47
- spec = {
48
- "resource_type" => "instance",
49
- "tags" => []
50
- }
51
- specs << spec
52
- end
53
- # guaranteed there's a tag_specifications with resource_type instance at this point
54
-
55
- tags = spec["tags"] || []
56
-
57
- unless tags.map { |t| t["key"] }.include?("Name")
58
- tags << { "key" => "Name", "value" => @options[:name] }
59
- end
60
-
61
- specs = specs.map do |s|
62
- # replace the name tag value
63
- if s["resource_type"] == "instance"
64
- {
65
- "resource_type" => "instance",
66
- "tags" => tags
67
- }
68
- else
69
- s
70
- end
71
- end
72
-
73
- params["tag_specifications"] = specs
74
- params
75
- end
76
-
77
- # Allow adding launch template as a simple string.
78
- #
79
- # Standard structure:
80
- # {
81
- # launch_template: { launch_template_name: "TestLaunchTemplate" },
82
- # }
83
- #
84
- # Simple string:
85
- # {
86
- # launch_template: "TestLaunchTemplate",
87
- # }
88
- #
89
- # When launch_template is a simple String it will get transformed to the
90
- # standard structure.
91
- def normalize_launch_template(params)
92
- if params["launch_template"].is_a?(String)
93
- launch_template_identifier = params["launch_template"]
94
- launch_template = if launch_template_identifier =~ /^lt-/
95
- { "launch_template_id" => launch_template_identifier }
96
- else
97
- { "launch_template_name" => launch_template_identifier }
98
- end
99
- params["launch_template"] = launch_template
100
- end
101
- params
102
- end
103
-
104
- # Hard coded sensible defaults.
105
- # Can be overridden easily with profiles
106
- def defaults
107
- {
108
- max_count: 1,
109
- min_count: 1,
110
- }
29
+ @params ||= Params.new(@options).generate
111
30
  end
112
31
 
113
32
  def display_info
@@ -137,5 +56,16 @@ module AwsEc2
137
56
  puts "Please double check that it exists."
138
57
  exit
139
58
  end
59
+
60
+ def pretty_display(data)
61
+ data = data.deep_stringify_keys
62
+
63
+ if data["user_data"]
64
+ message = "base64-encoded: cat /tmp/aws-ec2/user-data.txt to view"
65
+ data["user_data"] = message
66
+ end
67
+
68
+ puts YAML.dump(data)
69
+ end
140
70
  end
141
71
  end