コード例 #1
0
def getFromCache(URILink, CacheDir):
    CacheDir = os.path.join(CacheDir + URILink)
    if os.path.isfile(CacheDir):
        with open(CacheDir) as f:
            payload = f.read()
    if os.path.isfile(os.path.join(CacheDir, 'index.xml')):
        with open(os.path.join(CacheDir, 'index.xml')) as f:
            payload = f.read()
    if os.path.isfile(os.path.join(CacheDir, 'index.json')):
        with open(os.path.join(CacheDir, 'index.json')) as f:
            payload = json.loads(f.read())
        payload = navigateJsonFragment(payload, URILink)
    return payload
コード例 #2
0
    def callResourceURI(self, URILink):
        """
        Makes a call to a given URI or URL

        param arg1: path to URI "/example/1", or URL "http://example.com"
        return: (success boolean, data, request status code)
        """
        # rs-assertions: 6.4.1, including accept, content-type and odata-versions
        # rs-assertion: handle redirects?  and target permissions
        # rs-assertion: require no auth for serviceroot calls
        if URILink is None:
            traverseLogger.warn("This URI is empty!")
            return False, None, -1, 0

        URILink = URILink.rstrip('/')
        config = currentService.config
        proxies = currentService.proxies
        ConfigIP, UseSSL, AuthType, ChkCert, ChkCertBundle, timeout, Token = config['targetip'], config['usessl'], config['authtype'], \
                config['certificatecheck'], config['certificatebundle'], config['timeout'], config['token']
        CacheMode, CacheDir = config['cachemode'], config['cachefilepath']

        scheme, netloc, path, params, query, fragment = urlparse(URILink)
        inService = scheme is '' and netloc is ''
        scheme = ('https' if UseSSL else 'http') if scheme is '' else scheme
        netloc = ConfigIP if netloc is '' else netloc
        URLDest = urlunparse((scheme, netloc, path, params, query, fragment))

        payload, statusCode, elapsed, auth, noauthchk = None, '', 0, None, True

        isXML = False
        if "$metadata" in URILink or ".xml" in URILink[:-5]:
            isXML = True
            traverseLogger.debug('Should be XML')

        ExtraHeaders = None
        if 'extrajsonheaders' in config and not isXML:
            ExtraHeaders = config['extrajsonheaders']
        elif 'extraxmlheaders' in config and isXML:
            ExtraHeaders = config['extraxmlheaders']

        # determine if we need to Auth...
        if inService:
            noauthchk =  URILink in ['/redfish', '/redfish/v1', '/redfish/v1/odata'] or\
                '/redfish/v1/$metadata' in URILink

            auth = None if noauthchk else (config['username'],
                                           config['password'])
            traverseLogger.debug('dont chkauth' if noauthchk else 'chkauth')

            if CacheMode in ["Fallback", "Prefer"]:
                payload = rfService.getFromCache(URILink, CacheDir)

        if not inService and config['servicemode']:
            traverseLogger.debug('Disallowed out of service URI ' + URILink)
            return False, None, -1, 0

        # rs-assertion: do not send auth over http
        # remove UseSSL if necessary if you require unsecure auth
        if (not UseSSL and not config['forceauth']
            ) or not inService or AuthType != 'Basic':
            auth = None

        # only send token when we're required to chkauth, during a Session, and on Service and Secure
        headers = {}
        headers.update(commonHeader)
        if not noauthchk and inService and UseSSL:
            traverseLogger.debug('successauthchk')
            if AuthType == 'Session':
                currentSession = currentService.currentSession
                headers.update(
                    {"X-Auth-Token": currentSession.getSessionKey()})
            elif AuthType == 'Token':
                headers.update({"Authorization": "Bearer " + Token})

        if ExtraHeaders is not None:
            headers.update(ExtraHeaders)

        certVal = ChkCertBundle if ChkCert and ChkCertBundle not in [
            None, ""
        ] else ChkCert

        # rs-assertion: must have application/json or application/xml
        traverseLogger.debug(
            'callingResourceURI {}with authtype {} and ssl {}: {} {}'.format(
                'out of service ' if not inService else '', AuthType, UseSSL,
                URILink, headers))
        response = None
        try:
            if payload is not None and CacheMode == 'Prefer':
                return True, payload, -1, 0
            response = requests.get(URLDest,
                                    headers=headers,
                                    auth=auth,
                                    verify=certVal,
                                    timeout=timeout,
                                    proxies=proxies if not inService else
                                    None)  # only proxy non-service
            expCode = [200]
            elapsed = response.elapsed.total_seconds()
            statusCode = response.status_code
            traverseLogger.debug('{}, {}, {},\nTIME ELAPSED: {}'.format(
                statusCode, expCode, response.headers, elapsed))
            if statusCode in expCode:
                contenttype = response.headers.get('content-type')
                if contenttype is None:
                    traverseLogger.error(
                        "Content-type not found in header: {}".format(URILink))
                    contenttype = ''
                if 'application/json' in contenttype:
                    traverseLogger.debug("This is a JSON response")
                    decoded = response.json(object_pairs_hook=OrderedDict)
                    # navigate fragment
                    decoded = navigateJsonFragment(decoded, URILink)
                    if decoded is None:
                        traverseLogger.error(
                            "The JSON pointer in the fragment of this URI is not constructed properly: {}"
                            .format(URILink))
                elif 'application/xml' in contenttype:
                    decoded = response.text
                elif 'text/xml' in contenttype:
                    # non-service schemas can use "text/xml" Content-Type
                    if inService:
                        traverseLogger.warn(
                            "Incorrect content type 'text/xml' for file within service"
                            .format(URILink))
                    decoded = response.text
                else:
                    traverseLogger.error(
                        "This URI did NOT return XML or Json contenttype, is this not a Redfish resource (is this redirected?): {}"
                        .format(URILink))
                    decoded = None
                    if isXML:
                        traverseLogger.info('Attempting to interpret as XML')
                        decoded = response.text
                    else:
                        try:
                            json.loads(response.text)
                            traverseLogger.info(
                                'Attempting to interpret as JSON')
                            decoded = response.json(
                                object_pairs_hook=OrderedDict)
                        except ValueError:
                            pass

                return decoded is not None, decoded, statusCode, elapsed
            elif statusCode == 401:
                if inService and AuthType in ['Basic', 'Token']:
                    if AuthType == 'Token':
                        cred_type = 'token'
                    else:
                        cred_type = 'username and password'
                    raise AuthenticationError(
                        'Error accessing URI {}. Status code "{} {}". Check {} supplied for "{}" authentication.'
                        .format(URILink, statusCode, responses[statusCode],
                                cred_type, AuthType))

        except requests.exceptions.SSLError as e:
            traverseLogger.error("SSLError on {}: {}".format(URILink, repr(e)))
            traverseLogger.debug("output: ", exc_info=True)
        except requests.exceptions.ConnectionError as e:
            traverseLogger.error("ConnectionError on {}: {}".format(
                URILink, repr(e)))
            traverseLogger.debug("output: ", exc_info=True)
        except requests.exceptions.Timeout as e:
            traverseLogger.error(
                "Request has timed out ({}s) on resource {}".format(
                    timeout, URILink))
            traverseLogger.debug("output: ", exc_info=True)
        except requests.exceptions.RequestException as e:
            traverseLogger.error(
                "Request has encounted a problem when getting resource {}: {}".
                format(URILink, repr(e)))
            traverseLogger.debug("output: ", exc_info=True)
        except AuthenticationError as e:
            raise e  # re-raise exception
        except Exception as e:
            traverseLogger.error(
                "A problem when getting resource {} has occurred: {}".format(
                    URILink, repr(e)))
            traverseLogger.debug("output: ", exc_info=True)
            if response and response.text:
                traverseLogger.debug("payload: {}".format(response.text))

        if payload is not None and CacheMode == 'Fallback':
            return True, payload, -1, 0
        return False, None, statusCode, elapsed