Update CI - Continue work from #195 (#202)

* Upgrade Ansible and OKD versions for CI

* Use ubi9 and fix sanity

* Use correct pip install

* Try using quotes

* Ensure python3.9

* Upgrade ansible and molecule versions

* Remove DeploymentConfig

DeploymentConfigs are deprecated and seem to now be causing idempotence
problems. Replacing them with Deployments fixes it.

* Attempt to fix ldap integration tests

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Move sanity and unit tests to GH actions

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Firt round of sanity fixes

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add kubernetes.core collection as sanity requirement

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add ignore-2.16.txt

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Attempt to fix units

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add ignore-2.17

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Attempt to fix unit tests

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add pytest-ansible to test-requirements.txt

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add changelog fragment

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add workflow for ansible-lint

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Apply black

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Fix linters

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Add # fmt: skip

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Yet another round of linting

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Yet another round of linting

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Remove setup.cfg

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Revert #fmt

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Use ansible-core 2.14

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Cleanup ansible-lint ignores

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>

* Try using service instead of pod IP

* Fix typo

* Actually use the correct port

* See if NetworkPolicy is preventing connection

* using Pod internal IP

* fix adm prune auth roles syntax

* adding some retry steps

* fix: openshift_builds target

* add flag --force-with-deps when building downstream collection

* Remove yamllint from tox linters, bump minimum python supported version to 3.9, Remove support for ansible-core < 2.14

---------

Signed-off-by: Alina Buzachis <abuzachis@redhat.com>
Co-authored-by: Mike Graves <mgraves@redhat.com>
Co-authored-by: Alina Buzachis <abuzachis@redhat.com>
This commit is contained in:
Bikouo Aubin
2023-11-15 18:00:38 +01:00
committed by GitHub
parent cb796e1298
commit a63e5b7b36
76 changed files with 4364 additions and 3510 deletions

View File

