ftl 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -4,3 +4,5 @@ vendor/bundle
4
4
  results.html
5
5
  pkg
6
6
  html
7
+
8
+ .rvmrc
data/Changelog CHANGED
@@ -1,18 +1,26 @@
1
- Release Version 0.2.2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1
+ # Release Version 0.2.4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
+
3
+ * Add ftl <action> <server> to execute arbitrary commands on running instances
4
+ * Add ftl sample_config to see the latest sample ftl.yml
5
+ * Add ftl images # Shows AMIs associated with your account
6
+
7
+ # Release Version 0.2.3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
8
 
3
- * Add ftl status
4
- * find_instances returns exact match preferentially
9
+ * Add ftl status
10
+ * find_instances returns exact match preferentially
11
+ * Update README with more examples and setup
12
+ * Adds :keys config parameter
5
13
 
6
- Release Version 0.2.2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14
+ # Release Version 0.2.2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7
15
 
8
- * Adds templates feature to config file
9
- * Start and cancel spot requests
10
- * Execution without parameters shows help screen
11
- * Fixes various bugs
16
+ * Adds templates feature to config file
17
+ * Start and cancel spot requests
18
+ * Execution without parameters shows help screen
19
+ * Fixes various bugs
12
20
 
13
- Release Version 0.2.0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
+ # Release Version 0.2.0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14
22
 
15
- * First revamped release handling AWS in a more generic way
23
+ * First revamped release handling AWS in a more generic way
16
24
 
17
25
  Previous releases were focused on starting up Pair Programming servers.
18
26
  The latest releases can also be used for this but are more useful in a generic
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ftl (0.2.3)
4
+ ftl (0.2.4)
5
5
  fog
6
6
  formatador (~> 0.2.2)
7
7
 
data/README.md CHANGED
@@ -4,7 +4,7 @@ Faster Than Light. Fog Terminal Language. For Terminal Launching.
4
4
 
5
5
  ## Description
6
6
 
7
- Ftl is an AWS (fog-based) application for managing cloud instances from the command line.
7
+ `ftl` is an AWS (fog-based) application for managing cloud instances from the command line.
8
8
  Easier than chef or the ec2 command line tools. Smarter too.
9
9
 
10
10
  ## Installation
@@ -15,8 +15,6 @@ Install is easy.
15
15
 
16
16
  ## Usage
17
17
 
18
- ### Example commands
19
-
20
18
  Usage: ftl [<config-options>] <command> [<command-options>]
21
19
  commands: start, kill, list, edit, connect, servers, tags, images, snapshots, volumes
22
20
  examples:
@@ -35,10 +33,75 @@ Install is easy.
35
33
  ftl headers servers # Show possible headers for servers
36
34
  ftl headers volumes # Show possible headers for volumes
37
35
  ftl edit # Edit ftl.yml with your $EDITOR
38
- ftl --config=~/ftl.yml servers # Uses custom config file
39
- ftl --headers=id,tags.Name servers # Uses specified headers
36
+ ftl --config=~/ftl.yml servers # Uses custom config file
37
+ ftl --headers=id,tags.Name servers # Uses specified headers
40
38
  ftl --version # Show version number
41
39
 
