mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-06 13:02:37 +00:00
Enable black formatting test (#259)
Enable black formatting test SUMMARY Signed-off-by: Abhijeet Kasurde akasurde@redhat.com ISSUE TYPE Bugfix Pull Request COMPONENT NAME plugins/action/k8s_info.py plugins/connection/kubectl.py plugins/doc_fragments/helm_common_options.py plugins/doc_fragments/k8s_auth_options.py plugins/doc_fragments/k8s_delete_options.py plugins/doc_fragments/k8s_name_options.py plugins/doc_fragments/k8s_resource_options.py plugins/doc_fragments/k8s_scale_options.py plugins/doc_fragments/k8s_state_options.py plugins/doc_fragments/k8s_wait_options.py plugins/filter/k8s.py plugins/inventory/k8s.py plugins/lookup/k8s.py plugins/lookup/kustomize.py plugins/module_utils/ansiblemodule.py plugins/module_utils/apply.py plugins/module_utils/args_common.py plugins/module_utils/client/discovery.py plugins/module_utils/client/resource.py plugins/module_utils/common.py plugins/module_utils/exceptions.py plugins/module_utils/hashes.py plugins/module_utils/helm.py plugins/module_utils/k8sdynamicclient.py plugins/module_utils/selector.py plugins/modules/helm.py plugins/modules/helm_info.py plugins/modules/helm_plugin.py plugins/modules/helm_plugin_info.py plugins/modules/helm_repository.py plugins/modules/helm_template.py plugins/modules/k8s.py plugins/modules/k8s_cluster_info.py plugins/modules/k8s_cp.py plugins/modules/k8s_drain.py plugins/modules/k8s_exec.py plugins/modules/k8s_info.py plugins/modules/k8s_json_patch.py plugins/modules/k8s_log.py plugins/modules/k8s_rollback.py plugins/modules/k8s_scale.py plugins/modules/k8s_service.py tests/integration/targets/kubernetes/library/test_tempfile.py tests/unit/module_utils/test_apply.py tests/unit/module_utils/test_common.py tests/unit/module_utils/test_discoverer.py tests/unit/module_utils/test_hashes.py tests/unit/module_utils/test_marshal.py tests/unit/module_utils/test_selector.py tox.ini Reviewed-by: None <None> Reviewed-by: Mike Graves <mgraves@redhat.com> Reviewed-by: None <None>
This commit is contained in:
@@ -14,13 +14,16 @@
|
||||
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
from collections import OrderedDict
|
||||
import json
|
||||
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.exceptions import ApplyException
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.exceptions import (
|
||||
ApplyException,
|
||||
)
|
||||
|
||||
try:
|
||||
from kubernetes.dynamic.exceptions import NotFoundError
|
||||
@@ -28,50 +31,52 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
LAST_APPLIED_CONFIG_ANNOTATION = 'kubectl.kubernetes.io/last-applied-configuration'
|
||||
LAST_APPLIED_CONFIG_ANNOTATION = "kubectl.kubernetes.io/last-applied-configuration"
|
||||
|
||||
POD_SPEC_SUFFIXES = {
|
||||
'containers': 'name',
|
||||
'initContainers': 'name',
|
||||
'ephemeralContainers': 'name',
|
||||
'volumes': 'name',
|
||||
'imagePullSecrets': 'name',
|
||||
'containers.volumeMounts': 'mountPath',
|
||||
'containers.volumeDevices': 'devicePath',
|
||||
'containers.env': 'name',
|
||||
'containers.ports': 'containerPort',
|
||||
'initContainers.volumeMounts': 'mountPath',
|
||||
'initContainers.volumeDevices': 'devicePath',
|
||||
'initContainers.env': 'name',
|
||||
'initContainers.ports': 'containerPort',
|
||||
'ephemeralContainers.volumeMounts': 'mountPath',
|
||||
'ephemeralContainers.volumeDevices': 'devicePath',
|
||||
'ephemeralContainers.env': 'name',
|
||||
'ephemeralContainers.ports': 'containerPort',
|
||||
"containers": "name",
|
||||
"initContainers": "name",
|
||||
"ephemeralContainers": "name",
|
||||
"volumes": "name",
|
||||
"imagePullSecrets": "name",
|
||||
"containers.volumeMounts": "mountPath",
|
||||
"containers.volumeDevices": "devicePath",
|
||||
"containers.env": "name",
|
||||
"containers.ports": "containerPort",
|
||||
"initContainers.volumeMounts": "mountPath",
|
||||
"initContainers.volumeDevices": "devicePath",
|
||||
"initContainers.env": "name",
|
||||
"initContainers.ports": "containerPort",
|
||||
"ephemeralContainers.volumeMounts": "mountPath",
|
||||
"ephemeralContainers.volumeDevices": "devicePath",
|
||||
"ephemeralContainers.env": "name",
|
||||
"ephemeralContainers.ports": "containerPort",
|
||||
}
|
||||
|
||||
POD_SPEC_PREFIXES = [
|
||||
'Pod.spec',
|
||||
'Deployment.spec.template.spec',
|
||||
'DaemonSet.spec.template.spec',
|
||||
'StatefulSet.spec.template.spec',
|
||||
'Job.spec.template.spec',
|
||||
'Cronjob.spec.jobTemplate.spec.template.spec',
|
||||
"Pod.spec",
|
||||
"Deployment.spec.template.spec",
|
||||
"DaemonSet.spec.template.spec",
|
||||
"StatefulSet.spec.template.spec",
|
||||
"Job.spec.template.spec",
|
||||
"Cronjob.spec.jobTemplate.spec.template.spec",
|
||||
]
|
||||
|
||||
# patch merge keys taken from generated.proto files under
|
||||
# staging/src/k8s.io/api in kubernetes/kubernetes
|
||||
STRATEGIC_MERGE_PATCH_KEYS = {
|
||||
'Service.spec.ports': 'port',
|
||||
'ServiceAccount.secrets': 'name',
|
||||
'ValidatingWebhookConfiguration.webhooks': 'name',
|
||||
'MutatingWebhookConfiguration.webhooks': 'name',
|
||||
"Service.spec.ports": "port",
|
||||
"ServiceAccount.secrets": "name",
|
||||
"ValidatingWebhookConfiguration.webhooks": "name",
|
||||
"MutatingWebhookConfiguration.webhooks": "name",
|
||||
}
|
||||
|
||||
STRATEGIC_MERGE_PATCH_KEYS.update(
|
||||
{"%s.%s" % (prefix, key): value
|
||||
for prefix in POD_SPEC_PREFIXES
|
||||
for key, value in POD_SPEC_SUFFIXES.items()}
|
||||
{
|
||||
"%s.%s" % (prefix, key): value
|
||||
for prefix in POD_SPEC_PREFIXES
|
||||
for key, value in POD_SPEC_SUFFIXES.items()
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -79,21 +84,28 @@ def annotate(desired):
|
||||
return dict(
|
||||
metadata=dict(
|
||||
annotations={
|
||||
LAST_APPLIED_CONFIG_ANNOTATION: json.dumps(desired, separators=(',', ':'), indent=None, sort_keys=True)
|
||||
LAST_APPLIED_CONFIG_ANNOTATION: json.dumps(
|
||||
desired, separators=(",", ":"), indent=None, sort_keys=True
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def apply_patch(actual, desired):
|
||||
last_applied = actual['metadata'].get('annotations', {}).get(LAST_APPLIED_CONFIG_ANNOTATION)
|
||||
last_applied = (
|
||||
actual["metadata"].get("annotations", {}).get(LAST_APPLIED_CONFIG_ANNOTATION)
|
||||
)
|
||||
|
||||
if last_applied:
|
||||
# ensure that last_applied doesn't come back as a dict of unicode key/value pairs
|
||||
# json.loads can be used if we stop supporting python 2
|
||||
last_applied = json.loads(last_applied)
|
||||
patch = merge(dict_merge(last_applied, annotate(last_applied)),
|
||||
dict_merge(desired, annotate(desired)), actual)
|
||||
patch = merge(
|
||||
dict_merge(last_applied, annotate(last_applied)),
|
||||
dict_merge(desired, annotate(desired)),
|
||||
actual,
|
||||
)
|
||||
if patch:
|
||||
return actual, patch
|
||||
else:
|
||||
@@ -104,7 +116,10 @@ def apply_patch(actual, desired):
|
||||
|
||||
def apply_object(resource, definition):
|
||||
try:
|
||||
actual = resource.get(name=definition['metadata']['name'], namespace=definition['metadata'].get('namespace'))
|
||||
actual = resource.get(
|
||||
name=definition["metadata"]["name"],
|
||||
namespace=definition["metadata"].get("namespace"),
|
||||
)
|
||||
except NotFoundError:
|
||||
return None, dict_merge(definition, annotate(definition))
|
||||
return apply_patch(actual.to_dict(), definition)
|
||||
@@ -113,14 +128,21 @@ def apply_object(resource, definition):
|
||||
def k8s_apply(resource, definition, **kwargs):
|
||||
existing, desired = apply_object(resource, definition)
|
||||
if not existing:
|
||||
return resource.create(body=desired, namespace=definition['metadata'].get('namespace'), **kwargs)
|
||||
return resource.create(
|
||||
body=desired, namespace=definition["metadata"].get("namespace"), **kwargs
|
||||
)
|
||||
if existing == desired:
|
||||
return resource.get(name=definition['metadata']['name'], namespace=definition['metadata'].get('namespace'))
|
||||
return resource.patch(body=desired,
|
||||
name=definition['metadata']['name'],
|
||||
namespace=definition['metadata'].get('namespace'),
|
||||
content_type='application/merge-patch+json',
|
||||
**kwargs)
|
||||
return resource.get(
|
||||
name=definition["metadata"]["name"],
|
||||
namespace=definition["metadata"].get("namespace"),
|
||||
)
|
||||
return resource.patch(
|
||||
body=desired,
|
||||
name=definition["metadata"]["name"],
|
||||
namespace=definition["metadata"].get("namespace"),
|
||||
content_type="application/merge-patch+json",
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
# The patch is the difference from actual to desired without deletions, plus deletions
|
||||
@@ -129,7 +151,7 @@ def k8s_apply(resource, definition, **kwargs):
|
||||
# deletions, and then apply delta to deletions as a patch, which should be strictly additive.
|
||||
def merge(last_applied, desired, actual, position=None):
|
||||
deletions = get_deletions(last_applied, desired)
|
||||
delta = get_delta(last_applied, actual, desired, position or desired['kind'])
|
||||
delta = get_delta(last_applied, actual, desired, position or desired["kind"])
|
||||
return dict_merge(deletions, delta)
|
||||
|
||||
|
||||
@@ -139,7 +161,9 @@ def list_to_dict(lst, key, position):
|
||||
try:
|
||||
result[item[key]] = item
|
||||
except KeyError:
|
||||
raise ApplyException("Expected key '%s' not found in position %s" % (key, position))
|
||||
raise ApplyException(
|
||||
"Expected key '%s' not found in position %s" % (key, position)
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@@ -158,7 +182,12 @@ def list_merge(last_applied, actual, desired, position):
|
||||
if key not in actual_dict or key not in last_applied_dict:
|
||||
result.append(desired_dict[key])
|
||||
else:
|
||||
patch = merge(last_applied_dict[key], desired_dict[key], actual_dict[key], position)
|
||||
patch = merge(
|
||||
last_applied_dict[key],
|
||||
desired_dict[key],
|
||||
actual_dict[key],
|
||||
position,
|
||||
)
|
||||
result.append(dict_merge(actual_dict[key], patch))
|
||||
for key in actual_dict:
|
||||
if key not in desired_dict and key not in last_applied_dict:
|
||||
@@ -198,11 +227,11 @@ def recursive_list_diff(list1, list2, position=None):
|
||||
|
||||
def recursive_diff(dict1, dict2, position=None):
|
||||
if not position:
|
||||
if 'kind' in dict1 and dict1.get('kind') == dict2.get('kind'):
|
||||
position = dict1['kind']
|
||||
if "kind" in dict1 and dict1.get("kind") == dict2.get("kind"):
|
||||
position = dict1["kind"]
|
||||
left = dict((k, v) for (k, v) in dict1.items() if k not in dict2)
|
||||
right = dict((k, v) for (k, v) in dict2.items() if k not in dict1)
|
||||
for k in (set(dict1.keys()) & set(dict2.keys())):
|
||||
for k in set(dict1.keys()) & set(dict2.keys()):
|
||||
if position:
|
||||
this_position = "%s.%s" % (position, k)
|
||||
if isinstance(dict1[k], dict) and isinstance(dict2[k], dict):
|
||||
@@ -247,11 +276,15 @@ def get_delta(last_applied, actual, desired, position=None):
|
||||
if actual_value is None:
|
||||
patch[k] = desired_value
|
||||
elif isinstance(desired_value, dict):
|
||||
p = get_delta(last_applied.get(k, {}), actual_value, desired_value, this_position)
|
||||
p = get_delta(
|
||||
last_applied.get(k, {}), actual_value, desired_value, this_position
|
||||
)
|
||||
if p:
|
||||
patch[k] = p
|
||||
elif isinstance(desired_value, list):
|
||||
p = list_merge(last_applied.get(k, []), actual_value, desired_value, this_position)
|
||||
p = list_merge(
|
||||
last_applied.get(k, []), actual_value, desired_value, this_position
|
||||
)
|
||||
if p:
|
||||
patch[k] = [item for item in p if item is not None]
|
||||
elif actual_value != desired_value:
|
||||
|
||||
Reference in New Issue
Block a user