veronic 0.0.4
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/.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: []
|