40
+ ## Getting started
41
+
42
+ `ftl` depends on a configuration file. When you run it for the first time,
43
+ it will create a simple configuration file at `~/.ftl/ftl.yml`. Note that the starter file is incomplete;
44
+ you will need to supply at least your Amazon AWS security credentials. You can open the
45
+ configuration file in the editor named by the `$EDITOR` environment variable by running `ftl edit`.
46
+
47
+ ### Configuration file
48
+
49
+ In addition to the AWS security credentials, the configuration file contains parameters for
50
+ launching instances and connecting to them.
51
+
52
+ ACCESS_KEY_ID: # Amazon AWS access key
53
+ SECRET_ACCESS_KEY: # Amazon AWS secret access key
54
+
55
+ :keys:
56
+ ninja-keypair: ~/.ec2/id_rsa-ninja-keypair
57
+
58
+ :templates:
59
+ :ninja:
60
+ :ami: ami-a29943cb # Ubuntu 12.04 LTS Precise Pangolin
61
+ :username: ubuntu
62
+ :keypair: ninja-keypair
63
+ :instance_type: m1.small
64
+ :tags: {}
65
+ :groups:
66
+ - default
67
+ - apache
68
+ - postgresql
69
+
70
+ #### The :templates section
71
+
72
+ `:templates` is a hash of server names and the EC2 parameters used to launch them.
73
+
74
+ * :ami -- the ID of the AMI to use
75
+ * :availability_zone -- the availability zone into which the instance should be launched
76
+ * :groups -- a list of names and/or IDs of security groups to assign to the instance
77
+ * :instance_type -- the name of the EC2 instance size (e.g. 'm1.small')
78
+ * :ip_private -- the private IP address to assign to the instance (optional)
79
+ * :ip_public -- the public IP address to assign to the instance (optional)
80
+ * :keypair -- the name of the keypair installed in the instance when launched; this is important
81
+ for connecting to the instance once it has been launched
82
+ * :subnet_id -- the ID of the subnet into which the instance should be launched (optional)
83
+ * :tags -- a hash of tags to be set on the instance; 'Name' will be automatically set from the
84
+ server name
85
+ * :username -- the username to use when connecting to the instance
86
+
87
+ #### A note on security groups
88
+
89
+ Security groups defined in a virtual private cloud (VPC) can be specified only by ID.
90
+
91
+ #### The :keys section
92
+
93
+ `:keys`, if defined, is a hash of keypair names and the names of files on the local filesystem
94
+ containing them. If there is an entry in `:keys` with the same name as the server, the file will be
95
+ passed in the `-i` option to `ssh` when connecting.
96
+
97
+ ### Launching an instance
98
+
99
+ Once a server has been configured, it can be launched by name.
100
+
101
+ ftl launch ninja
102
+
103
+ To connect to it, run `ftl connect ninja`.
104
+
42
105
  ## Contributing
43
106
 
44
107
  1. Fork it
data/bin/ftl CHANGED
@@ -11,6 +11,10 @@ optparse = OptionParser.new do |opts|
11
11
  exit
12
12
  end
13
13
 
14
+ # opts.on('-s', '--sample-config', "Displays sample ftl.yml config file") do |opts|
15
+ # Ftl.sample_config
16
+ # end
17
+
14
18
  opts.on('-d', '--headers FILE', Array, "provide custom headers") do |headers|
15
19
  options[:headers] = headers
16
20
  end
@@ -20,8 +20,10 @@ module Ftl
20
20
  ftl headers servers # Show possible headers for servers
21
21
  ftl headers volumes # Show possible headers for volumes
22
22
  ftl edit # Edit ftl.yml with your $EDITOR
23
- ftl --config=~/ftl.yml servers # Uses custom config file
24
- ftl --headers=id,tags.Name servers # Uses specified headers
23
+ ftl images # Show AMIs associated with your account
24
+ ftl <action> ninja # Execute the <action> (specified in ftl.yml) on the remote server instance
25
+ ftl --config=~/ftl.yml servers # Uses custom config file
26
+ ftl --headers=id,tags.Name servers # Uses specified headers
25
27
  ftl --version # Show version number
26
28
  }
27
29
  end
@@ -32,39 +34,59 @@ module Ftl
32
34
 
33
35
  class Client
34
36
 
37
+ SINGLE_COMMANDS = %w{ edit sample }
38
+
35
39
  attr_reader :con
36
40
  attr_accessor :options
37
41
 
38
42
  def initialize(args=nil, opts={})
39
43
  load_config(opts)
40
- @con = Fog::Compute.new(:provider => 'AWS', :aws_secret_access_key => options['SECRET_ACCESS_KEY'], :aws_access_key_id => options['ACCESS_KEY_ID'])
41
44
  if args && args.length > 0
