testlab 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -5
- data/lib/testlab/container/actions.rb +47 -0
- data/lib/testlab/container/generators.rb +42 -0
- data/lib/testlab/container/lifecycle.rb +25 -0
- data/lib/testlab/container/lxc.rb +43 -0
- data/lib/testlab/container/network.rb +31 -0
- data/lib/testlab/container/status.rb +28 -0
- data/lib/testlab/container.rb +58 -150
- data/lib/testlab/network/actions.rb +37 -0
- data/lib/testlab/network/cidr.rb +102 -0
- data/lib/testlab/network/lifecycle.rb +25 -0
- data/lib/testlab/network/status.rb +30 -0
- data/lib/testlab/network.rb +11 -101
- data/lib/testlab/node/bind.rb +95 -0
- data/lib/testlab/node/lifecycle.rb +43 -0
- data/lib/testlab/node/lxc.rb +31 -0
- data/lib/testlab/node/resolv.rb +30 -0
- data/lib/testlab/node/ssh.rb +43 -0
- data/lib/testlab/node/status.rb +26 -0
- data/lib/testlab/node/templates/bind-db.erb +12 -0
- data/lib/testlab/node/templates/bind-setup.erb +6 -0
- data/lib/testlab/node/templates/bind-zone.erb +4 -0
- data/lib/testlab/node/templates/bind.erb +60 -0
- data/lib/testlab/node/templates/node-setup.erb +18 -0
- data/lib/testlab/node/templates/resolv.erb +4 -0
- data/lib/testlab/node.rb +36 -89
- data/lib/testlab/providers/vagrant.rb +9 -1
- data/lib/testlab/provisioner.rb +0 -1
- data/lib/testlab/router.rb +3 -8
- data/lib/testlab/version.rb +1 -1
- data/lib/testlab.rb +21 -7
- data/spec/spec_helper.rb +2 -0
- data/spec/testlab_spec.rb +1 -1
- data/testlab.gemspec +2 -2
- metadata +28 -6
data/README.md
CHANGED
@@ -6,10 +6,20 @@
|
|
6
6
|
|
7
7
|
# TestLab
|
8
8
|
|
9
|
-
A framework for building lightweight virtual
|
9
|
+
A framework for building lightweight virtual infrastructure using LXC
|
10
|
+
|
11
|
+
# REQUIREMENTS
|
12
|
+
|
13
|
+
* Latest VirtualBox Package
|
14
|
+
* Latest Vagrant Package (non-gem version)
|
15
|
+
* Ubuntu 13.04 Server 64-bit (Raring) Base Box - https://github.com/zpatten/raring64
|
10
16
|
|
11
17
|
# RESOURCES
|
12
18
|
|
19
|
+
Documentation:
|
20
|
+
|
21
|
+
* http://zpatten.github.io/testlab/
|
22
|
+
|
13
23
|
Source:
|
14
24
|
|
15
25
|
* https://github.com/zpatten/testlab
|
@@ -18,10 +28,6 @@ Issues:
|
|
18
28
|
|
19
29
|
* https://github.com/zpatten/testlab/issues
|
20
30
|
|
21
|
-
Documentation:
|
22
|
-
|
23
|
-
* http://zpatten.github.com/testlab/
|
24
|
-
|
25
31
|
# LICENSE
|
26
32
|
|
27
33
|
TestLab - A framework for building lightweight virtual laboratories using LXC
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Container
|
3
|
+
|
4
|
+
module Actions
|
5
|
+
|
6
|
+
# Create the container
|
7
|
+
def create
|
8
|
+
@ui.logger.debug { "Container Create: #{self.id} " }
|
9
|
+
|
10
|
+
self.distro ||= "ubuntu"
|
11
|
+
self.release ||= "precise"
|
12
|
+
self.arch ||= detect_arch
|
13
|
+
|
14
|
+
self.lxc.config.clear
|
15
|
+
self.lxc.config['lxc.utsname'] = self.id
|
16
|
+
self.lxc.config['lxc.arch'] = self.arch
|
17
|
+
self.lxc.config.networks = build_lxc_network_conf(self.interfaces)
|
18
|
+
self.lxc.config.save
|
19
|
+
|
20
|
+
self.lxc.create(*create_args)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Destroy the container
|
24
|
+
def destroy
|
25
|
+
@ui.logger.debug { "Container Destroy: #{self.id} " }
|
26
|
+
|
27
|
+
self.lxc.destroy
|
28
|
+
end
|
29
|
+
|
30
|
+
# Start the container
|
31
|
+
def up
|
32
|
+
@ui.logger.debug { "Container Up: #{self.id} " }
|
33
|
+
|
34
|
+
self.lxc.start
|
35
|
+
end
|
36
|
+
|
37
|
+
# Stop the container
|
38
|
+
def down
|
39
|
+
@ui.logger.debug { "Container Down: #{self.id} " }
|
40
|
+
|
41
|
+
self.lxc.stop
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Container
|
3
|
+
|
4
|
+
module Generators
|
5
|
+
|
6
|
+
def generate_ip
|
7
|
+
octets = [ 192..192,
|
8
|
+
168..168,
|
9
|
+
0..254,
|
10
|
+
1..254 ]
|
11
|
+
ip = Array.new
|
12
|
+
for x in 1..4 do
|
13
|
+
ip << octets[x-1].to_a[rand(octets[x-1].count)].to_s
|
14
|
+
end
|
15
|
+
ip.join(".")
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_mac
|
19
|
+
digits = [ %w(0),
|
20
|
+
%w(0),
|
21
|
+
%w(0),
|
22
|
+
%w(0),
|
23
|
+
%w(5),
|
24
|
+
%w(e),
|
25
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
26
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
27
|
+
%w(5 6 7 8 9 a b c d e f),
|
28
|
+
%w(3 4 5 6 7 8 9 a b c d e f),
|
29
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
30
|
+
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f) ]
|
31
|
+
mac = ""
|
32
|
+
for x in 1..12 do
|
33
|
+
mac += digits[x-1][rand(digits[x-1].count)]
|
34
|
+
mac += ":" if (x.modulo(2) == 0) && (x != 12)
|
35
|
+
end
|
36
|
+
mac
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Container
|
3
|
+
|
4
|
+
module Lifecycle
|
5
|
+
|
6
|
+
# Container Setup
|
7
|
+
def setup
|
8
|
+
@ui.logger.debug { "Container Setup: #{self.id} " }
|
9
|
+
|
10
|
+
self.create
|
11
|
+
self.up
|
12
|
+
end
|
13
|
+
|
14
|
+
# Container Teardown
|
15
|
+
def teardown
|
16
|
+
@ui.logger.debug { "Container Teardown: #{self.id} " }
|
17
|
+
|
18
|
+
self.down
|
19
|
+
self.destroy
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Container
|
3
|
+
|
4
|
+
module LXC
|
5
|
+
|
6
|
+
# Our LXC Container class
|
7
|
+
#
|
8
|
+
# @return [LXC] An instance of LXC::Container configured for this
|
9
|
+
# container.
|
10
|
+
def lxc
|
11
|
+
@lxc ||= self.node.lxc.container(self.id)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns arguments for lxc-create based on our distro
|
15
|
+
#
|
16
|
+
# @return [Array] An array of arguments for lxc-create
|
17
|
+
def create_args
|
18
|
+
case self.distro.downcase
|
19
|
+
when "ubuntu" then
|
20
|
+
%W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release} --arch #{self.arch})
|
21
|
+
when "fedora" then
|
22
|
+
%W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Attempt to detect the architecture of the node. The value returned is
|
27
|
+
# respective to the container distro.
|
28
|
+
#
|
29
|
+
# @return [String] The arch of the node in the context of the container
|
30
|
+
# distro
|
31
|
+
def detect_arch
|
32
|
+
case self.distro.downcase
|
33
|
+
when "ubuntu" then
|
34
|
+
((self.node.arch =~ /x86_64/) ? "amd64" : "i386")
|
35
|
+
when "fedora" then
|
36
|
+
((self.node.arch =~ /x86_64/) ? "amd64" : "i686")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Container
|
3
|
+
|
4
|
+
module Network
|
5
|
+
|
6
|
+
# Builds an array of hashes containing the lxc configuration options for
|
7
|
+
# our networks
|
8
|
+
def build_lxc_network_conf(interfaces)
|
9
|
+
networks = Array.new
|
10
|
+
|
11
|
+
interfaces.each do |network, network_config|
|
12
|
+
networks << Hash[
|
13
|
+
'lxc.network.type' => :veth,
|
14
|
+
'lxc.network.flags' => :up,
|
15
|
+
'lxc.network.link' => TestLab::Network.first(network).bridge,
|
16
|
+
'lxc.network.name' => network_config[:name],
|
17
|
+
'lxc.network.hwaddr' => network_config[:mac],
|
18
|
+
'lxc.network.ipv4' => network_config[:ip]
|
19
|
+
]
|
20
|
+
if (network_config[:primary] == true) || (interfaces.count == 1)
|
21
|
+
networks.last.merge!('lxc.network.ipv4.gateway' => :auto)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
networks
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Container
|
3
|
+
|
4
|
+
module Status
|
5
|
+
|
6
|
+
def status
|
7
|
+
interfaces = self.interfaces.collect{ |network, network_config| "#{network}:#{network_config[:name]}:#{network_config[:ip]}" }.join(', ')
|
8
|
+
|
9
|
+
{
|
10
|
+
:id => self.id,
|
11
|
+
:state => self.state,
|
12
|
+
:distro => self.distro,
|
13
|
+
:release => self.release,
|
14
|
+
:interfaces => interfaces,
|
15
|
+
:provisioner => self.provisioner,
|
16
|
+
:node_id => self.node.id
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# State of the container
|
21
|
+
def state
|
22
|
+
self.lxc.state
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/testlab/container.rb
CHANGED
@@ -14,6 +14,11 @@ class TestLab
|
|
14
14
|
attribute :provisioner
|
15
15
|
attribute :config
|
16
16
|
|
17
|
+
attribute :domain
|
18
|
+
|
19
|
+
attribute :user
|
20
|
+
attribute :keys
|
21
|
+
|
17
22
|
attribute :interfaces
|
18
23
|
|
19
24
|
attribute :distro
|
@@ -22,125 +27,85 @@ class TestLab
|
|
22
27
|
|
23
28
|
attribute :persist
|
24
29
|
|
25
|
-
def initialize(*args)
|
26
|
-
super(*args)
|
27
|
-
|
28
|
-
@ui = TestLab.ui
|
29
|
-
@provisioner = self.provisioner.new(self.config) if !self.provisioner.nil?
|
30
|
-
end
|
31
|
-
|
32
|
-
def status
|
33
|
-
interfaces = self.interfaces.collect{ |key, value| "#{key}:#{value[:name]}:#{value[:ip]}" }.join(', ')
|
34
|
-
|
35
|
-
{
|
36
|
-
:id => self.id,
|
37
|
-
:state => self.state,
|
38
|
-
:distro => self.distro,
|
39
|
-
:release => self.release,
|
40
|
-
:interfaces => interfaces,
|
41
|
-
:provisioner => self.provisioner,
|
42
|
-
:node_id => self.node.id
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
|
-
# Our LXC Container class
|
47
|
-
def lxc
|
48
|
-
@lxc ||= self.node.lxc.container(self.id)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Create the container
|
52
|
-
def create
|
53
|
-
@ui.logger.debug { "Container Create: #{self.id} " }
|
54
|
-
|
55
|
-
self.arch ||= detect_arch
|
56
30
|
|
57
|
-
|
31
|
+
autoload :Actions, 'testlab/container/actions'
|
32
|
+
autoload :Generators, 'testlab/container/generators'
|
33
|
+
autoload :Lifecycle, 'testlab/container/lifecycle'
|
34
|
+
autoload :LXC, 'testlab/container/lxc'
|
35
|
+
autoload :Network, 'testlab/container/network'
|
36
|
+
autoload :Status, 'testlab/container/status'
|
58
37
|
|
59
|
-
|
38
|
+
include TestLab::Container::Actions
|
39
|
+
include TestLab::Container::Generators
|
40
|
+
include TestLab::Container::Lifecycle
|
41
|
+
include TestLab::Container::LXC
|
42
|
+
include TestLab::Container::Network
|
43
|
+
include TestLab::Container::Status
|
60
44
|
|
61
|
-
self.interfaces.each do |network, network_config|
|
62
|
-
n = Hash.new
|
63
|
-
n['lxc.network.type'] = :veth
|
64
|
-
n['lxc.network.flags'] = :up
|
65
|
-
n['lxc.network.link'] = TestLab::Network.first(network).bridge
|
66
|
-
n['lxc.network.name'] = (network_config[:name] || "eth0")
|
67
|
-
n['lxc.network.hwaddr'] = (network_config[:mac] || generate_mac)
|
68
|
-
n['lxc.network.ipv4'] = (network_config[:ip] || generate_ip)
|
69
|
-
self.lxc.config.networks << n
|
70
|
-
end
|
71
45
|
|
72
|
-
|
46
|
+
def initialize(*args)
|
47
|
+
super(*args)
|
73
48
|
|
74
|
-
|
49
|
+
@ui = TestLab.ui
|
50
|
+
@provisioner = self.provisioner.new(self.config) if !self.provisioner.nil?
|
75
51
|
end
|
76
52
|
|
77
|
-
|
78
|
-
def destroy
|
79
|
-
@ui.logger.debug { "Container Destroy: #{self.id} " }
|
80
|
-
|
81
|
-
self.lxc.destroy
|
82
|
-
end
|
53
|
+
################################################################################
|
83
54
|
|
84
|
-
#
|
85
|
-
def
|
86
|
-
@ui.logger.debug { "Container
|
55
|
+
# Does the container exist?
|
56
|
+
def exists?
|
57
|
+
@ui.logger.debug { "Container Exists?: #{self.id} " }
|
87
58
|
|
88
|
-
self.lxc.
|
59
|
+
self.lxc.exists?
|
89
60
|
end
|
90
61
|
|
91
|
-
|
92
|
-
def down
|
93
|
-
@ui.logger.debug { "Container Down: #{self.id} " }
|
62
|
+
################################################################################
|
94
63
|
|
95
|
-
|
64
|
+
# SSH to the container
|
65
|
+
def ssh(options={})
|
66
|
+
self.node.container_ssh(self, options)
|
96
67
|
end
|
97
68
|
|
98
|
-
|
99
|
-
|
100
|
-
@ui.logger.debug { "Container Reload: #{self.id} " }
|
101
|
-
|
102
|
-
self.down
|
103
|
-
self.up
|
69
|
+
def ip
|
70
|
+
self.primary_interface.last[:ip].split('/').first
|
104
71
|
end
|
105
72
|
|
106
|
-
#
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
self.lxc.exists?
|
73
|
+
# Returns the CIDR of the container
|
74
|
+
def cidr
|
75
|
+
self.primary_interface.last[:ip].split('/').last.to_i
|
111
76
|
end
|
112
77
|
|
113
|
-
|
114
|
-
|
115
|
-
self.lxc.state
|
116
|
-
end
|
78
|
+
def ptr
|
79
|
+
octets = self.ip.split('.')
|
117
80
|
|
118
|
-
|
81
|
+
result = case self.cidr
|
82
|
+
when 0..7 then
|
83
|
+
octets[-4,4]
|
84
|
+
when 8..15 then
|
85
|
+
octets[-3,3]
|
86
|
+
when 16..23 then
|
87
|
+
octets[-2,2]
|
88
|
+
when 24..31 then
|
89
|
+
octets[-1,1]
|
90
|
+
end
|
119
91
|
|
120
|
-
|
121
|
-
def after_create
|
122
|
-
@ui.logger.debug { "Container Callback: After Create: #{self.id} " }
|
92
|
+
result.reverse.join('.')
|
123
93
|
end
|
124
94
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
95
|
+
def primary_interface
|
96
|
+
if self.interfaces.any?{ |i,c| c[:primary] == true }
|
97
|
+
self.interfaces.find{ |i,c| c[:primary] == true }
|
98
|
+
else
|
99
|
+
self.interfaces.first
|
100
|
+
end
|
131
101
|
end
|
132
102
|
|
133
|
-
|
134
|
-
def before_down
|
135
|
-
@ui.logger.debug { "Container Callback: Before Down: #{self.id} " }
|
103
|
+
class << self
|
136
104
|
|
137
|
-
|
138
|
-
|
139
|
-
|
105
|
+
def domains
|
106
|
+
self.all.map(&:domain).compact
|
107
|
+
end
|
140
108
|
|
141
|
-
# Container Callback: before_destroy
|
142
|
-
def before_destroy
|
143
|
-
@ui.logger.debug { "Container Callback: Before Destroy: #{self.id} " }
|
144
109
|
end
|
145
110
|
|
146
111
|
################################################################################
|
@@ -156,63 +121,6 @@ class TestLab
|
|
156
121
|
end
|
157
122
|
end
|
158
123
|
|
159
|
-
################################################################################
|
160
|
-
private
|
161
|
-
################################################################################
|
162
|
-
|
163
|
-
# Returns arguments for lxc-create based on our distro
|
164
|
-
def create_args
|
165
|
-
case self.distro.downcase
|
166
|
-
when "ubuntu" then
|
167
|
-
%W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release} --arch #{arch})
|
168
|
-
when "fedora" then
|
169
|
-
%W(-f /etc/lxc/#{self.id} -t #{self.distro} -- --release #{self.release})
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
# Attempt to detect the architecture of the node our container is running on
|
174
|
-
def detect_arch
|
175
|
-
case self.distro.downcase
|
176
|
-
when "ubuntu" then
|
177
|
-
((self.node.arch =~ /x86_64/) ? "amd64" : "i386")
|
178
|
-
when "fedora" then
|
179
|
-
((self.node.arch =~ /x86_64/) ? "amd64" : "i686")
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def generate_ip
|
184
|
-
octets = [ 192..192,
|
185
|
-
168..168,
|
186
|
-
0..254,
|
187
|
-
1..254 ]
|
188
|
-
ip = Array.new
|
189
|
-
for x in 1..4 do
|
190
|
-
ip << octets[x-1].to_a[rand(octets[x-1].count)].to_s
|
191
|
-
end
|
192
|
-
ip.join(".")
|
193
|
-
end
|
194
|
-
|
195
|
-
def generate_mac
|
196
|
-
digits = [ %w(0),
|
197
|
-
%w(0),
|
198
|
-
%w(0),
|
199
|
-
%w(0),
|
200
|
-
%w(5),
|
201
|
-
%w(e),
|
202
|
-
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
203
|
-
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
204
|
-
%w(5 6 7 8 9 a b c d e f),
|
205
|
-
%w(3 4 5 6 7 8 9 a b c d e f),
|
206
|
-
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f),
|
207
|
-
%w(0 1 2 3 4 5 6 7 8 9 a b c d e f) ]
|
208
|
-
mac = ""
|
209
|
-
for x in 1..12 do
|
210
|
-
mac += digits[x-1][rand(digits[x-1].count)]
|
211
|
-
mac += ":" if (x.modulo(2) == 0) && (x != 12)
|
212
|
-
end
|
213
|
-
mac
|
214
|
-
end
|
215
|
-
|
216
124
|
end
|
217
125
|
|
218
126
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Network
|
3
|
+
|
4
|
+
module Actions
|
5
|
+
|
6
|
+
# Create the network
|
7
|
+
def create
|
8
|
+
@ui.logger.debug { "Network Create: #{self.id} " }
|
9
|
+
|
10
|
+
self.node.ssh.exec(%(sudo brctl addbr #{self.bridge}), :silence => true, :ignore_exit_status => true)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Destroy the network
|
14
|
+
def destroy
|
15
|
+
@ui.logger.debug { "Network Destroy: #{self.id} " }
|
16
|
+
|
17
|
+
self.node.ssh.exec(%(sudo brctl delbr #{self.bridge}), :silence => true, :ignore_exit_status => true)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Start the network
|
21
|
+
def up
|
22
|
+
@ui.logger.debug { "Network Up: #{self.id} " }
|
23
|
+
|
24
|
+
self.node.ssh.exec(%(sudo ifconfig #{self.bridge} #{self.ip} up), :silence => true, :ignore_exit_status => true)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Stop the network
|
28
|
+
def down
|
29
|
+
@ui.logger.debug { "Network Down: #{self.id} " }
|
30
|
+
|
31
|
+
self.node.ssh.exec(%(sudo ifconfig #{self.bridge} down), :silence => true, :ignore_exit_status => true)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Network
|
3
|
+
|
4
|
+
module CIDR
|
5
|
+
|
6
|
+
CIDR_MATRIX = {
|
7
|
+
32 => { :netmask => '255.255.255.255', :broadcast => '%s.%s.%s.%s', :network => '%s.%s.%s.%s' },
|
8
|
+
31 => { :netmask => '255.255.255.254', :broadcast => '%s.%s.%s.1', :network => '%s.%s.%s.254' },
|
9
|
+
30 => { :netmask => '255.255.255.252', :broadcast => '%s.%s.%s.3', :network => '%s.%s.%s.252' },
|
10
|
+
29 => { :netmask => '255.255.255.248', :broadcast => '%s.%s.%s.7', :network => '%s.%s.%s.248' },
|
11
|
+
28 => { :netmask => '255.255.255.240', :broadcast => '%s.%s.%s.15', :network => '%s.%s.%s.240' },
|
12
|
+
27 => { :netmask => '255.255.255.224', :broadcast => '%s.%s.%s.31', :network => '%s.%s.%s.224' },
|
13
|
+
26 => { :netmask => '255.255.255.192', :broadcast => '%s.%s.%s.63', :network => '%s.%s.%s.192' },
|
14
|
+
25 => { :netmask => '255.255.255.128', :broadcast => '%s.%s.%s.127', :network => '%s.%s.%s.128' },
|
15
|
+
24 => { :netmask => '255.255.255.0', :broadcast => '%s.%s.%s.255', :network => '%s.%s.%s.0' },
|
16
|
+
23 => { :netmask => '255.255.254.0', :broadcast => '%s.%s.1.255', :network => '%s.%s.254.0' },
|
17
|
+
22 => { :netmask => '255.255.252.0', :broadcast => '%s.%s.3.255', :network => '%s.%s.252.0' },
|
18
|
+
21 => { :netmask => '255.255.248.0', :broadcast => '%s.%s.7.255', :network => '%s.%s.248.0' },
|
19
|
+
20 => { :netmask => '255.255.240.0', :broadcast => '%s.%s.15.255', :network => '%s.%s.240.0' },
|
20
|
+
19 => { :netmask => '255.255.224.0', :broadcast => '%s.%s.31.255', :network => '%s.%s.224.0' },
|
21
|
+
18 => { :netmask => '255.255.192.0', :broadcast => '%s.%s.63.255', :network => '%s.%s.192.0' },
|
22
|
+
17 => { :netmask => '255.255.128.0', :broadcast => '%s.%s.127.255', :network => '%s.%s.128.0' },
|
23
|
+
16 => { :netmask => '255.255.0.0', :broadcast => '%s.%s.255.255', :network => '%s.%s.0.0' },
|
24
|
+
15 => { :netmask => '255.254.0.0', :broadcast => '%s.1.255.255', :network => '%s.254.0.0' },
|
25
|
+
14 => { :netmask => '255.252.0.0', :broadcast => '%s.3.255.255', :network => '%s.252.0.0' },
|
26
|
+
13 => { :netmask => '255.248.0.0', :broadcast => '%s.7.255.255', :network => '%s.248.0.0' },
|
27
|
+
12 => { :netmask => '255.240.0.0', :broadcast => '%s.15.255.255', :network => '%s.240.0.0' },
|
28
|
+
11 => { :netmask => '255.224.0.0', :broadcast => '%s.31.255.255', :network => '%s.224.0.0' },
|
29
|
+
10 => { :netmask => '255.192.0.0', :broadcast => '%s.63.255.255', :network => '%s.192.0.0' },
|
30
|
+
9 => { :netmask => '255.128.0.0', :broadcast => '%s.127.255.255', :network => '%s.128.0.0' },
|
31
|
+
8 => { :netmask => '255.0.0.0', :broadcast => '%s.255.255.255', :network => '%s.0.0.0' },
|
32
|
+
7 => { :netmask => '254.0.0.0', :broadcast => '1.255.255.255', :network => '254.0.0.0' },
|
33
|
+
6 => { :netmask => '252.0.0.0', :broadcast => '3.255.255.255', :network => '252.0.0.0' },
|
34
|
+
5 => { :netmask => '248.0.0.0', :broadcast => '7.255.255.255', :network => '248.0.0.0' },
|
35
|
+
4 => { :netmask => '240.0.0.0', :broadcast => '15.255.255.255', :network => '240.0.0.0' },
|
36
|
+
3 => { :netmask => '224.0.0.0', :broadcast => '31.255.255.255', :network => '224.0.0.0' },
|
37
|
+
2 => { :netmask => '192.0.0.0', :broadcast => '63.255.255.255', :network => '192.0.0.0' },
|
38
|
+
1 => { :netmask => '128.0.0.0', :broadcast => '127.255.255.255', :network => '128.0.0.0' },
|
39
|
+
0 => { :netmask => '0.0.0.0', :broadcast => '255.255.255.255', :network => '0.0.0.0' }
|
40
|
+
}
|
41
|
+
|
42
|
+
# Returns the CIDR of the network
|
43
|
+
def cidr
|
44
|
+
self.ip.split('/').last.to_i
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the IP with the CIDR notation stripped away
|
48
|
+
def clean_ip
|
49
|
+
self.ip.split('/').first
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the entry from the CIDR_MATRIX constant based on our CIDR
|
53
|
+
def cidr_matrix
|
54
|
+
CIDR_MATRIX[self.cidr]
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the network mask
|
58
|
+
def netmask
|
59
|
+
cidr_matrix[:netmask]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the network address
|
63
|
+
def network
|
64
|
+
cidr_matrix[:network] % clean_ip.split('.')
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the broadcast address
|
68
|
+
def broadcast
|
69
|
+
cidr_matrix[:broadcast] % clean_ip.split('.')
|
70
|
+
end
|
71
|
+
|
72
|
+
def cidr_octets(fill=nil)
|
73
|
+
octets = self.clean_ip.split('.')
|
74
|
+
|
75
|
+
result = case self.cidr
|
76
|
+
when 0..7 then
|
77
|
+
octets[-4,4]
|
78
|
+
when 8..15 then
|
79
|
+
[octets[-3,3], fill]
|
80
|
+
when 16..23 then
|
81
|
+
[octets[-2,2], fill, fill]
|
82
|
+
when 24..31 then
|
83
|
+
[octets[-1,1], fill, fill, fill]
|
84
|
+
end
|
85
|
+
|
86
|
+
result.flatten.compact
|
87
|
+
end
|
88
|
+
|
89
|
+
def ptr
|
90
|
+
cidr_octets.reverse.join('.')
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the ARPA address
|
94
|
+
def arpa
|
95
|
+
result = self.network.split('.').delete_if{ |ip| ip == '0' }.reverse.join('.')
|
96
|
+
"#{result}.in-addr.arpa"
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class TestLab
|
2
|
+
class Network
|
3
|
+
|
4
|
+
module Lifecycle
|
5
|
+
|
6
|
+
# Network Setup
|
7
|
+
def setup
|
8
|
+
@ui.logger.debug { "Network Setup: #{self.id} " }
|
9
|
+
|
10
|
+
self.create
|
11
|
+
self.up
|
12
|
+
end
|
13
|
+
|
14
|
+
# Network Teardown
|
15
|
+
def teardown
|
16
|
+
@ui.logger.debug { "Network Teardown: #{self.id} " }
|
17
|
+
|
18
|
+
self.down
|
19
|
+
self.destroy
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|