Revision acd65a16
b/daemons/import-export | ||
---|---|---|
40 | 40 |
from ganeti import constants |
41 | 41 |
from ganeti import cli |
42 | 42 |
from ganeti import utils |
43 |
from ganeti import errors |
|
43 | 44 |
from ganeti import serializer |
44 | 45 |
from ganeti import objects |
45 | 46 |
from ganeti import locking |
... | ... | |
401 | 402 |
# Won't return |
402 | 403 |
parser.error("Invalid mode: %s" % mode) |
403 | 404 |
|
405 |
# Normalize and check parameters |
|
406 |
if options.host is not None: |
|
407 |
try: |
|
408 |
options.host = utils.HostInfo.NormalizeName(options.host) |
|
409 |
except errors.OpPrereqError, err: |
|
410 |
parser.error("Invalid hostname '%s': %s" % (options.host, err)) |
|
411 |
|
|
412 |
if options.port is not None: |
|
413 |
options.port = utils.ValidateServiceName(options.port) |
|
414 |
|
|
404 | 415 |
if (options.exp_size is not None and |
405 | 416 |
options.exp_size != constants.IE_CUSTOM_SIZE): |
406 | 417 |
try: |
b/lib/cmdlib.py | ||
---|---|---|
9100 | 9100 |
_CheckNodeNotDrained(self, self.dst_node.name) |
9101 | 9101 |
|
9102 | 9102 |
self._cds = None |
9103 |
self.dest_disk_info = None |
|
9103 | 9104 |
self.dest_x509_ca = None |
9104 | 9105 |
|
9105 | 9106 |
elif self.export_mode == constants.EXPORT_MODE_REMOTE: |
... | ... | |
9139 | 9140 |
self.dest_x509_ca = cert |
9140 | 9141 |
|
9141 | 9142 |
# Verify target information |
9143 |
disk_info = [] |
|
9142 | 9144 |
for idx, disk_data in enumerate(self.op.target_node): |
9143 | 9145 |
try: |
9144 |
masterd.instance.CheckRemoteExportDiskInfo(cds, idx, disk_data) |
|
9146 |
(host, port) = masterd.instance.CheckRemoteExportDiskInfo(cds, idx, |
|
9147 |
disk_data) |
|
9145 | 9148 |
except errors.GenericError, err: |
9146 | 9149 |
raise errors.OpPrereqError("Target info for disk %s: %s" % (idx, err), |
9147 | 9150 |
errors.ECODE_INVAL) |
9148 | 9151 |
|
9152 |
disk_info.append((host, port)) |
|
9153 |
|
|
9154 |
assert len(disk_info) == len(self.op.target_node) |
|
9155 |
self.dest_disk_info = disk_info |
|
9156 |
|
|
9149 | 9157 |
else: |
9150 | 9158 |
raise errors.ProgrammerError("Unhandled export mode %r" % |
9151 | 9159 |
self.export_mode) |
... | ... | |
9236 | 9244 |
opts = objects.ImportExportOptions(key_name=key_name, |
9237 | 9245 |
ca_pem=dest_ca_pem) |
9238 | 9246 |
|
9239 |
(fin_resu, dresults) = helper.RemoteExport(opts, self.op.target_node,
|
|
9247 |
(fin_resu, dresults) = helper.RemoteExport(opts, self.dest_disk_info,
|
|
9240 | 9248 |
timeouts) |
9241 | 9249 |
finally: |
9242 | 9250 |
helper.Cleanup() |
b/lib/masterd/instance.py | ||
---|---|---|
1239 | 1239 |
|
1240 | 1240 |
ieloop = ImportExportLoop(self._lu) |
1241 | 1241 |
try: |
1242 |
for idx, (dev, (host, port, _, _)) in enumerate(zip(instance.disks,
|
|
1243 |
disk_info)):
|
|
1242 |
for idx, (dev, (host, port)) in enumerate(zip(instance.disks, |
|
1243 |
disk_info)): |
|
1244 | 1244 |
self._feedback_fn("Sending disk %s to %s:%s" % (idx, host, port)) |
1245 | 1245 |
finished_fn = compat.partial(self._TransferFinished, idx) |
1246 | 1246 |
ieloop.Add(DiskExport(self._lu, instance.primary_node, |
... | ... | |
1514 | 1514 |
if not utils.VerifySha1Hmac(cds, msg, hmac_digest, salt=hmac_salt): |
1515 | 1515 |
raise errors.GenericError("HMAC is wrong") |
1516 | 1516 |
|
1517 |
return (host, port) |
|
1517 |
return (utils.HostInfo.NormalizeName(host), |
|
1518 |
utils.ValidateServiceName(port)) |
|
1518 | 1519 |
|
1519 | 1520 |
|
1520 | 1521 |
def ComputeRemoteImportDiskInfo(cds, salt, disk_index, host, port): |
b/test/ganeti.masterd.instance_unittest.py | ||
---|---|---|
111 | 111 |
self.assertRaises(errors.GenericError, CheckRemoteExportDiskInfo, |
112 | 112 |
cds, i, di) |
113 | 113 |
|
114 |
def testInvalidHostPort(self): |
|
115 |
cds = "3ZoJY8KtGJ" |
|
116 |
salt = "drK5oYiHWD" |
|
117 |
|
|
118 |
for host in [",", "...", "Hello World", "`", "!", "#", "\\"]: |
|
119 |
di = ComputeRemoteImportDiskInfo(cds, salt, 0, host, 1234) |
|
120 |
self.assertRaises(errors.OpPrereqError, |
|
121 |
CheckRemoteExportDiskInfo, cds, 0, di) |
|
122 |
|
|
123 |
for port in [-1, 792825908, "HelloWorld!", "`#", "\\\"", "_?_"]: |
|
124 |
di = ComputeRemoteImportDiskInfo(cds, salt, 0, "localhost", port) |
|
125 |
self.assertRaises(errors.OpPrereqError, |
|
126 |
CheckRemoteExportDiskInfo, cds, 0, di) |
|
127 |
|
|
114 | 128 |
def testCheckErrors(self): |
115 | 129 |
cds = "0776450535a" |
116 | 130 |
self.assertRaises(errors.GenericError, CheckRemoteExportDiskInfo, |
b/test/import-export_unittest.bash | ||
---|---|---|
108 | 108 |
$impexpd $src_statusfile invalidmode >/dev/null 2>&1 && |
109 | 109 |
err "daemon-util succeeded with invalid mode" |
110 | 110 |
|
111 |
$impexpd $src_statusfile import --compression=rot13 >/dev/null 2>&1 && |
|
112 |
err "daemon-util succeeded with invalid compression" |
|
111 |
for mode in import export; do |
|
112 |
$impexpd $src_statusfile $mode --compression=rot13 >/dev/null 2>&1 && |
|
113 |
err "daemon-util succeeded with invalid compression" |
|
114 |
|
|
115 |
for host in '' ' ' ' s p a c e' ... , foo.example.net... \ |
|
116 |
'some"evil"name' 'x\ny\tmoo'; do |
|
117 |
$impexpd $src_statusfile $mode --host="$host" >/dev/null 2>&1 && |
|
118 |
err "daemon-util succeeded with invalid host '$host'" |
|
119 |
done |
|
120 |
|
|
121 |
for port in '' ' ' -1234 'some ` port " here'; do |
|
122 |
$impexpd $src_statusfile $mode --port="$port" >/dev/null 2>&1 && |
|
123 |
err "daemon-util succeeded with invalid port '$port'" |
|
124 |
done |
|
125 |
done |
|
113 | 126 |
|
114 | 127 |
upto 'Generate test data' |
115 | 128 |
cat $(get_testfile proc_drbd8.txt) $(get_testfile cert1.pem) > $testdata |
Also available in: Unified diff