42
45
  arg = args.reverse.pop
43
- send(arg, args - [arg])
46
+ if (!SINGLE_COMMANDS.include?(arg))
47
+ @con = Fog::Compute.new(:provider => 'AWS', :aws_secret_access_key => options['SECRET_ACCESS_KEY'], :aws_access_key_id => options['ACCESS_KEY_ID'])
48
+ end
49
+ begin
50
+ send(arg, args - [arg])
51
+ rescue
52
+ Ftl.help
53
+ end
44
54
  else
45
55
  Ftl.help
46
56
  end
47
57
  end
48
58
 
49
- def launch(args={})
50
- if args.first.nil?
51
- display "Please provide a short name for instance\n\t[bold]ftl[/] launch <name>"
52
- return
53
- end
59
+ def launch_instance(args)
54
60
  display "Spinning up FTL..."
55
61
  opts = options
56
62
  opts = options[:templates][args.first.to_sym] if !options[:templates][args.first.to_sym].nil?
57
- server = con.servers.create(:user_data => opts[:user_data],
58
- :key_name => opts[:keypair],
59
- :groups => opts[:groups],
60
- :image_id => opts[:ami],
61
- :availability_zone => opts[:availability_zone],
62
- :flavor_id => opts[:instance_type],
63
- :username => opts[:username],
64
- :tags => opts[:tags].merge(:Name => args.first)
65
- )
63
+
64
+ opts[:group_ids] = (opts[:group_ids] || []) + opts[:groups].select { | group | group.to_s =~ /^sg-[0-9a-f]{8}$/ }
65
+ opts[:groups] = opts[:groups].reject { | group | group.to_s =~ /^sg-[0-9a-f]{8}$/ }
66
+
67
+ server = con.servers.create(:user_data => opts[:user_data],
68
+ :key_name => opts[:keypair],
69
+ :groups => opts[:groups],
70
+ :security_group_ids => opts[:group_ids],
71
+ :image_id => opts[:ami],
72
+ :availability_zone => opts[:availability_zone],
73
+ :flavor_id => opts[:instance_type],
74
+ :username => opts[:username],
75
+ :tags => opts[:tags].merge(:Name => args.first),
76
+ :subnet_id => opts[:subnet_id],
77
+ :private_ip_address => opts[:ip_private],
78
+ )
79
+
66
80
  display server
67
- eval(options[:post_script]) if options[:post_script]
81
+ display "Executing :post_script..." if opts[:post_script]
82
+ eval(opts[:post_script]) if opts[:post_script]
83
+ end
84
+
85
+ def launch(args={})
86
+ guard(args.first, "Please provide a short name for instance\n\t[bold]ftl[/] launch <name>")
87
+ display "Spinning up FTL..."
88
+ options.merge(options[:templates][args.first.to_sym]) if !options[:templates][args.first.to_sym].nil?
89
+ server = launch_instance(args)
68
90
  end
69
91
  alias :up :launch
70
92
  alias :spinup :launch
@@ -72,28 +94,12 @@ module Ftl
72
94
  alias :new :launch
73
95
 
74
96
  def spot(args={})
75
- if args.first.nil?
76
- display "Please provide a short name for instance\n\t[bold]ftl[/] spot <name> <price>"
77
- return
78
- end
79
- if args[1].nil?
80
- display "Please provide a price for spot request\n\t[bold]ftl[/] spot <name> <price>"
81
- return
82
- end
97
+ guard(args.first, "Please provide a short name for instance\n\t[bold]ftl[/] spot <name> <price>")
98
+ guard(args[1], "Please provide a price for spot request\n\t[bold]ftl[/] spot <name> <price>")
83
99
  display "Spinning up FTL..."
