veronic 0.0.21 → 0.0.22

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/bin/veronic CHANGED
@@ -18,6 +18,7 @@ opt_parser = OptionParser.new do |opt|
18
18
  opt.separator " bootstrap: bootstrap box"
19
19
  opt.separator " destroy: destroy box"
20
20
  opt.separator " deploy: deploy box"
21
+ opt.separator " search_and_deploy: search & deploy box"
21
22
  opt.separator " deploy_stacks: deploy stacks on box"
22
23
  opt.separator " deploy_apps: destroy apps on box"
23
24
  opt.separator " run_tests: tests apps on box"
@@ -95,6 +96,11 @@ opt_parser = OptionParser.new do |opt|
95
96
  options[:deploy_cmd] = dc
96
97
  end
97
98
 
99
+ options[:query] = ENV['query']
100
+ opt.on("-q","--query query-line","Which query line us to deploy the boxes") do |q|
101
+ options[:query] = q
102
+ end
103
+
98
104
  options[:verbose] = ENV['verbose']
99
105
  opt.on("-v","--verbose debug","Which verbose level us to deploy the box") do |v|
100
106
  options[:verbose] = v
@@ -114,6 +120,8 @@ when "destroy"
114
120
  Veronic::Deployer.new(options).destroy
115
121
  when "deploy"
116
122
  Veronic::Deployer.new(options).deploy
123
+ when "search_and_deploy"
124
+ Veronic::Deployer.new(options).search_and_deploy
117
125
  when "deploy_stacks"
118
126
  Veronic::Deployer.new(options).deploy_stacks
119
127
  when "deploy_apps"
data/lib/config/config.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Veronic
2
2
  class Config
3
- attr_accessor :dnsprovider, :cloudprovider, :configprovider, :dnsprovider_access_key_id, :dnsprovider_secret_access_key, :cloudprovider_access_key_id, :cloudprovider_secret_access_key, :cloudprovider_images_owner_id, :dnsprovider_zones, :region, :availability_zone, :aws_ssh_key_id, :node_name, :client_key, :validation_client_name, :validation_key, :chef_server_url, :ssl_version, :identity_file, :branch, :environment, :ssh_user, :ssh_port, :role, :flavor, :security_groups, :deploy_cmd, :name, :image, :zone_name, :zone_url, :verbose
3
+ attr_accessor :dnsprovider, :cloudprovider, :configprovider, :dnsprovider_access_key_id, :dnsprovider_secret_access_key, :cloudprovider_access_key_id, :cloudprovider_secret_access_key, :cloudprovider_images_owner_id, :dnsprovider_zones, :region, :availability_zone, :aws_ssh_key_id, :node_name, :client_key, :validation_client_name, :validation_key, :chef_server_url, :ssl_version, :identity_file, :branch, :environment, :ssh_user, :ssh_port, :role, :flavor, :security_groups, :deploy_cmd, :name, :image, :zone_name, :zone_url, :verbose, :query
4
4
 
5
5
  def initialize(options={})
6
6
  config_file = File.exists?('/etc/veronic/veronic.yml') ? '/etc/veronic/veronic.yml' : '../../' + File.dirname($0) + '/veronic.yml'
@@ -36,6 +36,7 @@ module Veronic
36
36
  @name = (options[:branch] || config_from_file['branch']) ? (options[:branch] || config_from_file['branch']) : (options[:name] || config_from_file['name'])
37
37
  @image = options[:ami_image] || config_from_file['ami_image']
38
38
  @verbose = options[:verbose] || config_from_file['verbose']
39
+ @query = options[:query] || config_from_file['query']
39
40
  end
40
41
 
41
42
  def to_hash
@@ -13,6 +13,7 @@ module Provider
13
13
  @identity_file = config[:identity_file]
14
14
  @aws_ssh_key_id = config[:aws_ssh_key_id]
15
15
  @environment = config[:environment]
16
+ @role = config[:role]
16
17
  @roles = "role[#{config[:role]}]"
17
18
  @flavor = config[:flavor]
18
19
  @region = config[:region]
@@ -105,10 +106,10 @@ module Provider
105
106
  def set_environment
106
107
  node = Chef::Node.new.tap do |n|
107
108
  n.name( @name )
108
- n.chef_environment( @environment )
109
- end
110
- node.save
111
- puts "Environment: #{@environment}"
109
+ n.chef_environment( @environment )
110
+ end
111
+ node.save
112
+ puts "Environment: #{@environment}"
112
113
  end
