mirror of
https://github.com/openshift/community.okd.git
synced 2026-03-26 19:03:14 +00:00
* 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>
198 lines
7.1 KiB
Python
198 lines
7.1 KiB
Python
#!/usr/bin/env python
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
__metaclass__ = type
|
|
|
|
import os
|
|
|
|
from ansible.module_utils._text import to_native
|
|
|
|
from ansible_collections.community.okd.plugins.module_utils.openshift_common import (
|
|
AnsibleOpenshiftModule,
|
|
)
|
|
|
|
try:
|
|
from kubernetes.dynamic.exceptions import DynamicApiError
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
class OpenShiftProcess(AnsibleOpenshiftModule):
|
|
def __init__(self, **kwargs):
|
|
super(OpenShiftProcess, self).__init__(**kwargs)
|
|
|
|
def execute_module(self):
|
|
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
|
|
)
|
|
|
|
name = self.params.get("name")
|
|
namespace = self.params.get("namespace")
|
|
namespace_target = self.params.get("namespace_target")
|
|
definition = self.params.get("resource_definition")
|
|
src = self.params.get("src")
|
|
|
|
state = self.params.get("state")
|
|
|
|
parameters = self.params.get("parameters") or {}
|
|
parameter_file = self.params.get("parameter_file")
|
|
|
|
if (name and definition) or (name and src) or (src and definition):
|
|
self.fail_json("Only one of src, name, or definition may be provided")
|
|
|
|
if name and not namespace:
|
|
self.fail_json("namespace is required when name is set")
|
|
|
|
template = None
|
|
|
|
if src or definition:
|
|
self.set_resource_definitions()
|
|
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:
|
|
self.fail_json(
|
|
"Multiple Template resources found in src or resource_definition, only one Template may be processed at a time"
|
|
)
|
|
template = self.resource_definitions[0]
|
|
template_namespace = template.get("metadata", {}).get("namespace")
|
|
namespace = template_namespace or namespace or namespace_target or "default"
|
|
elif name and namespace:
|
|
try:
|
|
template = v1_templates.get(name=name, namespace=namespace).to_dict()
|
|
except DynamicApiError as exc:
|
|
self.fail_json(
|
|
msg="Failed to retrieve Template with name '{0}' in namespace '{1}': {2}".format(
|
|
name, namespace, exc.body
|
|
),
|
|
error=exc.status,
|
|
status=exc.status,
|
|
reason=exc.reason,
|
|
)
|
|
except Exception as exc:
|
|
self.fail_json(
|
|
msg="Failed to retrieve Template with name '{0}' in namespace '{1}': {2}".format(
|
|
name, namespace, to_native(exc)
|
|
),
|
|
error="",
|
|
status="",
|
|
reason="",
|
|
)
|
|
else:
|
|
self.fail_json(
|
|
"One of resource_definition, src, or name and namespace must be provided"
|
|
)
|
|
|
|
if parameter_file:
|
|
parameters = self.parse_dotenv_and_merge(parameters, parameter_file)
|
|
|
|
for k, v in parameters.items():
|
|
template = self.update_template_param(template, k, v)
|
|
|
|
result = {"changed": False}
|
|
|
|
try:
|
|
response = v1_processed_templates.create(
|
|
body=template, namespace=namespace
|
|
).to_dict()
|
|
except DynamicApiError as exc:
|
|
self.fail_json(
|
|
msg="Server failed to render the Template: {0}".format(exc.body),
|
|
error=exc.status,
|
|
status=exc.status,
|
|
reason=exc.reason,
|
|
)
|
|
except Exception as exc:
|
|
self.fail_json(
|
|
msg="Server failed to render the Template: {0}".format(to_native(exc)),
|
|
error="",
|
|
status="",
|
|
reason="",
|
|
)
|
|
result["message"] = ""
|
|
if "message" in response:
|
|
result["message"] = response["message"]
|
|
result["resources"] = response["objects"]
|
|
|
|
if state != "rendered":
|
|
self.create_resources(response["objects"])
|
|
|
|
self.exit_json(**result)
|
|
|
|
def create_resources(self, definitions):
|
|
params = {"namespace": self.params.get("namespace_target")}
|
|
|
|
self.params["apply"] = False
|
|
self.params["validate"] = None
|
|
|
|
changed = False
|
|
results = []
|
|
|
|
flattened_definitions = []
|
|
for definition in definitions:
|
|
if definition is None:
|
|
continue
|
|
kind = definition.get("kind")
|
|
if kind and kind.endswith("List"):
|
|
flattened_definitions.extend(self.flatten_list_kind(definition, params))
|
|
else:
|
|
flattened_definitions.append(self.merge_params(definition, params))
|
|
|
|
for definition in flattened_definitions:
|
|
result = self.perform_action(definition, self.params)
|
|
changed = changed or result["changed"]
|
|
results.append(result)
|
|
|
|
if len(results) == 1:
|
|
self.exit_json(**results[0])
|
|
|
|
self.exit_json(**{"changed": changed, "result": {"results": results}})
|
|
|
|
def update_template_param(self, template, k, v):
|
|
for i, param in enumerate(template["parameters"]):
|
|
if param["name"] == k:
|
|
template["parameters"][i]["value"] = v
|
|
return template
|
|
return template
|
|
|
|
def parse_dotenv_and_merge(self, parameters, parameter_file):
|
|
import re
|
|
|
|
DOTENV_PARSER = re.compile(
|
|
r"(?x)^(\s*(\#.*|\s*|(export\s+)?(?P<key>[A-z_][A-z0-9_.]*)=(?P<value>.+?)?)\s*)[\r\n]*$"
|
|
)
|
|
path = os.path.normpath(parameter_file)
|
|
if not os.path.exists(path):
|
|
self.fail(msg="Error accessing {0}. Does the file exist?".format(path))
|
|
try:
|
|
with open(path, "r") as f:
|
|
multiline = ""
|
|
for line in f.readlines():
|
|
line = line.strip()
|
|
if line.endswith("\\"):
|
|
multiline += " ".join(line.rsplit("\\", 1))
|
|
continue
|
|
if multiline:
|
|
line = multiline + line
|
|
multiline = ""
|
|
match = DOTENV_PARSER.search(line)
|
|
if not match:
|
|
continue
|
|
match = match.groupdict()
|
|
if match.get("key"):
|
|
if match["key"] in parameters:
|
|
self.fail_json(
|
|
msg="Duplicate value for '{0}' detected in parameter file".format(
|
|
match["key"]
|
|
)
|
|
)
|
|
parameters[match["key"]] = match["value"]
|
|
except IOError as exc:
|
|
self.fail(msg="Error loading parameter file: {0}".format(exc))
|
|
return parameters
|