Skip to content

Commit 42f0ddd

Browse files
committed
fix(helm): add OCI registry client for chart operations
OCI-based Helm charts were failing to install because the action configuration lacked a registry client. This change: - Add GetDefaultOCIRegistry() to create and attach a registry client to the Helm action configuration - Integrate registry client initialization into all Helm handlers: install, upgrade, uninstall, rollback, and chart get operations - Add unit tests for the new registry client function Without a registry client, operations on OCI charts (oci://) would fail with errors about missing registry support. Fixes: HELM-611
1 parent 2db4d62 commit 42f0ddd

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

pkg/helm/actions/get_registry.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package actions
2+
3+
import (
4+
"fmt"
5+
6+
"helm.sh/helm/v3/pkg/action"
7+
"helm.sh/helm/v3/pkg/registry"
8+
)
9+
10+
func GetDefaultOCIRegistry(conf *action.Configuration) error {
11+
if conf == nil {
12+
return fmt.Errorf("action configuration cannot be nil")
13+
}
14+
registryclient, err := registry.NewClient(registry.ClientOptDebug(false))
15+
if err != nil {
16+
return fmt.Errorf("failed to create registry client: %w", err)
17+
}
18+
conf.RegistryClient = registryclient
19+
return nil
20+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package actions
2+
3+
import (
4+
"io"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
"helm.sh/helm/v3/pkg/action"
9+
"helm.sh/helm/v3/pkg/chartutil"
10+
kubefake "helm.sh/helm/v3/pkg/kube/fake"
11+
"helm.sh/helm/v3/pkg/storage"
12+
"helm.sh/helm/v3/pkg/storage/driver"
13+
)
14+
15+
func TestGetDefaultOCIRegistry_Success(t *testing.T) {
16+
store := storage.Init(driver.NewMemory())
17+
conf := &action.Configuration{
18+
RESTClientGetter: FakeConfig{},
19+
Releases: store,
20+
KubeClient: &kubefake.PrintingKubeClient{Out: io.Discard},
21+
Capabilities: chartutil.DefaultCapabilities,
22+
}
23+
require.Nil(t, conf.RegistryClient, "Registry Client should be nil")
24+
25+
// Store original values
26+
originalReleases := conf.Releases
27+
originalKubeClient := conf.KubeClient
28+
originalCapabilities := conf.Capabilities
29+
30+
err := GetDefaultOCIRegistry(conf)
31+
require.NoError(t, err)
32+
require.NotNil(t, conf.RegistryClient, "Registry Client should not be nil")
33+
34+
// Verify other configuration fields are not modified.
35+
require.Equal(t, originalReleases, conf.Releases, "Releases should not be modified")
36+
require.Equal(t, originalKubeClient, conf.KubeClient, "KubeClient should not be modified")
37+
require.Equal(t, originalCapabilities, conf.Capabilities, "Capabilities should not be modified")
38+
39+
}
40+
41+
func TestGetDefaultOCIRegistry_NilConfig(t *testing.T) {
42+
err := GetDefaultOCIRegistry(nil)
43+
require.Error(t, err)
44+
require.Contains(t, err.Error(), "action configuration cannot be nil")
45+
}
46+
47+
func TestGetDefaultOCIRegistry_MinimumConfig(t *testing.T) {
48+
conf := &action.Configuration{}
49+
err := GetDefaultOCIRegistry(conf)
50+
require.NoError(t, err)
51+
require.NotNil(t, conf.RegistryClient, "Registry Client should not be nil")
52+
}

pkg/helm/handlers/handlers.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ func New(apiUrl string, transport http.RoundTripper, kubeversionGetter version.K
3939
uninstallReleaseAsync: actions.UninstallReleaseAsync,
4040
rollbackRelease: actions.RollbackRelease,
4141
getReleaseHistory: actions.GetReleaseHistory,
42+
getDefaultOCIRegistry: actions.GetDefaultOCIRegistry,
4243
}
4344

4445
h.newProxy = func(bearerToken string) (getter chartproxy.Proxy, err error) {
@@ -72,6 +73,7 @@ type helmHandlers struct {
7273
getChart func(chartUrl string, conf *action.Configuration, namespace string, client dynamic.Interface, coreClient corev1client.CoreV1Interface, filesCleanup bool, indexEntry string) (*chart.Chart, error)
7374
getReleaseHistory func(releaseName string, conf *action.Configuration) ([]*release.Release, error)
7475
newProxy func(bearerToken string) (chartproxy.Proxy, error)
76+
getDefaultOCIRegistry func(*action.Configuration) error
7577
}
7678

7779
func (h *helmHandlers) restConfig(bearerToken string) *rest.Config {
@@ -127,6 +129,11 @@ func (h *helmHandlers) HandleHelmInstall(user *auth.User, w http.ResponseWriter,
127129
}
128130

129131
conf := h.getActionConfigurations(h.ApiServerHost, req.Namespace, user.Token, &h.Transport)
132+
err = h.getDefaultOCIRegistry(conf)
133+
if err != nil {
134+
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to get default registry: %v", err)})
135+
return
136+
}
130137
restConfig, err := conf.RESTClientGetter.ToRESTConfig()
131138
if err != nil {
132139
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to parse request: %v", err)})
@@ -163,6 +170,11 @@ func (h *helmHandlers) HandleHelmInstallAsync(user *auth.User, w http.ResponseWr
163170
}
164171

165172
conf := h.getActionConfigurations(h.ApiServerHost, req.Namespace, user.Token, &h.Transport)
173+
err = h.getDefaultOCIRegistry(conf)
174+
if err != nil {
175+
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to get default registry: %v", err)})
176+
return
177+
}
166178
restConfig, err := conf.RESTClientGetter.ToRESTConfig()
167179
if err != nil {
168180
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to parse request: %v", err)})
@@ -240,6 +252,11 @@ func (h *helmHandlers) HandleChartGet(user *auth.User, w http.ResponseWriter, r
240252
indexEntry := params.Get("indexEntry")
241253
// scope request to default namespace
242254
conf := h.getActionConfigurations(h.ApiServerHost, "default", user.Token, &h.Transport)
255+
err := h.getDefaultOCIRegistry(conf)
256+
if err != nil {
257+
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to get default registry: %v", err)})
258+
return
259+
}
243260
restConfig, err := conf.RESTClientGetter.ToRESTConfig()
244261
if err != nil {
245262
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to parse request: %v", err)})
@@ -277,6 +294,11 @@ func (h *helmHandlers) HandleUpgradeRelease(user *auth.User, w http.ResponseWrit
277294
}
278295

279296
conf := h.getActionConfigurations(h.ApiServerHost, req.Namespace, user.Token, &h.Transport)
297+
err = h.getDefaultOCIRegistry(conf)
298+
if err != nil {
299+
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to get default registry: %v", err)})
300+
return
301+
}
280302
restConfig, err := conf.RESTClientGetter.ToRESTConfig()
281303
if err != nil {
282304
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to parse request: %v", err)})
@@ -313,6 +335,11 @@ func (h *helmHandlers) HandleUpgradeReleaseAsync(user *auth.User, w http.Respons
313335
}
314336

315337
conf := h.getActionConfigurations(h.ApiServerHost, req.Namespace, user.Token, &h.Transport)
338+
err = h.getDefaultOCIRegistry(conf)
339+
if err != nil {
340+
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to get default registry: %v", err)})
341+
return
342+
}
316343
restConfig, err := conf.RESTClientGetter.ToRESTConfig()
317344
if err != nil {
318345
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to parse request: %v", err)})
@@ -366,6 +393,11 @@ func (h *helmHandlers) HandleRollbackRelease(user *auth.User, w http.ResponseWri
366393
}
367394

368395
conf := h.getActionConfigurations(h.ApiServerHost, req.Namespace, user.Token, &h.Transport)
396+
err = h.getDefaultOCIRegistry(conf)
397+
if err != nil {
398+
serverutils.SendResponse(w, http.StatusBadGateway, serverutils.ApiError{Err: fmt.Sprintf("Failed to get default registry: %v", err)})
399+
return
400+
}
369401
rel, err := h.rollbackRelease(req.Name, req.Version, conf)
370402
if err != nil {
371403
if err.Error() == actions.ErrReleaseRevisionNotFound.Error() {

0 commit comments

Comments
 (0)