Проблема с командами AWS CLI/запросом JMESPATH

Может ли кто-нибудь из вас помочь мне определить проблему с командами CLI /запросами JMESPATH в разделе «Что не работает?» ниже.

P.S. Вывод JSON, приведенный ниже, действителен, и вы можете использовать его для проверки части запроса JMESPATH на JMESPATH.org.

Что работает?

1) aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[]
2) aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[].FromPort
3) aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[].IpProtocol

Что не работает?

1) aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[?IpProtocol=='tcp'].IpProtocol
2) aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[?FromPort=='22'].FromPort

ВЫВОД JSON

{
    "SecurityGroups": [
        {
            "Description": "default VPC security group",
            "GroupName": "default",
            "IpPermissions": [
                {
                    "IpProtocol": "-1",
                    "IpRanges": [],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "UserIdGroupPairs": [
                        {
                            "GroupId": "sg-06d7c8d3300000000",
                            "UserId": "400000000000"
                        }
                    ]
                }
            ],
            "OwnerId": "400000000000",
            "GroupId": "sg-06d7c000000000000",
            "IpPermissionsEgress": [
                {
                    "IpProtocol": "-1",
                    "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "UserIdGroupPairs": []
                }
            ],
            "VpcId": "vpc-0d26c7ba200000000"
        },
        {
            "Description": "BastionSG",
            "GroupName": "BastionSG",
            "IpPermissions": [
                {
                    "FromPort": 22,
                    "IpProtocol": "tcp",
                    "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "ToPort": 22,
                    "UserIdGroupPairs": []
                }
            ],
            "OwnerId": "400000000000",
            "GroupId": "sg-0a26abc0a00000000",
            "IpPermissionsEgress": [
                {
                    "IpProtocol": "-1",
 "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "UserIdGroupPairs": []
                }
            ],
            "VpcId": "vpc-0d26c7ba200000000"
        }
    ]
}

Ожидаемые/фактические результаты

aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[?IpProtocol=='tcp'].IpProtocol

Результат

Ожидаемый - tcp, фактический - не возвращает результат

aws ec2 describe-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[?FromPort=='22'].FromPort

Результат

Ожидаемое - 22, фактическое - не возвращает результат


person ykm    schedule 02.01.2019    source источник
comment
Я попытался использовать онлайн-оценщик JMESPATH по адресу jmespath.org, и, похоже, он не поддерживает фильтры в отфильтрованных результатах. Грамматика ABNF описывает list-filter-expr, но затем не может ссылаться на это где-либо еще в грамматике (что предположительно является ошибкой в ​​​​документации). Я предполагаю, что JMESPATH просто не поддерживает такое использование. Вы можете обсудить это с ними по адресу gitter.im/jmespath/ чат.   -  person jarmod    schedule 03.01.2019
comment
Это как бы работало на моем Mac с aws ec2 describe-security-groups --query 'SecurityGroups[].IpPermissions[?FromPort==`22`].FromPort', но также давало пустые наборы.   -  person John Rotenstein    schedule 03.01.2019
comment
@JohnRotenstein, мы только что нашли ошибку в интерфейсе командной строки AWS?   -  person ykm    schedule 03.01.2019
comment
Честно говоря, мне проще запрашивать такую ​​информацию через SDK, чем пытаться заставить JMESPath выдать конкретный результат. Например: JMESPath спускается по дереву для фильтра   -  person John Rotenstein    schedule 03.01.2019
comment
Я тоже потратил некоторое время на это, и я также думаю, что JMESPath не работает.   -  person Alex Harvey    schedule 03.01.2019
comment
@AlexHarvey Я не думаю, что он сломан. проверьте мой ответ. Это просто проблема с использованием одинарных и обратных кавычек в нужных местах. Дай мне знать. @John, так как IpPermissions - это массив, который вам нужно передать отфильтрованному массиву и извлечь из него FromPort.   -  person Imran    schedule 06.01.2019


Ответы (2)


Вот те, которые я попробовал и получил ожидаемые данные. Дайте мне знать, если это работает для вас.

aws ec2 describe-security-groups --query 'SecurityGroups[?GroupId==`sg-xxxxxx`].[IpPermissions[?IpProtocol==`tcp`] | [0].IpProtocol]' --output text
//tcp
aws ec2 describe-security-groups --query 'SecurityGroups[?GroupId==`sg-xxxxxx`].[IpPermissions[?FromPort==`22`] | [0].FromPort]' --output text
//22

