summaryrefslogtreecommitdiffstats
path: root/source4/scripting/python
Commit message (Expand)AuthorAgeFilesLines
...
* s4: Exceptions in "provision.py"Michael Ströder2009-09-071-11/+15
* s4:Foreign security principals - Fix them upMatthias Dieter Wallnöfer2009-09-071-19/+0
* s4:provision - Change the module order to match Windows ServerMatthias Dieter Wallnöfer2009-09-071-1/+1
* s4:samldb - Major reworkMatthias Dieter Wallnöfer2009-09-071-32/+0
* s4:provision - Add a new delete function only for users and computersMatthias Dieter Wallnöfer2009-09-071-0/+25
* s4:setup: Use ms_display_specifiers script for provision.Andrew Kroeger2009-09-071-2/+5
* s4:setup: Added script to parse Microsoft DisplaySpecifiers document.Andrew Kroeger2009-09-071-0/+189
* s4:python fixed subunit tests of dcerpcAndrew Tridgell2009-09-046-0/+0
* allow setting of the debug level in python from CAndrew Tridgell2009-09-032-1/+14
* repl_meta_data should only be included when we are a DCAndrew Tridgell2009-09-021-1/+1
* move the repl_meta_data module up the ldb module stackAndrew Tridgell2009-09-021-1/+2
* s4: Create helpers functions related to provisionMatthieu Patou2009-08-281-17/+34
* s4:python Add helper to get at the domain SIDAndrew Bartlett2009-08-272-0/+33
* s4:provision Ensure that @OPTIONS is mirrored into each partitionAndrew Bartlett2009-08-261-0/+4
* s4:provison Add prefixes to ldb using same code a later modify will useAndrew Bartlett2009-08-263-5/+38
* s4:provision Only create references to our server DN after the self joinAndrew Bartlett2009-08-261-0/+10
* s4:python Fix the reprovision test by deleting 'deleted' objects too.Andrew Bartlett2009-08-251-6/+9
* fixed the buildAndrew Tridgell2009-08-171-3/+5
* s4: Major rework of the LDB/SAMDB/IDMAP python bindingsMatthias Dieter Wallnöfer2009-08-174-55/+57
* s4:pyglue Add a wrapper for loading the correct UTF8 casefolderMatthias Dieter Wallnöfer2009-08-171-0/+20
* Revert "s4:samdb python bindings - we don't need the attributes here"Matthias Dieter Wallnöfer2009-08-171-1/+2
* sigh - still not rightAndrew Tridgell2009-08-171-5/+5
* fixed up add_foreign againAndrew Tridgell2009-08-172-23/+23
* more fixups from provision changesAndrew Tridgell2009-08-172-24/+24
* fixed up some provision errors from the recent changesAndrew Tridgell2009-08-171-3/+2
* s4:provision Add comments to the provision scriptAndrew Bartlett2009-08-171-1/+10
* s4:provision Avoid one more call to ltdb_reindexAndrew Bartlett2009-08-172-6/+19
* s4:provision Fix existing ldapi:// backend detection exceptionAndrew Bartlett2009-08-171-1/+1
* s4:provision Make sure that we don't use Kerberos to our LDAP backendAndrew Bartlett2009-08-171-1/+3
* s4:provison Print the LDAP backend admin username/passwordAndrew Bartlett2009-08-171-6/+14
* s4: Re-add --ldapadminpass as an option to provisionAndrew Bartlett2009-08-171-5/+9
* s4:python Allow 'no such object' on the delete of the DNAndrew Bartlett2009-08-171-1/+5
* s4:provision Keep a single transaction for the erase and rebuildAndrew Bartlett2009-08-171-15/+6
* s4:provision Rework provision-backend into provisionAndrew Bartlett2009-08-171-618/+558
* s4:provision Move helper functions back to provisionAndrew Bartlett2009-08-171-21/+0
* s4:python Push some helper functions from SamDB into samba.LdbAndrew Bartlett2009-08-172-64/+57
* s4:schema Allow a schema load on an unconnected databaseAndrew Bartlett2009-08-171-1/+1
* s4:schema Provide a way to reference a loaded schema between ldbsAndrew Bartlett2009-08-172-5/+37
* s4:samdb python bindings - we don't need the attributes hereMatthias Dieter Wallnöfer2009-08-141-2/+1
* s4: Better way to call "dom_sid_to_rid" from ldap.pyMatthias Dieter Wallnöfer2009-08-141-0/+10
* s4:test for "primaryGroupToken"Matthias Dieter Wallnöfer2009-08-111-0/+23
* s4:provision Allow provision-backend to not run slapd for 'make test'Andrew Bartlett2009-08-121-22/+23
* s4:provision Make the --ol-slapd paramter take the full path to slapdAndrew Bartlett2009-08-121-2/+1
* s4:provision Rework and further automate setup of OpenLDAP backendOliver Liebel2009-08-121-35/+191
* s4: Simplify two lines in the "samdb.py" file (cosmetic)Matthias Dieter Wallnöfer2009-08-061-2/+1
* python: Cope with the dom_sid2 alias in pidl's python generating code.Jelmer Vernooij2009-07-301-2/+2
* DCE/RPC(Python): Rename py_talloc_import to py_talloc_steal.Jelmer Vernooij2009-07-301-1/+1
* s4:provision We no longer add krbtgt or kpasswd account into secrets.ldbAndrew Bartlett2009-07-291-1/+1
* s4:provision Fix provision on FreeBSDAndrew Bartlett2009-07-221-0/+1
* Re-add accidently removed shares test.Jelmer Vernooij2009-07-201-0/+74
n_missing_mod_i18n = 0 # Iterate over every command for cmd in api.Command(): cmd_class = cmd.__class__ # Skip commands marked as NO_CLI if getattr(cmd, 'NO_CLI', False): continue # Have we processed this module yet? if not modules.setdefault(cmd.module, 0): # First time seeing this module, validate the module contents mod = sys.modules[cmd.module] # See if there is a module topic, if so validate it topic = getattr(mod, 'topic', None) if topic is not None: if not is_i18n(topic[1]): src_file = inspect.getsourcefile(cmd_class) n_missing_mod_i18n += 1 print "%s: topic in module \"%s\" is not internationalized" % \ (src_file, cmd.module) # Does the module have documentation? if mod.__doc__ is None: src_file = inspect.getsourcefile(mod) n_missing_mod_doc += 1 print "%s: module \"%s\" has no doc" % \ (src_file, cmd.module) # Yes the module has doc, but is it internationalized? elif not is_i18n(mod.__doc__): src_file = inspect.getsourcefile(cmd_class) n_missing_mod_i18n += 1 print "%s: module \"%s\" doc is not internationalized" % \ (src_file, cmd.module) # Increment the count of how many commands in this module modules[cmd.module] = modules[cmd.module] + 1 # Does the command have documentation? if cmd.__doc__ is None: src_file = inspect.getsourcefile(cmd_class) line_num = inspect.getsourcelines(cmd_class)[1] n_missing_cmd_doc += 1 print "%s:%d command \"%s\" has no doc" % (src_file, line_num, cmd.name) # Yes the command has doc, but is it internationalized? elif not is_i18n(cmd.__doc__): src_file = inspect.getsourcefile(cmd_class) line_num = inspect.getsourcelines(cmd_class)[1] n_missing_cmd_i18n += 1 print "%s:%d command \"%s\" doc is not internationalized" % (src_file, line_num, cmd.name) # If any errors, emit summary information and adjust return value if n_missing_cmd_doc > 0 or n_missing_cmd_i18n > 0: rval = API_DOC_ERROR print "%d commands without doc, %d commands whose doc is not i18n" % \ (n_missing_cmd_doc, n_missing_cmd_i18n) if n_missing_mod_doc > 0 or n_missing_mod_i18n > 0: rval = API_DOC_ERROR print "%d modules without doc, %d modules whose doc is not i18n" % \ (n_missing_mod_doc, n_missing_mod_i18n) return rval def make_api(): """ Write a new API file from the current tree. """ fd = open(API_FILE, 'w') for cmd in api.Command(): fd.write('command: %s\n' % cmd.name) fd.write('args: %d,%d,%d\n' % (len(cmd.args), len(cmd.options), len(cmd.output))) for a in cmd.args(): fd.write('arg: %s\n' % param_repr(a)) for o in sorted(cmd.options(), key=operator.attrgetter('name')): fd.write('option: %s\n' % param_repr(o)) for o in sorted(cmd.output(), key=operator.attrgetter('name')): fd.write('output: %s\n' % param_repr(o)) for name, version in sorted( capabilities.items(), key=lambda (k, v): (v, k)): fd.write('capability: %s %s\n' % (name, version)) fd.close() return 0 def find_name(line): """ Break apart a Param line and pull out the name. It would be nice if we could just eval() the line but we wouldn't have defined any validators or normalizers it may be using. """ m = re.match('^[a-zA-Z0-9]+\(\'([a-z][_a-z0-9?\*\+]*)\'.*', line) if m: name = m.group(1) else: print "Couldn't find name in: %s" % line name = '' return name def _finalize_command_validation(cmd, found_args, expected_args, found_options, expected_options, found_output, expected_output): passed = True # Check the args of the previous command. if len(found_args) != expected_args: print 'Argument count in %s of %d doesn\'t match expected: %d' % ( cmd.name, len(found_args), expected_args) passed = False if len(found_options) != expected_options: print 'Options count in %s of %d doesn\'t match expected: %d' % ( cmd.name, len(found_options), expected_options) passed = False if len(found_output) != expected_output: print 'Output count in %s of %d doesn\'t match expected: %d' % ( cmd.name, len(found_output), expected_output) passed = False # Check if there is not a new arg/opt/output in previous command for a in cmd.args(): if a.param_spec not in found_args: print 'Argument %s of command %s in ipalib, not in API file:\n%s' % ( a.param_spec, cmd.name, param_repr(a)) passed = False for o in cmd.options(): if o.param_spec not in found_options: print 'Option %s of command %s in ipalib, not in API file:\n%s' % ( o.param_spec, cmd.name, param_repr(o)) passed = False for o in cmd.output(): if o.name not in found_output: print 'Output %s of command %s in ipalib, not in API file:\n%s' % ( o.name, cmd.name, param_repr(o)) passed = False return passed def validate_api(): """ Compare the API in the file to the one in ipalib. Return a bitwise return code to identify the types of errors found, if any. """ fd = open(API_FILE, 'r') lines = fd.readlines() fd.close() rval = 0 expected_args = 0 expected_options = 0 expected_output = 0 found_args = [] found_options = [] found_output = [] # First run through the file and compare it to the API existing_cmds = [] existing_capabilities = set() cmd = None for line in lines: line = line.strip() if line.startswith('command:'): if cmd: if not _finalize_command_validation(cmd, found_args, expected_args, found_options, expected_options, found_output, expected_output): rval |= API_FILE_DIFFERENCE (arg, name) = line.split(': ', 1) if name not in api.Command: print "Command %s in API file, not in ipalib" % name rval |= API_FILE_DIFFERENCE cmd = None else: existing_cmds.append(name) cmd = api.Command[name] found_args = [] found_options = [] found_output = [] if line.startswith('args:') and cmd: line = line.replace('args: ', '') (expected_args, expected_options, expected_output) = line.split(',') expected_args = int(expected_args) expected_options = int(expected_options) expected_output = int(expected_output) if line.startswith('arg:') and cmd: line = line.replace('arg: ', '') found = False arg = find_name(line) for a in cmd.args(): if param_repr(a) == line: found = True else: if a.name == arg: found = True print 'Arg in %s doesn\'t match.\nGot %s\nExpected %s' % ( name, param_repr(a), line) rval |= API_FILE_DIFFERENCE if found: found_args.append(arg) else: arg = find_name(line) print "Argument '%s' in command '%s' in API file not found" % (arg, name) rval |= API_FILE_DIFFERENCE if line.startswith('option:') and cmd: line = line.replace('option: ', '') found = False option = find_name(line) for o in cmd.options(): if param_repr(o) == line: found = True else: if o.name == option: found = True print 'Option in %s doesn\'t match. Got %s Expected %s' % (name, o, line) rval |= API_FILE_DIFFERENCE if found: found_options.append(option) else: option = find_name(line) print "Option '%s' in command '%s' in API file not found" % (option, name) rval |= API_FILE_DIFFERENCE if line.startswith('output:') and cmd: line = line.replace('output: ', '') found = False output = find_name(line) for o in cmd.output(): if param_repr(o) == line: found = True else: if o.name == output: found = True print 'Output in %s doesn\'t match. Got %s Expected %s' % (name, o, line) rval |= API_FILE_DIFFERENCE if found: found_output.append(output) else: output = find_name(line) print "Option '%s' in command '%s' in API file not found" % (output, name) rval |= API_FILE_DIFFERENCE if line.startswith('capability:'): cap, version = line.replace('capability: ', '').split(' ', 1) existing_capabilities.add(cap) try: expected_version = str(capabilities[cap]) except KeyError: print "Capability '%s' in API file not found" % cap rval |= API_FILE_DIFFERENCE else: if version != expected_version: print ( "Capability '%s' in API file doesn't match. Got %s, " "expected %s.") % (cap, version, expected_version) rval |= API_FILE_DIFFERENCE if cmd: if not _finalize_command_validation(cmd, found_args, expected_args, found_options, expected_options, found_output, expected_output): rval |= API_FILE_DIFFERENCE # Now look for new commands not in the current API for cmd in api.Command(): if cmd.name not in existing_cmds: print "Command %s in ipalib, not in API" % cmd.name rval |= API_NEW_COMMAND for cap in capabilities: if cap not in existing_capabilities: print "Capability %s in ipalib, not in API" % cap rval |= API_FILE_DIFFERENCE return rval def main(): rval = 0 options, args = parse_options() cfg = dict( context='cli', in_server=False, debug=False, verbose=0, validate_api=True, enable_ra=True, mode='developer', plugins_on_demand=False, ) api.bootstrap(**cfg) api.finalize() if options.validate_doc: rval |= validate_doc() if options.validate: if not os.path.exists(API_FILE): print 'No %s to validate' % API_FILE rval |= API_NO_FILE else: rval |= validate_api() else: print "Writing API to API.txt" rval |= make_api() if rval & API_FILE_DIFFERENCE: print '' print 'There are one or more changes to the API.\nEither undo the API changes or update API.txt and increment the major version in VERSION.' if rval & API_NEW_COMMAND: print '' print 'There are one or more new commands defined.\nUpdate API.txt and increment the minor version in VERSION.' if rval & API_DOC_ERROR: print '' print 'There are one or more documentation problems.\nYou must fix these before preceeding' return rval sys.exit(main())