84
- opts = options
85
- opts = options[:templates][args.first.to_sym] if !options[:templates][args.first.to_sym].nil?
86
- server = con.spot_requests.create(:user_data => opts[:user_data],
87
- :price => args[1],
88
- :key_name => opts[:keypair],
89
- :groups => opts[:groups],
90
- :image_id => opts[:ami],
91
- :availability_zone => opts[:availability_zone],
92
- :flavor_id => opts[:instance_type],
93
- :username => opts[:username],
94
- :tags => {:Name => args.first}
95
- )
96
- display server
100
+ options.merge(options[:templates][args.first.to_sym]) if !options[:templates][args.first.to_sym].nil?
101
+ options[:price] = args[1]
102
+ server = launch_instance(args)
97
103
  end
98
104
 
99
105
  def spots(args={})
@@ -101,10 +107,7 @@ module Ftl
101
107
  end
102
108
 
103
109
  def cancel(args={})
104
- if args.first.nil?
105
- display "Please provide the id for the spot request to cancel."
106
- return
107
- end
110
+ guard(args.first, "Please provide the id for the spot request to cancel.")
108
111
  spot = con.spot_requests.get(args.first)
109
112
  if spot && spot.destroy
110
113
  display "Canceled Spot Instance #{spot.id}."
@@ -115,7 +118,9 @@ module Ftl
115
118
 
116
119
  def connect(args={})
117
120
  if match = find_instances(args.first).select{|i| i.state == "running" }.first
118
- exec("ssh #{options[:username]||'root'}@#{match[:dns_name]}")
121
+ opt_key = "-i #{options[:keys][match[:key_name]]}" unless (options[:keys].nil? || options[:keys][match[:key_name]].nil?)
122
+ hostname = match[:dns_name] || match[:public_ip_address] || match[:private_ip_address]
123
+ exec("ssh #{opt_key} #{options[:username]||'root'}@#{hostname}")
119
124
  else
120
125
  display "Typo alert! No server found!"
121
126
  end
@@ -124,6 +129,7 @@ module Ftl
124
129
  alias :ssh :connect
125
130
 
126
131
  def status(args={})
132
+ guard(args, :message => "Please provide the name/id of a server (ftl status <server>)")
127
133
  server = find_instance(args.first)
128
134
  display server
129
135
  end
@@ -150,11 +156,11 @@ module Ftl
150
156
  display "No instances found"
151
157
  end
152
158
  end
153
- alias :d :destroy
154
- alias :delete :destroy
155
- alias :kill :destroy
156
- alias :down :destroy
157
- alias :shutdown :destroy
159
+ alias :d :destroy
160
+ alias :delete :destroy
161
+ alias :kill :destroy
162
+ alias :down :destroy
163
+ alias :shutdown :destroy
158
164
 
159
165
  def info(args={})
160
166
  display find_instance(args.first)
@@ -171,9 +177,17 @@ module Ftl
171
177
  Formatador.display_table(con.images.find(:id => args.first))
172
178
  end
173
179
 
174
- # TODO: Make images return only account's images by default
175
- # def images(args={})
176
- # end
180
+ # TODO: Make this better by including more details of block devices
181
+ def images(args={})
182
+ hashes = con.describe_images('Owner' => 'self').body['imagesSet'].collect do |hash|
183
+ h = {}
184
+ h[:image_id] = hash['imageId']
185
+ h[:name] = hash['name']
186
+ h[:rootDeviceType] = hash['rootDeviceType']
187
+ h
188
+ end
189
+ puts Formatador.display_table(hashes)
190
+ end
177
191
 
178
192
  def headers(args={})
179
193
  display "Showing header options for #{args.first}"
@@ -189,12 +203,22 @@ module Ftl
189
203
  `$EDITOR ~/.ftl/ftl.yml`
190
204
  end
191
205
 
206
+ def sample(args={})
207
+ puts File.open(File.dirname(__FILE__) + "/../resources/ftl.yml").read
208
+ end
192
209
 
193
210
  ###########################################################################
194
211
  ## private ###
195
212
  ###########################################################################
196
213
  private
197
214
 
215
+ def guard(arg, options={:message => "Please refer to ftl help"})
216
+ if arg.nil?
217
+ display options[:message]
218
+ exit
219
+ end
220
+ end
221
+
198
222
  def ftl_yml