Примечание -

  1. Лучше заключать запрос в одинарные кавычки, чтобы CLI мог правильно проанализировать весь запрос.
  2. Вы можете заполнить условия обратной кавычкой (`).
person Imran    schedule 05.01.2019
comment
Я могу ошибаться, но это похоже на обходной путь к нарушению JMESPath, и я до сих пор не могу понять, почему необходимо принуждать к массиву, а затем снова брать первый элемент этого массива. - person Alex Harvey; 06.01.2019
comment
@AlexHarvey Я абсолютно согласен. Наличие такого выражения, как IpPermissions[?IpProtocol==tcp].IpProtocol, делает его очень простым, и я, привыкнув к jq выражениям, хочу попробовать только этот способ. Кстати, в приведенном выше выражении [0] не нужно, и вы можете указать [].IpProtocol, поскольку массив уже отфильтрован до одной строки. - person Imran; 06.01.2019
comment
Я вижу проблему с JMESPATH, и это связано с кавычками и их использованием. Это работает, только если вы ставите или используете их определенным образом. Ниже приведены несколько тестов, которые я провел с различными комбинациями кавычек. Это также сбивает с толку, когда вы не уверены, какой из них использовать. Я не уверен, есть ли какая-либо документация по использованию кавычек. Пожалуйста, найдите мои тесты в комментариях ниже. - person ykm; 07.01.2019
comment
Test1 -> NoOutsideQuotes/DoubleQuotes ------------------------------------- aws ec2 description-security-groups --query SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxx].IpPermissions[] Результат: неверное значение для --query SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxxx].IpPermissions[]: Ожидается: rbracket, получено: число: Ошибка синтаксического анализа в столбце 27, токен 0 (ЧИСЛО), для выражения: SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxxx].IpPermissions[] - person ykm; 07.01.2019
comment
Test2 -> NoOutSideQuotes/SingleQuotes-> aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-xxxxxxxxxxxxxxxxxx'].IpPermissions[] Result-> Неверное значение для --query SecurityGroups[?GroupId==sg -xxxxxxxxxxxxxxxxx].IpPermissions[]: Ожидается: rbracket, получено: число: Ошибка синтаксического анализа в столбце 27, токен 0 (ЧИСЛО), для выражения: SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxx].IpPermissions[] - person ykm; 07.01.2019
comment
Test3 -> OutSideDoubleQuotes/SingleQuotes-> aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-xxxxxxxxxxxxxxxxxx'].IpPermissions[] Result-› [ { FromPort: 22, IpProtocol: tcp, IpRanges: [ { CidrIp: 0.0.0.0/0 } ], Ipv6Ranges: [], PrefixListIds: [], ToPort: 22, UserIdGroupPairs: [] } ] - person ykm; 07.01.2019
comment
Test4 -> OutSideSingleQuotes/DoubleQuotes -> aws ec2 description-security-groups --query 'SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxxx].IpPermissions[]' Result-› [] - person ykm; 07.01.2019
comment
Test5 -> OutSideDoubleQuotes/BackQuotes-> aws ec2 description-security-groups --query SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxx].IpPermissions[] Результат-> bash: sg-xxxxxxxxxxxxxxxxxxx: команда не найдена Неверное значение для --query SecurityGroups[ ?GroupId==].IpPermissions[]: неверный токен: ошибка синтаксического анализа в столбце 25, токен ] (RBRACKET), для выражения: SecurityGroups[?GroupId==].IpPermissions[] - person ykm; 07.01.2019
comment
Test6 -> OutSideSingleQuotes/BackQuotes -> aws ec2 description-security-groups --query 'SecurityGroups[?GroupId==sg-xxxxxxxxxxxxxxxxx].IpPermissions[]' Результат-> [ { FromPort: 22, IpProtocol: tcp, IpRanges: [ { CidrIp : 0.0.0.0/0 } ], Ipv6Ranges: [], PrefixListIds: [], ToPort: 22, UserIdGroupPairs: [] } ] - person ykm; 07.01.2019
comment
@ykm Я понимаю, что вы новичок в stackoverflow, но давайте решать одну проблему за раз. в чем ошибка, которую вы получаете, когда пытаетесь использовать способ, который я показал в ответе? 1. Держите запрос в одинарных кавычках. 2. условия в кавычках. Я думаю, вы пробовали под Test6. Результат Test6 не то, что вы ищете? - person Imran; 07.01.2019
comment
@Imran Имран, спасибо, я проверил оба ваших запроса. Они работают нормально, и я получаю ожидаемый ответ. Кстати, с чего вы взяли, что я новичок в stackoverflow :)? или это действительно имеет значение? - person ykm; 07.01.2019
comment
@ykm Я получил кучу уведомлений одно за другим :) вы можете подождать моего ответа и позволить нам решить одну проблему за раз :) - person Imran; 07.01.2019
comment
@ykm, если вы согласны с моим ответом, тогда вы можете принять ответ :) Ниже я нашел несколько предложений по литералам, используемым в jmespath, если они вам полезны. jmespath.org/proposals/filter-expressions.html . jmespath.org/proposals/raw-string-literals.html - person Imran; 07.01.2019
comment
@imran, причина была в том, что я не мог уместить все результаты своих тестов в один комментарий. Я приму ваш ответ и еще раз спасибо. - person ykm; 08.01.2019
comment
@ykm Я думаю, вы запутались в синтаксисе кавычек bash и jmespath. - person james.haggerty; 13.01.2019
comment
jmespath (как описано на jmespath.org). Для этого вам нужно знать, что одинарные кавычки = строка json, обратные кавычки = все внутри является необработанным выражением json. Цитаты Баша... эх, кошмар. Я считаю, что использование @Imran обратных кавычек для строки здесь является ошибкой в ​​​​реализации Python jmespath. Это не работает для Go. - person james.haggerty; 13.01.2019
comment
(в частности, я считаю, что пункт (2) неверен - одинарные кавычки должны быть простым способом создания строкового литерала JSON и не всегда «используются для условий». Для 22 нам нужен номер JSON, поэтому мы нельзя использовать одинарные кавычки). - person james.haggerty; 13.01.2019

SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?IpProtocol=='tcp'].IpProtocol | [0]

SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==`22`].FromPort | [0]

Или, цитируется/скорректировано для bash:

'SecurityGroups[?GroupId==`"sg-0a26abc0a00000000"`].IpPermissions[] | [?IpProtocol==`"tcp"`].IpProtocol | [0]'

'SecurityGroups[?GroupId==`"sg-0a26abc0a00000000`"].IpPermissions[] | [?FromPort==`22`].FromPort | [0]'

