def get_package_path(server_id, pkg_spec, channel): log_debug(3, server_id, pkg_spec, channel) if isinstance(pkg_spec, ListType): pkg = pkg_spec[:4] #Insert EPOCH pkg.insert(1, None) else: pkg = parseRPMFilename(pkg_spec) if pkg is None: log_debug(4, "Error", "Requested weird package", pkg_spec) raise rhnFault(17, _("Invalid RPM package %s requested") % pkg_spec) statement = """ select p.id, p.path path, pe.epoch epoch from rhnPackageArch pa, rhnChannelPackage cp, rhnPackage p, rhnPackageEVR pe, rhnServerChannel sc, rhnPackageName pn, rhnChannel c where 1=1 and c.label = :channel and pn.name = :name and sc.server_id = :server_id and pe.version = :ver and pe.release = :rel and c.id = sc.channel_id and c.id = cp.channel_id and pa.label = :arch and pn.id = p.name_id and p.id = cp.package_id and p.evr_id = pe.id and sc.channel_id = cp.channel_id and p.package_arch_id = pa.id """ h = rhnSQL.prepare(statement) pkg = map(str, pkg) h.execute(name = pkg[0], ver = pkg[2], rel = pkg[3], arch = pkg[4], channel = channel, server_id = server_id) rs = h.fetchall_dict() if not rs: log_debug(4, "Error", "Non-existant package requested", server_id, pkg_spec, channel) raise rhnFault(17, _("Invalid RPM package %s requested") % pkg_spec) # It is unlikely for this query to return more than one row, # but it is possible # (having two packages with the same n, v, r, a and different epoch in # the same channel is prohibited by the RPM naming scheme; but extra # care won't hurt) max_row = rs[0] for each in rs[1:]: # Compare the epoch as string if _none2emptyString(each['epoch']) > _none2emptyString(max_row['epoch']): max_row = each # Set the flag for the proxy download accelerator rhnFlags.set("Download-Accelerator-Path", max_row['path']) return check_package_file(max_row['path'], max_row['id'], pkg_spec), max_row['id']
def auth_client(self, token): """ Authenticate a system based on the same authentication tokens the client is sending for GET requests """ log_debug(3) # Build a UserDictCase out of the token dict = UserDictCase(token) # Set rhnFlags so that we can piggyback on apacheAuth's auth_client rhnFlags.set('AUTH_SESSION_TOKEN', dict) # XXX To clean up apacheAuth.auth_client's logging, this is not about # GET requests result = apacheAuth.auth_client() if not result: raise rhnFault(33, _("Invalid session key")) log_debug(4, "Client auth OK") # We checked it already, so we're sure it's there client_id = dict['X-RHN-Server-Id'] server = rhnServer.search(client_id) if not server: raise rhnFault(8, _("This server ID no longer exists")) # XXX: should we check if the username still has access to it? # probably not, because there is no known good way we can # update the server system_id on the client side when # permissions change... Damn it. --gafton self.server = server self.server_id = client_id self.user = dict['X-RHN-Auth-User-Id'] return server
def set_client_capabilities(capabilities): if not capabilities: # No capabilities presented; don't set the global flag return caps = {} regexp = re.compile( r"^(?P<name>[^(]*)\((?P<version>[^)]*)\)\s*=\s*(?P<value>.*)$") for cap in capabilities: mo = regexp.match(cap) if not mo: # XXX Just ignoring it, for now continue dict = mo.groupdict() name = string.strip(dict['name']) version = string.strip(dict['version']) value = string.strip(dict['value']) caps[name] = { 'version': version, 'value': value, } rhnFlags.set('client-capabilities', caps) log_debug(4, "Client capabilities", caps)
def _repodata_python(self, file_name): log_debug(3, 'repodata', file_name) c_info = rhnChannel.channel_info(self.channelName) repo = repository.get_repository(c_info) output = None content_type = "application/x-gzip" if file_name == "repomd.xml": content_type = "text/xml" output = repo.get_repomd_file() elif file_name == "primary.xml.gz": output = repo.get_primary_xml_file() elif file_name == "other.xml.gz": output = repo.get_other_xml_file() elif file_name == "filelists.xml.gz": output = repo.get_filelists_xml_file() elif file_name == "updateinfo.xml.gz": output = repo.get_updateinfo_xml_file() elif file_name == "comps.xml": content_type = "text/xml" output = repo.get_comps_file() elif file_name == "modules.yaml": output = repo.get_modules_file() else: log_debug(2, "Unknown repomd file requested: %s" % file_name) raise rhnFault(6) output = rpclib.transports.File(output, name=file_name) rhnFlags.set('Content-Type', content_type) return output
def _repodata_taskomatic(self, file_name): log_debug(3, 'repodata', file_name) content_type = "application/x-gzip" if file_name in ["repomd.xml", "comps.xml"]: content_type = "text/xml" elif file_name not in ["primary.xml.gz", "other.xml.gz", "filelists.xml.gz", "updateinfo.xml.gz", "Packages.gz", "modules.yaml"]: log_debug(2, "Unknown repomd file requested: %s" % file_name) raise rhnFault(6) # XXX this won't be repconned or CDNd if file_name in ["comps.xml", "modules.yaml"]: return self._repodata_python(file_name) file_path = "%s/%s/%s" % (CFG.REPOMD_PATH_PREFIX, self.channelName, file_name) rhnFlags.set('Content-Type', content_type) try: rhnFlags.set('Download-Accelerator-Path', file_path) return self._getFile(CFG.REPOMD_CACHE_MOUNT_POINT + "/" + file_path) except IOError: e = sys.exc_info()[1] # For file not found, queue up a regen, and return 404 if e.errno == 2 and file_name != "comps.xml" and file_name != "modules.yaml": taskomatic.add_to_repodata_queue(self.channelName, "repodata request", file_name, bypass_filters=True) rhnSQL.commit() # This returns 404 to the client raise_with_tb(rhnFault(6), sys.exc_info()[2]) raise
def __init__(self, username=None, password=None, email=None, dbusername=None, dbpassword=None, dbhostname=None): #start_init = time.time() self.filesuploaded = False self.options = rhnConfig.initCFG( 'server' ) print self.options mytime = time.time() self.test_username = username or ("test_username_%.3f" % mytime) self.test_password = password or ("test_password_%.3f" % mytime) self.test_email = email or ("%s@test_domain.com" % self.test_username) self.dbusername = dbusername or 'rhnuser' self.dbpassword = dbpassword or 'rhnuser' self.dbhostname = dbhostname or 'webdev' self.channel_arch = 'unittestarch' self.roles = ['org_admin'] rhnFlags.set( 'outputTransportOptions', UserDictCase() ) self._init_db( self.dbusername, self.dbpassword, self.dbhostname ) self._init_org() self._init_user(self.roles) self._init_server() self._init_channels() self._init_up2date()
def get_function(self, function): if function not in self.functions: return None # Turn compression on by default rhnFlags.set('compress_response', 1) return getattr(self, self.functions[function])
def get_package_path(server_id, pkg_spec, channel): log_debug(3, server_id, pkg_spec, channel) if isinstance(pkg_spec, ListType): pkg = pkg_spec[:4] # Insert EPOCH pkg.insert(1, None) else: pkg = parseRPMFilename(pkg_spec) if pkg is None: log_debug(4, "Error", "Requested weird package", pkg_spec) raise rhnFault(17, _("Invalid RPM package %s requested") % pkg_spec) statement = """ select p.id, p.path path, pe.epoch epoch from rhnPackageArch pa, rhnChannelPackage cp, rhnPackage p, rhnPackageEVR pe, rhnServerChannel sc, rhnPackageName pn, rhnChannel c where 1=1 and c.label = :channel and pn.name = :name and sc.server_id = :server_id and pe.version = :ver and pe.release = :rel and c.id = sc.channel_id and c.id = cp.channel_id and pa.label = :arch and pn.id = p.name_id and p.id = cp.package_id and p.evr_id = pe.id and sc.channel_id = cp.channel_id and p.package_arch_id = pa.id """ h = rhnSQL.prepare(statement) pkg = list(map(str, pkg)) h.execute(name=pkg[0], ver=pkg[2], rel=pkg[3], arch=pkg[4], channel=channel, server_id=server_id) rs = h.fetchall_dict() if not rs: log_debug(4, "Error", "Non-existant package requested", server_id, pkg_spec, channel) raise rhnFault(17, _("Invalid RPM package %s requested") % pkg_spec) # It is unlikely for this query to return more than one row, # but it is possible # (having two packages with the same n, v, r, a and different epoch in # the same channel is prohibited by the RPM naming scheme; but extra # care won't hurt) max_row = rs[0] for each in rs[1:]: # Compare the epoch as string if _none2emptyString(each['epoch']) > _none2emptyString(max_row['epoch']): max_row = each # Set the flag for the proxy download accelerator rhnFlags.set("Download-Accelerator-Path", max_row['path']) return check_package_file(max_row['path'], max_row['id'], pkg_spec), max_row['id']
def _repodata_python(self, file_name): log_debug(3, 'repodata', file_name) c_info = rhnChannel.channel_info(self.channelName) repo = repository.get_repository(c_info) output = None content_type = "application/x-gzip" if file_name == "repomd.xml": content_type = "text/xml" output = repo.get_repomd_file() elif file_name == "primary.xml.gz": output = repo.get_primary_xml_file() elif file_name == "other.xml.gz": output = repo.get_other_xml_file() elif file_name == "filelists.xml.gz": output = repo.get_filelists_xml_file() elif file_name == "updateinfo.xml.gz": output = repo.get_updateinfo_xml_file() elif file_name == "comps.xml": content_type = "text/xml" output = repo.get_comps_file() else: log_debug(2, "Unknown repomd file requested: %s" % file_name) raise rhnFault(6) output = rpclib.transports.File(output, name=file_name) rhnFlags.set('Content-Type', content_type) return output
def _repodata_taskomatic(self, file_name): log_debug(3, 'repodata', file_name) content_type = "application/x-gzip" if file_name in ["repomd.xml", "comps.xml"]: content_type = "text/xml" elif file_name not in ["primary.xml.gz", "other.xml.gz", "filelists.xml.gz", "updateinfo.xml.gz", "Packages.gz"]: log_debug(2, "Unknown repomd file requested: %s" % file_name) raise rhnFault(6) # XXX this won't be repconned or CDNd if file_name == "comps.xml": return self._repodata_python(file_name) file_path = "%s/%s/%s" % (CFG.REPOMD_PATH_PREFIX, self.channelName, file_name) rhnFlags.set('Content-Type', content_type) try: rhnFlags.set('Download-Accelerator-Path', file_path) return self._getFile(CFG.REPOMD_CACHE_MOUNT_POINT + "/" + file_path) except IOError, e: # For file not found, queue up a regen, and return 404 if e.errno == 2 and file_name != "comps.xml": taskomatic.add_to_repodata_queue(self.channelName, "repodata request", file_name, bypass_filters=True) rhnSQL.commit() # This returns 404 to the client raise rhnFault(6), None, sys.exc_info()[2] raise
def set_client_capabilities(capabilities): if not capabilities: # No capabilities presented; don't set the global flag return caps = {} regexp = re.compile( r"^(?P<name>[^(]*)\((?P<version>[^)]*)\)\s*=\s*(?P<value>.*)$") for cap in capabilities: mo = regexp.match(cap) if not mo: # XXX Just ignoring it, for now continue dict = mo.groupdict() name = string.strip(dict['name']) version = string.strip(dict['version']) value = string.strip(dict['value']) caps[name] = { 'version' : version, 'value' : value, } rhnFlags.set('client-capabilities', caps) log_debug(4, "Client capabilities", caps)
def _repodata_taskomatic(self, file_name): log_debug(3, 'repodata', file_name) content_type = "application/x-gzip" if file_name.endswith(".xml"): content_type = "text/xml" elif file_name in ["repomd.xml.asc", "repomd.xml.key"]: content_type = "text/plain" elif file_name.endswith(".yaml"): content_type = "text/yaml" file_path = "%s/%s/%s" % (CFG.REPOMD_PATH_PREFIX, self.channelName, file_name) if file_name in ["comps.xml", "modules.yaml"]: # without checksum in the filename, they are only available in the old style return self._repodata_python(file_name) elif not os.path.exists(os.path.join(CFG.REPOMD_CACHE_MOUNT_POINT, file_path)): log_debug(2, "Unknown repomd file requested: %s" % file_name) raise rhnFault(6) rhnFlags.set('Content-Type', content_type) try: rhnFlags.set('Download-Accelerator-Path', file_path) return self._getFile(CFG.REPOMD_CACHE_MOUNT_POINT + "/" + file_path) except IOError: e = sys.exc_info()[1] # For file not found, queue up a regen, and return 404 if e.errno == 2: if file_name not in ["repomd.xml.key", "repomd.xml.asc"]: taskomatic.add_to_repodata_queue(self.channelName, "repodata request", file_name, bypass_filters=True) rhnSQL.commit() # This returns 404 to the client raise_with_tb(rhnFault(6), sys.exc_info()[2]) raise
def headerParserHandler(self, req): ret = basePackageUpload.BasePackageUpload.headerParserHandler( self, req) # Optional headers maps = [['Null-Org', 'null_org'], ['Packaging', 'packaging']] for hn, sn in maps: header_name = "%s-%s" % (self.header_prefix, hn) if req.headers_in.has_key(header_name): setattr(self, sn, req.headers_in[header_name]) if ret != apache.OK: return ret if CFG.SEND_MESSAGE_TO_ALL: rhnSQL.closeDB() log_debug(1, "send_message_to_all is set") rhnFlags.set("apache-return-code", apache.HTTP_NOT_FOUND) try: outage_message = open(CFG.MESSAGE_TO_ALL).read() except IOError: log_error("Missing outage message file") outage_message = "Outage mode" raise rhnFault(20001, outage_message, explain=0) # Init the database connection rhnSQL.initDB() use_session = 0 if self.field_data.has_key('Auth-Session'): session_token = self.field_data['Auth-Session'] use_session = 1 else: encoded_auth_token = self.field_data['Auth'] if not use_session: auth_token = self.get_auth_token(encoded_auth_token) if len(auth_token) < 2: log_debug(3, auth_token) raise rhnFault(105, "Unable to autenticate") self.username, self.password = auth_token[:2] force = self.field_data['Force'] force = int(force) log_debug(1, "Username", self.username, "Force", force) if use_session: self.org_id, self.force = rhnPackageUpload.authenticate_session( session_token, force=force, null_org=self.null_org) else: # We don't push to any channels self.org_id, self.force = rhnPackageUpload.authenticate( self.username, self.password, force=force, null_org=self.null_org) return apache.OK
def __init__(self): # We store the security list in the global flags. This way, we don't # have to worry about clearing it up. if rhnFlags.test(self._flag_string): self.sec = rhnFlags.get(self._flag_string) else: self.sec = [] rhnFlags.set(self._flag_string, self.sec)
def headerParserHandler(self, req): ret = basePackageUpload.BasePackageUpload.headerParserHandler(self, req) # Optional headers maps = [['Null-Org', 'null_org'], ['Packaging', 'packaging']] for hn, sn in maps: header_name = "%s-%s" % (self.header_prefix, hn) if req.headers_in.has_key(header_name): setattr(self, sn, req.headers_in[header_name]) if ret != apache.OK: return ret if CFG.SEND_MESSAGE_TO_ALL: rhnSQL.closeDB() log_debug(1, "send_message_to_all is set") rhnFlags.set("apache-return-code", apache.HTTP_NOT_FOUND) try: outage_message = open(CFG.MESSAGE_TO_ALL).read() except IOError: log_error("Missing outage message file") outage_message = "Outage mode" raise rhnFault(20001, outage_message, explain=0) # Init the database connection rhnSQL.initDB() use_session = 0 if self.field_data.has_key('Auth-Session'): session_token = self.field_data['Auth-Session'] use_session = 1 else: encoded_auth_token = self.field_data['Auth'] if not use_session: auth_token = self.get_auth_token(encoded_auth_token) if len(auth_token) < 2: log_debug(3, auth_token) raise rhnFault(105, "Unable to autenticate") self.username, self.password = auth_token[:2] force = self.field_data['Force'] force = int(force) log_debug(1, "Username", self.username, "Force", force) if use_session: self.org_id, self.force = rhnPackageUpload.authenticate_session(session_token, force=force, null_org=self.null_org) else: # We don't push to any channels self.org_id, self.force = rhnPackageUpload.authenticate(self.username, self.password, force=force, null_org=self.null_org) nevra = [self.package_name, "", self.package_version, self.package_release, self.package_arch] return apache.OK
def welcome_message(self, lang = None): """ returns string of welcome message """ log_debug(1, "lang: %s" % lang) if lang: cat.setlangs(lang) msg = _("Red Hat Satellite Welcome Message") # compress this one rhnFlags.set("compress_response", 1) return msg
def __local_GET_handler(self, req): """ GETs: authenticate user, and service local GETs. if not a local fetch, return None """ # Early test to check if this is a request the proxy can handle log_debug(2, 'request method: %s' % req.method) if req.method != "GET": # Don't know how to handle this return None (req_type, reqchannel, reqaction, reqparams) = self._split_url(req) if req_type is None or (req_type not in ['$RHN', 'GET-REQ']): # not a traditional RHN GET (i.e., it is an arbitrary get) # XXX: there has to be a more elegant way to do this return None # --- AUTH. CHECK: # Check client authentication. If not authenticated, throw # an exception. token = self.__getSessionToken() self.__checkAuthSessionTokenCache(token, reqchannel) # --- LOCAL GET: localFlist = CFG.PROXY_LOCAL_FLIST or [] # Can we serve this request? if not CFG.PKG_DIR: return None if reqaction not in localFlist: # Not an action we know how to handle return None # Is this channel local? for ch in self.authChannels: channel, _version, _isBaseChannel, isLocalChannel = ch[:4] if channel == reqchannel and str(isLocalChannel) == '1': # Local channel break else: # Not a local channel return None # We have a match; we'll try to serve packages from the local # repository log_debug(3, "Retrieve from local repository.") log_debug(3, reqchannel, reqaction, reqparams) result = self.__callLocalRepository(reqchannel, reqaction, reqparams) if result is None: log_debug(3, "Not available locally; will try higher up the chain.") else: # Signal that we have to XMLRPC encode the response in apacheHandler #log_debug(0, 'XXXXXXXXX result is not None XXXXXXXXXX') rhnFlags.set("NeedEncoding", 1) return result
def privacy_statement(self, lang = None): """ returns string of privacy statement """ log_debug(1, "lang: %s" % lang) if lang: cat.setlangs(lang) msg = _("Red Hat Satellite Privacy Statement") # compress this one rhnFlags.set("compress_response", 1) return msg
def register_system(client, minion): """ Adds a spacewalk registration for a minion. """ # ask for the minion data to get its id that tell us # if it is registered, and data to register it ret = client.cmd_iter(minion, GRAINS_ITEMS_CMD) for grains in ret: logger.info("Registering new minion: %s", minion) if minion in grains: values = grains[minion]['ret'] logger.debug("%s grains:\n%s", minion, pp.pformat(values)) username = client.cmd(minion, PILLAR_GET_CMD, [ADMIN_USER_PILLAR_KEY]) if not username[minion]: logger.error("Can't get admin user from pillar key '%s'", ADMIN_USER_PILLAR_KEY) continue user = rhnUser.search(username[minion]) rhnSQL.clear_log_id() newserv = rhnServer.Server(user, values['osarch']) token = client.cmd(minion, PILLAR_GET_CMD, [ACTIVATION_KEY_PILLAR_KEY]) if not token[minion]: tokens_obj = rhnServer.search_org_token(user.contact["org_id"]) rhnFlags.set("universal_registration_token", tokens_obj) else: tokens_obj = rhnServer.search_token(token[minion]) rhnFlags.set("registration_token", tokens_obj) # reserve the id newserv.getid() # overrite the digital id # FIXME: None of these values appear in the systems properties newserv.server['digital_server_id'] = 'SALT-ID-%s' % minion newserv.server['release'] = values['osrelease'] newserv.server['os'] = values['osfullname'] newserv.server['name'] = minion newserv.server['running_kernel'] = values['kernelrelease'] newserv.virt_uuid = None newserv.save() rhnSQL.commit() logger.info("%s registered as %s", minion, newserv.getid()) else: logger.error("Registration failed: Can't get grains for %s", minion)
def get_source_package_path(server_id, pkgFilename, channel): log_debug(3, server_id, pkgFilename, channel) rs = __query_source_package_path_by_name(server_id, pkgFilename, channel) if rs is None: log_debug(4, "Error", "Non-existant package requested", server_id, pkgFilename, channel) raise rhnFault(17, _("Invalid RPM package %s requested") % pkgFilename) # Set the flag for the proxy download accelerator rhnFlags.set("Download-Accelerator-Path", rs['path']) return check_package_file(rs['path'], pkgFilename, pkgFilename)
def _setSessionToken(headers): # extended to always return a token, even if an empty one ret = rhnApache._setSessionToken(headers) if ret: log_debug(4, "Returning", ret) return ret # Session token did not verify, we have an empty auth token token = UserDictCase() rhnFlags.set("AUTH_SESSION_TOKEN", token) return token
def header(self, system_id, pkgList): """ Clients v1- IN: system_id: .... a package identifier (or a list of them) [n,v,r,e] or [[n,v,r,e],...] OUT: If Proxy: If Client: """ log_debug(5, system_id, pkgList) if type(pkgList) not in (ListType, TupleType) or not len(pkgList): log_error("Invalid package list spec", type(pkgList), "len = %d" % len(pkgList)) raise rhnFault(30, _("Invalid value %s (type %s)") % ( pkgList, type(pkgList))) # Okay, it's a list; is it a list of lists? if type(pkgList[0]) is StringType: # Wrap it in a list pkgList = [pkgList] # Now check all params req_list = [] for p in pkgList: req_list.append(check_package_spec(p)) # Authenticate the system certificate server = self.auth_system('header', system_id) # log the entry log_debug(1, self.server_id, "items: %d" % len(req_list)) rpmHeaders = [] for pkg in pkgList: # Authorize this package fetch. # XXX: a bit heavy-handed I think... but old client stuff. # NOTE: pkg for old client is [n,v,r,e] path = rhnPackage.get_package_path_compat_arches( self.server_id, pkg, server.archname) # read the header from the file on disk h = rhn_rpm.get_package_header(filename=path) if h is None: log_error("Unable to read package header", pkg) raise rhnFault(17, _("Unable to retrieve package header %s") % str(pkg)) rpmHeaders.append(rpclib.xmlrpclib.Binary(h.unload())) del h # Reset the flag for the proxy download accelerator # This gets set by default in rhnPackage rhnFlags.set("Download-Accelerator-Path", None) if CFG.COMPRESS_HEADERS: # Compress rhnFlags.set("compress_response", 1) return rpmHeaders
def _set_proxy_info(self, req): """ Spacewalk Proxy stuff. """ proxyVersion = 'X-RHN-Proxy-Version' if proxyVersion in req.headers_in: self.proxyVersion = req.headers_in[proxyVersion] # Make sure the proxy version gets set in the headers. rhnFlags.get('outputTransportOptions')[proxyVersion] = str( self.proxyVersion) # Make sure the proxy auth-token gets set in global flags. if 'X-RHN-Proxy-Auth' in req.headers_in: rhnFlags.set('X-RHN-Proxy-Auth', req.headers_in['X-RHN-Proxy-Auth']) return apache.OK
def listAllPackagesKickstart(self, channel, system_id): """ Creates and/or serves up a cached copy of all the packages for this channel, including checksum information. """ log_debug(5, channel) # authenticate that this request is initiated from a proxy self.auth_system(system_id) packages = rhnChannel.list_all_packages_checksum(channel) # transport options... rhnFlags.set("compress_response", 1) return packages
def test_server_search(use_key=0): if use_key: user = None else: user = '******' u = rhnUser.search(user) s = rhnServer.Server(u, arch="athlon") s.server["release"] = "2.1AS" s.server["name"] = "test 1" if use_key: rhnFlags.set("registration_token", 'a02487cf77e72f86338f44212d23140d') s.save() print s.server["id"]
def _check_version(self): # Check the version version = self.rootAttributes.get("version") # Entitlement/certificate generation generation = self.rootAttributes.get("generation") rhnFlags.set("stream-generation", generation) if not version: version = "0" stream_version = list(map(int, version.split("."))) allowed_version = list(map(int, self.version.split("."))) if stream_version[0] != allowed_version[0] or stream_version[1] < allowed_version[1]: raise IncompatibleVersionError( version, self.version, "Incompatible stream version %s; code supports %s" % (version, self.version) )
def headerParserHandler(self, req): """ after a request has been received, first thing we do is to create the input object """ # pylint: disable=R0911 log_setreq(req) log_debug(3) self.start_time = time.time() # Decline if this is a subrequest: if req.main: return apache.DECLINED log_debug(4, req.method, req.path_info, req.headers_in) # Clear the global flags. rhnFlags.reset() # Init the transport options. rhnFlags.set('outputTransportOptions', UserDictCase()) # Init the session token dictionary. rhnFlags.set("AUTH_SESSION_TOKEN", UserDictCase()) ret = self._init_request_processor(req) if ret != apache.OK: return ret ret = self._set_client_info(req) if ret != apache.OK: return ret # Check the protocol version if req.proto_num < 1001: # HTTP protocols prior to 1.1 close the connection rhnFlags.get('outputTransportOptions')["Connection"] = "close" ret = self._set_proxy_info(req) if ret != apache.OK: return ret # Need to run _set_other first, since _set_lang needs RoodDir set ret = self._set_other(req) if ret != apache.OK: return ret ret = self._set_lang(req) if ret != apache.OK: return ret return apache.OK
def deploy_configs_if_needed(server): server_id = server['id'] log_debug(4, server_id) # determine if there are actually any files to be deployed... revisions = {} h = rhnSQL.prepare(_query_token_latest_revisions) h.execute(server_id=server_id) while 1: row = h.fetchone_dict() if not row: break # only care about the 1st revision of a particular path due to # sql ordering... if row['path'] not in revisions: revisions[row['path']] = row['revision_id'] if not len(revisions): return None # Get the latest action scheduled for this token last_action_id = rhnFlags.get('token_last_action_id') action_id = rhnAction.schedule_server_action( server_id, action_type='activation.schedule_deploy', action_name="Activation Key Config File Deployment", delta_time=0, scheduler=None, org_id=server['org_id'], prerequisite=last_action_id, ) # This action becomes the latest now rhnFlags.set('token_last_action_id', action_id) log_debug(4, "scheduled activation key config deploy") h = rhnSQL.prepare(_query_add_revision_to_action) # XXX should use executemany() or execute_bulk for revision_id in revisions.values(): log_debug(5, action_id, revision_id) h.execute(server_id=server_id, action_id=action_id, config_revision_id=revision_id) return action_id
def _check_version(self): # Check the version version = self.rootAttributes.get("version") # Entitlement/certificate generation generation = self.rootAttributes.get("generation") rhnFlags.set("stream-generation", generation) if not version: version = "0" stream_version = list(map(int, version.split('.'))) allowed_version = list(map(int, self.version.split("."))) if (stream_version[0] != allowed_version[0] or stream_version[1] < allowed_version[1]): raise IncompatibleVersionError(version, self.version, "Incompatible stream version %s; code supports %s" % ( version, self.version))
def headerParserHandler(self, req): log_setreq(req) # We need to init CFG and Logging options = req.get_options() # if we are initializing out of a <Location> handler don't # freak out if "RHNComponentType" not in options: # clearly nothing to do return apache.OK initCFG(options["RHNComponentType"]) initLOG(CFG.LOG_FILE, CFG.DEBUG) """ parse the request, init database and figure out what can we call """ log_debug(2, req.the_request) # call method from inherited class ret = apacheSession.headerParserHandler(self, req) if ret != apache.OK: return ret # make sure we have DB connection if not CFG.SEND_MESSAGE_TO_ALL: try: rhnSQL.initDB() except rhnSQL.SQLConnectError: rhnTB.Traceback(mail=1, req=req, severity="schema") return apache.HTTP_INTERNAL_SERVER_ERROR else: # If in outage mode, close the DB connections rhnSQL.closeDB() # Store client capabilities client_cap_header = 'X-RHN-Client-Capability' if client_cap_header in req.headers_in: client_caps = req.headers_in[client_cap_header] client_caps = [ _f for _f in list( map(string.strip, string.split(client_caps, ","))) if _f ] rhnCapability.set_client_capabilities(client_caps) # Enabling the input header flags associated with the redirects/newer clients redirect_support_flags = [ 'X-RHN-Redirect', 'X-RHN-Transport-Capability' ] for flag in redirect_support_flags: if flag in req.headers_in: rhnFlags.set(flag, str(req.headers_in[flag])) return apache.OK
def deploy_configs_if_needed(server): server_id = server['id'] log_debug(4, server_id) # determine if there are actually any files to be deployed... revisions = {} h = rhnSQL.prepare(_query_token_latest_revisions) h.execute(server_id=server_id) while 1: row = h.fetchone_dict() if not row: break # only care about the 1st revision of a particular path due to # sql ordering... if not revisions.has_key(row['path']): revisions[row['path']] = row['revision_id'] if not len(revisions): return None # Get the latest action scheduled for this token last_action_id = rhnFlags.get('token_last_action_id') action_id = rhnAction.schedule_server_action( server_id, action_type='activation.schedule_deploy', action_name="Activation Key Config File Deployment", delta_time=0, scheduler=None, org_id=server['org_id'], prerequisite=last_action_id, ) # This action becomes the latest now rhnFlags.set('token_last_action_id', action_id) log_debug(4, "scheduled activation key config deploy") h = rhnSQL.prepare(_query_add_revision_to_action) # XXX should use executemany() or execute_bulk for revision_id in revisions.values(): log_debug(5, action_id, revision_id) h.execute(server_id=server_id, action_id=action_id, config_revision_id=revision_id) return action_id
def getObsoletes(self, version): """ Returns a list of packages that obsolete other packages """ log_debug(3, self.channelName, version) # Check to see if the version they are requesting is the latest # check the validity of what the client thinks about this channel # or blow up self.__check_channel(version) obsoletes = rhnChannel.list_obsoletes(self.channelName) # Set the transport options transportOptions = rhnFlags.get('outputTransportOptions') transportOptions['Last-Modified'] = rfc822time(timestamp(version)) rhnFlags.set("compress_response", 1) return obsoletes
def _validate_version(req): server_version = constants.PROTOCOL_VERSION vstr = 'X-RHN-Satellite-XML-Dump-Version' if vstr not in req.headers_in: raise rhnFault(3010, "Missing version string") client_version = req.headers_in[vstr] # set the client version through rhnFlags to access later rhnFlags.set('X-RHN-Satellite-XML-Dump-Version', client_version) log_debug(1, "Server version", server_version, "Client version", client_version) client_ver_arr = str(client_version).split(".") server_ver_arr = str(server_version).split(".") client_major = client_ver_arr[0] server_major = server_ver_arr[0] if len(client_ver_arr) >= 2: client_minor = client_ver_arr[1] else: client_minor = 0 server_minor = server_ver_arr[1] try: client_major = int(client_major) client_minor = int(client_minor) except ValueError: raise_with_tb( rhnFault(3011, "Invalid version string %s" % client_version), sys.exc_info()[2]) try: server_major = int(server_major) server_minor = int(server_minor) except ValueError: raise_with_tb( rhnException("Invalid server version string %s" % server_version), sys.exc_info()[2]) if client_major != server_major: raise rhnFault(3012, "Client version %s does not match" " server version %s" % (client_version, server_version), explain=0)
def headerParserHandler(self, req): log_setreq(req) # We need to init CFG and Logging options = req.get_options() # if we are initializing out of a <Location> handler don't # freak out if not options.has_key("RHNComponentType"): # clearly nothing to do return apache.OK initCFG(options["RHNComponentType"]) initLOG(CFG.LOG_FILE, CFG.DEBUG) """ parse the request, init database and figure out what can we call """ log_debug(2, req.the_request) # call method from inherited class ret = apacheSession.headerParserHandler(self, req) if ret != apache.OK: return ret # make sure we have DB connection if not CFG.SEND_MESSAGE_TO_ALL: try: rhnSQL.initDB() except rhnSQL.SQLConnectError: rhnTB.Traceback(mail=1, req=req, severity="schema") return apache.HTTP_INTERNAL_SERVER_ERROR else: # If in outage mode, close the DB connections rhnSQL.closeDB() # Store client capabilities client_cap_header = 'X-RHN-Client-Capability' if req.headers_in.has_key(client_cap_header): client_caps = req.headers_in[client_cap_header] client_caps = filter(None, map(string.strip, string.split(client_caps, ",")) ) rhnCapability.set_client_capabilities(client_caps) # Enabling the input header flags associated with the redirects/newer clients redirect_support_flags = ['X-RHN-Redirect', 'X-RHN-Transport-Capability'] for flag in redirect_support_flags: if req.headers_in.has_key(flag): rhnFlags.set(flag, str(req.headers_in[flag])) return apache.OK
def handler(self, req): """ main Apache handler """ log_debug(2) ret = apacheSession.handler(self, req) if ret != apache.OK: return ret if not CFG.SEND_MESSAGE_TO_ALL: # Need to get any string template overrides here, before any app # code gets executed, as the rhnFault error messages use the # templates # If send_message_to_all, we don't have DB connectivity though h = rhnSQL.prepare("select label, value from rhnTemplateString") h.execute() templateStrings = {} while 1: row = h.fetchone_dict() if not row: break templateStrings[row['label']] = row['value'] if templateStrings: rhnFlags.set('templateOverrides', templateStrings) log_debug(4, "template strings: %s" % templateStrings) if not CFG.SECRET_KEY: # Secret key not defined, complain loudly try: raise rhnException("Secret key not found!") except: rhnTB.Traceback(mail=1, req=req, severity="schema") req.status = 500 req.send_http_header() return apache.OK # Try to authenticate the proxy if it this request passed # through a proxy. if self.proxyVersion: try: ret = self._req_processor.auth_proxy() except rhnFault, f: return self._req_processor.response(f.getxml())
def _setSessionToken(headers): """ Pushes token into rhnFlags. If doesn't exist, returns None. Pull session token out of the headers and into rhnFlags. """ log_debug(3) token = UserDictCase() if 'X-RHN-Server-Id' in headers: token['X-RHN-Server-Id'] = headers['X-RHN-Server-Id'] else: # This has to be here, or else we blow-up. return None prefix = "x-rhn-auth" tokenKeys = [x for x in headers.keys() if x[:len(prefix)].lower() == prefix] for k in tokenKeys: token[k] = headers[k] rhnFlags.set("AUTH_SESSION_TOKEN", token) return token
def listAllPackagesComplete(self, version): """ Creates and/or serves up a cached copy of all the packages for this channel including requires, obsoletes, conflicts, etc. """ log_debug(3, self.channelName, version) # Check to see if the version they are requesting is the latest # check the validity of what the client thinks about this channel # or blow up self.__check_channel(version) packages = rhnChannel.list_all_packages_complete(self.channelName) # transport options... transportOptions = rhnFlags.get('outputTransportOptions') transportOptions['Last-Modified'] = rfc822time(timestamp(version)) rhnFlags.set("compress_response", 1) return packages
def _getHeaderFromFile(self, filePath, stat_info=None): """ Utility function to extract a header from an rpm. If stat_info was already passed, don't re-stat the file """ log_debug(3, filePath) if stat_info: s = stat_info else: s = None try: s = os.stat(filePath) except: usix.raise_with_tb( rhnFault( 17, "Unable to read package %s" % os.path.basename(filePath)), sys.exc_info()[2]) lastModified = s[stat.ST_MTIME] del s # XXX: not neccessary? # Get the package header from the file # since we stat()ed the file, we know it's there already fd = os.open(filePath, os.O_RDONLY) h = rhn_rpm.get_package_header(fd=fd) os.close(fd) if h is None: raise rhnFault(17, "Invalid RPM %s" % os.path.basename(filePath)) stringIO = cStringIO.StringIO() # Put the result in stringIO stringIO.write(h.unload()) del h # XXX: not neccessary? pkgFilename = os.path.basename(filePath) pkg = pkgFilename.split('.') # Replace .rpm with .hdr pkg[-1] = "hdr" pkgFilename = ".".join(pkg) extra_headers = { 'X-RHN-Package-Header': pkgFilename, } self._set_last_modified(lastModified, extra_headers=extra_headers) rhnFlags.set("AlreadyEncoded", 1) return stringIO.getvalue()
def _validate_version(req): server_version = constants.PROTOCOL_VERSION vstr = 'X-RHN-Satellite-XML-Dump-Version' if vstr not in req.headers_in: raise rhnFault(3010, "Missing version string") client_version = req.headers_in[vstr] # set the client version through rhnFlags to access later rhnFlags.set('X-RHN-Satellite-XML-Dump-Version', client_version) log_debug(1, "Server version", server_version, "Client version", client_version) client_ver_arr = str(client_version).split(".") server_ver_arr = str(server_version).split(".") client_major = client_ver_arr[0] server_major = server_ver_arr[0] if len(client_ver_arr) >= 2: client_minor = client_ver_arr[1] else: client_minor = 0 server_minor = server_ver_arr[1] try: client_major = int(client_major) client_minor = int(client_minor) except ValueError: raise_with_tb(rhnFault(3011, "Invalid version string %s" % client_version), sys.exc_info()[2]) try: server_major = int(server_major) server_minor = int(server_minor) except ValueError: raise_with_tb(rhnException("Invalid server version string %s" % server_version), sys.exc_info()[2]) if client_major != server_major: raise rhnFault(3012, "Client version %s does not match" " server version %s" % (client_version, server_version), explain=0)
def _getHeaderFromFile(self, filePath, stat_info=None): """ Utility function to extract a header from an rpm. If stat_info was already passed, don't re-stat the file """ log_debug(3, filePath) if stat_info: s = stat_info else: s = None try: s = os.stat(filePath) except: raise_with_tb(rhnFault(17, "Unable to read package %s" % os.path.basename(filePath)), sys.exc_info()[2]) lastModified = s[stat.ST_MTIME] del s # XXX: not neccessary? # Get the package header from the file # since we stat()ed the file, we know it's there already fd = os.open(filePath, os.O_RDONLY) h = rhn_rpm.get_package_header(fd=fd) os.close(fd) if h is None: raise rhnFault(17, "Invalid RPM %s" % os.path.basename(filePath)) stringIO = cStringIO.StringIO() # Put the result in stringIO stringIO.write(h.unload()) del h # XXX: not neccessary? pkgFilename = os.path.basename(filePath) pkg = pkgFilename.split('.') # Replace .rpm with .hdr pkg[-1] = "hdr" pkgFilename = ".".join(pkg) extra_headers = { 'X-RHN-Package-Header': pkgFilename, } self._set_last_modified(lastModified, extra_headers=extra_headers) rhnFlags.set("AlreadyEncoded", 1) return stringIO.getvalue()
def token_packages(server_id, tokens_obj): assert (isinstance(tokens_obj, ActivationTokens)) h = rhnSQL.prepare(_query_token_packages) package_names = {} for token in tokens_obj.tokens: token_id = token['token_id'] h.execute(token_id=token_id) while True: row = h.fetchone_dict() if not row: break pn_id = row['name_id'] pa_id = row['arch_id'] package_names[(pn_id, pa_id)] = row['name'] ret = [] if not package_names: return ret package_arch_ids = list(package_names.keys()) # Get the latest action scheduled for this token last_action_id = rhnFlags.get('token_last_action_id') action_id = rhnAction.schedule_server_packages_update_by_arch( server_id, package_arch_ids, org_id=token['org_id'], prerequisite=last_action_id, action_name="Activation Key Package Auto-Install") # This action becomes the latest now rhnFlags.set('token_last_action_id', action_id) for p in package_names.values(): ret.append("Scheduled for install: '%s'" % p) rhnSQL.commit() return ret
def token_packages(server_id, tokens_obj): assert(isinstance(tokens_obj, ActivationTokens)) h = rhnSQL.prepare(_query_token_packages) package_names = {} for token in tokens_obj.tokens: token_id = token['token_id'] h.execute(token_id=token_id) while True: row = h.fetchone_dict() if not row: break pn_id = row['name_id'] pa_id = row['arch_id'] package_names[(pn_id, pa_id)] = row['name'] ret = [] if not package_names: return ret package_arch_ids = package_names.keys() # Get the latest action scheduled for this token last_action_id = rhnFlags.get('token_last_action_id') action_id = rhnAction.schedule_server_packages_update_by_arch(server_id, package_arch_ids, org_id=token['org_id'], prerequisite=last_action_id, action_name="Activation Key Package Auto-Install") # This action becomes the latest now rhnFlags.set('token_last_action_id', action_id) for p in package_names.values(): ret.append("Scheduled for install: '%s'" % p) rhnSQL.commit() return ret
def __init__(self): #start_init = time.time() self.filesuploaded = False self.options = rhnConfig.initCFG('server') print self.options mytime = time.time() self.test_username = username or ("test_username_%.3f" % mytime) self.test_password = password or ("test_password_%.3f" % mytime) self.test_email = email or ("%s@test_domain.com" % self.test_username) self.channel_arch = 'unittestarch' self.roles = ['org_admin'] rhnFlags.set('outputTransportOptions', UserDictCase()) self._init_db() self._init_org() self._init_user(self.roles) self._init_server() self._init_channels() self._init_up2date()