chef-vpc-toolkit 2.4.0 → 2.5.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/CHANGELOG +7 -0
- data/README.rdoc +14 -4
- data/VERSION +1 -1
- data/lib/chef-vpc-toolkit/chef-0.9.bash +1 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/client.rb +8 -6
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/server.rb +4 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/server_group.rb +35 -0
- data/lib/chef-vpc-toolkit/vpn_network_manager.rb +4 -0
- data/rake/chef_vpc_toolkit.rake +40 -0
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
* Thu Apr 14 2011 Dan Prince <dan.prince@rackspace.com> - 2.5.0
|
2
|
+
- Make /root/cookbook-repos on the Chef server if it doesn't exist.
|
3
|
+
- Add cache_file option to the VPC Client class.
|
4
|
+
- Implement 'rdesktop' task for Windows servers.
|
5
|
+
- Implement 'group:vpn_gateway_ip' task.
|
6
|
+
- Store client information in the server group cache.
|
7
|
+
|
1
8
|
* Thu Mar 27 2011 Dan Prince <dan.prince@rackspace.com> - 2.4.0
|
2
9
|
- Implement 'chef:poll_clients' task.
|
3
10
|
|
data/README.rdoc
CHANGED
@@ -73,6 +73,11 @@ Example commands:
|
|
73
73
|
|
74
74
|
$ rake vpn:disconnect
|
75
75
|
|
76
|
+
- Connect to a Windows machine using rdesktop.
|
77
|
+
|
78
|
+
$ rake rdesktop SERVER_NAME=win1
|
79
|
+
|
80
|
+
|
76
81
|
== Bash Automation Script
|
77
82
|
The following is an example bash script to spin up a group and run commands via SSH. Useful for CI automation in Hudson, etc.
|
78
83
|
|
@@ -81,10 +86,15 @@ The following is an example bash script to spin up a group and run commands via
|
|
81
86
|
chef-vpc-toolkit -v
|
82
87
|
trap "rake group:delete" INT TERM EXIT # cleanup the group on exit
|
83
88
|
|
89
|
+
# create a server group and Chef (includes Chef Server, cookbooks, clients)
|
84
90
|
rake create
|
85
|
-
|
86
|
-
|
87
|
-
|
91
|
+
|
92
|
+
# wait for Chef clients to finish running
|
93
|
+
rake chef:poll_clients
|
94
|
+
|
95
|
+
# Run some scripts on the login server
|
96
|
+
rake ssh bash <<-EOF_BASH
|
97
|
+
echo 'It works!'
|
88
98
|
EOF_BASH
|
89
99
|
|
90
100
|
== Author
|
@@ -94,4 +104,4 @@ Dan Prince <dan.prince@rackspace.com>
|
|
94
104
|
== License
|
95
105
|
|
96
106
|
See COPYING for license information.
|
97
|
-
Copyright (c) 2010, Rackspace US, Inc.
|
107
|
+
Copyright (c) 2010-2011, Rackspace US, Inc.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.5.0
|
@@ -207,6 +207,7 @@ echo -n "Downloading $CB_REPO..."
|
|
207
207
|
download_cloud_file "$CB_REPO" "/tmp/cookbook-repo.tar.gz"
|
208
208
|
fi
|
209
209
|
echo "OK"
|
210
|
+
[ -d "$REPOS_BASEDIR" ] || mkdir -p "$REPOS_BASEDIR"
|
210
211
|
cd $REPOS_BASEDIR
|
211
212
|
echo -n "Extracting $CB_REPO..."
|
212
213
|
tar xzf /tmp/cookbook-repo.tar.gz
|
@@ -19,6 +19,7 @@ class Client
|
|
19
19
|
attr_accessor :description
|
20
20
|
attr_accessor :status
|
21
21
|
attr_accessor :server_group_id
|
22
|
+
attr_accessor :cache_file
|
22
23
|
|
23
24
|
def initialize(options={})
|
24
25
|
@id=options[:id].to_i
|
@@ -26,6 +27,7 @@ class Client
|
|
26
27
|
@description=options[:description]
|
27
28
|
@status=options[:status] or @status = "Pending"
|
28
29
|
@server_group_id=options[:server_group_id]
|
30
|
+
@cache_file=options[:cache_file] or options[:server_group_id]
|
29
31
|
|
30
32
|
@vpn_network_interfaces=[]
|
31
33
|
end
|
@@ -36,14 +38,14 @@ class Client
|
|
36
38
|
|
37
39
|
def cache_to_disk
|
38
40
|
FileUtils.mkdir_p(@@data_dir)
|
39
|
-
File.open(File.join(@@data_dir, "#{@
|
41
|
+
File.open(File.join(@@data_dir, "#{@cache_file}.xml"), 'w') do |f|
|
40
42
|
f.chmod(0600)
|
41
43
|
f.write(self.to_xml)
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
47
|
def delete
|
46
|
-
client_xml_file=File.join(@@data_dir, "#{@
|
48
|
+
client_xml_file=File.join(@@data_dir, "#{@cache_file}.xml")
|
47
49
|
if File.exists?(client_xml_file) then
|
48
50
|
File.delete(client_xml_file)
|
49
51
|
end
|
@@ -139,7 +141,7 @@ class Client
|
|
139
141
|
|
140
142
|
end
|
141
143
|
|
142
|
-
def self.create(server_group, client_name)
|
144
|
+
def self.create(server_group, client_name, cache_to_disk=true)
|
143
145
|
|
144
146
|
xml = Builder::XmlMarkup.new
|
145
147
|
xml.client do |client|
|
@@ -150,14 +152,14 @@ class Client
|
|
150
152
|
|
151
153
|
xml=Connection.post("/clients.xml", xml.target!)
|
152
154
|
client=Client.from_xml(xml)
|
153
|
-
client.cache_to_disk
|
155
|
+
client.cache_to_disk if cache_to_disk
|
154
156
|
client
|
155
157
|
|
156
158
|
end
|
157
159
|
|
158
|
-
# Fetch a
|
160
|
+
# Fetch a client. The following options are available:
|
159
161
|
#
|
160
|
-
# :id - The ID of the
|
162
|
+
# :id - The ID of the client to fetch.
|
161
163
|
# :source - valid options are 'remote' and 'cache'
|
162
164
|
#
|
163
165
|
def self.fetch(options = {})
|
@@ -17,6 +17,7 @@ class Server
|
|
17
17
|
attr_accessor :retry_count
|
18
18
|
attr_accessor :error_message
|
19
19
|
attr_accessor :status
|
20
|
+
attr_accessor :admin_password
|
20
21
|
|
21
22
|
def initialize(options={})
|
22
23
|
@id=options[:id].to_i
|
@@ -27,6 +28,7 @@ class Server
|
|
27
28
|
@cloud_server_id_number=options[:cloud_server_id_number].to_i
|
28
29
|
@flavor_id=options[:flavor_id].to_i
|
29
30
|
@image_id=options[:image_id].to_i
|
31
|
+
@admin_password=options[:admin_password]
|
30
32
|
@server_group_id=options[:server_group_id].to_i
|
31
33
|
@openvpn_server = [true, "true"].include?(options[:openvpn_server])
|
32
34
|
@retry_count=options[:retry_count].to_i or 0
|
@@ -51,6 +53,7 @@ class Server
|
|
51
53
|
server.tag! "cloud-server-id-number", @cloud_server_id_number if @cloud_server_id_number
|
52
54
|
server.tag! "flavor-id", @flavor_id
|
53
55
|
server.tag! "image-id", @image_id
|
56
|
+
server.tag! "admin-password", @admin_password
|
54
57
|
server.tag! "server-group-id", @server_group_id
|
55
58
|
server.tag! "openvpn-server", "true" if openvpn_server?
|
56
59
|
server.tag! "error-message", @error_message if @error_message
|
@@ -70,6 +73,7 @@ class Server
|
|
70
73
|
:name => XMLUtil.element_text(sg_xml, "name"),
|
71
74
|
:flavor_id => XMLUtil.element_text(sg_xml, "flavor-id"),
|
72
75
|
:image_id => XMLUtil.element_text(sg_xml, "image-id"),
|
76
|
+
:admin_password => XMLUtil.element_text(sg_xml, "admin-password"),
|
73
77
|
:description => XMLUtil.element_text(sg_xml, "description"),
|
74
78
|
:cloud_server_id_number => XMLUtil.element_text(sg_xml, "cloud-server-id-number"),
|
75
79
|
:description => XMLUtil.element_text(sg_xml, "description"),
|
@@ -44,6 +44,7 @@ class ServerGroup
|
|
44
44
|
@owner_name=options[:owner_name] or @owner_name=ENV['USER']
|
45
45
|
|
46
46
|
@servers=[]
|
47
|
+
@clients=[]
|
47
48
|
@ssh_public_keys=[]
|
48
49
|
end
|
49
50
|
|
@@ -55,6 +56,14 @@ class ServerGroup
|
|
55
56
|
@servers
|
56
57
|
end
|
57
58
|
|
59
|
+
def client(name)
|
60
|
+
@clients.select {|s| s.name == name}[0] if @clients.size > 0
|
61
|
+
end
|
62
|
+
|
63
|
+
def clients
|
64
|
+
@clients
|
65
|
+
end
|
66
|
+
|
58
67
|
def vpn_gateway_name
|
59
68
|
@servers.select {|s| s.openvpn_server? }[0].name if @servers.size > 0
|
60
69
|
end
|
@@ -121,6 +130,9 @@ class ServerGroup
|
|
121
130
|
xml_server.description(server.description)
|
122
131
|
xml_server.tag! "flavor-id", server.flavor_id
|
123
132
|
xml_server.tag! "image-id", server.image_id
|
133
|
+
if server.admin_password then
|
134
|
+
xml_server.tag! "admin-password", server.admin_password
|
135
|
+
end
|
124
136
|
xml_server.tag! "cloud-server-id-number", server.cloud_server_id_number if server.cloud_server_id_number
|
125
137
|
xml_server.tag! "status", server.status if server.status
|
126
138
|
xml_server.tag! "external-ip-addr", server.external_ip_addr if server.external_ip_addr
|
@@ -141,6 +153,17 @@ class ServerGroup
|
|
141
153
|
end
|
142
154
|
end
|
143
155
|
end
|
156
|
+
sg.tag! "clients", { "type" => "array"} do |xml_clients|
|
157
|
+
self.clients.each do |client|
|
158
|
+
xml_clients.tag! "client" do |xml_client|
|
159
|
+
xml_client.id client.id
|
160
|
+
xml_client.name client.name
|
161
|
+
xml_client.description client.description
|
162
|
+
xml_client.status client.status
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
144
167
|
end
|
145
168
|
xml.target!
|
146
169
|
|
@@ -172,12 +195,24 @@ class ServerGroup
|
|
172
195
|
:internal_ip_addr => XMLUtil.element_text(server_xml, "internal-ip-addr"),
|
173
196
|
:error_message => XMLUtil.element_text(server_xml, "error-message"),
|
174
197
|
:image_id => XMLUtil.element_text(server_xml, "image-id"),
|
198
|
+
:admin_password => XMLUtil.element_text(server_xml, "admin-password"),
|
175
199
|
:flavor_id => XMLUtil.element_text(server_xml, "flavor-id"),
|
176
200
|
:retry_count => XMLUtil.element_text(server_xml, "retry-count"),
|
177
201
|
:openvpn_server => XMLUtil.element_text(server_xml, "openvpn-server")
|
178
202
|
)
|
179
203
|
sg.servers << server
|
180
204
|
end
|
205
|
+
REXML::XPath.each(dom, "//client") do |client_xml|
|
206
|
+
|
207
|
+
client=Client.new(
|
208
|
+
:id => XMLUtil.element_text(client_xml, "id").to_i,
|
209
|
+
:name => XMLUtil.element_text(client_xml, "name"),
|
210
|
+
:description => XMLUtil.element_text(client_xml, "description"),
|
211
|
+
:status => XMLUtil.element_text(client_xml, "status")
|
212
|
+
)
|
213
|
+
sg.clients << client
|
214
|
+
end
|
215
|
+
|
181
216
|
end
|
182
217
|
|
183
218
|
sg
|
@@ -217,6 +217,10 @@ module VpnNetworkManager
|
|
217
217
|
puts %x{#{sudo_display} nmcli con down id "VPC Group: #{server_group_id}"}
|
218
218
|
end
|
219
219
|
|
220
|
+
def self.connected?(server_group_id)
|
221
|
+
return system("#{sudo_display} nmcli con status | grep -c 'VPC Group: #{server_group_id}' &> /dev/null")
|
222
|
+
end
|
223
|
+
|
220
224
|
def self.ip_to_integer(ip_string)
|
221
225
|
return 0 if ip_string.nil?
|
222
226
|
ip_arr=ip_string.split(".").collect{ |s| s.to_i }
|
data/rake/chef_vpc_toolkit.rake
CHANGED
@@ -137,6 +137,12 @@ namespace :group do
|
|
137
137
|
puts "Server '#{server_name}' deleted."
|
138
138
|
end
|
139
139
|
|
140
|
+
desc "Print the VPN gateway IP address"
|
141
|
+
task :vpn_gateway_ip do
|
142
|
+
group=ServerGroup.fetch(:source => "cache")
|
143
|
+
puts group.vpn_gateway_ip
|
144
|
+
end
|
145
|
+
|
140
146
|
end
|
141
147
|
|
142
148
|
namespace :server do
|
@@ -393,6 +399,40 @@ task :rechef => [ "server:rebuild", "group:poll" ] do
|
|
393
399
|
|
394
400
|
end
|
395
401
|
|
402
|
+
desc "Use rdesktop to connect to Windows servers."
|
403
|
+
task :rdesktop => 'group:init' do
|
404
|
+
|
405
|
+
server_name=ENV['SERVER_NAME']
|
406
|
+
raise "Please specify a SERVER_NAME." if server_name.nil?
|
407
|
+
|
408
|
+
# VPC machines have their public IPs disabled
|
409
|
+
# This option is useful for debugging failed VPN connections
|
410
|
+
use_public_ip=ENV['PUBLIC_IP']
|
411
|
+
|
412
|
+
sg=ServerGroup.fetch(:source => "cache")
|
413
|
+
pass=sg.server(server_name).admin_password
|
414
|
+
|
415
|
+
if use_public_ip.nil? then
|
416
|
+
if ChefVPCToolkit::VpnNetworkManager.connected?(sg.id)
|
417
|
+
# on the VPN we connect directly to the windows machine
|
418
|
+
local_ip=%x{ssh -o \"StrictHostKeyChecking no\" root@#{sg.vpn_gateway_ip} grep #{server_name}.#{sg.domain_name} /etc/hosts | cut -f 1}.chomp
|
419
|
+
exec("rdesktop #{local_ip} -u Administrator -p #{pass}")
|
420
|
+
else
|
421
|
+
# when not on the VPN create an SSH tunnel for rdesktop traffic
|
422
|
+
local_ip=%x{ssh -o \"StrictHostKeyChecking no\" root@#{sg.vpn_gateway_ip} grep #{server_name}.#{sg.domain_name} /etc/hosts | cut -f 1}.chomp
|
423
|
+
%x{
|
424
|
+
ssh root@#{sg.vpn_gateway_ip} -L 1234:#{local_ip}:3389 'sleep 3 & exit' &
|
425
|
+
sleep 1
|
426
|
+
rdesktop localhost:1234 -u Administrator -p #{pass}
|
427
|
+
}
|
428
|
+
end
|
429
|
+
else
|
430
|
+
public_ip=sg.server(server_name).external_ip_addr
|
431
|
+
exec("rdesktop #{public_ip} -u Administrator -p #{pass}")
|
432
|
+
end
|
433
|
+
|
434
|
+
end
|
435
|
+
|
396
436
|
desc "Alias to the vpn:connect task."
|
397
437
|
task :vpn => "vpn:connect"
|
398
438
|
|
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: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 0
|
10
|
-
version: 2.
|
10
|
+
version: 2.5.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: 2011-
|
18
|
+
date: 2011-04-14 00:00:00 -04:00
|
19
19
|
default_executable: chef-vpc-toolkit
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|