113
114
 
114
115
  def ssh(query, cmd_line, manual)
@@ -118,6 +119,15 @@ module Provider
118
119
  knife_ssh.config[:ssh_user] = @ssh_user
119
120
  knife_ssh.config[:identity_file] = @identity_file
120
121
  knife_ssh.config[:log_level] = @verbose
122
+
123
+ unless manual
124
+ if @environment
125
+ query += "#{query.empty? ? '' : ' AND'} chef_environment:#{@environment}"
126
+ end
127
+ if @role
128
+ query += "#{query.empty? ? '' : ' AND'} role:#{@role}"
129
+ end
130
+ end
121
131
 
122
132
  knife_ssh.name_args = [query, cmd_line]
123
133
  sys_status = knife_ssh.run
@@ -129,7 +139,7 @@ module Provider
129
139
 
130
140
  def delete_client_key(node, client_key="/etc/chef/client.pem")
131
141
  puts "Deleting client_key #{client_key}"
132
- self.ssh(node, "sudo chef-client -W ; sudo rm -f #{client_key}", true)
142
+ self.ssh(node, "sudo chef-client -W > /dev/null ; sudo rm -f #{client_key}", true)
133
143
  end
134
144
  end
135
145
  end
@@ -13,8 +13,8 @@ class CloudProvider
13
13
  CLOUDPROVIDERS[@config[:cloudprovider]].new(@config)
14
14
  end
15
15
 
16
- def image(name=nil)
17
- @provider.image(name)
16
+ def image
17
+ @provider.image
18
18
  end
19
19
 
20
20
  def instance
@@ -25,6 +25,10 @@ class CloudProvider
25
25
  @provider.instances
26
26
  end
27
27
 
28
+ def regions
29
+ @provider.regions
30
+ end
31
+
28
32
  def instances_list
29
33
  printf "%17s %35s %34s\n", 'NAME', 'DNS', 'STATUS'
30
34
  @provider.instances.each do |instance|
@@ -8,19 +8,20 @@ module Provider
8
8
  def initialize(config)
9
9
  @name = config[:name]
10
10
  @region = config[:region]
11
- @environment = config[:environment]
11
+ @role = config[:role]
12
12
  @access_key_id = config[:cloudprovider_access_key_id]
13
13
  @secret_access_key = config[:cloudprovider_secret_access_key]
14
14
  @owner_id = config[:cloudprovider_images_owner_id]
15
+ @image = config[:image]
15
16
  @ec2 = ec2
16
17
  end
17
18
 
18
- def image(name=nil)
19
- Provider::Ec2::Image.new(@ec2, @environment, @owner_id, name)
19
+ def image
20
+ Provider::Ec2::Image.new(@ec2, @role, @owner_id, @image)
20
21
  end
21
22
 
22
23
  def instance
23
- Provider::Ec2::Instance.new(@ec2, @name, @environment)
24
+ Provider::Ec2::Instance.new(@ec2, @name, @image)
24
25
  end
25
26
 
26
27
  def instances
@@ -29,8 +30,16 @@ module Provider
29
30
  end
30
31
  end
31
32
 
33
+ def regions
34
+ AWS.memoize do
35
+ @ec2.regions
36
+ end
37
+ end
38
+
32
39
  def ec2
33
- AWS::EC2.new(:access_key_id => @access_key_id, :secret_access_key => @secret_access_key, :region => @region)
40
+ AWS.memoize do
41
+ AWS::EC2.new(:access_key_id => @access_key_id, :secret_access_key => @secret_access_key, :region => @region)
42
+ end
34
43
  end
35
44
 
36
45
  end
@@ -2,11 +2,10 @@ module Provider
2
2
  class Ec2
3
3
  class Image
4
4
 
5
- def initialize(ec2, environment, owner_id, name=nil)
5
+ def initialize(ec2, role, owner_id, ami_name)
6
6
  @ec2 = ec2
7
- @environment = environment
8
- @name = name
9
- @ami_name = @name || @environment + '-ami'
7
+ @role = role
8
+ @ami_name = ami_name
10
9
  @owner_id = owner_id
11
10
  end
12
11
 
@@ -2,26 +2,25 @@ module Provider
2
2
  class Ec2
3
3
  class Instance
4
4
 
5
- def initialize(ec2, name, environment)
5
+ def initialize(ec2, name, image)
6
6
  @ec2 = ec2
