---
# System prepended metadata

title: Привязка интерфейсов к физическим портам inventory

---

# Привязка интерфейсов к физическим портам inventory

## Задача
Установить соответсвие между физическими портами, полученными через
asset discovery и из моделей устройств с логическими интерфейсами,
полученными через interface discovery.

## ConnectionType
В ConnectionType необходимо добавить дополнительный признак:

* is_physical_interface

Признак показывает, что в данном слоте находится физический интерфейс.

Такие слоты могут быть привязаны к логическим интерфейсам.

## iter_physical_interface
```
ManagedObject.iter_physical_interface() -> Iterable[PhysicalPath]

где:

PhysicalPath = Tuple[PathItem, *]
PathItem - namedtuple(object, connection_type, connection_name) 
```
Итератор возвращает записи с полным физическим путем для каждого
интерфейса. Полный физический путь состоит из всех модулей, начиная с шасси, вплоть до конкретного порта.

Порты определяются по признаку `is_physical_interface`,
порты являются границей, на которой останавливается рекурсивный спуск.

По умолчанию считается, что порт начинается на дырке SFP, а не на оптических разъмах.

## Collator
Класс, осуществляющий привязку логических интерфейсов к физическим.
Должен реализовывать интерфейс:

```
class BaseCollator(object):
    def __init__(self, **kwargs):
        ...
    
    def collate(self, physical_path, interfaces):
        # type: (PhysicalPath, Dict[str, Interface]) -> Optional[str]
```

Класс `Collator` должен наследоваться от `BaseCollator` и может дополнительно конфигурироваться через именнованные аргументы конструктора.

Экземпляр `Collator` создается один раз на весь процесс привязки в соотвествующем Job'е discovery. Таким образом разрешается хранение  внутреннего состояния на весь процесс привязки.

Основным рабочим методом является `collate`, который принимает на вход полный физический путь порта (результат одного yield `iter_physical_interface`) и словарь интерфейсов, нуждающихся в привязке (нормализованное имя интерфейса -> Interface instance).

Метод `collate` возвращает имя логического интерфейса соответсвующего данному физическому пути, если привязка удалась, или None, если привязка не удалась.

## Цепочки Collator'ов
Collator'ы могут быть сгруппированы в цепочки. Каждый физический
порт прогоняется по цепочке, пока не будет получен ответ, отличный от None. Первый успешный ответ и будет использоваться в привязке.

## Конфигурирование Сollator'ов
Осуществляется аналогично аппликаторам. В класс профилей добавляются настройки:

* `interface_collators` - список из:
    * имя handler, или
    * (имя handler, настройки)

настройки - dict с аргументами для конструктора collator'а.

Получение эффективных настроек осуществляется методом профиля:
```
@classmethod
def iter_collators(cls, object)
    # type:  (ManagedObject) -> Iterable[BaseCollator]
```
может использоваться для тонкой настройки collator'ов в зависимости от платформы.

## Процесс привязки
После отработки `interface` и `asset` discovery.
Осуществляется в конце `asset` discovery.

* Получаем цепочку настроенных collator'ов через `iter_collators`
* Если она пуста - завершаем обработку
* Строим словарь логических интерфейсов `interfaces`
* по всем `path` из iter_physical_interfaces`
    * по всем `collator` из цепочки `collator'ов`
        * вызываем метод `collate(path, interfaces)`
        * если вернулся не None
            * осущесвляем привязку
            * break

## Хранение привязки
Вводится новый тип `EmbeddedDocument` - ObjectConnectionData,
для хранения дополнительных данных по связям объектов.

Поля:

* `name` - имя `ObjectConnection` из модели
* `interface_name` - имя привязанного интерфейса (если есть)
* `interface_managed_object` - опциональная ссылка на ManagedObject, если интерфейсы внутри объекта могут принадлежать разным ManagedObject. По умолчанию - всегда пустой.

В дальнейшем в ObjectConnectionData могут появляться другие поля.

Также в структуре `Object` появляется поле:

* `connections` - список `ObjectConnectionData`

При заполнении привязок происходит синхронизация `ObjectConnectionData`,  добавляются и редактируются необходимые записи, пустые записи удаляются.

## Доработка datastream managedobject
В разделе `asset.slots` добавляется дополнительный опциональный параметр `interface`.

## Stopper'ы
* Изменяется структура `ConnectionType`, целесообразно реализовывать после слияния репозитория коллекций с `master`
