chef-vpc-toolkit 2.0.1 → 2.1.0
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/.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
|