rig 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,2 +1,37 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+
4
+ task :changelog do
5
+ command="git --no-pager log --format='%an::::%h::::%s'"
6
+
7
+ list = `git tag`
8
+ last = nil
9
+
10
+ puts "# Changelog"
11
+ puts
12
+
13
+ list.lines.reverse_each do |t|
14
+ tag = t.chomp
15
+
16
+ if last
17
+ check = { }
18
+ out = []
19
+ log = `#{command} #{last}...#{tag}`
20
+ log.lines.each do |line|
21
+ (who, hash, msg) = line.split('::::')
22
+ unless check[msg]
23
+ unless msg =~ /^Merge branch/ || msg =~ /^(v|version|changes for|preparing|ready for release|ready to release|bump version)*\s*(v|version)*\d+\.\d+\.\d+/
24
+ out << "#{msg.gsub(" *", "\n*")}"
25
+ check[msg] = hash
26
+ end
27
+ end
28
+ end
29
+ puts "## #{last}:"
30
+ out.each { |e| puts e }
31
+ #puts log
32
+ puts
33
+ end
34
+
35
+ last = tag
36
+ end
37
+ end
@@ -55,6 +55,8 @@ module Rig
55
55
  configure
56
56
  server = ::Scout::Server.first(:name => name)
57
57
  ::Scout::Server.delete(server.id) if server
58
+ rescue => e
59
+ Rig::Log.error "#{self.class} : #{e.message} at #{e.backtrace.first}"
58
60
  end
59
61
 
60
62
  def environment_destroy(name)
@@ -0,0 +1,51 @@
1
+
2
+ template do
3
+ balancer :web do
4
+ primary true
5
+ listener do
6
+ from :https, 443
7
+ to :http, 80
8
+ cert 'arn:aws:iam::101010101010:server-certificate/domain.com'
9
+ end
10
+ listener do
11
+ from :http, 80
12
+ to :http, 80
13
+ end
14
+ end
15
+
16
+ balancer :app do
17
+ listener do
18
+ from :https, 443
19
+ to :http, 80
20
+ cert 'arn:aws:iam::101010101010:server-certificate/domain.com'
21
+ end
22
+ end
23
+
24
+ server :app do
25
+ count 3
26
+ flavor "c1.large"
27
+ balancer :app
28
+ role "app"
29
+ end
30
+
31
+ server :app do
32
+ count 2
33
+ flavor "c1.large"
34
+ balancer :app
35
+ role "app"
36
+ role "scheduler"
37
+ end
38
+
39
+ server :web do
40
+ count 3
41
+ flavor "c1.large"
42
+ balancer :web
43
+ role "web"
44
+ end
45
+
46
+ server :cache do
47
+ count 1
48
+ flavor "m1.large"
49
+ role "cache"
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+
2
+ template do
3
+ balancer :app do
4
+ primary true
5
+ listener do
6
+ from :https, 443
7
+ to :http, 80
8
+ cert 'arn:aws:iam::101010101010:server-certificate/domain.com'
9
+ end
10
+ end
11
+
12
+ server :app do
13
+ count 1
14
+ role :app
15
+ flavor "c1.medium"
16
+ userdata "chef"
17
+ balancer :app
18
+ group 'app-server'
19
+ group 'db-inqcloud-dev'
20
+ end
21
+ end
@@ -27,14 +27,14 @@ gem install <%= gem %> --no-ri --no-rdoc
27
27
 
28
28
  cat <<FACTS > /etc/facts.yml
29
29
  rig_name: <%= @name %>
30
- rig_role: <%= @role %>
30
+ rig_roles: <%= @roles.join(",") %>
31
31
  rig_environment: <%= @environment %>
32
32
  FACTS
33
33
 
34
34
  cat <<JSON > /etc/chef/bootstrap.json
35
35
  {
36
36
  "run_list": [
37
- "role[<%= @role %>]"
37
+ <%= @roles.map {|e| "\"role[#{e}]\""}.join(",") %>
38
38
  ]
39
39
  }
