-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Health check #37
Health check #37
Changes from 4 commits
beb481c
53bbdd1
a138134
2591c70
793f8b9
c8da163
61ead36
c3ec9a4
8ea428b
a52ab7c
81382af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ | |
import ssl | ||
import urllib3 | ||
from kubernetes import client, config | ||
import requests | ||
|
||
from robot.api import logger | ||
|
||
# supressing SSL warnings when using self-signed certs | ||
|
@@ -11,27 +13,19 @@ | |
|
||
class KubeLibrary(object): | ||
"""KubeLibrary is a Robot Framework test library for Kubernetes. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please leave those empty lines as they improve readability. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
The approach taken by this library is to provide easy to access kubernetes objects representation that can | ||
be then accessed to define highlevel keywords for tests. | ||
|
||
= Kubeconfigs = | ||
|
||
By default ~/.kube/config is used. Kubeconfig location | ||
can also be passed by setting KUBECONFIG environment variable or as Library argument. | ||
|
||
| ***** Settings ***** | ||
| Library KubeLibrary /path/to/kubeconfig | ||
|
||
= In cluster execution = | ||
|
||
If tests are supposed to be executed from within cluster, KubeLibrary can be configured to use standard | ||
token authentication. Just set incluster parameter to True. If True then kubeconfigs are not used, | ||
even if provided. | ||
|
||
| ***** Settings ***** | ||
| Library KubeLibrary None True | ||
|
||
""" | ||
def __init__(self, kube_config=None, incluster=False, cert_validation=True): | ||
"""KubeLibrary can be configured with several optional arguments. | ||
|
@@ -73,7 +67,6 @@ def reload_config(self, kube_config=None, incluster=False, cert_validation=True) | |
|
||
def k8s_api_ping(self): | ||
"""Performs GET on /api/v1/ for simple check of API availability. | ||
|
||
Returns tuple of (response data, response status, response headers). Can be used as prerequisite in tests. | ||
""" | ||
path_params = {} | ||
|
@@ -92,19 +85,15 @@ def k8s_api_ping(self): | |
|
||
def get_namespaces(self, label_selector=""): | ||
"""Gets a list of available namespaces. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of namespaces. | ||
""" | ||
ret = self.v1.list_namespace(watch=False, label_selector=label_selector) | ||
return [item.metadata.name for item in ret.items] | ||
|
||
def get_healthy_nodes_count(self, label_selector=""): | ||
"""Counts node with KubeletReady and status True. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Can be used to check number of healthy nodes. Can be used as prerequisite in tests. | ||
""" | ||
ret = self.v1.list_node(watch=False, label_selector=label_selector) | ||
|
@@ -117,11 +106,8 @@ def get_healthy_nodes_count(self, label_selector=""): | |
|
||
def get_pod_names_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets pod name matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of strings. | ||
|
||
- ``name_pattern``: | ||
Pod name pattern to check | ||
- ``namespace``: | ||
|
@@ -133,11 +119,8 @@ def get_pod_names_in_namespace(self, name_pattern, namespace, label_selector="") | |
|
||
def get_pods_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets pods matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of pods. | ||
|
||
- ``name_pattern``: | ||
Pod name pattern to check | ||
- ``namespace``: | ||
|
@@ -150,9 +133,7 @@ def get_pods_in_namespace(self, name_pattern, namespace, label_selector=""): | |
|
||
def get_pod_logs(self, name, namespace, container): | ||
"""Gets container logs of given pod in given namespace. | ||
|
||
Returns logs. | ||
|
||
- ``name``: | ||
Pod name to check | ||
- ``namespace``: | ||
|
@@ -165,11 +146,8 @@ def get_pod_logs(self, name, namespace, container): | |
|
||
def get_configmaps_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets configmaps matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of configmaps. | ||
|
||
- ``name_pattern``: | ||
configmap name pattern to check | ||
- ``namespace``: | ||
|
@@ -182,11 +160,8 @@ def get_configmaps_in_namespace(self, name_pattern, namespace, label_selector="" | |
|
||
def get_service_accounts_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets service accounts matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of service accounts. | ||
|
||
- ``name_pattern``: | ||
Service Account name pattern to check | ||
- ``namespace``: | ||
|
@@ -199,11 +174,8 @@ def get_service_accounts_in_namespace(self, name_pattern, namespace, label_selec | |
|
||
def get_deployments_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets deployments matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of deployments. | ||
|
||
- ``name_pattern``: | ||
deployment name pattern to check | ||
- ``namespace``: | ||
|
@@ -216,11 +188,8 @@ def get_deployments_in_namespace(self, name_pattern, namespace, label_selector=" | |
|
||
def get_jobs_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets jobs matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of jobs. | ||
|
||
- ``name_pattern``: | ||
job name pattern to check | ||
- ``namespace``: | ||
|
@@ -233,11 +202,8 @@ def get_jobs_in_namespace(self, name_pattern, namespace, label_selector=""): | |
|
||
def get_secrets_in_namespace(self, name_pattern, namespace, label_selector=""): | ||
"""Gets secrets matching pattern in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of secrets. | ||
|
||
- ``name_pattern``: | ||
secret name pattern to check | ||
- ``namespace``: | ||
|
@@ -250,29 +216,23 @@ def get_secrets_in_namespace(self, name_pattern, namespace, label_selector=""): | |
|
||
def filter_pods_names(self, pods): | ||
"""Filter pod names for list of pods. | ||
|
||
Returns list of strings. | ||
|
||
- ``pods``: | ||
List of pods objects | ||
""" | ||
return [pod.metadata.name for pod in pods] | ||
|
||
def filter_service_accounts_names(self, service_accounts): | ||
"""Filter service accounts names for list of service accounts. | ||
|
||
Returns list of strings. | ||
|
||
- ``service_accounts``: | ||
List of service accounts objects | ||
""" | ||
return [sa.metadata.name for sa in service_accounts] | ||
|
||
def filter_pods_containers_by_name(self, pods, name_pattern): | ||
"""Filters pods containers by name for given list of pods. | ||
|
||
Returns lists of containers (flattens). | ||
|
||
- ``pods``: | ||
List of pods objects | ||
""" | ||
|
@@ -286,29 +246,23 @@ def filter_pods_containers_by_name(self, pods, name_pattern): | |
|
||
def filter_containers_images(self, containers): | ||
"""Filters container images for given lists of containers. | ||
|
||
Returns list of images. | ||
|
||
- ``containers``: | ||
List of containers | ||
""" | ||
return [container.image for container in containers] | ||
|
||
def filter_containers_resources(self, containers): | ||
"""Filters container resources for given lists of containers. | ||
|
||
Returns list of resources. | ||
|
||
- ``containers``: | ||
List of containers | ||
""" | ||
return [container.resources for container in containers] | ||
|
||
def filter_pods_containers_statuses_by_name(self, pods, name_pattern): | ||
"""Filters pods containers statuses by container name for given list of pods. | ||
|
||
Returns lists of containers statuses. | ||
|
||
- ``pods``: | ||
List of pods objects | ||
""" | ||
|
@@ -322,7 +276,6 @@ def filter_pods_containers_statuses_by_name(self, pods, name_pattern): | |
|
||
def get_pod_status_in_namespace(self, name, namespace): | ||
"""Gets pod status in given namespace. | ||
|
||
- ``name``: | ||
Name of pod. | ||
- ``namespace``: | ||
|
@@ -333,9 +286,7 @@ def get_pod_status_in_namespace(self, name, namespace): | |
|
||
def assert_pod_has_labels(self, pod, labels_json): | ||
"""Assert pod has labels. | ||
|
||
Returns True/False | ||
|
||
- ``pod``: | ||
Pod object. | ||
- ``labels_json``: | ||
|
@@ -358,9 +309,7 @@ def assert_pod_has_labels(self, pod, labels_json): | |
|
||
def assert_pod_has_annotations(self, pod, annotations_json): | ||
"""Assert pod has annotations. | ||
|
||
Returns True/False | ||
|
||
- ``pod``: | ||
Pod object. | ||
- ``annotations_json``: | ||
|
@@ -383,9 +332,7 @@ def assert_pod_has_annotations(self, pod, annotations_json): | |
|
||
def assert_container_has_env_vars(self, container, env_vars_json): | ||
"""Assert container has env vars. | ||
|
||
Returns True/False | ||
|
||
- ``container``: | ||
Container object. | ||
- ``env_var_json``: | ||
|
@@ -412,11 +359,8 @@ def assert_container_has_env_vars(self, container, env_vars_json): | |
|
||
def get_services_in_namespace(self, namespace, label_selector=""): | ||
"""Gets services in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of strings. | ||
|
||
- ``namespace``: | ||
Namespace to check | ||
""" | ||
|
@@ -425,11 +369,8 @@ def get_services_in_namespace(self, namespace, label_selector=""): | |
|
||
def get_service_details_in_namespace(self, name, namespace): | ||
"""Gets service details in given namespace. | ||
|
||
Returns Service object representation. Can be accessed using | ||
|
||
| Should Be Equal As integers | ${service_details.spec.ports[0].port} | 8080 | | ||
|
||
- ``name``: | ||
Name of service. | ||
- ``namespace``: | ||
|
@@ -440,11 +381,8 @@ def get_service_details_in_namespace(self, name, namespace): | |
|
||
def get_endpoints_in_namespace(self, name, namespace): | ||
"""Gets endpoint details in given namespace. | ||
|
||
Returns Endpoint object representation. Can be accessed using | ||
|
||
| Should Match | ${endpoint_details.subsets[0].addresses[0].target_ref.name} | pod-name-123456 | | ||
|
||
- ``name``: | ||
Name of endpoint. | ||
- ``namespace``: | ||
|
@@ -455,11 +393,8 @@ def get_endpoints_in_namespace(self, name, namespace): | |
|
||
def get_pvc_in_namespace(self, namespace, label_selector=""): | ||
"""Gets pvcs in given namespace. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of strings. | ||
|
||
- ``namespace``: | ||
Namespace to check | ||
""" | ||
|
@@ -468,11 +403,8 @@ def get_pvc_in_namespace(self, namespace, label_selector=""): | |
|
||
def get_pvc_capacity(self, name, namespace): | ||
"""Gets PVC details in given namespace. | ||
|
||
Returns PVC object representation. Can be accessed using | ||
|
||
| Should Be Equal As strings | ${pvc.status.capacity.storage} | 1Gi | | ||
|
||
- ``name``: | ||
Name of PVC. | ||
- ``namespace``: | ||
|
@@ -483,19 +415,15 @@ def get_pvc_capacity(self, name, namespace): | |
|
||
def get_kubelet_version(self, label_selector=""): | ||
"""Gets list of kubelet versions on each node. | ||
|
||
Can be optionally filtered by label. e.g. label_selector=label_key=label_value | ||
|
||
Returns list of strings. | ||
""" | ||
ret = self.v1.list_node(watch=False, label_selector=label_selector) | ||
return [item.status.node_info.kubelet_version for item in ret.items] | ||
|
||
def create_service_account_in_namespace(self, namespace, body): | ||
"""Creates service account in a namespace | ||
|
||
Returns created service account | ||
|
||
- ``body``: | ||
Service Account object. | ||
- ``namespace``: | ||
|
@@ -506,14 +434,19 @@ def create_service_account_in_namespace(self, namespace, body): | |
|
||
def delete_service_account_in_namespace(self, name, namespace): | ||
"""Deletes service account in a namespace | ||
|
||
Returns V1status | ||
|
||
|
||
- ``name``: | ||
Service Account name | ||
- ``namespace``: | ||
Namespace to check | ||
""" | ||
ret = self.v1.delete_namespaced_service_account(name=name, namespace=namespace) | ||
return ret | ||
|
||
def get_healthcheck(self): | ||
"""check cluster leverl healthcheck | ||
Can be used to verify the readiness/current status of the API server | ||
""" | ||
output = requests.get('https://localhost:6443/readyz?verbose=', verify = False) | ||
satish-nubolab marked this conversation as resolved.
Show resolved
Hide resolved
|
||
logger.debug(output) | ||
return output |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*** Settings *** | ||
Resource ./healthcheck_kw.robot | ||
|
||
*** Test Cases *** | ||
Healthcheck | ||
[Tags] other | ||
Healthcheck | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
*** Settings *** | ||
Library Collections | ||
Library RequestsLibrary | ||
Library String | ||
# For regular execution | ||
Library KubeLibrary | ||
# For incluster execution | ||
#Library KubeLibrary None True False | ||
# For development | ||
#Library ../../src/KubeLibrary/KubeLibrary.py ~/.kube/k3d | ||
|
||
*** Keywords *** | ||
Healthcheck | ||
${output}= Get Healthcheck | ||
Log \nHealthcheck ${output}: console=True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice if your example keyword could also verify if all checks have passed with ok. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Evaluated the response and verified if all checks have passed with ok. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requests is not needed, see the comment below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
request module removed.