diff --git a/changelogs/fragments/20250522-add-plain-http-for-oci-registries.yaml b/changelogs/fragments/20250522-add-plain-http-for-oci-registries.yaml new file mode 100644 index 0000000000..7b1702802d --- /dev/null +++ b/changelogs/fragments/20250522-add-plain-http-for-oci-registries.yaml @@ -0,0 +1,4 @@ +minor_changes: + - helm - Parameter plain_http added for working with insecure OCI registries (https://github.com/ansible-collections/kubernetes.core/pull/934). + - helm_pull - Parameter plain_http added for working with insecure OCI registries (https://github.com/ansible-collections/kubernetes.core/pull/934). + - helm_template - Parameter plain_http added for working with insecure OCI registries (https://github.com/ansible-collections/kubernetes.core/pull/934). diff --git a/docs/kubernetes.core.helm_module.rst b/docs/kubernetes.core.helm_module.rst index e7df00d381..b81eb9831e 100644 --- a/docs/kubernetes.core.helm_module.rst +++ b/docs/kubernetes.core.helm_module.rst @@ -716,6 +716,26 @@ Parameters
The use of wait_timeout to wait for kubernetes commands to complete has been deprecated and will be removed after 2022-12-01.
+ + +
+ plain_http + +
+ boolean +
+
added in 5.1.0
+ + + + + +
Use HTTP instead of HTTPS when working with OCI registries
+ +
diff --git a/docs/kubernetes.core.helm_pull_module.rst b/docs/kubernetes.core.helm_pull_module.rst index ac3cc5c571..0ccdec7662 100644 --- a/docs/kubernetes.core.helm_pull_module.rst +++ b/docs/kubernetes.core.helm_pull_module.rst @@ -336,6 +336,26 @@ Parameters
location of public keys used for verification.
+ + +
+ plain_http + +
+ boolean +
+
added in 5.1.0
+ + + + + +
Use HTTP instead of HTTPS when working with OCI registries
+ +
diff --git a/docs/kubernetes.core.helm_template_module.rst b/docs/kubernetes.core.helm_template_module.rst index 983616d3f7..9bb5398fa8 100644 --- a/docs/kubernetes.core.helm_template_module.rst +++ b/docs/kubernetes.core.helm_template_module.rst @@ -361,6 +361,26 @@ Parameters
Paths are evaluated in the order the paths are specified.
+ + +
+ plain_http + +
+ boolean +
+
added in 5.1.0
+ + + + + +
Use HTTP instead of HTTPS when working with OCI registries
+ +
diff --git a/plugins/modules/helm.py b/plugins/modules/helm.py index 8940158d8c..8d8ecc253b 100644 --- a/plugins/modules/helm.py +++ b/plugins/modules/helm.py @@ -237,6 +237,13 @@ default: False aliases: [ skip_tls_certs_check ] version_added: 5.3.0 + plain_http: + description: + - Use HTTP instead of HTTPS when working with OCI registries + - Requires Helm >= 3.13.0 + type: bool + default: False + version_added: 6.1.0 extends_documentation_fragment: - kubernetes.core.helm_common_options """ @@ -319,6 +326,12 @@ chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz" release_namespace: monitoring +- name: Deploy Bitnami's MongoDB latest chart from OCI registry + kubernetes.core.helm: + name: test + chart_ref: "oci://registry-1.docker.io/bitnamicharts/mongodb" + release_namespace: database + # Using complex Values - name: Deploy new-relic client chart kubernetes.core.helm: @@ -495,7 +508,9 @@ def run_dep_update(module, chart_ref): rc, out, err = module.run_helm_command(dep_update) -def fetch_chart_info(module, command, chart_ref, insecure_skip_tls_verify=False): +def fetch_chart_info( + module, command, chart_ref, insecure_skip_tls_verify=False, plain_http=False +): """ Get chart info """ @@ -504,6 +519,17 @@ def fetch_chart_info(module, command, chart_ref, insecure_skip_tls_verify=False) if insecure_skip_tls_verify: inspect_command += " --insecure-skip-tls-verify" + if plain_http: + helm_version = module.get_helm_version() + if LooseVersion(helm_version) < LooseVersion("3.13.0"): + module.fail_json( + msg="plain_http requires helm >= 3.13.0, current version is {0}".format( + helm_version + ) + ) + else: + inspect_command += " --plain-http" + rc, out, err = module.run_helm_command(inspect_command) return yaml.safe_load(out) @@ -533,6 +559,7 @@ def deploy( reset_values=True, reset_then_reuse_values=False, insecure_skip_tls_verify=False, + plain_http=False, ): """ Install/upgrade/rollback release chart @@ -595,6 +622,9 @@ def deploy( else: deploy_command += " --insecure-skip-tls-verify" + if plain_http: + deploy_command += " --plain-http" + if values_files: for value_file in values_files: deploy_command += " --values=" + value_file @@ -690,6 +720,7 @@ def helmdiff_check( reset_values=True, reset_then_reuse_values=False, insecure_skip_tls_verify=False, + plain_http=False, ): """ Use helm diff to determine if a release would change by upgrading a chart. @@ -745,6 +776,17 @@ def helmdiff_check( if insecure_skip_tls_verify: cmd += " --insecure-skip-tls-verify" + if plain_http: + helm_version = module.get_helm_version() + if LooseVersion(helm_version) < LooseVersion("3.13.0"): + module.fail_json( + msg="plain_http requires helm >= 3.13.0, current version is {0}".format( + helm_version + ) + ) + else: + cmd += " --plain-http" + rc, out, err = module.run_helm_command(cmd) return (len(out.strip()) > 0, out.strip()) @@ -808,6 +850,7 @@ def argument_spec(): insecure_skip_tls_verify=dict( type="bool", default=False, aliases=["skip_tls_certs_check"] ), + plain_http=dict(type="bool", default=False), ) ) return arg_spec @@ -862,6 +905,7 @@ def main(): reset_values = module.params.get("reset_values") reset_then_reuse_values = module.params.get("reset_then_reuse_values") insecure_skip_tls_verify = module.params.get("insecure_skip_tls_verify") + plain_http = module.params.get("plain_http") if update_repo_cache: run_repo_update(module) @@ -871,6 +915,16 @@ def main(): release_status = get_release_status(module, release_name, all_status=all_status) helm_cmd = module.get_helm_binary() + + if plain_http: + helm_version = module.get_helm_version() + if LooseVersion(helm_version) < LooseVersion("3.13.0"): + module.fail_json( + msg="plain_http requires helm >= 3.13.0, current version is {0}".format( + helm_version + ) + ) + opt_result = {} if release_state == "absent" and release_status is not None: # skip release statuses 'uninstalled' and 'uninstalling' @@ -900,7 +954,7 @@ def main(): # Fetch chart info to have real version and real name for chart_ref from archive, folder or url chart_info = fetch_chart_info( - module, helm_cmd, chart_ref, insecure_skip_tls_verify + module, helm_cmd, chart_ref, insecure_skip_tls_verify, plain_http ) if dependency_update: @@ -962,6 +1016,7 @@ def main(): reset_values=reset_values, reset_then_reuse_values=reset_then_reuse_values, insecure_skip_tls_verify=insecure_skip_tls_verify, + plain_http=plain_http, ) changed = True @@ -989,6 +1044,7 @@ def main(): reset_values=reset_values, reset_then_reuse_values=reset_then_reuse_values, insecure_skip_tls_verify=insecure_skip_tls_verify, + plain_http=plain_http, ) if would_change and module._diff: opt_result["diff"] = {"prepared": prepared} @@ -1026,6 +1082,7 @@ def main(): reset_values=reset_values, reset_then_reuse_values=reset_then_reuse_values, insecure_skip_tls_verify=insecure_skip_tls_verify, + plain_http=plain_http, ) changed = True diff --git a/plugins/modules/helm_pull.py b/plugins/modules/helm_pull.py index b6ec273e2c..ebf414d394 100644 --- a/plugins/modules/helm_pull.py +++ b/plugins/modules/helm_pull.py @@ -114,6 +114,13 @@ - The path of a helm binary to use. required: false type: path + plain_http: + description: + - Use HTTP instead of HTTPS when working with OCI registries + - Requires Helm >= 3.13.0 + type: bool + default: False + version_added: 6.1.0 """ EXAMPLES = r""" @@ -201,6 +208,7 @@ def main(): chart_ssl_cert_file=dict(type="path"), chart_ssl_key_file=dict(type="path"), binary_path=dict(type="path"), + plain_http=dict(type="bool", default=False), ) module = AnsibleHelmModule( argument_spec=argspec, @@ -225,6 +233,7 @@ def main(): chart_ca_cert="3.1.0", chart_ssl_cert_file="3.1.0", chart_ssl_key_file="3.1.0", + plain_http="3.13.0", ) def test_version_requirement(opt): @@ -264,6 +273,7 @@ def test_version_requirement(opt): skip_tls_certs_check=dict(key="insecure-skip-tls-verify"), chart_devel=dict(key="devel"), untar_chart=dict(key="untar"), + plain_http=dict(key="plain-http"), ) for k, v in helm_flag_args.items(): diff --git a/plugins/modules/helm_template.py b/plugins/modules/helm_template.py index 16a1131ced..b0f0079e33 100644 --- a/plugins/modules/helm_template.py +++ b/plugins/modules/helm_template.py @@ -147,6 +147,13 @@ - json - file version_added: 2.4.0 + plain_http: + description: + - Use HTTP instead of HTTPS when working with OCI registries + - Requires Helm >= 3.13.0 + type: bool + default: False + version_added: 6.1.0 """ EXAMPLES = r""" @@ -218,6 +225,9 @@ from ansible_collections.kubernetes.core.plugins.module_utils.helm import ( AnsibleHelmModule, ) +from ansible_collections.kubernetes.core.plugins.module_utils.version import ( + LooseVersion, +) def template( @@ -236,6 +246,7 @@ def template( values_files=None, include_crds=False, set_values=None, + plain_http=False, ): cmd += " template " @@ -262,6 +273,9 @@ def template( if insecure_registry: cmd += " --insecure-skip-tls-verify" + if plain_http: + cmd += " --plain-http" + if show_only: for template in show_only: cmd += " -s " + template @@ -307,6 +321,7 @@ def main(): values_files=dict(type="list", default=[], elements="str"), update_repo_cache=dict(type="bool", default=False), set_values=dict(type="list", elements="dict"), + plain_http=dict(type="bool", default=False), ), supports_check_mode=True, ) @@ -327,12 +342,22 @@ def main(): values_files = module.params.get("values_files") update_repo_cache = module.params.get("update_repo_cache") set_values = module.params.get("set_values") + plain_http = module.params.get("plain_http") if not IMP_YAML: module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR) helm_cmd = module.get_helm_binary() + if plain_http: + helm_version = module.get_helm_version() + if LooseVersion(helm_version) < LooseVersion("3.13.0"): + module.fail_json( + msg="plain_http requires helm >= 3.13.0, current version is {0}".format( + helm_version + ) + ) + if update_repo_cache: update_cmd = helm_cmd + " repo update" module.run_helm_command(update_cmd) @@ -357,6 +382,7 @@ def main(): values_files=values_files, include_crds=include_crds, set_values=set_values_args, + plain_http=plain_http, ) if not check_mode: diff --git a/tests/integration/targets/helm_plain_http/aliases b/tests/integration/targets/helm_plain_http/aliases new file mode 100644 index 0000000000..069f055393 --- /dev/null +++ b/tests/integration/targets/helm_plain_http/aliases @@ -0,0 +1,3 @@ +helm_template +helm_pull +helm \ No newline at end of file diff --git a/tests/integration/targets/helm_plain_http/inventory.ini b/tests/integration/targets/helm_plain_http/inventory.ini new file mode 100644 index 0000000000..cdb5f7dc97 --- /dev/null +++ b/tests/integration/targets/helm_plain_http/inventory.ini @@ -0,0 +1,3 @@ +[all] +helm-3.12.3 helm_version=v3.12.3 test_namespace=helm-plain-http-v3-12-3 tests_should_failed=true +helm-3.18.2 helm_version=v3.18.2 test_namespace=helm-plain-http-v3-18-2 tests_should_failed=false \ No newline at end of file diff --git a/tests/integration/targets/helm_plain_http/playbooks/play.yaml b/tests/integration/targets/helm_plain_http/playbooks/play.yaml new file mode 100644 index 0000000000..4ef540b928 --- /dev/null +++ b/tests/integration/targets/helm_plain_http/playbooks/play.yaml @@ -0,0 +1,14 @@ +- name: Run test for helm plain http option + hosts: all + gather_facts: true + + vars: + ansible_connection: local + ansible_python_interpreter: "{{ ansible_playbook_python }}" + chart_test_oci: "oci://registry-1.docker.io/bitnamicharts/redis" + + roles: + - setup_namespace + + tasks: + - ansible.builtin.include_tasks: tasks/test.yaml diff --git a/tests/integration/targets/helm_plain_http/playbooks/tasks/test.yaml b/tests/integration/targets/helm_plain_http/playbooks/tasks/test.yaml new file mode 100644 index 0000000000..e9bd2a2f58 --- /dev/null +++ b/tests/integration/targets/helm_plain_http/playbooks/tasks/test.yaml @@ -0,0 +1,99 @@ +--- +- name: Run test for helm + block: + - name: Create temporary directory to install chart In + ansible.builtin.tempfile: + state: directory + suffix: .helm + register: install_path + + - name: Install required helm version + ansible.builtin.include_role: + name: install_helm + vars: + helm_install_path: "{{ install_path.path }}" + + - name: Set helm binary path + ansible.builtin.set_fact: + helm_binary: "{{ install_path.path }}/{{ ansible_system | lower }}-amd64/helm" + + # helm + - name: Run helm with plain_http + kubernetes.core.helm: + binary_path: "{{ helm_binary }}" + chart_ref: "{{ chart_test_oci }}" + release_name: test-secure + release_namespace: "{{ test_namespace }}" + create_namespace: true + plain_http: true + register: install_chart + ignore_errors: true + + - name: Ensure module failed as expected + ansible.builtin.assert: + that: + - install_chart is failed + - '"plain_http requires helm >= 3.13.0" in install_chart.msg' + when: tests_should_failed | bool + + - name: Ensure the result command contains the expected option + ansible.builtin.assert: + that: + - install_chart is not failed + - '"--plain-http" in install_chart.command' + when: not (tests_should_failed | bool) + + # helm_pull + - name: Trying to download helm chart with option plain_http + kubernetes.core.helm_pull: + chart_ref: "{{ chart_test_oci }}" + destination: "{{ playbook_dir }}" + binary_path: "{{ helm_binary }}" + plain_http: true + register: pull_chart + ignore_errors: true + + - name: Ensure module failed as expected + ansible.builtin.assert: + that: + - pull_chart is failed + - '"plain_http requires helm >= 3.13.0" in pull_chart.msg' + when: tests_should_failed | bool + + - name: Ensure the result command contains the expected option + ansible.builtin.assert: + that: + - pull_chart is not failed + - '"--plain-http" in pull_chart.command' + when: not (tests_should_failed | bool) + + # helm_template + - name: Test helm render template + kubernetes.core.helm_template: + binary_path: "{{ helm_binary }}" + chart_ref: "{{ chart_test_oci }}" + output_dir: "{{ playbook_dir }}" + plain_http: true + register: template + ignore_errors: true + + - name: Ensure module failed as expected + ansible.builtin.assert: + that: + - template is failed + - '"plain_http requires helm >= 3.13.0" in template.msg' + when: tests_should_failed | bool + + - name: Ensure the result command contains the expected option + ansible.builtin.assert: + that: + - template is not failed + - '"--plain-http" in template.command' + when: not (tests_should_failed | bool) + + always: + - name: Delete temporary file + ansible.builtin.file: + path: "{{ install_path.path }}" + state: absent + ignore_errors: true diff --git a/tests/integration/targets/helm_plain_http/runme.sh b/tests/integration/targets/helm_plain_http/runme.sh new file mode 100755 index 0000000000..3cfa5280ee --- /dev/null +++ b/tests/integration/targets/helm_plain_http/runme.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eux +export ANSIBLE_ROLES_PATH=../ +ansible-playbook playbooks/play.yaml -i inventory.ini "$@" \ No newline at end of file