def _normalize_packages(self, system_id, packages, allow_none=0): """ the function checks if list of packages is well formated and also converts packages from old list of lists (extended_profile >= 2) to new list of dicts (extended_profile = 2) """ if allow_none and packages is None: return None # we need to be paranoid about the format of the argument because # if we accept wrong input then we might end up disposing in error # of all packages registered here if type(packages) != type([]): log_error("Invalid argument type", type(packages)) raise rhnFault(21) # Update the capabilities list server = self.auth_system(system_id) rhnCapability.update_client_capabilities(self.server_id) # old clients send packages as a list of arrays # while new (capability packages.extended_profile >= {version: 2, value: 1}) # use a list of dicts client_caps = rhnCapability.get_client_capabilities() package_is_dict = 0 packagesV2 = [] if client_caps and client_caps.has_key('packages.extended_profile'): cap_info = client_caps['packages.extended_profile'] if cap_info and int(cap_info['version']) >= 2: package_is_dict = 1 packagesV2 = packages for package in packages: if package_is_dict: # extended_profile >= 2 if type(package) != type({}): log_error("Invalid package spec for extended_profile >= 2", type(package), "len = %d" % len(package)) raise rhnFault(21) else: # extended_profile < 2 if (type(package) != type([]) or len(package) < 4): log_error("Invalid package spec", type(package), "len = %d" % len(package)) raise rhnFault(21) else: p = {'name' : package[0], 'version': package[1], 'release': package[2], 'epoch' : package[3], } if len(package) > 4: p['arch'] = package[4] if len(package) > 5: p['cookie'] = package[5] packagesV2.append(p) return packagesV2
def login(self, system_id, extra_data={}): """ Clients v2+ Log in routine. Return a dictionary of session token/channel information. Also sets this information in the headers. """ log_debug(5, system_id) # Authenticate the system certificate. We need the user record # to generate the tokens self.load_user = 1 server = self.auth_system('login', system_id) # log the entry log_debug(1, self.server_id) # Update the capabilities list rhnCapability.update_client_capabilities(self.server_id) # Fetch the channels this client is subscribed to channels = rhnChannel.getSubscribedChannels(self.server_id) rhnServerTime = str(time.time()) expireOffset = str(CFG.CLIENT_AUTH_TIMEOUT) signature = computeSignature(CFG.SECRET_KEY, self.server_id, self.user, rhnServerTime, expireOffset) loginDict = { 'X-RHN-Server-Id': self.server_id, 'X-RHN-Auth-User-Id': self.user, 'X-RHN-Auth': signature, 'X-RHN-Auth-Server-Time': rhnServerTime, 'X-RHN-Auth-Expire-Offset': expireOffset, # List of lists [[label,last_mod],...]: 'X-RHN-Auth-Channels': channels } # Duplicate these values in the headers so that the proxy can # intercept and cache them without parseing the xmlrpc. transport = rhnFlags.get('outputTransportOptions') for k, v in loginDict.items(): # Special case for channels if string.lower(k) == string.lower('X-RHN-Auth-Channels'): # Concatenate the channel information column-separated transport[k] = [string.join(x, ':') for x in v] else: transport[k] = v log_debug(5, "loginDict", loginDict, transport) # store route in DB (schema for RHN 3.1+ only!) server_route.store_client_route(self.server_id) return loginDict
def delta_packages(self, system_id, packages): log_debug(5, system_id, packages) if CFG.DISABLE_PACKAGES: return 0 if type(packages) != type({}): log_error("Invalid argument type", type(packages)) raise rhnFault(21) added_packages = self._normalize_packages(system_id, packages.get('added'), allow_none=1) removed_packages = self._normalize_packages(system_id, packages.get('deleted'), allow_none=1) server = self.auth_system(system_id) # log the entry if added_packages is not None: log_debug(1, self.server_id, "added: %d" % len(added_packages)) if removed_packages is not None: log_debug(1, self.server_id, "deleted: %d" % len(removed_packages)) # Update the capabilities list rhnCapability.update_client_capabilities(self.server_id) for package in added_packages or []: server.add_package(package) for package in removed_packages or []: server.delete_package(package) server.save_packages() return 0
def get(self, system_id, version=1, status={}): # Authenticate the system certificate if CFG.DISABLE_CHECKINS: self.update_checkin = 0 else: self.update_checkin = 1 self.auth_system(system_id) log_debug(1, self.server_id, version, "checkins %s" % ["disabled", "enabled"][self.update_checkin]) if status: self.__update_status(status) # Update the capabilities list rhnCapability.update_client_capabilities(self.server_id) # Invalidate failed actions self._invalidate_failed_prereq_actions() server_locked = self.server.server_locked() log_debug(3, "Server locked", server_locked) if self.__reboot_in_progress(): log_debug(3, "Server reboot in progress", self.server_id) rhnSQL.commit() return "" ret = {} # get the action. Status codes are currently: # 0 Queued # 1 Picked Up # 2 Completed # 3 Failed # XXX: we should really be using labels from rhnActionType instead of # hard coded type id numbers. # We fetch actions whose prerequisites have completed, and actions # that don't have prerequisites at all h = rhnSQL.prepare(self._query_queue_get) should_execute = 1 # Loop to get a valid action # (only one valid action will be dealt with per execution of this function...) while 1: if should_execute: h.execute(server_id=self.server_id) should_execute = 0 # Okay, got an action action = h.fetchone_dict() if not action: # No actions available; bail out # Don't forget the commit at the end... ret = "" break action_id = action['id'] log_debug(4, "Checking action %s" % action_id) # okay, now we have the action - process it. if action['remaining_tries'] < 1: log_debug(4, "Action %s picked up too many times" % action_id) # We've run out of pickup attempts for this action... self.__update_action(action_id, status=3, message="This action has been picked up multiple times " "without a successful transaction; " "this action is now failed for this system.") # Invalidate actions that depend on this one self._invalidate_child_actions(action_id) # keep looking for a good action to process... continue if server_locked and action['unlocked_only'] == 'Y': # This action is locked log_debug(4, "server id %s locked for action id %s" % ( self.server_id, action_id)) continue try: if version == 1: ret = self.__getV1(action) else: ret = self.__getV2(action) except ShadowAction: # Action the client should not see e = sys.exc_info()[1] # Make sure we re-execute the query, so we pick up whatever # extra actions were added should_execute = 1 text = e.args[0] log_debug(4, "Shadow Action", text) self.__update_action(action['id'], 2, 0, text) continue except InvalidAction: # This is an invalid action e = sys.exc_info()[1] # Update its status so it won't bother us again text = e.args[0] log_debug(4, "Invalid Action", text) self.__update_action(action['id'], 3, -99, text) continue except EmptyAction: e = sys.exc_info()[1] # this means that we have some sort of internal error # which gets reported in the logs. We don't touch the # action because this should get fixed on our side. log_error("Can not process action data", action, e.args) ret = "" break else: # all fine # Update the status of the action h = rhnSQL.prepare(""" update rhnServerAction set status = 1, pickup_time = current_timestamp, remaining_tries = :tries - 1 where action_id = :action_id and server_id = :server_id """) h.execute(action_id=action["id"], server_id=self.server_id, tries=action["remaining_tries"]) break # commit all changes rhnSQL.commit() return ret
def get(self, system_id, version=1, status={}): # Authenticate the system certificate if CFG.DISABLE_CHECKINS: self.update_checkin = 0 else: self.update_checkin = 1 self.auth_system(system_id) log_debug(1, self.server_id, version, "checkins %s" % ["disabled", "enabled"][self.update_checkin]) if status: self.__update_status(status) # Update the capabilities list rhnCapability.update_client_capabilities(self.server_id) # Invalidate failed actions self._invalidate_failed_prereq_actions() server_locked = self.server.server_locked() log_debug(3, "Server locked", server_locked) if self.__reboot_in_progress(): log_debug(3, "Server reboot in progress", self.server_id) rhnSQL.commit() return "" ret = {} # get the action. Status codes are currently: # 0 Queued # 1 Picked Up # 2 Completed # 3 Failed # XXX: we should really be using labels from rhnActionType instead of # hard coded type id numbers. # We fetch actions whose prerequisites have completed, and actions # that don't have prerequisites at all h = rhnSQL.prepare(self._query_queue_get) should_execute = 1 # Loop to get a valid action # (only one valid action will be dealt with per execution of this function...) while 1: if should_execute: h.execute(server_id=self.server_id) should_execute = 0 # Okay, got an action action = h.fetchone_dict() if not action: # No actions available; bail out # Don't forget the commit at the end... ret = "" break action_id = action['id'] log_debug(4, "Checking action %s" % action_id) # okay, now we have the action - process it. if action['remaining_tries'] < 1: log_debug(4, "Action %s picked up too many times" % action_id) # We've run out of pickup attempts for this action... self.__update_action(action_id, status=3, message="This action has been picked up multiple times " "without a successful transaction; " "this action is now failed for this system.") # Invalidate actions that depend on this one self._invalidate_child_actions(action_id) # keep looking for a good action to process... continue if server_locked and action['unlocked_only'] == 'Y': # This action is locked log_debug(4, "server id %s locked for action id %s" % ( self.server_id, action_id)) continue try: if version == 1: ret = self.__getV1(action) else: ret = self.__getV2(action) except ShadowAction, e: # Action the client should not see # Make sure we re-execute the query, so we pick up whatever # extra actions were added should_execute = 1 text = e.args[0] log_debug(4, "Shadow Action", text) self.__update_action(action['id'], 2, 0, text) continue except InvalidAction, e: # This is an invalid action # Update its status so it won't bother us again text = e.args[0] log_debug(4, "Invalid Action", text) self.__update_action(action['id'], 3, -99, text) continue
def login(self, system_id, extra_data={}): """ Clients v2+ Log in routine. Return a dictionary of session token/channel information. Also sets this information in the headers. """ log_debug(5, system_id) # Authenticate the system certificate. We need the user record # to generate the tokens self.load_user = 1 server = self.auth_system('login', system_id) # log the entry log_debug(1, self.server_id) # Update the capabilities list rhnCapability.update_client_capabilities(self.server_id) # Fetch the channels this client is subscribed to channelList = rhnChannel.channels_for_server(self.server_id) channels = [] for each in channelList: if not each.has_key('last_modified'): # No last_modified attribute # Probably an empty channel, so ignore continue channel = [each['label'], each['last_modified']] # isBaseChannel if each['parent_channel']: flag = "0" else: flag = "1" channel.append(flag) # isLocalChannel if each['local_channel']: flag = "1" else: flag = "0" channel.append(flag) channels.append(channel) rhnServerTime = str(time.time()) expireOffset = str(CFG.CLIENT_AUTH_TIMEOUT) signature = computeSignature(CFG.SECRET_KEY, self.server_id, self.user, rhnServerTime, expireOffset) loginDict = { 'X-RHN-Server-Id': self.server_id, 'X-RHN-Auth-User-Id': self.user, 'X-RHN-Auth': signature, 'X-RHN-Auth-Server-Time': rhnServerTime, 'X-RHN-Auth-Expire-Offset': expireOffset, # List of lists [[label,last_mod],...]: 'X-RHN-Auth-Channels': channels } # Duplicate these values in the headers so that the proxy can # intercept and cache them without parseing the xmlrpc. transport = rhnFlags.get('outputTransportOptions') for k, v in loginDict.items(): # Special case for channels if string.lower(k) == string.lower('X-RHN-Auth-Channels'): # Concatenate the channel information column-separated transport[k] = map(lambda x: string.join(x, ':'), v) else: transport[k] = v log_debug(5, "loginDict", loginDict, transport) # store route in DB (schema for RHN 3.1+ only!) server_route.store_client_route(self.server_id) return loginDict
def login(self, system_id, extra_data={}): """ Clients v2+ Log in routine. Return a dictionary of session token/channel information. Also sets this information in the headers. """ log_debug(5, system_id) # Authenticate the system certificate. We need the user record # to generate the tokens self.load_user = 1 server = self.auth_system('login', system_id) # log the entry log_debug(1, self.server_id) # Update the capabilities list rhnCapability.update_client_capabilities(self.server_id) # Fetch the channels this client is subscribed to channelList = rhnChannel.channels_for_server(self.server_id) channels = [] for each in channelList: if not each.has_key('last_modified'): # No last_modified attribute # Probably an empty channel, so ignore continue channel = [each['label'], each['last_modified']] # isBaseChannel if each['parent_channel']: flag = "0" else: flag = "1" channel.append(flag) # isLocalChannel if each['local_channel']: flag = "1" else: flag = "0" channel.append(flag) channels.append(channel) rhnServerTime = str(time.time()) expireOffset = str(CFG.CLIENT_AUTH_TIMEOUT) signature = computeSignature(CFG.SECRET_KEY, self.server_id, self.user, rhnServerTime, expireOffset) loginDict = { 'X-RHN-Server-Id' : self.server_id, 'X-RHN-Auth-User-Id' : self.user, 'X-RHN-Auth' : signature, 'X-RHN-Auth-Server-Time' : rhnServerTime, 'X-RHN-Auth-Expire-Offset' : expireOffset, # List of lists [[label,last_mod],...]: 'X-RHN-Auth-Channels' : channels } # Duplicate these values in the headers so that the proxy can # intercept and cache them without parseing the xmlrpc. transport = rhnFlags.get('outputTransportOptions') for k, v in loginDict.items(): # Special case for channels if string.lower(k) == string.lower('X-RHN-Auth-Channels'): # Concatenate the channel information column-separated transport[k] = map(lambda x: string.join(x, ':'), v) else: transport[k] = v log_debug(5, "loginDict", loginDict, transport) # store route in DB (schema for RHN 3.1+ only!) server_route.store_client_route(self.server_id) return loginDict
# # Copyright (c) 2008--2013 Red Hat, Inc. # # This software is licensed to you under the GNU General Public License, # version 2 (GPLv2). There is NO WARRANTY for this software, express or # implied, including the implied warranties of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 # along with this software; if not, see # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. # # Red Hat trademarks are not licensed under GPLv2. No permission is # granted to use or replicate Red Hat trademarks that are incorporated # in this software or its documentation. # import spacewalk.server.rhnSQL as rhnSQL from spacewalk.server.rhnCapability import set_client_capabilities, update_client_capabilities if __name__ == '__main__': rhnSQL.initDB('rhnuser/rhnuser@webdev') set_client_capabilities([ "caneatCheese(1)=1", "caneatMeat(22)=3", "a(3)=4", "b(3)=5", ]) update_client_capabilities(1000102174)