From a8753953e4f364cbd6f2da8ac71f7d3e95745764 Mon Sep 17 00:00:00 2001
From: Edmund Ochieng <ochienged@gmail.com>
Date: Thu, 20 Mar 2025 12:02:57 -0500
Subject: [PATCH 1/2] check if helm chart is served by registry/v1 bundle

---
 internal/shared/util/helm/chart.go      | 95 ++++++++++++++++++++++++
 internal/shared/util/helm/chart_test.go | 96 +++++++++++++++++++++++++
 2 files changed, 191 insertions(+)
 create mode 100644 internal/shared/util/helm/chart.go
 create mode 100644 internal/shared/util/helm/chart_test.go

diff --git a/internal/shared/util/helm/chart.go b/internal/shared/util/helm/chart.go
new file mode 100644
index 000000000..41c1e441a
--- /dev/null
+++ b/internal/shared/util/helm/chart.go
@@ -0,0 +1,95 @@
+package helm
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"regexp"
+	"slices"
+	"strings"
+
+	"helm.sh/helm/v3/pkg/chart"
+	"helm.sh/helm/v3/pkg/chart/loader"
+	"helm.sh/helm/v3/pkg/registry"
+)
+
+func IsChart(ctx context.Context, chartUri string) (chart, oci bool, err error) {
+	addr, err := url.Parse(chartUri)
+	if err != nil {
+		return chart, oci, err
+	}
+
+	if addr.Scheme != "" {
+		if !strings.HasPrefix(addr.Scheme, "http") {
+			err = fmt.Errorf("unexpected Url scheme; %s\n", addr.Scheme)
+			return
+		}
+
+		oci = false
+		helmchart, err := validateHelmChart(addr.String())
+		if err != nil {
+			chart = false
+			return chart, oci, err
+		}
+
+		if helmchart != nil &&
+			helmchart.Metadata != nil &&
+			helmchart.Metadata.Name != "" {
+			chart = true
+		}
+
+		return chart, oci, err
+	}
+
+	ociRe := regexp.MustCompile("^(?P<host>[a-zA-Z0-9-_.:]+)([/]?)(?P<org>[a-zA-Z0-9-_/]+)?([/](?P<chart>[a-zA-Z0-9-_.:@]+))$")
+	if ociRe.MatchString(chartUri) {
+		oci = true
+
+		chart, err = helmOciCheck(ctx, chartUri)
+		if err != nil {
+			return chart, oci, err
+		}
+	}
+
+	return
+}
+
+// helmOciCheck() pull a helm chart using the provided chartUri from an
+// OCI registiry and inspects its media type to determine if a Helm chart
+func helmOciCheck(ctx context.Context, chartUri string) (bool, error) {
+	helmclient, err := registry.NewClient()
+	if err != nil {
+		return false, err
+	}
+
+	summary, err := helmclient.Pull(chartUri,
+		registry.PullOptWithProv(false),
+		registry.PullOptWithChart(true),
+		registry.PullOptIgnoreMissingProv(true),
+	)
+	if err != nil {
+		return false, err
+	}
+
+	return summary != nil && summary.Ref != "", nil
+}
+
+func validateHelmChart(chartUri string) (*chart.Chart, error) {
+	// Download helm chart from HTTP
+	resp, err := http.Get(chartUri)
+	if err != nil {
+		return nil, fmt.Errorf("loading URL failed; %w", err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("unexpected response; %w", err)
+	}
+
+	if !slices.Contains(resp.Header["Content-Type"], "application/octet-stream") {
+		return nil, fmt.Errorf("unknown contype-type")
+	}
+
+	return loader.LoadArchive(resp.Body)
+}
diff --git a/internal/shared/util/helm/chart_test.go b/internal/shared/util/helm/chart_test.go
new file mode 100644
index 000000000..ad2e84c2c
--- /dev/null
+++ b/internal/shared/util/helm/chart_test.go
@@ -0,0 +1,96 @@
+package helm_test
+
+import (
+	"context"
+	"testing"
+
+	helmutils "github.com/operator-framework/operator-controller/internal/shared/util/helm"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestIsChart(t *testing.T) {
+	type response struct {
+		Oci   bool
+		Chart bool
+	}
+
+	tt := []struct {
+		name    string
+		url     string
+		want    response
+		wantErr bool
+	}{
+		{
+			name: "pull helm chart using image tag",
+			url:  "quay.io/eochieng/metrics-server:3.12.0",
+			want: response{
+				Oci:   true,
+				Chart: true,
+			},
+			wantErr: false,
+		},
+		{
+			name: "pull helm chart using image digest",
+			url:  "quay.io/eochieng/metrics-server@sha256:dd56f2ccc6e29ba7a2c5492e12c8210fb7367771eca93380a8dd64a6c9c985cb",
+			want: response{
+				Oci:   true,
+				Chart: true,
+			},
+			wantErr: false,
+		},
+		{
+			name: "pull helm chart from HTTP repository",
+			url:  "https://github.com/kubernetes-sigs/metrics-server/releases/download/metrics-server-helm-chart-3.12.0/metrics-server-3.12.0.tgz",
+			want: response{
+				Oci:   false,
+				Chart: true,
+			},
+			wantErr: false,
+		},
+		{
+			name: "pull helm chart with oci scheme",
+			url:  "oci://quay.io/eochieng/metrics-server@sha256:dd56f2ccc6e29ba7a2c5492e12c8210fb7367771eca93380a8dd64a6c9c985cb",
+			want: response{
+				Oci:   false,
+				Chart: false,
+			},
+			wantErr: true,
+		},
+		{
+			name: "pull kubernetes web page",
+			url:  "https://kubernetes.io",
+			want: response{
+				Oci:   false,
+				Chart: false,
+			},
+			wantErr: true,
+		},
+		{
+			name: "pull busybox image from OCI registry",
+			url:  "quay.io/opdev/busybox:latest",
+			want: response{
+				Oci:   true,
+				Chart: false,
+			},
+			wantErr: true,
+		},
+	}
+
+	for _, tc := range tt {
+		t.Run(tc.name, func(t *testing.T) {
+			chart, oci, err := helmutils.IsChart(context.Background(), tc.url)
+			assert.Equal(t, oci, tc.want.Oci)
+			assert.Equal(t, chart, tc.want.Chart)
+
+			if testing.Verbose() {
+				t.Logf("IsChart() is verifying if %s is a helm chart.\n The result should be %t but, got %t\n", tc.url, chart, tc.want.Chart)
+			}
+
+			if !tc.wantErr {
+				assert.NoError(t, err)
+			} else {
+				assert.Error(t, err, "helm chart not found")
+			}
+		})
+	}
+}

From 97c7e46afb94d440fd82b28791bcfb31667de0df Mon Sep 17 00:00:00 2001
From: Edmund Ochieng <ochienged@gmail.com>
Date: Mon, 24 Mar 2025 12:36:08 -0500
Subject: [PATCH 2/2] Fix golang ci linting issues

Signed-off-by: Edmund Ochieng <ochienged@gmail.com>
---
 internal/shared/util/helm/chart.go      | 66 ++++++++++++++++---------
 internal/shared/util/helm/chart_test.go | 11 +++--
 2 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/internal/shared/util/helm/chart.go b/internal/shared/util/helm/chart.go
index 41c1e441a..1bb5be48a 100644
--- a/internal/shared/util/helm/chart.go
+++ b/internal/shared/util/helm/chart.go
@@ -14,56 +14,71 @@ import (
 	"helm.sh/helm/v3/pkg/registry"
 )
 
-func IsChart(ctx context.Context, chartUri string) (chart, oci bool, err error) {
-	addr, err := url.Parse(chartUri)
+type HelmCheckResponse struct {
+	// Chart returns true if helm chart
+	Chart bool
+	// Oci returns true if resource is stored
+	// in an OCI registry
+	Oci bool
+}
+
+func IsChart(ctx context.Context, chartURI string) (HelmCheckResponse, error) {
+	addr, err := url.Parse(chartURI)
 	if err != nil {
-		return chart, oci, err
+		return HelmCheckResponse{}, err
 	}
 
 	if addr.Scheme != "" {
 		if !strings.HasPrefix(addr.Scheme, "http") {
-			err = fmt.Errorf("unexpected Url scheme; %s\n", addr.Scheme)
-			return
+			return HelmCheckResponse{}, fmt.Errorf("unexpected scheme; %s", addr.Scheme)
 		}
 
-		oci = false
 		helmchart, err := validateHelmChart(addr.String())
 		if err != nil {
-			chart = false
-			return chart, oci, err
+			return HelmCheckResponse{}, err
 		}
 
 		if helmchart != nil &&
 			helmchart.Metadata != nil &&
 			helmchart.Metadata.Name != "" {
-			chart = true
+			return HelmCheckResponse{
+				Chart: true,
+				Oci:   false,
+			}, err
 		}
-
-		return chart, oci, err
 	}
 
 	ociRe := regexp.MustCompile("^(?P<host>[a-zA-Z0-9-_.:]+)([/]?)(?P<org>[a-zA-Z0-9-_/]+)?([/](?P<chart>[a-zA-Z0-9-_.:@]+))$")
-	if ociRe.MatchString(chartUri) {
-		oci = true
+	if !ociRe.MatchString(chartURI) {
+		return HelmCheckResponse{
+			Chart: false,
+			Oci:   false,
+		}, fmt.Errorf("does not conform to OCI url format")
+	}
 
-		chart, err = helmOciCheck(ctx, chartUri)
-		if err != nil {
-			return chart, oci, err
-		}
+	ociCheck, err := helmOciCheck(ctx, chartURI)
+	if err != nil {
+		return HelmCheckResponse{
+			Chart: false,
+			Oci:   true,
+		}, err
 	}
 
-	return
+	return HelmCheckResponse{
+		Chart: ociCheck,
+		Oci:   true,
+	}, nil
 }
 
-// helmOciCheck() pull a helm chart using the provided chartUri from an
+// helmOciCheck() pull a helm chart using the provided chartURI from an
 // OCI registiry and inspects its media type to determine if a Helm chart
-func helmOciCheck(ctx context.Context, chartUri string) (bool, error) {
+func helmOciCheck(_ context.Context, chartURI string) (bool, error) {
 	helmclient, err := registry.NewClient()
 	if err != nil {
 		return false, err
 	}
 
-	summary, err := helmclient.Pull(chartUri,
+	summary, err := helmclient.Pull(chartURI,
 		registry.PullOptWithProv(false),
 		registry.PullOptWithChart(true),
 		registry.PullOptIgnoreMissingProv(true),
@@ -75,9 +90,14 @@ func helmOciCheck(ctx context.Context, chartUri string) (bool, error) {
 	return summary != nil && summary.Ref != "", nil
 }
 
-func validateHelmChart(chartUri string) (*chart.Chart, error) {
+func validateHelmChart(chartURI string) (*chart.Chart, error) {
 	// Download helm chart from HTTP
-	resp, err := http.Get(chartUri)
+	req, err := http.NewRequest(http.MethodGet, chartURI, nil)
+	if err != nil {
+		return nil, fmt.Errorf("creating request failed; %w", err)
+	}
+
+	resp, err := http.DefaultClient.Do(req)
 	if err != nil {
 		return nil, fmt.Errorf("loading URL failed; %w", err)
 	}
diff --git a/internal/shared/util/helm/chart_test.go b/internal/shared/util/helm/chart_test.go
index ad2e84c2c..2e6501557 100644
--- a/internal/shared/util/helm/chart_test.go
+++ b/internal/shared/util/helm/chart_test.go
@@ -4,8 +4,9 @@ import (
 	"context"
 	"testing"
 
-	helmutils "github.com/operator-framework/operator-controller/internal/shared/util/helm"
 	"github.com/stretchr/testify/assert"
+
+	helmutils "github.com/operator-framework/operator-controller/internal/shared/util/helm"
 )
 
 func TestIsChart(t *testing.T) {
@@ -78,12 +79,12 @@ func TestIsChart(t *testing.T) {
 
 	for _, tc := range tt {
 		t.Run(tc.name, func(t *testing.T) {
-			chart, oci, err := helmutils.IsChart(context.Background(), tc.url)
-			assert.Equal(t, oci, tc.want.Oci)
-			assert.Equal(t, chart, tc.want.Chart)
+			response, err := helmutils.IsChart(context.Background(), tc.url)
+			assert.Equal(t, response.Oci, tc.want.Oci)
+			assert.Equal(t, response.Chart, tc.want.Chart)
 
 			if testing.Verbose() {
-				t.Logf("IsChart() is verifying if %s is a helm chart.\n The result should be %t but, got %t\n", tc.url, chart, tc.want.Chart)
+				t.Logf("IsChart() is checking if %s is a helm chart.\n", tc.url)
 			}
 
 			if !tc.wantErr {