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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 3 additions & 1 deletion .github/workflows/e2e-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ jobs:
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install -r test-requirements.txt
python -m pip install -r requirements-asyncio.txt
python -m pip install -r test-requirements-asyncio.txt
- name: Install package
run: python -m pip install -e .
- name: Run End to End tests
run: pytest -vvv -s kubernetes/e2e_test
run: pytest -vvv -s kubernetes/e2e_test -s kubernetes_asyncio/e2e_test
1 change: 1 addition & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-asyncio.txt
- name: Lint with flake8
run: |
pip install flake8
Expand Down
86 changes: 86 additions & 0 deletions examples_asyncio/in_cluster_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Simple example to show loading config from the cluster

#
# If you get 403 errors from API server you will have to configure
# RBAC to add necessay permissions.
#
# ---
# kind: ClusterRole
# apiVersion: rbac.authorization.k8s.io/v1
# metadata:
# name: pods-list
# rules:
# - apiGroups: [""]
# resources: ["pods"]
# verbs: ["list"]
# ---
# kind: ClusterRoleBinding
# apiVersion: rbac.authorization.k8s.io/v1
# metadata:
# name: pods-list
# subjects:
# - kind: ServiceAccount
# name: default
# namespace: default
# roleRef:
# kind: ClusterRole
# name: pods-list
# apiGroup: rbac.authorization.k8s.io
# ---
#
# Doc: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
#
# This example can be run from the image: https://hub.docker.com/r/tpimages/kubernetes_asyncio_examples/
#
# $ kubectl run kubernetes-asyncio-examples --image tpimages/kubernetes_asyncio_examples
#

import asyncio
import sys
import traceback

from kubernetes_asyncio import client, config


async def main():

while True:

try:

# it works only if this script is run by K8s as a POD
config.load_incluster_config()

v1 = client.CoreV1Api()
print("Listing pods with their IPs:")
ret = await v1.list_pod_for_all_namespaces()

for i in ret.items:
print(i.status.pod_ip, i.metadata.namespace, i.metadata.name)

except Exception:
traceback.print_exc(file=sys.stdout)

finally:
print("sleep 10s")
await asyncio.sleep(10)


if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
27 changes: 27 additions & 0 deletions examples_asyncio/list_pods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import asyncio

from kubernetes_asyncio import client, config
from kubernetes_asyncio.client.api_client import ApiClient


async def main():
# Configs can be set in Configuration class directly or using helper
# utility. If no argument provided, the config will be loaded from
# default location.
await config.load_kube_config()

# use the context manager to close http sessions automatically
async with ApiClient() as api:

v1 = client.CoreV1Api(api)
print("Listing pods with their IPs:")
ret = await v1.list_pod_for_all_namespaces()

for i in ret.items:
print(i.status.pod_ip, i.metadata.namespace, i.metadata.name)


if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
109 changes: 109 additions & 0 deletions examples_asyncio/patch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import asyncio

from kubernetes_asyncio import client, config
from kubernetes_asyncio.client.api_client import ApiClient

SERVICE_NAME = "example-service"
SERVICE_NS = "default"
SERVICE_SPEC = {
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"labels": {"name": SERVICE_NAME},
"name": SERVICE_NAME,
"resourceversion": "v1",
},
"spec": {
"ports": [{"name": "port-80", "port": 80, "protocol": "TCP", "targetPort": 80}],
"selector": {"name": SERVICE_NAME},
},
}


async def main():

await config.load_kube_config()

async with ApiClient() as api:

v1 = client.CoreV1Api(api)

print(f"Recreate {SERVICE_NAME}...")
try:
await v1.read_namespaced_service(SERVICE_NAME, SERVICE_NS)
await v1.delete_namespaced_service(SERVICE_NAME, SERVICE_NS)
except client.exceptions.ApiException as ex:
if ex.status == 404:
pass

await v1.create_namespaced_service(SERVICE_NS, SERVICE_SPEC)

print("Patch using JSON patch - replace port-80 with port-1000")
patch = [
{
"op": "replace",
"path": "/spec/ports/0",
"value": {
"name": "port-1000",
"protocol": "TCP",
"port": 1000,
"targetPort": 1000,
},
}
]
await v1.patch_namespaced_service(
SERVICE_NAME,
SERVICE_NS,
patch,
# _content_type='application/json-patch+json' # (optional, default if patch is a list)
)

print(
"Patch using strategic merge patch - add port-2000, service will have two ports: port-1000 and port-2000"
)
patch = {
"spec": {
"ports": [
{
"name": "port-2000",
"protocol": "TCP",
"port": 2000,
"targetPort": 2000,
}
]
}
}
await v1.patch_namespaced_service(
SERVICE_NAME,
SERVICE_NS,
patch,
# _content_type='application/strategic-merge-patch+json' # (optional, default if patch is a dict)
)

print(
"Patch using merge patch - recreate list of ports, service will have only one port: port-3000"
)
patch = {
"spec": {
"ports": [
{
"name": "port-3000",
"protocol": "TCP",
"port": 3000,
"targetPort": 3000,
}
]
}
}
await v1.patch_namespaced_service(
SERVICE_NAME,
SERVICE_NS,
patch,
_content_type="application/merge-patch+json", # required to force merge patch
)


if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
66 changes: 66 additions & 0 deletions kubernetes_asyncio/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
venv/
.venv/
.python-version
.pytest_cache

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/

#Ipython Notebook
.ipynb_checkpoints
33 changes: 33 additions & 0 deletions kubernetes_asyncio/.gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# ref: https://docs.gitlab.com/ee/ci/README.html

stages:
- test

.nosetest:
stage: test
script:
- pip install -r requirements.txt
- pip install -r test-requirements.txt
- pytest --cov=client

nosetest-2.7:
extends: .nosetest
image: python:2.7-alpine
nosetest-3.3:
extends: .nosetest
image: python:3.3-alpine
nosetest-3.4:
extends: .nosetest
image: python:3.4-alpine
nosetest-3.5:
extends: .nosetest
image: python:3.5-alpine
nosetest-3.6:
extends: .nosetest
image: python:3.6-alpine
nosetest-3.7:
extends: .nosetest
image: python:3.7-alpine
nosetest-3.8:
extends: .nosetest
image: python:3.8-alpine
23 changes: 23 additions & 0 deletions kubernetes_asyncio/.openapi-generator-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator

# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.

# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs

# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux

# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux

# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
2 changes: 2 additions & 0 deletions kubernetes_asyncio/.openapi-generator/COMMIT
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Requested Commit/Tag : v6.6.0
Actual Commit : 7f8b853f502d9039c9a0aac2614ce92871e895ed
Loading