rig 0.5.2 → 0.6.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.
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