Ошибка 422 при использовании Powershell для обновления записей DNS в API GoDaddy

Я пытаюсь обновить свой DNS с помощью GoDaddy через их API (моя домашняя сеть имеет динамический IP-адрес).

Я могу успешно обновлять при использовании скрипта, найденного на http://teanazar.com/2016/05/godaddy-ddns-updater/ при запуске через cygwin.

Однако я пытаюсь просто вещи, и сделать это в PowerShell вместо этого.

Однако при попытке использовать следующий скрипт:

$IP = Invoke-WebRequest http://api.ipify.org?format=json
$IP2 = ConvertFrom-JSON $ip
$domain = 'example.com'
$type = 'A'
$name = '@'

$key = 'key'
$secret = 'secret'


$Request = @{ttl='600';data=$ip2.ip;priority='1'}

$JSON = Convertto-Json $request

$headers = @{}
$headers["Authorization"] = 'sso-key ' + $key + ':' + $secret

Invoke-WebRequest    https://api.godaddy.com/v1/domains/$domain/records/$Type/$Name -contenttype "application/json" -method put -body $json -headers $headers

До сих пор мне удавалось проработать каждую проблему, и я знаю, что это проверка подлинности. Но когда я выполняюсь, я получаю "Удаленный сервер возвратил ошибку: (422) Unprocessable Entity

6 ответов

Я использовал реализацию, основанную на решении, предоставленном drizin... и до недавнего времени она работала очень хорошо.

Кажется, что GoDaddy ужесточил проверку JSON, и теперь он завершается ошибкой со следующей ошибкой:

{
  "code": "INVALID_BODY",
  "fields": [
    {
      "code": "UNEXPECTED_TYPE",
      "message": "is not a array",
      "path": "records"
    }
  ],
  "message": "Request body doesn't fulfill schema, see details in `fields`"
}

Согласно спецификации для API по адресу https://developer.godaddy.com/doc/endpoint/domains отправляемый JSON должен быть массивом... т.е. [ { ... } ] где код создает { ... },

Чтобы это исправить, требуется простое изменение строки кода, которая создает JSON...

От:

$JSON = ConvertTo-Json @{data=$IP;ttl=3600}

Для того, чтобы:

$JSON = ConvertTo-Json @(@{data=$IP;ttl=3600})

Сделайте ключ производства на Годди. Тестовый ключ у меня не работал.

И ваш ттл должен быть целым числом. не строка, удалите '' из него.

(и измените свой @ на%40)

$IP = Invoke-WebRequest http://api.ipify.org?format=json
$IP2 = ConvertFrom-JSON $ip
$domain = 'example.com'
$type = 'A'
$name = 'Test'

$key = 'key'
$secret = 'secret'


[array]$Request=@{data=$IP2.ip; "port"=1; "priority"=0; "protocol"="none"; "service"="none"; "ttl"=3600; "weight"=1}

$JSON = Convertto-Json $request

$headers = @{}
$headers["Authorization"] = 'sso-key ' + $key + ':' + $secret


Invoke-WebRequest    https://api.godaddy.com/v1/domains/$domain/records  -method get -headers $headers
Invoke-WebRequest    https://api.godaddy.com/v1/domains/$domain/records/A/Test  -method put -headers $headers -Body $json -ContentType "application/json"

Похоже, GoDaddy обновил API. Обновлено решение, включив требование "массив" для JSON, а также дополнительные поля, которые теперь, по-видимому, также являются обязательными.

Чтобы решить эту проблему, я бы сначала порекомендовал вам начать с GET работа той же конечной точки. Что вы видите, когда запускаете эту команду?

Invoke-WebRequest   https://api.godaddy.com/v1/domains/$domain/records `
  -contenttype "application/json" -method GET -headers $headers

Давайте проверим, какие данные GoDaddy покажет вам через эту конечную точку. Может быть, у них другая терминология для создания @ запись? Есть много способов, которыми мы могли бы столкнуться с проблемами.

Дайте мне знать, что вы видите здесь, и мы будем работать над решением.

Я смог заставить его работать со следующим:

