hawser 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/lib/hawser.rb +4 -0
- data/lib/hawser/baking-command.rb +85 -0
- data/lib/hawser/baking.rb +85 -0
- data/lib/hawser/cluster.rb +63 -0
- data/lib/hawser/credentialing.rb +208 -0
- data/lib/hawser/servers.rb +36 -0
- data/spec/hawser_spec.rb +10 -0
- metadata +29 -13
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MzNhN2RlMTZiMDFhYzE2YjI5ZDdlMDRiZTg4NDdlN2FlY2E0NDdkNQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZWExZDdlZTAyOTMzZGUxNTIwNTY0ZmMyNDliZjAzMmI2YmQ0ZmM3MA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTc2YWJlYzllZGMxMjJjMmE1ZTcxZjg5YmI4MGY1ODljNmRkYTk0Y2Q3Yjkz
|
10
|
+
ZTFlOWVjZTJiMjZhMzE0MTVmNDhkMWJkODUwZWRmZjU3ODM2ODBjZjNmMDgz
|
11
|
+
MjJmYWFhMTFjZTcxNDQ4MWQ4YWJhNDRhMjJmNjk1MTBjZmM0Yjg=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NTNlNmUzOTg1YWY4MGNjNjk1MWRiNDBjZWRkY2E5OGFhNmMwODQ5MWRmY2Mw
|
14
|
+
NzI4ZjA0ZDkxMmIzZTMyZGY4OThkOTZiYTRjZDM3ZGIyMzdhNjg1MGE5ODhl
|
15
|
+
NGVhOTk2MmM1NmJkMGIyODYwMDBjZGVjOTUzOWIyMmYwMDJkZGY=
|
data/lib/hawser.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'mattock'
|
2
|
+
|
3
|
+
module Hawser
|
4
|
+
class BakingCommand < Mattock::Rake::RemoteCommandTask
|
5
|
+
setting :arch, "x86_64"
|
6
|
+
setting :ec2_version_pattern, "1.4.0.5 20071010"
|
7
|
+
|
8
|
+
setting :absolute_path, "/"
|
9
|
+
|
10
|
+
setting :region, "us-west-1"
|
11
|
+
|
12
|
+
dir(:ephemeral_dir, "mnt",
|
13
|
+
dir(:keyfile_dir, "keys",
|
14
|
+
path(:private_key, "pk.pem"),
|
15
|
+
path(:certificate_file, "cert.pem")))
|
16
|
+
|
17
|
+
runtime_setting :image_name
|
18
|
+
runtime_setting :prefix
|
19
|
+
|
20
|
+
runtime_setting :bucket
|
21
|
+
runtime_setting :access_key
|
22
|
+
runtime_setting :secret_key
|
23
|
+
runtime_setting :aws_account_id
|
24
|
+
|
25
|
+
runtime_setting :manifest_name
|
26
|
+
runtime_setting :manifest_path
|
27
|
+
|
28
|
+
def resolve_configuration
|
29
|
+
super
|
30
|
+
|
31
|
+
resolve_paths
|
32
|
+
end
|
33
|
+
|
34
|
+
def resolve_runtime_configuration
|
35
|
+
if field_unset?(:prefix)
|
36
|
+
self.prefix = image_name
|
37
|
+
end
|
38
|
+
|
39
|
+
if field_unset?(:manifest_name)
|
40
|
+
self.manifest_name = "#{prefix}.manifest.xml"
|
41
|
+
end
|
42
|
+
|
43
|
+
if field_unset?(:manifest_path)
|
44
|
+
self.manifest_path = File::join(ephemeral_dir.abspath, manifest_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def command
|
51
|
+
cmd("(ec2-bundle-vol --version | grep \"#{ec2_version_pattern}\")") &
|
52
|
+
(cmd("rm") {|rm|
|
53
|
+
rm.options = ["-f", File::join(ephemeral_dir.abspath, prefix || "no-such-file") ]
|
54
|
+
}) &
|
55
|
+
(cmd("ec2-bundle-vol") { |bundle|
|
56
|
+
bundle.options += ["-k", private_key.abspath ]
|
57
|
+
bundle.options += ["-c", certificate_file.abspath ]
|
58
|
+
bundle.options += ["--user", aws_account_id ]
|
59
|
+
|
60
|
+
bundle.options += ["--destination", ephemeral_dir.abspath ]
|
61
|
+
bundle.options += ["--prefix", prefix ]
|
62
|
+
bundle.options += ["--arch", arch ]
|
63
|
+
bundle.options += %w{-i /etc/ec2/amitools/cert-ec2.pem}
|
64
|
+
bundle.options += ["-i", '$(ls /etc/ssl/certs/*.pem | tr \\\\n ,)']
|
65
|
+
bundle.options += %w{--ec2cert /etc/ec2/amitools/cert-ec2.pem}
|
66
|
+
bundle.options += ["-e", keyfile_dir.abspath]
|
67
|
+
}) &
|
68
|
+
(cmd("ec2-upload-bundle") {|upload|
|
69
|
+
upload.options += ["-b", bucket ]
|
70
|
+
upload.options += ["-m", manifest_path]
|
71
|
+
upload.options += ["-a", access_key ]
|
72
|
+
upload.options += ["-s", secret_key ]
|
73
|
+
upload.options += ["--location", region ]
|
74
|
+
upload.options += ["--retry"]
|
75
|
+
}) &
|
76
|
+
(cmd("ec2-register") {|register|
|
77
|
+
register.options << "#{bucket}/#{manifest_name}"
|
78
|
+
register.options += ["-n", image_name]
|
79
|
+
register.options += ["--region", region]
|
80
|
+
register.options += ["--aws-access-key", access_key]
|
81
|
+
register.options += ["--aws-secret-key", secret_key]
|
82
|
+
})
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'mattock'
|
2
|
+
require 'hawser/baking-command'
|
3
|
+
|
4
|
+
module Hawser
|
5
|
+
class Baking < Mattock::Tasklib
|
6
|
+
include Caliph::CommandLineDSL
|
7
|
+
|
8
|
+
default_namespace :baking
|
9
|
+
|
10
|
+
setting :location, "us-west-1"
|
11
|
+
|
12
|
+
setting :arch, "x86_64"
|
13
|
+
setting :ec2_version_pattern, "1.4.0.5 20071010"
|
14
|
+
|
15
|
+
dir(:ephemeral_dir, "/mnt",
|
16
|
+
dir(:keyfile_dir, "keys",
|
17
|
+
path(:private_key, "pk.pem"),
|
18
|
+
path(:certificate_file, "cert.pem")))
|
19
|
+
|
20
|
+
path(:signing_cert, "cert.pem")
|
21
|
+
path(:signing_key, "key.pem")
|
22
|
+
|
23
|
+
setting(:image_name).isnt(:required)
|
24
|
+
setting(:bucket)
|
25
|
+
|
26
|
+
setting :access_key
|
27
|
+
setting :secret_key
|
28
|
+
setting :aws_account_id
|
29
|
+
|
30
|
+
setting(:remote_server, nested{
|
31
|
+
setting(:address).isnt(:required)
|
32
|
+
setting :port, 22
|
33
|
+
setting :user, nil
|
34
|
+
})
|
35
|
+
|
36
|
+
def resolve_configuration
|
37
|
+
ephemeral_dir.absolute_path = ephemeral_dir.relative_path
|
38
|
+
|
39
|
+
super
|
40
|
+
resolve_paths
|
41
|
+
end
|
42
|
+
|
43
|
+
def define
|
44
|
+
in_namespace do
|
45
|
+
Mattock::Rake::RemoteCommandTask.define_task(:create_dirs => :collect) do |task|
|
46
|
+
task.remote_server = proxy_value.remote_server
|
47
|
+
task.command = cmd("mkdir") do |mkdir|
|
48
|
+
mkdir.options << "-p" #ok
|
49
|
+
mkdir.options << keyfile_dir.abspath
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Mattock::Rake::CommandTask.define_task(:copy_cert => [:collect, :create_dirs]) do |task|
|
54
|
+
task.runtime_definition do |task|
|
55
|
+
task.command = cmd("scp") do |scp|
|
56
|
+
scp.options << signing_cert.abspath
|
57
|
+
scp.options << "#{remote_server.address}:#{certificate_file.abspath}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Mattock::Rake::CommandTask.define_task(:copy_key => [:collect, :create_dirs]) do |task|
|
63
|
+
task.runtime_definition do |task|
|
64
|
+
task.command = cmd("scp") do |scp|
|
65
|
+
scp.options << signing_key.abspath
|
66
|
+
scp.options << "#{remote_server.address}:#{private_key.abspath}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
task :collect, [:target, :name] do |task, args|
|
72
|
+
self.remote_server.address = args[:target]
|
73
|
+
self.image_name = args[:name]
|
74
|
+
end
|
75
|
+
|
76
|
+
BakingCommand.define_task(:bake, [:target, :name] => [:collect, :copy_cert, :copy_key]) do |task|
|
77
|
+
self.copy_settings_to(task)
|
78
|
+
proxied = self.proxy_settings
|
79
|
+
proxied.field_names = [:remote_server, :image_name, :bucket]
|
80
|
+
proxied.to(task)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'mattock'
|
2
|
+
require 'hawser/credentialing'
|
3
|
+
require 'hawser/baking'
|
4
|
+
require 'hawser/servers'
|
5
|
+
|
6
|
+
module Hawser
|
7
|
+
# Represents a cluster of servers on AWS
|
8
|
+
#
|
9
|
+
# @example in Rakefile
|
10
|
+
# Hawser::Cluster.new do |bollard|
|
11
|
+
# bollard.name = "bollard"
|
12
|
+
# bollard.user = "ahab"
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# @example at console
|
16
|
+
# > rake bollard:servers:list
|
17
|
+
# > rake bollard:bake[app1.bollard.com,app1-number1]
|
18
|
+
#
|
19
|
+
class Cluster < Mattock::Tasklib
|
20
|
+
setting :name
|
21
|
+
setting :user
|
22
|
+
setting :bucket
|
23
|
+
|
24
|
+
def resolve_configuration
|
25
|
+
@namespace ||= name.downcase
|
26
|
+
self.bucket ||= "#{name.downcase}-amis"
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def define
|
31
|
+
in_namespace do
|
32
|
+
creds = Hawser::Credentialing.new do |creds|
|
33
|
+
copy_settings_to(creds)
|
34
|
+
creds.cluster_name = name
|
35
|
+
end
|
36
|
+
|
37
|
+
Hawser::Baking.new do |bake|
|
38
|
+
copy_settings_to(bake)
|
39
|
+
creds.copy_settings_to(bake)
|
40
|
+
creds.credentials.proxy_settings_to(bake)
|
41
|
+
end
|
42
|
+
|
43
|
+
Hawser::Servers.new do |servers|
|
44
|
+
copy_settings_to(servers)
|
45
|
+
servers.cluster_name = name
|
46
|
+
creds.copy_settings_to(servers)
|
47
|
+
creds.credentials.proxy_settings_to(servers)
|
48
|
+
end
|
49
|
+
|
50
|
+
namespace :baking do
|
51
|
+
task :bake => "credentials:establish"
|
52
|
+
end
|
53
|
+
|
54
|
+
namespace :servers do
|
55
|
+
task :list => "credentials:establish"
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Make an AMI copy of the running instance at :target. Name the AMI :name and store it in :bucket"
|
59
|
+
task :bake, [:target, :name] => "baking:bake"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'mattock'
|
2
|
+
require 'aws-sdk'
|
3
|
+
|
4
|
+
module Hawser
|
5
|
+
class Credentialing < Mattock::TaskLib
|
6
|
+
default_namespace :credentials
|
7
|
+
|
8
|
+
setting :user
|
9
|
+
setting :cluster_name
|
10
|
+
|
11
|
+
setting :credentials, nested{
|
12
|
+
nil_fields :access_key, :secret_key, :certificate_id, :password, :aws_account_id
|
13
|
+
setting :mfa, true
|
14
|
+
}
|
15
|
+
|
16
|
+
setting :key_size, 4096
|
17
|
+
|
18
|
+
setting :cert, nested{
|
19
|
+
setting :lifetime, nested{
|
20
|
+
setting :years, 1
|
21
|
+
setting :days, 0
|
22
|
+
setting :hours, 0
|
23
|
+
setting :minutes, 0
|
24
|
+
setting :seconds, 0
|
25
|
+
setting :total_seconds
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
setting :iam, nil
|
30
|
+
setting :iam_user, nil
|
31
|
+
|
32
|
+
dir(:creds_root, "credentials",
|
33
|
+
dir(:cluster_dir,
|
34
|
+
dir(:user_dir,
|
35
|
+
path(:creds_csv, "creds.csv"),
|
36
|
+
path(:config_yaml, "config.yaml"),
|
37
|
+
path(:signing_cert, "cert.pem"),
|
38
|
+
path(:signing_key, "key.pem"))))
|
39
|
+
|
40
|
+
def resolve_configuration
|
41
|
+
cluster_dir.relative_path = cluster_name
|
42
|
+
user_dir.relative_path = user
|
43
|
+
|
44
|
+
cert.lifetime.total_seconds =
|
45
|
+
cert.lifetime.seconds + 60 * (
|
46
|
+
cert.lifetime.minutes + 60 * (
|
47
|
+
cert.lifetime.hours + 24 * (
|
48
|
+
cert.lifetime.days + 365 * cert.lifetime.years)))
|
49
|
+
|
50
|
+
super
|
51
|
+
|
52
|
+
resolve_paths
|
53
|
+
end
|
54
|
+
|
55
|
+
def signing_key_content
|
56
|
+
require 'openssl'
|
57
|
+
if key_size <= 1024
|
58
|
+
raise "Refusing to create an insecure RSA key"
|
59
|
+
end
|
60
|
+
|
61
|
+
#XXX Consider using a passphrase here - although #managment for baking
|
62
|
+
#etc...
|
63
|
+
key = OpenSSL::PKey::RSA.generate(key_size)
|
64
|
+
|
65
|
+
key.to_pem
|
66
|
+
end
|
67
|
+
|
68
|
+
def signing_cert_content(key_string)
|
69
|
+
require 'openssl'
|
70
|
+
|
71
|
+
key = OpenSSL::PKey.read(key_string)
|
72
|
+
|
73
|
+
cert = OpenSSL::X509::Certificate.new
|
74
|
+
cert.version = 2
|
75
|
+
cert.serial = 2
|
76
|
+
cert.public_key = key.public_key
|
77
|
+
cert.not_before = Time.now
|
78
|
+
cert.not_after = cert.not_before + self.cert.lifetime.total_seconds
|
79
|
+
|
80
|
+
File.open(task.name, "w") do |pem_file|
|
81
|
+
pem_file.write(cert.to_pem)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def load_from_yaml(string)
|
86
|
+
require 'yaml'
|
87
|
+
config = YAML::load(string)
|
88
|
+
|
89
|
+
credentials.aws_account_id = config["aws_account_id"] if config.has_key? "aws_account_id"
|
90
|
+
credentials.access_key = config["access_key"] if config.has_key? "access_key"
|
91
|
+
credentials.secret_key = config["secret_key"] if config.has_key? "secret_key"
|
92
|
+
credentials.password = config["password"] if config.has_key? "password"
|
93
|
+
credentials.certificate_id = config["certificate_id"] if config.has_key? "certificate_id"
|
94
|
+
credentials.mfa = config["mfa"] if config.has_key? "mfa"
|
95
|
+
end
|
96
|
+
|
97
|
+
def load_from_csv(string)
|
98
|
+
require 'csv'
|
99
|
+
|
100
|
+
rows = CSV.new(string).to_a
|
101
|
+
|
102
|
+
rows.shift #headers
|
103
|
+
row = rows.find do |name, key, secret|
|
104
|
+
name =~ /^#{user}$/i
|
105
|
+
end
|
106
|
+
if row.nil?
|
107
|
+
fail "Couldn't find Access credentials line for #{user.inspect} in #{rows.map{|name, _,_| name}.inspect}"
|
108
|
+
end
|
109
|
+
|
110
|
+
_, key, secret = *row
|
111
|
+
|
112
|
+
credentials.access_key = key
|
113
|
+
credentials.secret_key = secret
|
114
|
+
end
|
115
|
+
|
116
|
+
def find_cert_id(cert_body)
|
117
|
+
remote_cert = iam_user.signing_certificates.find do |certificate|
|
118
|
+
certificate.contents == cert_body
|
119
|
+
end
|
120
|
+
|
121
|
+
unless remote_cert.nil?
|
122
|
+
credentials.certificate_id = remote_cert.id
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def define
|
127
|
+
in_namespace do
|
128
|
+
directory user_dir.abspath
|
129
|
+
|
130
|
+
file signing_cert.abspath => signing_key.abspath do |task|
|
131
|
+
key = File::read(signing_key.abspath)
|
132
|
+
File.write(task.name, signing_cert_content(key))
|
133
|
+
end
|
134
|
+
|
135
|
+
file signing_key.abspath do |task|
|
136
|
+
File.write(task.name, signing_key_content)
|
137
|
+
end
|
138
|
+
|
139
|
+
task :load do
|
140
|
+
if File::exists?(config_yaml.abspath)
|
141
|
+
load_from_yaml(File::read(config_yaml.abspath))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
task :store do
|
146
|
+
require 'yaml'
|
147
|
+
|
148
|
+
File::open(config_yaml.abspath, "w") do |config|
|
149
|
+
config.write YAML.dump(Hash[credentials.to_hash.map do |key,value|
|
150
|
+
[key.to_s, value]
|
151
|
+
end])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
task :iam => "get:access" do
|
156
|
+
self.iam = AWS::IAM.new(:access_key_id => credentials.access_key, :secret_access_key => credentials.secret_key)
|
157
|
+
end
|
158
|
+
|
159
|
+
task :iam_user => :iam do
|
160
|
+
self.iam_user = iam.users[user]
|
161
|
+
end
|
162
|
+
|
163
|
+
namespace :get do
|
164
|
+
task :access => :load do
|
165
|
+
if credentials.access_key.nil? or not credentials.secret_key.nil?
|
166
|
+
load_from_csv(File.read(creds_csv.abspath))
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
task :aws_account_id => :iam do
|
171
|
+
credentials.aws_account_id = iam.users.first.arn.split(":")[4]
|
172
|
+
end
|
173
|
+
|
174
|
+
task :certificate_id => [:iam_user, signing_cert.abspath] do
|
175
|
+
if credentials.certificate_id.nil?
|
176
|
+
find_cert_id(File::read(signing_cert.abspath))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
task :get => %w{get:access get:certificate_id get:aws_account_id}
|
181
|
+
|
182
|
+
namespace :set do
|
183
|
+
task :password => :iam_user do
|
184
|
+
unless credentials.password.nil?
|
185
|
+
iam_user.login_policy.password = credentials.password
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
task :certificate => [:iam_user, signing_cert.abspath, "get:certificate_id"] do
|
190
|
+
if !credentials.certificate_id.nil?
|
191
|
+
begin
|
192
|
+
iam_user.signing_certificates[credentials.certificate_id].contents
|
193
|
+
next
|
194
|
+
rescue AWS::Core::Resource::NotFound
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
cert = iam_user.signing_certificates.upload(File::read(signing_cert.abspath))
|
199
|
+
credentials.certificate_id = cert.id
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
desc "Set up credentials for #{user} on cluster_name #{cluster_name}"
|
204
|
+
task :establish => %w{get set:certificate store}
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "mattock"
|
2
|
+
require 'aws-sdk'
|
3
|
+
|
4
|
+
module Hawser
|
5
|
+
class Servers < Mattock::Tasklib
|
6
|
+
default_namespace :servers
|
7
|
+
|
8
|
+
setting :cluster_name
|
9
|
+
setting :access_key
|
10
|
+
setting :secret_key
|
11
|
+
setting :region, "us-west-1"
|
12
|
+
|
13
|
+
def define
|
14
|
+
in_namespace do
|
15
|
+
task :list do
|
16
|
+
require 'yaml'
|
17
|
+
ec2 = AWS::EC2.new(:region => region, :access_key_id => access_key, :secret_access_key => secret_key)
|
18
|
+
puts(YAML::dump( ec2.instances.map do |instance|
|
19
|
+
{ "cluster_name" => cluster_name,
|
20
|
+
"platform" => "aws",
|
21
|
+
"id_from_platform" => instance.instance_id,
|
22
|
+
"private_dns_name" => instance.public_dns_name,
|
23
|
+
"public_dns_name" => instance.public_dns_name,
|
24
|
+
"private_ip_address" => instance.private_ip_address,
|
25
|
+
"public_ip_address" => instance.public_ip_address,
|
26
|
+
"architecture" => instance.architecture.to_s,
|
27
|
+
"availability_zone" => instance.placement[:availability_zone],
|
28
|
+
"launch_time" => instance.launch_time,
|
29
|
+
"image_id" => instance.image_id,
|
30
|
+
"key_name" => instance.key_name }
|
31
|
+
end))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/spec/hawser_spec.rb
ADDED
metadata
CHANGED
@@ -1,32 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hawser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.0.1
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Judson Lester
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-08-22 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ! '>'
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
|
-
none: false
|
21
|
-
name: aws-sdk
|
22
20
|
type: :runtime
|
23
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: mattock
|
24
29
|
requirement: !ruby/object:Gem::Requirement
|
25
30
|
requirements:
|
26
31
|
- - ! '>'
|
27
32
|
- !ruby/object:Gem::Version
|
28
33
|
version: '0'
|
29
|
-
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>'
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
30
41
|
description: ! ' A toolbelt of utilities for doing stuff with AWS
|
31
42
|
|
32
43
|
'
|
@@ -36,17 +47,25 @@ executables: []
|
|
36
47
|
extensions: []
|
37
48
|
extra_rdoc_files: []
|
38
49
|
files:
|
50
|
+
- lib/hawser.rb
|
51
|
+
- lib/hawser/cluster.rb
|
52
|
+
- lib/hawser/credentialing.rb
|
53
|
+
- lib/hawser/servers.rb
|
54
|
+
- lib/hawser/baking-command.rb
|
55
|
+
- lib/hawser/baking.rb
|
56
|
+
- spec/hawser_spec.rb
|
39
57
|
- spec_help/gem_test_suite.rb
|
40
58
|
homepage: http://nyarly.github.com/hawser
|
41
59
|
licenses:
|
42
60
|
- MIT
|
61
|
+
metadata: {}
|
43
62
|
post_install_message:
|
44
63
|
rdoc_options:
|
45
64
|
- --inline-source
|
46
65
|
- --main
|
47
66
|
- doc/README
|
48
67
|
- --title
|
49
|
-
- hawser-0.0
|
68
|
+
- hawser-0.1.0 Documentation
|
50
69
|
require_paths:
|
51
70
|
- lib/
|
52
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -54,19 +73,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
54
73
|
- - ! '>='
|
55
74
|
- !ruby/object:Gem::Version
|
56
75
|
version: '0'
|
57
|
-
none: false
|
58
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
77
|
requirements:
|
60
78
|
- - ! '>='
|
61
79
|
- !ruby/object:Gem::Version
|
62
80
|
version: '0'
|
63
|
-
none: false
|
64
81
|
requirements: []
|
65
82
|
rubyforge_project: hawser
|
66
|
-
rubygems_version:
|
83
|
+
rubygems_version: 2.0.14
|
67
84
|
signing_key:
|
68
|
-
specification_version:
|
85
|
+
specification_version: 4
|
69
86
|
summary: AWS tools for towing your servers around
|
70
87
|
test_files:
|
71
88
|
- spec_help/gem_test_suite.rb
|
72
|
-
has_rdoc: true
|