Skip to content

Commit

Permalink
support plain HTTP OCI registries in HelmRepositories
Browse files Browse the repository at this point in the history
The new field `.spec.insecure` in the HelmRepository CRD signals to
the controllers that the registry is served via HTTP and not HTTPS.

Signed-off-by: Max Jonas Werner <[email protected]>
  • Loading branch information
makkes committed Jul 13, 2022
1 parent 22c9e2e commit de9c285
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 6 deletions.
4 changes: 4 additions & 0 deletions api/v1beta2/helmrepository_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ type HelmRepositorySpec struct {
// +kubebuilder:validation:Enum=default;oci
// +optional
Type string `json:"type,omitempty"`

// Insecure allows connecting to a non-TLS/plain HTTP OCI endpoint.
// +optional
Insecure bool `json:"insecure,omitempty"`
}

// HelmRepositoryStatus records the observed state of the HelmRepository.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,10 @@ spec:
required:
- namespaceSelectors
type: object
insecure:
description: Insecure allows connecting to a non-TLS/plain HTTP OCI
endpoint.
type: boolean
interval:
description: Interval at which to check the URL for updates.
type: string
Expand Down
8 changes: 6 additions & 2 deletions controllers/helmchart_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,10 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
loginOpts = append([]helmreg.LoginOption{}, loginOpt)
}

if repo.Spec.Insecure {
loginOpts = append(loginOpts, helmreg.LoginOptInsecure(true))
}

// Initialize the chart repository
var chartRepo repository.Downloader
switch repo.Spec.Type {
Expand All @@ -532,7 +536,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
// this is needed because otherwise the credentials are stored in ~/.docker/config.json.
// TODO@souleb: remove this once the registry move to Oras v2
// or rework to enable reusing credentials to avoid the unneccessary handshake operations
registryClient, credentialsFile, err := r.RegistryClientGenerator(loginOpts != nil)
registryClient, credentialsFile, err := r.RegistryClientGenerator(loginOpts != nil, repo.Spec.Insecure)
if err != nil {
e := &serror.Event{
Err: fmt.Errorf("failed to construct Helm client: %w", err),
Expand Down Expand Up @@ -976,7 +980,7 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont

var chartRepo repository.Downloader
if helmreg.IsOCI(normalizedURL) {
registryClient, credentialsFile, err := r.RegistryClientGenerator(loginOpts != nil)
registryClient, credentialsFile, err := r.RegistryClientGenerator(loginOpts != nil, repo.Spec.Insecure)
if err != nil {
return nil, fmt.Errorf("failed to create registry client for HelmRepository '%s': %w", repo.Name, err)
}
Expand Down
8 changes: 6 additions & 2 deletions controllers/helmrepository_controller_oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type HelmRepositoryOCIReconciler struct {
// and an optional file name.
// The file is used to store the registry client credentials.
// The caller is responsible for deleting the file.
type RegistryClientGeneratorFunc func(isLogin bool) (*helmreg.Client, string, error)
type RegistryClientGeneratorFunc func(isLogin, plainHTTP bool) (*helmreg.Client, string, error)

func (r *HelmRepositoryOCIReconciler) SetupWithManager(mgr ctrl.Manager) error {
return r.SetupWithManagerAndOptions(mgr, HelmRepositoryReconcilerOptions{})
Expand Down Expand Up @@ -295,8 +295,12 @@ func (r *HelmRepositoryOCIReconciler) reconcile(ctx context.Context, obj *v1beta
}
}

if obj.Spec.Insecure {
loginOpts = append(loginOpts, helmreg.LoginOptInsecure(true))
}

// Create registry client and login if needed.
registryClient, file, err := r.RegistryClientGenerator(loginOpts != nil)
registryClient, file, err := r.RegistryClientGenerator(loginOpts != nil, obj.Spec.Insecure)
if err != nil {
e := fmt.Errorf("failed to create registry client: %w", err)
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, e.Error())
Expand Down
11 changes: 9 additions & 2 deletions internal/helm/registry/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
// ClientGenerator generates a registry client and a temporary credential file.
// The client is meant to be used for a single reconciliation.
// The file is meant to be used for a single reconciliation and deleted after.
func ClientGenerator(isLogin bool) (*registry.Client, string, error) {
func ClientGenerator(isLogin, plainHTTP bool) (*registry.Client, string, error) {
if isLogin {
// create a temporary file to store the credentials
// this is needed because otherwise the credentials are stored in ~/.docker/config.json.
Expand All @@ -37,7 +37,14 @@ func ClientGenerator(isLogin bool) (*registry.Client, string, error) {
}

var errs []error
rClient, err := registry.NewClient(registry.ClientOptWriter(io.Discard), registry.ClientOptCredentialsFile(credentialsFile.Name()))
opts := []registry.ClientOption{
registry.ClientOptWriter(io.Discard),
registry.ClientOptCredentialsFile(credentialsFile.Name()),
}
if plainHTTP {
opts = append(opts, registry.ClientOptPlainHTTP())
}
rClient, err := registry.NewClient(opts...)
if err != nil {
errs = append(errs, err)
// attempt to delete the temporary file
Expand Down

0 comments on commit de9c285

Please sign in to comment.