dewiring 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/wire-network-container.sh +74 -28
- data/lib/wire/commands/base_command.rb +32 -4
- data/lib/wire/commands/down_command.rb +1 -0
- data/lib/wire/commands/down_command_handler.rb +25 -85
- data/lib/wire/commands/spec_command.rb +24 -7
- data/lib/wire/commands/spec_templates.rb +82 -39
- data/lib/wire/commands/up_command.rb +1 -1
- data/lib/wire/commands/up_command_handler.rb +30 -80
- data/lib/wire/commands/verify_command_handler.rb +30 -48
- data/lib/wire/execution/local_exec.rb +1 -1
- data/lib/wire/model/network_validation.rb +32 -17
- data/lib/wire/model/project.rb +12 -0
- data/lib/wire/model/state.rb +2 -1
- data/lib/wire/resource/bridge.rb +2 -0
- data/lib/wire/resource/network_injection.rb +31 -20
- data/lib/wire/resource/resource.rb +2 -2
- data/lib/wire/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWI3MDA5Yzc1ZGNhY2JlNzJiYjQyMTJjMmQwNTJiNWU5Njc0NzhmNw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NDIxM2Y4Mzc2NDM4NzYwMzQ4MzJmYzFiMzYzOTBlMjJjMDY1NWEyNw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDY5OGNmMzIxNjJmZTUwM2I5NTZhZjVkNzM2NjZmNzg5YTAyMTk4OTJkMjZk
|
10
|
+
M2FhYzNmODI4YWM5ZjE4NzU4MDk0OGY5MjI5N2MwMmZkNWU0ZWNhNWU3OTM5
|
11
|
+
ZThmNDQ3ZDYzMDhlMWI4N2MwY2YzZjFiNzI4Mzc2ZTRiNTllNmM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZGYxNDY4Yzg1MTM3NDZhZjIyMzJhMThmOTUxMWE4Zjc0YzMzYTQyY2NkNWI4
|
14
|
+
ZGFhMWQ4YzNkN2E4ZDdiYjIxZmNhYmQyZDg2NTk5MmExMjEwOTU3YzVjM2Vh
|
15
|
+
NjE1ZTUwMTA3MTliYzlkZjdjNTYwNjg2OTU1YjdkYWQxMGMzZjc=
|
@@ -23,9 +23,9 @@ function usage() {
|
|
23
23
|
echo ' -n/--noop only print commands, do not change'
|
24
24
|
echo ' -d/--debug show debug output'
|
25
25
|
echo ' -q/--quiet be quiet'
|
26
|
-
|
26
|
+
echo ' -s/--state <FILE> write state to <FILE>'
|
27
27
|
echo ' Examples:'
|
28
|
-
echo ' attach-containers.sh attach --debug -- eth1:br1 eth2:br2 02978729 12673482'
|
28
|
+
echo ' attach-containers.sh attach --debug -- eth1:br1:NODHCP eth2:br2 02978729 12673482'
|
29
29
|
echo ' attach-containers.sh verify -- eth1:br1 eth2:br2 02978729 12673482'
|
30
30
|
echo ' attach-containers.sh detach -q -- eth1:br1 eth2:br2 02978729 12673482'
|
31
31
|
}
|
@@ -64,6 +64,7 @@ MODE=
|
|
64
64
|
ACTION=
|
65
65
|
DEBUG=nodebug
|
66
66
|
QUIET=
|
67
|
+
STATEFILE=
|
67
68
|
|
68
69
|
while :
|
69
70
|
do
|
@@ -80,6 +81,11 @@ do
|
|
80
81
|
NOOP=1
|
81
82
|
shift
|
82
83
|
;;
|
84
|
+
-s | --state)
|
85
|
+
shift
|
86
|
+
STATEFILE=$1
|
87
|
+
shift
|
88
|
+
;;
|
83
89
|
-d | --debug)
|
84
90
|
DEBUG=debug
|
85
91
|
shift
|
@@ -124,6 +130,12 @@ if [[ -z "$ID_ARR" ]]; then
|
|
124
130
|
exit 3
|
125
131
|
fi
|
126
132
|
|
133
|
+
# empty state file
|
134
|
+
if [[ ! -z "$STATEFILE" ]]; then
|
135
|
+
echo "# This is a wire network state file" >"$STATEFILE"
|
136
|
+
echo "TIMESTAMP=`date`" >>"$STATEFILE"
|
137
|
+
fi
|
138
|
+
|
127
139
|
[[ "$NOOP" -eq 1 ]] && MODE='echo NOOP% '
|
128
140
|
|
129
141
|
# DEBUG
|
@@ -136,12 +148,25 @@ OVS_VSCTL=$(which ovs-vsctl)
|
|
136
148
|
DOCKER=$(which docker)
|
137
149
|
DHCLIENT=$(which dhclient)
|
138
150
|
|
151
|
+
# -- FUNCTION ----------------------------------------------------------------
|
152
|
+
# Name: add_to_state
|
153
|
+
# Description: Adds given text line to state file. If STATEFILE is empty,
|
154
|
+
# nothing is done
|
155
|
+
# Parameters
|
156
|
+
# 1: state info line
|
157
|
+
# ----------------------------------------------------------------------------
|
158
|
+
function add_to_state() {
|
159
|
+
if [[ ! -z "$STATEFILE" ]]; then
|
160
|
+
echo $* >>"$STATEFILE"
|
161
|
+
fi
|
162
|
+
}
|
163
|
+
|
139
164
|
# -- FUNCTION ----------------------------------------------------------------
|
140
165
|
# Name: container_process
|
141
166
|
# Description: Given ID of container, this returns the Process id
|
142
167
|
# Parameters
|
143
168
|
# 1: Docker Container ID
|
144
|
-
# Returns : Container Process ID
|
169
|
+
# Returns : Container Process ID
|
145
170
|
# ----------------------------------------------------------------------------
|
146
171
|
function container_process() {
|
147
172
|
T="$1"
|
@@ -170,7 +195,11 @@ function link_netns() {
|
|
170
195
|
# ----------------------------------------------------------------------------
|
171
196
|
function unlink_netns() {
|
172
197
|
local PID=$1
|
173
|
-
|
198
|
+
if [[ -z $PID ]]; then
|
199
|
+
log_error unlink_netns: pid not specified
|
200
|
+
else
|
201
|
+
$MODE sudo rm "/var/run/netns/$PID"
|
202
|
+
fi
|
174
203
|
}
|
175
204
|
|
176
205
|
# -- FUNCTION ----------------------------------------------------------------
|
@@ -292,11 +321,11 @@ function has_interfaces() {
|
|
292
321
|
if [[ $? -ne 0 ]]; then
|
293
322
|
return 1
|
294
323
|
fi
|
295
|
-
# check if we have an ip
|
296
|
-
|
297
|
-
if [[ $? -ne 0 ]]; then
|
298
|
-
|
299
|
-
fi
|
324
|
+
# check if we have an ip (todo: fix in NODHCP mode)
|
325
|
+
#$MODE sudo $IP netns exec $NS $IP addr show $DEVICE 2>&1 | grep 'inet ' >/dev/null 2>&1
|
326
|
+
#if [[ $? -ne 0 ]]; then
|
327
|
+
# return 1
|
328
|
+
#fi
|
300
329
|
|
301
330
|
# host devices
|
302
331
|
$MODE sudo $IP link show $HOST_IF >/dev/null 2>&1
|
@@ -376,8 +405,9 @@ function handle_verify() {
|
|
376
405
|
# on host and in container
|
377
406
|
|
378
407
|
$DEBUG - Checking devices in $ID
|
379
|
-
|
380
|
-
|
408
|
+
link_netns "${PID}"
|
409
|
+
add_to_state ${ID}.CONTAINER_PID=${TARGET_PID}
|
410
|
+
|
381
411
|
# iterate given devices
|
382
412
|
for DEVICE_PAIR in $DEVICE_ARR; do
|
383
413
|
INTF=$(echo "$DEVICE_PAIR" | awk -F':' '{ print $1 }' )
|
@@ -419,11 +449,13 @@ function handle_attach() {
|
|
419
449
|
$DEBUG PID of $TARGET is $TARGET_PID
|
420
450
|
|
421
451
|
link_netns "${TARGET_PID}"
|
422
|
-
|
452
|
+
add_to_state ${TARGET}.CONTAINER_PID=${TARGET_PID}
|
453
|
+
|
423
454
|
# iterate given devices
|
424
455
|
for DEVICE_PAIR in $DEVICE_ARR; do
|
425
456
|
INTF=$(echo $DEVICE_PAIR | awk -F':' '{ print $1 }' )
|
426
457
|
BRIDGE=$(echo $DEVICE_PAIR | awk -F':' '{ print $2 }' )
|
458
|
+
FLAGS=$(echo $DEVICE_PAIR | awk -F':' '{ print $3 }' )
|
427
459
|
$DEBUG Attaching $INTF to $BRIDGE
|
428
460
|
|
429
461
|
BRIDGEDEV_MTU=$(get_mtu $BRIDGE)
|
@@ -432,6 +464,7 @@ function handle_attach() {
|
|
432
464
|
RES=1
|
433
465
|
break
|
434
466
|
fi
|
467
|
+
add_to_state ${TARGET}.BRIDGEDEV_MTU=${BRIDGEDEV_MTU}
|
435
468
|
|
436
469
|
HOST_IFNAME=v${INTF}h${TARGET_PID}
|
437
470
|
CONTAINER_IFNAME=v${INTF}c${TARGET_PID}
|
@@ -444,7 +477,10 @@ function handle_attach() {
|
|
444
477
|
RES=1
|
445
478
|
continue
|
446
479
|
fi
|
447
|
-
|
480
|
+
|
481
|
+
add_to_state ${TARGET}.HOST_IFNAME=${HOST_IFNAME}
|
482
|
+
add_to_state ${TARGET}.CONTAINER_IFNAME=${CONTAINER_IFNAME}
|
483
|
+
|
448
484
|
$DEBUG - adding $HOST_IFNAME to $BRIDGE
|
449
485
|
add_device_to_switch "$HOST_IFNAME" "$BRIDGE"
|
450
486
|
if [[ $? -ne 0 ]]; then
|
@@ -452,25 +488,35 @@ function handle_attach() {
|
|
452
488
|
RES=1
|
453
489
|
continue
|
454
490
|
fi
|
455
|
-
|
491
|
+
add_to_state ${TARGET}.ON_BRIDGE=$BRIDGE
|
492
|
+
|
456
493
|
$DEBUG - configuring interfaces
|
457
494
|
configure_interfaces "$HOST_IFNAME" "$CONTAINER_IFNAME" "$TARGET_PID" "$INTF"
|
458
495
|
if [[ $? -ne 0 ]]; then
|
459
496
|
log_error configuring interfaces. aborting
|
460
497
|
RES=1
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
$DEBUG - dhcp requesting address
|
465
|
-
dhcp_container "$TARGET_PID" "$INTF"
|
466
|
-
if [[ $? -ne 0 ]]; then
|
467
|
-
log_error running dhcp. aborting
|
468
|
-
RES=1
|
469
|
-
continue
|
498
|
+
add_to_state ${CONTAINER_IFNAME}.configured=error
|
499
|
+
continue
|
470
500
|
fi
|
471
|
-
|
501
|
+
add_to_state ${TARGET}.${CONTAINER_IFNAME}.configured=ok
|
472
502
|
|
473
|
-
|
503
|
+
if [[ "$FLAGS" =~ NODHCP ]]; then
|
504
|
+
$DEBUG - skipping dhcp for $INTF
|
505
|
+
else
|
506
|
+
$DEBUG - dhcp requesting address
|
507
|
+
dhcp_container "$TARGET_PID" "$INTF"
|
508
|
+
if [[ $? -ne 0 ]]; then
|
509
|
+
log_error running dhcp. aborting
|
510
|
+
add_to_state ${CONTAINER_IFNAME}.dhcp=error
|
511
|
+
RES=1
|
512
|
+
continue
|
513
|
+
fi
|
514
|
+
add_to_state ${TARGET}.${CONTAINER_IFNAME}.dhcp=ok
|
515
|
+
|
516
|
+
fi
|
517
|
+
|
518
|
+
done
|
519
|
+
unlink_netns "$TARGET_PID"
|
474
520
|
done
|
475
521
|
|
476
522
|
return $RES
|
@@ -490,10 +536,10 @@ function handle_detach() {
|
|
490
536
|
$DEBUG Detaching $TARGET
|
491
537
|
|
492
538
|
TARGET_PID=$(container_process $TARGET)
|
493
|
-
|
494
|
-
|
495
|
-
link_netns ${TARGET_PID}
|
539
|
+
$DEBUG PID of $TARGET is $TARGET_PID
|
496
540
|
|
541
|
+
link_netns ${TARGET_PID}
|
542
|
+
|
497
543
|
# iterate given devices
|
498
544
|
for DEVICE_PAIR in $DEVICE_ARR; do
|
499
545
|
INTF=$(echo $DEVICE_PAIR | awk -F':' '{ print $1 }' )
|
@@ -113,6 +113,37 @@ module Wire
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
# brings given +resource+ up by first asking if its up?.
|
117
|
+
# If not, call up. Writes states, outputs state
|
118
|
+
# Params:
|
119
|
+
# ++resource++: Resource object, i.e. BridgeResource
|
120
|
+
# ++resource_type++: Resource type symbol, i.e. :bridge
|
121
|
+
# ++resource_desc_str++: Description to dump out
|
122
|
+
# ++action++: one of :up, :down
|
123
|
+
def default_handle_resource(resource, resource_type, resource_desc_str, action)
|
124
|
+
question = "#{action}?".to_sym
|
125
|
+
output_method = action.to_s.upcase
|
126
|
+
|
127
|
+
b_ok = false
|
128
|
+
|
129
|
+
if resource.send(question)
|
130
|
+
outputs output_method, "#{resource_desc_str} is already #{action}.", :ok2
|
131
|
+
b_ok = true
|
132
|
+
else
|
133
|
+
resource.send(action)
|
134
|
+
|
135
|
+
if resource.send(question)
|
136
|
+
outputs output_method, "#{resource_desc_str} is #{action}.", :ok
|
137
|
+
b_ok = true
|
138
|
+
else
|
139
|
+
outputs output_method, "#{resource_desc_str} could not be brought #{action}.", :err
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
state.update(resource_type, resource.name, action) if b_ok
|
144
|
+
b_ok
|
145
|
+
end
|
146
|
+
|
116
147
|
private
|
117
148
|
|
118
149
|
# Save state to state file
|
@@ -122,18 +153,15 @@ module Wire
|
|
122
153
|
state.save
|
123
154
|
rescue => save_exception
|
124
155
|
$stderr.puts "Error saving state, #{save_exception}"
|
125
|
-
$log.debug? && puts(save_exception.inspect)
|
126
|
-
$log.debug? && puts(save_exception.backtrace)
|
127
156
|
end
|
128
157
|
|
158
|
+
# Load state from state file
|
129
159
|
def handle_state_load
|
130
160
|
state.load
|
131
161
|
# dump state
|
132
162
|
$log.debug? && dump_state
|
133
163
|
rescue => load_exception
|
134
164
|
$stderr.puts "Error loading state, #{load_exception}"
|
135
|
-
$log.debug? && puts(load_exception.inspect)
|
136
|
-
$log.debug? && puts(load_exception.backtrace)
|
137
165
|
end
|
138
166
|
end
|
139
167
|
end
|
@@ -7,32 +7,19 @@
|
|
7
7
|
# Wire module
|
8
8
|
module Wire
|
9
9
|
# implements handle_xxx methods for DownCommand
|
10
|
+
# delegates to BaseCommand.default_handle_resource for most parts
|
10
11
|
# rubocop:disable ClassLength
|
11
12
|
class DownCommandHandler < BaseCommand
|
12
13
|
# take bridge down
|
13
14
|
def handle_bridge(bridge_name)
|
14
15
|
bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
bridge_resource.down
|
21
|
-
if bridge_resource.down?
|
22
|
-
outputs 'DOWN', "Bridge #{bridge_name} down/removed.", :ok
|
23
|
-
state.update(:bridge, bridge_name, :down)
|
24
|
-
else
|
25
|
-
outputs 'DOWN', "Error bringing down bridge #{bridge_name}.", :err
|
26
|
-
b_result = false
|
27
|
-
end
|
28
|
-
|
29
|
-
b_result
|
16
|
+
default_handle_resource(bridge_resource, :bridge, "Bridge \'#{bridge_name}\'", :down)
|
17
|
+
rescue => e
|
18
|
+
$log.error "processing bridge: #{e}"
|
30
19
|
end
|
31
20
|
|
32
21
|
# remove ip from bridge interface
|
33
22
|
def handle_hostip(bridge_name, hostip)
|
34
|
-
b_result = true
|
35
|
-
|
36
23
|
bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
|
37
24
|
if bridge_resource.down?
|
38
25
|
outputs 'DOWN', "Bridge #{bridge_name} already down, will not care about ip", :ok2
|
@@ -42,22 +29,10 @@ module Wire
|
|
42
29
|
# we should have a bridge with that name.
|
43
30
|
hostip_resource = Wire::Resource::ResourceFactory
|
44
31
|
.instance.create(:bridgeip, hostip, bridge_name)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
hostip_resource.down
|
51
|
-
if hostip_resource.down?
|
52
|
-
outputs 'DOWN', "IP #{hostip} on bridge #{bridge_name} down/removed.", :ok
|
53
|
-
state.update(:hostip, hostip, :down)
|
54
|
-
else
|
55
|
-
outputs 'DOWN', "Error taking down ip #{hostip} on bridge #{bridge_name}.", :err
|
56
|
-
|
57
|
-
b_result = false
|
58
|
-
end
|
59
|
-
|
60
|
-
b_result
|
32
|
+
default_handle_resource(hostip_resource, :hostip,
|
33
|
+
"IP \'#{hostip}\' on bridge \'#{bridge_name}\'", :down)
|
34
|
+
rescue => e
|
35
|
+
$log.error "processing host ip: #{e}"
|
61
36
|
end
|
62
37
|
|
63
38
|
# unconfigures dnsmasq for dhcp
|
@@ -73,21 +48,10 @@ module Wire
|
|
73
48
|
resource_dhcp = Wire::Resource::ResourceFactory
|
74
49
|
.instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
|
75
50
|
network_entry, address_start, address_end)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
resource_dhcp.down
|
82
|
-
if resource_dhcp.down?
|
83
|
-
outputs 'DOWN', "dnsmasq/dhcp config on network \'#{network_name}\' is down.", :ok
|
84
|
-
state.update(:dnsmasq, network_name, :down)
|
85
|
-
return true
|
86
|
-
else
|
87
|
-
outputs 'DOWN', 'Error unconfiguring dnsmasq/dhcp ' \
|
88
|
-
"config on network \'#{network_name}\'.", :err
|
89
|
-
return false
|
90
|
-
end
|
51
|
+
default_handle_resource(resource_dhcp, :dnsmasq,
|
52
|
+
"dnsmasq/dhcp config on network \'#{network_name}\'", :down)
|
53
|
+
rescue => e
|
54
|
+
$log.error "processing dhcp configuration: #{e}"
|
91
55
|
end
|
92
56
|
|
93
57
|
# take the appgroups' controller and directs methods to
|
@@ -109,6 +73,8 @@ module Wire
|
|
109
73
|
$log.error "Appgroup not handled for zone #{zone_name}, " \
|
110
74
|
"unknown controller type #{controller_entry[:type]}"
|
111
75
|
false
|
76
|
+
rescue => e
|
77
|
+
$log.error "processing appgroup: #{e}"
|
112
78
|
end
|
113
79
|
|
114
80
|
# implement appgroup handling for fig controller
|
@@ -126,24 +92,10 @@ module Wire
|
|
126
92
|
resource_fig = Wire::Resource::ResourceFactory
|
127
93
|
.instance.create(:figadapter, "#{appgroup_name}", fig_path)
|
128
94
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
b_result = false
|
135
|
-
resource_fig.down
|
136
|
-
if resource_fig.down?
|
137
|
-
outputs 'DOWN', "appgroup \'#{appgroup_name}\' for zone #{zone_name} is down.", :ok
|
138
|
-
state.update(:appgroup, appgroup_name, :down)
|
139
|
-
b_result = true
|
140
|
-
else
|
141
|
-
outputs 'DOWN', "Error taking down appgroup \'#{appgroup_name}\' for zone #{zone_name}.",
|
142
|
-
:err
|
143
|
-
b_result = false
|
144
|
-
end
|
145
|
-
|
146
|
-
b_result
|
95
|
+
default_handle_resource(resource_fig, :appgroup,
|
96
|
+
"appgroup \'#{appgroup_name}\' for zone \'#{zone_name}\'", :down)
|
97
|
+
rescue => e
|
98
|
+
$log.error "processing appgroup/fig: #{e}"
|
147
99
|
end
|
148
100
|
|
149
101
|
# detaches networks to containers of appgroup
|
@@ -175,25 +127,13 @@ module Wire
|
|
175
127
|
|
176
128
|
#
|
177
129
|
resource_nw = Wire::Resource::ResourceFactory
|
178
|
-
.instance.create(:networkinjection, appgroup_name, networks
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
resource_nw.down
|
186
|
-
if resource_nw.down?
|
187
|
-
outputs 'DOWN', "appgroup \'#{appgroup_name}\' detached " \
|
188
|
-
"networks #{networks.keys.join(',')}.", :ok
|
189
|
-
state.update(:appgroup, appgroup_name, :down)
|
190
|
-
return true
|
191
|
-
else
|
192
|
-
outputs 'DOWN', "Error detaching networks to appgroup \'#{appgroup_name}\'.",
|
193
|
-
:err
|
194
|
-
return false
|
195
|
-
end
|
196
|
-
end
|
130
|
+
.instance.create(:networkinjection, appgroup_name, networks, container_ids)
|
131
|
+
|
132
|
+
default_handle_resource(resource_nw, :network_injection,
|
133
|
+
"Network(s) \'#{networks.keys.join(',')}\' in "\
|
134
|
+
"appgroup \'#{appgroup_name}\'", :down)
|
135
|
+
rescue => e
|
136
|
+
$log.error "processing network attachments: #{e}"
|
197
137
|
end
|
198
138
|
end
|
199
139
|
end
|
@@ -45,7 +45,7 @@ module Wire
|
|
45
45
|
outputs 'SPEC', 'To run automatically, use --run'
|
46
46
|
rescue => exception
|
47
47
|
$log.error "Error writing serverspec files, #{exception}"
|
48
|
-
STDERR.puts
|
48
|
+
STDERR.puts exception.inspect
|
49
49
|
end
|
50
50
|
|
51
51
|
run_serverspec(target_specdir) if @params[:auto_run]
|
@@ -102,14 +102,31 @@ module Wire
|
|
102
102
|
def run_on_network_in_zone(zone_name, bridge_name, network_data)
|
103
103
|
$log.debug("Creating specs for network #{bridge_name}")
|
104
104
|
|
105
|
-
template =
|
105
|
+
template = SpecTemplatesNetwork.build_template__bridge_exists
|
106
106
|
erb = ERB.new(template, nil, '%')
|
107
107
|
@spec_code << erb.result(binding)
|
108
108
|
|
109
|
+
vlan = network_data[:vlan]
|
110
|
+
if vlan
|
111
|
+
vlanid = vlan[:id]
|
112
|
+
on_trunk = vlan[:on_trunk]
|
113
|
+
template = SpecTemplatesNetwork.build_template__bridge_vlan_id_and_trunk
|
114
|
+
erb = ERB.new(template, nil, '%')
|
115
|
+
@spec_code << erb.result(binding)
|
116
|
+
end
|
117
|
+
|
109
118
|
# render template for hostip (if any)
|
110
119
|
ip = network_data[:hostip]
|
111
120
|
if ip
|
112
|
-
template =
|
121
|
+
template = SpecTemplatesNetwork.build_template__ip_is_up
|
122
|
+
erb = ERB.new(template, nil, '%')
|
123
|
+
@spec_code << erb.result(binding)
|
124
|
+
end
|
125
|
+
|
126
|
+
# render template for network/port attachments (if any)
|
127
|
+
attach_intf = network_data[:attach]
|
128
|
+
if attach_intf
|
129
|
+
template = SpecTemplatesNetwork.build_template__port_exists
|
113
130
|
erb = ERB.new(template, nil, '%')
|
114
131
|
@spec_code << erb.result(binding)
|
115
132
|
end
|
@@ -120,7 +137,7 @@ module Wire
|
|
120
137
|
ip_start = dhcp_data[:start]
|
121
138
|
ip_end = dhcp_data[:end]
|
122
139
|
hostip = ip
|
123
|
-
template =
|
140
|
+
template = SpecTemplatesNetwork.build_template__dhcp_is_valid
|
124
141
|
erb = ERB.new(template, nil, '%')
|
125
142
|
@spec_code << erb.result(binding)
|
126
143
|
|
@@ -147,11 +164,11 @@ module Wire
|
|
147
164
|
figfile_part = controller_data[:file] || "#{zone_name}/fig.yaml"
|
148
165
|
figfile = File.join(File.expand_path(@target_dir), figfile_part)
|
149
166
|
|
150
|
-
template =
|
167
|
+
template = SpecTemplatesContainers.build_template__fig_file_is_valid
|
151
168
|
erb = ERB.new(template, nil, '%')
|
152
169
|
@spec_code << erb.result(binding)
|
153
170
|
|
154
|
-
template =
|
171
|
+
template = SpecTemplatesContainers.build_template__fig_containers_are_up
|
155
172
|
erb = ERB.new(template, nil, '%')
|
156
173
|
@spec_code << erb.result(binding)
|
157
174
|
end
|
@@ -159,4 +176,4 @@ module Wire
|
|
159
176
|
$log.debug("Done for appgroup #{appgroup_name}")
|
160
177
|
end
|
161
178
|
end
|
162
|
-
end
|
179
|
+
end
|
@@ -8,6 +8,53 @@
|
|
8
8
|
module Wire
|
9
9
|
# stateless erb template methods used by spec_command.rb
|
10
10
|
class SpecTemplates
|
11
|
+
# generate template part
|
12
|
+
# returns
|
13
|
+
# - erb template for spec_helper.rb file
|
14
|
+
def self.template_spec_helper
|
15
|
+
<<ERB
|
16
|
+
require 'serverspec'
|
17
|
+
|
18
|
+
set :backend, :exec
|
19
|
+
ERB
|
20
|
+
end
|
21
|
+
|
22
|
+
# generate template part
|
23
|
+
# returns
|
24
|
+
# - erb template for Rakefile
|
25
|
+
def self.template_rakefile
|
26
|
+
<<ERB
|
27
|
+
require 'rake'
|
28
|
+
require 'rspec/core/rake_task'
|
29
|
+
|
30
|
+
task :spec => 'spec:all'
|
31
|
+
task :default => :spec
|
32
|
+
|
33
|
+
namespace :spec do
|
34
|
+
targets = []
|
35
|
+
Dir.glob('./spec/*').each do |dir|
|
36
|
+
next unless File.directory?(dir)
|
37
|
+
targets << File.basename(dir)
|
38
|
+
end
|
39
|
+
|
40
|
+
task :all => targets
|
41
|
+
task :default => :all
|
42
|
+
|
43
|
+
targets.each do |target|
|
44
|
+
desc "Run serverspec tests to \#{target}"
|
45
|
+
RSpec::Core::RakeTask.new(target.to_sym) do |t|
|
46
|
+
ENV['TARGET_HOST'] = target
|
47
|
+
t.pattern = "spec/\#{target}/*_spec.rb"
|
48
|
+
t.rspec_opts = '--format documentation --color'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
ERB
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Templates for network-related stuff
|
57
|
+
class SpecTemplatesNetwork
|
11
58
|
# rubocop:disable Lint/UnusedMethodArgument
|
12
59
|
# :reek:UnusedParameters
|
13
60
|
def self.build_template__bridge_exists
|
@@ -20,6 +67,38 @@ module Wire
|
|
20
67
|
ERB
|
21
68
|
end
|
22
69
|
|
70
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
71
|
+
# :reek:UnusedParameters
|
72
|
+
def self.build_template__port_exists
|
73
|
+
<<ERB
|
74
|
+
describe 'In zone <%= zone_name %> we should have a port <%= attach_intf %> on ovs ' \
|
75
|
+
'bridge <%= bridge_name %>' do
|
76
|
+
describe command "sudo ovs-vsctl list-ports <%= bridge_name %>" do
|
77
|
+
its(:stdout) { should match /<%= attach_intf %>/ }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
ERB
|
81
|
+
end
|
82
|
+
|
83
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
84
|
+
# :reek:UnusedParameters
|
85
|
+
def self.build_template__bridge_vlan_id_and_trunk
|
86
|
+
<<ERB
|
87
|
+
describe 'In zone <%= zone_name %>, ovs vlan bridge named <%= bridge_name %> ' \
|
88
|
+
'should have id <%= vlanid %>' do
|
89
|
+
describe command "sudo ovs-vsctl br-to-vlan <%= bridge_name %>" do
|
90
|
+
its(:stdout) { should match /<%= vlanid %>/ }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
describe 'In zone <%= zone_name %>, ovs vlan bridge named <%= bridge_name %> ' \
|
94
|
+
'should have parent <%= on_trunk %>' do
|
95
|
+
describe command "sudo ovs-vsctl br-to-parent <%= bridge_name %>" do
|
96
|
+
its(:stdout) { should match /<%= on_trunk %>/ }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
ERB
|
100
|
+
end
|
101
|
+
|
23
102
|
# rubocop:disable Lint/UnusedMethodArgument
|
24
103
|
# :reek:UnusedParameters
|
25
104
|
def self.build_template__ip_is_up
|
@@ -63,7 +142,10 @@ ERB
|
|
63
142
|
end
|
64
143
|
ERB
|
65
144
|
end
|
145
|
+
end
|
66
146
|
|
147
|
+
# templates for container-related specs
|
148
|
+
class SpecTemplatesContainers
|
67
149
|
# rubocop:disable Lint/UnusedMethodArgument
|
68
150
|
# :reek:UnusedParameters
|
69
151
|
# requires figfile, appgroup_name
|
@@ -89,45 +171,6 @@ ERB
|
|
89
171
|
its(:stdout) { should match /Up/ }
|
90
172
|
end
|
91
173
|
end
|
92
|
-
ERB
|
93
|
-
end
|
94
|
-
|
95
|
-
# generate template part
|
96
|
-
# returns
|
97
|
-
# - erb template for spec_helper.rb file
|
98
|
-
def self.template_spec_helper
|
99
|
-
<<ERB
|
100
|
-
require 'serverspec'
|
101
|
-
require 'rspec/its'
|
102
|
-
|
103
|
-
include SpecInfra::Helper::Exec
|
104
|
-
include SpecInfra::Helper::DetectOS
|
105
|
-
|
106
|
-
RSpec.configure do |c|
|
107
|
-
if ENV['ASK_SUDO_PASSWORD']
|
108
|
-
require 'highline/import'
|
109
|
-
c.sudo_password = ask("Enter sudo password: ") { |q| q.echo = false }
|
110
|
-
else
|
111
|
-
c.sudo_password = ENV['SUDO_PASSWORD']
|
112
|
-
end
|
113
|
-
end
|
114
|
-
ERB
|
115
|
-
end
|
116
|
-
|
117
|
-
# generate template part
|
118
|
-
# returns
|
119
|
-
# - erb template for Rakefile
|
120
|
-
def self.template_rakefile
|
121
|
-
<<ERB
|
122
|
-
require 'rake'
|
123
|
-
require 'rspec/core/rake_task'
|
124
|
-
|
125
|
-
RSpec::Core::RakeTask.new(:spec) do |t|
|
126
|
-
t.pattern = 'spec/*/*_spec.rb'
|
127
|
-
t.rspec_opts = '--format documentation --color'
|
128
|
-
end
|
129
|
-
|
130
|
-
task :default => :spec
|
131
174
|
ERB
|
132
175
|
end
|
133
176
|
end
|
@@ -59,7 +59,7 @@ module Wire
|
|
59
59
|
zone_networks = objects_in_zone('networks', zone_name)
|
60
60
|
success = handler.handle_network_attachments(zone_name, zone_networks,
|
61
61
|
appgroup_name, appgroup_data,
|
62
|
-
@project.target_dir)
|
62
|
+
@project.target_dir, @project.vartmp_dir)
|
63
63
|
b_result &= success
|
64
64
|
end
|
65
65
|
|
@@ -7,6 +7,7 @@
|
|
7
7
|
# Wire module
|
8
8
|
module Wire
|
9
9
|
# handle_xxx methods for UpCommand
|
10
|
+
# delegates to BaseCommand.default_handle_resource for most parts
|
10
11
|
# rubocop:disable ClassLength
|
11
12
|
class UpCommandHandler < BaseCommand
|
12
13
|
# bring bridge resource up, identified by
|
@@ -14,24 +15,13 @@ module Wire
|
|
14
15
|
# Returns
|
15
16
|
# - [Bool] true if hostip if up on bridge
|
16
17
|
def handle_bridge(bridge_name)
|
17
|
-
b_result = true
|
18
|
-
|
19
18
|
# we should have a bridge with that name.
|
20
19
|
bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
|
21
|
-
if bridge_resource.up?
|
22
|
-
outputs 'UP', "Bridge #{bridge_name} already up.", :ok2
|
23
|
-
else
|
24
|
-
bridge_resource.up
|
25
|
-
if bridge_resource.up?
|
26
|
-
outputs 'UP', "Bridge #{bridge_name} up.", :ok
|
27
|
-
state.update(:bridge, bridge_name, :up)
|
28
|
-
else
|
29
|
-
outputs 'UP', "Error bringing up bridge #{bridge_name}.", :err
|
30
|
-
b_result = false
|
31
|
-
end
|
32
20
|
|
33
|
-
|
34
|
-
|
21
|
+
default_handle_resource(bridge_resource, :bridge,
|
22
|
+
"Bridge \'#{bridge_name}\'", :up)
|
23
|
+
rescue => e
|
24
|
+
$log.error "processing bridge: #{e}"
|
35
25
|
end
|
36
26
|
|
37
27
|
# bring ip resource up on device identified by
|
@@ -39,25 +29,14 @@ module Wire
|
|
39
29
|
# Returns
|
40
30
|
# - [Bool] true if hostip if up on bridge
|
41
31
|
def handle_hostip(bridge_name, hostip)
|
42
|
-
b_result = true
|
43
|
-
|
44
32
|
# we should have a bridge with that name.
|
45
33
|
hostip_resource = Wire::Resource::ResourceFactory
|
46
34
|
.instance.create(:bridgeip, hostip, bridge_name)
|
47
|
-
if hostip_resource.up?
|
48
|
-
outputs 'UP', "IP #{hostip} on bridge #{bridge_name} already up.", :ok2
|
49
|
-
else
|
50
|
-
hostip_resource.up
|
51
|
-
if hostip_resource.up?
|
52
|
-
outputs 'UP', "IP #{hostip} on bridge #{bridge_name} up.", :ok
|
53
|
-
state.update(:hostip, hostip, :up)
|
54
|
-
else
|
55
|
-
outputs 'UP', "Error bringing up ip #{hostip} on bridge #{bridge_name}.", :err
|
56
|
-
b_result = false
|
57
|
-
end
|
58
35
|
|
59
|
-
|
60
|
-
|
36
|
+
default_handle_resource(hostip_resource, :hostip,
|
37
|
+
"IP \'#{hostip}\' on bridge \'#{bridge_name}\'", :up)
|
38
|
+
rescue => e
|
39
|
+
$log.error "processing host ip: #{e}"
|
61
40
|
end
|
62
41
|
|
63
42
|
# configures dnsmasq for dhcp
|
@@ -72,21 +51,11 @@ module Wire
|
|
72
51
|
resource_dhcp = Wire::Resource::ResourceFactory
|
73
52
|
.instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
|
74
53
|
network_entry, address_start, address_end)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
if resource_dhcp.up?
|
81
|
-
outputs 'UP', "dnsmasq/dhcp config on network \'#{network_name}\' is up.", :ok
|
82
|
-
state.update(:dnsmasq, network_name, :up)
|
83
|
-
return true
|
84
|
-
else
|
85
|
-
outputs 'UP', "Error configuring dnsmasq/dhcp config on network \'#{network_name}\'.",
|
86
|
-
:err
|
87
|
-
return false
|
88
|
-
end
|
89
|
-
end
|
54
|
+
|
55
|
+
default_handle_resource(resource_dhcp, :dnsmasq,
|
56
|
+
"dnsmasq/dhcp config on network \'#{network_name}\'", :up)
|
57
|
+
rescue => e
|
58
|
+
$log.error "processing dhcp: #{e}"
|
90
59
|
end
|
91
60
|
|
92
61
|
# take the appgroups' controller and directs methods to
|
@@ -106,6 +75,8 @@ module Wire
|
|
106
75
|
|
107
76
|
$log.error "Appgroup not handled, unknown controller type #{controller_entry[:type]}"
|
108
77
|
false
|
78
|
+
rescue => e
|
79
|
+
$log.error "processing appgroup: #{e}"
|
109
80
|
end
|
110
81
|
|
111
82
|
# implement appgroup handling for fig controller
|
@@ -123,21 +94,10 @@ module Wire
|
|
123
94
|
resource_fig = Wire::Resource::ResourceFactory
|
124
95
|
.instance.create(:figadapter, "#{appgroup_name}", fig_path)
|
125
96
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
resource_fig.up
|
131
|
-
if resource_fig.up?
|
132
|
-
outputs 'UP', "appgroup \'#{appgroup_name}\' in zone #{zone_name} is up.", :ok
|
133
|
-
state.update(:appgroup, appgroup_name, :up)
|
134
|
-
return true
|
135
|
-
else
|
136
|
-
outputs 'UP', "Error bringing up appgroup \'#{appgroup_name}\' in zone #{zone_name} .",
|
137
|
-
:err
|
138
|
-
return false
|
139
|
-
end
|
140
|
-
end
|
97
|
+
default_handle_resource(resource_fig, :appgroup,
|
98
|
+
"appgroup \'#{appgroup_name}\' for zone \'#{zone_name}\'", :up)
|
99
|
+
rescue => e
|
100
|
+
$log.error "processing appgroup/fig: #{e}"
|
141
101
|
end
|
142
102
|
|
143
103
|
# attaches networks to containers of appgroup
|
@@ -147,10 +107,11 @@ module Wire
|
|
147
107
|
# ++appgroup_name++: Name of appgroup
|
148
108
|
# ++appgroup_entry++: appgroup hash
|
149
109
|
# ++target_dir++: project target dir
|
110
|
+
# ++state_dir++: project state dir (network statefile is written there)
|
150
111
|
# Returns
|
151
112
|
# - [Bool] true if appgroup setup is ok
|
152
113
|
def handle_network_attachments(_zone_name, networks, appgroup_name,
|
153
|
-
appgroup_entry, target_dir)
|
114
|
+
appgroup_entry, target_dir, state_dir)
|
154
115
|
# query container ids of containers running here
|
155
116
|
# get path
|
156
117
|
controller_entry = appgroup_entry[:controller]
|
@@ -168,26 +129,15 @@ module Wire
|
|
168
129
|
end
|
169
130
|
|
170
131
|
#
|
132
|
+
statefile_name = File.join(state_dir, ".network_attachment_#{Time.now.to_i}")
|
171
133
|
resource_nw = Wire::Resource::ResourceFactory
|
172
|
-
.instance.create(:networkinjection, appgroup_name, networks
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
resource_nw.up
|
180
|
-
if resource_nw.up?
|
181
|
-
outputs 'UP', "appgroup \'#{appgroup_name}\' attached " \
|
182
|
-
"networks #{networks.keys.join(',')}.", :ok
|
183
|
-
state.update(:appgroup, appgroup_name, :up)
|
184
|
-
return true
|
185
|
-
else
|
186
|
-
outputs 'UP', "Error attaching networks to appgroup \'#{appgroup_name}\'.",
|
187
|
-
:err
|
188
|
-
return false
|
189
|
-
end
|
190
|
-
end
|
134
|
+
.instance.create(:networkinjection, appgroup_name, networks, container_ids, statefile_name)
|
135
|
+
|
136
|
+
default_handle_resource(resource_nw, :network_injection,
|
137
|
+
"Network(s) \'#{networks.keys.join(',')}\' in "\
|
138
|
+
"appgroup \'#{appgroup_name}\'", :up)
|
139
|
+
rescue => e
|
140
|
+
$log.error "processing network attachments: #{e}"
|
191
141
|
end
|
192
142
|
end
|
193
143
|
end
|
@@ -8,21 +8,32 @@
|
|
8
8
|
module Wire
|
9
9
|
# handle_xxx methods for VerifyCommand
|
10
10
|
class VerifyCommandHandler < BaseCommand
|
11
|
+
# asks given +resource+ if it is up. Writes states, outputs state
|
12
|
+
# Params:
|
13
|
+
# ++resource++: Resource object, i.e. BridgeResource
|
14
|
+
# ++resource_type++: Resource type symbol, i.e. :bridge
|
15
|
+
# ++resource_desc_str++: Description to dump out
|
16
|
+
# Returns
|
17
|
+
# [Bool] true = resource is up, false otherwise
|
18
|
+
def default_handle_resource(resource, resource_type, resource_desc_str)
|
19
|
+
if resource.up?
|
20
|
+
outputs 'VERIFY', "#{resource_desc_str} is up.", :ok
|
21
|
+
state.update(resource_type, resource.name, :up)
|
22
|
+
return true
|
23
|
+
else
|
24
|
+
outputs 'VERIFY', "#{resource_desc_str} is not up.", :err
|
25
|
+
state.update(resource_type, resource.name, :down)
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
11
30
|
# runs verification for a bridge resource identified by
|
12
31
|
# +bridge_name+
|
13
32
|
# Returns
|
14
33
|
# - [Bool] true if bridge exists
|
15
34
|
def handle_bridge(bridge_name)
|
16
35
|
bridge_resource = Wire::Resource::ResourceFactory.instance.create(:ovsbridge, bridge_name)
|
17
|
-
|
18
|
-
outputs 'VERIFY', "Bridge \'#{bridge_name}\' exists.", :ok
|
19
|
-
state.update(:bridge, bridge_name, :up)
|
20
|
-
return true
|
21
|
-
else
|
22
|
-
outputs 'VERIFY', "Bridge \'#{bridge_name}\' does not exist.", :err
|
23
|
-
state.update(:bridge, bridge_name, :down)
|
24
|
-
return false
|
25
|
-
end
|
36
|
+
default_handle_resource(bridge_resource, :bridge, "Bridge \'#{bridge_name}\'")
|
26
37
|
end
|
27
38
|
|
28
39
|
# runs verification for a ip resource identified by
|
@@ -32,15 +43,8 @@ module Wire
|
|
32
43
|
def handle_hostip(bridge_name, hostip)
|
33
44
|
hostip_resource = Wire::Resource::ResourceFactory
|
34
45
|
.instance.create(:bridgeip, hostip, bridge_name)
|
35
|
-
|
36
|
-
|
37
|
-
state.update(:hostip, hostip, :up)
|
38
|
-
return true
|
39
|
-
else
|
40
|
-
outputs 'VERIFY', "IP \'#{hostip}\' on bridge \'#{bridge_name}\' does not exist.", :err
|
41
|
-
state.update(:hostip, hostip, :down)
|
42
|
-
return false
|
43
|
-
end
|
46
|
+
default_handle_resource(hostip_resource, :hostip,
|
47
|
+
"IP \'#{hostip}\' on bridge \'#{bridge_name}\'")
|
44
48
|
end
|
45
49
|
|
46
50
|
# runs verification for dnsmasqs dhcp resource
|
@@ -50,15 +54,8 @@ module Wire
|
|
50
54
|
resource = Wire::Resource::ResourceFactory
|
51
55
|
.instance.create(:dhcpconfig, "wire__#{zone_name}", network_name,
|
52
56
|
network_entry, address_start, address_end)
|
53
|
-
|
54
|
-
|
55
|
-
state.update(:dnsmasq, network_name, :up)
|
56
|
-
return true
|
57
|
-
else
|
58
|
-
outputs 'VERIFY', "dnsmasq/dhcp config on network \'#{network_name}\' is not valid.", :err
|
59
|
-
state.update(:dnsmasq, network_name, :down)
|
60
|
-
return false
|
61
|
-
end
|
57
|
+
default_handle_resource(resource, :dnsmasq,
|
58
|
+
"dnsmasq/dhcp config on network \'#{network_name}\'")
|
62
59
|
end
|
63
60
|
|
64
61
|
# runs verification for appgroups
|
@@ -73,15 +70,8 @@ module Wire
|
|
73
70
|
|
74
71
|
resource = Wire::Resource::ResourceFactory
|
75
72
|
.instance.create(:figadapter, "#{appgroup_name}", fig_path)
|
76
|
-
|
77
|
-
|
78
|
-
state.update(:appgroup, appgroup_name, :up)
|
79
|
-
return true
|
80
|
-
else
|
81
|
-
outputs 'VERIFY', "appgroup \'#{appgroup_name}\' is not running.", :err
|
82
|
-
state.update(:appgroup, appgroup_name, :down)
|
83
|
-
return false
|
84
|
-
end
|
73
|
+
return default_handle_resource(resource, :appgroup,
|
74
|
+
"Fig Appgroup \'#{appgroup_name}\'")
|
85
75
|
end
|
86
76
|
|
87
77
|
$log.error "Appgroup not handled, unknown controller type #{controller_entry[:type]}"
|
@@ -117,18 +107,10 @@ module Wire
|
|
117
107
|
|
118
108
|
#
|
119
109
|
resource = Wire::Resource::ResourceFactory
|
120
|
-
.instance.create(:networkinjection, appgroup_name, networks
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
state.update(:appgroup, appgroup_name, :up)
|
125
|
-
return true
|
126
|
-
else
|
127
|
-
outputs 'VERIFY', "appgroup \'#{appgroup_name}\' does not have " \
|
128
|
-
"all networks \'#{networks.keys.join(',')}\' attached.", :err
|
129
|
-
state.update(:appgroup, appgroup_name, :down)
|
130
|
-
return false
|
131
|
-
end
|
110
|
+
.instance.create(:networkinjection, appgroup_name, networks, container_ids)
|
111
|
+
default_handle_resource(resource, :network_injection,
|
112
|
+
"Network(s) \'#{networks.keys.join(',')}\' in " \
|
113
|
+
"appgroup \'#{appgroup_name}\'")
|
132
114
|
end
|
133
115
|
end
|
134
116
|
end
|
@@ -17,6 +17,7 @@ module Wire
|
|
17
17
|
missing_network_def_found?
|
18
18
|
nonmatching_hostips_found?
|
19
19
|
dhcp_address_ranges_valid?
|
20
|
+
networks_names_too_long?
|
20
21
|
end
|
21
22
|
|
22
23
|
# ensures that all networks are attached to a zone
|
@@ -24,6 +25,20 @@ module Wire
|
|
24
25
|
objects_attached_to_zones? 'networks'
|
25
26
|
end
|
26
27
|
|
28
|
+
# ensures that networks with names > 6 chars have
|
29
|
+
# a short name defined, and short names are 6 chars. max.
|
30
|
+
def networks_names_too_long?
|
31
|
+
@project.get_element('networks').each do |network_name, network_data|
|
32
|
+
b_short_name_ok = (network_data[:shortname] && network_data[:shortname].size <= 6)
|
33
|
+
|
34
|
+
mark("Network name #{network_name} too long, please define a :shortname with 6 chars. max.",
|
35
|
+
'network', network_name) if network_name.size > 6 && !b_short_name_ok
|
36
|
+
mark("Network short name of network #{network_name} too long, please define a :shortname " \
|
37
|
+
'with 6 chars. max.',
|
38
|
+
'network', network_name) if network_data[:shortname] && !b_short_name_ok
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
27
42
|
# ensures that all network ranges are unique
|
28
43
|
def duplicate_networks_found?
|
29
44
|
dup_map = {}
|
@@ -86,26 +101,26 @@ module Wire
|
|
86
101
|
'network', network_name)
|
87
102
|
return false
|
88
103
|
else
|
89
|
-
|
90
|
-
|
91
|
-
begin
|
92
|
-
dhcp_start_ip = IPAddr.new(dhcp_data[:start])
|
93
|
-
dhcp_end_ip = IPAddr.new(dhcp_data[:end])
|
94
|
-
network_ip = IPAddr.new(network)
|
95
|
-
|
96
|
-
mark("Network dhcp start ip #{dhcp_data[:start]} is not within network range" \
|
97
|
-
"#{network} of network #{network_name}", 'network', network_name) unless
|
98
|
-
dhcp_start_ip.in_range_of?(network_ip)
|
99
|
-
|
100
|
-
mark("Network dhcp end ip #{dhcp_data[:end]} is not within network range" \
|
101
|
-
"#{network} of network #{network_name}", 'network', network_name) unless
|
102
|
-
dhcp_end_ip.in_range_of?(network_ip)
|
103
|
-
rescue => e
|
104
|
-
mark("Network dhcp ip range is not valid: #{e}", 'network', network_name)
|
105
|
-
end
|
104
|
+
check_network_ip_ranges(dhcp_data, network, network_name)
|
106
105
|
end
|
107
106
|
end
|
108
107
|
end
|
109
108
|
end
|
109
|
+
|
110
|
+
# check ip ranges of +dhcp_data+ and given +network+
|
111
|
+
# with name +network_name+
|
112
|
+
def check_network_ip_ranges(dhcp_data, network, network_name)
|
113
|
+
network_ip = IPAddr.new(network)
|
114
|
+
|
115
|
+
# check both starting/ending ip range
|
116
|
+
{ :start => IPAddr.new(dhcp_data[:start]),
|
117
|
+
:end => IPAddr.new(dhcp_data[:end]) }.each do |type, data|
|
118
|
+
mark("Network dhcp #{type} ip #{dhcp_data[type]} is not within network range" \
|
119
|
+
"#{network} of network #{network_name}",
|
120
|
+
'network', network_name) unless data.in_range_of?(network_ip)
|
121
|
+
end
|
122
|
+
rescue => e
|
123
|
+
mark("Network dhcp ip range is not valid: #{e}", 'network', network_name)
|
124
|
+
end
|
110
125
|
end
|
111
126
|
end
|
data/lib/wire/model/project.rb
CHANGED
@@ -48,6 +48,18 @@ module Wire
|
|
48
48
|
@data[element_name.to_sym]
|
49
49
|
end
|
50
50
|
|
51
|
+
# return project's var/tmp directory, will be configurable
|
52
|
+
# in the future
|
53
|
+
def vartmp_dir
|
54
|
+
# as of now, use .state in target dir
|
55
|
+
state_dir = File.join(@target_dir, '.state')
|
56
|
+
unless File.directory? state_dir
|
57
|
+
FileUtils.mkdir_p state_dir
|
58
|
+
$log.debug "created state dir #{state_dir}"
|
59
|
+
end
|
60
|
+
state_dir
|
61
|
+
end
|
62
|
+
|
51
63
|
# calculates count statistics on project
|
52
64
|
# returns:
|
53
65
|
# - [Hash], key => element type, value => [int] count
|
data/lib/wire/model/state.rb
CHANGED
@@ -114,13 +114,14 @@ module Wire
|
|
114
114
|
@state = YAML.load_file(statefile_filename)
|
115
115
|
else
|
116
116
|
$log.debug 'No statefile found.'
|
117
|
+
clean
|
117
118
|
end
|
118
119
|
@changed = false
|
119
120
|
end
|
120
121
|
|
121
122
|
# construct name of state file
|
122
123
|
def state_filename
|
123
|
-
File.join(@project.
|
124
|
+
File.join(@project.vartmp_dir, '.state.yaml')
|
124
125
|
end
|
125
126
|
end
|
126
127
|
|
data/lib/wire/resource/bridge.rb
CHANGED
@@ -24,16 +24,21 @@ module Wire
|
|
24
24
|
# names of networks to attach appgroup containers to
|
25
25
|
attr_accessor :networks
|
26
26
|
|
27
|
+
# filename of state file
|
28
|
+
attr_accessor :statefile
|
29
|
+
|
27
30
|
# initialize the object with
|
28
31
|
# given appgroup +name+ and +container+ ids
|
29
32
|
# params:
|
30
33
|
# ++name++: Application group name
|
31
|
-
# ++networks++: [Array] of network
|
32
|
-
# ++containers
|
33
|
-
|
34
|
+
# ++networks++: [Array] of network objects to attach containers to
|
35
|
+
# ++containers++: [Array] of container ids (i.e. from fig ps -q)
|
36
|
+
# ++statefile++: Optional name of (network) statefile
|
37
|
+
def initialize(name, networks, containers, statefile = nil)
|
34
38
|
super(name)
|
35
39
|
self.containers = containers
|
36
40
|
self.networks = networks
|
41
|
+
self.statefile = statefile
|
37
42
|
|
38
43
|
begin
|
39
44
|
# try to locate the gem base path and find shell script
|
@@ -73,12 +78,18 @@ module Wire
|
|
73
78
|
# an array of container devices names and bridge names,
|
74
79
|
# i.e. eht1:br0 meaning container will be attached
|
75
80
|
# to bridge br0 with eth1.
|
76
|
-
#
|
77
|
-
#
|
81
|
+
# if a network defines a short name, it will be used for
|
82
|
+
# the container interface.
|
83
|
+
# will check if a network does not have dhcp enable and add a
|
84
|
+
# NODHCP flag.
|
78
85
|
def construct_helper_params
|
79
86
|
res = []
|
80
|
-
networks.each do |
|
81
|
-
|
87
|
+
networks.each do |network_name, network_data|
|
88
|
+
name = (network_data[:shortname]) ? network_data[:shortname] : network_name
|
89
|
+
|
90
|
+
line = "#{name}:#{network_name}"
|
91
|
+
(network_data[:dhcp]) || line << ':NODHCP'
|
92
|
+
res << line
|
82
93
|
end
|
83
94
|
res.join(' ')
|
84
95
|
end
|
@@ -93,17 +104,23 @@ module Wire
|
|
93
104
|
end
|
94
105
|
end
|
95
106
|
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
107
|
+
# Params:
|
108
|
+
# ++cmd++: One of :attach, :detach
|
109
|
+
def updown_command(cmd)
|
110
|
+
$log.debug "About to #{cmd.to_s.capitalize} containers to networks ..."
|
111
|
+
statefile_param = (@statefile) ? "-s #{@statefile}" : ''
|
112
|
+
with_helper(cmd.to_s, [construct_helper_params,
|
113
|
+
containers.join(' ')], statefile_param) do |exec_obj|
|
101
114
|
exec_obj.run
|
102
|
-
|
103
115
|
return (exec_obj.exitstatus == 0 && count_errors(exec_obj) == 0)
|
104
116
|
end
|
105
117
|
end
|
106
118
|
|
119
|
+
# attaches containers to networks
|
120
|
+
def up
|
121
|
+
updown_command :attach
|
122
|
+
end
|
123
|
+
|
107
124
|
# checks if the bridge is down
|
108
125
|
def down?
|
109
126
|
!(up?)
|
@@ -111,13 +128,7 @@ module Wire
|
|
111
128
|
|
112
129
|
# detaches network interfaces form containers and bridges
|
113
130
|
def down
|
114
|
-
|
115
|
-
with_helper('detach', [construct_helper_params,
|
116
|
-
containers.join(' ')]) do |exec_obj|
|
117
|
-
exec_obj.run
|
118
|
-
|
119
|
-
return (exec_obj.exitstatus == 0 && count_errors(exec_obj) == 0)
|
120
|
-
end
|
131
|
+
updown_command :detach
|
121
132
|
end
|
122
133
|
|
123
134
|
# Returns a string representation
|
@@ -26,11 +26,11 @@ module Wire
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# ResourceFactory creates Resource objects
|
29
|
-
# given by name
|
29
|
+
# given by symbolic name
|
30
30
|
class ResourceFactory
|
31
31
|
include Singleton
|
32
32
|
|
33
|
-
# given a +
|
33
|
+
# given a +resource_symname+ as a symbol (i.e. :ovsbridge)
|
34
34
|
# this creates a resource with given name (i.e. "testbridge")
|
35
35
|
# and hands on arguments (+resource_nameargs+, may be 1..n)
|
36
36
|
# returns
|
data/lib/wire/version.rb
CHANGED