Skip to content

Commit

Permalink
Merge pull request #440 from Mirantis/fix-templates-creation
Browse files Browse the repository at this point in the history
Create HelmRepository during the initial HMC installation
  • Loading branch information
Kshatrix authored Oct 7, 2024
2 parents 2d022ba + 38da748 commit 330b9bd
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 59 deletions.
23 changes: 16 additions & 7 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (

hmcmirantiscomv1alpha1 "github.com/Mirantis/hmc/api/v1alpha1"
"github.com/Mirantis/hmc/internal/controller"
"github.com/Mirantis/hmc/internal/helm"
"github.com/Mirantis/hmc/internal/telemetry"
"github.com/Mirantis/hmc/internal/utils"
hmcwebhook "github.com/Mirantis/hmc/internal/webhook"
Expand Down Expand Up @@ -183,13 +184,15 @@ func main() {
currentNamespace := utils.CurrentNamespace()

templateReconciler := controller.TemplateReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
SystemNamespace: currentNamespace,
DefaultRegistryURL: defaultRegistryURL,
DefaultRepoType: determinedRepositoryType,
RegistryCredentialsSecret: registryCredentialsSecret,
InsecureRegistry: insecureRegistry,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
SystemNamespace: currentNamespace,
DefaultRegistryConfig: helm.DefaultRegistryConfig{
URL: defaultRegistryURL,
RepoType: determinedRepositoryType,
CredentialsSecret: registryCredentialsSecret,
Insecure: insecureRegistry,
},
}

if err = (&controller.ClusterTemplateReconciler{
Expand Down Expand Up @@ -261,6 +264,12 @@ func main() {
CreateRelease: createRelease,
HMCTemplatesChartName: hmcTemplatesChartName,
SystemNamespace: currentNamespace,
DefaultRegistryConfig: helm.DefaultRegistryConfig{
URL: defaultRegistryURL,
RepoType: determinedRepositoryType,
CredentialsSecret: registryCredentialsSecret,
Insecure: insecureRegistry,
},
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Release")
os.Exit(1)
Expand Down
14 changes: 12 additions & 2 deletions internal/controller/release_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ type ReleaseReconciler struct {

HMCTemplatesChartName string
SystemNamespace string

DefaultRegistryConfig helm.DefaultRegistryConfig
}

func (r *ReleaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
Expand Down Expand Up @@ -150,8 +152,8 @@ func (r *ReleaseReconciler) ensureManagement(ctx context.Context) error {

func (r *ReleaseReconciler) reconcileHMCTemplates(ctx context.Context, req ctrl.Request) error {
l := ctrl.LoggerFrom(ctx)
if !r.CreateRelease {
l.Info("Reconciling HMC Templates is skipped")
if initialReconcile(req) && !r.CreateRelease {
l.Info("Initial creation of HMC Release is skipped")
return nil
}
name := utils.ReleaseNameFromVersion(build.Version)
Expand All @@ -175,6 +177,14 @@ func (r *ReleaseReconciler) reconcileHMCTemplates(ctx context.Context, req ctrl.
}
}

if initialReconcile(req) {
err := helm.ReconcileHelmRepository(ctx, r.Client, defaultRepoName, r.SystemNamespace, r.DefaultRegistryConfig.HelmRepositorySpec())
if err != nil {
l.Error(err, "Failed to reconcile default HelmRepository", "namespace", r.SystemNamespace)
return err
}
}

helmChart := &sourcev1.HelmChart{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Expand Down
56 changes: 6 additions & 50 deletions internal/controller/template_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"strings"

helmcontrollerv2 "github.com/fluxcd/helm-controller/api/v2"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
"helm.sh/helm/v3/pkg/chart"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
Expand All @@ -30,7 +29,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

hmc "github.com/Mirantis/hmc/api/v1alpha1"
"github.com/Mirantis/hmc/internal/helm"
Expand All @@ -46,14 +44,7 @@ type TemplateReconciler struct {
Scheme *runtime.Scheme
SystemNamespace string

// DefaultRepoType is the type specified by default in HelmRepository
// objects. Valid types are 'default' for http/https repositories, and
// 'oci' for OCI repositories. The RepositoryType is set in main based on
// the URI scheme of the DefaultRegistryURL.
DefaultRepoType string
DefaultRegistryURL string
RegistryCredentialsSecret string
InsecureRegistry bool
DefaultRegistryConfig helm.DefaultRegistryConfig

downloadHelmChartFunc func(context.Context, *sourcev1.Artifact) (*chart.Chart, error)
}
Expand Down Expand Up @@ -148,7 +139,11 @@ func (r *TemplateReconciler) ReconcileTemplate(ctx context.Context, template Tem
return ctrl.Result{}, err
}
if template.GetNamespace() == r.SystemNamespace || !templateManagedByHMC(template) {
err := r.reconcileDefaultHelmRepository(ctx, template.GetNamespace())
namespace := template.GetNamespace()
if namespace == "" {
namespace = r.SystemNamespace
}
err := helm.ReconcileHelmRepository(ctx, r.Client, defaultRepoName, namespace, r.DefaultRegistryConfig.HelmRepositorySpec())
if err != nil {
l.Error(err, "Failed to reconcile default HelmRepository", "namespace", template.GetNamespace())
return ctrl.Result{}, err
Expand Down Expand Up @@ -271,45 +266,6 @@ func (r *TemplateReconciler) updateStatus(ctx context.Context, template Template
return nil
}

func (r *TemplateReconciler) reconcileDefaultHelmRepository(ctx context.Context, namespace string) error {
l := ctrl.LoggerFrom(ctx)
if namespace == "" {
namespace = r.SystemNamespace
}
helmRepo := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
Name: defaultRepoName,
Namespace: namespace,
},
}
operation, err := ctrl.CreateOrUpdate(ctx, r.Client, helmRepo, func() error {
if helmRepo.Labels == nil {
helmRepo.Labels = make(map[string]string)
}

helmRepo.Labels[hmc.HMCManagedLabelKey] = hmc.HMCManagedLabelValue
helmRepo.Spec = sourcev1.HelmRepositorySpec{
Type: r.DefaultRepoType,
URL: r.DefaultRegistryURL,
Interval: metav1.Duration{Duration: helm.DefaultReconcileInterval},
Insecure: r.InsecureRegistry,
}
if r.RegistryCredentialsSecret != "" {
helmRepo.Spec.SecretRef = &meta.LocalObjectReference{
Name: r.RegistryCredentialsSecret,
}
}
return nil
})
if err != nil {
return err
}
if operation == controllerutil.OperationResultCreated || operation == controllerutil.OperationResultUpdated {
l.Info(fmt.Sprintf("Successfully %s %s/%s HelmRepository", operation, namespace, defaultRepoName))
}
return nil
}

func (r *TemplateReconciler) reconcileHelmChart(ctx context.Context, template Template) (*sourcev1.HelmChart, error) {
spec := template.GetSpec()
namespace := template.GetNamespace()
Expand Down
83 changes: 83 additions & 0 deletions internal/helm/repo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2024
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package helm

import (
"context"
"fmt"

"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

hmc "github.com/Mirantis/hmc/api/v1alpha1"
)

type DefaultRegistryConfig struct {
// RepoType is the type specified by default in HelmRepository
// objects. Valid types are 'default' for http/https repositories, and
// 'oci' for OCI repositories. The RepositoryType is set in main based on
// the URI scheme of the DefaultRegistryURL.
RepoType string
URL string
CredentialsSecret string
Insecure bool
}

func (r *DefaultRegistryConfig) HelmRepositorySpec() sourcev1.HelmRepositorySpec {
return sourcev1.HelmRepositorySpec{
Type: r.RepoType,
URL: r.URL,
Interval: metav1.Duration{Duration: DefaultReconcileInterval},
Insecure: r.Insecure,
SecretRef: func() *meta.LocalObjectReference {
if r.CredentialsSecret != "" {
return &meta.LocalObjectReference{
Name: r.CredentialsSecret,
}
}
return nil
}(),
}
}

func ReconcileHelmRepository(ctx context.Context, cl client.Client, name, namespace string, spec sourcev1.HelmRepositorySpec) error {
l := ctrl.LoggerFrom(ctx)
helmRepo := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
operation, err := ctrl.CreateOrUpdate(ctx, cl, helmRepo, func() error {
if helmRepo.Labels == nil {
helmRepo.Labels = make(map[string]string)
}

helmRepo.Labels[hmc.HMCManagedLabelKey] = hmc.HMCManagedLabelValue
helmRepo.Spec = spec
return nil
})
if err != nil {
return err
}
if operation == controllerutil.OperationResultCreated || operation == controllerutil.OperationResultUpdated {
l.Info(fmt.Sprintf("Successfully %s %s/%s HelmRepository", operation, namespace, name))
}
return nil
}

0 comments on commit 330b9bd

Please sign in to comment.