$apiKey = 'YOUR API KEY'
$apiSecret = 'YOUR API SECRET'
$domain = 'YOUR DOMAIN NAME'
#ENTER THE NAME OF THE RECORD YOU WISH TO UPDATE#
$name = '@'
$Headers = @{}
$Headers["Authorization"] = 'sso-key ' + $apiKey + ':' + $apiSecret
$result = Invoke-WebRequest https://api.godaddy.com/v1/domains/$domain/records/A/$name -method get -headers $headers
$content = ConvertFrom-Json $result.content
$dnsIp = $content.data
$currentIp = Invoke-RestMethod http://ipinfo.io/json | Select -exp ip
#THIS SECTION CHECKS THE CURRENT IP ADDRESS AGAINST THE PULL AND WILL UPDATE IF NOT CORRECT#
if ( $currentIp -ne $dnsIp) {
    #$Request = @{ttl=600;data=$currentIp }
    $JSON = ConvertTo-Json @(@{data=$currentIp;ttl=600})
    Invoke-WebRequest https://api.godaddy.com/v1/domains/$domain/records/A/$name -method put -headers $headers -Body $json -ContentType "application/json"

}
#SHOWS RESULTS OF THE HEADER PULL
Invoke-WebRequest https://api.godaddy.com/v1/domains/$domain/records/ -Method Get -Headers $Headers | ConvertFrom-Json

Запись A устанавливается в строке 20, а не является именем VAR $, а TTL устанавливается в 1 в строке 11, я думаю, что godaddy пинает ее при этом значении. установите TTL на 3600 и вставьте переменную на 20, это должно работать, в любом случае, у меня получилось.

Спасибо за указатель:)

$IP = Invoke-WebRequest http://api.ipify.org?format=json
$IP2 = ConvertFrom-JSON $ip
$domain = 'domain.co.uk'
$type = 'A'
$name = 'record'

$key = 'blahhhhh'
$secret = 'blahhh'


$Request = @{ttl=3600;data=$ip2.ip}

$JSON = Convertto-Json $request

$headers = @{}
$headers["Authorization"] = 'sso-key ' + $key + ':' + $secret


Invoke-WebRequest    https://api.godaddy.com/v1/domains/$domain/records  -method get -headers $headers
Invoke-WebRequest    https://api.godaddy.com/v1/domains/$domain/records/A/$name  -method put -headers $headers -Body $json -ContentType "application/json"

Go Daddy имеет некоторые ограничения по типу (TTL должен быть числовым, Priority должен быть числовым [обратите внимание, что приоритет должен использоваться только для записей SRV]), а также некоторые бизнес-ограничения (например, заставить TTL быть не менее 600, что составляет 10 минут) и т. Д.,

Вы можете обратиться к их API здесь, где вы можете увидеть примеры данных, а также попробовать команды и увидеть сообщения об ошибках.

С другой стороны, если вы предпочитаете видеть сообщения об ошибках непосредственно в powershell, поскольку свойство Content недоступно при получении ошибки HTTP, вы должны извлечь сообщение об ошибке из потока ответов, как описано здесь.

Полный образец с обработкой ошибок:

$IPj = Invoke-WebRequest http://api.ipify.org?format=json
$IP = (ConvertFrom-JSON $IPj).ip
$domain = 'mydomain.com'
$type = 'A'
$alias = 'myalias' # myalias.mydomain.com

$key = 'etc'
$secret = 'etc'

$JSON = ConvertTo-Json @{data=$IP;ttl=3600}
# you can also use an array of values: @(@{data=$IP1;ttl=3600},@{data=$IP2;ttl=3600},etc...)

$headers = @{}
$headers["Authorization"] = 'sso-key ' + $key + ':' + $secret

try {
    $ret = Invoke-WebRequest https://api.godaddy.com/v1/domains/$domain/records/$type/$alias  -method put -headers $headers -Body $json -ContentType "application/json"
    if ($ret.StatusCode -eq 200) { Write-Host "Success!" -for yellow } else { Write-Host "ERROR" -for red }
}
catch {
    $result = $_.Exception.Response.GetResponseStream()
    $reader = New-Object System.IO.StreamReader($result)
    $reader.BaseStream.Position = 0
    $reader.DiscardBufferedData()
    $responseBody = $reader.ReadToEnd();
    $responseBody = $responseBody | ConvertFrom-Json | Format-Custom | Out-String
    Write-Host "ERROR: $responseBody" -for red
}
Другие вопросы по тегам