ebfly 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/README.md +173 -0
- data/Rakefile +11 -0
- data/bin/ebfly +17 -0
- data/ebfly.gemspec +23 -0
- data/lib/ebfly/cli.rb +26 -0
- data/lib/ebfly/command/app.rb +86 -0
- data/lib/ebfly/command/config.rb +99 -0
- data/lib/ebfly/command/env.rb +184 -0
- data/lib/ebfly/ebfly.rb +75 -0
- data/lib/ebfly/version.rb +3 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: caddbe101734e059c894728ac1198a1705df2cbe
|
4
|
+
data.tar.gz: 1c2946180f78e71d7539f4730fafacbc191904ac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 359ca0f932e298ba91d7ff51580d1055b4107279882ca6369d04b0455d99dfcef134fea4e6b3cb04ed5263a7912d2ad6094e40c4f6c7d66906851d2d647b971b
|
7
|
+
data.tar.gz: 6075acb96e091bdc49cbdac40182e2e476efcc1f20ef5c491e30dcbe40688c873df3012bbf09050a66231e278c00b653fe0527173837ed930aa7c6b7f0931066
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
# Ebfly
|
2
|
+
|
3
|
+
Ebfly is a simple command line interface for [AWS ElasticBeanstalk](http://aws.amazon.com/en/elasticbeanstalk/).
|
4
|
+
|
5
|
+
## Prerequisities
|
6
|
+
|
7
|
+
- Ruby 1.9+
|
8
|
+
- git
|
9
|
+
|
10
|
+
## Install
|
11
|
+
|
12
|
+
Ebfly can be install via gem:
|
13
|
+
|
14
|
+
```
|
15
|
+
$ gem install ebfly
|
16
|
+
```
|
17
|
+
|
18
|
+
After install, you can use `ebfly` command.
|
19
|
+
|
20
|
+
## Setup
|
21
|
+
|
22
|
+
You need to create `$HOME/.ebfly` and specify following values.
|
23
|
+
|
24
|
+
```
|
25
|
+
AWS_ACCESS_KEY_ID='...'
|
26
|
+
AWS_SECRET_ACCESS_KEY='...'
|
27
|
+
AWS_REGION='us-east-1'
|
28
|
+
```
|
29
|
+
|
30
|
+
or you can also specify these values via `ENV`:
|
31
|
+
|
32
|
+
```
|
33
|
+
export AWS_ACCESS_KEY_ID='...'
|
34
|
+
export AWS_SECRET_ACCESS_KEY='...'
|
35
|
+
export AWS_REGION='us-east-1'
|
36
|
+
```
|
37
|
+
|
38
|
+
## Quick Start
|
39
|
+
|
40
|
+
If you want to deploy sinatra app, you should do following step.
|
41
|
+
|
42
|
+
### Step 1 Create git repository
|
43
|
+
|
44
|
+
Create working directory, and create git repository.
|
45
|
+
|
46
|
+
```sh
|
47
|
+
$ mkdir sinatraapp
|
48
|
+
$ cd sinatraapp
|
49
|
+
$ git init .
|
50
|
+
```
|
51
|
+
|
52
|
+
### Step 2 Create application
|
53
|
+
|
54
|
+
Create application using `ebfly app create` command.
|
55
|
+
|
56
|
+
```sh
|
57
|
+
# Usage: "ebfly app create <application-name>"
|
58
|
+
$ ebfly app create sinatraapp
|
59
|
+
Create app: sinatraapp ...
|
60
|
+
|
61
|
+
=== application info ===
|
62
|
+
application name: sinatraapp
|
63
|
+
description:
|
64
|
+
created at: 2014-02-25 08:43:30 UTC
|
65
|
+
updated at: application name: 2014-02-25 08:43:30 UTC
|
66
|
+
configuration_templates:
|
67
|
+
```
|
68
|
+
|
69
|
+
### Step 3 Create environment
|
70
|
+
|
71
|
+
Create environment using 'ebfly env create' command.
|
72
|
+
|
73
|
+
```sh
|
74
|
+
# Usage: "ebfly env create <environment-name> -a <application-name> -s <solution_stack_name> -t <tier-type>
|
75
|
+
$ ebfly env create dev -a sinatraapp -s ruby19 -t web
|
76
|
+
Create environment: sinatraapp-dev ...
|
77
|
+
|
78
|
+
=== environment info ===
|
79
|
+
application name: sinatraapp
|
80
|
+
environment id: e-XXX
|
81
|
+
environment name: sinatraapp-dev
|
82
|
+
description:
|
83
|
+
status: Launching
|
84
|
+
health: Grey
|
85
|
+
tier: WebServer Standard 1.0
|
86
|
+
solution stack name: 64bit Amazon Linux 2013.09 running Ruby 1.9.3
|
87
|
+
updated at: 2014-02-25 08:45:39 UTC
|
88
|
+
```
|
89
|
+
|
90
|
+
### Step 4 Create sinatraapp
|
91
|
+
|
92
|
+
Create `config.ru`, `helloworld.rb` and `Gemfile` like this:
|
93
|
+
|
94
|
+
#### config.ru
|
95
|
+
|
96
|
+
```rb
|
97
|
+
require './helloworld'
|
98
|
+
run Sinatra::Application
|
99
|
+
```
|
100
|
+
|
101
|
+
#### helloworld.rb
|
102
|
+
|
103
|
+
```rb
|
104
|
+
require 'sinatra'
|
105
|
+
get '/' do
|
106
|
+
"Hello World!"
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
#### Gemfile
|
111
|
+
|
112
|
+
```rb
|
113
|
+
source 'http://rubygems.org'
|
114
|
+
gem 'sinatra'
|
115
|
+
```
|
116
|
+
|
117
|
+
### Step 5 Bundle install and commit working files
|
118
|
+
|
119
|
+
```sh
|
120
|
+
$ bundle install
|
121
|
+
$ git add .
|
122
|
+
$ git commit -m "First commit"
|
123
|
+
```
|
124
|
+
|
125
|
+
### Step 6 Deploy app
|
126
|
+
|
127
|
+
Deploy app's `master` branch to environment using `ebfly env push` command.
|
128
|
+
|
129
|
+
```sh
|
130
|
+
# Usage: "ebfly push <name> <branch or tree_ish>".
|
131
|
+
$ ebfly env push dev master -a sinatraapp
|
132
|
+
|
133
|
+
=== environment info ===
|
134
|
+
application name: sinatraapp
|
135
|
+
environment id: e-wwdh3u39bg
|
136
|
+
environment name: sinatraapp-dev
|
137
|
+
description:
|
138
|
+
status: Ready
|
139
|
+
health: Green
|
140
|
+
tier: WebServer Standard 1.0
|
141
|
+
solution stack name: 64bit Amazon Linux 2013.09 running Ruby 1.9.3
|
142
|
+
endpoint url: awseb-e-w-AWSEBLoa-18QJHE7KJ67YX-1070649090.us-east-1.elb.amazonaws.com
|
143
|
+
cname: sinatraapp-dev-esfmkp3rgk.elasticbeanstalk.com
|
144
|
+
updated at: 2014-02-25 08:50:51 UTC
|
145
|
+
|
146
|
+
Create archive: git-8e81464455269535c89149643ba50fab5cfa82da-1393318559.zip
|
147
|
+
Upload archive git-8e81464455269535c89149643ba50fab5cfa82da-1393318559.zip to s3://elasticbeanstalk-us-east-1-283381710361
|
148
|
+
Create application version: 8e81464455269535c89149643ba50fab5cfa82da-1393318559
|
149
|
+
Update environment: sinatraapp-dev to 8e81464455269535c89149643ba50fab5cfa82da-1393318559
|
150
|
+
|
151
|
+
=== environment info ===
|
152
|
+
application name: sinatraapp
|
153
|
+
environment id: e-wwdh3u39bg
|
154
|
+
environment name: sinatraapp-dev
|
155
|
+
description:
|
156
|
+
status: Updating
|
157
|
+
health: Grey
|
158
|
+
tier: WebServer Standard 1.0
|
159
|
+
solution stack name: 64bit Amazon Linux 2013.09 running Ruby 1.9.3
|
160
|
+
endpoint url: awseb-e-w-AWSEBLoa-18QJHE7KJ67YX-1070649090.us-east-1.elb.amazonaws.com
|
161
|
+
cname: sinatraapp-dev-esfmkp3rgk.elasticbeanstalk.com
|
162
|
+
version label: 8e81464455269535c89149643ba50fab5cfa82da-1393318559
|
163
|
+
updated at: 2014-02-25 08:56:01 UTC
|
164
|
+
```
|
165
|
+
|
166
|
+
### Step 7 Open app
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
## License
|
171
|
+
|
172
|
+
This tool is distributed under the
|
173
|
+
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
|
data/Rakefile
ADDED
data/bin/ebfly
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
require 'pathname'
|
5
|
+
bin_file = Pathname.new(__FILE__).realpath
|
6
|
+
|
7
|
+
$:.unshift File.expand_path("../../lib", bin_file)
|
8
|
+
|
9
|
+
conf = File.expand_path("~/.ebfly")
|
10
|
+
File.readlines(conf).each do |line|
|
11
|
+
key, val = line.split('=')
|
12
|
+
next if val.nil?
|
13
|
+
ENV[key.strip] = val.strip
|
14
|
+
end if File.exist?(conf)
|
15
|
+
|
16
|
+
require "ebfly/cli"
|
17
|
+
Ebfly::CLI.start(ARGV)
|
data/ebfly.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ebfly/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ebfly"
|
8
|
+
spec.version = Ebfly::VERSION
|
9
|
+
spec.authors = ["Kazuyuki Honda"]
|
10
|
+
spec.email = ["hakobera@gmail.com"]
|
11
|
+
spec.summary = %q{Simple command line interface for AWS ElasticBeanstalk}
|
12
|
+
spec.description = %q{Simple command line interface for AWS ElasticBeanstalk}
|
13
|
+
spec.homepage = "https://github.com/hakobera/ebifly"
|
14
|
+
spec.license = "Apache License, Version 2.0"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "aws-sdk"
|
22
|
+
spec.add_runtime_dependency "thor"
|
23
|
+
end
|
data/lib/ebfly/cli.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "aws-sdk"
|
3
|
+
|
4
|
+
require_relative 'ebfly'
|
5
|
+
require_relative 'version'
|
6
|
+
require_relative 'command/app'
|
7
|
+
require_relative 'command/env'
|
8
|
+
require_relative 'command/config'
|
9
|
+
|
10
|
+
module Ebfly
|
11
|
+
class CLI < Thor
|
12
|
+
desc "version", "show version"
|
13
|
+
def version
|
14
|
+
puts "Ebfly #{Ebfly::VERSION}"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "app SUBCOMMAND ...ARGS", "manage application"
|
18
|
+
subcommand "app", App
|
19
|
+
|
20
|
+
desc "env SUBCOMMAND ...ARGS -a APP", "manager environment"
|
21
|
+
subcommand "env", Environment
|
22
|
+
|
23
|
+
desc "config SUBCOMMAND ...ARGS -a APP", "manager environment's config vars"
|
24
|
+
subcommand "config", Config
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Ebfly
|
2
|
+
class App < Thor
|
3
|
+
include Command
|
4
|
+
|
5
|
+
desc "create <name>", "Create an application named <name>"
|
6
|
+
option :d, :banner => "<description>", :desc => "Describes the application"
|
7
|
+
def create(name)
|
8
|
+
puts "Create app: #{name} ..."
|
9
|
+
opts = { application_name: name }
|
10
|
+
opts.merge!(description: options[:d]) if options[:d]
|
11
|
+
|
12
|
+
debug(opts)
|
13
|
+
ret = run { eb.create_application(opts) }
|
14
|
+
debug(ret)
|
15
|
+
show_app_info(ret[:application])
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "delete <name>", "Delete an application named <name>"
|
19
|
+
option :f, :desc => "Terminate running environment by force", :default => false, :type => :boolean
|
20
|
+
def delete(name)
|
21
|
+
puts "Delete app: #{name} ..."
|
22
|
+
opts = {
|
23
|
+
application_name: name,
|
24
|
+
terminate_env_by_force: options[:f]
|
25
|
+
}
|
26
|
+
debug(opts)
|
27
|
+
run { eb.delete_application(opts) }
|
28
|
+
puts "Done"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "info <name>", "Show information of the application"
|
32
|
+
def info(name)
|
33
|
+
begin
|
34
|
+
inf = app_info(name)
|
35
|
+
debug inf
|
36
|
+
show_app_info(inf)
|
37
|
+
rescue => err
|
38
|
+
style_err err
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "versions <name>", "Show the application versions"
|
44
|
+
def versions(name)
|
45
|
+
opts = {
|
46
|
+
application_name: name
|
47
|
+
}
|
48
|
+
ret = run { eb.describe_application_versions(opts) }
|
49
|
+
debug(ret)
|
50
|
+
show_app_versions(ret[:application_versions])
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def app_info(app)
|
56
|
+
opts = {
|
57
|
+
application_names: [ app ]
|
58
|
+
}
|
59
|
+
ret = run { eb.describe_applications(opts) }
|
60
|
+
raise "application named #{app} not found" unless ret[:applications][0]
|
61
|
+
ret[:applications][0]
|
62
|
+
end
|
63
|
+
|
64
|
+
def show_app_info(app)
|
65
|
+
puts ""
|
66
|
+
puts "=== application info ==="
|
67
|
+
puts "application name:\t#{app[:application_name]}"
|
68
|
+
puts "description:\t\t#{app[:description]}"
|
69
|
+
puts "created at:\t\t#{app[:date_created]}"
|
70
|
+
puts "updated at:\t\tapplication name: #{app[:date_updated]}"
|
71
|
+
puts "configuration_templates:"
|
72
|
+
app[:configuration_templates].each do |t|
|
73
|
+
puts " #{t}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def show_app_versions(versions)
|
78
|
+
len = versions.length
|
79
|
+
puts ""
|
80
|
+
puts "=== application versions ==="
|
81
|
+
versions.each_with_index do |v, i|
|
82
|
+
puts "#{len-i}. #{v[:version_label]}\t#{v[:date_updated]}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Ebfly
|
2
|
+
class Config < Thor
|
3
|
+
include Command
|
4
|
+
|
5
|
+
class_option :a, :required => true, :banner => "<application-name>", :desc => "Application name"
|
6
|
+
class_option :e, :required => true, :banner => "<environment-name>", :desc => "Environment name"
|
7
|
+
|
8
|
+
desc "show", "Show environment's config vars"
|
9
|
+
def show
|
10
|
+
app = options[:a]
|
11
|
+
env = options[:e]
|
12
|
+
|
13
|
+
opts = {
|
14
|
+
application_name: app,
|
15
|
+
environment_name: env_name(app, env)
|
16
|
+
}
|
17
|
+
|
18
|
+
ret = run { eb.describe_configuration_settings(opts) }
|
19
|
+
debug(ret)
|
20
|
+
show_env_conf(app, env, ret)
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "rm", "Add configuration ot the environment"
|
24
|
+
option :c, :required => true, :banner => "<key1=value1 key2=value2 ...>", :type => :array, :desc => "Config vars"
|
25
|
+
def add
|
26
|
+
ret = add_environment_config(options[:a], options[:e], options[:c])
|
27
|
+
debug(ret)
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "rm", "Remove configuration ot the environment"
|
31
|
+
option :c, :required => true, :banner => "<key1 key2 ...>", :type => :array, :desc => "Config vars"
|
32
|
+
def rm
|
33
|
+
ret = remove_environment_config(options[:a], options[:e], options[:c])
|
34
|
+
debug(ret)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def add_environment_config(app, env, configs)
|
40
|
+
puts "Add config vars: #{env_name(app, env)}"
|
41
|
+
|
42
|
+
settings = []
|
43
|
+
configs.each do |config|
|
44
|
+
k, v = config.split("=")
|
45
|
+
next if v.nil?
|
46
|
+
conf = {
|
47
|
+
namespace: "aws:elasticbeanstalk:application:environment",
|
48
|
+
option_name: k.strip,
|
49
|
+
value: v.strip
|
50
|
+
}
|
51
|
+
settings << conf
|
52
|
+
end
|
53
|
+
|
54
|
+
opts = {
|
55
|
+
environment_name: env_name(app, env),
|
56
|
+
option_settings: settings
|
57
|
+
}
|
58
|
+
run { eb.update_environment(opts) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def remove_environment_config(app, env, keys)
|
62
|
+
puts "Remove config vars: #{env_name(app, env)}"
|
63
|
+
|
64
|
+
settings = []
|
65
|
+
keys.each do |key|
|
66
|
+
conf = {
|
67
|
+
namespace: "aws:elasticbeanstalk:application:environment",
|
68
|
+
option_name: key.strip,
|
69
|
+
}
|
70
|
+
settings << conf
|
71
|
+
end
|
72
|
+
|
73
|
+
opts = {
|
74
|
+
environment_name: env_name(app, env),
|
75
|
+
options_to_remove: settings
|
76
|
+
}
|
77
|
+
run { eb.update_environment(opts) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def show_env_conf(app, env, res)
|
81
|
+
config_vars = []
|
82
|
+
|
83
|
+
puts ""
|
84
|
+
puts "=== #{env_name(app, env)} Config Vars ==="
|
85
|
+
settings = res[:configuration_settings]
|
86
|
+
settings.each do |setting|
|
87
|
+
opts = setting[:option_settings]
|
88
|
+
opts.each do |opt|
|
89
|
+
next unless opt[:option_name] == "EnvironmentVariables"
|
90
|
+
config_vars = opt[:value].split(",")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
config_vars.sort.each do |config_var|
|
95
|
+
puts config_var
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
module Ebfly
|
2
|
+
class Environment < Thor
|
3
|
+
include Command
|
4
|
+
|
5
|
+
class_option :a, :required => true, :banner => "<application-name>", :desc => "Application name"
|
6
|
+
|
7
|
+
desc "create <name>", "Create a environment named <name>"
|
8
|
+
option :s, :required => true, :banner => "<solution stack name>", :desc => "This is an alternative to specifying a configuration name"
|
9
|
+
option :t, :banner => "<type>", :default => "web", :desc => "tier type, web or worker"
|
10
|
+
option :d, :banner => "<description>", :desc => "Describes the environment"
|
11
|
+
option :v, :banner => "<version label>", :desc => "The name of the application version to deploy"
|
12
|
+
def create(name)
|
13
|
+
app = options[:a]
|
14
|
+
puts "Create environment: #{env_name(app, name)} ..."
|
15
|
+
opts = {
|
16
|
+
application_name: app,
|
17
|
+
environment_name: env_name(app, name),
|
18
|
+
solution_stack_name: solution_stack(options[:s]),
|
19
|
+
tier: tier(options[:t])
|
20
|
+
}
|
21
|
+
opts.merge!(description: options[:d]) if options[:d]
|
22
|
+
opts.merge!(version_label: options[:v]) if options[:v]
|
23
|
+
|
24
|
+
debug opts
|
25
|
+
ret = run { eb.create_environment(opts) }
|
26
|
+
show_env_info(ret)
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "delete <name>", "Delete the environment named <name>"
|
30
|
+
def delete(name)
|
31
|
+
app = options[:a]
|
32
|
+
puts "Delete environment: #{env_name(app, name)} ..."
|
33
|
+
opts = {
|
34
|
+
environment_name: env_name(app, name)
|
35
|
+
}
|
36
|
+
run { eb.terminate_environment(opts) }
|
37
|
+
puts "Done"
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "info <name>", "Show information of the enviroment"
|
41
|
+
option :r, :default => false, :desc => "Show environment resources info"
|
42
|
+
def info(name)
|
43
|
+
app = options[:a]
|
44
|
+
begin
|
45
|
+
inf = env_info(app, name)
|
46
|
+
debug inf
|
47
|
+
show_env_info(inf)
|
48
|
+
rescue => err
|
49
|
+
style_err err
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
|
53
|
+
if options[:r]
|
54
|
+
res = env_resources(app, name)
|
55
|
+
debug res
|
56
|
+
show_env_resources(res)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "open <name>", "Open environment in browser (Mac OS Only)"
|
61
|
+
def open(name)
|
62
|
+
raise "This feature can run on Mac OS Only" unless exist_command?('open')
|
63
|
+
|
64
|
+
inf = env_info(options[:a], name)
|
65
|
+
url = "http://#{inf[:cname]}"
|
66
|
+
system "open #{url}"
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "push <name> <branch or tree_ish>", "Push and deploy specified branch to environment"
|
70
|
+
def push(name, branch)
|
71
|
+
raise "git must be installed" unless exist_command?('git')
|
72
|
+
app = options[:a]
|
73
|
+
|
74
|
+
puts "push #{branch} to #{env_name(app, name)}"
|
75
|
+
inf = env_info(app, name)
|
76
|
+
show_env_info(inf)
|
77
|
+
raise "Environment named #{env_name(app, name)} is in an invalid state for this operation. Must be Ready." if inf[:status] != "Ready"
|
78
|
+
puts ""
|
79
|
+
|
80
|
+
ish, e, s = Open3.capture3("git", "rev-parse", branch)
|
81
|
+
ish.strip!
|
82
|
+
time = Time.now.to_i
|
83
|
+
version = "#{ish}-#{time}"
|
84
|
+
file_name = "git-#{version}.zip"
|
85
|
+
|
86
|
+
begin
|
87
|
+
create_archive(file_name, ish)
|
88
|
+
upload_archive(file_name)
|
89
|
+
create_application_version(app, version, ish, file_name)
|
90
|
+
ret = update_environment(app, name, version)
|
91
|
+
debug(ret)
|
92
|
+
show_env_info(ret)
|
93
|
+
rescue => err
|
94
|
+
style_err err
|
95
|
+
exit 1
|
96
|
+
ensure
|
97
|
+
File.delete file_name if File.exist? file_name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def env_info(app, env)
|
104
|
+
opts = {
|
105
|
+
application_name: app,
|
106
|
+
environment_names: [ env_name(app, env) ]
|
107
|
+
}
|
108
|
+
ret = run { eb.describe_environments(opts) }
|
109
|
+
raise "Environment named #{env_name(app, env)} not found" unless ret[:environments][0]
|
110
|
+
ret[:environments][0]
|
111
|
+
end
|
112
|
+
|
113
|
+
def env_resources(app, env)
|
114
|
+
opts = {
|
115
|
+
environment_name: env_name(app, env)
|
116
|
+
}
|
117
|
+
ret = run { eb.describe_environment_resources(opts) }
|
118
|
+
ret[:environment_resources]
|
119
|
+
end
|
120
|
+
|
121
|
+
def create_archive(file_name, ish)
|
122
|
+
puts "Create archive: #{file_name}"
|
123
|
+
Open3.capture3("git", "archive", "--format", "zip", "--output", file_name, ish)
|
124
|
+
end
|
125
|
+
|
126
|
+
def upload_archive(file_name)
|
127
|
+
puts "Upload archive #{file_name} to s3://#{s3_bucket}"
|
128
|
+
bucket = s3.buckets[s3_bucket]
|
129
|
+
obj = bucket.objects[file_name]
|
130
|
+
obj.write(Pathname.new(file_name))
|
131
|
+
end
|
132
|
+
|
133
|
+
def create_application_version(app, version, ish, file_name)
|
134
|
+
puts "Create application version: #{version}"
|
135
|
+
opts = {
|
136
|
+
application_name: app,
|
137
|
+
version_label: version,
|
138
|
+
description: ish,
|
139
|
+
source_bundle: {
|
140
|
+
s3_bucket: s3_bucket,
|
141
|
+
s3_key: file_name
|
142
|
+
}
|
143
|
+
}
|
144
|
+
run { eb.create_application_version(opts) }
|
145
|
+
end
|
146
|
+
|
147
|
+
def update_environment(app, env, version)
|
148
|
+
puts "Update environment: #{env_name(app, env)} to #{version}"
|
149
|
+
opts = {
|
150
|
+
environment_name: env_name(app, env),
|
151
|
+
version_label: version
|
152
|
+
}
|
153
|
+
run { eb.update_environment(opts) }
|
154
|
+
end
|
155
|
+
|
156
|
+
def show_env_info(res)
|
157
|
+
puts ""
|
158
|
+
puts "=== environment info ==="
|
159
|
+
puts "application name:\t#{res[:application_name]}"
|
160
|
+
puts "environment id:\t\t#{res[:environment_id]}"
|
161
|
+
puts "environment name:\t#{res[:environment_name]}"
|
162
|
+
puts "description:\t\t#{res[:description]}"
|
163
|
+
puts "status:\t\t\t#{res[:status]}"
|
164
|
+
puts "health:\t\t\t#{res[:health]}"
|
165
|
+
puts "tier:\t\t\t#{res[:tier][:name]} #{res[:tier][:type]} #{res[:tier][:version]}"
|
166
|
+
puts "solution stack name:\t#{res[:solution_stack_name]}"
|
167
|
+
puts "endpoint url:\t\t#{res[:endpoint_url]}" if res[:endpoint_url]
|
168
|
+
puts "cname:\t\t\t#{res[:cname]}" if res[:cname]
|
169
|
+
puts "version label:\t\t#{res[:version_label]}" if res[:version_label]
|
170
|
+
puts "updated at:\t\t#{res[:date_updated]}"
|
171
|
+
end
|
172
|
+
|
173
|
+
def show_env_resources(res)
|
174
|
+
puts ""
|
175
|
+
puts "=== environment resources ==="
|
176
|
+
puts "auto scaling groups:\t#{res[:auto_scaling_groups]}"
|
177
|
+
puts "instances:\t\t#{res[:instances]}"
|
178
|
+
puts "launch configurations:\t#{res[:launch_configurations]}"
|
179
|
+
puts "load balancers:\t\t#{res[:load_balancers]}"
|
180
|
+
puts "triggers:\t\t#{res[:triggers]}"
|
181
|
+
puts "queues:\t\t\t#{res[:queues]}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
data/lib/ebfly/ebfly.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "aws-sdk"
|
3
|
+
require "pp"
|
4
|
+
require "open3"
|
5
|
+
|
6
|
+
module Ebfly
|
7
|
+
module Command
|
8
|
+
PREDEFINED_SOLUTION_STACKS = {
|
9
|
+
"php53" => "64bit Amazon Linux running PHP 5.3",
|
10
|
+
"php54" => "64bit Amazon Linux 2013.09 running PHP 5.4",
|
11
|
+
"php55" => "64bit Amazon Linux 2013.09 running PHP 5.5",
|
12
|
+
"nodejs" => "64bit Amazon Linux 2013.09 running Node.js",
|
13
|
+
"java7" => "64bit Amazon Linux 2013.09 running Tomcat 7 Java 7",
|
14
|
+
"java6" => "64bit Amazon Linux 2013.09 running Tomcat 7 Java 6",
|
15
|
+
"python27" => "64bit Amazon Linux 2013.09 running Python 2.7",
|
16
|
+
"ruby18" => "64bit Amazon Linux 2013.09 running Ruby 1.8.7",
|
17
|
+
"ruby19" => "64bit Amazon Linux 2013.09 running Ruby 1.9.3",
|
18
|
+
}
|
19
|
+
|
20
|
+
def eb
|
21
|
+
@eb ||= AWS::ElasticBeanstalk.new
|
22
|
+
@eb.client
|
23
|
+
end
|
24
|
+
|
25
|
+
def s3
|
26
|
+
@s3 ||= AWS::S3.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def run(&block)
|
30
|
+
begin
|
31
|
+
res = yield
|
32
|
+
raise res.error unless res.successful?
|
33
|
+
res
|
34
|
+
rescue => err
|
35
|
+
style_err(err)
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def s3_bucket
|
41
|
+
@s3_bucket ||= (run { eb.create_storage_location }[:s3_bucket])
|
42
|
+
end
|
43
|
+
|
44
|
+
def style_err(err)
|
45
|
+
puts "ERR! #{err.message}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def debug(obj)
|
49
|
+
pp obj if ENV["DEBUG"]
|
50
|
+
end
|
51
|
+
|
52
|
+
def exist_command?(cmd)
|
53
|
+
Open3.capture3("type", cmd)[2].exitstatus == 0 rescue nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def env_name(app, env)
|
57
|
+
"#{app}-#{env}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def tier(type)
|
61
|
+
if type == "web"
|
62
|
+
return { name: "WebServer", type: "Standard", version: "1.0" }
|
63
|
+
elsif type == "worker"
|
64
|
+
return { name: "Worker", type: "SQS/HTTP", version: "1.0" }
|
65
|
+
else
|
66
|
+
raise "Environment tier definition not found"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def solution_stack(name)
|
71
|
+
return PREDEFINED_SOLUTION_STACKS[name] if PREDEFINED_SOLUTION_STACKS.key?(name)
|
72
|
+
return name
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ebfly
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kazuyuki Honda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Simple command line interface for AWS ElasticBeanstalk
|
42
|
+
email:
|
43
|
+
- hakobera@gmail.com
|
44
|
+
executables:
|
45
|
+
- ebfly
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- Gemfile
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- bin/ebfly
|
54
|
+
- ebfly.gemspec
|
55
|
+
- lib/ebfly/cli.rb
|
56
|
+
- lib/ebfly/command/app.rb
|
57
|
+
- lib/ebfly/command/config.rb
|
58
|
+
- lib/ebfly/command/env.rb
|
59
|
+
- lib/ebfly/ebfly.rb
|
60
|
+
- lib/ebfly/version.rb
|
61
|
+
homepage: https://github.com/hakobera/ebifly
|
62
|
+
licenses:
|
63
|
+
- Apache License, Version 2.0
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.2.0
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: Simple command line interface for AWS ElasticBeanstalk
|
85
|
+
test_files: []
|