Hi Chris,
I did a few changes to the previously sent patch. Also added the test script for
regexes' validation.
Please have a look and let me know your thoughts on them.
Regarding the lookaheads and the dots, I feel regexes might need major changes to
accomodate those changes.
I have added few comments for the regexes also. Feel free to add/modify them, if
required.
Thanks and Regards,
Sujith Pandel
When adding iSCSI target disk during installation, the iSCSI Initiator name and the Target
IP is validated to enable/disable the "Start Discovery" button on the page.
Currently, the validation of iSCSI Initiator Name is based on the existence of dots only
(".") and this can be more efficiently done by using a regular expression.
The conditions for iSCSI initiator name used in this regex are
(
https://tools.ietf.org/html/rfc3720#section-3.2.6.3.1 ,
https://tools.ietf.org/html/rfc3721#page-5 and
http://standards.ieee.org/regauth/oui/tutorials/EUI64.html):
1. For iqn format:
a. Starts with string 'iqn.'
b. A date code specifying the year and month in which the organization registered
the domain or sub-domain name used as the naming authority string. "yyyy-mm"
c. A dot (".")
d. The organizational naming authority string, which consists of a valid, reversed
domain or subdomain name.
e. Optionally, a colon (":"), followed by a string of the assigning
organization's choosing, which must make each assigned iSCSI name unique. With the
exception of the colon prefix, the owner of the domain name can assign everything after
the reversed domain name as desired.
2. For eui format:
The format is "eui." followed by an EUI-64 identifier (16 ASCII-encoded
hexadecimal digits).
Signed-off-by: Sujith Pandel <sujithpshankar(a)gmail.com>
---
pyanaconda/regexes.py | 19 +++++++
pyanaconda/ui/gui/spokes/advstorage/iscsi.py | 9 +++-
tests/regex_tests/iscsi_name_test.py | 78 ++++++++++++++++++++++++++++
3 files changed, 104 insertions(+), 2 deletions(-)
create mode 100644 tests/regex_tests/iscsi_name_test.py
diff --git a/pyanaconda/regexes.py b/pyanaconda/regexes.py
index b4e52a3..a30b451 100644
--- a/pyanaconda/regexes.py
+++ b/pyanaconda/regexes.py
@@ -135,3 +135,22 @@ REPO_NAME_VALID = re.compile(r'^[a-zA-Z0-9_.:-]+$')
# Product Version string, just the starting numbers like 21 or 21.1
VERSION_DIGITS = r'([\d.]+)'
+
+
+#Regexes to validate iSCSI Names according to RFC 3720 and RFC 3721
+#The conditions for iSCSI name used in the following regexes are
+#(https://tools.ietf.org/html/rfc3720#section-3.2.6.3.1 ,
https://tools.ietf.org/html/rfc3721#page-5 and
http://standards.ieee.org/regauth/oui/tutorials/EUI64.html):
+#1. For iqn format:
+# a. Starts with string 'iqn.'
+# b. A date code specifying the year and month in which the organization registered
the domain or sub-domain name used as the naming authority string. "yyyy-mm"
+# c. A dot (".")
+# d. The organizational naming authority string, which consists of a valid, reversed
domain or subdomain name.
+# e. Optionally, a colon (":"), followed by a string of the assigning
organization's choosing, which must make each assigned iSCSI name unique. With the
exception of the colon prefix, the owner of the domain name can assign everything after
the reversed domain name as desired.
+
+#2. For eui format:
+# a. The format is "eui." followed by an EUI-64 identifier (16 ASCII-encoded
hexadecimal digits).
+ISCSI_IQN_NAME_REGEX =
re.compile(r'^iqn\.\d{4}-\d{2}((?<!-)\.(?!-)[a-zA-Z0-9\-]+){1,63}(?<!-)(?<!\.)(:[^:]+)?$')
+
+ISCSI_EUI_NAME_REGEX = re.compile(r'^eui\.[a-fA-F0-9]{16}$')
+
+
diff --git a/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
b/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
index 22e11c3..26c34c3 100644
--- a/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
+++ b/pyanaconda/ui/gui/spokes/advstorage/iscsi.py
@@ -18,7 +18,7 @@
#
# Red Hat Author(s): Chris Lumens <clumens(a)redhat.com>
#
-
+import re
from IPy import IP
from collections import namedtuple
from gi.repository import GLib
@@ -29,6 +29,7 @@ from pyanaconda.ui.gui import GUIObject
from pyanaconda.ui.gui.utils import escape_markup
from pyanaconda.i18n import _
from pyanaconda import nm
+from pyanaconda.regexes import ISCSI_IQN_NAME_REGEX, ISCSI_EUI_NAME_REGEX
__all__ = ["ISCSIDialog"]
@@ -303,7 +304,11 @@ class ISCSIDialog(GUIObject):
stripped = text.strip()
#iSCSI Naming Standards: RFC 3720 and RFC 3721
- return "." in stripped
+ #iSCSI Name validation using regex. Name should either match IQN format or EUI
format.
+ if re.match(ISCSI_IQN_NAME_REGEX,stripped) or
re.match(ISCSI_EUI_NAME_REGEX,stripped):
+ return True
+ else:
+ return False
def on_discover_field_changed(self, *args):
# Make up a credentials object so we can test if it's valid.
diff --git a/tests/regex_tests/iscsi_name_test.py b/tests/regex_tests/iscsi_name_test.py
new file mode 100644
index 0000000..8571396
--- /dev/null
+++ b/tests/regex_tests/iscsi_name_test.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# vim:set fileencoding=utf-8
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <
http://www.gnu.org/licenses/>.
+
+# Author(s): Sujith Pandel <sujithpshankar(a)gmail.com>
+# Ajith Pandel <ajithpandel(a)gmail.com>
+#
+import unittest
+import re
+
+from regexcheck import regex_match
+from pyanaconda.regexes import ISCSI_IQN_NAME_REGEX, ISCSI_EUI_NAME_REGEX
+
+class iSCSIiqnnameRegexTestCase(unittest.TestCase):
+ def iqnname_test(self):
+ good_tests = [
+ 'iqn.2014-15.com.example',
+ 'iqn.2014-15.com.example:iscsi',
+ 'iqn.2014-15.c-om.example:iscsi',
+ 'iqn.2014-15.c.om.example:iscsi',
+ 'iqn.2014-15.com.example:...',
+
'iqn.2014-15.com.example:iscsi_@nything_except_colon_after_colon!'
+ ]
+
+ bad_tests = [
+ 'iqn',
+ 'iqn.',
+ 'iqn.2014-15',
+ 'iqn.2014-15.',
+ 'iqn.2014-15..',
+ 'iqn.2014-15.com.example.',
+ 'iqn.2014-15.com.example...',
+ 'iqn.2014-15.com.example:',
+ 'iqn.2014-15.-com.example',
+ 'iqn.2014-15.com-.example',
+ 'iqn.2014-15.-.example',
+ 'iqn.2014-15.com.example-:iscsi',
+ 'abciqn.2014-15.com.example:iscsi',
+ 'iqn.2014-15.-.example:iscsi',
+ 'iqn.2014-15.com&com.example:iscsi',
+ 'iqn.2014-15.com.example:iscsi:doublecolon',
+ 'iqn.2014-15..om.example:iscsi',
+ ]
+
+ if not regex_match(ISCSI_IQN_NAME_REGEX, good_tests, bad_tests):
+ self.fail()
+
+class iSCSIeuinameRegexTestCase(unittest.TestCase):
+ def euiname_test(self):
+ good_tests = [
+ 'eui.ABCDEF0123456789',
+ 'eui.abcdef0123456789',
+ 'eui.0123456789ABCDEF'
+ ]
+
+ bad_tests = [
+ 'eui',
+ 'eui.',
+ 'eui.2014-',
+ 'eui.exampleeui789abc'
+ 'eui.AAAABBBBCCC2345',
+ 'eui.AAAABBBBCCCCD4567'
+ ]
+
+ if not regex_match(ISCSI_EUI_NAME_REGEX, good_tests, bad_tests):
+ self.fail()
--
2.1.0