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