mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-26 21:33:02 +00:00
* Cleanup gha * test by removing matrix excludes * Rename sanity tests * trigger integration tests * Fix ansible-lint workflow * Fix concurrency * Add ansible-lint config * Add ansible-lint config * Fix integration and lint issues * integration wf * fix yamllint issues * fix yamllint issues * update readme and add ignore-2.16.txt * fix ansible-doc * Add version * Use /dev/random to generate random data The GHA environment has difficultly generating entropy. Trying to read from /dev/urandom just blocks forever. We don't care if the random data is cryptographically secure; it's just garbage data for the test. Read from /dev/random, instead. This is only used during the k8s_copy test target. This also removes the custom test module that was being used to generate the files. It's not worth maintaining this for two task that can be replaced with some simple command/shell tasks. * Fix saniry errors * test github_action fix * Address review comments * Remove default types * review comments * isort fixes * remove tags * Add setuptools to venv * Test gh changes * update changelog * update ignore-2.16 * Fix indentation in inventory plugin example * Update .github/workflows/integration-tests.yaml * Update integration-tests.yaml --------- Co-authored-by: Mike Graves <mgraves@redhat.com> Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>
264 lines
7.4 KiB
Python
264 lines
7.4 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2018, KubeVirt Team <@kubevirt>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
|
|
DOCUMENTATION = r"""
|
|
|
|
module: k8s_service
|
|
|
|
short_description: Manage Services on Kubernetes
|
|
|
|
author: KubeVirt Team (@kubevirt)
|
|
|
|
description:
|
|
- Use Kubernetes Python SDK to manage Services on Kubernetes
|
|
|
|
extends_documentation_fragment:
|
|
- kubernetes.core.k8s_auth_options
|
|
- kubernetes.core.k8s_resource_options
|
|
- kubernetes.core.k8s_state_options
|
|
|
|
options:
|
|
merge_type:
|
|
description:
|
|
- Whether to override the default patch merge approach with a specific type. By default, the strategic
|
|
merge will typically be used.
|
|
- 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)
|
|
- 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.
|
|
choices:
|
|
- json
|
|
- merge
|
|
- strategic-merge
|
|
type: list
|
|
elements: str
|
|
name:
|
|
description:
|
|
- Use to specify a Service object name.
|
|
required: true
|
|
type: str
|
|
namespace:
|
|
description:
|
|
- Use to specify a Service object namespace.
|
|
required: true
|
|
type: str
|
|
type:
|
|
description:
|
|
- Specifies the type of Service to create.
|
|
- See U(https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types)
|
|
choices:
|
|
- NodePort
|
|
- ClusterIP
|
|
- LoadBalancer
|
|
- ExternalName
|
|
type: str
|
|
ports:
|
|
description:
|
|
- A list of ports to expose.
|
|
- U(https://kubernetes.io/docs/concepts/services-networking/service/#multi-port-services)
|
|
type: list
|
|
elements: dict
|
|
selector:
|
|
description:
|
|
- Label selectors identify objects this Service should apply to.
|
|
- U(https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/)
|
|
type: dict
|
|
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'
|
|
- mutually exclusive with C(merge_type)
|
|
default: False
|
|
type: bool
|
|
|
|
requirements:
|
|
- python >= 3.6
|
|
- kubernetes >= 12.0.0
|
|
"""
|
|
|
|
EXAMPLES = r"""
|
|
- name: Expose https port with ClusterIP
|
|
kubernetes.core.k8s_service:
|
|
state: present
|
|
name: test-https
|
|
namespace: default
|
|
ports:
|
|
- port: 443
|
|
protocol: TCP
|
|
selector:
|
|
key: special
|
|
|
|
- name: Expose https port with ClusterIP using spec
|
|
kubernetes.core.k8s_service:
|
|
state: present
|
|
name: test-https
|
|
namespace: default
|
|
inline:
|
|
spec:
|
|
ports:
|
|
- port: 443
|
|
protocol: TCP
|
|
selector:
|
|
key: special
|
|
"""
|
|
|
|
RETURN = r"""
|
|
result:
|
|
description:
|
|
- The created, patched, or otherwise present Service object. Will be empty in the case of a deletion.
|
|
returned: success
|
|
type: complex
|
|
contains:
|
|
api_version:
|
|
description: The versioned schema of this representation of an object.
|
|
returned: success
|
|
type: str
|
|
kind:
|
|
description: Always 'Service'.
|
|
returned: success
|
|
type: str
|
|
metadata:
|
|
description: Standard object metadata. Includes name, namespace, annotations, labels, etc.
|
|
returned: success
|
|
type: complex
|
|
spec:
|
|
description: Specific attributes of the object. Will vary based on the I(api_version) and I(kind).
|
|
returned: success
|
|
type: complex
|
|
status:
|
|
description: Current status details for the object.
|
|
returned: success
|
|
type: complex
|
|
"""
|
|
|
|
import copy
|
|
from collections import defaultdict
|
|
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
|
AnsibleModule,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
|
AUTH_ARG_SPEC,
|
|
COMMON_ARG_SPEC,
|
|
RESOURCE_ARG_SPEC,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
|
get_api_client,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.core import (
|
|
AnsibleK8SModule,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import (
|
|
CoreException,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.resource import (
|
|
create_definitions,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.runner import (
|
|
perform_action,
|
|
)
|
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
|
|
K8sService,
|
|
)
|
|
|
|
SERVICE_ARG_SPEC = {
|
|
"apply": {"type": "bool", "default": False},
|
|
"name": {"required": True},
|
|
"namespace": {"required": True},
|
|
"merge_type": {
|
|
"type": "list",
|
|
"elements": "str",
|
|
"choices": ["json", "merge", "strategic-merge"],
|
|
},
|
|
"selector": {"type": "dict"},
|
|
"type": {
|
|
"type": "str",
|
|
"choices": ["NodePort", "ClusterIP", "LoadBalancer", "ExternalName"],
|
|
},
|
|
"ports": {"type": "list", "elements": "dict"},
|
|
}
|
|
|
|
|
|
def merge_dicts(x, y):
|
|
for k in set(x.keys()).union(y.keys()):
|
|
if k in x and k in y:
|
|
if isinstance(x[k], dict) and isinstance(y[k], dict):
|
|
yield (k, dict(merge_dicts(x[k], y[k])))
|
|
else:
|
|
yield (k, y[k] if y[k] else x[k])
|
|
elif k in x:
|
|
yield (k, x[k])
|
|
else:
|
|
yield (k, y[k])
|
|
|
|
|
|
def argspec():
|
|
"""argspec property builder"""
|
|
argument_spec = copy.deepcopy(AUTH_ARG_SPEC)
|
|
argument_spec.update(COMMON_ARG_SPEC)
|
|
argument_spec.update(RESOURCE_ARG_SPEC)
|
|
argument_spec.update(SERVICE_ARG_SPEC)
|
|
return argument_spec
|
|
|
|
|
|
def execute_module(svc):
|
|
"""Module execution"""
|
|
module = svc.module
|
|
api_version = "v1"
|
|
selector = module.params.get("selector")
|
|
service_type = module.params.get("type")
|
|
ports = module.params.get("ports")
|
|
|
|
definition = defaultdict(defaultdict)
|
|
|
|
definition["kind"] = "Service"
|
|
definition["apiVersion"] = api_version
|
|
|
|
def_spec = definition["spec"]
|
|
def_spec["type"] = service_type
|
|
def_spec["ports"] = ports
|
|
def_spec["selector"] = selector
|
|
|
|
def_meta = definition["metadata"]
|
|
def_meta["name"] = module.params.get("name")
|
|
def_meta["namespace"] = module.params.get("namespace")
|
|
|
|
definitions = create_definitions(module.params)
|
|
|
|
# 'resource_definition:' has lower priority than module parameters
|
|
definition = dict(merge_dicts(definitions[0], definition))
|
|
|
|
result = perform_action(svc, definition, module.params)
|
|
|
|
module.exit_json(**result)
|
|
|
|
|
|
def main():
|
|
module = AnsibleK8SModule(
|
|
module_class=AnsibleModule,
|
|
argument_spec=argspec(),
|
|
supports_check_mode=True,
|
|
)
|
|
|
|
try:
|
|
client = get_api_client(module=module)
|
|
svc = K8sService(client, module)
|
|
execute_module(svc)
|
|
except CoreException as e:
|
|
module.fail_from_exception(e)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|