7
7
  @name = name
8
- @environment = environment
9
- @instance = instance
10
- end
8
+ @instance = instance
9
+ @image = image
10
+ end
11
11
 
12
12
  def stop
13
13
  print "Stopping instance #{@name}..."
14
14
  if self.exist?
15
15
  @instance.stop
16
- @i = 0
16
+ i = 0
17
17
  while self.status != :stopped
18
- if @i > 120
19
- return false
20
- end
21
- print "." ; sleep 3 ; @i += 1
18
+ print "." ; sleep 3 ; i += 1
19
+ return false if i > 120
22
20
  end
21
+ puts "\nInstance #{@name} is stopped"
23
22
  end
24
- puts "\nInstance #{@name} is stopped"
23
+ return true
25
24
  end
26
25
 
27
26
  def start
@@ -31,15 +30,14 @@ module Provider
31
30
  sleep 2
32
31
  end
33
32
  @instance.start
34
- @i = 0
33
+ i = 0
35
34
  while self.status != :running
36
- if @i > 120
37
- return false
38
- end
39
- print "." ; sleep 3 ; @i += 1
35
+ print "." ; sleep 3 ; i += 1
36
+ return false if i > 120
40
37
  end
38
+ puts "\nInstance #{@name} is started"
41
39
  end
42
- puts "\nInstance #{@name} is started"
40
+ return true
43
41
  end
44
42
 
45
43
  def exist?
@@ -79,8 +77,8 @@ module Provider
79
77
  end
80
78
  end
81
79
 
82
- def create_image(name=nil)
83
- @ami_name = name || @environment + '-ami'
80
+ def create_image
81
+ @ami_name = @image || @name
84
82
  puts "Create image #{@ami_name}"
85
83
  image = @instance.create_image(@ami_name, { :no_reboot => true })
86
84
  while image.exists? == false && image.state != :failed
@@ -94,6 +92,14 @@ module Provider
94
92
  puts ""
95
93
  return image
96
94
  end
95
+
96
+ def tags(hash={})
97
+ puts "Tagging instance ..."
98
+ hash.keys.each do |k|
99
+ puts k + ': ' + hash[k]
100
+ @instance.tags[k] = hash[k]
101
+ end
102
+ end
97
103
 
98
104
  end
99
105
  end
data/lib/veronic.rb CHANGED
@@ -97,13 +97,22 @@ module Veronic
97
97
  configprovider.ssh(query, @config.deploy_cmd, manual)
98
98
  end
99
99
 
100
+ def search_and_deploy
101
+ unless @config.deploy_cmd || @config.query
102
+ abort('Arguments --deploy_cmd or --query is missing')
103
+ end
104
+ query = @config.query
105
+ manual = false
106
+ configprovider.ssh(query, @config.deploy_cmd, manual)
107
+ end
108
+
100
109
  def update_instance_dns
101
110
  @config.dnsprovider_zones.each do |z|
102
111
  @config.zone_name = z['zone_name']
103
112
  @config.zone_url = z['zone_url']
104
113
  dns = "#{@config.name}.#{z['zone_name']}"
105
114
  puts "Setting DNS #{dns} ..."
106
- record = dnsprovider.zone.record(dns, [cloudprovider.instance.public_ip_address], "A", "1").wait_set
115
+ record = dnsprovider.zone.record(dns, [cloudprovider.instance.dns_name], "CNAME", "1").wait_set
107
116
  puts "DNS #{dns} updated"
108
117
  end
109
118
  end
@@ -118,7 +127,7 @@ module Veronic
118
127
 
119
128
  def start
120
129
  unless cloudprovider.instance.start == false
121
- update_instance_dns
130
+ exit 1
122
131
  end
123
132
  end
124
133
 
@@ -137,10 +146,10 @@ module Veronic
137
146
  elsif cloudprovider.instance.status == :stopped
138
147
  start
139
148
  elsif cloudprovider.instance.exist? == false
149
+ @config.availability_zone = get_availability_zone
140
150
  get_image
141
151
  configprovider.instance.client.destroy
142
152
  configprovider.instance.bootstrap
143
- update_instance_dns
144
153
  status = true
145
154
  else
146
155
  abort('Error during connecting instance')
@@ -150,20 +159,21 @@ module Veronic
150
159
  end
151
160
 
152
161
  def create_image
