2017-02-10 12 views
0

Я написал небольшой скрипт Python, который должен получить доступ к API контейнера IBM Bluemix, описанному here, используя модуль requests Python.Значок аутентификации IBM Bluemix всегда недействителен

Вот сценарий:

""" 
You can run this script for example as follows: 

python test-script.py \ 
--user <YOUR IBM BLUEMIX USER NAME> \ 
--ca-certificate <PATH TO YOUR ca.pem> \ 
--oauth-token "$(cf oauth-token)" \ 
--space-id "$(cf space dev --guid)" \ 
--request-url https://containers-api.ng.bluemix.net/v3/containers/version \ 
--method GET 

The request-url is an EXAMPLE! 
""" 

import argparse 
import getpass 
import requests 
import json 

# for parsing arguments provided on command line 
parser = argparse.ArgumentParser() 
parser.add_argument(
    '-u', '--user', 
    required=True, 
    help='Specify the username for IBM Bluemix.', 
) 
parser.add_argument(
    '-c', '--ca-certificate', 
    required=True, 
    help='Specify the location of the certificate of the trusted certification authority (ca.pem).' 
) 
parser.add_argument(
    '-t', '--oauth-token', 
    required=True, 
    help='Specify your IBM Bluemix oauth-token.' 
) 
parser.add_argument(
    '-s', '--space-id', 
    required=True, 
    help='Specify your IBM Bluemix space id (cf space <your space> --guid). Beware, the space needs to be available in the region you are logged in to (US South, United Kindom).' 
) 
parser.add_argument(
    '-l', '--request-url', 
    required=True, 
    default='https://containers-api.ng.bluemix.net/v3/containers/version', 
    help='Specify the URL you want to send the request to.' 
) 
parser.add_argument(
    '-m', '--method', 
    default='GET', 
    help='Specify the HTTP method.' 
) 

args = parser.parse_args() 

def run_script(): 
    password = getpass.getpass(prompt='IBM Bluemix password:') 
    # for now hard coded 
    headers = { 
     'Accept': 'application/json', 
     'X-Auth-Token': args.oauth_token, 
     'X-Auth-Project-Id': args.space_id 
    } 

    # first we get the appropriate HTTP request method 
    request_method = getattr(requests, args.method.lower()) 

    # then we try to make the request with that method 
    try: 
     response = request_method(
      args.request_url, 
      auth=(args.user, password), 
      data=None, # expects a dict or json.dumps return type 
      verify=args.ca_certificate, 
      headers=headers 
     ) 
     print(response) 
     print(response.json()) 
    except Exception as exc: 
     print('ERROR!') 

def main(): 
    try: 
     run_script() 
    except KeyboardInterrupt as exc: 
     exit('Interrupted, exiting ...') 

main() 

Этот скрипт я вызываю с:

python script.py \ 
--user <IBM Bluemix login name> \ 
--ca-certificate /home/<USER>/.ice/certs/containers-api.eu-gb.bluemix.net/<ID>/ca.pem \ 
--oauth-token "$(cf oauth-token)" \ 
--space-id "$(cf space dev --guid)" \ 
--request-url https://containers-api.ng.bluemix.net/v3/images/json \ 
--method GET 

Для параметра --user Я попробовал несколько вещей:

  • первое имя плюс фамилия с страницы панели инструментов IBM Bluemix с пробелом между строками между двумя "
  • полный адрес электронной почты я использовал для регистрации, также помечены User:, когда я cf login
  • название организации, которая отображается, когда я cf login

Что касается --space-id и аутентификации маркера --oauth-token: Документация самого APi говорит мне, чтобы я получил их так, как я. Я также попытался предоставить их с помощью копии & пасты вывода подкоманд, которые я использовал, а также напечатал их из скрипта, чтобы убедиться, что все это попало внутрь скрипта. Оно делает.

Значение параметра --request-url Я также получил из документации по API, используя кнопку «Попробовать» и скопировав URL-адрес из команды curl, которая была использована для попытки, так что это также должно быть правильно.

Однако в каждом запросе, который требовал аутентификации, например, для перечисления всех изображений в пространстве, я получаю ответ от API 401, говоря, что токен аутентификации недействителен и что я должен попытаться сделать cf login и cf ic init. Выполнено, что не меняет токен или что-то еще и не исправляет ошибку.

Вот пример ответа я получаю:

<Response [401]> 
{'code': 'IC5097E', 
'description': "Authentication was not successful: bearer <SOME ID> Please login via 'cf login ...' + 'cf ic init ...' and try again.", 
'environment': 'prod-dal09', 
'host_id': '176', 
'incident_id': '<SOME ID>', 
'name': 'InvalidToken', 
'rc': '401', 
'type': 'Infrastructure'} 

(я сломал линии, чтобы сделать его более удобным для чтения здесь на SO)

Так интересно, что я делаю неправильно с маркером. Как создать правильный запрос с помощью токена аутентификации?

Редактировать # 1

Я также декодируются веб-токен JSON с помощью https://jwt.io/. Он показывает, что имя пользователя, которое я ввело, действительно тот, который содержит токен.

Edit # 2

Я также проверил (снова) для пространства будут доступны:

IBM Bluemix Dashboard spaces overview

Как вы можете видеть, что есть пространство по имени dev в обоих регионах.

ответ

1

Похоже, вы смешиваете регионы Великобритании и США - я вижу сертификат для eu-gb.bluemix.net и сервера US API. Это может быть проблемой. У меня есть только место в США, поэтому я не могу это проверить, но ...

Если вы работаете с пространством в Великобритании, используйте cert-api.eu-gb.bluemix.net cert и UK region api server: https://containers-api.eu-gb.bluemix.net

Если вы работаете с пространством в США, используйте cert для container-api.ng.bluemix.net и используйте этот сервер API.

+0

Это решило проблему. Я был зарегистрирован в 1 регионе, но использовал API другого, считая его независимым. Тогда 'cf oauth-token' вернул неверный токен для URL-адреса запроса. Также нужно знать, что нельзя использовать полный вывод 'cf oauth-token', но только все после« носителя »(это пространство носителя). – Zelphir