Skip to content
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

Replace openshift client with kubernetes client #96

Merged
merged 7 commits into from
May 6, 2021
Merged
Show file tree
Hide file tree
Changes from 6 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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ collections:
version: 1.2.0
```

### Installing the OpenShift Python Library
### Installing the Kubernetes Python Library

Content in this collection requires the [OpenShift Python client](https://pypi.org/project/openshift/) to interact with Kubernetes' APIs. You can install it with:
Content in this collection requires the [Kubernetes Python client](https://pypi.org/project/kubernetes/) to interact with Kubernetes' APIs. You can install it with:

pip3 install openshift
pip3 install kubernetes

### Using modules from the Kubernetes Collection in your playbooks

Expand Down
3 changes: 3 additions & 0 deletions changelogs/fragments/96-replace-openshift-client.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
major_changes:
- replaces the openshift client with the official kubernetes client (https://github.com/ansible-collections/kubernetes.core/issues/34).
5 changes: 1 addition & 4 deletions plugins/doc_fragments/k8s_auth_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ModuleDocFragment(object):
kubeconfig:
description:
- Path to an existing Kubernetes config file. If not provided, and no other connection
options are provided, the openshift client will attempt to load the default
options are provided, the Kubernetes client will attempt to load the default
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG environment
variable.
type: path
Expand Down Expand Up @@ -110,9 +110,6 @@ class ModuleDocFragment(object):
- "The fix for this k8s python library is here: https://github.com/kubernetes-client/python-base/pull/169"
type: bool
notes:
- "The OpenShift Python client wraps the K8s Python client, providing full access to
all of the APIS and models available on both platforms. For API version details and
additional information visit https://github.com/openshift/openshift-restclient-python"
- "To avoid SSL certificate validation errors when C(validate_certs) is I(True), the full
certificate chain for the API server must be provided via C(ca_cert) or in the
kubeconfig file."
Expand Down
9 changes: 1 addition & 8 deletions plugins/filter/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,11 @@
__metaclass__ = type


try:
from openshift.helper.hashes import generate_hash
HAS_GENERATE_HASH = True
except ImportError:
HAS_GENERATE_HASH = False

from ansible.errors import AnsibleFilterError
from ansible_collections.kubernetes.core.plugins.module_utils.hashes import generate_hash


def k8s_config_resource_name(resource):
if not HAS_GENERATE_HASH:
raise AnsibleFilterError("k8s_config_resource_name requires openshift>=0.7.2")
try:
return resource['metadata']['name'] + '-' + generate_hash(resource)
except KeyError:
Expand Down
8 changes: 4 additions & 4 deletions plugins/inventory/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
kubeconfig:
description:
- Path to an existing Kubernetes config file. If not provided, and no other connection
options are provided, the OpenShift client will attempt to load the default
options are provided, the Kubernetes client will attempt to load the default
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG
environment variable.
context:
Expand Down Expand Up @@ -87,7 +87,7 @@

requirements:
- "python >= 3.6"
- "openshift >= 0.6"
- "kubernetes >= 11.0.0"
- "PyYAML >= 3.11"
'''

Expand Down Expand Up @@ -121,7 +121,7 @@
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable

try:
from openshift.dynamic.exceptions import DynamicApiError
from kubernetes.dynamic.exceptions import DynamicApiError
except ImportError:
pass

Expand Down Expand Up @@ -158,7 +158,7 @@ def setup(self, config_data, cache, cache_key):

if not HAS_K8S_MODULE_HELPER:
raise K8sInventoryException(
"This module requires the OpenShift Python client. Try `pip install openshift`. Detail: {0}".format(k8s_import_exception)
"This module requires the Kubernetes Python client. Try `pip install kubernetes`. Detail: {0}".format(k8s_import_exception)
)

source_data = None
Expand Down
15 changes: 5 additions & 10 deletions plugins/lookup/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
- Fabian von Feilitzsch <@fabianvf>

description:
- Uses the OpenShift Python client to fetch a specific object by name, all matching objects within a
- Uses the Kubernetes Python client to fetch a specific object by name, all matching objects within a
namespace, or all matching objects for all namespaces, as well as information about the cluster.
- Provides access the full range of K8s APIs.
- Enables authentication via config file, certificates, password or token.
Expand Down Expand Up @@ -85,7 +85,7 @@
kubeconfig:
description:
- Path to an existing Kubernetes config file. If not provided, and no other connection
options are provided, the openshift client will attempt to load the default
options are provided, the Kubernetes client will attempt to load the default
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG environment
variable.
context:
Expand Down Expand Up @@ -125,13 +125,8 @@

requirements:
- "python >= 3.6"
- "openshift >= 0.6"
- "kubernetes >= 11.0.0"
gravesm marked this conversation as resolved.
Show resolved Hide resolved
- "PyYAML >= 3.11"

notes:
- "The OpenShift Python client wraps the K8s Python client, providing full access to
all of the APIS and models available on both platforms. For API version details and
additional information visit https://github.com/openshift/openshift-restclient-python"
'''

EXAMPLES = """
Expand Down Expand Up @@ -206,7 +201,7 @@


try:
from openshift.dynamic.exceptions import NotFoundError
from kubernetes.dynamic.exceptions import NotFoundError
HAS_K8S_MODULE_HELPER = True
k8s_import_exception = None
except ImportError as e:
Expand All @@ -220,7 +215,7 @@ def __init__(self):

if not HAS_K8S_MODULE_HELPER:
raise Exception(
"Requires the OpenShift Python client. Try `pip install openshift`. Detail: {0}".format(k8s_import_exception)
"Requires the Kubernetes Python client. Try `pip install kubernetes`. Detail: {0}".format(k8s_import_exception)
)

self.kind = None
Expand Down
53 changes: 15 additions & 38 deletions plugins/module_utils/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
K8S_IMP_ERR = None
try:
import kubernetes
import openshift
from kubernetes.dynamic.exceptions import (
NotFoundError, ResourceNotFoundError, ResourceNotUniqueError, DynamicApiError,
ConflictError, ForbiddenError, MethodNotAllowedError, BadRequestError
ConflictError, ForbiddenError, MethodNotAllowedError, BadRequestError,
KubernetesValidateMissing
)
HAS_K8S_MODULE_HELPER = True
k8s_import_exception = None
Expand All @@ -69,14 +69,6 @@
YAML_IMP_ERR = traceback.format_exc()
HAS_YAML = False

K8S_CONFIG_HASH_IMP_ERR = None
try:
from kubernetes.dynamic.exceptions import KubernetesValidateMissing
HAS_K8S_CONFIG_HASH = True
except ImportError:
K8S_CONFIG_HASH_IMP_ERR = traceback.format_exc()
HAS_K8S_CONFIG_HASH = False

HAS_K8S_APPLY = None
try:
from ansible_collections.kubernetes.core.plugins.module_utils.apply import apply_object
Expand Down Expand Up @@ -229,9 +221,9 @@ class K8sAnsibleMixin(object):

def __init__(self, module, *args, **kwargs):
if not HAS_K8S_MODULE_HELPER:
module.fail_json(msg=missing_required_lib('openshift'), exception=K8S_IMP_ERR,
module.fail_json(msg=missing_required_lib('kubernetes'), exception=K8S_IMP_ERR,
error=to_native(k8s_import_exception))
self.openshift_version = openshift.__version__
self.kubernetes_version = kubernetes.__version__

if not HAS_YAML:
module.fail_json(msg=missing_required_lib("PyYAML"), exception=YAML_IMP_ERR)
Expand Down Expand Up @@ -495,21 +487,8 @@ def set_resource_definitions(self, module):
self.resource_definitions = [implicit_definition]

def check_library_version(self):
validate = self.params.get('validate')
if validate and LooseVersion(self.openshift_version) < LooseVersion("0.8.0"):
self.fail_json(msg="openshift >= 0.8.0 is required for validate")
self.append_hash = self.params.get('append_hash')
if self.append_hash and not HAS_K8S_CONFIG_HASH:
self.fail_json(msg=missing_required_lib("openshift >= 0.7.2", reason="for append_hash"),
exception=K8S_CONFIG_HASH_IMP_ERR)
if self.params['merge_type'] and LooseVersion(self.openshift_version) < LooseVersion("0.6.2"):
self.fail_json(msg=missing_required_lib("openshift >= 0.6.2", reason="for merge_type"))
self.apply = self.params.get('apply', False)
if self.apply and not HAS_K8S_APPLY:
self.fail_json(msg=missing_required_lib("openshift >= 0.9.2", reason="for apply"))
wait = self.params.get('wait', False)
if wait and not HAS_K8S_INSTANCE_HELPER:
self.fail_json(msg=missing_required_lib("openshift >= 0.4.0", reason="for wait"))
if LooseVersion(self.kubernetes_version) < LooseVersion("11.0.0"):
self.fail_json(msg="kubernetes >= 11.0.0 is required")

def flatten_list_kind(self, list_resource, definitions):
flattened = []
Expand Down Expand Up @@ -590,6 +569,8 @@ def set_defaults(self, resource, definition):
return definition

def perform_action(self, resource, definition):
append_hash = self.params.get('append_hash', False)
apply = self.params.get('apply', False)
delete_options = self.params.get('delete_options')
result = {'changed': False, 'result': {}}
state = self.params.get('state', None)
Expand All @@ -613,7 +594,7 @@ def build_error_msg(kind, name, msg):

try:
# ignore append_hash for resources other than ConfigMap and Secret
if self.append_hash and definition['kind'] in ['ConfigMap', 'Secret']:
if append_hash and definition['kind'] in ['ConfigMap', 'Secret']:
name = '%s-%s' % (name, generate_hash(definition))
definition['metadata']['name'] = name
params = dict(name=name)
Expand Down Expand Up @@ -690,7 +671,7 @@ def build_error_msg(kind, name, msg):
self.fail_json(msg=build_error_msg(definition['kind'], origin_name, msg), **result)
return result
else:
if self.apply:
if apply:
if self.check_mode:
ignored, patch = apply_object(resource, _encode_stringdata(definition))
if existing:
Expand Down Expand Up @@ -786,7 +767,7 @@ def build_error_msg(kind, name, msg):
k8s_obj = _encode_stringdata(definition)
else:
try:
k8s_obj = resource.replace(definition, name=name, namespace=namespace, append_hash=self.append_hash).to_dict()
k8s_obj = resource.replace(definition, name=name, namespace=namespace, append_hash=append_hash).to_dict()
except DynamicApiError as exc:
msg = "Failed to replace object: {0}".format(exc.body)
if self.warnings:
Expand Down Expand Up @@ -819,15 +800,11 @@ def build_error_msg(kind, name, msg):
if self.check_mode:
k8s_obj = dict_merge(existing.to_dict(), _encode_stringdata(definition))
else:
if LooseVersion(self.openshift_version) < LooseVersion("0.6.2"):
for merge_type in self.params['merge_type'] or ['strategic-merge', 'merge']:
k8s_obj, error = self.patch_resource(resource, definition, existing, name,
namespace)
else:
for merge_type in self.params['merge_type'] or ['strategic-merge', 'merge']:
k8s_obj, error = self.patch_resource(resource, definition, existing, name,
namespace, merge_type=merge_type)
if not error:
break
namespace, merge_type=merge_type)
if not error:
break
if error:
if continue_on_error:
result['error'] = error
Expand Down
23 changes: 6 additions & 17 deletions plugins/modules/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
- "Fabian von Feilitzsch (@fabianvf)"

description:
- Use the OpenShift Python client to perform CRUD operations on K8s objects.
- Use the Kubernetes Python client to perform CRUD operations on K8s objects.
- Pass the object definition from a source file or inline. See examples for reading
files and using Jinja templates or vault-encrypted files.
- Access to the full range of K8s APIs.
Expand All @@ -37,13 +37,6 @@
- kubernetes.core.k8s_wait_options
- kubernetes.core.k8s_delete_options

notes:
- If your OpenShift Python library is not 0.9.0 or newer and you are trying to
remove an item from an associative array/dictionary, for example a label or
an annotation, you will need to explicitly set the value of the item to be
removed to `null`. Simply deleting the entry in the dictionary will not
remove it from openshift or kubernetes.

options:
merge_type:
description:
Expand All @@ -52,11 +45,9 @@
- For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may
want to use C(merge) if you see "strategic merge patch format is not supported"
- See U(https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment)
- Requires openshift >= 0.6.2
- If more than one merge_type is given, the merge_types will be tried in order
- If openshift >= 0.6.2, this defaults to C(['strategic-merge', 'merge']), which is ideal for using the same parameters
on resource kinds that combine Custom Resources and built-in resources. For openshift < 0.6.2, the default
is simply C(strategic-merge).
- If more than one C(merge_type) is given, the merge_types will be tried in order. This defaults to
C(['strategic-merge', 'merge']), which is ideal for using the same parameters on resource kinds that
combine Custom Resources and built-in resources.
- mutually exclusive with C(apply)
choices:
- json
Expand All @@ -67,7 +58,7 @@
validate:
description:
- how (if at all) to validate the resource definition against the kubernetes schema.
Requires the kubernetes-validate python module and openshift >= 0.8.0
Requires the kubernetes-validate python module.
suboptions:
fail_on_error:
description: whether to fail on validation errors.
Expand All @@ -88,15 +79,13 @@
- The full definition of an object is needed to generate the hash - this means that deleting an object created with append_hash
will only work if the same object is passed with state=absent (alternatively, just use state=absent with the name including
the generated hash and append_hash=no)
- Requires openshift >= 0.7.2
default: False
type: bool
apply:
description:
- C(apply) compares the desired resource definition with the previously supplied resource definition,
ignoring properties that are automatically generated
- C(apply) works better with Services than 'force=yes'
- Requires openshift >= 0.9.2
- mutually exclusive with C(merge_type)
default: False
type: bool
Expand Down Expand Up @@ -134,7 +123,7 @@

requirements:
- "python >= 3.6"
- "openshift >= 0.6"
- "kubernetes >= 11.0.0"
- "PyYAML >= 3.11"
- "jsonpatch"
'''
Expand Down
6 changes: 3 additions & 3 deletions plugins/modules/k8s_cluster_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- Abhijeet Kasurde (@Akasurde)

description:
- Use the OpenShift Python client to perform read operations on K8s objects.
- Use the Kubernetes Python client to perform read operations on K8s objects.
- Authenticate using either a config file, certificates, password or token.
- Supports check mode.

Expand All @@ -34,7 +34,7 @@

requirements:
- "python >= 3.6"
- "openshift >= 0.6"
- "kubernetes >= 11.0.0"
- "PyYAML >= 3.11"
'''

Expand Down Expand Up @@ -186,7 +186,7 @@ def execute_module(module, client):
'username': configuration.username,
'verify_ssl': configuration.verify_ssl,
}
from openshift import __version__ as version
from kubernetes import __version__ as version
version_info = {
'client': version,
'server': client.version,
Expand Down
2 changes: 1 addition & 1 deletion plugins/modules/k8s_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

requirements:
- "python >= 3.6"
- "openshift == 0.4.3"
- "kubernetes >= 11.0.0"
- "PyYAML >= 3.11"

notes:
Expand Down
4 changes: 2 additions & 2 deletions plugins/modules/k8s_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- "Will Thames (@willthames)"

description:
- Use the OpenShift Python client to perform read operations on K8s objects.
- Use the Kubernetes Python client to perform read operations on K8s objects.
- Access to the full range of K8s APIs.
- Authenticate using either a config file, certificates, password or token.
- Supports check mode.
Expand Down Expand Up @@ -50,7 +50,7 @@

requirements:
- "python >= 3.6"
- "openshift >= 0.6"
- "kubernetes >= 11.0.0"
- "PyYAML >= 3.11"
'''

Expand Down
Loading