dewiring 0.1.3 → 0.1.4
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.
- 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