This file is indexed.

/usr/lib/python2.7/dist-packages/jnpr/junos/factory/factory_loader.py is in python-junos-eznc 2.0.1-1.

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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
"""
This file contains the FactoryLoader class that is used to dynamically
create Runstat Table and View objects from a <dict> of data.  The <dict> can
originate from any kind of source: YAML, JSON, program.  For examples of YAML
refer to the .yml files in this jnpr.junos.op directory.
"""
# stdlib
from copy import deepcopy
import re

# locally
from jnpr.junos.factory.factory_cls import *
from jnpr.junos.factory.viewfields import *

__all__ = ['FactoryLoader']

# internally used shortcuts

_VIEW = FactoryView
_FIELDS = ViewFields
_GET = FactoryOpTable
_TABLE = FactoryTable
_CFGTBL = FactoryCfgTable


class FactoryLoader(object):

    """
    Used to load a <dict> of data that contains Table and View definitions.

    The primary method is :load(): which will return a <dict> of item-name and
    item-class definitions.

    If you want to import these definitions directly into your namespace,
    (like a module) you would do the following:

      loader = FactoryLoader()
      catalog = loader.load( <catalog_dict> )
      globals().update( catalog )

    If you did not want to do this, you can access the items as the catalog.
    For example, if your <catalog_dict> contained a Table called MyTable, then
    you could do something like:

      MyTable = catalog['MyTable']
      table = MyTable(dev)
      table.get()
      ...
    """

    def __init__(self):
        self._catalog_dict = None       # YAML data

        self._item_optables = []    # list of the get/op-tables
        self._item_cfgtables = []   # list of get/cfg-tables
        self._item_views = []        # list of views to build
        self._item_tables = []       # list of tables to build

        self.catalog = {}           # catalog of built classes

    # -----------------------------------------------------------------------
    # Create a View class from YAML definition
    # -----------------------------------------------------------------------

    def _fieldfunc_True(self, value_rhs):
        def true_test(x):
            if value_rhs.startswith('regex('):
                return True if bool(re.search(value_rhs.strip('regex()'), x)) else False
            return x == value_rhs
        return true_test

    def _fieldfunc_False(self, value_rhs):
        def false_test(x):
            if value_rhs.startswith('regex('):
                return False if bool(re.search(value_rhs.strip('regex()'), x)) else True
            return x != value_rhs
        return false_test

    def _add_dictfield(self, fields, f_name, f_dict, kvargs):
        """ add a field based on its associated dictionary """
        # at present if a field is a <dict> then there is **one
        # item** - { the xpath value : the option control }.  typically
        # the option would be a bultin class type like 'int'
        # however, as this framework expands in capability, this
        # will be enhaced, yo!

        xpath, opt = list(f_dict.items())[0]       # get first/only key,value

        if opt == 'group':
            fields.group(f_name, xpath)
            return

        if 'flag' == opt:
            opt = 'bool'       # flag is alias for bool

        # first check to see if the option is a built-in Python
        # type, most commonly would be 'int' for numbers, like counters
        if isinstance(opt, dict):
            kvargs.update(opt)
            fields.str(f_name, xpath, **kvargs)
            return

        astype = __builtins__.get(opt) or globals().get(opt)
        if astype is not None:
            kvargs['astype'] = astype
            fields.astype(f_name, xpath, **kvargs)
            return

        # next check to see if this is a "field-function"
        # operator in the form "func=value", like "True=enabled"

        if isinstance(opt, str) and opt.find('=') > 0:
            field_cmd, value_rhs = opt.split('=')
            fn_field = '_fieldfunc_' + field_cmd
            if not hasattr(self, fn_field):
                raise ValueError("Unknown field-func: '%'" % field_cmd)
            kvargs['astype'] = getattr(self, fn_field)(value_rhs)
            fields.astype(f_name, xpath, **kvargs)
            return

        raise RuntimeError("Dont know what to do with field: '%s'" % f_name)

    # ---[ END: _add_dictfield ] ---------------------------------------------

    def _add_view_fields(self, view_dict, fields_name, fields):
        """ add a group of fields to the view """
        fields_dict = view_dict[fields_name]
        try:
            # see if this is a 'fields_<group>' collection, and if so
            # then we automatically setup using the group mechanism
            mark = fields_name.index('_')
            group = {'group': fields_name[mark + 1:]}
        except:
            # otherwise, no group, just standard 'fields'
            group = {}

        for f_name, f_data in fields_dict.items():
            # each field could have its own unique set of properties
            # so create a kvargs <dict> each time.  but copy in the
            # groups <dict> (single item) generically.
            kvargs = {}
            kvargs.update(group)

            if isinstance(f_data, dict):
                self._add_dictfield(fields, f_name, f_data, kvargs)
                continue

            if f_data in self._catalog_dict:
                # f_data is the table name
                cls_tbl = self.catalog.get(f_data, self._build_table(f_data))
                fields.table(f_name, cls_tbl)
                continue

            # if we are here, then it means that the field is a string value
            xpath = f_name if f_data is True else f_data
            fields.str(f_name, xpath, **kvargs)

    # -------------------------------------------------------------------------

    def _build_view(self, view_name):
        """ build a new View definition """
        if view_name in self.catalog:
            return self.catalog[view_name]

        view_dict = self._catalog_dict[view_name]
        kvargs = {'view_name': view_name}

        # if there are field groups, then get that now.
        if 'groups' in view_dict:
            kvargs['groups'] = view_dict['groups']

        # if this view extends another ...
        if 'extends' in view_dict:
            base_cls = self.catalog.get(view_dict['extends'])
            # @@@ should check for base_cls is None!
            kvargs['extends'] = base_cls

        fields = _FIELDS()
        fg_list = [name for name in view_dict if name.startswith('fields')]
        for fg_name in fg_list:
            self._add_view_fields(view_dict, fg_name, fields)

        cls = _VIEW(fields.end, **kvargs)
        self.catalog[view_name] = cls
        return cls

    # -----------------------------------------------------------------------
    # Create a Get-Table from YAML definition
    # -----------------------------------------------------------------------

    def _build_optable(self, table_name):
        """ build a new Get-Table definition """
        if table_name in self.catalog:
            return self.catalog[table_name]

        tbl_dict = self._catalog_dict[table_name]
        kvargs = deepcopy(tbl_dict)

        rpc = kvargs.pop('rpc')
        kvargs['table_name'] = table_name

        if 'view' in tbl_dict:
            view_name = tbl_dict['view']
            cls_view = self.catalog.get(view_name, self._build_view(view_name))
            kvargs['view'] = cls_view

        cls = _GET(rpc, **kvargs)
        self.catalog[table_name] = cls
        return cls

    # -----------------------------------------------------------------------
    # Create a Table class from YAML definition
    # -----------------------------------------------------------------------

    def _build_table(self, table_name):
        """ build a new Table definition """
        if table_name in self.catalog:
            return self.catalog[table_name]

        tbl_dict = self._catalog_dict[table_name]

        table_item = tbl_dict.pop('item')
        kvargs = deepcopy(tbl_dict)
        kvargs['table_name'] = table_name

        if 'view' in tbl_dict:
            view_name = tbl_dict['view']
            cls_view = self.catalog.get(view_name, self._build_view(view_name))
            kvargs['view'] = cls_view

        cls = _TABLE(table_item, **kvargs)
        self.catalog[table_name] = cls
        return cls

    def _build_cfgtable(self, table_name):
        """ build a new Config-Table definition """
        if table_name in self.catalog:
            return self.catalog[table_name]
        tbl_dict = self._catalog_dict[table_name]

        if 'view' in tbl_dict:
            # transpose name to class
            view_name = tbl_dict['view']
            tbl_dict['view'] = self.catalog.get(
                view_name,
                self._build_view(view_name))

        cls = _CFGTBL(table_name, tbl_dict)
        self.catalog[table_name] = cls
        return cls

    # -----------------------------------------------------------------------
    # Primary builders ...
    # -----------------------------------------------------------------------

    def _sortitems(self):
        for k, v in self._catalog_dict.items():
            if 'rpc' in v:
                self._item_optables.append(k)
            elif 'get' in v:
                self._item_cfgtables.append(k)
            elif 'set' in v:
                self._item_cfgtables.append(k)
            elif 'view' in v:
                self._item_tables.append(k)
            else:
                self._item_views.append(k)

    def load(self, catalog_dict, envrion={}):

        # load the yaml data and extract the item names.  these names will
        # become the new class definitions

        self._catalog_dict = catalog_dict
        self._sortitems()

        list(map(self._build_optable, self._item_optables))
        list(map(self._build_cfgtable, self._item_cfgtables))
        list(map(self._build_table, self._item_tables))
        list(map(self._build_view, self._item_views))

        return self.catalog