Вы заметите [] в конце IpPermissions, что сглаживает список. Если вы этого не сделаете (или сделаете SecurityGroups[?GroupId=='sg-0a26abc0a00000000'][]), фильтр будет применяться к верхнему уровню списка, где IpPermissions не существует.

Почему это правда, мне непонятно. Это кажется неправильным, потому что без более раннего фильтра к подсписку применяется более поздний фильтр.

person james.haggerty    schedule 03.01.2019
comment
пожалуйста, найдите результаты теста ниже после использования вашего модифицированного запроса jmespath - person ykm; 04.01.2019
comment
$ aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?IpProtocol=='tcp'].IpProtocol | [0] - person ykm; 04.01.2019
comment
bash: [?IpProtocol==tcp].IpProtocol: команда не найдена bash: 0: команда не найдена Исключение игнорируется в: ‹_io.TextIOWrapper name='‹stdout›' mode='w' encoding='cp1252'› OSError: [Errno 22] Неверный аргумент - person ykm; 04.01.2019
comment
Вам нужно правильно указать запрос, чтобы bash не интерпретировал канал. В этом случае я бы предложил использовать двойные кавычки вокруг всего этого, это будет проще всего. - person james.haggerty; 04.01.2019
comment
Трюк с двойными кавычками работал для текста - IpProtocol='tcp', но не для номера FromPort=22. Пожалуйста, найдите результаты ниже - person ykm; 04.01.2019
comment
Результат без кавычек - aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0] Неверное значение --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0]: неверный токен: ошибка синтаксического анализа в столбце 79, токен 22 (ЧИСЛО), для выражения: SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0] - person ykm; 04.01.2019
comment
Результат для одиночной кавычки - aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort=='22'].FromPort | [0] ноль - person ykm; 04.01.2019
comment
Результат для двойных кавычек - aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0] Неверное значение --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0]: неверный токен: ошибка синтаксического анализа в столбце 79, токен 22 (ЧИСЛО), для выражения: SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0] - person ykm; 04.01.2019
comment
aws ec2 description-security-groups --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==22].FromPort | [0] bash: 22: команда не найдена Неверное значение для --query SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==].FromPort | [0]: недопустимый токен: ошибка синтаксического анализа в столбце 79, токен ] (RBRACKET), для выражения: SecurityGroups[?GroupId=='sg-0a26abc0a00000000'].IpPermissions[] | [?FromPort==].FromPort | [0] - person ykm; 04.01.2019
comment
К сожалению, ни один из них не имеет правильного содержания. Самое простое, наверное, это: 'SecurityGroups[?GroupId==`"sg-0a26abc0a00000000"`].IpPermissions[] | [?FromPort==`22`].FromPort | [0]' (извините, я забыл об особом значении обратных кавычек - я не использую оболочку Борна;)) - person james.haggerty; 04.01.2019
comment
Странно, это только номер. - person ykm; 05.01.2019
comment
Используете ли вы awscli? - person ykm; 05.01.2019
comment
Часто. Вы пробовали последнее выражение? Вы либо не можете скопировать исходное выражение, либо неправильно цитируете его для bash. Последнее, что я дал, должно быть правильным для bash. Ошибка «числа», как и ожидалось: вы пытаетесь либо сравнить его со строкой (одинарная кавычка jmespath), выполнить ее (обратные кавычки bash), интерпретировать ее как номер jmespath, а не номер json (без кавычек). Вам нужно использовать ТОЛЬКО обратные кавычки и избегать их интерпретации bash, как показано в моем последнем комментарии. - person james.haggerty; 13.01.2019