This file is indexed.

/usr/lib/python2.7/dist-packages/networking_arista/common/api.py is in python-networking-arista 2017.2.2-2ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# Copyright (c) 2017 Arista Networks, Inc
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json

from oslo_log import log as logging
from oslo_utils import excutils
import requests
from requests import exceptions as requests_exc
from six.moves.urllib import parse

from networking_arista._i18n import _LI, _LW
from networking_arista.common import exceptions as arista_exc

LOG = logging.getLogger(__name__)

# EAPI error message
ERR_CVX_NOT_LEADER = 'only available on cluster leader'


class EAPIClient(object):
    def __init__(self, host, username=None, password=None, verify=False,
                 timeout=None):
        self.host = host
        self.timeout = timeout
        self.url = self._make_url(host)
        self.session = requests.Session()
        self.session.headers['Content-Type'] = 'application/json'
        self.session.headers['Accept'] = 'application/json'
        self.session.verify = verify
        if username and password:
            self.session.auth = (username, password)

    @staticmethod
    def _make_url(host, scheme='https'):
        return parse.urlunsplit(
            (scheme, host, '/command-api', '', '')
        )

    def execute(self, commands, commands_to_log=None):
        params = {
            'timestamps': False,
            'format': 'json',
            'version': 1,
            'cmds': commands
        }

        data = {
            'id': 'Networking Arista Driver',
            'method': 'runCmds',
            'jsonrpc': '2.0',
            'params': params
        }

        if commands_to_log:
            log_data = dict(data)
            log_data['params'] = dict(params)
            log_data['params']['cmds'] = commands_to_log
        else:
            log_data = data

        LOG.info(
            _LI('EAPI request %(ip)s contains %(data)s'),
            {'ip': self.host, 'data': json.dumps(log_data)}
        )

        # request handling
        try:
            error = None
            response = self.session.post(
                self.url,
                data=json.dumps(data),
                timeout=self.timeout
            )
        except requests_exc.ConnectionError:
            error = _LW('Error while trying to connect to %(ip)s')
        except requests_exc.ConnectTimeout:
            error = _LW('Timed out while trying to connect to %(ip)s')
        except requests_exc.Timeout:
            error = _LW('Timed out during an EAPI request to %(ip)s')
        except requests_exc.InvalidURL:
            error = _LW('Ingoring attempt to connect to invalid URL at %(ip)s')
        except Exception as e:
            with excutils.save_and_reraise_exception():
                LOG.warning(
                    _LW('Error during processing the EAPI request %(error)s'),
                    {'error': e}
                )
        finally:
            if error:
                msg = error % {'ip': self.host}
                # stop processing since we've encountered request error
                LOG.warning(msg)
                raise arista_exc.AristaRpcError(msg=msg)

        # response handling
        try:
            resp_data = response.json()
            return resp_data['result']
        except ValueError as e:
            LOG.info(_LI('Ignoring invalid JSON response'))
        except KeyError:
            if 'error' in resp_data and resp_data['error']['code'] == 1002:
                for d in resp_data['error']['data']:
                    if not isinstance(d, dict):
                        continue
                    elif ERR_CVX_NOT_LEADER in d.get('errors', {})[0]:
                        LOG.info(
                            _LI('%(ip)s is not the CVX leader'),
                            {'ip': self.host}
                        )
                        return
            msg = _LI('Unexpected EAPI error')
            LOG.info(msg)
            raise arista_exc.AristaRpcError(msg=msg)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                LOG.warning(
                    _LW('Error during processing the EAPI response %(error)s'),
                    {'error': e}
                )