40
40
  JSON
data/lib/rig.rb CHANGED
@@ -4,6 +4,7 @@ require 'fog'
4
4
  require 'rig/version'
5
5
  require 'rig/config'
6
6
  require 'rig/account'
7
+ require 'rig/template'
7
8
  require 'rig/log'
8
9
  require 'rig/plugin'
9
10
  require 'rig/model'
@@ -12,7 +12,7 @@ module Rig
12
12
  env = ENV['ENVIRONMENT'] || Rig.config[:environment]
13
13
  role = ENV['ROLE'] || Rig.config[:role]
14
14
  servers = Rig::Model::Environment.find(env).servers
15
- list = role == 'all' ? servers : servers.select { |s| s.tags['Role'] == role }
15
+ list = role == 'all' ? servers : servers.select { |s| (s.tags['Roles']||"").split(",").include?(role) }
16
16
 
17
17
  raise "Rig could not find any servers matching environment=#{env} and role=#{role}" unless list && list.count > 0
18
18
  list.each do |s|
@@ -17,15 +17,24 @@ module Rig
17
17
 
18
18
  subcommand "userdata", "test userdata" do
19
19
  parameter "NAME", "name of server"
20
- parameter "ROLE", "role of server"
21
20
  parameter "ENVIRONMENT", "environment of server"
21
+ parameter "ROLE ...", "role of server"
22
22
 
23
23
  def execute
24
- userdata = Rig::Model::Userdata.create(name, role, environment)
24
+ userdata = Rig::Model::Userdata.create(name, role_list, environment)
25
25
  puts "USERDATA:\n#{userdata}"
26
26
  end
27
27
  end
28
28
 
29
+ subcommand "template", "test template" do
30
+ parameter "NAME", "name of template"
31
+
32
+ def execute
33
+ t = Rig::Template.load(name)
34
+ ap t
35
+ end
36
+ end
37
+
29
38
  subcommand "init", "initialize configuration directory" do
30
39
  option %w{-f --force}, :flag, "force creation of files", :default => false
31
40
  option %w{-d --directory}, "DIRECTORY", "configuration directory", :default => "~/.rig"
@@ -40,8 +49,8 @@ module Rig
40
49
 
41
50
  accounts/default.yml
42
51
 
43
- templates/solo.yml
44
- templates/multi.yml
52
+ templates/solo.rb
53
+ templates/multi.rb
45
54
 
46
55
  userdata/default/userdata.sh.erb
47
56
  userdata/default/userdata.yml
@@ -27,7 +27,7 @@ module Rig
27
27
  r = []
28
28
  r << server.tags['Name']
29
29
  r << server.tags['Environment']
30
- r << server.tags['Role']
30
+ r << (server.tags['Roles']||server.tags["Role"])
31
31
  r << (server.tags['Protected'] ? 'true' : '')
32
32
  r << server.public_ip_address.to_s
33
33
  if detailed
@@ -37,7 +37,7 @@ module Rig
37
37
  rows = []
38
38
  envs.each do |e|
39
39
  env = Rig::Model::Environment.find(e)
40
- zones = env.servers.collect { |e| e.availability_zone }
40
+ zones = env.servers.collect { |e| e.availability_zone }.uniq.join(",")
41
41
  rows << [env.name, env.template, env.region, env.servers.count, env.balancers.count, env.protected?, zones]
42
42
  end
