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 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
@@ -28,6 +28,7 @@ begin
28
28
  gemspec.add_dependency 'rake'
29
29
  gemspec.add_dependency 'builder'
30
30
  gemspec.add_dependency 'json'
31
+ gemspec.add_dependency 'uuidtools'
31
32
  end
32
33
  rescue LoadError
33
34
  puts "Jeweler not available. Install it with: sudo gem install jeweler"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.1
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 cloud project with the given directory name.") do |name|
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 cloud project to work with the latest Cloud Toolkit.") do
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 "Cloud Toolkit Version: #{Version::VERSION}"
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 'cloud-toolkit -u' commmand from within a cloud project directory."
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
 
@@ -5,12 +5,12 @@
5
5
  "servers": {
6
6
  "login": {
7
7
  "image_id": "51",
8
- "flavor_id": "4",
8
+ "flavor_id": "2",
9
9
  "openvpn_server": "true"
10
10
  },
11
11
  "client1": {
12
12
  "image_id": "51",
13
- "flavor_id": "4"
13
+ "flavor_id": "2"
14
14
  }
15
15
  }
16
16
  }
@@ -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
@@ -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
- toolkit_version=ENV['CHEF_VPC_TOOLKIT_VERSION']
8
+ toolkit_version=ENV['CHEF_VPC_TOOLKIT_VERSION']
9
9
  elsif File.exists?(version_file)
10
- toolkit_version=IO.read(version_file)
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
- Dir[File.join(File.dirname("__FILE__"), 'tasks', '*.rake')].each do |rakefile|
26
- puts rakefile
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
@@ -4,3 +4,4 @@ require 'chef-vpc-toolkit/cloud_servers_vpc'
4
4
  require 'chef-vpc-toolkit/http_util'
5
5
  require 'chef-vpc-toolkit/ssh_util'
6
6
  require 'chef-vpc-toolkit/version'
7
+ require 'chef-vpc-toolkit/vpn_network_manager'
@@ -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
- cp /usr/lib/ruby/gems/1.8/gems/chef-0.9.8/distro/redhat/etc/init.d/chef-client /etc/init.d/
38
- cp /usr/lib/ruby/gems/1.8/gems/chef-0.9.8/distro/redhat/etc/logrotate.d/chef-client /etc/logrotate.d/
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
@@ -72,6 +72,7 @@ def self.post(url_string, post_data, auth_user=nil, auth_password=nil)
72
72
  when Net::HTTPSuccess
73
73
  return response.body
74
74
  else
75
+ puts response.body
75
76
  response.error!
76
77
  end
77
78
  end
@@ -1,9 +1,14 @@
1
1
  require 'yaml'
2
+ require 'socket'
2
3
 
3
4
  module ChefVPCToolkit
4
5
 
5
6
  module Util
6
7
 
8
+ def self.hostname
9
+ Socket.gethostname
10
+ end
11
+
7
12
  def self.load_configs
8
13
 
9
14
  config_file=ENV['CHEF_VPC_TOOLKIT_CONF']
@@ -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
@@ -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') { |f| f.write(resp) }
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') { |f| f.write(xml) }
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-cloud-toolkit")
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,15 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ module ChefVPCToolkit
4
+
5
+ class UtilTest < Test::Unit::TestCase
6
+
7
+ def test_hostname
8
+
9
+ assert_not_nil Util.hostname
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -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: 13
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 0
9
8
  - 1
10
- version: 2.0.1
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: 2010-12-07 00:00:00 -05:00
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