veronic 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.md +26 -0
- data/bin/veronic +160 -0
- data/lib/deployer.rb +109 -0
- data/lib/providers/chefserver/chefserver.rb +54 -0
- data/lib/providers/chefserver/instance.rb +114 -0
- data/lib/providers/chefserver/rest_request.rb +54 -0
- data/lib/providers/cloudprovider.rb +34 -0
- data/lib/providers/configprovider.rb +23 -0
- data/lib/providers/dnsprovider.rb +19 -0
- data/lib/providers/ec2/ec2.rb +34 -0
- data/lib/providers/ec2/image.rb +15 -0
- data/lib/providers/ec2/instance.rb +62 -0
- data/lib/providers/route53/r53.rb +26 -0
- data/lib/providers/route53/record.rb +51 -0
- data/lib/providers/route53/zone.rb +26 -0
- data/veronic.gemspec +13 -0
- data/veronic.yml +16 -0
- metadata +63 -0
data/.gitignore
ADDED
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,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: []
|