43
43
  print_table(%w{Name Template Region Servers# Balancers# Protected? AZs}, rows)
@@ -52,7 +52,7 @@ module Rig
52
52
  end
53
53
 
54
54
  def get_template(name)
55
- Rig::Model::Template.load(name)
55
+ Rig::Template.load(name)
56
56
  end
57
57
 
58
58
  end
@@ -49,99 +49,81 @@ module Rig
49
49
 
50
50
  }.merge(opts)
51
51
 
52
- @name = name
52
+ @name = name
53
+ @template = Rig.get_template(template) unless template.nil?
53
54
  @template_name = template
54
- @servers = []
55
- @balancers = []
55
+ @servers = []
56
+ @balancers = []
56
57
  end
57
58
 
58
59
  def save
59
60
  puts "creating instances"
60
-
61
- #@template = TEMPLATES[@template_name]
62
- @template = Rig.get_template(@template_name)
63
- raise "unknown template #{template}" unless @template
64
61
  load_config
62
+ set = { }
63
+
64
+ @template.servers.each do |s|
65
+ 1.upto(s.count) do |i|
66
+ n = "#{s.name}#{i}.#@name.env"
67
+ o = {
68
+ :image_id => s.image || @image,
69
+ :flavor_id => s.flavor || @flavor,
70
+ :key_name => s.keypair || @keypair,
71
+ :groups => s.groups || @groups,
72
+ :user_data => Rig::Model::Userdata.create(n, s.roles, @name)
73
+ }
74
+
75
+ # throw this error, because Fog and AWS don't care if you don't set a keypair
76
+ # but you won't be able to easily connect to it
77
+ raise "No key_name (keypair) set." unless o[:key_name]
78
+
79
+ Rig::Log.debug "creating instance: name:#{n} environment:#@name roles:#{s.roles.inspect}"
80
+ instance = Rig::Model::Instance.create(o, 'Name' => n, 'Environment' => name, 'Roles' => s.roles.join(","))
81
+ set[s.balancer] ||= []
82
+ set[s.balancer] << instance if s.balancer
83
+ @servers << instance
84
+ end
85
+ end
65
86
 
66
- @template[:instances].each do |inst|
67
- setinstances = []
68
- inst.each do |role, tmpl|
69
- count = tmpl[:count] || 1
70
- count.times do |i|
71
- n = "#{role}#{i+1}.#{name}.env"
72
- chef = Rig.config[:chef] ? true : false
73
-
74
- o = {
75
- :image_id => tmpl[:image] || @image,
76
- :flavor_id => tmpl[:flavor] || @flavor,
77
- :key_name => tmpl[:keypair] || @keypair,
78
- :groups => tmpl[:groups] || @template[:groups] || @groups,
79
- :user_data => Rig::Model::Userdata.create(n, role, name, :chef => chef)
80
- }
81
-
82
- # throw this error, because Fog and AWS don't care if you don't set a keypair
83
- # but you won't be able to easily connect to it
84
- raise "No key_name (keypair) set." unless o[:key_name]
85
-
86
- server = Rig::Model::Instance.create(o, 'Name' => n, 'Environment' => name, 'Role' => role)
87
- @servers << server
88
- setinstances << server
89
- end
87
+ @template.balancers.each do |b|
88
+ if set[b.name]
89
+ zones = set[b.name].collect { |e| e.availability_zone }
90
+ balancer = Rig::Model::Balancer.create("#@name-#{b.name}", b.listeners, zones)
91
+ balancer.register_instances(set[b.name].collect { |e| e.id })
92
+ balancer.save
93
+
94
+ @balancers << balancer
90
95
 
91
- if tmpl[:balance]
92
- puts "creating balancer"
93
- zones = setinstances.collect {|e| e.availability_zone }
94
- balancer = Rig::Model::Balancer.create("#{name}-#{role}", tmpl[:listeners], zones)
95
- balancer.register_instances(setinstances.collect { |e| e.id })
96
- balancer.save
97
-
98
- @balancers << balancer
99
-
100
- # set primary dns for environment (<name>.env.inqlabs.com)
101
- # to point to this load balancer
102
- if tmpl[:primary]
103
- puts ".. primary: #{name}.env.#@zone #{balancer.attributes[:dns_name]}"
104
- Rig::Model::Dns.create("#{name}.env.#@zone", balancer.attributes[:dns_name], :ttl => 30)
105
- end
106
- else
107
- #TODO: need to support balancer: false, primary: true = point to server instance
108
- #if tmpl[:primary]
109
- # puts ".. primary #{name}.env.#@zone #{}"
110
- #end
96
+ if b.primary
97
+ Rig::Log.info ".. primary: #{name}.env.#@zone #{balancer.attributes[:dns_name]}"
98
+ Rig::Model::Dns.create("#{name}.env.#@zone", balancer.attributes[:dns_name], :ttl => 30)
111
99
  end
112
100
  end
113
101
  end
114
102
 
115
- # if we've got a chef config, use it
116
- #if Rig.config[:chef]
117
- # puts "creating chef environment"
118
- # Rig::Chef.environment_create(name)
119
- #end
120
-
121
- # all of this crap to be absolutely sure that the instance has an ip and dns
122
- puts "sleeping 3"
103
+ Rig::Log.info "sleeping 3 seconds"
123
104
  sleep 3
124
105
  reload
125
106
 
126
- puts "associating servers' DNS"
107
+
108
+ Rig::Log.info "associating servers' DNS"
127
109
  @servers.each do |server|
128
110
  record = "#{server.tags['Name']}.#{Rig.get_config(:dns_zone)}"
129
111
  dns = server.attributes[:dns_name]
130
112
  ip = server.attributes[:public_ip_address]
131
113
 
132
- puts ".. #{record} dns=#{dns} ip=#{ip}"
114
+ Rig::Log.info ".. #{record} dns=#{dns} ip=#{ip}"
133
115
  if dns
134
116
  Rig::Model::Dns.create(record, dns)
135
117
  else
136
- puts "server #{server.id} doesn't have public_ip_address"
118
+ Rig::Log.info "server #{server.id} doesn't have public_ip_address"
137
119
  end
138
120
  end
139
121
 
140
122
  Rig::Plugin.run "environment:create", self
141
123
  rescue => e
142
- puts "error creating environment:\n#{e.message} at #{e.backtrace.join("\n")}"
124
+ Rig::Log.error "error creating environment:\n#{e.message} at #{e.backtrace.join("\n")}"
143
125
  destroy
144
- raise "error creating environment: #{e.message} at #{e.backtrace.first}"
126
+ Rig::Log.error "error creating environment: #{e.message} at #{e.backtrace.first}"
145
127
  end
146
128
 
147
129
  def destroy
@@ -176,7 +158,7 @@ module Rig
176
158
  def reload
177
159
  find_servers
178
160
  find_balancers
179
- @protected = @servers.any? {|s| s.tags["Protected"] == "true" }
161
+ @protected = @servers.any? { |s| s.tags["Protected"] == "true" }
180
162
  end
181
163
 
182
164
  def protected?
@@ -201,7 +183,7 @@ module Rig
201
183
  @keypair = @options[:keypair] ||
202
184
  Rig.account[:keypair] ||
203
185
  nil
204
- @groups = @options[:groups] ||
186
+ @groups = @options[:groups] ||
205
187
  Rig.account[:groups] ||
206
188
  nil
207
189
  end
@@ -5,14 +5,14 @@ module Rig
5
5
  module Model
6
6
  class Userdata
7
7
  class << self
8
- def create(name, role, environment, opts={ })
8
+ def create(name, roles, environment, opts={ })
9
9
  package = Rig.get_config(:userdata)
10
10
  directory = "#{Rig::Config.dir}/userdata/#{package}"
11
11
  config = YAML.load_file("#{directory}/userdata.yml")
12
12
 
13
13
  data = {
14
14
  :name => name,
15
- :role => role,
15
+ :roles => roles,
16
16
  :environment => environment,
17
17
  :zone => Rig.get_config(:dns_zone),
18
18
  :dependencies => [],
@@ -0,0 +1,170 @@
1
+ module Rig
2
+ module Template
3
+ class << self
4
+ def load(name)
5
+ @templates ||= { }
6
+ template_name = name.to_sym
7
+ template_file = "#{dir}/#{name}.rb"
8
+
9
+ raise "could not load template #{template_name} (#{template_file})" unless File.file?(template_file)
10
+ raise "template already loaded #{template_name}" if @templates[template_name]
11
+
12
+ t = Rig::Template::DSL.new(template_name)
13
+ t.instance_eval(File.read(template_file), "Template(#{template_file})")
14
+ @templates[template_name] = t
15
+ end
16
+
17
+ def load_yaml_file(path)
18
+ file = File.expand_path(path)
19
+ raise "Configuration not found: #{path} (#{file})" unless File.exists?(file)
20
+ yaml = YAML.load_file(file)
21
+ yaml = yaml[yaml.keys.first] if yaml.keys.count == 1
22
+
23
+ yaml
24
+ end
25
+
26
+ def list
27
+ Dir["#{dir}/*"].inject({ }) do |h, e|
28
+ f = e.gsub("#{dir}/", "")
29
+ f = File.basename(f, ".yml")
30
+ h[f.to_sym] = e
31
+ h
32
+ end
33
+ end
34
+
35
+ private
36
+ def dir
37
+ "#{Rig::Config.dir}/templates"
38
+ end
39
+ end
40
+
41
+ class DSL
42
+ attr_reader :balancers, :servers
43
+
44
+ def initialize(name)
45
+ @name = name.to_sym
46
+ @balancers = []
47
+ @servers = []
48
+ end
49
+
50
+ def template(&block)
51
+ instance_eval &block
52
+ end
53
+
54
+ def balancer(name, &block)
55
+ balancer = Balancer.new(name)
56
+ balancer.instance_eval &block
57
+ @balancers << balancer
58
+ end
59
+
60
+ def server(name, &block)
61
+ server = Server.new(name)
62
+ server.instance_eval &block
63
+ @servers << server
64
+ end
65
+ end
66
+
67
+ class Server
68
+ attr_reader :name, :roles, :groups
69
+
70
+ def initialize(name)
71
+ @name = name.to_sym
72
+ @roles = []
73
+ @groups = []
74
+ @count = 1
75
+ @image = nil
76
+ @flavor = nil
77
+ @keypair = nil
78
+ @userdata = "default"
79
+ end
80
+
81
+ def role(r)
82
+ @roles << r
83
+ end
84
+
85
+ def count(c=nil)
86
+ c.nil? ? @count : @count = c
87
+ end
88
+
89
+ def image(i=nil)
90
+ i.nil? ? @image : @image = i
91
+ end
92
+
93
+ def flavor(f=nil)
94
+ f.nil? ? @flavor : @flavor = f
95
+ end
96
+
97
+ def group(g)
98
+ @groups << g
99
+ end
100
+
101
+ def keypair(k=nil)
102
+ k.nil? ? @keypair : @keypair = k
103
+ end
104
+
105
+ def userdata(u=nil)
106
+ u.nil? ? @userdata : @userdata = u.to_sym
107
+ end
108
+
109
+ def balancer(b=nil)
110
+ b.nil? ? @balancer : @balancer = b.to_sym
111
+ end
112
+ end
113
+
114
+ class Balancer
115
+ attr_reader :name
116
+
117
+ def initialize(name)
118
+ @listeners = []
119
+ @name = name.to_sym
120
+ @primary = false
121
+ end
122
+
123
+ def primary(enable = nil)
124
+ enable.nil? ? @primary : @primary = enable
125
+ end
126
+
127
+ def listener(&block)
128
+ listener = Listener.new
129
+ listener.instance_eval &block
130
+ @listeners << listener
131
+ end
132
+
133
+ def listeners
134
+ @listeners.map {|e| e.spec}
135
+ end
136
+ end
137
+
138
+ class Listener
139
+ def initialize
140
+ @from_proto = nil
141
+ @from_port = nil
142
+ @to_proto = nil
143
+ @to_port = nil
144
+ @cert = nil
145
+ end
146
+
147
+ def from(proto, port)
148
+ @from_proto = proto
149
+ @from_port = port
150
+ end
151
+
152
+ def to(proto, port)
153
+ @to_proto = proto
154
+ @to_port = port
155
+ end
156
+
157
+ def cert(cert)
158
+ @cert = cert
159
+ end
160
+
161
+ def spec
162
+ {
163
+ :from => "#@from_proto:#@from_port",
164
+ :to => "#@to_proto:#@to_port",
165
+ :cert => @cert,
166
+ }
167
+ end
168
+ end
169
+ end
170
+ end
@@ -2,8 +2,8 @@ unless defined?(Rig::Version)
2
2
  module Rig
3
3
  module Version
4
4
  MAJOR = 0
5
- MINOR = 5
6
- TINY = 2
5
+ MINOR = 6
6
+ TINY = 0
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rig
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-19 00:00:00.000000000 Z
12
+ date: 2012-06-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -128,8 +128,8 @@ files:
128
128
  - conf/plugins/mongo.rb
129
129
  - conf/plugins/mysql.rb
130
130
  - conf/plugins/scout.rb
131
- - conf/templates/multi.yml
132
- - conf/templates/solo.yml
131
+ - conf/templates/multi.rb
132
+ - conf/templates/solo.rb
133
133
  - conf/userdata/chef/userdata.sh.erb
134
134
  - conf/userdata/chef/userdata.yml
135
135
  - conf/userdata/chef/validation.pem
@@ -158,9 +158,9 @@ files:
158
158
  - lib/rig/model/dns.rb
159
159
  - lib/rig/model/environment.rb
160
160
  - lib/rig/model/instance.rb
161
- - lib/rig/model/template.rb
162
161
  - lib/rig/model/userdata.rb
163
162
  - lib/rig/plugin.rb
163
+ - lib/rig/template.rb
164
164
  - lib/rig/version.rb
165
165
  - rig.gemspec
166
166
  homepage: https://github.com/shawncatz/rig
@@ -1,26 +0,0 @@
1
- ---
2
- :instances:
3
- - :memcache:
4
- :count: 1
5
- :flavor: m1.large
6
- :appserver:
7
- :count: 3
8
- :flavor: c1.large
9
- :balance: true
10
- :listeners:
11
- - :from: HTTP:80
12
- :to: HTTP:80
13
- - :from: HTTPS:443
14
- :to: HTTP:80
15
- :cert: arn:cert:name
16
- :webserver:
17
- :count: 3
18
- :flavor: c1.large
19
- :balance: true
20
- :listeners:
21
- - :from: HTTP:80
22
- :to: HTTP:80
23
- - :from: HTTPS:443
24
- :to: HTTP:80
25
- :cert: arn:cert:name
26
- :primary: true
@@ -1,13 +0,0 @@
1
- ---
2
- :instances:
3
- - :appserver:
4
- :count: 1
5
- :flavor: c1.medium
6
- :balance: true
7
- :primary: true
8
- :listeners:
9
- - :from: HTTP:80
10
- :to: HTTP:80
11
- - :from: HTTPS:443
12
- :to: HTTP:80
13
- :cert: arn:cert:name
@@ -1,34 +0,0 @@
1
- module Rig
2
- module Model
3
- class Template
4
- class << self
5
- def load(name)
6
- self.load_yaml_file("#{dir}/#{name}.yml")
7
- end
8
-
9
- def load_yaml_file(path)
10
- file = File.expand_path(path)
11
- raise "Configuration not found: #{path} (#{file})" unless File.exists?(file)
12
- yaml = YAML.load_file(file)
13
- yaml = yaml[yaml.keys.first] if yaml.keys.count == 1
14
-
15
- yaml
16
- end
17
-
18
- def list
19
- Dir["#{dir}/*"].inject({ }) do |h, e|
20
- f = e.gsub("#{dir}/", "")
21
- f = File.basename(f, ".yml")
22
- h[f.to_sym] = e
23
- h
24
- end
25
- end
26
-
27
- private
28
- def dir
29
- "#{Rig::Config.dir}/templates"
30
- end
31
- end
32
- end
33
- end
34
- end