chef-vpc-toolkit 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/CHANGELOG +14 -0
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/chef-vpc-toolkit +7 -5
- data/config/server_group.json +2 -2
- data/contrib/etc/chef_vpc_toolkit.conf +4 -0
- data/contrib/rake/Rakefile +5 -4
- data/lib/chef-vpc-toolkit.rb +1 -0
- data/lib/chef-vpc-toolkit/chef-0.9.bash +1 -1
- data/lib/chef-vpc-toolkit/chef_bootstrap/fedora.bash +3 -2
- data/lib/chef-vpc-toolkit/chef_installer.rb +11 -10
- data/lib/chef-vpc-toolkit/cloud_servers_vpc.rb +109 -1
- data/lib/chef-vpc-toolkit/http_util.rb +1 -0
- data/lib/chef-vpc-toolkit/util.rb +5 -0
- data/lib/chef-vpc-toolkit/vpn_network_manager.rb +227 -0
- data/rake/chef_vpc_toolkit.rake +113 -4
- data/test/cloud_servers_vpc_test.rb +19 -64
- data/test/ssh_util_test.rb +21 -0
- data/test/test_helper.rb +150 -1
- data/test/util_test.rb +15 -0
- data/test/vpn_network_manager_test.rb +35 -0
- metadata +27 -4
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.8.7@chef_vpc_toolkit
|
data/CHANGELOG
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
* Tue Jan 11 2011 Dan Prince <dan.prince@rackspace.com> - 2.1.0
|
2
|
+
- Implement 'rake vpn' tasks.
|
3
|
+
- Set permission to 0600 on tmp/server_group files.
|
4
|
+
- Create config/TOOLKIT_VERSION when running chef-vpc-toolkit -upgrade.
|
5
|
+
- Set 'StrictHostKeyChecking no' when using ssh.
|
6
|
+
|
7
|
+
* Thu Dec 7 2010 Dan Prince <dan.prince@rackspace.com> - 2.0.1
|
8
|
+
- Automatically load rake files from the tasks directory.
|
9
|
+
- Rename config file from cloud_toolkit.conf to chef_vpc_toolkit.conf.
|
10
|
+
- Rename variable that can be used to override default config file location
|
11
|
+
to be called CHEF_VPC_TOOLKIT_CONF.
|
12
|
+
|
13
|
+
* Thu Oct 26 2010 Dan Prince <dan.prince@rackspace.com> - 2.0.0
|
14
|
+
- Initial open source release.
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0
|
1
|
+
2.1.0
|
data/bin/chef-vpc-toolkit
CHANGED
@@ -13,17 +13,17 @@ opts = OptionParser.new
|
|
13
13
|
|
14
14
|
options[:name] = ""
|
15
15
|
opts.on("-n name", "--name", String,
|
16
|
-
"Create a new
|
16
|
+
"Create a new project with the given directory name.") do |name|
|
17
17
|
options[:name] = name
|
18
18
|
end
|
19
19
|
|
20
20
|
options[:upgrade] = false
|
21
|
-
opts.on("-u", "--upgrade", "Upgrade a
|
21
|
+
opts.on("-u", "--upgrade", "Upgrade a project to work with the latest Chef VPC Toolkit.") do
|
22
22
|
options[:upgrade] = true
|
23
23
|
end
|
24
24
|
|
25
25
|
opts.on_tail("-v", "--version", "Print version") do
|
26
|
-
puts "
|
26
|
+
puts "Chef VPC Toolkit Version: #{Version::VERSION}"
|
27
27
|
exit
|
28
28
|
end
|
29
29
|
|
@@ -47,10 +47,10 @@ if options[:upgrade]
|
|
47
47
|
|
48
48
|
# Rakefile
|
49
49
|
if not File.exists?("Rakefile") then
|
50
|
-
puts "Unable to find Rakefile. Run the '
|
50
|
+
puts "Unable to find Rakefile. Run the 'chef-vpc-toolkit -u' commmand from within a project directory."
|
51
51
|
exit 1
|
52
52
|
else
|
53
|
-
FileUtils.cp("#{Version::CHEF_VPC_TOOLKIT_ROOT}/contrib/Rakefile", "Rakefile")
|
53
|
+
FileUtils.cp("#{Version::CHEF_VPC_TOOLKIT_ROOT}/contrib/rake/Rakefile", "Rakefile")
|
54
54
|
end
|
55
55
|
|
56
56
|
# chef_installer.yml
|
@@ -58,6 +58,8 @@ if options[:upgrade]
|
|
58
58
|
FileUtils.mv("config/chef_installer.conf", "config/chef_installer.yml")
|
59
59
|
end
|
60
60
|
|
61
|
+
FileUtils.cp("#{Version::CHEF_VPC_TOOLKIT_ROOT}/VERSION", File.join("config", "TOOLKIT_VERSION"))
|
62
|
+
|
61
63
|
else
|
62
64
|
exit_if_nil_or_empty(options, :name)
|
63
65
|
|
data/config/server_group.json
CHANGED
@@ -8,3 +8,7 @@ cloud_servers_vpc_password:
|
|
8
8
|
# The text editor to use for Chef knife commands. Used when a new server group
|
9
9
|
# is created. Default: vim
|
10
10
|
# knife_editor: vim
|
11
|
+
#
|
12
|
+
# VPN client name. The name given to this machine when connecting to a
|
13
|
+
# server group as a VPN client.
|
14
|
+
# vpn_client_name: local
|
data/contrib/rake/Rakefile
CHANGED
@@ -5,9 +5,9 @@ require 'rubygems'
|
|
5
5
|
version_file=(File.join(CHEF_VPC_PROJECT, 'config', 'TOOLKIT_VERSION'))
|
6
6
|
toolkit_version=nil
|
7
7
|
if ENV['CHEF_VPC_TOOLKIT_VERSION'] then
|
8
|
-
|
8
|
+
toolkit_version=ENV['CHEF_VPC_TOOLKIT_VERSION']
|
9
9
|
elsif File.exists?(version_file)
|
10
|
-
|
10
|
+
toolkit_version=IO.read(version_file)
|
11
11
|
end
|
12
12
|
|
13
13
|
#puts "Chef VPC Toolkit Version: #{toolkit_version}"
|
@@ -22,7 +22,8 @@ Dir[File.join("#{ChefVPCToolkit::Version::CHEF_VPC_TOOLKIT_ROOT}/rake", '*.rake'
|
|
22
22
|
import(rakefile)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
if File.exist?(File.join(CHEF_VPC_PROJECT, 'tasks')) then
|
26
|
+
Dir[File.join(File.dirname("__FILE__"), 'tasks', '*.rake')].each do |rakefile|
|
27
27
|
import(rakefile)
|
28
|
+
end
|
28
29
|
end
|
data/lib/chef-vpc-toolkit.rb
CHANGED
@@ -166,7 +166,7 @@ local REPOS_BASEDIR=${2:-"/root/cookbook-repos"}
|
|
166
166
|
for CB_REPO in $COOKBOOK_URLS; do
|
167
167
|
echo -n "Downloading $CB_REPO..."
|
168
168
|
if [ "http:" == ${CB_REPO:0:5} ] || [ "https:" == ${CB_REPO:0:6} ]; then
|
169
|
-
wget "$CB_REPO" -O "/tmp/cookbook-repo.tar.gz" &> /dev/null || { echo "Failed to download cookbook tarball."; return 1; }
|
169
|
+
wget --no-check-certificate "$CB_REPO" -O "/tmp/cookbook-repo.tar.gz" &> /dev/null || { echo "Failed to download cookbook tarball."; return 1; }
|
170
170
|
else
|
171
171
|
download_cloud_file "$CB_REPO" "/tmp/cookbook-repo.tar.gz"
|
172
172
|
fi
|
@@ -34,8 +34,9 @@ validation_key "/etc/chef/validation.pem"
|
|
34
34
|
client_key "/etc/chef/client.pem"
|
35
35
|
EOF_CAT
|
36
36
|
|
37
|
-
|
38
|
-
cp /
|
37
|
+
CHEF_GEM_DIR=$(gem contents chef | sed -e "s|\(.*chef-0.9.8\).*|\1|" | head -n 1)
|
38
|
+
cp $CHEF_GEM_DIR/distro/redhat/etc/init.d/chef-client /etc/init.d/
|
39
|
+
cp $CHEF_GEM_DIR/distro/redhat/etc/logrotate.d/chef-client /etc/logrotate.d/
|
39
40
|
chmod 755 /etc/init.d/chef-client
|
40
41
|
|
41
42
|
}
|
@@ -72,7 +72,7 @@ end
|
|
72
72
|
os_type=machine_os_types[options['chef_server_name']]
|
73
73
|
|
74
74
|
data=%x{
|
75
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
75
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
76
76
|
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
77
77
|
echo "Installing Chef server on: $HOSTNAME"
|
78
78
|
EOF_BASH
|
@@ -81,7 +81,7 @@ EOF_GATEWAY
|
|
81
81
|
puts data
|
82
82
|
|
83
83
|
data=%x{
|
84
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
84
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
85
85
|
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
86
86
|
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
87
87
|
#{IO.read(File.dirname(__FILE__) + "/chef_bootstrap/#{os_type}.bash")}
|
@@ -115,7 +115,7 @@ end
|
|
115
115
|
def self.client_validation_key(options)
|
116
116
|
|
117
117
|
client_validation_key=%x{
|
118
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
118
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
119
119
|
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
120
120
|
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
121
121
|
print_client_validation_key
|
@@ -146,7 +146,7 @@ def self.install_chef_client(options, client_name, client_validation_key, os_typ
|
|
146
146
|
puts "Installing Chef client on: #{client_name}"
|
147
147
|
|
148
148
|
data=%x{
|
149
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
149
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
150
150
|
ssh #{client_name} bash <<-"EOF_BASH"
|
151
151
|
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
152
152
|
#{IO.read(File.dirname(__FILE__) + "/chef_bootstrap/#{os_type}.bash")}
|
@@ -192,15 +192,16 @@ json.each_pair do |bag_name, items_json|
|
|
192
192
|
end
|
193
193
|
|
194
194
|
data=%x{
|
195
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
195
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
196
196
|
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
197
197
|
#{databag_cmds}
|
198
198
|
EOF_GATEWAY
|
199
199
|
}
|
200
|
-
puts "OK."
|
201
200
|
|
202
201
|
end
|
203
202
|
|
203
|
+
puts "OK."
|
204
|
+
|
204
205
|
end
|
205
206
|
|
206
207
|
def self.knife_readd_node(options, client_name)
|
@@ -214,7 +215,7 @@ run_list=node_json['run_list'].inspect
|
|
214
215
|
node_json.delete("run_list")
|
215
216
|
attributes=node_json.to_json.to_s
|
216
217
|
data=%x{
|
217
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
218
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
218
219
|
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
219
220
|
knife_delete_node '#{client_name}'
|
220
221
|
knife_add_node '#{client_name}' '#{run_list}' '#{attributes}'
|
@@ -224,7 +225,7 @@ EOF_GATEWAY
|
|
224
225
|
end
|
225
226
|
|
226
227
|
def self.tail_log(gateway_ip, server_name, log_file="/var/log/chef/client.log", num_lines="100")
|
227
|
-
%x{ssh root@#{gateway_ip} ssh #{server_name} tail -n #{num_lines} #{log_file}}
|
228
|
+
%x{ssh -o "StrictHostKeyChecking no" root@#{gateway_ip} ssh #{server_name} tail -n #{num_lines} #{log_file}}
|
228
229
|
end
|
229
230
|
|
230
231
|
def self.rsync_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-repos/", remote_directory="/root/cookbook-repos")
|
@@ -232,7 +233,7 @@ def self.rsync_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-r
|
|
232
233
|
if File.exists?(local_dir) then
|
233
234
|
$stdout.printf "Syncing local Chef cookbook repositories..."
|
234
235
|
configs=Util.load_configs
|
235
|
-
%x{ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
236
|
+
%x{ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
236
237
|
mkdir -p #{remote_directory}
|
237
238
|
if [ -f /usr/bin/yum ]; then
|
238
239
|
rpm -q rsync &> /dev/null || yum install -y -q rsync
|
@@ -251,7 +252,7 @@ def self.rsync_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-r
|
|
251
252
|
end
|
252
253
|
|
253
254
|
data=%x{
|
254
|
-
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
255
|
+
ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
255
256
|
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
256
257
|
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
257
258
|
|
@@ -83,7 +83,8 @@ module CloudServersVPC
|
|
83
83
|
hash["description"]=sg.elements["description"].text
|
84
84
|
hash["id"]=sg.elements["id"].text
|
85
85
|
hash["domain-name"]=sg.elements["domain-name"].text
|
86
|
-
|
86
|
+
hash["vpn-network"]=sg.elements["vpn-network"].text
|
87
|
+
hash["vpn-subnet"]=sg.elements["vpn-subnet"].text
|
87
88
|
hash["servers"]={}
|
88
89
|
REXML::XPath.each(dom, "//server") do |server|
|
89
90
|
server_name=server.elements["name"].text
|
@@ -180,6 +181,21 @@ module CloudServersVPC
|
|
180
181
|
|
181
182
|
end
|
182
183
|
|
184
|
+
# Return the name of the VPN server within a server group
|
185
|
+
def self.vpn_server_name(hash)
|
186
|
+
|
187
|
+
hash["servers"].each_pair do |name, hash|
|
188
|
+
if hash['openvpn-server'] and hash['openvpn-server'] == "true" then
|
189
|
+
if block_given? then
|
190
|
+
yield name
|
191
|
+
else
|
192
|
+
return name
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
183
199
|
# default timeout of 20 minutes
|
184
200
|
def self.poll_until_online(group_id, timeout=1200)
|
185
201
|
|
@@ -229,6 +245,8 @@ module CloudServersVPC
|
|
229
245
|
"centos"
|
230
246
|
when 187811 # Centos 5.4
|
231
247
|
"centos"
|
248
|
+
when 71 # Fedora 14
|
249
|
+
"fedora"
|
232
250
|
when 53 # Fedora 13
|
233
251
|
"fedora"
|
234
252
|
when 17 # Fedora 12
|
@@ -280,6 +298,96 @@ module CloudServersVPC
|
|
280
298
|
|
281
299
|
end
|
282
300
|
|
301
|
+
def self.client_hash(xml)
|
302
|
+
|
303
|
+
hash={}
|
304
|
+
dom = REXML::Document.new(xml)
|
305
|
+
REXML::XPath.each(dom, "/client") do |client|
|
306
|
+
|
307
|
+
hash["name"]=client.elements["name"].text
|
308
|
+
hash["description"]=client.elements["description"].text
|
309
|
+
hash["id"]=client.elements["id"].text
|
310
|
+
hash["status"]=client.elements["status"].text
|
311
|
+
hash["server-group-id"]=client.elements["server-group-id"].text
|
312
|
+
hash["vpn-network-interfaces"]=[]
|
313
|
+
REXML::XPath.each(dom, "//vpn-network-interface") do |vni|
|
314
|
+
client_attributes={
|
315
|
+
"id" => vni.elements["id"].text,
|
316
|
+
"vpn-ip-addr" => vni.elements["vpn-ip-addr"].text,
|
317
|
+
"ptp-ip-addr" => vni.elements["ptp-ip-addr"].text,
|
318
|
+
"client-key" => vni.elements["client-key"].text,
|
319
|
+
"client-cert" => vni.elements["client-cert"].text,
|
320
|
+
"ca-cert" => vni.elements["ca-cert"].text
|
321
|
+
}
|
322
|
+
hash["vpn-network-interfaces"] << client_attributes
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
hash
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
def self.poll_client(client_id, timeout=300)
|
331
|
+
|
332
|
+
configs=Util.load_configs
|
333
|
+
|
334
|
+
online = false
|
335
|
+
count=0
|
336
|
+
until online or (count*5) >= timeout.to_i do
|
337
|
+
count+=1
|
338
|
+
begin
|
339
|
+
xml=HttpUtil.get(
|
340
|
+
configs["cloud_servers_vpc_url"]+"/clients/#{client_id}.xml",
|
341
|
+
configs["cloud_servers_vpc_username"],
|
342
|
+
configs["cloud_servers_vpc_password"]
|
343
|
+
)
|
344
|
+
hash=CloudServersVPC.client_hash(xml)
|
345
|
+
|
346
|
+
if hash["status"] == "Online" then
|
347
|
+
online = true
|
348
|
+
else
|
349
|
+
yield hash if block_given?
|
350
|
+
sleep 5
|
351
|
+
end
|
352
|
+
rescue EOFError
|
353
|
+
end
|
354
|
+
end
|
355
|
+
if (count*20) >= timeout.to_i then
|
356
|
+
raise "Timeout waiting for client to come online."
|
357
|
+
end
|
358
|
+
|
359
|
+
end
|
360
|
+
|
361
|
+
def self.client_xml_for_id(configs, dir, id=nil)
|
362
|
+
|
363
|
+
xml=HttpUtil.get(
|
364
|
+
configs["cloud_servers_vpc_url"]+"/clients/#{id}.xml",
|
365
|
+
configs["cloud_servers_vpc_username"],
|
366
|
+
configs["cloud_servers_vpc_password"]
|
367
|
+
)
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
def self.create_client(server_group_hash, client_name)
|
372
|
+
|
373
|
+
configs=Util.load_configs
|
374
|
+
|
375
|
+
xml = Builder::XmlMarkup.new
|
376
|
+
xml.client do |client|
|
377
|
+
client.name(client_name)
|
378
|
+
client.description("Toolkit Client: #{client_name}")
|
379
|
+
client.tag! "server-group-id", server_group_hash['id']
|
380
|
+
end
|
381
|
+
|
382
|
+
HttpUtil.post(
|
383
|
+
configs["cloud_servers_vpc_url"]+"/clients.xml",
|
384
|
+
xml.target!,
|
385
|
+
configs["cloud_servers_vpc_username"],
|
386
|
+
configs["cloud_servers_vpc_password"]
|
387
|
+
)
|
388
|
+
|
389
|
+
end
|
390
|
+
|
283
391
|
end
|
284
392
|
|
285
393
|
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'builder'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'rexml/xpath'
|
5
|
+
require 'uuidtools'
|
6
|
+
require 'ipaddr'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'tempfile'
|
9
|
+
|
10
|
+
module ChefVPCToolkit
|
11
|
+
|
12
|
+
module VpnNetworkManager
|
13
|
+
|
14
|
+
CERT_DIR=File.join(ENV['HOME'], '.pki', 'openvpn')
|
15
|
+
|
16
|
+
def self.configure_gconf(group_hash, client_hash)
|
17
|
+
|
18
|
+
ca_cert=File.join(CERT_DIR, group_hash['id'], 'ca.crt')
|
19
|
+
client_cert=File.join(CERT_DIR, group_hash['id'], 'client.crt')
|
20
|
+
client_key=File.join(CERT_DIR, group_hash['id'], 'client.key')
|
21
|
+
|
22
|
+
vpn_interface=client_hash['vpn-network-interfaces'][0]
|
23
|
+
|
24
|
+
FileUtils.mkdir_p(File.join(CERT_DIR, group_hash['id']))
|
25
|
+
File::chmod(0700, File.join(ENV['HOME'], '.pki'))
|
26
|
+
File::chmod(0700, CERT_DIR)
|
27
|
+
|
28
|
+
File.open(ca_cert, 'w') { |f| f.write(vpn_interface['ca-cert']) }
|
29
|
+
File.open(client_cert, 'w') { |f| f.write(vpn_interface['client-cert']) }
|
30
|
+
File.open(client_key, 'w') do |f|
|
31
|
+
f.write(vpn_interface['client-key'])
|
32
|
+
f.chmod(0600)
|
33
|
+
end
|
34
|
+
|
35
|
+
xml = Builder::XmlMarkup.new
|
36
|
+
xml.gconfentryfile do |file|
|
37
|
+
file.entrylist({ "base" => "/system/networking/connections/vpc_#{group_hash['id']}"}) do |entrylist|
|
38
|
+
|
39
|
+
entrylist.entry do |entry|
|
40
|
+
entry.key("connection/autoconnect")
|
41
|
+
entry.value do |value|
|
42
|
+
value.bool("false")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
entrylist.entry do |entry|
|
46
|
+
entry.key("connection/id")
|
47
|
+
entry.value do |value|
|
48
|
+
value.string("VPC Group: #{group_hash['id']}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
entrylist.entry do |entry|
|
52
|
+
entry.key("connection/name")
|
53
|
+
entry.value do |value|
|
54
|
+
value.string("connection")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
entrylist.entry do |entry|
|
58
|
+
entry.key("connection/timestamp")
|
59
|
+
entry.value do |value|
|
60
|
+
value.string(Time.now.to_i.to_s)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
entrylist.entry do |entry|
|
64
|
+
entry.key("connection/type")
|
65
|
+
entry.value do |value|
|
66
|
+
value.string("vpn")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
entrylist.entry do |entry|
|
70
|
+
entry.key("connection/uuid")
|
71
|
+
entry.value do |value|
|
72
|
+
value.string(UUIDTools::UUID.random_create)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
entrylist.entry do |entry|
|
76
|
+
entry.key("ipv4/addresses")
|
77
|
+
entry.value do |value|
|
78
|
+
value.list("type" => "int") do |list|
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
entrylist.entry do |entry|
|
83
|
+
entry.key("ipv4/dns")
|
84
|
+
entry.value do |value|
|
85
|
+
value.list("type" => "int") do |list|
|
86
|
+
ip=IPAddr.new(group_hash['vpn-network'].chomp("0")+"1")
|
87
|
+
list.value do |lv|
|
88
|
+
lv.int(ip_to_integer(ip.to_s))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
entrylist.entry do |entry|
|
94
|
+
entry.key("ipv4/dns-search")
|
95
|
+
entry.value do |value|
|
96
|
+
value.list("type" => "string") do |list|
|
97
|
+
list.value do |lv|
|
98
|
+
lv.string(group_hash['domain-name'])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
entrylist.entry do |entry|
|
104
|
+
entry.key("ipv4/ignore-auto-dns")
|
105
|
+
entry.value do |value|
|
106
|
+
value.bool("true")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
entrylist.entry do |entry|
|
110
|
+
entry.key("ipv4/method")
|
111
|
+
entry.value do |value|
|
112
|
+
value.string("auto")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
entrylist.entry do |entry|
|
116
|
+
entry.key("ipv4/name")
|
117
|
+
entry.value do |value|
|
118
|
+
value.string("ipv4")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
entrylist.entry do |entry|
|
122
|
+
entry.key("ipv4/never-default")
|
123
|
+
entry.value do |value|
|
124
|
+
value.bool("true")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
entrylist.entry do |entry|
|
128
|
+
entry.key("ipv4/routes")
|
129
|
+
entry.value do |value|
|
130
|
+
value.list("type" => "int") do |list|
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
entrylist.entry do |entry|
|
135
|
+
entry.key("vpn/ca")
|
136
|
+
entry.value do |value|
|
137
|
+
value.string(ca_cert)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
entrylist.entry do |entry|
|
141
|
+
entry.key("vpn/cert")
|
142
|
+
entry.value do |value|
|
143
|
+
value.string(client_cert)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
entrylist.entry do |entry|
|
147
|
+
entry.key("vpn/comp-lzo")
|
148
|
+
entry.value do |value|
|
149
|
+
value.string("yes")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
entrylist.entry do |entry|
|
153
|
+
entry.key("vpn/connection-type")
|
154
|
+
entry.value do |value|
|
155
|
+
value.string("tls")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
entrylist.entry do |entry|
|
159
|
+
entry.key("vpn/key")
|
160
|
+
entry.value do |value|
|
161
|
+
value.string(client_key)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
entrylist.entry do |entry|
|
165
|
+
entry.key("vpn/proto-tcp")
|
166
|
+
entry.value do |value|
|
167
|
+
value.string("yes")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
entrylist.entry do |entry|
|
171
|
+
entry.key("vpn/remote")
|
172
|
+
entry.value do |value|
|
173
|
+
value.string(group_hash['vpn-gateway'])
|
174
|
+
end
|
175
|
+
end
|
176
|
+
entrylist.entry do |entry|
|
177
|
+
entry.key("vpn/service-type")
|
178
|
+
entry.value do |value|
|
179
|
+
value.string("org.freedesktop.NetworkManager.openvpn")
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
Tempfile.open('w') do |f|
|
187
|
+
f.write(xml.target!)
|
188
|
+
f.flush
|
189
|
+
puts %x{gconftool-2 --load #{f.path}}
|
190
|
+
end
|
191
|
+
|
192
|
+
return true
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.unset_gconf_config(server_group_id)
|
197
|
+
puts %x{gconftool-2 --recursive-unset /system/networking/connections/vpc_#{server_group_id}}
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.delete_certs(server_group_id)
|
201
|
+
FileUtils.rm_rf(File.join(CERT_DIR, server_group_id))
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.connect(server_group_id)
|
205
|
+
puts %x{#{sudo_display} nmcli con up id "VPC Group: #{server_group_id}"}
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.disconnect(server_group_id)
|
209
|
+
puts %x{#{sudo_display} nmcli con down id "VPC Group: #{server_group_id}"}
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.ip_to_integer(ip_string)
|
213
|
+
return 0 if ip_string.nil?
|
214
|
+
ip_arr=ip_string.each(".").collect{ |s| s.chomp(".").to_i}
|
215
|
+
return ip_arr[0] + ip_arr[1]*2**8 + ip_arr[2]*2**16 + ip_arr[3]*2**24
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.sudo_display
|
219
|
+
if ENV['DISPLAY'].nil? or ENV['DISPLAY'] != ":0.0" then
|
220
|
+
"sudo"
|
221
|
+
else
|
222
|
+
""
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|
data/rake/chef_vpc_toolkit.rake
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
namespace :group do
|
4
4
|
TMP_SG=File.join(CHEF_VPC_PROJECT, 'tmp', 'server_groups')
|
5
|
+
TMP_CLIENTS=File.join(CHEF_VPC_PROJECT, 'tmp', 'clients')
|
5
6
|
|
6
7
|
directory TMP_SG
|
8
|
+
directory TMP_CLIENTS
|
7
9
|
|
8
10
|
desc "Create a new group of cloud servers"
|
9
11
|
task :create => [ TMP_SG, "chef:validate_json" ] do
|
@@ -20,7 +22,10 @@ namespace :group do
|
|
20
22
|
|
21
23
|
hash=CloudServersVPC.server_group_hash(resp)
|
22
24
|
out_file=hash["id"]+".xml"
|
23
|
-
File.open(File.join(TMP_SG, out_file), 'w')
|
25
|
+
File.open(File.join(TMP_SG, out_file), 'w') do |f|
|
26
|
+
f.chmod(0600)
|
27
|
+
f.write(resp)
|
28
|
+
end
|
24
29
|
puts "Cloud server group ID #{hash['id']} created."
|
25
30
|
|
26
31
|
end
|
@@ -51,13 +56,16 @@ namespace :group do
|
|
51
56
|
xml=CloudServersVPC.server_group_xml_for_id(configs, File.join(TMP_SG, '*.xml'), id)
|
52
57
|
|
53
58
|
hash=CloudServersVPC.server_group_hash(xml)
|
54
|
-
File.open(File.join(TMP_SG, "#{hash['id']}.xml"), 'w')
|
59
|
+
File.open(File.join(TMP_SG, "#{hash['id']}.xml"), 'w') do |f|
|
60
|
+
f.chmod(0600)
|
61
|
+
f.write(xml)
|
62
|
+
end
|
55
63
|
CloudServersVPC.print_server_group(hash)
|
56
64
|
|
57
65
|
end
|
58
66
|
|
59
67
|
desc "Delete a cloud server group"
|
60
|
-
task :delete do
|
68
|
+
task :delete => "vpn:delete" do
|
61
69
|
id=ENV['GROUP_ID']
|
62
70
|
configs=Util.load_configs
|
63
71
|
hash=Util.hash_for_group
|
@@ -72,6 +80,7 @@ namespace :group do
|
|
72
80
|
configs["cloud_servers_vpc_password"]
|
73
81
|
)
|
74
82
|
File.delete(File.join(TMP_SG, "#{id}.xml"))
|
83
|
+
|
75
84
|
end
|
76
85
|
|
77
86
|
desc "Force clean the cached server group files"
|
@@ -203,10 +212,106 @@ namespace :share do
|
|
203
212
|
|
204
213
|
end
|
205
214
|
|
215
|
+
namespace :vpn do
|
216
|
+
|
217
|
+
desc "Connect to a server group as a VPN client."
|
218
|
+
task :connect do
|
219
|
+
|
220
|
+
puts "Creating VPN Connection..."
|
221
|
+
configs=Util.load_configs
|
222
|
+
group_hash=Util.hash_for_group(configs)
|
223
|
+
if not File.exists?(File.join(TMP_CLIENTS, group_hash['id']+'.xml')) then
|
224
|
+
Rake::Task['vpn:create_client'].invoke
|
225
|
+
Rake::Task['vpn:poll_client'].invoke
|
226
|
+
end
|
227
|
+
client_hash=CloudServersVPC.client_hash(IO.read(File.join(TMP_CLIENTS, group_hash['id']+'.xml')))
|
228
|
+
ChefVPCToolkit::VpnNetworkManager.configure_gconf(group_hash, client_hash)
|
229
|
+
ChefVPCToolkit::VpnNetworkManager.connect(group_hash['id'])
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
desc "Disconnect from a server group as a VPN client."
|
234
|
+
task :disconnect do
|
235
|
+
|
236
|
+
configs=Util.load_configs
|
237
|
+
group_hash=Util.hash_for_group(configs)
|
238
|
+
ChefVPCToolkit::VpnNetworkManager.disconnect(group_hash['id'])
|
239
|
+
|
240
|
+
vpn_server_ip=group_hash["vpn-network"].chomp("0")+"1"
|
241
|
+
SshUtil.remove_known_hosts_ip(vpn_server_ip)
|
242
|
+
SshUtil.remove_known_hosts_ip("#{CloudServersVPC.vpn_server_name(group_hash)},#{vpn_server_ip}")
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
desc "Delete VPN config information."
|
247
|
+
task :delete do
|
248
|
+
|
249
|
+
configs=Util.load_configs
|
250
|
+
group_hash=Util.hash_for_group(configs)
|
251
|
+
group_id=group_hash['id']
|
252
|
+
ChefVPCToolkit::VpnNetworkManager.unset_gconf_config(group_id)
|
253
|
+
ChefVPCToolkit::VpnNetworkManager.delete_certs(group_id)
|
254
|
+
client_file=File.join(TMP_CLIENTS, "#{group_id}.xml")
|
255
|
+
|
256
|
+
vpn_server_ip=group_hash["vpn-network"].chomp("0")+"1"
|
257
|
+
SshUtil.remove_known_hosts_ip(vpn_server_ip)
|
258
|
+
SshUtil.remove_known_hosts_ip("#{CloudServersVPC.vpn_server_name(group_hash)},#{vpn_server_ip}")
|
259
|
+
|
260
|
+
if File.exists?(client_file) then
|
261
|
+
File.delete(client_file)
|
262
|
+
end
|
263
|
+
|
264
|
+
end
|
265
|
+
|
266
|
+
desc "Create a new VPN client."
|
267
|
+
task :create_client => [ TMP_CLIENTS ] do
|
268
|
+
|
269
|
+
configs=Util.load_configs
|
270
|
+
group_hash=Util.hash_for_group(configs)
|
271
|
+
|
272
|
+
vpn_client_name=Util.hostname
|
273
|
+
if not configs['vpn_client_name'].nil? then
|
274
|
+
vpn_client_name=configs['vpn_client_name']
|
275
|
+
end
|
276
|
+
|
277
|
+
xml=CloudServersVPC.create_client(group_hash, vpn_client_name)
|
278
|
+
client_hash=CloudServersVPC.client_hash(xml)
|
279
|
+
out_file=group_hash["id"]+".xml"
|
280
|
+
File.open(File.join(TMP_CLIENTS, out_file), 'w') do |f|
|
281
|
+
f.chmod(0600)
|
282
|
+
f.write(xml)
|
283
|
+
end
|
284
|
+
puts "Client ID #{client_hash['id']} created."
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
desc "Poll until a client is online"
|
289
|
+
task :poll_client => TMP_CLIENTS do
|
290
|
+
timeout=ENV['VPN_CLIENT_TIMEOUT']
|
291
|
+
if timeout.nil? or timeout.empty? then
|
292
|
+
timeout=300 # defaults to 5 minutes
|
293
|
+
end
|
294
|
+
configs=Util.load_configs
|
295
|
+
group_hash=Util.hash_for_group
|
296
|
+
client_hash=CloudServersVPC.client_hash(IO.read(File.join(TMP_CLIENTS, group_hash['id']+'.xml')))
|
297
|
+
puts "Polling for client VPN cert to be created (this may take a minute)...."
|
298
|
+
CloudServersVPC.poll_client(client_hash["id"], timeout)
|
299
|
+
xml=CloudServersVPC.client_xml_for_id(configs, TMP_CLIENTS, client_hash["id"])
|
300
|
+
out_file=group_hash["id"]+".xml"
|
301
|
+
File.open(File.join(TMP_CLIENTS, out_file), 'w') do |f|
|
302
|
+
f.chmod(0600)
|
303
|
+
f.write(xml)
|
304
|
+
end
|
305
|
+
puts "Client VPN certs are ready to use."
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
206
311
|
desc "SSH into the most recently created VPN gateway server."
|
207
312
|
task :ssh do
|
208
313
|
hash=Util.hash_for_group
|
209
|
-
exec("ssh root@#{hash['vpn-gateway']}")
|
314
|
+
exec("ssh -o \"StrictHostKeyChecking no\" root@#{hash['vpn-gateway']}")
|
210
315
|
end
|
211
316
|
|
212
317
|
desc "Create a server group, install chef, sync share data and cookbooks."
|
@@ -236,6 +341,10 @@ task :rechef => [ "server:rebuild", "group:poll" ] do
|
|
236
341
|
|
237
342
|
end
|
238
343
|
|
344
|
+
desc "Alias to the vpn:connect task."
|
345
|
+
task :vpn => "vpn:connect"
|
346
|
+
|
347
|
+
|
239
348
|
desc "Print help and usage information"
|
240
349
|
task :usage do
|
241
350
|
|
@@ -6,72 +6,8 @@ module ChefVPCToolkit
|
|
6
6
|
|
7
7
|
class CloudServersVPCTest < Test::Unit::TestCase
|
8
8
|
|
9
|
-
SERVER_GROUP_XML = %{
|
10
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
11
|
-
<server-group>
|
12
|
-
<created-at type="datetime">2010-10-15T15:15:58-04:00</created-at>
|
13
|
-
<description>test description</description>
|
14
|
-
<domain-name>mydomain.net</domain-name>
|
15
|
-
<historical type="boolean">false</historical>
|
16
|
-
<id type="integer">1759</id>
|
17
|
-
<last-used-ip-address>172.19.0.2</last-used-ip-address>
|
18
|
-
<name>test</name>
|
19
|
-
<owner-name>dan.prince</owner-name>
|
20
|
-
<updated-at type="datetime">2010-10-15T15:15:58-04:00</updated-at>
|
21
|
-
<user-id type="integer">3</user-id>
|
22
|
-
<vpn-network>172.19.0.0</vpn-network>
|
23
|
-
<vpn-subnet>255.255.128.0</vpn-subnet>
|
24
|
-
<servers type="array">
|
25
|
-
<server>
|
26
|
-
<account-id type="integer">3</account-id>
|
27
|
-
<cloud-server-id-number type="integer">1</cloud-server-id-number>
|
28
|
-
<created-at type="datetime">2010-10-15T15:15:58-04:00</created-at>
|
29
|
-
<description>login1</description>
|
30
|
-
<error-message nil="true"></error-message>
|
31
|
-
<external-ip-addr>184.106.205.120</external-ip-addr>
|
32
|
-
<flavor-id type="integer">4</flavor-id>
|
33
|
-
<historical type="boolean">false</historical>
|
34
|
-
<id type="integer">5513</id>
|
35
|
-
<image-id type="integer">14</image-id>
|
36
|
-
<internal-ip-addr>10.179.107.203</internal-ip-addr>
|
37
|
-
<name>login1</name>
|
38
|
-
<openvpn-server type="boolean">true</openvpn-server>
|
39
|
-
<retry-count type="integer">0</retry-count>
|
40
|
-
<server-group-id type="integer">1759</server-group-id>
|
41
|
-
<status>Online</status>
|
42
|
-
<updated-at type="datetime">2010-10-15T15:18:22-04:00</updated-at>
|
43
|
-
<vpn-network-interfaces type="array"/>
|
44
|
-
</server>
|
45
|
-
<server>
|
46
|
-
<account-id type="integer">3</account-id>
|
47
|
-
<cloud-server-id-number type="integer">2</cloud-server-id-number>
|
48
|
-
<created-at type="datetime">2010-10-15T15:15:58-04:00</created-at>
|
49
|
-
<description>test1</description>
|
50
|
-
<error-message nil="true"></error-message>
|
51
|
-
<external-ip-addr>184.106.205.121</external-ip-addr>
|
52
|
-
<flavor-id type="integer">49</flavor-id>
|
53
|
-
<historical type="boolean">false</historical>
|
54
|
-
<id type="integer">5513</id>
|
55
|
-
<image-id type="integer">49</image-id>
|
56
|
-
<internal-ip-addr>10.179.107.204</internal-ip-addr>
|
57
|
-
<name>test1</name>
|
58
|
-
<openvpn-server type="boolean">false</openvpn-server>
|
59
|
-
<retry-count type="integer">0</retry-count>
|
60
|
-
<server-group-id type="integer">1759</server-group-id>
|
61
|
-
<status>Online</status>
|
62
|
-
<updated-at type="datetime">2010-10-15T15:18:22-04:00</updated-at>
|
63
|
-
<vpn-network-interfaces type="array"/>
|
64
|
-
</server>
|
65
|
-
</servers>
|
66
|
-
</server-group>
|
67
|
-
}
|
68
|
-
|
69
9
|
def test_os_types
|
70
10
|
|
71
|
-
#response = mock()
|
72
|
-
#response.stubs(:code => "200", :body => json_response)
|
73
|
-
|
74
|
-
#@conn.stubs(:csreq).returns(response)
|
75
11
|
hash=CloudServersVPC.server_group_hash(SERVER_GROUP_XML)
|
76
12
|
os_types=CloudServersVPC.os_types(hash)
|
77
13
|
|
@@ -169,6 +105,25 @@ SERVER_GROUP_XML = %{
|
|
169
105
|
|
170
106
|
end
|
171
107
|
|
108
|
+
def test_create_client
|
109
|
+
|
110
|
+
response={}
|
111
|
+
response.stubs(:code).returns('200')
|
112
|
+
HttpUtil.stubs(:post).returns(response)
|
113
|
+
|
114
|
+
hash=CloudServersVPC.server_group_hash(SERVER_GROUP_XML)
|
115
|
+
|
116
|
+
assert "200", CloudServersVPC.create_client(hash, "test1").code
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_vpn_server_name
|
121
|
+
|
122
|
+
hash=CloudServersVPC.server_group_hash(SERVER_GROUP_XML)
|
123
|
+
assert_equal "login1", CloudServersVPC.vpn_server_name(hash)
|
124
|
+
|
125
|
+
end
|
126
|
+
|
172
127
|
end
|
173
128
|
|
174
129
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module ChefVPCToolkit
|
6
|
+
|
7
|
+
class SshUtilTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def test_remove_known_hosts_ip
|
10
|
+
|
11
|
+
t=Tempfile.new('ssh_test')
|
12
|
+
t.write(%{login,172.19.0.1 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu1Xfhjj0hZwDIXWa6Gd/Qk/S9VwO5ec9+u6CMLMteQY4seeXmpu643k8zCa6yLuDXyzucknfrsxtOKJVQ6F5glXW6+Ko/zPiPNQbeC6GIKDs2a3m6A5OJSqRHqoy0RTJu11Acs3tkWUgmvBKFX7jxEZuHJM1kI0/xP0JlO0zOVr8+9Wg6Zy5KfVnEsgbdaEvpk3Rrtt5Lm42w/uxvPTFY7AWBhUfloYqBQrX6zd8d17jHLCnukHmvdR7eVGihXREtvDjX4ycG1o5/9amLWR0ELVFkFiXPHyWCuyl21j5uI7Ro9P2pga5ypnDB+N1BjFJHSMMofT40XOBkzAxBUrLgw==\n})
|
13
|
+
t.flush
|
14
|
+
SshUtil.remove_known_hosts_ip('login,172.19.0.1', t.path)
|
15
|
+
assert_equal "", IO.read(t.path)
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -12,7 +12,7 @@ require 'fileutils'
|
|
12
12
|
|
13
13
|
class TmpDir
|
14
14
|
|
15
|
-
def self.new_tmp_dir(prefix="chef-
|
15
|
+
def self.new_tmp_dir(prefix="chef-vpc-toolkit")
|
16
16
|
|
17
17
|
tmp_file=Tempfile.new prefix
|
18
18
|
path=tmp_file.path
|
@@ -23,3 +23,152 @@ class TmpDir
|
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
26
|
+
|
27
|
+
SERVER_GROUP_XML = %{
|
28
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
29
|
+
<server-group>
|
30
|
+
<created-at type="datetime">2010-10-15T15:15:58-04:00</created-at>
|
31
|
+
<description>test description</description>
|
32
|
+
<domain-name>mydomain.net</domain-name>
|
33
|
+
<historical type="boolean">false</historical>
|
34
|
+
<id type="integer">1759</id>
|
35
|
+
<last-used-ip-address>172.19.0.2</last-used-ip-address>
|
36
|
+
<name>test</name>
|
37
|
+
<owner-name>dan.prince</owner-name>
|
38
|
+
<updated-at type="datetime">2010-10-15T15:15:58-04:00</updated-at>
|
39
|
+
<user-id type="integer">3</user-id>
|
40
|
+
<vpn-network>172.19.0.0</vpn-network>
|
41
|
+
<vpn-subnet>255.255.128.0</vpn-subnet>
|
42
|
+
<servers type="array">
|
43
|
+
<server>
|
44
|
+
<account-id type="integer">3</account-id>
|
45
|
+
<cloud-server-id-number type="integer">1</cloud-server-id-number>
|
46
|
+
<created-at type="datetime">2010-10-15T15:15:58-04:00</created-at>
|
47
|
+
<description>login1</description>
|
48
|
+
<error-message nil="true"></error-message>
|
49
|
+
<external-ip-addr>184.106.205.120</external-ip-addr>
|
50
|
+
<flavor-id type="integer">4</flavor-id>
|
51
|
+
<historical type="boolean">false</historical>
|
52
|
+
<id type="integer">5513</id>
|
53
|
+
<image-id type="integer">14</image-id>
|
54
|
+
<internal-ip-addr>10.179.107.203</internal-ip-addr>
|
55
|
+
<name>login1</name>
|
56
|
+
<openvpn-server type="boolean">true</openvpn-server>
|
57
|
+
<retry-count type="integer">0</retry-count>
|
58
|
+
<server-group-id type="integer">1759</server-group-id>
|
59
|
+
<status>Online</status>
|
60
|
+
<updated-at type="datetime">2010-10-15T15:18:22-04:00</updated-at>
|
61
|
+
<vpn-network-interfaces type="array"/>
|
62
|
+
</server>
|
63
|
+
<server>
|
64
|
+
<account-id type="integer">3</account-id>
|
65
|
+
<cloud-server-id-number type="integer">2</cloud-server-id-number>
|
66
|
+
<created-at type="datetime">2010-10-15T15:15:58-04:00</created-at>
|
67
|
+
<description>test1</description>
|
68
|
+
<error-message nil="true"></error-message>
|
69
|
+
<external-ip-addr>184.106.205.121</external-ip-addr>
|
70
|
+
<flavor-id type="integer">49</flavor-id>
|
71
|
+
<historical type="boolean">false</historical>
|
72
|
+
<id type="integer">5513</id>
|
73
|
+
<image-id type="integer">49</image-id>
|
74
|
+
<internal-ip-addr>10.179.107.204</internal-ip-addr>
|
75
|
+
<name>test1</name>
|
76
|
+
<openvpn-server type="boolean">false</openvpn-server>
|
77
|
+
<retry-count type="integer">0</retry-count>
|
78
|
+
<server-group-id type="integer">1759</server-group-id>
|
79
|
+
<status>Online</status>
|
80
|
+
<updated-at type="datetime">2010-10-15T15:18:22-04:00</updated-at>
|
81
|
+
<vpn-network-interfaces type="array"/>
|
82
|
+
</server>
|
83
|
+
</servers>
|
84
|
+
</server-group>
|
85
|
+
}
|
86
|
+
|
87
|
+
CLIENT_XML = %{
|
88
|
+
<client>
|
89
|
+
<created-at type="datetime">2011-01-09T19:37:32-05:00</created-at>
|
90
|
+
<description>Toolkit Client: local</description>
|
91
|
+
<id type="integer">5</id>
|
92
|
+
<is-windows type="boolean">false</is-windows>
|
93
|
+
<name>local</name>
|
94
|
+
<server-group-id type="integer">11</server-group-id>
|
95
|
+
<status>Online</status>
|
96
|
+
<updated-at type="datetime">2011-01-09T19:37:37-05:00</updated-at>
|
97
|
+
<vpn-network-interfaces type="array">
|
98
|
+
<vpn-network-interface>
|
99
|
+
<ca-cert>-----BEGIN CERTIFICATE-----
|
100
|
+
MIIDyDCCAzGgAwIBAgIJAORNZNRpPx87MA0GCSqGSIb3DQEBBQUAMIGfMQswCQYD
|
101
|
+
VQQGEwJVUzELMAkGA1UECBMCVkExEzARBgNVBAcTCkJsYWNrc2J1cmcxEjAQBgNV
|
102
|
+
BAoTCVJhY2tzcGFjZTEXMBUGA1UECxMOSW5mcmFzdHJ1Y3R1cmUxDjAMBgNVBAMT
|
103
|
+
BWxvZ2luMQ4wDAYDVQQpEwVsb2dpbjEhMB8GCSqGSIb3DQEJARYSY29icmFAc25h
|
104
|
+
a2VvaWwuY29tMB4XDTExMDExMDAwMzI1NVoXDTIxMDEwNzAwMzI1NVowgZ8xCzAJ
|
105
|
+
BgNVBAYTAlVTMQswCQYDVQQIEwJWQTETMBEGA1UEBxMKQmxhY2tzYnVyZzESMBAG
|
106
|
+
A1UEChMJUmFja3NwYWNlMRcwFQYDVQQLEw5JbmZyYXN0cnVjdHVyZTEOMAwGA1UE
|
107
|
+
AxMFbG9naW4xDjAMBgNVBCkTBWxvZ2luMSEwHwYJKoZIhvcNAQkBFhJjb2JyYUBz
|
108
|
+
bmFrZW9pbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0xIVIfh8rA
|
109
|
+
OCfc4BbWG+W+53iP9J6Fqhya5HSrYw3pdUCdimRBwQ0HoEnHndz2soRYc2Wtat8L
|
110
|
+
qqoS/qZMBbqerzEUFHumSKLADT3y8G1gkiGsb1fBZPmExPYyG/UQQUfK7CIM/L/m
|
111
|
+
W6Ji5ZEfTF9QPwHj3kVU99VUvm/BS8wXAgMBAAGjggEIMIIBBDAdBgNVHQ4EFgQU
|
112
|
+
dOvLRyxDa2Xso59PFLf22sZQ07wwgdQGA1UdIwSBzDCByYAUdOvLRyxDa2Xso59P
|
113
|
+
FLf22sZQ07yhgaWkgaIwgZ8xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJWQTETMBEG
|
114
|
+
A1UEBxMKQmxhY2tzYnVyZzESMBAGA1UEChMJUmFja3NwYWNlMRcwFQYDVQQLEw5J
|
115
|
+
bmZyYXN0cnVjdHVyZTEOMAwGA1UEAxMFbG9naW4xDjAMBgNVBCkTBWxvZ2luMSEw
|
116
|
+
HwYJKoZIhvcNAQkBFhJjb2JyYUBzbmFrZW9pbC5jb22CCQDkTWTUaT8fOzAMBgNV
|
117
|
+
HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAAVXIxOocwXi05004m9Znff6/cAj
|
118
|
+
2osr72g/Xux++lVqiSHf+T/R4QywsXy9//vKeXVEIyaaP9ImnWbbzHFFI+NStP4n
|
119
|
+
LILyv+/eOuZ6Dv7Vv6ZacjI3fexcXYr5VW52HHbb/M7G1ePAfdAixUHNH7lh58dY
|
120
|
+
WDzmJicksUYlyvI+
|
121
|
+
-----END CERTIFICATE-----
|
122
|
+
</ca-cert>
|
123
|
+
<client-cert>-----BEGIN CERTIFICATE-----
|
124
|
+
MIIEDjCCA3egAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMCVVMx
|
125
|
+
CzAJBgNVBAgTAlZBMRMwEQYDVQQHEwpCbGFja3NidXJnMRIwEAYDVQQKEwlSYWNr
|
126
|
+
c3BhY2UxFzAVBgNVBAsTDkluZnJhc3RydWN0dXJlMQ4wDAYDVQQDEwVsb2dpbjEO
|
127
|
+
MAwGA1UEKRMFbG9naW4xITAfBgkqhkiG9w0BCQEWEmNvYnJhQHNuYWtlb2lsLmNv
|
128
|
+
bTAeFw0xMTAxMTAwMDM3MzVaFw0yMTAxMDcwMDM3MzVaMIGfMQswCQYDVQQGEwJV
|
129
|
+
UzELMAkGA1UECBMCVkExEzARBgNVBAcTCkJsYWNrc2J1cmcxEjAQBgNVBAoTCVJh
|
130
|
+
Y2tzcGFjZTEXMBUGA1UECxMOSW5mcmFzdHJ1Y3R1cmUxDjAMBgNVBAMTBWxvY2Fs
|
131
|
+
MQ4wDAYDVQQpEwVsb2dpbjEhMB8GCSqGSIb3DQEJARYSY29icmFAc25ha2VvaWwu
|
132
|
+
Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCefsUr0T4oQUjKjW7Dpx0t
|
133
|
+
KwwafBF2HUW7CI75apeTjSBgYC1CHC6cggfFkUTFvndzspbGaeuJeYtvcvkAa2BD
|
134
|
+
p4jlSJgEXa+Uy1UAj1y06BePLNbKF4EfgEGf3eIWcdOtLYbOg4k33uNgto168iVO
|
135
|
+
owWOR+B2/z73NIHWxvtF3wIDAQABo4IBVjCCAVIwCQYDVR0TBAIwADAtBglghkgB
|
136
|
+
hvhCAQ0EIBYeRWFzeS1SU0EgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
|
137
|
+
BBSRXbeuamcuma4yo5B8IYSGGT3fNjCB1AYDVR0jBIHMMIHJgBR068tHLENrZeyj
|
138
|
+
n08Ut/baxlDTvKGBpaSBojCBnzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRMw
|
139
|
+
EQYDVQQHEwpCbGFja3NidXJnMRIwEAYDVQQKEwlSYWNrc3BhY2UxFzAVBgNVBAsT
|
140
|
+
DkluZnJhc3RydWN0dXJlMQ4wDAYDVQQDEwVsb2dpbjEOMAwGA1UEKRMFbG9naW4x
|
141
|
+
ITAfBgkqhkiG9w0BCQEWEmNvYnJhQHNuYWtlb2lsLmNvbYIJAORNZNRpPx87MBMG
|
142
|
+
A1UdJQQMMAoGCCsGAQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQUFAAOB
|
143
|
+
gQApPAG1suVSPugJyQGfBaL8H+7VJdAGXnc6INX5s1AxJ3mvp4o6PQ7ytP4v/QkJ
|
144
|
+
ZVMgWV8immfa3PboFgT00qqpbC2Vbf4RR972IEQfGuJLLl4YLrJsbloV9hBamKS7
|
145
|
+
Z1lllmEHxFWpNK2FLSZNaeQABZyvzfZYkk6zsHoY8XsCBg==
|
146
|
+
-----END CERTIFICATE-----
|
147
|
+
</client-cert>
|
148
|
+
<client-key>-----BEGIN RSA PRIVATE KEY-----
|
149
|
+
MIICXQIBAAKBgQCefsUr0T4oQUjKjW7Dpx0tKwwafBF2HUW7CI75apeTjSBgYC1C
|
150
|
+
HC6cggfFkUTFvndzspbGaeuJeYtvcvkAa2BDp4jlSJgEXa+Uy1UAj1y06BePLNbK
|
151
|
+
F4EfgEGf3eIWcdOtLYbOg4k33uNgto168iVOowWOR+B2/z73NIHWxvtF3wIDAQAB
|
152
|
+
AoGAf3tFykWl8ij4jHsP8Wz0CcWLGa5bOR64XIS4wyKaQoML3JjfLkKOtzHbYGzE
|
153
|
+
3Syi1bt6jKLbYZsSrRTT9SNorB3M2HI/uu1NHVyJ8fqxSJs9wQWv26XcMq6iPXR6
|
154
|
+
JQmiG44r0NoHtDOw0NCoo+9il4wjTIVSwN58x69EO1hsWokCQQDREYW73F536KzN
|
155
|
+
GSsLy+8VsaRiHCboi7lZwITGt4xFhykP/P5R/mNMTklVpJENuZH5jhiBr8r2O/XE
|
156
|
+
NQpIEZiFAkEAwhL4EnXax5p50g2CpkJM2B9F/p3IjjMs/sdUh4/RvAVkVAzz7uOh
|
157
|
+
TjtrL0T6480wA7rk3324IG5x4XTgXYVkEwJBAKkg7LgJ0N5d+xS8TIdxhctd9uZr
|
158
|
+
ccpj5iDGTmNXbwF8EurdNnvsODYtisPeqn2Y5o8ktYyMQrupy+rbIaMloOUCQAsI
|
159
|
+
pQ33oV6jy7VDi2AEePX4oTQeqF5dTnuVvZqPdK8p51BYBC5axrr56dggJdt5uPcd
|
160
|
+
UxHZxfQiE1tsF615ff0CQQCjeBskODATJkbN0kw+6FIF9m7QoEAYtJD1jLiY/2Sv
|
161
|
+
QRiYX+gvycrIph1yyIGA1qeHYnjhQp4ZijhcwSFUAAyF
|
162
|
+
-----END RSA PRIVATE KEY-----
|
163
|
+
</client-key>
|
164
|
+
<created-at type="datetime">2011-01-09T19:37:32-05:00</created-at>
|
165
|
+
<id type="integer">15</id>
|
166
|
+
<interfacable-id type="integer">5</interfacable-id>
|
167
|
+
<interfacable-type>Client</interfacable-type>
|
168
|
+
<ptp-ip-addr>172.19.0.6</ptp-ip-addr>
|
169
|
+
<updated-at type="datetime">2011-01-09T19:37:36-05:00</updated-at>
|
170
|
+
<vpn-ip-addr>172.19.0.5</vpn-ip-addr>
|
171
|
+
</vpn-network-interface>
|
172
|
+
</vpn-network-interfaces>
|
173
|
+
</client>
|
174
|
+
}
|
data/test/util_test.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module ChefVPCToolkit
|
6
|
+
|
7
|
+
class VpnNetworkManagerTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
tmpdir=TmpDir.new_tmp_dir
|
11
|
+
File.open(File.join(tmpdir, "gconftool-2"), 'w') do |f|
|
12
|
+
f.write("#!/bin/bash\nexit 0")
|
13
|
+
f.chmod(0755)
|
14
|
+
end
|
15
|
+
ENV['PATH']=tmpdir+":"+ENV['PATH']
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
group_hash=CloudServersVPC.server_group_hash(SERVER_GROUP_XML)
|
20
|
+
VpnNetworkManager.delete_certs(group_hash['id'])
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_configure_gconf
|
24
|
+
group_hash=CloudServersVPC.server_group_hash(SERVER_GROUP_XML)
|
25
|
+
client_hash=CloudServersVPC.client_hash(CLIENT_XML)
|
26
|
+
assert VpnNetworkManager.configure_gconf(group_hash, client_hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_ip_to_integer
|
30
|
+
assert_equal 16782252, VpnNetworkManager.ip_to_integer("172.19.0.1")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-vpc-toolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 2.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dan Prince
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-11 00:00:00 -05:00
|
19
19
|
default_executable: chef-vpc-toolkit
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -60,6 +60,20 @@ dependencies:
|
|
60
60
|
version: "0"
|
61
61
|
type: :runtime
|
62
62
|
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: uuidtools
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
63
77
|
description: The Chef VPC Toolkit is a set of Rake tasks that provide a framework to help automate the creation and configuration of cloud server groups for development or testing. Requires Cloud Servers VPC.
|
64
78
|
email: dan.prince@rackspace.com
|
65
79
|
executables:
|
@@ -70,6 +84,8 @@ extra_rdoc_files:
|
|
70
84
|
- README.rdoc
|
71
85
|
files:
|
72
86
|
- .gitignore
|
87
|
+
- .rvmrc
|
88
|
+
- CHANGELOG
|
73
89
|
- COPYING
|
74
90
|
- README.rdoc
|
75
91
|
- Rakefile
|
@@ -111,9 +127,13 @@ files:
|
|
111
127
|
- lib/chef-vpc-toolkit/ssh_util.rb
|
112
128
|
- lib/chef-vpc-toolkit/util.rb
|
113
129
|
- lib/chef-vpc-toolkit/version.rb
|
130
|
+
- lib/chef-vpc-toolkit/vpn_network_manager.rb
|
114
131
|
- rake/chef_vpc_toolkit.rake
|
115
132
|
- test/cloud_servers_vpc_test.rb
|
133
|
+
- test/ssh_util_test.rb
|
116
134
|
- test/test_helper.rb
|
135
|
+
- test/util_test.rb
|
136
|
+
- test/vpn_network_manager_test.rb
|
117
137
|
has_rdoc: true
|
118
138
|
homepage: http://github.com/rackspace/chef-vpc-toolkit
|
119
139
|
licenses: []
|
@@ -149,5 +169,8 @@ signing_key:
|
|
149
169
|
specification_version: 3
|
150
170
|
summary: Rake tasks to automate and configure server groups in the cloud with Chef.
|
151
171
|
test_files:
|
172
|
+
- test/util_test.rb
|
173
|
+
- test/ssh_util_test.rb
|
152
174
|
- test/test_helper.rb
|
153
175
|
- test/cloud_servers_vpc_test.rb
|
176
|
+
- test/vpn_network_manager_test.rb
|