veronic 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ .DS_Store
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ Veronic
2
+ =======
3
+
4
+ Veronic, deux qui la tiennent trois qui la niquent is a simple cloud deployer
5
+
6
+ 1) Create veronic directory:
7
+
8
+ ````
9
+ $ mkdir /etc/veronic
10
+ ````
11
+
12
+ 2) Create veronic.yml base on https://github.com/GabKlein/veronic/blob/master/veronic.yml
13
+
14
+ ````
15
+ $ vim /etc/veronic/veronic.yml
16
+ ````
17
+
18
+ 3) Set veronic.yml values
19
+
20
+ Usage
21
+ =======
22
+
23
+ ````
24
+ $ gem install veronic
25
+ $ veronic --help
26
+ ````
data/bin/veronic ADDED
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require 'yaml'
6
+ require "cgi"
7
+
8
+ require_relative '../lib/deployer'
9
+
10
+ file = __FILE__
11
+ path = File.dirname($0)
12
+ config_file = File.exists?('/etc/veronic/veronic.yml') ? '/etc/veronic/veronic.yml' : path + '/veronic.yml'
13
+
14
+ options = {}
15
+
16
+ opt_parser = OptionParser.new do |opt|
17
+ opt.banner = "Usage: #{file} COMMAND [OPTIONS]"
18
+ opt.separator ""
19
+ opt.separator "Commands"
20
+ opt.separator " create: create box"
21
+ opt.separator " bootstrap: bootstrap box"
22
+ opt.separator " destroy: destroy box"
23
+ opt.separator " deploy: deploy box"
24
+ opt.separator " deploy_stacks: deploy stacks on box"
25
+ opt.separator " deploy_apps: destroy apps on box"
26
+ opt.separator " run_tests: tests apps on box"
27
+ opt.separator " update_instance_dns: update box dns"
28
+ opt.separator " stop: stop box"
29
+ opt.separator " start: start box"
30
+ opt.separator " list: list boxes"
31
+ opt.separator ""
32
+ opt.separator "Options"
33
+
34
+ options[:config_file] = ENV['config_file'] || config_file
35
+ opt.on("-c","--config_file veronic.yml","Use specific config file") do |c|
36
+ options[:config_file] = c
37
+ end
38
+ CONFIG = YAML.load_file(options[:config_file])
39
+
40
+ options[:environment] = ENV['environment'] || 'branch'
41
+ opt.on("-E","--environment ENVIRONMENT","Which environment you want box run") do |e|
42
+ options[:environment] = e
43
+ end
44
+
45
+ options[:name] = ENV['name'] || 'sitemap-generator-45625091'
46
+ opt.on("-N","--node-name NAME","Which node name you want for the box") do |n|
47
+ options[:name] = n
48
+ end
49
+
50
+ options[:branch] = ENV['branch']
51
+ opt.on("-b","--branch BRANCH","Which branch you want to run a box for") do |b|
52
+ options[:branch] = b
53
+ end
54
+
55
+ options[:ssh_user] = ENV['ssh_user'] || "ubuntu"
56
+ opt.on("-u","--ssh_user ssh_user","Which ssh user use to connect box") do |s|
57
+ options[:ssh_user] = s
58
+ end
59
+
60
+ options[:ssh_port] = ENV['ssh_port'] || 22
61
+ opt.on("-p","--ssh_port ssh_port","Which ssh port use to connect box") do |p|
62
+ options[:ssh_port] = p
63
+ end
64
+
65
+ options[:identity_file] = ENV['identity_file'] || CONFIG['identity_file']
66
+ opt.on("-i","--identity_file identity_file.pem","Which file use by ssh to connect box") do |i|
67
+ options[:identity_file] = i
68
+ end
69
+
70
+ options[:role] = ENV['role'] || 'beta'
71
+ opt.on("-r","--role role","Which role use to deploy the box") do |r|
72
+ options[:role] = r
73
+ end
74
+
75
+ options[:flavor] = ENV['flavor'] || 'm1.medium'
76
+ opt.on("-f","--flavor flavor","Which flavor use to deploy the box") do |f|
77
+ options[:flavor] = f
78
+ end
79
+
80
+ options[:dns_zone_name] = ENV['dns_zone_name'] || 'aipotfil.com'
81
+ opt.on("-d","--dns_zone_name dns_zone_name","Which dns zone use for the box's dns") do |d|
82
+ options[:dns_zone_name] = d
83
+ end
84
+
85
+ options[:security_groups] = ENV['security_groups'] || 'public-web'
86
+ opt.on("-S","--security_groups security_groups","Which security groups use for the box") do |s|
87
+ options[:security_groups] = s
88
+ end
89
+
90
+ options[:deploy_cmd] = ENV['deploy_cmd'] || 'sudo chef-client'
91
+ opt.on("-D","--deploy_cmd security_groups","Which command line us to deploy the box") do |dc|
92
+ options[:deploy_cmd] = dc
93
+ end
94
+
95
+ opt.on("-h","--help","help")
96
+ end
97
+
98
+ opt_parser.parse!
99
+
100
+ config = {}
101
+ config[:dnsprovider] = :route53
102
+ config[:cloudprovider] = :ec2
103
+ config[:configprovider] = :chefserver
104
+ config[:dnsprovider_access_key_id] = CONFIG['dnsprovider_access_key_id']
105
+ config[:dnsprovider_secret_access_key] = CONFIG['dnsprovider_secret_access_key']
106
+ config[:cloudprovider_access_key_id] = CONFIG['cloudprovider_access_key_id']
107
+ config[:cloudprovider_secret_access_key] = CONFIG['cloudprovider_secret_access_key']
108
+ config[:cloudprovider_images_owner_id] = CONFIG['cloudprovider_images_owner_id']
109
+ config[:dnsprovider_zone_url] = CONFIG['dnsprovider_zone_url']
110
+ config[:region] = CONFIG['us-east-1']
111
+ config[:availability_zone] = CONFIG['us-east-1b']
112
+ config[:aws_ssh_key_id] = CONFIG['aws_ssh_key_id']
113
+ config[:node_name] = CONFIG['node_name']
114
+ config[:client_key] = CONFIG['client_key']
115
+ config[:validation_client_name] = CONFIG['validation_client_name']
116
+ config[:validation_key] = CONFIG['validation_key']
117
+ config[:chef_server_url] = CONFIG['chef_server_url']
118
+ config[:ssl_version] = CONFIG['ssl_version']
119
+ config[:identity_file] = options[:identity_file]
120
+ config[:dnsprovider_zone_name] = "#{options[:dns_zone_name]}."
121
+ config[:branch] = options[:branch]
122
+ config[:environment] = options[:environment]
123
+ config[:name] = options[:branch] ? options[:branch] : options[:name]
124
+ config[:ssh_user] = options[:ssh_user]
125
+ config[:ssh_port] = options[:ssh_port]
126
+ config[:role] = options[:role]
127
+ config[:roles] = "role[#{options[:role]}]"
128
+ config[:flavor] = options[:flavor]
129
+ config[:domain] = options[:dns_zone_name]
130
+ config[:security_groups] = [options[:security_groups]]
131
+ config[:deploy_cmd] = options[:deploy_cmd]
132
+ config[:dns_array] = ["#{config[:name]}.#{options[:dns_zone_name]}", "#{config[:name]}.core.#{options[:dns_zone_name]}", "#{config[:name]}.store.#{options[:dns_zone_name]}", "*.#{config[:name]}.store.#{options[:dns_zone_name]}"]
133
+
134
+ case ARGV[0] || ENV['action']
135
+ when "create"
136
+ Deployer.new(config).create
137
+ when "bootstrap"
138
+ Deployer.new(config).bootstrap
139
+ when "destroy"
140
+ Deployer.new(config).destroy
141
+ when "deploy"
142
+ Deployer.new(config).deploy
143
+ when "deploy_stacks"
144
+ Deployer.new(config).deploy_stacks
145
+ when "deploy_apps"
146
+ Deployer.new(config).deploy_apps
147
+ when "run_tests"
148
+ Deployer.new(config).run_tests
149
+ when "update_instance_dns"
150
+ Deployer.new(config).update_instance_dns
151
+ when "stop"
152
+ Deployer.new(config).stop
153
+ when "start"
154
+ Deployer.new(config).start
155
+ Deployer.new(config).update_instance_dns
156
+ when "list"
157
+ Deployer.new(config).instances_list
158
+ else
159
+ puts opt_parser
160
+ end
data/lib/deployer.rb ADDED
@@ -0,0 +1,109 @@
1
+ require_relative 'providers/cloudprovider'
2
+ require_relative 'providers/dnsprovider'
3
+ require_relative 'providers/configprovider'
4
+
5
+ class Deployer
6
+
7
+ def initialize(config)
8
+ @role = config[:role]
9
+ @environment = config[:environment]
10
+ @deploy_cmd = config[:deploy_cmd]
11
+ @dns_array = config[:dns_array]
12
+ @cloudprovider = CloudProvider.new(config)
13
+ config[:image] = @cloudprovider.image.id
14
+ @dnsprovider = DnsProvider.new(config)
15
+ @configprovider = ConfigProvider.new(config)
16
+ end
17
+
18
+ def create
19
+ if bootstrap
20
+ @configprovider.instance.create
21
+ end
22
+ end
23
+
24
+ def deploy_stacks
25
+ bootstrap
26
+ query = @cloudprovider.instance.dns_name
27
+ deploy_cmd = 'sudo chef-client -l debug'
28
+ manual = true
29
+ @configprovider.ssh(query, deploy_cmd, manual)
30
+ end
31
+
32
+ def deploy_apps
33
+ unless bootstrap
34
+ deploy_stacks
35
+ end
36
+ query = @cloudprovider.instance.dns_name
37
+ deploy_cmd = 'sudo chef-client -o "recipe[lift_envs::app_deploy]" -l debug'
38
+ manual = true
39
+ @configprovider.ssh(query, deploy_cmd, manual)
40
+ end
41
+
42
+ def run_tests
43
+ unless bootstrap
44
+ deploy_stacks
45
+ deploy_apps
46
+ end
47
+ query = @cloudprovider.instance.dns_name
48
+ deploy_cmd = 'sudo chef-client -o "recipe[lift_envs::app_testing]" -l debug'
49
+ manual = true
50
+ @configprovider.ssh(query, deploy_cmd, manual)
51
+ end
52
+
53
+ def destroy
54
+ if @cloudprovider.instance.exist?
55
+ @configprovider.instance.destroy([@cloudprovider.instance.id])
56
+ else
57
+ @configprovider.instance.destroy([])
58
+ end
59
+ end
60
+
61
+ def deploy
62
+ if @cloudprovider.instance.exist?
63
+ if @environment == 'branch'
64
+ query = @cloudprovider.instance.dns_name
65
+ manual = true
66
+ else
67
+ query = "role:#{@role}"
68
+ manual = false
69
+ end
70
+ @configprovider.ssh(query, @deploy_cmd, manual)
71
+ end
72
+ end
73
+
74
+ def update_instance_dns
75
+ @dns_array.each do |dns|
76
+ puts "Setting DNS #{dns} ..."
77
+ @dnsprovider.zone.record.new(@dnsprovider.zone, dns, [@cloudprovider.instance.public_ip_address], "A", "10")
78
+ puts "DNS #{dns} updated"
79
+ end
80
+ end
81
+
82
+ def instances_list
83
+ @cloudprovider.instances_list
84
+ end
85
+
86
+ def stop
87
+ @cloudprovider.instance.stop
88
+ end
89
+
90
+ def start
91
+ @cloudprovider.instance.start
92
+ update_instance_dns
93
+ end
94
+
95
+ def bootstrap
96
+ if @cloudprovider.instance.status == :running
97
+ return true
98
+ elsif @cloudprovider.instance.status == :stopped
99
+ start
100
+ return true
101
+ elsif @cloudprovider.instance.exist? == false
102
+ @configprovider.instance.bootstrap
103
+ @configprovider.instance.set_role
104
+ return false
105
+ else
106
+ raise ArgumentError.new('Error during connecting instance')
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,54 @@
1
+ require 'fog'
2
+ require 'chef'
3
+ require 'chef/json_compat'
4
+ require 'chef/node'
5
+ require 'chef/api_client'
6
+ require 'tempfile'
7
+ require 'highline'
8
+ require 'net/ssh'
9
+ require 'net/ssh/multi'
10
+ require_relative 'instance'
11
+
12
+ module Provider
13
+ class ChefServer
14
+
15
+ def initialize(config)
16
+ @path = File.dirname($0)
17
+ @config = config
18
+ Chef::Config[:environment] = config[:environment]
19
+ Chef::Config[:node_name] = config[:node_name]
20
+ Chef::Config[:client_key] = config[:client_key]
21
+ Chef::Config[:validation_client_name] = config[:validation_client_name]
22
+ Chef::Config[:validation_key] = config[:validation_key]
23
+ Chef::Config[:chef_server_url] = config[:chef_server_url]
24
+ Chef::Config[:ssl_version] = config[:ssl_version]
25
+ Chef::Config[:log_level] = :debug
26
+ @knife = knife
27
+ end
28
+
29
+ def knife
30
+ knife = Provider::ChefServer::Instance.new(@config)
31
+ end
32
+
33
+ def instances(query)
34
+ q = Chef::Search::Query.new
35
+ nodes = q.search(:node, query).first
36
+ nodes
37
+ end
38
+
39
+ def search(query)
40
+ q = Chef::Search::Query.new
41
+ nodes = q.search(:node, query).first
42
+ nodes
43
+ end
44
+
45
+ def ssh(query, deploy_cmd, manual)
46
+ @knife.ssh(query, deploy_cmd, manual)
47
+ end
48
+
49
+ def instance
50
+ instance = Provider::ChefServer::Instance.new(@config)
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,114 @@
1
+ require 'chef/knife'
2
+ require 'chef/knife/ec2_server_create'
3
+ require 'chef/knife/ec2_server_delete'
4
+ require 'chef/knife/bootstrap'
5
+ require 'chef/knife/ssh'
6
+ require 'chef/knife/node_run_list_add'
7
+ require 'chef/knife/core/bootstrap_context'
8
+ require 'chef/knife/ec2_base'
9
+ require_relative 'rest_request'
10
+
11
+ module Provider
12
+ class ChefServer
13
+ class Instance
14
+
15
+ def initialize(config)
16
+ @access_key_id = config[:cloudprovider_access_key_id]
17
+ @secret_access_key = config[:cloudprovider_secret_access_key]
18
+ @name = config[:name]
19
+ @image = config[:image]
20
+ @security_groups = config[:security_groups]
21
+ @ssh_user = config[:ssh_user]
22
+ @ssh_port = config[:ssh_port]
23
+ @identity_file = config[:identity_file]
24
+ @aws_ssh_key_id = config[:aws_ssh_key_id]
25
+ @environment = config[:environment]
26
+ @roles = config[:roles]
27
+ @flavor = config[:flavor]
28
+ @region = config[:region]
29
+ @availability_zone = config[:availability_zone]
30
+ Chef::Config[:knife][:image] = @image
31
+ Chef::Config[:knife][:aws_ssh_key_id] = @aws_ssh_key_id
32
+ Chef::Config[:knife][:aws_access_key_id] = @access_key_id
33
+ Chef::Config[:knife][:aws_secret_access_key] = @secret_access_key
34
+ Chef::Config[:knife][:region] = @region
35
+ Chef::Config[:knife][:availability_zone] = @availability_zone
36
+ Chef::Config[:knife][:log_level] = :debug
37
+ end
38
+
39
+ def create
40
+ puts "Creating ec2 server #{@name} ..."
41
+
42
+ create = Chef::Knife::Ec2ServerCreate.new()
43
+
44
+ create.config[:run_list] = [@roles]
45
+ create.config[:image] = @image
46
+ create.config[:flavor] = @flavor
47
+ create.config[:security_groups] = @security_groups
48
+ create.config[:ssh_user] = @ssh_user
49
+ create.config[:ssh_port] = @ssh_port
50
+ create.config[:chef_node_name] = @name
51
+ create.config[:identity_file] = @identity_file
52
+ create.config[:environment] = @environment
53
+ create.config[:log_level] = :debug
54
+
55
+ puts create.config
56
+ create.run
57
+ end
58
+
59
+ def bootstrap
60
+ puts "Bootstrapping ec2 server #{@name} ..."
61
+
62
+ bootstrap = Chef::Knife::Ec2ServerCreate.new()
63
+
64
+ bootstrap.config[:image] = @image
65
+ bootstrap.config[:flavor] = @flavor
66
+ bootstrap.config[:security_groups] = @security_groups
67
+ bootstrap.config[:ssh_user] = @ssh_user
68
+ bootstrap.config[:ssh_port] = @ssh_port
69
+ bootstrap.config[:chef_node_name] = @name
70
+ bootstrap.config[:identity_file] = @identity_file
71
+ bootstrap.config[:environment] = @environment
72
+ bootstrap.config[:log_level] = :debug
73
+
74
+ puts bootstrap.config
75
+ bootstrap.run
76
+ end
77
+
78
+ def destroy(instance_ids = [])
79
+ puts "Deleting ec2 server #{@name} ..."
80
+
81
+ destroy = Chef::Knife::Ec2ServerDelete.new()
82
+
83
+ destroy.config[:purge] = true
84
+ destroy.config[:chef_node_name] = @name
85
+ destroy.config[:yes] = true
86
+ destroy.name_args = instance_ids
87
+
88
+ puts destroy.config
89
+ destroy.run
90
+ destroy.destroy_item(Chef::Node, @name, "node")
91
+ destroy.destroy_item(Chef::ApiClient, @name, "client")
92
+ end
93
+
94
+ def set_role
95
+ node = Chef::Knife::NodeRunListAdd.new()
96
+ node.name_args = [@name, @roles]
97
+ node.run
98
+ end
99
+
100
+ def ssh(query, cmd_line, manual)
101
+ knife_ssh = Chef::Knife::Ssh.new()
102
+
103
+ knife_ssh.config[:manual] = manual
104
+ knife_ssh.config[:ssh_user] = @ssh_user
105
+ knife_ssh.config[:identity_file] = @identity_file
106
+ knife_ssh.config[:log_level] = :debug
107
+
108
+ knife_ssh.name_args = [query, cmd_line]
109
+ sys_status = knife_ssh.run
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,54 @@
1
+ class Chef
2
+ class REST
3
+ class RESTRequest
4
+ def configure_http_client
5
+ http_proxy = proxy_uri
6
+ if http_proxy.nil?
7
+ @http_client = Net::HTTP.new(host, port)
8
+ else
9
+ Chef::Log.debug("Using #{http_proxy.host}:#{http_proxy.port} for proxy")
10
+ user = Chef::Config["#{url.scheme}_proxy_user"]
11
+ pass = Chef::Config["#{url.scheme}_proxy_pass"]
12
+ @http_client = Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass).new(host, port)
13
+ end
14
+ if url.scheme == HTTPS
15
+ @http_client.use_ssl = true
16
+ if config[:ssl_version].to_sym == :SSLv3
17
+ @http_client.ssl_version = :SSLv3
18
+ end
19
+ if config[:ssl_verify_mode] == :verify_none
20
+ @http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
21
+ elsif config[:ssl_verify_mode] == :verify_peer
22
+ @http_client.verify_mode = OpenSSL::SSL::VERIFY_PEER
23
+ end
24
+ if config[:ssl_ca_path]
25
+ unless ::File.exist?(config[:ssl_ca_path])
26
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_path #{config[:ssl_ca_path]} does not exist"
27
+ end
28
+ @http_client.ca_path = config[:ssl_ca_path]
29
+ elsif config[:ssl_ca_file]
30
+ unless ::File.exist?(config[:ssl_ca_file])
31
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_ca_file #{config[:ssl_ca_file]} does not exist"
32
+ end
33
+ @http_client.ca_file = config[:ssl_ca_file]
34
+ end
35
+ if (config[:ssl_client_cert] || config[:ssl_client_key])
36
+ unless (config[:ssl_client_cert] && config[:ssl_client_key])
37
+ raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
38
+ end
39
+ unless ::File.exists?(config[:ssl_client_cert])
40
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
41
+ end
42
+ unless ::File.exists?(config[:ssl_client_key])
43
+ raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
44
+ end
45
+ @http_client.cert = OpenSSL::X509::Certificate.new(::File.read(config[:ssl_client_cert]))
46
+ @http_client.key = OpenSSL::PKey::RSA.new(::File.read(config[:ssl_client_key]))
47
+ end
48
+ end
49
+
50
+ @http_client.read_timeout = config[:rest_timeout]
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'ec2/ec2'
2
+
3
+ class CloudProvider
4
+
5
+ CLOUDPROVIDERS = { :ec2 => Provider::Ec2 }
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ @provider = provider
10
+ end
11
+
12
+ def provider
13
+ CLOUDPROVIDERS[@config[:cloudprovider]].new(@config)
14
+ end
15
+
16
+ def image
17
+ @provider.image
18
+ end
19
+
20
+ def instance
21
+ @provider.instance
22
+ end
23
+
24
+ def instances
25
+ @provider.instances
26
+ end
27
+
28
+ def instances_list
29
+ printf "%17s %35s %34s\n", 'NAME', 'DNS', 'STATUS'
30
+ @provider.instances.each do |instance|
31
+ printf "%-30s %-50s %s\n", instance.tags['Name'], instance.dns_name, instance.status.to_s
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'chefserver/chefserver'
2
+
3
+ class ConfigProvider
4
+
5
+ CONFIGPROVIDERS = { :chefserver => Provider::ChefServer }
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ @provider = provider
10
+ end
11
+
12
+ def provider
13
+ CONFIGPROVIDERS[@config[:configprovider]].new(@config)
14
+ end
15
+
16
+ def ssh(query, deploy_cmd, manual)
17
+ @provider.ssh(query, deploy_cmd, manual)
18
+ end
19
+
20
+ def instance
21
+ @provider.instance
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'route53/r53'
2
+
3
+ class DnsProvider
4
+
5
+ DNSPROVIDERS = { :route53 => Provider::R53 }
6
+
7
+ def initialize(config)
8
+ @config = config
9
+ @dnsprovider = provider
10
+ end
11
+
12
+ def provider
13
+ DNSPROVIDERS[@config[:dnsprovider]].new(@config)
14
+ end
15
+
16
+ def zone
17
+ @dnsprovider.zone
18
+ end
19
+ end
@@ -0,0 +1,34 @@
1
+ require 'aws-sdk'
2
+ require_relative 'instance'
3
+ require_relative 'image'
4
+
5
+ module Provider
6
+ class Ec2
7
+
8
+ def initialize(config)
9
+ @name = config[:name]
10
+ @environment = config[:environment]
11
+ @access_key_id = config[:cloudprovider_access_key_id]
12
+ @secret_access_key = config[:cloudprovider_secret_access_key]
13
+ @owner_id = config[:cloudprovider_images_owner_id]
14
+ @ec2 = ec2
15
+ end
16
+
17
+ def image
18
+ Provider::Ec2::Image.new(@ec2, @environment, @owner_id)
19
+ end
20
+
21
+ def instance
22
+ Provider::Ec2::Instance.new(@ec2, @name)
23
+ end
24
+
25
+ def instances
26
+ @ec2.instances
27
+ end
28
+
29
+ def ec2
30
+ AWS::EC2.new(:access_key_id => @access_key_id, :secret_access_key => @secret_access_key)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ module Provider
2
+ class Ec2
3
+ class Image
4
+
5
+ def initialize(ec2, environment, owner_id)
6
+ @image = ec2.images.with_owner(owner_id).select {|x| x.name == environment + '-ami'}.first
7
+ end
8
+
9
+ def id
10
+ @image.id
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,62 @@
1
+ module Provider
2
+ class Ec2
3
+ class Instance
4
+
5
+ def initialize(ec2, name)
6
+ @ec2 = ec2
7
+ @name = name
8
+ @instance = @ec2.instances.select {|x| x.tags['Name'] == @name && x.status != :shutting_down && x.status != :terminated}.first
9
+ end
10
+
11
+ def stop
12
+ print "Stopping instance #{@name}..."
13
+ @instance.stop if @instance.status == :running
14
+ while @instance.status != :stopped && @i < 40
15
+ print "." ; sleep 3 ; @i += 1 || 1
16
+ end
17
+ puts "\nInstance #{@name} is stopped"
18
+ end
19
+
20
+ def start
21
+ print "Starting instance #{@name}..."
22
+ @instance.start if @instance.status == :stopped && @i < 40
23
+ while @instance.status != :running
24
+ print "." ; sleep 3 ; @i += 1 || 1
25
+ end
26
+ puts "\nInstance #{@name} is started"
27
+ end
28
+
29
+ def exist?
30
+ puts "Checking for ec2 server #{@name} ..."
31
+ if @ec2.instances.any? {|x| x.tags['Name'] == @name && x.status != :shutting_down && x.status != :terminated}
32
+ puts "Instance #{@name} found"
33
+ return true
34
+ else
35
+ puts "Instance #{@name} is misssing"
36
+ return false
37
+ end
38
+ end
39
+
40
+ def status
41
+ begin
42
+ @instance.status
43
+ rescue Exception => e
44
+ return :missing
45
+ end
46
+ end
47
+
48
+ def dns_name
49
+ @instance.dns_name
50
+ end
51
+
52
+ def public_ip_address
53
+ @instance.public_ip_address
54
+ end
55
+
56
+ def id
57
+ @instance.id
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,26 @@
1
+ require 'route53'
2
+ require_relative 'zone'
3
+ require_relative 'record'
4
+
5
+ module Provider
6
+ class R53
7
+
8
+ def initialize(config)
9
+ @access_key_id = config[:dnsprovider_access_key_id]
10
+ @secret_access_key = config[:dnsprovider_secret_access_key]
11
+ @zone_name = config[:dnsprovider_zone_name]
12
+ @zone_url = config[:dnsprovider_zone_url]
13
+ @r53 = r53
14
+ @zone = zone
15
+ end
16
+
17
+ def r53
18
+ Route53::Connection.new(@access_key_id, @secret_access_key)
19
+ end
20
+
21
+ def zone
22
+ Provider::R53::Zone.new(@r53, @zone_name, @zone_url)
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ module Provider
2
+ class R53::Zone
3
+ class Record
4
+
5
+ def initialize(zone, name, values=[], type, ttl)
6
+ @zone = zone
7
+ @name = name
8
+ @values = values
9
+ @type = type
10
+ @ttl = ttl
11
+ @update = wait_set
12
+ end
13
+
14
+ def get
15
+ @zone.records.select {|x| x.name == @name+'.'}.first
16
+ end
17
+
18
+ def exist?
19
+ @zone.records.any? {|x| x.name == @name+'.'}
20
+ end
21
+
22
+ def match?
23
+ @zone.records.any? {|x| x.name == @name+'.' && x.values == @values}
24
+ end
25
+
26
+ def wait_set
27
+ print "Waitting for record { name: #{@name}, value: #{@values} }..."
28
+ while !self.match?
29
+ print "."
30
+ self.set
31
+ sleep 5
32
+ end
33
+ puts "\nRecord { name: #{@name}, value: #{@values} } updated"
34
+ end
35
+
36
+ def set
37
+ if self.exist?
38
+ record = self.get
39
+ new_record = Route53::DNSRecord.new(record.name, record.type, record.ttl, record.values, @zone)
40
+ action = "update"
41
+ record.update(@name, @type, @ttl, @values, @zone)
42
+ else
43
+ record = Route53::DNSRecord.new(@name, @type, @ttl, @values, @zone)
44
+ action = "create"
45
+ record.create
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,26 @@
1
+ module Provider
2
+ class R53
3
+ class Zone
4
+
5
+ def initialize(r53, zone_name, zone_url)
6
+ @zone_name = zone_name
7
+ @zone_url = zone_url
8
+ @r53 = r53
9
+ @zone = zone
10
+ end
11
+
12
+ def record
13
+ Provider::R53::Zone::Record
14
+ end
15
+
16
+ def records
17
+ @zone.get_records
18
+ end
19
+
20
+ def zone
21
+ zone = Route53::Zone.new(@zone_name, @zone_url, @r53)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
data/veronic.gemspec ADDED
@@ -0,0 +1,13 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'veronic'
3
+ s.version = '0.0.4'
4
+ s.date = '2013-04-05'
5
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
6
+ s.summary = "Veronic, deux qui la tiennent trois qui la niquent"
7
+ s.description = "A simple cloud deployer"
8
+ s.authors = ["Gabriel Klein"]
9
+ s.email = 'gabriel.klein.fr@gmail.com'
10
+ s.files = `git ls-files`.split("\n")
11
+ s.require_paths = ["lib"]
12
+ s.homepage = 'http://github.com/GabKlein/veronic'
13
+ end
data/veronic.yml ADDED
@@ -0,0 +1,16 @@
1
+ dnsprovider_access_key_id:
2
+ dnsprovider_secret_access_key:
3
+ dnsprovider_zone_url:
4
+ cloudprovider_access_key_id:
5
+ cloudprovider_secret_access_key:
6
+ cloudprovider_images_owner_id:
7
+ region:
8
+ availability_zone:
9
+ aws_ssh_key_id:
10
+ node_name:
11
+ chef_server_url:
12
+ validation_client_name:
13
+ validation_key:
14
+ client_key:
15
+ identity_file:
16
+ ssl_version:
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: veronic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gabriel Klein
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-05 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple cloud deployer
15
+ email: gabriel.klein.fr@gmail.com
16
+ executables:
17
+ - veronic
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - README.md
23
+ - bin/veronic
24
+ - lib/deployer.rb
25
+ - lib/providers/chefserver/chefserver.rb
26
+ - lib/providers/chefserver/instance.rb
27
+ - lib/providers/chefserver/rest_request.rb
28
+ - lib/providers/cloudprovider.rb
29
+ - lib/providers/configprovider.rb
30
+ - lib/providers/dnsprovider.rb
31
+ - lib/providers/ec2/ec2.rb
32
+ - lib/providers/ec2/image.rb
33
+ - lib/providers/ec2/instance.rb
34
+ - lib/providers/route53/r53.rb
35
+ - lib/providers/route53/record.rb
36
+ - lib/providers/route53/zone.rb
37
+ - veronic.gemspec
38
+ - veronic.yml
39
+ homepage: http://github.com/GabKlein/veronic
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.24
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Veronic, deux qui la tiennent trois qui la niquent
63
+ test_files: []