199
223
  File.open("lib/resources/ftl.yml").read
200
224
  end
@@ -208,11 +232,11 @@ module Ftl
208
232
  default_config_dir = '/.ftl/'
209
233
  default_config_home = "#{ENV['HOME']}#{default_config_dir}"
210
234
  default_config_file = "#{default_config_home}#{default_config_name}"
211
- if Dir.exist?(default_config_home) # Directory exists
235
+ if Dir.exist?(default_config_home) # Directory exists
212
236
  if !File.exist?(default_config_file) # File does not
213
237
  File.open(default_config_file, 'w') {|f| f << ftl_yml }
214
238
  end
215
- else # Directory does not exist
239
+ else # Directory does not exist
216
240
  Dir.mkdir(default_config_home)
217
241
  File.open(default_config_file, 'w') {|f| f << ftl_yml }
218
242
  end
@@ -235,7 +259,7 @@ module Ftl
235
259
 
236
260
  def _headers_for(object)
237
261
  return options[:headers].map(&:to_sym) if options[:headers]
238
- case object.to_sym
262
+ case object
239
263
  when :snapshots
240
264
  [:id, :volume_id, :state, :volume_size, :description, :"tags.Name"]
241
265
  when :spot_requests
@@ -258,16 +282,20 @@ module Ftl
258
282
  Formatador.display_line(msg)
259
283
  end
260
284
 
285
+ def eval_action(script, args)
286
+ # TODO Complete the script to handle multiple servers, like:
287
+ # ftl bundle server1 server2 server3
288
+ server = find_instance(args[1].first)
289
+ eval(script, binding)
290
+ end
291
+
261
292
  def method_missing(*args)
262
293
  begin
263
- method = args.first
264
- # opts = args[1]
265
- if con.respond_to? method
266
- display con.send(method).table(_headers_for(method))
267
- else
268
- Ftl.help
269
- end
270
- rescue
294
+ method = args.first.to_sym
295
+ display con.send(method).table(_headers_for(method)) if con.respond_to? method
296
+ eval_action(@options[:actions][method], args) if @options[:actions][method]
297
+ Ftl.help
298
+ rescue
271
299
  end
272
300
  end
273
301
 
@@ -1,3 +1,3 @@
1
1
  module Ftl
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -1,20 +1,33 @@
1
+ # Sample ftl.yml. Your ftl.yml should be located in ~/.ftl/ftl.yml and should
2
+ # look similar to this file
3
+ #
4
+ # FILL IN THESE TWO VALUES
1
5
  ACCESS_KEY_ID:
2
6
  SECRET_ACCESS_KEY:
7
+
3
8
  :ami: ami-a29943cb # Ubuntu 12.04 LTS Precise Pangolin
4
9
  :username: ubuntu
5
- :instance_type: m1.small
6
- :instance_script: |
10
+ :instance_type: t1.micro # m1.small
11
+ :user_data: |
7
12
  #!/bin/sh
8
13
  touch /root/file.touched
9
- :spinup_script: |
14
+ :post_script: |
10
15
  :tags: {}
16
+ :actions:
17
+ :uptime: puts server.ssh('uptime').first.stdout
18
+ :mount: puts server.ssh('mount').first.stdout
19
+ :df: puts server.ssh('df -h').first.stdout
20
+ :w: puts server.ssh('w').first.stdout
21
+
11
22
 
12
23
  :templates:
13
24
  :default:
14
25
  :ami: ami-a29943cb # Ubuntu 12.04 LTS Precise Pangolin
15
26
  :username: ubuntu
16
27
  :instance_type: m1.small
17
- :instance_script: |
28
+ :user_data: |
18
29
  #!/bin/sh
19
30
  touch /root/file.touched
20
- :spinup_script: |
31
+ :post_script: |
32
+
33
+
metadata CHANGED
@@ -1,79 +1,82 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ftl
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.3
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.2.4
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Matt Petty
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-18 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
12
+
13
+ date: 2012-07-15 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
15
16
  name: rdoc
