chef-vpc-toolkit 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|