summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2012-04-18 11:22:35 -0400
committerMartin Kosek <mkosek@redhat.com>2012-05-09 11:54:20 +0200
commitf19218f7d87f5847d51f79b5d2850f90b0ae8407 (patch)
tree500d3101dc1375d3eb75ffb927040c2593216aa9
parentc02fcf5d34ad880e082cbc0c7f59fc3812d11c9e (diff)
downloadfreeipa-f19218f7d87f5847d51f79b5d2850f90b0ae8407.tar.gz
freeipa-f19218f7d87f5847d51f79b5d2850f90b0ae8407.tar.xz
freeipa-f19218f7d87f5847d51f79b5d2850f90b0ae8407.zip
Remove duplicate and unused utility code
IPA has some unused code from abandoned features (Radius, ipa 1.x user input, commant-line tab completion), as well as some duplicate utilities. This patch cleans up the utility modules. Duplicate code consolidated into ipapython.ipautil: {ipalib.util,ipaserver.ipautil,ipapython.ipautil}.realm_to_suffix {ipaserver,ipapython}.ipautil.CIDict (with style improvements from the ipaserver version) {ipapython.entity,ipaserver.ipautil}.utf8_encode_value {ipapython.entity,ipaserver.ipautil}.utf8_encode_values ipalib.util.get_fqdn was removed in favor of the same function in ipaserver.install.installutils Removed unused code: ipalib.util: load_plugins_in_dir import_plugins_subpackage make_repr (was imported but unused; also removed from tests) ipapython.ipautil: format_list parse_key_value_pairs read_pairs_file read_items_file user_input_plain AttributeValueCompleter ItemCompleter ipaserver.ipautil: get_gsserror (a different version exists in ipapython.ipautil) ipaserver.ipautil ended up empty and is removed entirely. https://fedorahosted.org/freeipa/ticket/2650
-rwxr-xr-xinstall/tools/ipa-ca-install2
-rwxr-xr-xinstall/tools/ipa-csreplica-manage4
-rwxr-xr-xinstall/tools/ipa-replica-install8
-rwxr-xr-xinstall/tools/ipa-replica-manage6
-rwxr-xr-xinstall/tools/ipa-replica-prepare2
-rwxr-xr-xinstall/tools/ipa-server-install9
-rw-r--r--ipalib/frontend.py1
-rw-r--r--ipalib/parameters.py1
-rw-r--r--ipalib/util.py47
-rw-r--r--ipapython/entity.py31
-rw-r--r--ipapython/ipautil.py506
-rw-r--r--ipaserver/install/bindinstance.py6
-rw-r--r--ipaserver/install/cainstance.py4
-rw-r--r--ipaserver/install/dsinstance.py6
-rw-r--r--ipaserver/install/httpinstance.py2
-rw-r--r--ipaserver/install/krbinstance.py2
-rw-r--r--ipaserver/install/ldapupdate.py2
-rw-r--r--ipaserver/install/replication.py2
-rw-r--r--ipaserver/ipaldap.py2
-rw-r--r--ipaserver/ipautil.py141
-rw-r--r--ipaserver/plugins/join.py6
-rw-r--r--ipaserver/rpcserver.py2
-rw-r--r--tests/test_ipalib/test_util.py11
23 files changed, 78 insertions, 725 deletions
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 57f867e70..55b4dbfb8 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -143,7 +143,7 @@ def main():
# We need to ldap_enable the CA now that DS is up and running
CA.ldap_enable('CA', config.host_name, config.dirman_password,
- util.realm_to_suffix(config.realm_name))
+ ipautil.realm_to_suffix(config.realm_name))
cs.add_simple_service('dogtagldap/%s@%s' % (config.host_name, config.realm_name))
cs.add_cert_to_service()
diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index 97c504552..938201fed 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -165,7 +165,7 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
conn = ipaldap.IPAdmin(host, 636, cacert=CACERT)
conn.do_simple_bind(bindpw=dirman_passwd)
- dn = str(DN('cn=masters,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)))
+ dn = str(DN('cn=masters,cn=ipa,cn=etc,%s' % ipautil.realm_to_suffix(realm)))
entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
for ent in entries:
@@ -316,7 +316,7 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
conn = ipaldap.IPAdmin(replica2, 636, cacert=CACERT)
conn.do_simple_bind(bindpw=dirman_passwd)
- dn = str(DN('cn=CA,cn=%s,cn=masters,cn=ipa,cn=etc,%s' % (replica2, util.realm_to_suffix(realm))))
+ dn = str(DN('cn=CA,cn=%s,cn=masters,cn=ipa,cn=etc,%s' % (replica2, ipautil.realm_to_suffix(realm))))
conn.search_s(dn, ldap.SCOPE_ONELEVEL)
conn.unbind_s()
except ldap.NO_SUCH_OBJECT:
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 07b1781ee..39ce09bf1 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -186,7 +186,7 @@ def install_http(config, auto_redirect):
config.dir + "/http_pin.txt")
memcache = memcacheinstance.MemcacheInstance()
- memcache.create_instance('MEMCACHE', config.host_name, config.dirman_password, util.realm_to_suffix(config.realm_name))
+ memcache.create_instance('MEMCACHE', config.host_name, config.dirman_password, ipautil.realm_to_suffix(config.realm_name))
http = httpinstance.HTTPInstance()
http.create_instance(config.realm_name, config.host_name, config.domain_name, config.dirman_password, False, pkcs12_info, self_signed_ca=True, auto_redirect=auto_redirect)
@@ -236,7 +236,7 @@ def install_bind(config, options):
def install_dns_records(config, options):
if not bindinstance.dns_container_exists(config.master_host_name,
- util.realm_to_suffix(config.realm_name),
+ ipautil.realm_to_suffix(config.realm_name),
dm_password=config.dirman_password):
return
@@ -355,7 +355,7 @@ def main():
fd = open("/etc/ipa/default.conf", "w")
fd.write("[global]\n")
fd.write("host=" + config.host_name + "\n")
- fd.write("basedn=" + util.realm_to_suffix(config.realm_name) + "\n")
+ fd.write("basedn=" + ipautil.realm_to_suffix(config.realm_name) + "\n")
fd.write("realm=" + config.realm_name + "\n")
fd.write("domain=" + config.domain_name + "\n")
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % ipautil.format_netloc(config.host_name))
@@ -434,7 +434,7 @@ def main():
# We need to ldap_enable the CA now that DS is up and running
if CA and config.setup_ca:
CA.ldap_enable('CA', config.host_name, config.dirman_password,
- util.realm_to_suffix(config.realm_name))
+ ipautil.realm_to_suffix(config.realm_name))
cs.add_simple_service('dogtagldap/%s@%s' % (config.host_name, config.realm_name))
cs.add_cert_to_service()
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index f1f5425ca..e23781738 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -126,13 +126,13 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
else:
conn.do_sasl_gssapi_bind()
- dn = 'cn=masters,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
+ dn = 'cn=masters,cn=ipa,cn=etc,%s' % ipautil.realm_to_suffix(realm)
entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
for ent in entries:
peers[ent.cn] = ['master', '']
- dn = 'cn=replicas,cn=ipa,cn=etc,%s' % util.realm_to_suffix(realm)
+ dn = 'cn=replicas,cn=ipa,cn=etc,%s' % ipautil.realm_to_suffix(realm)
entries = conn.search_s(dn, ldap.SCOPE_ONELEVEL)
for ent in entries:
@@ -255,7 +255,7 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
if type1 == replication.WINSYNC:
try:
dn = 'cn=%s,cn=replicas,cn=ipa,cn=etc,%s' % (replica2,
- util.realm_to_suffix(realm))
+ ipautil.realm_to_suffix(realm))
entries = repl1.conn.search_s(dn, ldap.SCOPE_SUBTREE)
if len(entries) != 0:
dnset = repl1.conn.get_dns_sorted_by_length(entries,
diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index c54aa62b8..3b6911288 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -307,7 +307,7 @@ def main():
enable_replication_version_checking(api.env.host, api.env.realm,
dirman_password)
- subject_base = get_subject_base(api.env.host, dirman_password, util.realm_to_suffix(api.env.realm))
+ subject_base = get_subject_base(api.env.host, dirman_password, ipautil.realm_to_suffix(api.env.realm))
top_dir = tempfile.mkdtemp("ipa")
dir = top_dir + "/realm_info"
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 1dd02ba87..f3377df6d 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -57,6 +57,7 @@ from ipaserver.plugins.ldap2 import ldap2
from ipapython import sysrestore
from ipapython.ipautil import *
+from ipapython import ipautil
from ipalib import api, errors, util
from ipapython.config import IPAOptionParser
from ipalib.dn import DN
@@ -812,7 +813,7 @@ def main():
fd = open(target_fname, "w")
fd.write("[global]\n")
fd.write("host=" + host_name + "\n")
- fd.write("basedn=" + util.realm_to_suffix(realm_name) + "\n")
+ fd.write("basedn=" + ipautil.realm_to_suffix(realm_name) + "\n")
fd.write("realm=" + realm_name + "\n")
fd.write("domain=" + domain_name + "\n")
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name))
@@ -938,7 +939,7 @@ def main():
# We need to ldap_enable the CA now that DS is up and running
if not options.selfsign:
ca.ldap_enable('CA', host_name, dm_password,
- util.realm_to_suffix(realm_name))
+ ipautil.realm_to_suffix(realm_name))
# Turn on SSL in the dogtag LDAP instance. This will get restarted
# later, we don't need SSL now.
@@ -984,7 +985,7 @@ def main():
os.close(pw_fd)
memcache = memcacheinstance.MemcacheInstance()
- memcache.create_instance('MEMCACHE', host_name, dm_password, util.realm_to_suffix(realm_name))
+ memcache.create_instance('MEMCACHE', host_name, dm_password, ipautil.realm_to_suffix(realm_name))
http = httpinstance.HTTPInstance(fstore)
if options.http_pkcs12:
@@ -995,7 +996,7 @@ def main():
http.create_instance(realm_name, host_name, domain_name, dm_password, autoconfig=True, self_signed_ca=options.selfsign, subject_base=options.subject, auto_redirect=options.ui_redirect)
ipaservices.restore_context("/var/cache/ipa/sessions")
- set_subject_in_config(realm_name, dm_password, util.realm_to_suffix(realm_name), options.subject)
+ set_subject_in_config(realm_name, dm_password, ipautil.realm_to_suffix(realm_name), options.subject)
# Apply any LDAP updates. Needs to be done after the configuration file
# is created
diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index b31d6d4b8..e8a84eabe 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -26,7 +26,6 @@ import inspect
from base import lock, check_name, NameSpace
from plugable import Plugin, is_production_mode
from parameters import create_param, parse_param_spec, Param, Str, Flag, Password
-from util import make_repr
from output import Output, Entry, ListOfEntries
from text import _, ngettext
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index e9951a1c8..83a86544d 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -106,7 +106,6 @@ import csv
from xmlrpclib import MAXINT, MININT
from types import NoneType
-from util import make_repr
from text import _ as ugettext
from plugable import ReadOnly, lock, check_name
from errors import ConversionError, RequirementError, ValidationError
diff --git a/ipalib/util.py b/ipalib/util.py
index 6fa69e7af..64ac6b2cf 100644
--- a/ipalib/util.py
+++ b/ipalib/util.py
@@ -61,16 +61,6 @@ def get_current_principal():
#TODO: do a kinit?
raise errors.CCacheError()
-def get_fqdn():
- fqdn = ""
- try:
- fqdn = socket.getfqdn()
- except:
- try:
- fqdn = socket.gethostname()
- except:
- fqdn = ""
- return fqdn
# FIXME: This function has no unit test
def find_modules_in_dir(src_dir):
@@ -94,43 +84,6 @@ def find_modules_in_dir(src_dir):
yield (module, pyfile)
-# FIXME: This function has no unit test
-def load_plugins_in_dir(src_dir):
- """
- Import each Python module found in ``src_dir``.
- """
- for module in find_modules_in_dir(src_dir):
- imp.load_module(module, *imp.find_module(module, [src_dir]))
-
-
-# FIXME: This function has no unit test
-def import_plugins_subpackage(name):
- """
- Import everythig in ``plugins`` sub-package of package named ``name``.
- """
- try:
- plugins = __import__(name + '.plugins').plugins
- except ImportError:
- return
- src_dir = os.path.dirname(os.path.abspath(plugins.__file__))
- for name in find_modules_in_dir(src_dir):
- full_name = '%s.%s' % (plugins.__name__, name)
- __import__(full_name)
-
-
-def make_repr(name, *args, **kw):
- """
- Construct a standard representation of a class instance.
- """
- args = [repr(a) for a in args]
- kw = ['%s=%r' % (k, kw[k]) for k in sorted(kw)]
- return '%s(%s)' % (name, ', '.join(args + kw))
-
-def realm_to_suffix(realm_name):
- s = realm_name.split(".")
- terms = ["dc=" + x.lower() for x in s]
- return ",".join(terms)
-
def validate_host_dns(log, fqdn):
"""
See if the hostname has a DNS A record.
diff --git a/ipapython/entity.py b/ipapython/entity.py
index 527adface..27d517879 100644
--- a/ipapython/entity.py
+++ b/ipapython/entity.py
@@ -17,18 +17,7 @@
import copy
-import ipapython.ipautil
-
-def utf8_encode_value(value):
- if isinstance(value,unicode):
- return value.encode('utf-8')
- return value
-
-def utf8_encode_values(values):
- if isinstance(values,list) or isinstance(values,tuple):
- return map(utf8_encode_value, values)
- else:
- return utf8_encode_value(values)
+from ipapython import ipautil
def copy_CIDict(x):
"""Do a deep copy of a CIDict"""
@@ -55,19 +44,19 @@ class Entity:
if entrydata:
if isinstance(entrydata,tuple):
self.dn = entrydata[0]
- self.data = ipapython.ipautil.CIDict(entrydata[1])
+ self.data = ipautil.CIDict(entrydata[1])
elif isinstance(entrydata,str) or isinstance(entrydata,unicode):
self.dn = entrydata
- self.data = ipapython.ipautil.CIDict()
+ self.data = ipautil.CIDict()
elif isinstance(entrydata,dict):
self.dn = entrydata['dn']
del entrydata['dn']
- self.data = ipapython.ipautil.CIDict(entrydata)
+ self.data = ipautil.CIDict(entrydata)
else:
self.dn = ''
- self.data = ipapython.ipautil.CIDict()
+ self.data = ipautil.CIDict()
- self.orig_data = ipapython.ipautil.CIDict(copy_CIDict(self.data))
+ self.orig_data = ipautil.CIDict(copy_CIDict(self.data))
def __nonzero__(self):
"""This allows us to do tests like if entry: returns false if there is no data,
@@ -120,9 +109,9 @@ class Entity:
if (len(value) < 1):
return
if (len(value) == 1):
- self.data[name] = utf8_encode_values(value[0])
+ self.data[name] = ipautil.utf8_encode_values(value[0])
else:
- self.data[name] = utf8_encode_values(value)
+ self.data[name] = ipautil.utf8_encode_values(value)
setValues = setValue
@@ -161,7 +150,7 @@ class Entity:
def toDict(self):
"""Convert the attrs and values to a dict. The dict is keyed on the
attribute name. The value is either single value or a list of values."""
- result = ipapython.ipautil.CIDict(self.data)
+ result = ipautil.CIDict(self.data)
result['dn'] = self.dn
return result
@@ -171,7 +160,7 @@ class Entity:
def origDataDict(self):
"""Returns a dict of the original values of the user. Used for updates."""
- result = ipapython.ipautil.CIDict(self.orig_data)
+ result = ipautil.CIDict(self.orig_data)
result['dn'] = self.dn
return result
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 69c328934..4a9db11e2 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -195,6 +195,7 @@ def format_netloc(host, port=None):
return '%s:%s' % (host, str(port))
def realm_to_suffix(realm_name):
+ """Convert a kerberos realm into the IPA suffix."""
s = realm_name.split(".")
terms = ["dc=" + x.lower() for x in s]
return ",".join(terms)
@@ -406,32 +407,32 @@ class CIDict(dict):
If you extend UserDict, isinstance(foo, dict) returns false.
"""
- def __init__(self,default=None):
+ def __init__(self, default=None):
super(CIDict, self).__init__()
self._keys = {}
self.update(default or {})
- def __getitem__(self,key):
- return super(CIDict,self).__getitem__(string.lower(key))
+ def __getitem__(self, key):
+ return super(CIDict, self).__getitem__(key.lower())
- def __setitem__(self,key,value):
- lower_key = string.lower(key)
+ def __setitem__(self, key, value):
+ lower_key = key.lower()
self._keys[lower_key] = key
- return super(CIDict,self).__setitem__(string.lower(key),value)
+ return super(CIDict, self).__setitem__(lower_key, value)
- def __delitem__(self,key):
- lower_key = string.lower(key)
+ def __delitem__(self, key):
+ lower_key = key.lower()
del self._keys[lower_key]
- return super(CIDict,self).__delitem__(string.lower(key))
+ return super(CIDict, self).__delitem__(key.lower())
- def update(self,dict):
+ def update(self, dict):
for key in dict.keys():
self[key] = dict[key]
- def has_key(self,key):
- return super(CIDict, self).has_key(string.lower(key))
+ def has_key(self, key):
+ return super(CIDict, self).has_key(key.lower())
- def get(self,key,failobj=None):
+ def get(self, key, failobj=None):
try:
return self[key]
except KeyError:
@@ -443,7 +444,7 @@ class CIDict(dict):
def items(self):
result = []
for k in self._keys.values():
- result.append((k,self[k]))
+ result.append((k, self[k]))
return result
def copy(self):
@@ -458,7 +459,7 @@ class CIDict(dict):
def iterkeys(self):
return self.copy().iterkeys()
- def setdefault(self,key,value=None):
+ def setdefault(self, key, value=None):
try:
return self[key]
except KeyError:
@@ -476,11 +477,11 @@ class CIDict(dict):
raise
def popitem(self):
- (lower_key,value) = super(CIDict,self).popitem()
+ (lower_key, value) = super(CIDict, self).popitem()
key = self._keys[lower_key]
del self._keys[lower_key]
- return (key,value)
+ return (key, value)
class GeneralizedTimeZone(datetime.tzinfo):
@@ -610,118 +611,17 @@ def ipa_generate_password(characters=None,pwd_len=None):
rndpwd += rndchar
return rndpwd
-def format_list(items, quote=None, page_width=80):
- '''Format a list of items formatting them so they wrap to fit the
- available width. The items will be sorted.
+def parse_items(text):
+ '''Given text with items separated by whitespace or comma, return a list of those items
- The items may optionally be quoted. The quote parameter may either be
- a string, in which case it is added before and after the item. Or the
- quote parameter may be a pair (either a tuple or list). In this case
- quote[0] is left hand quote and quote[1] is the right hand quote.
- '''
- left_quote = right_quote = ''
- num_items = len(items)
- if not num_items: return ""
-
- if quote is not None:
- if type(quote) in StringTypes:
- left_quote = right_quote = quote
- elif type(quote) is TupleType or type(quote) is ListType:
- left_quote = quote[0]
- right_quote = quote[1]
-
- max_len = max(map(len, items))
- max_len += len(left_quote) + len(right_quote)
- num_columns = (page_width + max_len) / (max_len+1)
- num_rows = (num_items + num_columns - 1) / num_columns
- items.sort()
-
- rows = [''] * num_rows
- i = row = col = 0
-
- while i < num_items:
- row = 0
- if col == 0:
- separator = ''
- else:
- separator = ' '
-
- while i < num_items and row < num_rows:
- rows[row] += "%s%*s" % (separator, -max_len, "%s%s%s" % (left_quote, items[i], right_quote))
- i += 1
- row += 1
- col += 1
- return '\n'.join(rows)
-
-key_value_re = re.compile("(\w+)\s*=\s*(([^\s'\\\"]+)|(?P<quote>['\\\"])((?P=quote)|(.*?[^\\\])(?P=quote)))")
-def parse_key_value_pairs(input):
- ''' Given a string composed of key=value pairs parse it and return
- a dict of the key/value pairs. Keys must be a word, a key must be followed
- by an equal sign (=) and a value. The value may be a single word or may be
- quoted. Quotes may be either single or double quotes, but must be balanced.
- Inside the quoted text the same quote used to start the quoted value may be
- used if it is escaped by preceding it with a backslash (\).
- White space between the key, the equal sign, and the value is ignored.
- Values are always strings. Empty values must be specified with an empty
- quoted string, it's value after parsing will be an empty string.
-
- Example: The string
-
- arg0 = '' arg1 = 1 arg2='two' arg3 = "three's a crowd" arg4 = "this is a \" quote"
-
- will produce
-
- arg0= arg1=1
- arg2=two
- arg3=three's a crowd
- arg4=this is a " quote
+ The returned list only contains non-empty items.
'''
-
- kv_dict = {}
- for match in key_value_re.finditer(input):
- key = match.group(1)
- quote = match.group('quote')
- if match.group(5):
- value = match.group(6)
- if value is None: value = ''
- value = re.sub('\\\%s' % quote, quote, value)
- else:
- value = match.group(2)
- kv_dict[key] = value
- return kv_dict
-
-def parse_items(text):
- '''Given text with items separated by whitespace or comma, return a list of those items'''
split_re = re.compile('[ ,\t\n]+')
items = split_re.split(text)
for item in items[:]:
if not item: items.remove(item)
return items
-def read_pairs_file(filename):
- comment_re = re.compile('#.*$', re.MULTILINE)
- if filename == '-':
- fd = sys.stdin
- else:
- fd = open(filename)
- text = fd.read()
- text = comment_re.sub('', text) # kill comments
- pairs = parse_key_value_pairs(text)
- if fd != sys.stdin: fd.close()
- return pairs
-
-def read_items_file(filename):
- comment_re = re.compile('#.*$', re.MULTILINE)
- if filename == '-':
- fd = sys.stdin
- else:
- fd = open(filename)
- text = fd.read()
- text = comment_re.sub('', text) # kill comments
- items = parse_items(text)
- if fd != sys.stdin: fd.close()
- return items
-
def user_input(prompt, default = None, allow_empty = True):
if default == None:
while True:
@@ -761,357 +661,6 @@ def user_input(prompt, default = None, allow_empty = True):
else:
return ret
-def user_input_plain(prompt, default = None, allow_empty = True, allow_spaces = True):
- while True:
- ret = user_input(prompt, default, allow_empty)
- if ipavalidate.Plain(ret, not allow_empty, allow_spaces):
- return ret
-
-class AttributeValueCompleter:
- '''
- Gets input from the user in the form "lhs operator rhs"
- TAB completes partial input.
- lhs completes to a name in @lhs_names
- The lhs is fully parsed if a lhs_delim delimiter is seen, then TAB will
- complete to the operator and a default value.
- Default values for a lhs value can specified as:
- - a string, all lhs values will use this default
- - a dict, the lhs value is looked up in the dict to return the default or None
- - a function with a single arg, the lhs value, it returns the default or None
-
- After creating the completer you must open it to set the terminal
- up, Then get a line of input from the user by calling read_input()
- which returns two values, the lhs and rhs, which might be None if
- lhs or rhs was not parsed. After you are done getting input you
- should close the completer to restore the terminal.
-
- Example: (note this is essentially what the convenience function get_pairs() does)
-
- This will allow the user to autocomplete foo & foobar, both have
- defaults defined in a dict. In addition the foobar attribute must
- be specified before the prompting loop will exit. Also, this
- example show how to require that each attrbute entered by the user
- is valid.
-
- attrs = ['foo', 'foobar']
- defaults = {'foo' : 'foo_default', 'foobar' : 'foobar_default'}
- mandatory_attrs = ['foobar']
-
- c = AttributeValueCompleter(attrs, defaults)
- c.open()
- mandatory_attrs_remaining = mandatory_attrs[:]
-
- while True:
- if mandatory_attrs_remaining:
- attribute, value = c.read_input("Enter: ", mandatory_attrs_remaining[0])
- try:
- mandatory_attrs_remaining.remove(attribute)
- except ValueError:
- pass
- else:
- attribute, value = c.read_input("Enter: ")
- if attribute is None:
- # Are we done?
- if mandatory_attrs_remaining:
- print "ERROR, you must specify: %s" % (','.join(mandatory_attrs_remaining))
- continue
- else:
- break
- if attribute not in attrs:
- print "ERROR: %s is not a valid attribute" % (attribute)
- else:
- print "got '%s' = '%s'" % (attribute, value)
-
- c.close()
- print "exiting..."
- '''
-
- def __init__(self, lhs_names, default_value=None, lhs_regexp=r'^\s*(?P<lhs>[^ =]+)', lhs_delims=' =',
- operator='=', strip_rhs=True):
- self.lhs_names = lhs_names
- self.default_value = default_value
- # lhs_regexp must have named group 'lhs' which returns the contents of the lhs
- self.lhs_regexp = lhs_regexp
- self.lhs_re = re.compile(self.lhs_regexp)
- self.lhs_delims = lhs_delims
- self.operator = operator
- self.strip_rhs = strip_rhs
- self.pairs = None
- self._reset()
-
- def _reset(self):
- self.lhs = None
- self.lhs_complete = False
- self.operator_complete = False
- self.rhs = None
-
- def open(self):
- # Save state
- self.prev_completer = readline.get_completer()
- self.prev_completer_delims = readline.get_completer_delims()
-
- # Set up for ourself
- readline.parse_and_bind("tab: complete")
- readline.set_completer(self.complete)
- readline.set_completer_delims(self.lhs_delims)
-
- def close(self):
- # Restore previous state
- readline.set_completer_delims(self.prev_completer_delims)
- readline.set_completer(self.prev_completer)
-
- def parse_input(self):
- '''We are looking for 3 tokens: <lhs,op,rhs>
- Extract as much of each token as possible.
- Set flags indicating if token is fully parsed.
- '''
- try:
- self._reset()
- buf_len = len(self.line_buffer)
- pos = 0
- lhs_match = self.lhs_re.search(self.line_buffer, pos)
- if not lhs_match: return # no lhs content
- self.lhs = lhs_match.group('lhs') # get lhs contents
- pos = lhs_match.end('lhs') # new scanning position
- if pos == buf_len: return # nothing after lhs, lhs incomplete
- self.lhs_complete = True # something trails the lhs, lhs is complete
- operator_beg = self.line_buffer.find(self.operator, pos) # locate operator
- if operator_beg == -1: return # did not find the operator
- self.operator_complete = True # operator fully parsed
- operator_end = operator_beg + len(self.operator)
- pos = operator_end # step over the operator
- self.rhs = self.line_buffer[pos:]
- except Exception, e:
- traceback.print_exc()
- print "Exception in %s.parse_input(): %s" % (self.__class__.__name__, e)
-
- def get_default_value(self):
- '''default_value can be a string, a dict, or a function.
- If it's a string it's a global default for all attributes.
- If it's a dict the default is looked up in the dict index by attribute.
- If it's a function, the function is called with 1 parameter, the attribute
- and it should return the default value for the attriubte or None'''
-
- if not self.lhs_complete: raise ValueError("attribute not parsed")
-
- # If the user previously provided a value let that override the supplied default
- if self.pairs is not None:
- prev_value = self.pairs.get(self.lhs)
- if prev_value is not None: return prev_value
-
- # No previous user provided value, query for a default
- default_value_type = type(self.default_value)
- if default_value_type is DictType:
- return self.default_value.get(self.lhs, None)
- elif default_value_type is FunctionType:
- return self.default_value(self.lhs)
- elif default_value_type is StringType:
- return self.default_value
- else:
- return None
-
- def get_lhs_completions(self, text):
- if text:
- self.completions = [lhs for lhs in self.lhs_names if lhs.startswith(text)]
- else:
- self.completions = self.lhs_names
-
- def complete(self, state):
- self.line_buffer= readline.get_line_buffer()
- self.parse_input()
- if not self.lhs_complete:
- # lhs is not complete, set up to complete the lhs
- if state == 0:
- beg = readline.get_begidx()
- end = readline.get_endidx()
- self.get_lhs_completions(self.line_buffer[beg:end])
- if state >= len(self.completions): return None
- return self.completions[state]
-
-
- elif not self.operator_complete:
- # lhs is complete, but the operator is not so we complete
- # by inserting the operator manually.
- # Also try to complete the default value at this time.
- readline.insert_text('%s ' % self.operator)
- default_value = self.get_default_value()
- if default_value is not None:
- readline.insert_text(default_value)
- readline.redisplay()
- return None
- else:
- # lhs and operator are complete, if the rhs is blank
- # (either empty or only only whitespace) then attempt
- # to complete by inserting the default value, otherwise
- # there is nothing we can complete to so we're done.
- if self.rhs.strip():
- return None
- default_value = self.get_default_value()
- if default_value is not None:
- readline.insert_text(default_value)
- readline.redisplay()
- return None
-
- def pre_input_hook(self):
- readline.insert_text('%s %s ' % (self.initial_lhs, self.operator))
- readline.redisplay()
-
- def read_input(self, prompt, initial_lhs=None):
- self.initial_lhs = initial_lhs
- try:
- self._reset()
- if initial_lhs is None:
- readline.set_pre_input_hook(None)
- else:
- readline.set_pre_input_hook(self.pre_input_hook)
- self.line_buffer = raw_input(prompt).strip()
- self.parse_input()
- if self.strip_rhs and self.rhs is not None:
- return self.lhs, self.rhs.strip()
- else:
- return self.lhs, self.rhs
- except EOFError:
- return None, None
-
- def get_pairs(self, prompt, mandatory_attrs=None, validate_callback=None, must_match=True, value_required=True):
- self.pairs = {}
- if mandatory_attrs:
- mandatory_attrs_remaining = mandatory_attrs[:]
- else:
- mandatory_attrs_remaining = []
-
- print "Enter name = value"
- print "Press <ENTER> to accept, a blank line terminates input"
- print "Pressing <TAB> will auto completes name, assignment, and value"
- print
- while True:
- if mandatory_attrs_remaining:
- attribute, value = self.read_input(prompt, mandatory_attrs_remaining[0])
- else:
- attribute, value = self.read_input(prompt)
- if attribute is None:
- # Are we done?
- if mandatory_attrs_remaining:
- print "ERROR, you must specify: %s" % (','.join(mandatory_attrs_remaining))
- continue
- else:
- break
- if value is None:
- if value_required:
- print "ERROR: you must specify a value for %s" % attribute
- continue
- else:
- if must_match and attribute not in self.lhs_names:
- print "ERROR: %s is not a valid name" % (attribute)
- continue
- if validate_callback is not None:
- if not validate_callback(attribute, value):
- print "ERROR: %s is not valid for %s" % (value, attribute)
- continue
- try:
- mandatory_attrs_remaining.remove(attribute)
- except ValueError:
- pass
-
- self.pairs[attribute] = value
- return self.pairs
-
-class ItemCompleter:
- '''
- Prompts the user for items in a list of items with auto completion.
- TAB completes partial input.
- More than one item can be specifed during input, whitespace and/or comma's seperate.
- Example:
-
- possible_items = ['foo', 'bar']
- c = ItemCompleter(possible_items)
- c.open()
- # Use read_input() to limit input to a single carriage return (e.g. <ENTER>)
- #items = c.read_input("Enter: ")
- # Use get_items to iterate until a blank line is entered.
- items = c.get_items("Enter: ")
- c.close()
- print "items=%s" % (items)
-
- '''
-
- def __init__(self, items):
- self.items = items
- self.initial_input = None
- self.item_delims = ' \t,'
- self.operator = '='
- self.split_re = re.compile('[%s]+' % self.item_delims)
-
- def open(self):
- # Save state
- self.prev_completer = readline.get_completer()
- self.prev_completer_delims = readline.get_completer_delims()
-
- # Set up for ourself
- readline.parse_and_bind("tab: complete")
- readline.set_completer(self.complete)
- readline.set_completer_delims(self.item_delims)
-
- def close(self):
- # Restore previous state
- readline.set_completer_delims(self.prev_completer_delims)
- readline.set_completer(self.prev_completer)
-
- def get_item_completions(self, text):
- if text:
- self.completions = [lhs for lhs in self.items if lhs.startswith(text)]
- else:
- self.completions = self.items
-
- def complete(self, state):
- self.line_buffer= readline.get_line_buffer()
- if state == 0:
- beg = readline.get_begidx()
- end = readline.get_endidx()
- self.get_item_completions(self.line_buffer[beg:end])
- if state >= len(self.completions): return None
- return self.completions[state]
-
- def pre_input_hook(self):
- readline.insert_text('%s %s ' % (self.initial_input, self.operator))
- readline.redisplay()
-
- def read_input(self, prompt, initial_input=None):
- items = []
-
- self.initial_input = initial_input
- try:
- if initial_input is None:
- readline.set_pre_input_hook(None)
- else:
- readline.set_pre_input_hook(self.pre_input_hook)
- self.line_buffer = raw_input(prompt).strip()
- items = self.split_re.split(self.line_buffer)
- for item in items[:]:
- if not item: items.remove(item)
- return items
- except EOFError:
- return items
-
- def get_items(self, prompt, must_match=True):
- items = []
-
- print "Enter name [name ...]"
- print "Press <ENTER> to accept, blank line or control-D terminates input"
- print "Pressing <TAB> auto completes name"
- print
- while True:
- new_items = self.read_input(prompt)
- if not new_items: break
- for item in new_items:
- if must_match:
- if item not in self.items:
- print "ERROR: %s is not valid" % (item)
- continue
- if item in items: continue
- items.append(item)
-
- return items
def get_gsserror(e):
"""
@@ -1446,3 +995,16 @@ def make_sshfp(key):
else:
return
return '%d 1 %s' % (algo, fp)
+
+
+def utf8_encode_value(value):
+ if isinstance(value, unicode):
+ return value.encode('utf-8')
+ return value
+
+
+def utf8_encode_values(values):
+ if isinstance(values, list) or isinstance(values, tuple):
+ return map(utf8_encode_value, values)
+ else:
+ return utf8_encode_value(values)
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index ce3166122..fa3864a22 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -395,7 +395,7 @@ class BindInstance(service.Service):
self.domain = domain_name
self.forwarders = forwarders
self.host = fqdn.split(".")[0]
- self.suffix = util.realm_to_suffix(self.realm)
+ self.suffix = ipautil.realm_to_suffix(self.realm)
self.ntp = ntp
self.reverse_zone = reverse_zone
self.zone_refresh = zone_refresh
@@ -614,7 +614,7 @@ class BindInstance(service.Service):
self.realm = realm_name
self.domain = domain_name
self.host = fqdn.split(".")[0]
- self.suffix = util.realm_to_suffix(self.realm)
+ self.suffix = ipautil.realm_to_suffix(self.realm)
self.ntp = ntp
self.reverse_zone = reverse_zone
@@ -622,7 +622,7 @@ class BindInstance(service.Service):
def remove_master_dns_records(self, fqdn, realm_name, domain_name):
host = fqdn.split(".")[0]
- suffix = util.realm_to_suffix(realm_name)
+ suffix = ipautil.realm_to_suffix(realm_name)
zone = domain_name
resource_records = (
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 56b84fcd8..af8d39aa5 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -240,7 +240,7 @@ class CADSInstance(service.Service):
if host_name and realm_name:
self.principal = "dogtagldap/%s@%s" % (self.fqdn, self.realm_name)
if realm_name:
- self.suffix = util.realm_to_suffix(self.realm_name)
+ self.suffix = ipautil.realm_to_suffix(self.realm_name)
self.__setup_sub_dict()
else:
self.suffix = None
@@ -250,7 +250,7 @@ class CADSInstance(service.Service):
subject_base=None):
self.ds_port = ds_port
self.realm_name = realm_name.upper()
- self.suffix = util.realm_to_suffix(self.realm_name)
+ self.suffix = ipautil.realm_to_suffix(self.realm_name)
self.fqdn = host_name
self.dm_password = dm_password
self.domain = domain_name
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 827f69136..359d76664 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -167,7 +167,7 @@ class DsInstance(service.Service):
self.open_ports = []
self.run_init_memberof = True
if realm_name:
- self.suffix = util.realm_to_suffix(self.realm_name)
+ self.suffix = ipautil.realm_to_suffix(self.realm_name)
self.__setup_sub_dict()
else:
self.suffix = None
@@ -218,7 +218,7 @@ class DsInstance(service.Service):
hbac_allow=True):
self.realm_name = realm_name.upper()
self.serverid = realm_to_serverid(self.realm_name)
- self.suffix = util.realm_to_suffix(self.realm_name)
+ self.suffix = ipautil.realm_to_suffix(self.realm_name)
self.fqdn = fqdn
self.dm_password = dm_password
self.domain = domain_name
@@ -251,7 +251,7 @@ class DsInstance(service.Service):
domain_name, dm_password, pkcs12_info=None):
self.realm_name = realm_name.upper()
self.serverid = realm_to_serverid(self.realm_name)
- self.suffix = util.realm_to_suffix(self.realm_name)
+ self.suffix = ipautil.realm_to_suffix(self.realm_name)
self.master_fqdn = master_fqdn
self.fqdn = fqdn
self.dm_password = dm_password
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index e1bbc30a1..a14115115 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -62,7 +62,7 @@ class HTTPInstance(service.Service):
self.realm = realm
self.domain = domain_name
self.dm_password = dm_password
- self.suffix = util.realm_to_suffix(self.realm)
+ self.suffix = ipautil.realm_to_suffix(self.realm)
self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca
self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm)
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index f38ae9b42..2faf8e196 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -132,7 +132,7 @@ class KrbInstance(service.Service):
self.host = host_name.split(".")[0]
self.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM)[0][4][0]
self.domain = domain_name
- self.suffix = util.realm_to_suffix(self.realm)
+ self.suffix = ipautil.realm_to_suffix(self.realm)
self.kdc_password = ipautil.ipa_generate_password()
self.admin_password = admin_password
self.dm_password = admin_password
diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index 90b3691a8..e803df8a2 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -79,7 +79,7 @@ class LDAPUpdate:
krbctx = krbV.default_context()
try:
self.realm = krbctx.default_realm
- suffix = util.realm_to_suffix(self.realm)
+ suffix = ipautil.realm_to_suffix(self.realm)
except krbV.Krb5Error:
self.realm = None
suffix = None
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index c8c5bc139..ed4caeb7b 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -105,7 +105,7 @@ class ReplicationManager(object):
self.dirman_passwd = dirman_passwd
self.realm = realm
self.starttls = starttls
- tmp = util.realm_to_suffix(realm)
+ tmp = ipautil.realm_to_suffix(realm)
self.suffix = str(DN(tmp)).lower()
self.need_memberof_fixup = False
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 7174072a6..23279aa0b 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -34,7 +34,7 @@ import ldap.sasl
import ldapurl
from ldap.controls import LDAPControl
from ldap.ldapobject import SimpleLDAPObject
-from ipaserver import ipautil
+from ipapython import ipautil
from ipalib import errors
from ipapython.ipautil import format_netloc
from ipapython.entity import Entity
diff --git a/ipaserver/ipautil.py b/ipaserver/ipautil.py
deleted file mode 100644
index 311f50ec3..000000000
--- a/ipaserver/ipautil.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Authors: Simo Sorce <ssorce@redhat.com>
-#
-# Copyright (C) 2007 Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# 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 3 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/>.
-#
-
-import xmlrpclib
-import re
-
-def realm_to_suffix(realm_name):
- """
- Convert a kerberos realm into the IPA suffix.
- """
- s = realm_name.split(".")
- terms = ["dc=" + x.lower() for x in s]
- return ",".join(terms)
-
-class CIDict(dict):
- """
- Case-insensitive but case-respecting dictionary.
-
- This code is derived from python-ldap's cidict.py module,
- written by stroeder: http://python-ldap.sourceforge.net/
-
- This version extends 'dict' so it works properly with TurboGears.
- If you extend UserDict, isinstance(foo, dict) returns false.
- """
-
- def __init__(self, default=None):
- super(CIDict, self).__init__()
- self._keys = {}
- self.update(default or {})
-
- def __getitem__(self, key):
- return super(CIDict, self).__getitem__(key.lower())
-
- def __setitem__(self, key, value):
- lower_key = key.lower()
- self._keys[lower_key] = key
- return super(CIDict, self).__setitem__(lower_key, value)
-
- def __delitem__(self, key):
- lower_key = key.lower()
- del self._keys[lower_key]
- return super(CIDict, self).__delitem__(key.lower())
-
- def update(self, dict):
- for key in dict.keys():
- self[key] = dict[key]
-
- def has_key(self, key):
- return super(CIDict, self).has_key(key.lower())
-
- def get(self, key, failobj=None):
- try:
- return self[key]
- except KeyError:
- return failobj
-
- def keys(self):
- return self._keys.values()
-
- def items(self):
- result = []
- for k in self._keys.values():
- result.append((k, self[k]))
- return result
-
- def copy(self):
- copy = {}
- for k in self._keys.values():
- copy[k] = self[k]
- return copy
-
- def iteritems(self):
- return self.copy().iteritems()
-
- def iterkeys(self):
- return self.copy().iterkeys()
-
- def setdefault(self, key, value=None):
- try:
- return self[key]
- except KeyError:
- self[key] = value
- return value
-
- def pop(self, key, *args):
- try:
- value = self[key]
- del self[key]
- return value
- except KeyError:
- if len(args) == 1:
- return args[0]
- raise
-
- def popitem(self):
- (lower_key, value) = super(CIDict, self).popitem()
- key = self._keys[lower_key]
- del self._keys[lower_key]
-
- return (key, value)
-
-
-def get_gsserror(e):
- """A GSSError exception looks differently in python 2.4 than it does
- in python 2.5, deal with it."""
-
- try:
- primary = e[0]
- secondary = e[1]
- except Exception:
- primary = e[0][0]
- secondary = e[0][1]
-
- return (primary[0], secondary[0])
-
-def utf8_encode_value(value):
- if isinstance(value, unicode):
- return value.encode('utf-8')
- return value
-
-def utf8_encode_values(values):
- if isinstance(values, list) or isinstance(values, tuple):
- return map(utf8_encode_value, values)
- else:
- return utf8_encode_value(values)
diff --git a/ipaserver/plugins/join.py b/ipaserver/plugins/join.py
index 007336387..e7713dc06 100644
--- a/ipaserver/plugins/join.py
+++ b/ipaserver/plugins/join.py
@@ -21,11 +21,13 @@
Joining an IPA domain
"""
+import krbV
+
from ipalib import api, util
from ipalib import Command, Str
from ipalib import errors
-import krbV
from ipalib import _
+from ipaserver.install import installutils
def get_realm():
"""
@@ -52,7 +54,7 @@ class join(Command):
validate_host,
cli_name='hostname',
doc=_("The hostname to register as"),
- default_from=lambda: unicode(util.get_fqdn()),
+ default_from=lambda: unicode(installutils.get_fqdn()),
autofill=True,
#normalizer=lamda value: value.lower(),
),
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index 83c5c2d67..f9a549f4e 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -31,7 +31,7 @@ from ipalib.backend import Executioner
from ipalib.errors import PublicError, InternalError, CommandError, JSONError, ConversionError, CCacheError, RefererError, InvalidSessionPassword
from ipalib.request import context, Connection, destroy_context
from ipalib.rpc import xml_dumps, xml_loads
-from ipalib.util import make_repr, parse_time_duration
+from ipalib.util import parse_time_duration
from ipalib.dn import DN
from ipaserver.plugins.ldap2 import ldap2
from ipapython.compat import json
diff --git a/tests/test_ipalib/test_util.py b/tests/test_ipalib/test_util.py
index 8304d117b..9d19dfb2c 100644
--- a/tests/test_ipalib/test_util.py
+++ b/tests/test_ipalib/test_util.py
@@ -21,17 +21,6 @@
Test the `ipalib.util` module.
"""
-from tests.util import raises
from ipalib import util
-def test_make_repr():
- """
- Test the `ipalib.util.make_repr` function.
- """
- f = util.make_repr
- assert f('my') == 'my()'
- assert f('my', True, u'hello') == "my(True, u'hello')"
- assert f('my', one=1, two='two') == "my(one=1, two='two')"
- assert f('my', None, 3, dog='animal', apple='fruit') == \
- "my(None, 3, apple='fruit', dog='animal')"