По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Дорогой читатель! В поисках полезной автоматизации и кастомизации своего Asterisk продвинутые администраторы прибегают к использованию различных скриптов. Это может быть PHP, Perl C, Pascal или Shell. Для использования скриптов, написанных на одном из перечисленных языков программирования в диалплане Asterisk используется AGI (Asterisk Gateway Interface) – о нем и поговорим. Как это работает? AGI - это прослойка между скриптом и диалпланом (планом набора) в Asterisk. В скрипт мы можем передавать различные переменные, а можем получать какие - то значения из скрипта. Когда Asterisk инициирует запуск скрипта через AGI, он передает в него набор переменных. Все переменные обладают префиксом agi_: Переменная Описание Пример agi_request Имя файла исполняемого скрипта trunk.php agi_channel Канал, инициирующий звонок Local/89123456789@from-internal-00000002;2 agi_language Языковой код en agi_type Тип канала, инициирующий вызов Local agi_uniqueid Уникальный идентификатор звонка 1497364935.15 agi_version Версия Asterisk 13.10.0 agi_callerid Номер звонящего (CID Number) 89123456789 agi_calleridname Имя звонящего (CID Name) 89123456789 agi_dnid Набранный номер unknown agi_context Контекст обработки вызова macro-dialout-trunk Как вызвать AGI в диалплане? Вызвать AGI скрипт очень просто: предварительно, загрузите скрипт в директорию /var/lib/asterisk/agi-bin/. После этого, скрипту необходимо дать права и собственника. Предположим, наш скрипт называется trunk.php: chmod 755 /var/lib/asterisk/agi-bin/trunk.php chown asterisk:asterisk /var/lib/asterisk/agi-bin/trunk.php Теперь, чтобы скрипт был вызван в диалплане, просто добавьте следующую конструкцию: exten => 1333,n,AGI(trunk.php) Просто, не правда ли? А если мы хотим передать переменную в скрипт? Просто добавьте ее после запятой: exten => 1333,n,AGI(trunk.php, ${CALLERID(number)}) А как же написать скрипт? Теперь к самому скрипту – напишем его на PHP. Пусть нам нужно отправлять письмо с номером звонящего. Выглядеть скрипт будет так: #!/usr/bin/php -q <?php require('phpagi.php'); $agi = new AGI(); //подключаем файл phpagi.php – 1 и 2 строки обязательны в любом скрипте $cid = $agi->request['agi_callerid']; // берем из AGI номер звонящего mail("info@merionet.ru", 'Привет!', 'Вот и номер звонящего:', $cid); //отправляем в письме Вот и все. Нам будет приходить на почту письмо с номером звонящего – прокачав данный функционал можно отслеживать пропущенные вызовы, например.
img
Использование REST API является полезной функцией для реализации ваших сценариев. Вы можете получить доступ к новым функциям, а также расширить возможности создания новых, более продвинутых сценариев. Опыт многих пользователей показывает, что, когда начинаешь использовать REST API в скриптах, то чувствуешь себя довольно неуклюже и непривычно. В этой заметке мы обсудим: Что такое REST API Как читать документацию Как использовать API REST с PowerShell Некоторые советы и подсказки, как облегчить и улучшить практику Что такое "REST"? REST, или RESTful API, это API, который использует HTTP запросы для получения, добавления, удаления или манипулирования данными в различных сервисах. Как правило, то, что нужно сделать с данными, решается тем, какой HTTP-метод вы используете. Вот краткий список методов HTTP и их применение в REST API: GET-Read POST-Create PATCH-Partial update/modify PUT-Update/replace DELETE-Remove Данные, которые возвращает API REST, обычно представляются в формате JSON. Теперь давайте начнём с нашего первого API запроса! Что такое API Работа с документацией Для использования различных API REST необходимо научиться читать и интерпретировать документацию. К счастью, если вы знаете, как читать один тип документации, вы сможете быстро научиться читать другие. В этой статье мы используем petstore.swagger.io, так как он использует популярный фреймворк Swagger, который довольно часто используется в разработке. На предыдущем рисунке показана наиболее важная информация о конечных точках REST API: HTTP-метод-GET/POST/DELETE и т.д. URL-адрес, связанный с конечной точкой REST API (Базовый URL, как правило, представлен в верхней части страницы документации) Краткое описание Подробности Первая страница документации просто замечательная, и, как правило, с помощью этой информации можно выполнить большинство запросов, требующих использования метода HTTP GET. Но такие методы, как POST и SET, обычно требуют, чтобы вы щелкнули и развернули строку, чтобы получить больше информации. Если вы нажмете на одну из строк, то получите информацию, которая выглядит так: Здесь мы представили конечную точку REST, которая может создать новый объект pet. Здесь указывается, как должен выглядеть JSON, предоставленный в теле POST, и какой тип контента он принимает. Другие конечные точки REST указывают, что это за параметры, каким типом данных они должны быть и т.д. Это основы для чтения документации. Теперь, когда общие принцип более-менее ясны, пора начать использовать REST API с PowerShell. Получение первых данных (GET) Используя REST API с PowerShell обычно довольно просто, используется встроенные командлеты, таким образом, нет необходимости в дополнительных модулях. Мы собираемся извлечь данные с помощью метода GET в конечной точке /pet/{ petId}. Если развернуть конечную точку /pet/{ petId} в документации, можно увидеть, что {petId} на самом деле является параметром, который принимает целое число. Это делает URL-адрес для выборки объекта pet с идентификатором 1: https://petstore.swagger.io/v2/pet/1 В документации SWAGGER REST API обычно отображается базовый URL-адрес в верхней части страницы. Теперь начнем с PowerShell. Откройте окно терминала и введите: PS51 > Invoke-RestMethod -Method GET -ContentType "application/json" -Uri "https://petstore.swagger.io/v2/pet/1" id : 1 category : @{id=0; name=string} name : doggie photoUrls : {string} tags : {@{id=0; name=string}} status : available Поскольку в ответе от сервера возвращается тип содержимого "application/json" используется метод Invoke-RestMethod, который автоматически преобразует возвращаемый JSON в объект. Ошибка 404 Not found, как правило, означает, что объект не найден или URL-адрес введен неправильно. Итак, мы выполнили первый вызов REST API. Но возможности метода GET для получения данных довольно ограничены, так что давайте создадим что-нибудь с помощью метода POST. Создание объекта методом POST Метод POST чаще всего используется для создания, например, пользователей или записей и т.д. Запрос POST отправляет BODY, содержащий информацию, конечной точке REST, обычно в формате JSON, но он также может быть в виде формы с кодировкой URL. Вы узнаете, как создать объект JSON, который можно отправить в конечную точку/pet. Можно увидеть, как должен выглядеть JSON, если развернуть строку POST/pet в документации. Начнем с создания хэштаблицы, который можно преобразовать в объект JSON. Raw JSON следует избегать в скриптах PowerShell, поскольку он ограничивает его возможности. $Body = @{ id = 19 category = @{ id = 45 name = "Whatever" } name = "Dawg" photoUrls = @( "string" ) tags = @( @{ id = 0 name = "string" } ) status = "available" } Если вам трудно создать хештаблицу, который преобразуется в нужный JSON, установите модуль PsdKit и используйте команду $ JsonString | ThreadTo-Psd Теперь имеется хэш-таблица, которую можно преобразовать в строку JSON и POST в конечную точку/pet: $JsonBody = $Body | ConvertTo-Json $Uri = "https://petstore.swagger.io/v2/pet" Invoke-RestMethod -ContentType "application/json" -Uri $Uri -Method Post -Body $JsonBody id : 19 category : @{id=45; name=Whatever} name : Dawg photoUrls : {string} tags : {@{id=0; name=string}} status : available При создании объекта он обычно получает созданный для подтверждения объект. Использование DELETE. Метод DELETE используется для удаления данных, а применение очень схоже с методом GET. PS51 > Invoke-RestMethod -Method DELETE -ContentType "application/json" -Uri "https://petstore.swagger.io/v2/pet/1" Только убедитесь, что не удалите ничего важного Использование PUT Метод PUT используется для обновления данных. Это делается аналогично методу POST путем представления полного или частичного объекта JSON: PS51> $Body = [PSCustomObject]@{ id = 19 name = "Dawg with a new name" } PS51> $JsonBody = $Body | ConvertTo-Json PS51> $Uri = "https://petstore.swagger.io/v2/pet" PS51> Invoke-RestMethod -ContentType "application/json" -Uri $Uri -Method PUT -Body $JsonBody id name photoUrls tags -- ---- --------- ---- 19 Dawg with a new name {} {} Обычно API REST возвращает объект JSON с использованными и/или обновленными данными. Можно увидеть, что объект был обновлен с помощью метода GET: PS 51> Invoke-RestMethod -ContentType "application/json" -Uri "https://petstore.swagger.io/v2/pet/19" id : 19 category : @{id=45; name=Whatever} name : Dawg with a new name photoUrls : {string} tags : {@{id=0; name=string}} status : available Создание функций Писать эти команды каждый раз вручную может стать довольно утомительным и на самом деле не масштабируемым. Если мы вызываем конечную точку несколько раз, то лучше создать для нее функцию. Это довольно просто и нужно написать всего несколько строк: Function Get-PetstorePet { [cmdletbinding()] param( # Id of the pet [Parameter(Mandatory,ValueFromPipeline)] [int]$Id ) Begin{} Process{ $RestMethodParams = @{ Uri = "https://petstore.swagger.io/v2/pet/$Id" ContentType = "application/json" Method = "GET" } Invoke-RestMethod @RestMethodParams } End{} } После создания функции ее можно вызвать в сценарии: PS51> Get-PetstorePet -Id 1 id name photoUrls tags -- ---- --------- ---- 1 Doggie {http://picture.url} {} Это можно сделать и для метода POST для создания нового объекта pet в Petstore: Function Add-PetstorePet { [cmdletbinding()] param( # Id of the pet [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [int]$Id, # Name of the pet [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string]$Name, # Status of the pet (available, sold etc) [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string]$Status, # Id of the pet category [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [int]$CategoryId, # Name of the pet category [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string]$CategoryName, # URLs to photos of the pet [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [string[]]$PhotoUrls, # Tags of the pets as hashtable array: @{Id=1;Name="Dog"} [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [Hashtable[]]$Tags ) Begin{} Process{ $Body = @{ id = $Id category = @{ id = $CategoryId name = $CategoryName } name = $Name photoUrls = $PhotoUrls tags = $Tags status = $Status } $BodyJson = $Body | ConvertTo-Json $RestMethodParams = @{ Uri = "https://petstore.swagger.io/v2/pet/" ContentType = "application/json" Method = "Post" Body = $BodyJson } Invoke-RestMethod @RestMethodParams } End{} } И вызов этой функции PowerShell намного упрощает задачу: PS51> $AddPetStorePetsParams = @{ Id = 44 Name = "Birdie" Status = "available" CategoryId = 50 CategoryName = "Hawks" PhotoUrls = "https://images.contoso.com/hawk.jpg" Tags = @( @{ Id=10 Name="Not eagles" } ) } PS51> Add-PetStorePet @AddPetStorePetsParams id : 44 category : @{id=50; name=Hawks} name : Birdie photoUrls : {https://images.domain.com/hawk.jpg} tags : {@{id=0}} status : available Возможно, что многие модули, которые вы ежедневно используете, состоят из функций, который за кулисами используют REST API. Заключение Обучение работы с REST API, главным образом основано на чтении документации. Мы использовали документацию на основе SWAGGER в этом посте, так как она представляет, как могут выглядеть другие стили документации. Кроме того, преобразование вызовов API в функцию может сэкономить много времени, упростить работу и очистить сценарии.
img
Почитатей первую часть статьи про траблшутинг NAT/PAT на Cisco. В этой части мы рассмотрим проблемы DHCP. Урок 1 Вот новый сценарий, позвольте мне сначала объяснить его: Зеленая зона - это наша локальная сеть, так что это наш NAT inside. Красная область - это Интернет, поэтому это наш NAT outside. Предполагается, что хост - это компьютер с шлюзом по умолчанию 192.168.12.2. Наш маршрутизатор NAT подключен к маршрутизатору ISP. Маршрутизатор ISP назначил нам подсеть 172.16.1.0 / 24, которую мы собираемся использовать для трансляции NAT. BGP был настроен между NAT и маршрутизатором ISP для доступа к сети 192.168.34.0/24. Предполагается, что веб-сервер прослушивает TCP-порт 80 и использует 192.168.34.3 в качестве шлюза по умолчанию. Однако пользователи нашей локальной сети жалуются на то, что не могут подключиться к веб-серверу. Давайте проверим нашу конфигурацию NAT: Мы можем убедиться, что трансляция работает: Inside local IP-адрес нашего хоста. Inside global находится один из IP-адресов из нашей подсети 172.16.1.0/24. Outside local and global IP-адрес нашего веб-сервера Эта трансляция выглядит хорошо, потому что все IP-адреса верные. Мы видим, что маршрутизатор NAT научился достигать сети 192.168.34.0 / 24 через BGP. Наш NAT-маршрутизатор может подключаться к веб-серверу, поэтому проблема с подключением отсутствует. Однако следует помнить одну важную вещь. Пакет IP, который производит маршрутизатор NAT, выглядит следующим образом: IP-адрес получателя является нашим веб-сервером, и с ним нет проблем. Исходный IP-адрес - 192.168.23.2, и поскольку мы получили ответ, мы знаем, что маршрутизатор ISP знает, как достичь подсети 192.168.23.0 / 24. Это важно, поскольку подсеть 192.168.23.0 / 24 напрямую подключена к маршрутизатору ISP. Однако, если мы отправляем эхо-запрос с хост-устройства, он преобразуется из-за NAT в IP-адрес в подсети 172.16.1.0/24. Пакет IP будет выглядеть так: Вот что происходит, когда этот IP-пакет покидает маршрутизатор NAT и отправляется маршрутизатору ISP: Маршрутизатор ISP получает IP-пакет и проверяет свою таблицу маршрутизации, знает ли он, куда отправлять трафик для сети 192.168.34.0 / 24. Сеть 192.168.34.0/24 напрямую подключена к маршрутизатору ISP, поэтому она выполняет запрос ARP для MAC-адреса веб-сервера, получает ответ ARP и может пересылать IP-пакет на веб-сервер. Веб-сервер хочет ответить, и он создает новый IP-пакет с IP-адресом назначения 172.16.1. Поскольку веб-сервер имеет маршрутизатор ISP в качестве шлюза по умолчанию, он отправит IP-пакет маршрутизатору ISP. Маршрутизатор ISP должен выполнить поиск в таблице маршрутизации, чтобы узнать, знает ли он, где находится сеть 172.16.1.0 / 24. Маршрутизатор ISP не знает, где находится 172.16.1.0 / 24, и отбросит IP-пакет. Если бы это была настоящая производственная сеть, у нас не было бы доступа к маршрутизатору ISP. Так как это эмуляция сети и устройств, к которой у нас есть доступ, поэтому давайте сделаем отладку! ISP#debug ip packet 1 IP packet debugging is on for access list 1 ISP#conf t ISP(config)#access-list 1 permit host 192.168.34.4 Сначала включим отладку IP-пакетов и используем список доступа, который соответствует IP-адресу веб-сервера. Следующим шагом является то, что мы будем генерировать некоторый трафик с хост-устройства. Это то, что будет производить маршрутизатор ISP. Он говорит нам, что понятия не имеет, куда отправить IP-пакет для 172.16.1.1 to...it является не маршрутизируемым и будет отброшен. Так как же мы решим эту проблему? ISP-маршрутизатор требует сеть 172.16.1.0 /24 в таблице маршрутизации. Поскольку мы уже запустили BGP мы можем использовать его для объявления этой сети с нашего маршрутизатора NAT: NAT(config)#ip route 172.16.1.0 255.255.255.0 null 0 NAT(config)#router bgp 1 NAT(config-router)#network 172.16.1.0 mask 255.255.255.0 Сначала мы создадим статическое правило, которое указывает сеть 172.16.1.0 / 24 на интерфейс null0. Мы делаю это потому, что невозможно объявлять то, чего у тебя нет. Следующий шаг-объявить эту сеть в BGP. Пинг прошел проблема решена! Итог урока: убедитесь, что ваши маршрутизаторы знают, как связаться с translated сетями. Урок 2 Начнем с простого сценария. Маршрутизатор с левой стороны - это наш DHCP-клиент, а маршрутизатор с правой стороны - это наш DHCP-сервер. Клиент, однако, не получает никаких IP-адресов ... что может быть не так? Сначала мы проверим, включен ли интерфейс на клиенте DHCP и настроен ли он для DHCP. И это действительно так. Мы также должны убедиться, что интерфейс на сервере DHCP включен/включен и что у него есть IP-адрес. Пока все выглядит хорошо... Если мы хотим быть абсолютно уверенным, что проблема не в клиенте, нам надо применить отладку командой debug dhcp detail, чтобы посмотреть, отправляет ли клиент DHCP сообщения об обнаружении DHCP. Мы видим некоторые отладочные выходные данные, как показано выше. Это говорит о том, что наш DHCP-клиент отправляет сообщения DHCP Discover. Клиент, скорее всего, не является источником этой проблемы. DHCPServer#show ip dhcp pool Мы будем использовать команду show ip dhcp pool, чтобы проверить, существует ли пул DHCP. Вы видите, что у нас есть пул DHCP с именем "MYPOOL", и он настроен для подсети 192.168.12.0 / 24. Пока все выглядит хорошо. Мы можем использовать команду show ip dhcp server statistics, чтобы узнать, что делает сервер DHCP. Вы видите, что он ничего не делает ... что это может значить? Эта команда не часто применяется. show ip sockets показывает нам, на каких портах роутер слушает. Как вы видите, он не прослушивает никакие порты ... если мы не видим здесь порт 67 (DHCP), это означает, что служба DHCP отключена. DHCPServer(config)#service dhcp Включим сервис. Так-то лучше! Теперь мы видим, что маршрутизатор прослушивает порт 67, это означает, что служба DHCP активна. Как только служба DHCP будет запущена, вы увидите, что клиент получает IP-адрес через DHCP ... проблема решена! Итог урока: если все в порядке, убедитесь, что служба DHCP работает. Урок 3 Взгляните на сценарий выше. У нас есть 3 маршрутизатора; маршрутизатор на левой стороне настроен как DHCP-клиент для своего интерфейса FastEthernet0/0. Маршрутизатор с правой стороны настроен как DHCP-сервер. Помните, что DHCP-сообщения об обнаружении от клиентов транслируются, а не пересылаются маршрутизаторами. Вот почему нам требуется команда ip helper на маршрутизаторе в середине, именуемым как relay. Проблема в этом сценарии заключается в том, что клиент не получает IP-адреса через DHCP Сначала мы проверим, что интерфейс настроен для DHCP. Мы определим это с помощью команды show ip interface brief. DHCPClient(config)#interface fastEthernet 0/0 DHCPClient(config-if)#shutdown DHCPClient(config-if)#no shutdown Мы будем переводить интерфейс в режимы up и down для проверки, будет ли он отправлять сообщение DHCP Discover. Мы видим, что сообщения DHCP Discover принимаются на DHCP-сервере. Это означает, что маршрутизатор в середине был настроен с IP helper, в противном случае мы даже не получили бы эти сообщения. Сообщения с предложениями DHCP отправлены, но мы не видим сообщений DHCPACK (Acknowledgment). Это дает нам понять, что что-то происходит... DHCPServer#debug ip dhcp server packet Включим отладку, чтобы увидеть, что происходит. Мы видим, что наш DHCP-сервер пытается достичь IP-адреса 192.168.12.2, это интерфейс FastEthernet0/0 нашего маршрутизатора в середине. Знает ли DHCP-сервер, как добраться до этого IP-адреса? Как вы можете видеть, его нет в таблице маршрутизации, это означает, что IP-пакеты с назначением 192.168.12.2 будут отброшены. Чтобы доказать это, мы можем включить отладку Здесь видим, что IP-адрес назначения 192.168.12.2 не является маршрутизируемым, и в результате IP-пакет будет отброшен. Давайте исправим эту проблему. DHCPServer(config)#ip route 192.168.12.0 255.255.255.0 192.168.23.2 Мы добавим этот статический маршрут, чтобы исправить нашу проблему с подключением. Через некоторое время вы должны увидеть, что клиент получает IP-адрес через DHCP. Если вы оставили "debug ip dhcp server packet" включенным, вы увидите весь процесс DHCP: DHCP Discover DHCP Offer DHCP Request DHCP ACK Вот и все ... проблема решена! Итог урока: если вы используете IP helper, убедитесь, что DHCP-сервер знает, как связаться с подсетью, в которой находится клиент. 3 часть статьи про FHRP траблшутинг на Cisco доступна по ссылке.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59