def test_validate_file(self): prof = [ '<?xml version="1.0"?>', '<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">', '<service_bundle type="profile" name="SUNWtime-slider">', '<service name="system/filesystem/zfs/auto-snapshot"', ' type="service"', ' version="0.2.96">', ' <property_group name="general" type="framework">', ' <propval name="action_authorization" type="astring"', ' value="solaris.smf.manage.zfs-auto-snapshot" />', ' <propval name="value_authorization" type="astring"', ' value="solaris.smf.manage.zfs-auto-snapshot" />', ' </property_group>', '</service>', '</service_bundle>' ] prof_str = '' for i in prof: prof_str += i + '\n' (tfp, fname) = tempfile.mkstemp() os.write(tfp, prof_str) os.close(tfp) #these tests should succeed for both string and file self.assertTrue(sc.validate_profile_string(prof_str)) self.assertTrue(df.validate_file(fname, fname)) os.unlink(fname) prof_str += 'should cause failure' (tfp, fname) = tempfile.mkstemp() os.write(tfp, prof_str) os.close(tfp) #these tests should fail for both string and file self.assertRaises(lxml.etree.XMLSyntaxError, sc.validate_profile_string, prof_str) self.assertFalse(df.validate_file(fname, fname)) os.unlink(fname)
def test_validate_file(self): prof = [ '<?xml version="1.0"?>', '<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">', '<service_bundle type="profile" name="SUNWtime-slider">', '<service name="system/filesystem/zfs/auto-snapshot"', ' type="service"', ' version="0.2.96">', ' <property_group name="general" type="framework">', ' <propval name="action_authorization" type="astring"', ' value="solaris.smf.manage.zfs-auto-snapshot" />', ' <propval name="value_authorization" type="astring"', ' value="solaris.smf.manage.zfs-auto-snapshot" />', ' </property_group>', '</service>', '</service_bundle>'] prof_str = '' for i in prof: prof_str += i + '\n' (tfp, fname) = tempfile.mkstemp() os.write(tfp, prof_str) os.close(tfp) #these tests should succeed for both string and file self.assertTrue(sc.validate_profile_string(prof_str)) self.assertTrue(df.validate_file(fname, fname)) os.unlink(fname) prof_str += 'should cause failure' (tfp, fname) = tempfile.mkstemp() os.write(tfp, prof_str) os.close(tfp) #these tests should fail for both string and file self.assertRaises(lxml.etree.XMLSyntaxError, sc.validate_profile_string, prof_str) self.assertFalse(df.validate_file(fname, fname)) os.unlink(fname)
def validate_internal(profile_list, database, table, image_dir): ''' given a list of profile files and the profile database and table, validate the list of profiles Args: profile_list - list of profile path names database - name of database table - name of database table image_dir - path of service image, used to locate service_bundle Returns True if all profiles are valid, return False if any are invalid ''' # Open the database dbn = AIdb.DB(database, commit=True) dbn.verifyDBStructure() isvalid = True queue = dbn.getQueue() if not profile_list: profile_list = [None] for profile in profile_list: qstr = "SELECT name, file FROM %s WHERE name = %s" % \ (table, AIdb.format_value('name', profile)) query = AIdb.DBrequest(qstr, commit=True) queue.put(query) query.waitAns() # check response, if failure, getResponse prints error if query.getResponse() is None: # database error return False # give up if len(query.getResponse()) == 0: print >> sys.stderr, \ _('No profiles in database with basename ') + profile isvalid = False continue # to the next profile for response in query.getResponse(): if not df.validate_file(response[0], response[1], image_dir): isvalid = False return isvalid
def do_validate_profile(cmd_options=None): ''' external entry point for installadm Arg: cmd_options - command line options Effect: validate per command line ''' options = parse_options(cmd_options) isvalid = True # get AI service directory, database name service = AIService(options.service_name) image_dir = service.image.path dbname = service.database_path if options.profile_name: isvalid = validate_internal(options.profile_name, dbname, AIdb.PROFILES_TABLE, image_dir) if options.profile_path: # iterate through profile files on command line for fname in options.profile_path: if not df.validate_file(os.path.basename(fname), fname, image_dir): isvalid = False # return failure status if any profiles failed validation if not isvalid: sys.exit(1)
def do_update_profile(cmd_options=None): ''' Updates exisiting profile Arg: cmd_options - command line options Effect: update existing profile Raises SystemExit if condition cannot be handled ''' # check for authorization and euid try: check_auth_and_euid(PROFILE_AUTH) except UnauthorizedUserError as err: raise SystemExit(err) options = parse_options(DO_UPDATE, cmd_options) # verify the file profile_file = options.profile_file[0] if not os.path.exists(profile_file): raise SystemExit(_("Error:\tFile does not exist: %s\n") % profile_file) # get profile name if not options.profile_name: profile_name = os.path.basename(profile_file) else: profile_name = options.profile_name # get AI service image path and database name service = AIService(options.service_name) dbname = service.database_path image_dir = service.image.path # open database dbn = AIdb.DB(dbname, commit=True) dbn.verifyDBStructure() queue = dbn.getQueue() # Handle old DB versions which did not store a profile. if not AIdb.tableExists(queue, AIdb.PROFILES_TABLE): raise SystemExit( _("Error:\tService %s does not support profiles") % options.service_name) # check for the existence of profile missing_profile_error = _("Error:\tService {service} has no profile " "named {profile}.") if not sc.is_name_in_table(profile_name, queue, AIdb.PROFILES_TABLE): raise SystemExit( missing_profile_error.format(service=options.service_name, profile=profile_name)) # validates the profile and report the errors if found raw_profile = df.validate_file(profile_name, profile_file, image_dir, verbose=False) if not raw_profile: raise SystemExit(1) # create file from string and report failures tmp_profile_path = copy_profile_internally(raw_profile) if not tmp_profile_path: raise SystemExit(1) # get the path of profile in db q_str = "SELECT file FROM " + AIdb.PROFILES_TABLE + " WHERE name=" \ + AIdb.format_value('name', profile_name) query = AIdb.DBrequest(q_str) queue.put(query) query.waitAns() response = query.getResponse() # database error if response is None: raise SystemExit( missing_profile_error.format(service=options.service_name, profile=profile_name)) db_profile_path = response[0][0] # replace the file try: shutil.copyfile(tmp_profile_path, db_profile_path) except IOError as err: raise SystemExit( _("Error writing profile %(profile)s: %(err)s") % { 'profile': profile_name, 'err': err }) finally: os.unlink(tmp_profile_path) print >> sys.stderr, _("Profile updated successfully.")
def do_create_profile(cmd_options=None): ''' external entry point for installadm Arg: cmd_options - command line options Effect: add profiles to database per command line Raises SystemExit if condition cannot be handled ''' # check for authorization and euid try: check_auth_and_euid(PROFILE_AUTH) except UnauthorizedUserError as err: raise SystemExit(err) options = parse_options(DO_CREATE, cmd_options) # get AI service image path and database name service = AIService(options.service_name) image_dir = service.image.path dbname = service.database_path # open database dbn = AIdb.DB(dbname, commit=True) dbn.verifyDBStructure() queue = dbn.getQueue() root = None criteria_dict = dict() # Handle old DB versions which did not store a profile. if not AIdb.tableExists(queue, AIdb.PROFILES_TABLE): raise SystemExit( _("Error:\tService %s does not support profiles") % options.service_name) try: if options.criteria_file: # extract criteria from file root = df.verifyCriteria(df.DataFiles.criteriaSchema, options.criteria_file, dbn, AIdb.PROFILES_TABLE) elif options.criteria_c: # if we have criteria from cmd line, convert into dictionary criteria_dict = pub_man.criteria_to_dict(options.criteria_c) root = df.verifyCriteriaDict(df.DataFiles.criteriaSchema, criteria_dict, dbn, AIdb.PROFILES_TABLE) except ValueError as err: raise SystemExit(_("Error:\tcriteria error: %s") % err) # Instantiate a Criteria object with the XML DOM of the criteria. criteria = df.Criteria(root) sc.validate_criteria_from_user(criteria, dbn, AIdb.PROFILES_TABLE) # track exit status for all profiles, assuming no errors has_errors = False # loop through each profile on command line for profile_file in options.profile_file: # take option name either from command line or from basename of profile if options.profile_name: profile_name = options.profile_name else: profile_name = os.path.basename(profile_file) # check for any scope violations if sc.is_name_in_table(profile_name, queue, AIdb.PROFILES_TABLE): print >> sys.stderr, \ _("Error: A profile named %(name)s is already in the " "database for service %(service)s.") % \ {'name': profile_name, 'service': options.service_name} has_errors = True continue # open profile file specified by user on command line if not os.path.exists(profile_file): print >> sys.stderr, _("File %s does not exist") % profile_file has_errors = True continue # validates the profile and report errors if found raw_profile = df.validate_file(profile_name, profile_file, image_dir, verbose=False) if not raw_profile: has_errors = True continue # create file from profile string and report failures full_profile_path = copy_profile_internally(raw_profile) if not full_profile_path: has_errors = True continue # add new profile to database if not add_profile(criteria, profile_name, full_profile_path, queue, AIdb.PROFILES_TABLE): os.unlink(full_profile_path) # failure, back out internal profile has_errors = True # exit with status if any errors in any profiles if has_errors: sys.exit(1)