16
- requirement: &70186162145440 !ruby/object:Gem::Requirement
17
+ requirement: &id001 !ruby/object:Gem::Requirement
17
18
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
22
23
  type: :development
23
24
  prerelease: false
24
- version_requirements: *70186162145440
25
- - !ruby/object:Gem::Dependency
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
26
27
  name: aruba
27
- requirement: &70186162190980 !ruby/object:Gem::Requirement
28
+ requirement: &id002 !ruby/object:Gem::Requirement
28
29
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *70186162190980
36
- - !ruby/object:Gem::Dependency
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
37
38
  name: rake
38
- requirement: &70186162190220 !ruby/object:Gem::Requirement
39
+ requirement: &id003 !ruby/object:Gem::Requirement
39
40
  none: false
40
- requirements:
41
+ requirements:
41
42
  - - ~>
42
- - !ruby/object:Gem::Version
43
+ - !ruby/object:Gem::Version
43
44
  version: 0.9.2
44
45
  type: :development
45
46
  prerelease: false
46
- version_requirements: *70186162190220
47
- - !ruby/object:Gem::Dependency
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
48
49
  name: fog
49
- requirement: &70186162189420 !ruby/object:Gem::Requirement
50
+ requirement: &id004 !ruby/object:Gem::Requirement
50
51
  none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
55
56
  type: :runtime
56
57
  prerelease: false
57
- version_requirements: *70186162189420
58
- - !ruby/object:Gem::Dependency
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
59
60
  name: formatador
60
- requirement: &70186162188520 !ruby/object:Gem::Requirement
61
+ requirement: &id005 !ruby/object:Gem::Requirement
61
62
  none: false
62
- requirements:
63
+ requirements:
63
64
  - - ~>
64
- - !ruby/object:Gem::Version
65
+ - !ruby/object:Gem::Version
65
66
  version: 0.2.2
66
67
  type: :runtime
67
68
  prerelease: false
68
- version_requirements: *70186162188520
69
+ version_requirements: *id005
69
70
  description: Ftl is a command line tool for Fog/AWS
70
- email:
71
+ email:
71
72
  - matt@kizmeta.com
72
- executables:
73
+ executables:
73
74
  - ftl
74
75
  extensions: []
76
+
75
77
  extra_rdoc_files: []
76
- files:
78
+
79
+ files:
77
80
  - .gitignore
78
81
  - Changelog
79
82
  - Gemfile
@@ -98,35 +101,38 @@ files:
98
101
  - test/tc_something.rb
99
102
  homepage: http://github.com/lodestone/ftl
100
103
  licenses: []
104
+
101
105
  post_install_message:
102
106
  rdoc_options: []
103
- require_paths:
107
+
108
+ require_paths:
104
109
  - lib
105
- required_ruby_version: !ruby/object:Gem::Requirement
110
+ required_ruby_version: !ruby/object:Gem::Requirement
106
111
  none: false
107
- requirements:
108
- - - ! '>='
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- segments:
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: -3514707693365094716
116
+ segments:
112
117
  - 0
113
- hash: 1941961806599830985
114
- required_rubygems_version: !ruby/object:Gem::Requirement
118
+ version: "0"
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
120
  none: false
116
- requirements:
117
- - - ! '>='
118
- - !ruby/object:Gem::Version
119
- version: '0'
120
- segments:
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: -3514707693365094716
125
+ segments:
121
126
  - 0
122
- hash: 1941961806599830985
127
+ version: "0"
123
128
  requirements: []
129
+
124
130
  rubyforge_project:
125
131
  rubygems_version: 1.8.11
126
132
  signing_key:
127
133
  specification_version: 3
128
134
  summary: Ftl is a command line tool for Fog/AWS
129
- test_files:
135
+ test_files:
130
136
  - features/ftl.feature
131
137
  - features/step_definitions/ftl_steps.rb
132
138
  - features/support/env.rb