Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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
Example #6
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
Example #7
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, 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
Example #8
0
    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
Example #9
0
    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
Example #10
0
#
# 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)