kytoon 1.3.9 → 1.4.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 +4 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/config/{server_group_vpc.json → server_group_cloudcue.json} +2 -4
- data/lib/kytoon.rb +0 -3
- data/lib/kytoon/providers/cloud_cue.rb +9 -0
- data/lib/kytoon/providers/{cloud_servers_vpc → cloud_cue}/connection.rb +4 -4
- data/lib/kytoon/providers/{cloud_servers_vpc → cloud_cue}/server.rb +8 -9
- data/lib/kytoon/providers/{cloud_servers_vpc → cloud_cue}/server_group.rb +19 -74
- data/lib/kytoon/providers/{cloud_servers_vpc → cloud_cue}/ssh_public_key.rb +1 -1
- data/lib/kytoon/server_group.rb +3 -3
- data/test/server_group_test.rb +8 -17
- data/test/server_test.rb +3 -3
- metadata +10 -16
- data/lib/kytoon/providers/cloud_servers_vpc.rb +0 -11
- data/lib/kytoon/providers/cloud_servers_vpc/client.rb +0 -197
- data/lib/kytoon/providers/cloud_servers_vpc/vpn_network_interface.rb +0 -33
- data/lib/kytoon/vpn/vpn_connection.rb +0 -46
- data/lib/kytoon/vpn/vpn_network_manager.rb +0 -237
- data/lib/kytoon/vpn/vpn_openvpn.rb +0 -112
- data/test/client_test.rb +0 -112
data/CHANGELOG
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
* Wed Jul 19 2013 Dan Prince <dprince@redhat.com> - 1.4.0
|
2
|
+
-Add support for CloudCue.
|
3
|
+
-Drop old CloudServers VPC stuff (no longer in use)
|
4
|
+
|
1
5
|
* Wed Jun 12 2013 Dan Prince <dprince@redhat.com> - 1.3.9
|
2
6
|
-XenServer: Extract configure_host_network (matelaket)
|
3
7
|
-XenServer: Fix: Configure host network before configuring nodes (matelaket)
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ Quick install on Fedora:
|
|
35
35
|
Create a .kytoon.conf file in your $HOME directory.
|
36
36
|
|
37
37
|
# The default group type.
|
38
|
-
# Set to one of: openstack, libvirt, xenserver
|
38
|
+
# Set to one of: openstack, libvirt, xenserver, cloudcue
|
39
39
|
group_type: openstack
|
40
40
|
|
41
41
|
# Openstack Settings
|
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ begin
|
|
21
21
|
Jeweler::Tasks.new do |gem|
|
22
22
|
gem.name = "kytoon"
|
23
23
|
gem.summary = "Create & configure ephemeral virtual private clouds."
|
24
|
-
gem.description = "A set of Rake tasks that provide a framework to help automate the creation and configuration
|
24
|
+
gem.description = "A set of Rake tasks that provide a framework to help automate the creation and configuration server groups."
|
25
25
|
gem.email = "dprince@redhat.com"
|
26
26
|
gem.homepage = "http://github.com/dprince/kytoon"
|
27
27
|
gem.authors = ["Dan Prince"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
@@ -1,14 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "Fedora",
|
3
|
-
"domain_name": "
|
3
|
+
"domain_name": "foo",
|
4
4
|
"description": "Fedora",
|
5
|
-
"vpn_device": "tap",
|
6
|
-
"vpn_proto": "udp",
|
7
5
|
"servers": {
|
8
6
|
"login": {
|
9
7
|
"image_id": "24344414",
|
10
8
|
"flavor_id": "3",
|
11
|
-
"
|
9
|
+
"gateway": "true"
|
12
10
|
}
|
13
11
|
}
|
14
12
|
}
|
data/lib/kytoon.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'kytoon/providers/cloud_cue/connection'
|
2
|
+
require 'kytoon/providers/cloud_cue/server'
|
3
|
+
require 'kytoon/providers/cloud_cue/server_group'
|
4
|
+
require 'kytoon/providers/cloud_cue/ssh_public_key'
|
5
|
+
require 'kytoon/util'
|
6
|
+
|
7
|
+
Kytoon::Util.check_config_param('cloudcue_url')
|
8
|
+
Kytoon::Util.check_config_param('cloudcue_username')
|
9
|
+
Kytoon::Util.check_config_param('cloudcue_password')
|
@@ -7,7 +7,7 @@ module Kytoon
|
|
7
7
|
|
8
8
|
module Providers
|
9
9
|
|
10
|
-
module
|
10
|
+
module CloudCue
|
11
11
|
|
12
12
|
class Connection
|
13
13
|
|
@@ -21,9 +21,9 @@ MULTI_PART_BOUNDARY="jtZ!pZ1973um"
|
|
21
21
|
|
22
22
|
configs=Util.load_configs
|
23
23
|
|
24
|
-
base_url = configs["
|
25
|
-
@@auth_user = configs["
|
26
|
-
@@auth_password = configs["
|
24
|
+
base_url = configs["cloudcue_url"]
|
25
|
+
@@auth_user = configs["cloudcue_username"]
|
26
|
+
@@auth_password = configs["cloudcue_password"]
|
27
27
|
|
28
28
|
ssl_key = configs["ssl_key"]
|
29
29
|
ssl_cert = configs["ssl_cert"]
|
@@ -2,7 +2,7 @@ module Kytoon
|
|
2
2
|
|
3
3
|
module Providers
|
4
4
|
|
5
|
-
module
|
5
|
+
module CloudCue
|
6
6
|
|
7
7
|
class Server
|
8
8
|
|
@@ -15,7 +15,7 @@ class Server
|
|
15
15
|
attr_accessor :flavor_id
|
16
16
|
attr_accessor :image_id
|
17
17
|
attr_accessor :server_group_id
|
18
|
-
attr_accessor :
|
18
|
+
attr_accessor :gateway
|
19
19
|
attr_accessor :retry_count
|
20
20
|
attr_accessor :error_message
|
21
21
|
attr_accessor :status
|
@@ -32,14 +32,14 @@ class Server
|
|
32
32
|
@image_id=options[:image_id]
|
33
33
|
@admin_password=options[:admin_password]
|
34
34
|
@server_group_id=options[:server_group_id].to_i
|
35
|
-
@
|
35
|
+
@gateway = [true, "true"].include?(options[:gateway])
|
36
36
|
@retry_count=options[:retry_count].to_i or 0
|
37
37
|
@error_message=options[:error_message]
|
38
38
|
@status=options[:status]
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
return @
|
41
|
+
def gateway?
|
42
|
+
return @gateway
|
43
43
|
end
|
44
44
|
|
45
45
|
def to_xml
|
@@ -57,7 +57,7 @@ class Server
|
|
57
57
|
server.tag! "image-id", @image_id
|
58
58
|
server.tag! "admin-password", @admin_password
|
59
59
|
server.tag! "server-group-id", @server_group_id
|
60
|
-
server.tag! "
|
60
|
+
server.tag! "gateway", "true" if gateway?
|
61
61
|
server.tag! "error-message", @error_message if @error_message
|
62
62
|
end
|
63
63
|
xml.target!
|
@@ -82,7 +82,7 @@ class Server
|
|
82
82
|
:external_ip_addr => XMLUtil.element_text(sg_xml, "external-ip-addr"),
|
83
83
|
:internal_ip_addr => XMLUtil.element_text(sg_xml, "internal-ip-addr"),
|
84
84
|
:server_group_id => XMLUtil.element_text(sg_xml, "server-group-id"),
|
85
|
-
:
|
85
|
+
:gateway => XMLUtil.element_text(sg_xml, "gateway"),
|
86
86
|
:retry_count => XMLUtil.element_text(sg_xml, "retry-count"),
|
87
87
|
:error_message => XMLUtil.element_text(sg_xml, "error-message"),
|
88
88
|
:status => XMLUtil.element_text(sg_xml, "status")
|
@@ -95,8 +95,7 @@ class Server
|
|
95
95
|
|
96
96
|
def rebuild
|
97
97
|
|
98
|
-
raise "Error: Rebuilding the
|
99
|
-
|
98
|
+
raise "Error: Rebuilding the gateway server is not supported at this time." if gateway?
|
100
99
|
Connection.post("/servers/#{@id}/rebuild", {})
|
101
100
|
|
102
101
|
end
|
@@ -8,11 +8,11 @@ module Kytoon
|
|
8
8
|
|
9
9
|
module Providers
|
10
10
|
|
11
|
-
module
|
11
|
+
module CloudCue
|
12
12
|
|
13
13
|
class ServerGroup
|
14
14
|
|
15
|
-
@@data_dir=File.join(KYTOON_PROJECT, "tmp", "
|
15
|
+
@@data_dir=File.join(KYTOON_PROJECT, "tmp", "cloudcue")
|
16
16
|
|
17
17
|
def self.data_dir
|
18
18
|
@@data_dir
|
@@ -28,10 +28,6 @@ class ServerGroup
|
|
28
28
|
attr_accessor :name
|
29
29
|
attr_accessor :description
|
30
30
|
attr_accessor :domain_name
|
31
|
-
attr_accessor :vpn_device
|
32
|
-
attr_accessor :vpn_proto
|
33
|
-
attr_accessor :vpn_network
|
34
|
-
attr_accessor :vpn_subnet
|
35
31
|
attr_accessor :owner_name
|
36
32
|
|
37
33
|
attr_reader :ssh_public_keys
|
@@ -41,14 +37,9 @@ class ServerGroup
|
|
41
37
|
@name=options[:name]
|
42
38
|
@description=options[:description]
|
43
39
|
@domain_name=options[:domain_name]
|
44
|
-
@vpn_device=options[:vpn_device] or @vpn_device="tun"
|
45
|
-
@vpn_proto=options[:vpn_proto] or @vpn_proto="tcp"
|
46
|
-
@vpn_network=options[:vpn_network] or @vpn_network="172.19.0.0"
|
47
|
-
@vpn_subnet=options[:vpn_subnet] or @vpn_subnet="255.255.128.0"
|
48
40
|
@owner_name=options[:owner_name] or @owner_name=ENV['USER']
|
49
41
|
|
50
42
|
@servers=[]
|
51
|
-
@clients=[]
|
52
43
|
@ssh_public_keys=[]
|
53
44
|
end
|
54
45
|
|
@@ -60,20 +51,8 @@ class ServerGroup
|
|
60
51
|
@servers
|
61
52
|
end
|
62
53
|
|
63
|
-
def client(name)
|
64
|
-
@clients.select {|s| s.name == name}[0] if @clients.size > 0
|
65
|
-
end
|
66
|
-
|
67
|
-
def clients
|
68
|
-
@clients
|
69
|
-
end
|
70
|
-
|
71
|
-
def vpn_gateway_name
|
72
|
-
@servers.select {|s| s.openvpn_server? }[0].name if @servers.size > 0
|
73
|
-
end
|
74
|
-
|
75
54
|
def gateway_ip
|
76
|
-
@servers.select {|s| s.
|
55
|
+
@servers.select {|s| s.gateway? }[0].external_ip_addr if @servers.size > 0
|
77
56
|
end
|
78
57
|
|
79
58
|
def ssh_public_keys
|
@@ -88,11 +67,7 @@ class ServerGroup
|
|
88
67
|
sg=ServerGroup.new(
|
89
68
|
:name => json_hash["name"],
|
90
69
|
:description => json_hash["description"],
|
91
|
-
:domain_name => json_hash["domain_name"]
|
92
|
-
:vpn_device => json_hash["vpn_device"],
|
93
|
-
:vpn_proto => json_hash["vpn_proto"],
|
94
|
-
:vpn_network => json_hash["vpn_network"],
|
95
|
-
:vpn_subnet => json_hash["vpn_subnet"]
|
70
|
+
:domain_name => json_hash["domain_name"]
|
96
71
|
)
|
97
72
|
json_hash["servers"].each_pair do |server_name, server_config|
|
98
73
|
sg.servers << Server.new(
|
@@ -100,7 +75,7 @@ class ServerGroup
|
|
100
75
|
:description => server_config["description"],
|
101
76
|
:flavor_id => server_config["flavor_id"],
|
102
77
|
:image_id => server_config["image_id"],
|
103
|
-
:
|
78
|
+
:gateway => server_config["gateway"]
|
104
79
|
)
|
105
80
|
end
|
106
81
|
|
@@ -124,29 +99,23 @@ class ServerGroup
|
|
124
99
|
sg.description(@description)
|
125
100
|
sg.tag! "owner-name", @owner_name
|
126
101
|
sg.tag! "domain-name", @domain_name
|
127
|
-
sg.tag! "vpn-device", @vpn_device if @vpn_device != "tun"
|
128
|
-
sg.tag! "vpn-proto", @vpn_proto if @vpn_proto != "tcp"
|
129
|
-
sg.tag! "vpn-network", @vpn_network
|
130
|
-
sg.tag! "vpn-subnet", @vpn_subnet
|
131
102
|
sg.servers("type" => "array") do |xml_servers|
|
132
103
|
self.servers.each do |server|
|
133
104
|
xml_servers.server do |xml_server|
|
134
|
-
xml_server.id(server.id)
|
135
105
|
xml_server.name(server.name)
|
136
106
|
xml_server.description(server.description)
|
137
107
|
xml_server.tag! "flavor-id", server.flavor_id
|
138
108
|
xml_server.tag! "image-id", server.image_id
|
139
|
-
|
140
|
-
|
141
|
-
|
109
|
+
if server.admin_password then
|
110
|
+
xml_server.tag! "admin-password", server.admin_password
|
111
|
+
end
|
142
112
|
xml_server.tag! "cloud-server-id-number", server.cloud_server_id_number if server.cloud_server_id_number
|
143
113
|
xml_server.tag! "status", server.status if server.status
|
144
114
|
xml_server.tag! "external-ip-addr", server.external_ip_addr if server.external_ip_addr
|
145
115
|
xml_server.tag! "internal-ip-addr", server.internal_ip_addr if server.internal_ip_addr
|
146
116
|
xml_server.tag! "error-message", server.error_message if server.error_message
|
147
|
-
|
148
|
-
|
149
|
-
xml_server.tag! "openvpn-server", "true", { "type" => "boolean"}
|
117
|
+
if server.gateway?
|
118
|
+
xml_server.tag! "gateway", "true", { "type" => "boolean"}
|
150
119
|
end
|
151
120
|
end
|
152
121
|
end
|
@@ -159,16 +128,6 @@ class ServerGroup
|
|
159
128
|
end
|
160
129
|
end
|
161
130
|
end
|
162
|
-
sg.tag! "clients", { "type" => "array"} do |xml_clients|
|
163
|
-
self.clients.each do |client|
|
164
|
-
xml_clients.tag! "client" do |xml_client|
|
165
|
-
xml_client.id client.id
|
166
|
-
xml_client.name client.name
|
167
|
-
xml_client.description client.description
|
168
|
-
xml_client.status client.status
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
131
|
|
173
132
|
end
|
174
133
|
xml.target!
|
@@ -185,11 +144,7 @@ class ServerGroup
|
|
185
144
|
:id => XMLUtil.element_text(sg_xml, "id").to_i,
|
186
145
|
:owner_name => XMLUtil.element_text(sg_xml, "owner-name"),
|
187
146
|
:domain_name => XMLUtil.element_text(sg_xml, "domain-name"),
|
188
|
-
:description => XMLUtil.element_text(sg_xml, "description")
|
189
|
-
:vpn_device => XMLUtil.element_text(sg_xml, "vpn-device"),
|
190
|
-
:vpn_proto => XMLUtil.element_text(sg_xml, "vpn-proto"),
|
191
|
-
:vpn_network => XMLUtil.element_text(sg_xml, "vpn-network"),
|
192
|
-
:vpn_subnet => XMLUtil.element_text(sg_xml, "vpn-subnet")
|
147
|
+
:description => XMLUtil.element_text(sg_xml, "description")
|
193
148
|
)
|
194
149
|
REXML::XPath.each(dom, "//server") do |server_xml|
|
195
150
|
|
@@ -205,20 +160,10 @@ class ServerGroup
|
|
205
160
|
:admin_password => XMLUtil.element_text(server_xml, "admin-password"),
|
206
161
|
:flavor_id => XMLUtil.element_text(server_xml, "flavor-id"),
|
207
162
|
:retry_count => XMLUtil.element_text(server_xml, "retry-count"),
|
208
|
-
:
|
163
|
+
:gateway => XMLUtil.element_text(server_xml, "gateway")
|
209
164
|
)
|
210
165
|
sg.servers << server
|
211
166
|
end
|
212
|
-
REXML::XPath.each(dom, "//client") do |client_xml|
|
213
|
-
|
214
|
-
client=Client.new(
|
215
|
-
:id => XMLUtil.element_text(client_xml, "id").to_i,
|
216
|
-
:name => XMLUtil.element_text(client_xml, "name"),
|
217
|
-
:description => XMLUtil.element_text(client_xml, "description"),
|
218
|
-
:status => XMLUtil.element_text(client_xml, "status")
|
219
|
-
)
|
220
|
-
sg.clients << client
|
221
|
-
end
|
222
167
|
|
223
168
|
end
|
224
169
|
|
@@ -232,13 +177,13 @@ class ServerGroup
|
|
232
177
|
puts "name: #{@name}"
|
233
178
|
puts "description: #{@description}"
|
234
179
|
puts "domain name: #{@domain_name}"
|
235
|
-
puts "
|
180
|
+
puts "Gateway IP: #{self.gateway_ip}"
|
236
181
|
puts "Servers:"
|
237
182
|
servers.each do |server|
|
238
183
|
puts "\tname: #{server.name} (id: #{server.id})"
|
239
184
|
puts "\tstatus: #{server.status}"
|
240
|
-
if server.
|
241
|
-
puts "\
|
185
|
+
if server.gateway?
|
186
|
+
puts "\tGateway server: #{server.gateway?}"
|
242
187
|
end
|
243
188
|
if server.error_message then
|
244
189
|
puts "\tlast error message: #{server.error_message}"
|
@@ -323,13 +268,13 @@ class ServerGroup
|
|
323
268
|
sg=ServerGroup.from_xml(xml)
|
324
269
|
|
325
270
|
old_group_xml=nil
|
326
|
-
|
271
|
+
gateway_ip=nil
|
327
272
|
sg.poll_until_online do |server_group|
|
328
273
|
if old_group_xml != server_group.to_xml then
|
329
274
|
old_group_xml = server_group.to_xml
|
330
|
-
|
331
|
-
if not
|
332
|
-
SshUtil.remove_known_hosts_ip(
|
275
|
+
gateway_ip = server_group.gateway_ip if server_group.gateway_ip
|
276
|
+
if not gateway_ip.nil? and not gateway_ip.empty? then
|
277
|
+
SshUtil.remove_known_hosts_ip(gateway_ip)
|
333
278
|
end
|
334
279
|
server_group.pretty_print
|
335
280
|
end
|
data/lib/kytoon/server_group.rb
CHANGED
@@ -18,9 +18,9 @@ class ServerGroup
|
|
18
18
|
elsif group_type == "libvirt" then
|
19
19
|
require 'kytoon/providers/libvirt'
|
20
20
|
@@group_class = Kytoon::Providers::Libvirt::ServerGroup
|
21
|
-
elsif group_type == "
|
22
|
-
require 'kytoon/providers/
|
23
|
-
@@group_class = Kytoon::Providers::
|
21
|
+
elsif group_type == "cloudcue" or group_type == "cloudcue" then
|
22
|
+
require 'kytoon/providers/cloud_cue'
|
23
|
+
@@group_class = Kytoon::Providers::CloudCue::ServerGroup
|
24
24
|
else
|
25
25
|
raise ConfigException, "Invalid 'group_type' specified."
|
26
26
|
end
|
data/test/server_group_test.rb
CHANGED
@@ -6,7 +6,7 @@ require 'tempfile'
|
|
6
6
|
|
7
7
|
module Kytoon
|
8
8
|
module Providers
|
9
|
-
module
|
9
|
+
module CloudCue
|
10
10
|
|
11
11
|
class ServerGroupTest < Test::Unit::TestCase
|
12
12
|
|
@@ -21,13 +21,13 @@ class ServerGroupTest < Test::Unit::TestCase
|
|
21
21
|
|
22
22
|
TEST_JSON_CONFIG = %{{
|
23
23
|
"name": "test",
|
24
|
-
"domain_name": "
|
24
|
+
"domain_name": "foo",
|
25
25
|
"description": "test description",
|
26
26
|
"servers": {
|
27
27
|
"login": {
|
28
28
|
"image_id": "51",
|
29
29
|
"flavor_id": "2",
|
30
|
-
"
|
30
|
+
"gateway": "true"
|
31
31
|
},
|
32
32
|
"client1": {
|
33
33
|
"image_id": "69",
|
@@ -37,12 +37,10 @@ class ServerGroupTest < Test::Unit::TestCase
|
|
37
37
|
}}
|
38
38
|
|
39
39
|
def test_server_new
|
40
|
-
sg=ServerGroup.new(:name => "test", :domain_name => "
|
40
|
+
sg=ServerGroup.new(:name => "test", :domain_name => "foo", :description => "zz")
|
41
41
|
assert_equal "test", sg.name
|
42
42
|
assert_equal "zz", sg.description
|
43
|
-
assert_equal "
|
44
|
-
assert_equal "172.19.0.0", sg.vpn_network
|
45
|
-
assert_equal "255.255.128.0", sg.vpn_subnet
|
43
|
+
assert_equal "foo", sg.domain_name
|
46
44
|
end
|
47
45
|
|
48
46
|
def test_gateway_ip
|
@@ -51,19 +49,12 @@ class ServerGroupTest < Test::Unit::TestCase
|
|
51
49
|
assert_equal 1759, sg.id
|
52
50
|
assert_equal "test description", sg.description
|
53
51
|
assert_equal "dan.prince", sg.owner_name
|
54
|
-
assert_equal "172.19.0.0", sg.vpn_network
|
55
|
-
assert_equal "255.255.128.0", sg.vpn_subnet
|
56
52
|
assert_equal 2, sg.servers.size
|
57
53
|
end
|
58
54
|
|
59
|
-
#def test_vpn_gateway_name
|
60
|
-
#sg=ServerGroup.from_xml(SERVER_GROUP_XML)
|
61
|
-
#assert_equal "login1", sg.vpn_gateway_name
|
62
|
-
#end
|
63
|
-
|
64
55
|
def test_server_group_from_json_config
|
65
56
|
sg=ServerGroup.from_json(TEST_JSON_CONFIG)
|
66
|
-
assert_equal "
|
57
|
+
assert_equal "foo", sg.domain_name
|
67
58
|
assert_equal "test", sg.name
|
68
59
|
assert_equal "test description", sg.description
|
69
60
|
assert_equal 2, sg.servers.size
|
@@ -73,13 +64,13 @@ class ServerGroupTest < Test::Unit::TestCase
|
|
73
64
|
login_server=sg.server("login")
|
74
65
|
assert_equal "51", login_server.image_id
|
75
66
|
assert_equal "2", login_server.flavor_id
|
76
|
-
assert_equal true, login_server.
|
67
|
+
assert_equal true, login_server.gateway?
|
77
68
|
|
78
69
|
# validate the client1 server
|
79
70
|
client1_server=sg.server("client1")
|
80
71
|
assert_equal "69", client1_server.image_id
|
81
72
|
assert_equal "3", client1_server.flavor_id
|
82
|
-
assert_equal false, client1_server.
|
73
|
+
assert_equal false, client1_server.gateway?
|
83
74
|
|
84
75
|
end
|
85
76
|
|
data/test/server_test.rb
CHANGED
@@ -3,11 +3,11 @@ require 'test_helper'
|
|
3
3
|
|
4
4
|
module Kytoon
|
5
5
|
module Providers
|
6
|
-
module
|
6
|
+
module CloudCue
|
7
7
|
|
8
8
|
class ServerTest < Test::Unit::TestCase
|
9
9
|
|
10
|
-
include Kytoon::Providers::
|
10
|
+
include Kytoon::Providers::CloudCue
|
11
11
|
|
12
12
|
def setup
|
13
13
|
@tmp_dir=TmpDir.new_tmp_dir
|
@@ -18,7 +18,7 @@ class ServerTest < Test::Unit::TestCase
|
|
18
18
|
FileUtils.rm_rf(@tmp_dir)
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
21
|
+
def test_gateway_server_rebuild_fails
|
22
22
|
group=ServerGroup.from_xml(SERVER_GROUP_XML)
|
23
23
|
server=group.server("login1")
|
24
24
|
assert_raises(RuntimeError) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kytoon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdoc
|
@@ -220,7 +220,7 @@ dependencies:
|
|
220
220
|
- !ruby/object:Gem::Version
|
221
221
|
version: '0'
|
222
222
|
description: A set of Rake tasks that provide a framework to help automate the creation
|
223
|
-
and configuration
|
223
|
+
and configuration server groups.
|
224
224
|
email: dprince@redhat.com
|
225
225
|
executables:
|
226
226
|
- kytoon
|
@@ -238,19 +238,17 @@ files:
|
|
238
238
|
- Rakefile
|
239
239
|
- VERSION
|
240
240
|
- bin/kytoon
|
241
|
+
- config/server_group_cloudcue.json
|
241
242
|
- config/server_group_libvirt.json
|
242
243
|
- config/server_group_openstack.json
|
243
|
-
- config/server_group_vpc.json
|
244
244
|
- config/server_group_xen.json
|
245
245
|
- lib/kytoon.rb
|
246
246
|
- lib/kytoon/exception.rb
|
247
|
-
- lib/kytoon/providers/
|
248
|
-
- lib/kytoon/providers/
|
249
|
-
- lib/kytoon/providers/
|
250
|
-
- lib/kytoon/providers/
|
251
|
-
- lib/kytoon/providers/
|
252
|
-
- lib/kytoon/providers/cloud_servers_vpc/ssh_public_key.rb
|
253
|
-
- lib/kytoon/providers/cloud_servers_vpc/vpn_network_interface.rb
|
247
|
+
- lib/kytoon/providers/cloud_cue.rb
|
248
|
+
- lib/kytoon/providers/cloud_cue/connection.rb
|
249
|
+
- lib/kytoon/providers/cloud_cue/server.rb
|
250
|
+
- lib/kytoon/providers/cloud_cue/server_group.rb
|
251
|
+
- lib/kytoon/providers/cloud_cue/ssh_public_key.rb
|
254
252
|
- lib/kytoon/providers/libvirt.rb
|
255
253
|
- lib/kytoon/providers/libvirt/server_group.rb
|
256
254
|
- lib/kytoon/providers/openstack.rb
|
@@ -262,12 +260,8 @@ files:
|
|
262
260
|
- lib/kytoon/thor_tasks.rb
|
263
261
|
- lib/kytoon/util.rb
|
264
262
|
- lib/kytoon/version.rb
|
265
|
-
- lib/kytoon/vpn/vpn_connection.rb
|
266
|
-
- lib/kytoon/vpn/vpn_network_manager.rb
|
267
|
-
- lib/kytoon/vpn/vpn_openvpn.rb
|
268
263
|
- lib/kytoon/xml_util.rb
|
269
264
|
- rake/kytoon.rake
|
270
|
-
- test/client_test.rb
|
271
265
|
- test/helper.rb
|
272
266
|
- test/server_group_test.rb
|
273
267
|
- test/server_test.rb
|
@@ -289,7 +283,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
289
283
|
version: '0'
|
290
284
|
segments:
|
291
285
|
- 0
|
292
|
-
hash:
|
286
|
+
hash: 4014569105622964663
|
293
287
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
294
288
|
none: false
|
295
289
|
requirements:
|
@@ -1,11 +0,0 @@
|
|
1
|
-
require 'kytoon/providers/cloud_servers_vpc/connection'
|
2
|
-
require 'kytoon/providers/cloud_servers_vpc/client'
|
3
|
-
require 'kytoon/providers/cloud_servers_vpc/server'
|
4
|
-
require 'kytoon/providers/cloud_servers_vpc/server_group'
|
5
|
-
require 'kytoon/providers/cloud_servers_vpc/ssh_public_key'
|
6
|
-
require 'kytoon/providers/cloud_servers_vpc/vpn_network_interface'
|
7
|
-
require 'kytoon/util'
|
8
|
-
|
9
|
-
Kytoon::Util.check_config_param('cloud_servers_vpc_url')
|
10
|
-
Kytoon::Util.check_config_param('cloud_servers_vpc_username')
|
11
|
-
Kytoon::Util.check_config_param('cloud_servers_vpc_password')
|
@@ -1,197 +0,0 @@
|
|
1
|
-
module Kytoon
|
2
|
-
|
3
|
-
module Providers
|
4
|
-
|
5
|
-
module CloudServersVPC
|
6
|
-
|
7
|
-
class Client
|
8
|
-
|
9
|
-
@@data_dir=File.join(KYTOON_PROJECT, "tmp", "clients")
|
10
|
-
|
11
|
-
def self.data_dir
|
12
|
-
@@data_dir
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.data_dir=(dir)
|
16
|
-
@@data_dir=dir
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_accessor :id
|
20
|
-
attr_accessor :name
|
21
|
-
attr_accessor :description
|
22
|
-
attr_accessor :status
|
23
|
-
attr_accessor :server_group_id
|
24
|
-
attr_accessor :cache_file
|
25
|
-
|
26
|
-
def initialize(options={})
|
27
|
-
@id=options[:id].to_i
|
28
|
-
@name=options[:name]
|
29
|
-
@description=options[:description]
|
30
|
-
if options[:status]
|
31
|
-
@status=options[:status]
|
32
|
-
else
|
33
|
-
@status = "Pending"
|
34
|
-
end
|
35
|
-
@status=options[:status] or @status = "Pending"
|
36
|
-
@server_group_id=options[:server_group_id]
|
37
|
-
if options[:cache_file] then
|
38
|
-
@cache_file=options[:cache_file]
|
39
|
-
else
|
40
|
-
@cache_file=options[:server_group_id]
|
41
|
-
end
|
42
|
-
@vpn_network_interfaces=[]
|
43
|
-
end
|
44
|
-
|
45
|
-
def vpn_network_interfaces
|
46
|
-
@vpn_network_interfaces
|
47
|
-
end
|
48
|
-
|
49
|
-
def cache_to_disk
|
50
|
-
FileUtils.mkdir_p(@@data_dir)
|
51
|
-
File.open(File.join(@@data_dir, "#{@cache_file}.xml"), 'w') do |f|
|
52
|
-
f.chmod(0600)
|
53
|
-
f.write(self.to_xml)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def delete
|
58
|
-
client_xml_file=File.join(@@data_dir, "#{@cache_file}.xml")
|
59
|
-
if File.exists?(client_xml_file) then
|
60
|
-
File.delete(client_xml_file)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.from_xml(xml)
|
65
|
-
client=nil
|
66
|
-
dom = REXML::Document.new(xml)
|
67
|
-
REXML::XPath.each(dom, "/client") do |cxml|
|
68
|
-
|
69
|
-
client=Client.new(
|
70
|
-
:id => XMLUtil.element_text(cxml,"id").to_i,
|
71
|
-
:name => XMLUtil.element_text(cxml, "name"),
|
72
|
-
:description => XMLUtil.element_text(cxml,"description"),
|
73
|
-
:status => XMLUtil.element_text(cxml,"status"),
|
74
|
-
:server_group_id => XMLUtil.element_text(cxml, "server-group-id").to_i
|
75
|
-
)
|
76
|
-
REXML::XPath.each(dom, "//vpn-network-interface") do |vni|
|
77
|
-
vni = VpnNetworkInterface.new(
|
78
|
-
:id => XMLUtil.element_text(vni, "id"),
|
79
|
-
:vpn_ip_addr => XMLUtil.element_text(vni, "vpn-ip-addr"),
|
80
|
-
:ptp_ip_addr => XMLUtil.element_text(vni, "ptp-ip-addr"),
|
81
|
-
:client_key => XMLUtil.element_text(vni, "client-key"),
|
82
|
-
:client_cert => XMLUtil.element_text(vni, "client-cert"),
|
83
|
-
:ca_cert => XMLUtil.element_text(vni, "ca-cert")
|
84
|
-
)
|
85
|
-
client.vpn_network_interfaces << vni
|
86
|
-
end
|
87
|
-
end
|
88
|
-
client
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_xml
|
92
|
-
|
93
|
-
xml = Builder::XmlMarkup.new
|
94
|
-
xml.tag! "client" do |sg|
|
95
|
-
sg.id(@id)
|
96
|
-
sg.name(@name)
|
97
|
-
sg.description(@description)
|
98
|
-
sg.status(@status)
|
99
|
-
sg.tag! "server-group-id", @server_group_id
|
100
|
-
sg.tag! "vpn-network-interfaces", {"type" => "array"} do |interfaces|
|
101
|
-
@vpn_network_interfaces.each do |vni|
|
102
|
-
interfaces.tag! "vpn-network-interface" do |xml_vni|
|
103
|
-
xml_vni.id(vni.id)
|
104
|
-
xml_vni.tag! "vpn-ip-addr", vni.vpn_ip_addr
|
105
|
-
xml_vni.tag! "ptp-ip-addr", vni.ptp_ip_addr
|
106
|
-
xml_vni.tag! "client-key", vni.client_key
|
107
|
-
xml_vni.tag! "client-cert", vni.client_cert
|
108
|
-
xml_vni.tag! "ca-cert", vni.ca_cert
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
xml.target!
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
# Poll the server group until it is online.
|
120
|
-
# :timeout - max number of seconds to wait before raising an exception.
|
121
|
-
# Defaults to 1500
|
122
|
-
def poll_until_online(options={})
|
123
|
-
|
124
|
-
timeout=options[:timeout] or timeout = ENV['VPN_CLIENT_TIMEOUT']
|
125
|
-
if timeout.nil? or timeout.empty? then
|
126
|
-
timeout=300 # defaults to 5 minutes
|
127
|
-
end
|
128
|
-
|
129
|
-
online = false
|
130
|
-
count=0
|
131
|
-
until online or (count*5) >= timeout.to_i do
|
132
|
-
count+=1
|
133
|
-
begin
|
134
|
-
client=Client.get(:id => @id, :source => "remote")
|
135
|
-
|
136
|
-
if client.status == "Online" then
|
137
|
-
online = true
|
138
|
-
else
|
139
|
-
yield client if block_given?
|
140
|
-
sleep 5
|
141
|
-
end
|
142
|
-
rescue EOFError
|
143
|
-
end
|
144
|
-
end
|
145
|
-
if (count*20) >= timeout.to_i then
|
146
|
-
raise "Timeout waiting for client to come online."
|
147
|
-
end
|
148
|
-
|
149
|
-
end
|
150
|
-
|
151
|
-
def self.create(server_group, client_name, cache_to_disk=true)
|
152
|
-
|
153
|
-
xml = Builder::XmlMarkup.new
|
154
|
-
xml.client do |client|
|
155
|
-
client.name(client_name)
|
156
|
-
client.description("Toolkit Client: #{client_name}")
|
157
|
-
client.tag! "server-group-id", server_group.id
|
158
|
-
end
|
159
|
-
|
160
|
-
xml=Connection.post("/clients.xml", xml.target!)
|
161
|
-
client=Client.from_xml(xml)
|
162
|
-
client.cache_to_disk if cache_to_disk
|
163
|
-
client
|
164
|
-
|
165
|
-
end
|
166
|
-
|
167
|
-
# Get a client. The following options are available:
|
168
|
-
#
|
169
|
-
# :id - The ID of the client to get.
|
170
|
-
# :source - valid options are 'remote' and 'cache'
|
171
|
-
#
|
172
|
-
def self.get(options = {})
|
173
|
-
|
174
|
-
source = options[:source] or source = "remote"
|
175
|
-
|
176
|
-
if source == "remote" then
|
177
|
-
id=options[:id] or raise "Please specify a Client ID."
|
178
|
-
xml=Connection.get("/clients/#{id}.xml")
|
179
|
-
Client.from_xml(xml)
|
180
|
-
elsif source == "cache" then
|
181
|
-
id=options[:id] or id = ENV['GROUP_ID']
|
182
|
-
client_xml_file=File.join(@@data_dir, "#{id}.xml")
|
183
|
-
raise "No client files exist." if not File.exists?(client_xml_file)
|
184
|
-
Client.from_xml(IO.read(client_xml_file))
|
185
|
-
else
|
186
|
-
raise "Invalid get :source specified."
|
187
|
-
end
|
188
|
-
|
189
|
-
end
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
end
|
194
|
-
|
195
|
-
end
|
196
|
-
|
197
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Kytoon
|
2
|
-
|
3
|
-
module Providers
|
4
|
-
|
5
|
-
module CloudServersVPC
|
6
|
-
|
7
|
-
class VpnNetworkInterface
|
8
|
-
|
9
|
-
attr_accessor :id
|
10
|
-
attr_accessor :vpn_ip_addr
|
11
|
-
attr_accessor :ptp_ip_addr
|
12
|
-
attr_accessor :client_key
|
13
|
-
attr_accessor :client_cert
|
14
|
-
attr_accessor :ca_cert
|
15
|
-
|
16
|
-
def initialize(options={})
|
17
|
-
|
18
|
-
@id=options[:id].to_i
|
19
|
-
@vpn_ip_addr=options[:vpn_ip_addr]
|
20
|
-
@ptp_ip_addr=options[:ptp_ip_addr]
|
21
|
-
@client_key=options[:client_key]
|
22
|
-
@client_cert=options[:client_cert]
|
23
|
-
@ca_cert=options[:ca_cert]
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
|
2
|
-
module Kytoon
|
3
|
-
module Vpn
|
4
|
-
class VpnConnection
|
5
|
-
|
6
|
-
CERT_DIR=File.join(ENV['HOME'], '.pki', 'openvpn')
|
7
|
-
|
8
|
-
def initialize(group, client = nil)
|
9
|
-
@group = group
|
10
|
-
@client = client
|
11
|
-
end
|
12
|
-
|
13
|
-
def create_certs
|
14
|
-
@ca_cert=get_cfile('ca.crt')
|
15
|
-
@client_cert=get_cfile('client.crt')
|
16
|
-
@client_key=get_cfile('client.key')
|
17
|
-
|
18
|
-
vpn_interface = @client.vpn_network_interfaces[0]
|
19
|
-
|
20
|
-
FileUtils.mkdir_p(get_cfile)
|
21
|
-
File::chmod(0700, File.join(ENV['HOME'], '.pki'))
|
22
|
-
File::chmod(0700, CERT_DIR)
|
23
|
-
|
24
|
-
File.open(@ca_cert, 'w') { |f| f.write(vpn_interface.ca_cert) }
|
25
|
-
File.open(@client_cert, 'w') { |f| f.write(vpn_interface.client_cert) }
|
26
|
-
File.open(@client_key, 'w') do |f|
|
27
|
-
f.write(vpn_interface.client_key)
|
28
|
-
f.chmod(0600)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def delete_certs
|
33
|
-
FileUtils.rm_rf(get_cfile)
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_cfile(file = nil)
|
37
|
-
if file
|
38
|
-
File.join(CERT_DIR, @group.id.to_s, file)
|
39
|
-
else
|
40
|
-
File.join(CERT_DIR, @group.id.to_s)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,237 +0,0 @@
|
|
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 Kytoon
|
11
|
-
module Vpn
|
12
|
-
|
13
|
-
class VpnNetworkManager < VpnConnection
|
14
|
-
|
15
|
-
def initialize(group, client = nil)
|
16
|
-
super(group, client)
|
17
|
-
end
|
18
|
-
|
19
|
-
def connect
|
20
|
-
create_certs
|
21
|
-
configure_gconf
|
22
|
-
puts %x{#{sudo_display} nmcli con up id "VPC Group: #{@group.id}"}
|
23
|
-
end
|
24
|
-
|
25
|
-
def disconnect
|
26
|
-
puts %x{#{sudo_display} nmcli con down id "VPC Group: #{@group.id}"}
|
27
|
-
end
|
28
|
-
|
29
|
-
def connected?
|
30
|
-
return system("#{sudo_display} nmcli con status | grep -c 'VPC Group: #{@group.id}' &> /dev/null")
|
31
|
-
end
|
32
|
-
|
33
|
-
def clean
|
34
|
-
unset_gconf_config
|
35
|
-
delete_certs
|
36
|
-
end
|
37
|
-
|
38
|
-
def configure_gconf
|
39
|
-
|
40
|
-
xml = Builder::XmlMarkup.new
|
41
|
-
xml.gconfentryfile do |file|
|
42
|
-
file.entrylist({ "base" => "/system/networking/connections/vpc_#{@group.id}"}) do |entrylist|
|
43
|
-
|
44
|
-
entrylist.entry do |entry|
|
45
|
-
entry.key("connection/autoconnect")
|
46
|
-
entry.value do |value|
|
47
|
-
value.bool("false")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
entrylist.entry do |entry|
|
51
|
-
entry.key("connection/id")
|
52
|
-
entry.value do |value|
|
53
|
-
value.string("VPC Group: #{@group.id}")
|
54
|
-
end
|
55
|
-
end
|
56
|
-
entrylist.entry do |entry|
|
57
|
-
entry.key("connection/name")
|
58
|
-
entry.value do |value|
|
59
|
-
value.string("connection")
|
60
|
-
end
|
61
|
-
end
|
62
|
-
entrylist.entry do |entry|
|
63
|
-
entry.key("connection/timestamp")
|
64
|
-
entry.value do |value|
|
65
|
-
value.string(Time.now.to_i.to_s)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
entrylist.entry do |entry|
|
69
|
-
entry.key("connection/type")
|
70
|
-
entry.value do |value|
|
71
|
-
value.string("vpn")
|
72
|
-
end
|
73
|
-
end
|
74
|
-
entrylist.entry do |entry|
|
75
|
-
entry.key("connection/uuid")
|
76
|
-
entry.value do |value|
|
77
|
-
value.string(UUIDTools::UUID.random_create)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
entrylist.entry do |entry|
|
81
|
-
entry.key("ipv4/addresses")
|
82
|
-
entry.value do |value|
|
83
|
-
value.list("type" => "int") do |list|
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
entrylist.entry do |entry|
|
88
|
-
entry.key("ipv4/dns")
|
89
|
-
entry.value do |value|
|
90
|
-
value.list("type" => "int") do |list|
|
91
|
-
ip=IPAddr.new(@group.vpn_network.chomp("0")+"1")
|
92
|
-
list.value do |lv|
|
93
|
-
lv.int(ip_to_integer(ip.to_s))
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
entrylist.entry do |entry|
|
99
|
-
entry.key("ipv4/dns-search")
|
100
|
-
entry.value do |value|
|
101
|
-
value.list("type" => "string") do |list|
|
102
|
-
list.value do |lv|
|
103
|
-
lv.string(@group.domain_name)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
entrylist.entry do |entry|
|
109
|
-
entry.key("ipv4/ignore-auto-dns")
|
110
|
-
entry.value do |value|
|
111
|
-
value.bool("true")
|
112
|
-
end
|
113
|
-
end
|
114
|
-
entrylist.entry do |entry|
|
115
|
-
entry.key("ipv4/method")
|
116
|
-
entry.value do |value|
|
117
|
-
value.string("auto")
|
118
|
-
end
|
119
|
-
end
|
120
|
-
entrylist.entry do |entry|
|
121
|
-
entry.key("ipv4/name")
|
122
|
-
entry.value do |value|
|
123
|
-
value.string("ipv4")
|
124
|
-
end
|
125
|
-
end
|
126
|
-
entrylist.entry do |entry|
|
127
|
-
entry.key("ipv4/never-default")
|
128
|
-
entry.value do |value|
|
129
|
-
value.bool("true")
|
130
|
-
end
|
131
|
-
end
|
132
|
-
entrylist.entry do |entry|
|
133
|
-
entry.key("ipv4/routes")
|
134
|
-
entry.value do |value|
|
135
|
-
value.list("type" => "int") do |list|
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
entrylist.entry do |entry|
|
140
|
-
entry.key("vpn/ca")
|
141
|
-
entry.value do |value|
|
142
|
-
value.string(@ca_cert)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
entrylist.entry do |entry|
|
146
|
-
entry.key("vpn/cert")
|
147
|
-
entry.value do |value|
|
148
|
-
value.string(@client_cert)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
entrylist.entry do |entry|
|
152
|
-
entry.key("vpn/comp-lzo")
|
153
|
-
entry.value do |value|
|
154
|
-
value.string("yes")
|
155
|
-
end
|
156
|
-
end
|
157
|
-
entrylist.entry do |entry|
|
158
|
-
entry.key("vpn/connection-type")
|
159
|
-
entry.value do |value|
|
160
|
-
value.string("tls")
|
161
|
-
end
|
162
|
-
end
|
163
|
-
entrylist.entry do |entry|
|
164
|
-
entry.key("vpn/key")
|
165
|
-
entry.value do |value|
|
166
|
-
value.string(@client_key)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
if @group.vpn_proto == "tcp"
|
170
|
-
entrylist.entry do |entry|
|
171
|
-
entry.key("vpn/proto-tcp")
|
172
|
-
entry.value do |value|
|
173
|
-
value.string("yes")
|
174
|
-
end
|
175
|
-
end
|
176
|
-
else
|
177
|
-
entrylist.entry do |entry|
|
178
|
-
entry.key("vpn/proto-udp")
|
179
|
-
entry.value do |value|
|
180
|
-
value.string("yes")
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
if @group.vpn_device == "tap"
|
185
|
-
entrylist.entry do |entry|
|
186
|
-
entry.key("vpn/tap-dev")
|
187
|
-
entry.value do |value|
|
188
|
-
value.string("yes")
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
entrylist.entry do |entry|
|
193
|
-
entry.key("vpn/remote")
|
194
|
-
entry.value do |value|
|
195
|
-
value.string(@group.gateway_ip)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
entrylist.entry do |entry|
|
199
|
-
entry.key("vpn/service-type")
|
200
|
-
entry.value do |value|
|
201
|
-
value.string("org.freedesktop.NetworkManager.openvpn")
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
end
|
207
|
-
|
208
|
-
Tempfile.open('w') do |f|
|
209
|
-
f.write(xml.target!)
|
210
|
-
f.flush
|
211
|
-
puts %x{gconftool-2 --load #{f.path}}
|
212
|
-
end
|
213
|
-
|
214
|
-
return true
|
215
|
-
|
216
|
-
end
|
217
|
-
|
218
|
-
def unset_gconf_config
|
219
|
-
puts %x{gconftool-2 --recursive-unset /system/networking/connections/vpc_#{@group.id}}
|
220
|
-
end
|
221
|
-
|
222
|
-
def ip_to_integer(ip_string)
|
223
|
-
return 0 if ip_string.nil?
|
224
|
-
ip_arr=ip_string.split(".").collect{ |s| s.to_i }
|
225
|
-
return ip_arr[0] + ip_arr[1]*2**8 + ip_arr[2]*2**16 + ip_arr[3]*2**24
|
226
|
-
end
|
227
|
-
|
228
|
-
def sudo_display
|
229
|
-
if ENV['DISPLAY'].nil? or ENV['DISPLAY'] != ":0.0" then
|
230
|
-
"sudo"
|
231
|
-
else
|
232
|
-
""
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
module Kytoon
|
2
|
-
module Vpn
|
3
|
-
class VpnOpenVpn < VpnConnection
|
4
|
-
|
5
|
-
def initialize(group, client = nil)
|
6
|
-
super(group, client)
|
7
|
-
end
|
8
|
-
|
9
|
-
def connect
|
10
|
-
create_certs
|
11
|
-
|
12
|
-
@up_script=get_cfile('up.bash')
|
13
|
-
File.open(@up_script, 'w') do |f|
|
14
|
-
f << <<EOF_UP
|
15
|
-
#!/bin/bash
|
16
|
-
|
17
|
-
# setup routes
|
18
|
-
/sbin/route add #{@group.vpn_network.chomp("0")+"1"} dev \$dev
|
19
|
-
/sbin/route add -net #{@group.vpn_network} netmask 255.255.128.0 gw #{@group.vpn_network.chomp("0")+"1"}
|
20
|
-
|
21
|
-
mv /etc/resolv.conf /etc/resolv.conf.bak
|
22
|
-
egrep ^search /etc/resolv.conf.bak | sed -e 's/search /search #{@group.domain_name} /' > /etc/resolv.conf
|
23
|
-
echo 'nameserver #{@group.vpn_network.chomp("0")+"1"}' >> /etc/resolv.conf
|
24
|
-
grep ^nameserver /etc/resolv.conf.bak >> /etc/resolv.conf
|
25
|
-
EOF_UP
|
26
|
-
f.chmod(0700)
|
27
|
-
end
|
28
|
-
@down_script=get_cfile('down.bash')
|
29
|
-
File.open(@down_script, 'w') do |f|
|
30
|
-
f << <<EOF_DOWN
|
31
|
-
#!/bin/bash
|
32
|
-
mv /etc/resolv.conf.bak /etc/resolv.conf
|
33
|
-
EOF_DOWN
|
34
|
-
f.chmod(0700)
|
35
|
-
end
|
36
|
-
|
37
|
-
@config_file=get_cfile('config')
|
38
|
-
File.open(@config_file, 'w') do |f|
|
39
|
-
f << <<EOF_CONFIG
|
40
|
-
client
|
41
|
-
dev #{@group.vpn_device}
|
42
|
-
proto #{@group.vpn_proto}
|
43
|
-
|
44
|
-
#Change my.publicdomain.com to your public domain or IP address
|
45
|
-
remote #{@group.gateway_ip} 1194
|
46
|
-
|
47
|
-
resolv-retry infinite
|
48
|
-
nobind
|
49
|
-
persist-key
|
50
|
-
persist-tun
|
51
|
-
|
52
|
-
script-security 2
|
53
|
-
|
54
|
-
ca #{@ca_cert}
|
55
|
-
cert #{@client_cert}
|
56
|
-
key #{@client_key}
|
57
|
-
|
58
|
-
ns-cert-type server
|
59
|
-
|
60
|
-
route-nopull
|
61
|
-
|
62
|
-
comp-lzo
|
63
|
-
|
64
|
-
verb 3
|
65
|
-
up #{@up_script}
|
66
|
-
down #{@down_script}
|
67
|
-
EOF_CONFIG
|
68
|
-
f.chmod(0600)
|
69
|
-
end
|
70
|
-
|
71
|
-
disconnect if File.exist?(get_cfile('openvpn.pid'))
|
72
|
-
out=%x{sudo openvpn --config #{@config_file} --writepid #{get_cfile('openvpn.pid')} --daemon}
|
73
|
-
retval=$?
|
74
|
-
if retval.success? then
|
75
|
-
poll_vpn_interface
|
76
|
-
puts "OK."
|
77
|
-
else
|
78
|
-
raise "Failed to create VPN connection: #{out}"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def disconnect
|
83
|
-
raise "Not running? No pid file found!" unless File.exist?(get_cfile('openvpn.pid'))
|
84
|
-
pid = File.read(get_cfile('openvpn.pid')).chomp
|
85
|
-
system("sudo kill -TERM #{pid}")
|
86
|
-
File.delete(get_cfile('openvpn.pid'))
|
87
|
-
end
|
88
|
-
|
89
|
-
def connected?
|
90
|
-
system("/sbin/route -n | grep #{@group.vpn_network.chomp("0")+"1"} &> /dev/null")
|
91
|
-
end
|
92
|
-
|
93
|
-
def clean
|
94
|
-
delete_certs
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
def poll_vpn_interface
|
99
|
-
interface_name=@group.vpn_device+"0"
|
100
|
-
1.upto(30) do |i|
|
101
|
-
break if system("/sbin/ifconfig #{interface_name} > /dev/null 2>&1")
|
102
|
-
if i == 30 then
|
103
|
-
disconnect
|
104
|
-
raise "Failed to connect to VPN."
|
105
|
-
end
|
106
|
-
sleep 0.5
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
data/test/client_test.rb
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)
|
2
|
-
require 'test_helper'
|
3
|
-
require 'kytoon/providers/cloud_servers_vpc'
|
4
|
-
|
5
|
-
module Kytoon
|
6
|
-
module Providers
|
7
|
-
module CloudServersVPC
|
8
|
-
|
9
|
-
class ClientTest < Test::Unit::TestCase
|
10
|
-
|
11
|
-
include Kytoon::Providers::CloudServersVPC
|
12
|
-
|
13
|
-
def setup
|
14
|
-
@tmp_dir=TmpDir.new_tmp_dir
|
15
|
-
Client.data_dir=@tmp_dir
|
16
|
-
end
|
17
|
-
|
18
|
-
def teardown
|
19
|
-
FileUtils.rm_rf(@tmp_dir)
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_new
|
23
|
-
client=Client.new(:name => "test", :description => "zz", :status => "Pending")
|
24
|
-
assert_equal "test", client.name
|
25
|
-
assert_equal "zz", client.description
|
26
|
-
assert_equal 0, client.vpn_network_interfaces.size
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_from_xml
|
30
|
-
client=Client.from_xml(CLIENT_XML)
|
31
|
-
assert_equal "local", client.name
|
32
|
-
assert_equal "Toolkit Client: local", client.description
|
33
|
-
assert_equal 5, client.id
|
34
|
-
assert_equal 11, client.server_group_id
|
35
|
-
vni=client.vpn_network_interfaces[0]
|
36
|
-
assert_not_nil vni.client_key
|
37
|
-
assert_not_nil vni.client_cert
|
38
|
-
assert_not_nil vni.ca_cert
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_client_to_and_from_xml
|
42
|
-
client=Client.from_xml(CLIENT_XML)
|
43
|
-
xml=client.to_xml
|
44
|
-
assert_not_nil xml
|
45
|
-
client=Client.from_xml(xml)
|
46
|
-
assert_equal "local", client.name
|
47
|
-
assert_equal "Toolkit Client: local", client.description
|
48
|
-
assert_equal 5, client.id
|
49
|
-
assert_equal 11, client.server_group_id
|
50
|
-
vni=client.vpn_network_interfaces[0]
|
51
|
-
assert_not_nil vni.client_key
|
52
|
-
assert_not_nil vni.client_cert
|
53
|
-
assert_not_nil vni.ca_cert
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_get
|
57
|
-
|
58
|
-
tmp_dir=TmpDir.new_tmp_dir
|
59
|
-
File.open("#{tmp_dir}/5.xml", 'w') do |f|
|
60
|
-
f.write(CLIENT_XML)
|
61
|
-
end
|
62
|
-
Client.data_dir=tmp_dir
|
63
|
-
|
64
|
-
Connection.stubs(:get).returns(CLIENT_XML)
|
65
|
-
|
66
|
-
# should raise exception if no ID is set and doing a remote lookup
|
67
|
-
assert_raises(RuntimeError) do
|
68
|
-
Client.get
|
69
|
-
end
|
70
|
-
|
71
|
-
client=Client.get(:id => "1234")
|
72
|
-
assert_not_nil client
|
73
|
-
assert_equal "Toolkit Client: local", client.description
|
74
|
-
|
75
|
-
client=Client.get(:id => "5", :source => "cache")
|
76
|
-
assert_not_nil client
|
77
|
-
assert_equal "Toolkit Client: local", client.description
|
78
|
-
|
79
|
-
#nonexistent group from cache
|
80
|
-
ENV['GROUP_ID']="1234"
|
81
|
-
assert_raises(RuntimeError) do
|
82
|
-
Client.get(:source => "cache")
|
83
|
-
end
|
84
|
-
|
85
|
-
#invalid get source
|
86
|
-
assert_raises(RuntimeError) do
|
87
|
-
Client.get(:id => "5", :source => "asdf")
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_delete
|
93
|
-
|
94
|
-
client=Client.from_xml(CLIENT_XML)
|
95
|
-
client.delete
|
96
|
-
assert_equal false, File.exists?(File.join(Client.data_dir, "#{client.id}.xml"))
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_create
|
101
|
-
|
102
|
-
Connection.stubs(:post).returns(CLIENT_XML)
|
103
|
-
client=Client.create(ServerGroup.from_xml(SERVER_GROUP_XML), "local")
|
104
|
-
assert_equal "local", client.name
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|