153
- unless @config.environment
154
- abort('Arguments --environment is missing')
155
- else
156
- configprovider.instance.delete_client_key(cloudprovider.instance.dns_name)
157
- configprovider.instance.client.destroy
158
- cloudprovider.image.detroy
159
- cloudprovider.instance.create_image
160
- end
162
+ configprovider.instance.delete_client_key(cloudprovider.instance.dns_name)
163
+ configprovider.instance.client.destroy
164
+ cloudprovider.image.detroy
165
+ cloudprovider.instance.create_image
161
166
  end
162
167
 
163
168
  def set_node
169
+ update_instance_dns
164
170
  if @config.role && @config.environment
165
171
  configprovider.instance.set_environment
166
172
  configprovider.instance.set_role
173
+ cloudprovider.instance.tags({'role' => @config.role, 'environment' => @config.environment})
174
+ if configprovider.instance.delete_client_key(cloudprovider.instance.dns_name)
175
+ configprovider.instance.client.destroy
176
+ end
167
177
  else
168
178
  abort('Arguments --role or --environment is missing')
169
179
  end
@@ -171,13 +181,36 @@ module Veronic
171
181
 
172
182
  def get_image
173
183
  if @config.image.nil?
174
- unless @config.environment
175
- abort('Arguments --environment is missing')
176
- else
177
- @config.image = cloudprovider.image.id
178
- end
184
+ abort('Arguments --ami_image is missing')
179
185
  else
180
- @config.image = cloudprovider.image(@config.image).id
186
+ @config.image = cloudprovider.image.id
187
+ end
188
+ end
189
+
190
+ def get_availability_zone
191
+ puts "Getting availability zone ..."
192
+ environments = {}
193
+ if @config.availability_zone.nil? || @config.availability_zone == 'auto'
194
+ cloudprovider.regions.each do |region|
195
+ region.instances.each do |instance|
196
+ if instance.tags[:environment] && instance.tags[:role] && instance.status != :shutting_down && instance.status != :terminated
197
+ environments[instance.tags[:environment]] = {} unless environments[instance.tags[:environment]]
198
+ environments[instance.tags[:environment]][instance.tags[:role]] = {} unless environments[instance.tags[:environment]][instance.tags[:role]]
199
+ environments[instance.tags[:environment]][instance.tags[:role]][region.name] = {} unless environments[instance.tags[:environment]][instance.tags[:role]][region.name]
200
+ region.availability_zones.each do |availability_zone|
201
+ environments[instance.tags[:environment]][instance.tags[:role]][region.name][availability_zone.name] = [] unless environments[instance.tags[:environment]][instance.tags[:role]][region.name][availability_zone.name]
202
+ end
203
+ environments[instance.tags[:environment]][instance.tags[:role]][region.name][instance.availability_zone] << instance.id
204
+ end
205
+ end
206
+ end
207
+ end
208
+ if environments[@config.environment] && environments[@config.environment][@config.role] && environments[@config.environment][@config.role][@config.region]
209
+ availability_zones = environments[@config.environment][@config.role][@config.region].sort_by { |availability_zone| availability_zone[1].count }
210
+ puts "Zones: " + availability_zones.to_s
211
+ availability_zone = availability_zones.first
212
+ puts "Zone selected: " + availability_zone[0]
213
+ availability_zone[0]
181
214
  end
182
215
  end
183
216
  end
data/veronic.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'veronic'
3
- s.version = '0.0.21'
3
+ s.version = '0.0.22'
4
4
  s.date = '2013-04-05'
5
5
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
6
6
  s.summary = "Veronic, a simple cloud deployer"
@@ -14,5 +14,5 @@ Gem::Specification.new do |s|
14
14
  s.add_dependency('knife-ec2')
15
15
  s.add_dependency('aws-sdk')
16
16
  s.add_dependency('route53')
17
- s.add_dependency('excon', '= 0.21.0')
17
+ s.add_dependency('excon', '~> 0.23.0')
18
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: veronic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.0.22
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -80,17 +80,17 @@ dependencies:
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
- - - '='
83
+ - - ~>
84
84
  - !ruby/object:Gem::Version
85
- version: 0.21.0
85
+ version: 0.23.0
86
86
  type: :runtime
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
89
89
  none: false
90
90
  requirements:
91
- - - '='
91
+ - - ~>
92
92
  - !ruby/object:Gem::Version
93
- version: 0.21.0
93
+ version: 0.23.0
94
94
  description: A simple cloud deployer
95
95
  email: gabriel.klein.fr@gmail.com
96
96
  executables: