1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

feat(oci): oci helm support [r8s-361] (#787)

This commit is contained in:
Ali 2025-07-13 10:37:43 +12:00 committed by GitHub
parent b6a6ce9aaf
commit 2697d6c5d7
80 changed files with 4264 additions and 812 deletions

View file

@ -0,0 +1,38 @@
package options
import (
"strings"
)
const (
// OCIProtocolPrefix is the standard OCI protocol prefix
OCIProtocolPrefix = "oci://"
)
// ConstructChartReference constructs the appropriate chart reference based on registry type
func ConstructChartReference(registryURL string, chartName string) string {
if registryURL == "" {
return chartName
}
// Don't double-prefix if chart already contains the registry URL
if strings.HasPrefix(chartName, OCIProtocolPrefix) {
return chartName
}
baseURL := ConstructOCIRegistryReference(registryURL)
// Handle cases where chartName might already have a path separator
if strings.HasPrefix(chartName, "/") {
return baseURL + chartName
}
return baseURL + "/" + chartName
}
func ConstructOCIRegistryReference(registryURL string) string {
// Remove oci:// prefix if present to avoid duplication
registryURL = strings.TrimPrefix(registryURL, OCIProtocolPrefix)
// Ensure we have oci:// prefix for OCI registries
return OCIProtocolPrefix + registryURL
}

View file

@ -0,0 +1,100 @@
package options
import (
"testing"
)
func TestConstructChartReference(t *testing.T) {
tests := []struct {
name string
registryURL string
chartName string
expected string
}{
{
name: "empty registry URL returns chart name as-is",
registryURL: "",
chartName: "nginx",
expected: "nginx",
},
{
name: "basic OCI registry with chart name",
registryURL: "registry.example.com",
chartName: "nginx",
expected: "oci://registry.example.com/nginx",
},
{
name: "registry with project path",
registryURL: "harbor.example.com",
chartName: "library/nginx",
expected: "oci://harbor.example.com/library/nginx",
},
{
name: "chart name already has oci prefix returns as-is",
registryURL: "registry.example.com",
chartName: "oci://registry.example.com/nginx",
expected: "oci://registry.example.com/nginx",
},
{
name: "chart name with leading slash",
registryURL: "registry.example.com",
chartName: "/nginx",
expected: "oci://registry.example.com/nginx",
},
{
name: "registry URL already has oci prefix",
registryURL: "oci://registry.example.com",
chartName: "nginx",
expected: "oci://registry.example.com/nginx",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ConstructChartReference(tt.registryURL, tt.chartName)
if result != tt.expected {
t.Errorf("ConstructChartReference(%q, %q) = %q, want %q",
tt.registryURL, tt.chartName, result, tt.expected)
}
})
}
}
func TestConstructOCIRegistryReference(t *testing.T) {
tests := []struct {
name string
registryURL string
expected string
}{
{
name: "simple registry URL",
registryURL: "registry.example.com",
expected: "oci://registry.example.com",
},
{
name: "registry URL with oci prefix",
registryURL: "oci://registry.example.com",
expected: "oci://registry.example.com",
},
{
name: "registry URL with port",
registryURL: "registry.example.com:5000",
expected: "oci://registry.example.com:5000",
},
{
name: "empty registry URL",
registryURL: "",
expected: "oci://",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ConstructOCIRegistryReference(tt.registryURL)
if result != tt.expected {
t.Errorf("ConstructOCIRegistryReference(%q) = %q, want %q",
tt.registryURL, result, tt.expected)
}
})
}
}

View file

@ -1,6 +1,10 @@
package options
import "time"
import (
"time"
portainer "github.com/portainer/portainer/api"
)
type InstallOptions struct {
Name string
@ -8,6 +12,7 @@ type InstallOptions struct {
Version string
Namespace string
Repo string
Registry *portainer.Registry
Wait bool
ValuesFile string
PostRenderer string

View file

@ -1,10 +1,15 @@
package options
import "net/http"
import (
"net/http"
portainer "github.com/portainer/portainer/api"
)
type SearchRepoOptions struct {
Repo string `example:"https://charts.gitlab.io/"`
Client *http.Client `example:"&http.Client{Timeout: time.Second * 10}"`
Chart string `example:"my-chart"`
UseCache bool `example:"false"`
Registry *portainer.Registry
}

View file

@ -1,5 +1,7 @@
package options
import portainer "github.com/portainer/portainer/api"
// ShowOutputFormat is the format of the output of `helm show`
type ShowOutputFormat string
@ -20,6 +22,6 @@ type ShowOptions struct {
Chart string
Repo string
Version string
Env []string
Env []string
Registry *portainer.Registry // Registry credentials for authentication
}