@@ -9,7 +9,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
# STARTREMOVE (downstream)
DOCUMENTATION = r'''
DOCUMENTATION = r"""
module: openshift_route
short_description: Expose a Service as an OpenShift Route.
@@ -133,9 +133,9 @@ options:
- insecure
default: insecure
type: str
'''
"""
EXAMPLES = r'''
EXAMPLES = r"""
- name: Create hello-world deployment
community.okd.k8s:
definition:
@@ -155,10 +155,10 @@ EXAMPLES = r'''
app: hello-kubernetes
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
- name: Create Service for the hello-world deployment
community.okd.k8s:
@@ -170,8 +170,8 @@ EXAMPLES = r'''
namespace: default
spec:
ports:
- port: 80
targetPort: 8080
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes
@@ -183,9 +183,9 @@ EXAMPLES = r'''
annotations:
haproxy.router.openshift.io/balance: roundrobin
register: route
'''
"""
RETURN = r'''
RETURN = r"""
result:
description:
- The Route object that was created or updated. Will be empty in the case of deletion.
@@ -303,20 +303,28 @@ duration:
returned: when C(wait) is true
type: int
sample: 48
'''
"""
# ENDREMOVE (downstream)
import copy
from ansible.module_utils._text import to_native
from ansible_collections.community.okd.plugins.module_utils.openshift_common import AnsibleOpenshiftModule
from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
AnsibleOpenshiftModule,
)
try:
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.runner import perform_action
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import Waiter
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.runner import (
perform_action,
)
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import (
Waiter,
)
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
AUTH_ARG_SPEC, WAIT_ARG_SPEC, COMMON_ARG_SPEC
AUTH_ARG_SPEC,
WAIT_ARG_SPEC,
COMMON_ARG_SPEC,
)
except ImportError as e:
pass
@@ -329,7 +337,6 @@ except ImportError:
class OpenShiftRoute(AnsibleOpenshiftModule):
def __init__(self):
super(OpenShiftRoute, self).__init__(
argument_spec=self.argspec,
@@ -339,7 +346,7 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
self.append_hash = False
self.apply = False
self.warnings = []
self.params['merge_type'] = None
self.params["merge_type"] = None
@property
def argspec(self):
@@ -347,80 +354,95 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
spec.update(copy.deepcopy(WAIT_ARG_SPEC))
spec.update(copy.deepcopy(COMMON_ARG_SPEC))
spec['service'] = dict(type='str', aliases=['svc'])
spec['namespace'] = dict(required=True, type='str')
spec['labels'] = dict(type='dict')
spec['name'] = dict(type='str')
spec['hostname'] = dict(type='str')
spec['path'] = dict(type='str')
spec['wildcard_policy'] = dict(choices=['Subdomain'], type='str')
spec['port'] = dict(type='str')
spec['tls'] = dict(type='dict', options=dict(
ca_certificate=dict(type='str'),
certificate=dict(type='str'),
destination_ca_certificate=dict(type='str'),
key=dict(type='str', no_log=False),
insecure_policy=dict(type='str', choices=['allow', 'redirect', 'disallow'], default='disallow'),
))
spec['termination'] = dict(choices=['edge', 'passthrough', 'reencrypt', 'insecure'], default='insecure')
spec['annotations'] = dict(type='dict')
spec["service"] = dict(type="str", aliases=["svc"])
spec["namespace"] = dict(required=True, type="str")
spec["labels"] = dict(type="dict")
spec["name"] = dict(type="str")
spec["hostname"] = dict(type="str")
spec["path"] = dict(type="str")
spec["wildcard_policy"] = dict(choices=["Subdomain"], type="str")
spec["port"] = dict(type="str")
spec["tls"] = dict(
type="dict",
options=dict(
ca_certificate=dict(type="str"),
certificate=dict(type="str"),
destination_ca_certificate=dict(type="str"),
key=dict(type="str", no_log=False),
insecure_policy=dict(
type="str",
choices=["allow", "redirect", "disallow"],
default="disallow",
),
),
)
spec["termination"] = dict(
choices=["edge", "passthrough", "reencrypt", "insecure"], default="insecure"
)
spec["annotations"] = dict(type="dict")
return spec
def execute_module(self):
service_name = self.params.get('service')
namespace = self.params['namespace']
termination_type = self.params.get('termination')
if termination_type == 'insecure':
service_name = self.params.get("service")
namespace = self.params["namespace"]
termination_type = self.params.get("termination")
if termination_type == "insecure":
termination_type = None
state = self.params.get('state')
state = self.params.get("state")
if state != 'absent' and not service_name:
if state != "absent" and not service_name:
self.fail_json("If 'state' is not 'absent' then 'service' must be provided")
# We need to do something a little wonky to wait if the user doesn't supply a custom condition
custom_wait = self.params.get('wait') and not self.params.get('wait_condition') and state != 'absent'
custom_wait = (
self.params.get("wait")
and not self.params.get("wait_condition")
and state != "absent"
)
if custom_wait:
# Don't use default wait logic in perform_action
self.params['wait'] = False
self.params["wait"] = False
route_name = self.params.get('name') or service_name
labels = self.params.get('labels')
hostname = self.params.get('hostname')
path = self.params.get('path')
wildcard_policy = self.params.get('wildcard_policy')
port = self.params.get('port')
annotations = self.params.get('annotations')
route_name = self.params.get("name") or service_name
labels = self.params.get("labels")
hostname = self.params.get("hostname")
path = self.params.get("path")
wildcard_policy = self.params.get("wildcard_policy")
port = self.params.get("port")
annotations = self.params.get("annotations")
if termination_type and self.params.get('tls'):
tls_ca_cert = self.params['tls'].get('ca_certificate')
tls_cert = self.params['tls'].get('certificate')
tls_dest_ca_cert = self.params['tls'].get('destination_ca_certificate')
tls_key = self.params['tls'].get('key')
tls_insecure_policy = self.params['tls'].get('insecure_policy')
if tls_insecure_policy == 'disallow':
if termination_type and self.params.get("tls"):
tls_ca_cert = self.params["tls"].get("ca_certificate")
tls_cert = self.params["tls"].get("certificate")
tls_dest_ca_cert = self.params["tls"].get("destination_ca_certificate")
tls_key = self.params["tls"].get("key")
tls_insecure_policy = self.params["tls"].get("insecure_policy")
if tls_insecure_policy == "disallow":
tls_insecure_policy = None
else:
tls_ca_cert = tls_cert = tls_dest_ca_cert = tls_key = tls_insecure_policy = None
tls_ca_cert = (
tls_cert
) = tls_dest_ca_cert = tls_key = tls_insecure_policy = None
route = {
'apiVersion': 'route.openshift.io/v1',
'kind': 'Route',
'metadata': {
'name': route_name,
'namespace': namespace,
'labels': labels,
"apiVersion": "route.openshift.io/v1",
"kind": "Route",
"metadata": {
"name": route_name,
"namespace": namespace,
"labels": labels,
},
'spec': {}
"spec": {},
}
if annotations:
route['metadata']['annotations'] = annotations
route["metadata"]["annotations"] = annotations
if state != 'absent':
route['spec'] = self.build_route_spec(
service_name, namespace,
if state != "absent":
route["spec"] = self.build_route_spec(
service_name,
namespace,
port=port,
wildcard_policy=wildcard_policy,
hostname=hostname,
@@ -434,79 +456,120 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
)
result = perform_action(self.svc, route, self.params)
timeout = self.params.get('wait_timeout')
sleep = self.params.get('wait_sleep')
timeout = self.params.get("wait_timeout")
sleep = self.params.get("wait_sleep")
if custom_wait:
v1_routes = self.find_resource('Route', 'route.openshift.io/v1', fail=True)
v1_routes = self.find_resource("Route", "route.openshift.io/v1", fail=True)
waiter = Waiter(self.client, v1_routes, wait_predicate)
success, result['result'], result['duration'] = waiter.wait(timeout=timeout, sleep=sleep, name=route_name, namespace=namespace)
success, result["result"], result["duration"] = waiter.wait(
timeout=timeout, sleep=sleep, name=route_name, namespace=namespace
)
self.exit_json(**result)
def build_route_spec(self, service_name, namespace, port=None, wildcard_policy=None, hostname=None, path=None, termination_type=None,
tls_insecure_policy=None, tls_ca_cert=None, tls_cert=None, tls_key=None, tls_dest_ca_cert=None):
v1_services = self.find_resource('Service', 'v1', fail=True)
def build_route_spec(
self,
service_name,
namespace,
port=None,
wildcard_policy=None,
hostname=None,
path=None,
termination_type=None,
tls_insecure_policy=None,
tls_ca_cert=None,
tls_cert=None,
tls_key=None,
tls_dest_ca_cert=None,
):
v1_services = self.find_resource("Service", "v1", fail=True)
try:
target_service = v1_services.get(name=service_name, namespace=namespace)
except NotFoundError:
if not port:
self.fail_json(msg="You need to provide the 'port' argument when exposing a non-existent service")
self.fail_json(
msg="You need to provide the 'port' argument when exposing a non-existent service"
)
target_service = None
except DynamicApiError as exc:
self.fail_json(msg='Failed to retrieve service to be exposed: {0}'.format(exc.body),
error=exc.status, status=exc.status, reason=exc.reason)
self.fail_json(
msg="Failed to retrieve service to be exposed: {0}".format(exc.body),
error=exc.status,
status=exc.status,
reason=exc.reason,
)
except Exception as exc:
self.fail_json(msg='Failed to retrieve service to be exposed: {0}'.format(to_native(exc)),
error='', status='', reason='')
self.fail_json(
msg="Failed to retrieve service to be exposed: {0}".format(
to_native(exc)
),
error="",
status="",
reason="",
)
route_spec = {
'tls': {},
'to': {
'kind': 'Service',
'name': service_name,
"tls": {},
"to": {
"kind": "Service",
"name": service_name,
},
'port': {
'targetPort': self.set_port(target_service, port),
"port": {
"targetPort": self.set_port(target_service, port),
},
'wildcardPolicy': wildcard_policy
"wildcardPolicy": wildcard_policy,
}
# Want to conditionally add these so we don't overwrite what is automically added when nothing is provided
if termination_type:
route_spec['tls'] = dict(termination=termination_type.capitalize())
route_spec["tls"] = dict(termination=termination_type.capitalize())
if tls_insecure_policy:
if termination_type == 'edge':
route_spec['tls']['insecureEdgeTerminationPolicy'] = tls_insecure_policy.capitalize()
elif termination_type == 'passthrough':
if tls_insecure_policy != 'redirect':
self.fail_json("'redirect' is the only supported insecureEdgeTerminationPolicy for passthrough routes")
route_spec['tls']['insecureEdgeTerminationPolicy'] = tls_insecure_policy.capitalize()
elif termination_type == 'reencrypt':
self.fail_json("'tls.insecure_policy' is not supported with reencrypt routes")
if termination_type == "edge":
route_spec["tls"][
"insecureEdgeTerminationPolicy"
] = tls_insecure_policy.capitalize()
elif termination_type == "passthrough":
if tls_insecure_policy != "redirect":
self.fail_json(
"'redirect' is the only supported insecureEdgeTerminationPolicy for passthrough routes"
)
route_spec["tls"][
"insecureEdgeTerminationPolicy"
] = tls_insecure_policy.capitalize()
elif termination_type == "reencrypt":
self.fail_json(
"'tls.insecure_policy' is not supported with reencrypt routes"
)
else:
route_spec['tls']['insecureEdgeTerminationPolicy'] = None
route_spec["tls"]["insecureEdgeTerminationPolicy"] = None
if tls_ca_cert:
if termination_type == 'passthrough':
self.fail_json("'tls.ca_certificate' is not supported with passthrough routes")
route_spec['tls']['caCertificate'] = tls_ca_cert
if termination_type == "passthrough":
self.fail_json(
"'tls.ca_certificate' is not supported with passthrough routes"
)
route_spec["tls"]["caCertificate"] = tls_ca_cert
if tls_cert:
if termination_type == 'passthrough':
self.fail_json("'tls.certificate' is not supported with passthrough routes")
route_spec['tls']['certificate'] = tls_cert
if termination_type == "passthrough":
self.fail_json(
"'tls.certificate' is not supported with passthrough routes"
)
route_spec["tls"]["certificate"] = tls_cert
if tls_key:
if termination_type == 'passthrough':
if termination_type == "passthrough":
self.fail_json("'tls.key' is not supported with passthrough routes")
route_spec['tls']['key'] = tls_key
route_spec["tls"]["key"] = tls_key
if tls_dest_ca_cert:
if termination_type != 'reencrypt':
self.fail_json("'destination_certificate' is only valid for reencrypt routes")
route_spec['tls']['destinationCACertificate'] = tls_dest_ca_cert
if termination_type != "reencrypt":
self.fail_json(
"'destination_certificate' is only valid for reencrypt routes"
)
route_spec["tls"]["destinationCACertificate"] = tls_dest_ca_cert
else:
route_spec['tls'] = None
route_spec["tls"] = None
if hostname:
route_spec['host'] = hostname
route_spec["host"] = hostname
if path:
route_spec['path'] = path
route_spec["path"] = path
return route_spec
@@ -514,7 +577,7 @@ class OpenShiftRoute(AnsibleOpenshiftModule):
if port_arg:
return port_arg
for p in service.spec.ports:
if p.protocol == 'TCP':
if p.protocol == "TCP":
if p.name is not None:
return p.name
return p.targetPort
@@ -525,7 +588,7 @@ def wait_predicate(route):
if not (route.status and route.status.ingress):
return False
for ingress in route.status.ingress:
match = [x for x in ingress.conditions if x.type == 'Admitted']
match = [x for x in ingress.conditions if x.type == "Admitted"]
if not match:
return False
match = match[0]
@@ -538,5 +601,5 @@ def main():
OpenShiftRoute().run_module()
if __name__ == '__main__':
if __name__ == "__main__":
main()