Update to work with k8s 2.0 (#93)

* Update to work with k8s 2.0

This makes the necessary changes to get the collection working with
kubernetes.core 2.0. The biggest changes here will be switching from the
openshift client to the kubernetes client, and dropping Python 2
support.

* Install kubernetes not openshift

* Add changelog fragment
This commit is contained in:
Mike Graves
2021-06-21 14:41:56 -04:00
committed by GitHub
parent 37833d4316
commit f60ded17b0
12 changed files with 82 additions and 55 deletions

View File

@@ -61,11 +61,11 @@ collections:
version: 1.1.2
```
### 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 OKD Collection in your playbooks

View File

@@ -0,0 +1,5 @@
---
breaking_changes:
- drop python 2 support (https://github.com/openshift/community.okd/pull/93).
major_changes:
- update to use kubernetes.core 2.0 (https://github.com/openshift/community.okd/pull/93).

View File

@@ -16,7 +16,7 @@ RUN yum install -y \
python3-setuptools \
&& pip3 install --no-cache-dir --upgrade setuptools pip \
&& pip3 install --no-cache-dir \
openshift \
kubernetes \
ansible==2.9.* \
"molecule<3.3.0" \
&& yum clean all \

View File

@@ -5,7 +5,7 @@ authors:
- willthames (https://github.com/willthames)
- Akasurde (https://github.com/akasurde)
dependencies:
kubernetes.core: '>=1.2.0,<1.3.0'
kubernetes.core: '>=2.0.0,<2.1.0'
description: OKD Collection for Ansible.
documentation: ''
homepage: ''

View File

@@ -10,7 +10,7 @@
- pip:
name:
- openshift>=0.9.2
- kubernetes>=12.0.0
- coverage
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"

View File

@@ -36,8 +36,8 @@ DOCUMENTATION = '''
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
configuration file from I(~/.kube/config.json). Can also be specified via K8S_AUTH_KUBECONFIG
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:
description:
@@ -85,8 +85,8 @@ DOCUMENTATION = '''
to access.
requirements:
- "python >= 2.7"
- "openshift >= 0.6"
- "python >= 3.6"
- "kubernetes >= 12.0.0"
- "PyYAML >= 3.11"
'''
@@ -114,9 +114,10 @@ connections:
'''
from ansible_collections.kubernetes.core.plugins.inventory.k8s import K8sInventoryException, InventoryModule as K8sInventoryModule, format_dynamic_api_exc
from ansible_collections.kubernetes.core.plugins.module_utils.common import get_api_client
try:
from openshift.dynamic.exceptions import DynamicApiError
from kubernetes.dynamic.exceptions import DynamicApiError
except ImportError:
pass
@@ -135,7 +136,7 @@ class InventoryModule(K8sInventoryModule):
raise K8sInventoryException("Expecting connections to be a list.")
for connection in connections:
client = self.get_api_client(**connection)
client = get_api_client(**connection)
name = connection.get('name', self.get_default_host_name(client.configuration.host))
if connection.get('namespaces'):
namespaces = connection['namespaces']
@@ -144,7 +145,7 @@ class InventoryModule(K8sInventoryModule):
for namespace in namespaces:
self.get_routes_for_namespace(client, name, namespace)
else:
client = self.get_api_client()
client = get_api_client()
name = self.get_default_host_name(client.configuration.host)
namespaces = self.get_available_namespaces(client)
for namespace in namespaces:

View File

@@ -21,7 +21,7 @@ author:
- "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.
@@ -31,21 +31,28 @@ description:
- Optimized for OKD/OpenShift Kubernetes flavors.
extends_documentation_fragment:
- kubernetes.core.k8s_state_options
- kubernetes.core.k8s_name_options
- kubernetes.core.k8s_resource_options
- kubernetes.core.k8s_auth_options
- 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:
state:
description:
- Determines if an object should be created, patched, or deleted. When set to C(present), an object will be
created, if it does not already exist. If set to C(absent), an existing object will be deleted. If set to
C(present), an existing object will be patched, if its attributes differ from those specified using
I(resource_definition) or I(src).
- C(patched) state is an existing resource that has a given patch applied. If the resource doesn't exist, silently skip it (do not raise an error).
type: str
default: present
choices: [ absent, present, patched ]
force:
description:
- If set to C(yes), and I(state) is C(present), an existing object will be replaced.
type: bool
default: no
merge_type:
description:
- Whether to override the default patch merge approach with a specific type. By default, the strategic
@@ -53,12 +60,11 @@ options:
- 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).
- 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)
- I(merge_type=json) is deprecated and will be removed in version 3.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
choices:
- json
- merge
@@ -124,10 +130,17 @@ options:
This functionality requires Jinja 2.7 or newer. Default value is false.'
type: raw
version_added: '2.0.0'
continue_on_error:
description:
- Whether to continue on creation/deletion errors when multiple resources are defined.
- This has no effect on the validation step which is controlled by the C(validate.fail_on_error) parameter.
type: bool
default: False
version_added: 2.0.0
requirements:
- "python >= 2.7"
- "openshift >= 0.6"
- "python >= 3.6"
- "kubernetes >= 12.0.0"
- "PyYAML >= 3.11"
'''
@@ -240,6 +253,10 @@ result:
returned: when C(wait) is true
type: int
sample: 48
error:
description: error while trying to create/delete the object.
returned: error
type: complex
'''
# ENDREMOVE (downstream)
@@ -253,9 +270,9 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
try:
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
K8sAnsibleMixin, COMMON_ARG_SPEC, NAME_ARG_SPEC,
RESOURCE_ARG_SPEC, AUTH_ARG_SPEC, WAIT_ARG_SPEC, DELETE_OPTS_ARG_SPEC)
from ansible_collections.kubernetes.core.plugins.module_utils.common import get_api_client, K8sAnsibleMixin
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
NAME_ARG_SPEC, RESOURCE_ARG_SPEC, AUTH_ARG_SPEC, WAIT_ARG_SPEC, DELETE_OPTS_ARG_SPEC)
HAS_KUBERNETES_COLLECTION = True
except ImportError as e:
HAS_KUBERNETES_COLLECTION = False
@@ -264,7 +281,7 @@ except ImportError as e:
try:
import yaml
from openshift.dynamic.exceptions import DynamicApiError, NotFoundError, ForbiddenError
from kubernetes.dynamic.exceptions import DynamicApiError, NotFoundError, ForbiddenError
except ImportError:
# Exceptions handled in common
pass
@@ -303,9 +320,9 @@ class OKDRawModule(K8sAnsibleMixin):
error=to_native(k8s_collection_import_exception)
)
super(OKDRawModule, self).__init__(*args, **kwargs)
super(OKDRawModule, self).__init__(module, *args, **kwargs)
self.client = None
self.client = get_api_client(module)
self.warnings = []
self.kind = k8s_kind or self.params.get('kind')
@@ -314,7 +331,7 @@ class OKDRawModule(K8sAnsibleMixin):
self.namespace = self.params.get('namespace')
self.check_library_version()
self.set_resource_definitions()
self.set_resource_definitions(module)
@property
def validate_spec(self):
@@ -326,8 +343,7 @@ class OKDRawModule(K8sAnsibleMixin):
@property
def argspec(self):
argument_spec = copy.deepcopy(COMMON_ARG_SPEC)
argument_spec.update(copy.deepcopy(NAME_ARG_SPEC))
argument_spec = copy.deepcopy(NAME_ARG_SPEC)
argument_spec.update(copy.deepcopy(RESOURCE_ARG_SPEC))
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
argument_spec.update(copy.deepcopy(WAIT_ARG_SPEC))
@@ -337,6 +353,9 @@ class OKDRawModule(K8sAnsibleMixin):
argument_spec['apply'] = dict(type='bool', default=False)
argument_spec['template'] = dict(type='raw', default=None)
argument_spec['delete_options'] = dict(type='dict', default=None, options=copy.deepcopy(DELETE_OPTS_ARG_SPEC))
argument_spec['continue_on_error'] = dict(type='bool', default=False)
argument_spec['state'] = dict(default='present', choices=['present', 'absent', 'patched'])
argument_spec['force'] = dict(type='bool', default=False)
return argument_spec
def perform_action(self, resource, definition):

View File

@@ -70,7 +70,7 @@ options:
type: str
requirements:
- python >= 2.7
- python >= 3.6
- urllib3
- requests
- requests-oauthlib

View File

@@ -29,8 +29,8 @@ extends_documentation_fragment:
- kubernetes.core.k8s_resource_options
requirements:
- "python >= 2.7"
- "openshift >= 0.11.0"
- "python >= 3.6"
- "kubernetes >= 12.0.0"
- "PyYAML >= 3.11"
options:
@@ -212,8 +212,9 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
try:
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
K8sAnsibleMixin, AUTH_ARG_SPEC, RESOURCE_ARG_SPEC, WAIT_ARG_SPEC
from ansible_collections.kubernetes.core.plugins.module_utils.common import K8sAnsibleMixin, get_api_client
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
AUTH_ARG_SPEC, RESOURCE_ARG_SPEC, WAIT_ARG_SPEC
)
HAS_KUBERNETES_COLLECTION = True
except ImportError as e:
@@ -224,7 +225,7 @@ except ImportError as e:
AUTH_ARG_SPEC = RESOURCE_ARG_SPEC = WAIT_ARG_SPEC = {}
try:
from openshift.dynamic.exceptions import DynamicApiError, NotFoundError
from kubernetes.dynamic.exceptions import DynamicApiError, NotFoundError
except ImportError:
pass
@@ -248,7 +249,7 @@ class OpenShiftProcess(K8sAnsibleMixin):
error=to_native(k8s_collection_import_exception)
)
super(OpenShiftProcess, self).__init__()
super(OpenShiftProcess, self).__init__(self.module)
self.params = self.module.params
self.check_mode = self.module.check_mode
@@ -269,7 +270,7 @@ class OpenShiftProcess(K8sAnsibleMixin):
return spec
def execute_module(self):
self.client = self.get_api_client()
self.client = get_api_client(self.module)
v1_templates = self.find_resource('templates', 'template.openshift.io/v1', fail=True)
v1_processed_templates = self.find_resource('processedtemplates', 'template.openshift.io/v1', fail=True)
@@ -294,7 +295,7 @@ class OpenShiftProcess(K8sAnsibleMixin):
template = None
if src or definition:
self.set_resource_definitions()
self.set_resource_definitions(self.module)
if len(self.resource_definitions) < 1:
self.fail_json('Unable to load a Template resource from src or resource_definition')
elif len(self.resource_definitions) > 1:

View File

@@ -29,8 +29,8 @@ extends_documentation_fragment:
- kubernetes.core.k8s_state_options
requirements:
- "python >= 2.7"
- "openshift >= 0.11.0"
- "python >= 3.6"
- "kubernetes >= 12.0.0"
- "PyYAML >= 3.11"
options:
@@ -305,8 +305,9 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
try:
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
K8sAnsibleMixin, AUTH_ARG_SPEC, WAIT_ARG_SPEC, COMMON_ARG_SPEC
from ansible_collections.kubernetes.core.plugins.module_utils.common import K8sAnsibleMixin, get_api_client
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
AUTH_ARG_SPEC, WAIT_ARG_SPEC, COMMON_ARG_SPEC
)
HAS_KUBERNETES_COLLECTION = True
except ImportError as e:
@@ -317,7 +318,7 @@ except ImportError as e:
AUTH_ARG_SPEC = WAIT_ARG_SPEC = COMMON_ARG_SPEC = {}
try:
from openshift.dynamic.exceptions import DynamicApiError, NotFoundError
from kubernetes.dynamic.exceptions import DynamicApiError, NotFoundError
except ImportError:
pass
@@ -338,7 +339,7 @@ class OpenShiftRoute(K8sAnsibleMixin):
error=to_native(k8s_collection_import_exception)
)
super(OpenShiftRoute, self).__init__()
super(OpenShiftRoute, self).__init__(self.module)
self.params = self.module.params
# TODO: should probably make it so that at least some of these aren't required for perform_action to work
@@ -375,7 +376,7 @@ class OpenShiftRoute(K8sAnsibleMixin):
return spec
def execute_module(self):
self.client = self.get_api_client()
self.client = get_api_client(self.module)
v1_routes = self.find_resource('Route', 'route.openshift.io/v1', fail=True)
service_name = self.params.get('service')

View File

@@ -1,2 +1,2 @@
openshift>=0.6.2
kubernetes>=12.0.0
requests-oauthlib

View File

@@ -1,3 +1,3 @@
collections:
- name: kubernetes.core
version: '>=1.2.0,<1.3.0'
version: '>=2.0.0,<2.1.0'