Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ notifications:

matrix:
include:
- python: 3.5
- python: 3.6
- python: 3.7
- python: 3.8
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Service Name | Imported Class Name

* An [IBM Cloud][ibm-cloud-onboarding] account.
* An IAM API key to allow the SDK to access your account. Create one [here](https://cloud.ibm.com/iam/apikeys).
* Python 3.5.3 or above.
* Python 3.6 or above.

## Installation

Expand Down
29 changes: 24 additions & 5 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
## Running example.py

To run the example, create a Code Engine project from the Console or Code Engine CLI, and run the following commands from this directory:
1. `pip3 install kubernetes`
1. `pip install kubernetes`
2. `export CE_API_KEY=<Your IBM Cloud API key>`
3. `export CE_PROJECT_ID=<Your Code Engine project ID>`
4. `export CE_PROJECT_REGION=<The region (e.g. 'us-south') of your Code Engine project>`
5. `python3 example.py`
5. `python example.py`

Note: Requires Python 3.6 or later.

## How-to

Expand All @@ -28,11 +30,28 @@ ce_client.set_service_url(
)
```

### Use an HTTP library to get a Delegated Refresh Token from IAM
```python
iam_response = requests.post('https://iam.cloud.ibm.com/identity/token', headers={
'Content-Type': 'application/x-www-form-urlencoded'
}, data={
'grant_type': 'urn:ibm:params:oauth:grant-type:apikey',
'apikey': os.environ.get('CE_API_KEY'),
'response_type': 'delegated_refresh_token',
'receiver_client_ids': 'ce',
'delegated_refresh_token_expiry': '3600'
})
delegated_refresh_token = iam_response.json()['delegated_refresh_token']
```

### Use the Code Engine client to get a Kubernetes config
```python
refresh_token = authenticator.token_manager.request_token().get('refresh_token')
kubeconfig_response = ce_client.list_kubeconfig(
refresh_token=refresh_token,
kubeconfig_response = ce_client.get_kubeconfig(
x_delegated_refresh_token=delegated_refresh_token,
id=os.environ.get('CE_PROJECT_ID'),
)
kubeconfig_string = kubeconfig_response.get_result().content
```

## Deprecated endpoint
The `/namespaces/{id}/config` endpoint function, `list_kubeconfig()`, is deprecated, and will be removed before Code Engine is out of Beta. Please use the `get_kubeconfig()` function, demonstrated in the example above.
22 changes: 17 additions & 5 deletions example/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import os
import tempfile
import kubernetes
import requests
import json
from ibm_code_engine_sdk.ibm_cloud_code_engine_v1 import IbmCloudCodeEngineV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

Expand All @@ -29,18 +31,28 @@
'https://api.' + os.environ.get('CE_PROJECT_REGION') + '.codeengine.cloud.ibm.com/api/v1'
)

# Get IAM tokens using the authenticator
refresh_token = authenticator.token_manager.request_token().get('refresh_token')
# Get a Delegated Refresh Token from IAM
iam_response = requests.post('https://iam.cloud.ibm.com/identity/token', headers={
'Content-Type': 'application/x-www-form-urlencoded'
}, data={
'grant_type': 'urn:ibm:params:oauth:grant-type:apikey',
'apikey': os.environ.get('CE_API_KEY'),
'response_type': 'delegated_refresh_token',
'receiver_client_ids': 'ce',
'delegated_refresh_token_expiry': '3600'
})
delegated_refresh_token = iam_response.json()['delegated_refresh_token']

# Get Code Engine project config using the Code Engine client.
kubeconfig_response = ce_client.list_kubeconfig(
refresh_token=refresh_token,
kubeconfig_response = ce_client.get_kubeconfig(
x_delegated_refresh_token=delegated_refresh_token,
id=os.environ.get('CE_PROJECT_ID'),
)
kubeconfig_string = kubeconfig_response.get_result().content

# Setup Kubernetes client using project config
kubeconfig_file, kubeconfig_filename = tempfile.mkstemp()
os.write(kubeconfig_file, kubeconfig_response.get_result().content)
os.write(kubeconfig_file, kubeconfig_string)
kubernetes.config.load_kube_config(config_file=kubeconfig_filename)
kube_client = kubernetes.client.CoreV1Api()

Expand Down
55 changes: 55 additions & 0 deletions example/example_deprecated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""
Example of IBM Cloud Code Engine SDK usage
"""

import os
import tempfile
import kubernetes
from ibm_code_engine_sdk.ibm_cloud_code_engine_v1 import IbmCloudCodeEngineV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

if (os.environ.get('CE_API_KEY') == None or
os.environ.get('CE_PROJECT_REGION') == None or
os.environ.get('CE_PROJECT_ID') == None):
print(
'You must set the envrionment variables CE_API_KEY, CE_PROJECT_REGION and CE_PROJECT_ID ' +
'before using the example.'
)

# Create an IAM authenticator.
authenticator = IAMAuthenticator(
apikey=os.environ.get('CE_API_KEY'),
client_id='bx',
client_secret='bx',
)

# Construct the Code Engine client.
ce_client = IbmCloudCodeEngineV1(authenticator=authenticator)
ce_client.set_service_url(
'https://api.' + os.environ.get('CE_PROJECT_REGION') + '.codeengine.cloud.ibm.com/api/v1'
)

# Get IAM tokens using the authenticator
refresh_token = authenticator.token_manager.request_token().get('refresh_token')

# Get Code Engine project config using the Code Engine client.
kubeconfig_response = ce_client.list_kubeconfig(
refresh_token=refresh_token,
id=os.environ.get('CE_PROJECT_ID'),
)
kubeconfig_string = kubeconfig_response.get_result().content

# Setup Kubernetes client using project config
kubeconfig_file, kubeconfig_filename = tempfile.mkstemp()
os.write(kubeconfig_file, kubeconfig_string)
kubernetes.config.load_kube_config(config_file=kubeconfig_filename)
kube_client = kubernetes.client.CoreV1Api()

# Get something from project.
contexts = kubernetes.config.list_kube_config_contexts(config_file=kubeconfig_filename)[0][0]
namespace = contexts.get('context').get('namespace')
configmaps = kube_client.list_namespaced_config_map(namespace)
print(
'Project ' + os.environ.get('CE_PROJECT_ID') +
' has ' + str(len(configmaps.items)) + ' configmaps.'
)
125 changes: 108 additions & 17 deletions ibm_code_engine_sdk/ibm_cloud_code_engine_v1.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# coding: utf-8

# (C) Copyright IBM Corp. 2020.
# (C) Copyright IBM Corp. 2021.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -14,10 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# IBM OpenAPI SDK Code Generator Version: 3.12.0-64fe8d3f-20200820-144050
# IBM OpenAPI SDK Code Generator Version: 3.15.0-45841b53-20201019-214802

"""
The purpose is to provide an API to get Kubeconfig for IBM Cloud Code Engine Project
The purpose is to provide an API to get Kubeconfig file for IBM Cloud Code Engine Project
"""

from enum import Enum
Expand Down Expand Up @@ -81,20 +81,22 @@ def list_kubeconfig(self,
**kwargs
) -> DetailedResponse:
"""
Retrieve KUBECONFIG for a specified project.
Deprecated soon: Retrieve KUBECONFIG for a specified project.

Returns the KUBECONFIG, similar to the output of `kubectl config view
--minify=true`.
**Deprecated soon**: This API will be deprecated soon. Use the [GET
/project/{id}/config](#get-kubeconfig) API instead. Returns the KUBECONFIG file,
similar to the output of `kubectl config view --minify=true`.

:param str refresh_token: The IAM Refresh token associated with the IBM
Cloud account.
:param str id: The id of the IBM Cloud Code Engine project.
:param str accept: (optional) The type of the response: application/json or
text/html. A character encoding can be specified by including a `charset`
parameter. For example, 'text/html;charset=utf-8'.
Cloud account. To retrieve your IAM token, run `ibmcloud iam oauth-tokens`.
:param str id: The id of the IBM Cloud Code Engine project. To retrieve
your project ID, run `ibmcloud ce project get -n <PROJECT_NAME>`.
:param str accept: (optional) The type of the response: text/plain or
application/json. A character encoding can be specified by including a
`charset` parameter. For example, 'text/plain;charset=utf-8'.
:param dict headers: A `dict` containing the request headers
:return: A `DetailedResponse` containing the result, headers and HTTP status code.
:rtype: DetailedResponse
:rtype: DetailedResponse with `str` result
"""

if refresh_token is None:
Expand All @@ -113,8 +115,82 @@ def list_kubeconfig(self,
if 'headers' in kwargs:
headers.update(kwargs.get('headers'))

url = '/namespaces/{0}/config'.format(
*self.encode_path_vars(id))
path_param_keys = ['id']
path_param_values = self.encode_path_vars(id)
path_param_dict = dict(zip(path_param_keys, path_param_values))
url = '/namespaces/{id}/config'.format(**path_param_dict)
request = self.prepare_request(method='GET',
url=url,
headers=headers)

response = self.send(request)
return response


def get_kubeconfig(self,
x_delegated_refresh_token: str,
id: str,
*,
accept: str = None,
**kwargs
) -> DetailedResponse:
"""
Retrieve KUBECONFIG for a specified project.

Returns the KUBECONFIG, similar to the output of `kubectl config view
--minify=true`. There are 2 tokens in the Request Header and a query parameter
that you must provide.
These values can be generated as follows: 1. Auth Header Pass the generated IAM
Token as the Authorization header from the CLI as `token=cat
$HOME/.bluemix/config.json | jq .IAMToken -r`. Generate the token with the [Create
an IAM access token for a user or service ID using an API
key](https://cloud.ibm.com/apidocs/iam-identity-token-api#gettoken-apikey) API.
2. X-Delegated-Refresh-Token Header Generate an IAM Delegated Refresh Token for
Code Engine with the [Create an IAM access token and delegated refresh token for a
user or service
ID](https://cloud.ibm.com/apidocs/iam-identity-token-api#gettoken-apikey-delegatedrefreshtoken)
API. Specify the `receiver_client_ids` value to be `ce` and the
`delegated_refresh_token_expiry` value to be `3600`.
3. Project ID In order to retrieve the Kubeconfig file for a specific Code Engine
project, use the CLI to extract the ID
`id=ibmcloud ce project get -n ${CE_PROJECT_NAME} -o jsonpath={.guid}` You must be
logged into the account where the project was created to retrieve the ID.

:param str x_delegated_refresh_token: This IAM Delegated Refresh Token is
specifically valid for Code Engine. Generate this token with the [Create an
IAM access token and delegated refresh token for a user or service
ID](https://cloud.ibm.com/apidocs/iam-identity-token-api#gettoken-apikey-delegatedrefreshtoken)
API. Specify the `receiver_client_ids` value to be `ce` and the
`delegated_refresh_token_expiry` value to be `3600`.
:param str id: The id of the IBM Cloud Code Engine project.
:param str accept: (optional) The type of the response: text/plain or
application/json. A character encoding can be specified by including a
`charset` parameter. For example, 'text/plain;charset=utf-8'.
:param dict headers: A `dict` containing the request headers
:return: A `DetailedResponse` containing the result, headers and HTTP status code.
:rtype: DetailedResponse with `str` result
"""

if x_delegated_refresh_token is None:
raise ValueError('x_delegated_refresh_token must be provided')
if id is None:
raise ValueError('id must be provided')
headers = {
'X-Delegated-Refresh-Token': x_delegated_refresh_token,
'Accept': accept
}
sdk_headers = get_sdk_headers(service_name=self.DEFAULT_SERVICE_NAME,
service_version='V1',
operation_id='get_kubeconfig')
headers.update(sdk_headers)

if 'headers' in kwargs:
headers.update(kwargs.get('headers'))

path_param_keys = ['id']
path_param_values = self.encode_path_vars(id)
path_param_dict = dict(zip(path_param_keys, path_param_values))
url = '/project/{id}/config'.format(**path_param_dict)
request = self.prepare_request(method='GET',
url=url,
headers=headers)
Expand All @@ -130,12 +206,27 @@ class ListKubeconfigEnums:

class Accept(str, Enum):
"""
The type of the response: application/json or text/html. A character encoding can
The type of the response: text/plain or application/json. A character encoding can
be specified by including a `charset` parameter. For example,
'text/plain;charset=utf-8'.
"""
TEXT_PLAIN = 'text/plain'
APPLICATION_JSON = 'application/json'


class GetKubeconfigEnums:
"""
Enums for get_kubeconfig parameters.
"""

class Accept(str, Enum):
"""
The type of the response: text/plain or application/json. A character encoding can
be specified by including a `charset` parameter. For example,
'text/html;charset=utf-8'.
'text/plain;charset=utf-8'.
"""
TEXT_PLAIN = 'text/plain'
APPLICATION_JSON = 'application/json'
TEXT_HTML = 'text/html'


##############################################################################
Expand Down
Loading