Skip to content

Commit

Permalink
Move TemplateManagement reconcile to Management controller
Browse files Browse the repository at this point in the history
Signed-off-by: Andrei Pavlov <[email protected]>
  • Loading branch information
Kshatrix committed Oct 2, 2024
1 parent 796e8eb commit 7694a19
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 110 deletions.
22 changes: 11 additions & 11 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,11 @@ func main() {
os.Exit(1)
}
if err = (&controller.ManagementReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Config: mgr.GetConfig(),
SystemNamespace: currentNamespace,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Config: mgr.GetConfig(),
SystemNamespace: currentNamespace,
CreateTemplateManagement: createTemplateManagement,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Management")
os.Exit(1)
Expand Down Expand Up @@ -254,13 +255,12 @@ func main() {
}

if err = (&controller.ReleaseReconciler{
Client: mgr.GetClient(),
Config: mgr.GetConfig(),
CreateManagement: createManagement,
CreateTemplateManagement: createTemplateManagement,
CreateTemplates: createTemplates,
HMCTemplatesChartName: hmcTemplatesChartName,
SystemNamespace: currentNamespace,
Client: mgr.GetClient(),
Config: mgr.GetConfig(),
CreateManagement: createManagement,
CreateTemplates: createTemplates,
HMCTemplatesChartName: hmcTemplatesChartName,
SystemNamespace: currentNamespace,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Release")
os.Exit(1)
Expand Down
52 changes: 48 additions & 4 deletions internal/controller/management_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
sourcev1 "github.com/fluxcd/source-controller/api/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
Expand All @@ -41,9 +42,10 @@ import (
// ManagementReconciler reconciles a Management object
type ManagementReconciler struct {
client.Client
Scheme *runtime.Scheme
Config *rest.Config
SystemNamespace string
Scheme *runtime.Scheme
Config *rest.Config
SystemNamespace string
CreateTemplateManagement bool
}

func (r *ManagementReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
Expand Down Expand Up @@ -75,11 +77,17 @@ func (r *ManagementReconciler) Update(ctx context.Context, management *hmc.Manag
finalizersUpdated := controllerutil.AddFinalizer(management, hmc.ManagementFinalizer)
if finalizersUpdated {
if err := r.Client.Update(ctx, management); err != nil {
return ctrl.Result{}, fmt.Errorf("failed to update Management %s: %w", management.Name, err)
l.Error(err, "Failed to update Management finalizers")
return ctrl.Result{}, err
}
return ctrl.Result{}, nil
}

if err := r.ensureTemplateManagement(ctx, management); err != nil {
l.Error(err, "Failed to ensure TemplateManagement is created")
return ctrl.Result{}, err
}

release := &hmc.Release{}
if err := r.Client.Get(ctx, client.ObjectKey{Name: management.Spec.Release}, release); err != nil {
l.Error(err, "failed to get Release object")
Expand Down Expand Up @@ -145,6 +153,42 @@ func (r *ManagementReconciler) Update(ctx context.Context, management *hmc.Manag
return ctrl.Result{}, nil
}

func (r *ManagementReconciler) ensureTemplateManagement(ctx context.Context, mgmt *hmc.Management) error {
l := ctrl.LoggerFrom(ctx)
if !r.CreateTemplateManagement {
return nil
}
l.Info("Ensuring TemplateManagement is created")
tmObj := &hmc.TemplateManagement{
ObjectMeta: metav1.ObjectMeta{
Name: hmc.TemplateManagementName,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: hmc.GroupVersion.String(),
Kind: mgmt.Kind,
Name: mgmt.Name,
UID: mgmt.UID,
},
},
},
}
err := r.Get(ctx, client.ObjectKey{
Name: hmc.TemplateManagementName,
}, tmObj)
if err == nil {
return nil
}
if !apierrors.IsNotFound(err) {
return fmt.Errorf("failed to get %s TemplateManagement object: %w", hmc.TemplateManagementName, err)
}
err = r.Create(ctx, tmObj)
if err != nil {
return fmt.Errorf("failed to create %s TemplateManagement object: %w", hmc.TemplateManagementName, err)
}
l.Info("Successfully created TemplateManagement object")
return nil
}

func (r *ManagementReconciler) Delete(ctx context.Context, management *hmc.Management) (ctrl.Result, error) {
l := ctrl.LoggerFrom(ctx)
listOpts := &client.ListOptions{
Expand Down
146 changes: 51 additions & 95 deletions internal/controller/release_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ type ReleaseReconciler struct {

Config *rest.Config

CreateManagement bool
CreateTemplateManagement bool
CreateTemplates bool
CreateManagement bool
CreateTemplates bool

HMCTemplatesChartName string
SystemNamespace string
Expand All @@ -71,16 +70,10 @@ func (r *ReleaseReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
}

if initialReconcile(req) {
mgmt, err := r.getOrCreateManagement(ctx)
if err != nil {
if err := r.ensureManagement(ctx); err != nil {
l.Error(err, "failed to get or create Management object")
return ctrl.Result{}, err
}
err = r.ensureTemplateManagement(ctx, mgmt)
if err != nil {
l.Error(err, "failed to ensure default TemplateManagement object")
return ctrl.Result{}, err
}
}
return ctrl.Result{}, nil
}
Expand All @@ -89,8 +82,12 @@ func initialReconcile(req ctrl.Request) bool {
return req.Name == ""
}

func (r *ReleaseReconciler) getOrCreateManagement(ctx context.Context) (*hmc.Management, error) {
func (r *ReleaseReconciler) ensureManagement(ctx context.Context) error {
l := ctrl.LoggerFrom(ctx)
if !r.CreateManagement {
return nil
}
l.Info("Ensuring Management is created")
mgmtObj := &hmc.Management{
ObjectMeta: metav1.ObjectMeta{
Name: hmc.ManagementName,
Expand All @@ -100,102 +97,61 @@ func (r *ReleaseReconciler) getOrCreateManagement(ctx context.Context) (*hmc.Man
err := r.Get(ctx, client.ObjectKey{
Name: hmc.ManagementName,
}, mgmtObj)
if err == nil {
return nil
}
if !apierrors.IsNotFound(err) {
return fmt.Errorf("failed to get %s Management object: %w", hmc.TemplateManagementName, err)
}
mgmtObj.Spec.Release, err = r.getCurrentReleaseName(ctx)
if err != nil {
if !apierrors.IsNotFound(err) {
return nil, fmt.Errorf("failed to get %s Management object: %w", hmc.ManagementName, err)
}
if !r.CreateManagement {
return nil, nil
}
mgmtObj.Spec.Release, err = r.getCurrentReleaseName(ctx)
if err != nil {
return nil, err
}

if err := mgmtObj.Spec.SetProvidersDefaults(); err != nil {
return nil, err
}

getter := helm.NewMemoryRESTClientGetter(r.Config, r.RESTMapper())
actionConfig := new(action.Configuration)
err = actionConfig.Init(getter, r.SystemNamespace, "secret", l.Info)
if err != nil {
return nil, err
}

hmcConfig := make(chartutil.Values)
release, err := actionConfig.Releases.Last("hmc")
if err != nil {
if !errors.Is(err, driver.ErrReleaseNotFound) {
return nil, err
}
} else {
if len(release.Config) > 0 {
chartutil.CoalesceTables(hmcConfig, release.Config)
}
}
return err
}
if err := mgmtObj.Spec.SetProvidersDefaults(); err != nil {
return err
}
getter := helm.NewMemoryRESTClientGetter(r.Config, r.RESTMapper())
actionConfig := new(action.Configuration)
err = actionConfig.Init(getter, r.SystemNamespace, "secret", l.Info)
if err != nil {
return err
}

// Initially set createManagement:false to automatically create Management object only once
chartutil.CoalesceTables(hmcConfig, map[string]any{
"controller": map[string]any{
"createManagement": false,
},
})
rawConfig, err := json.Marshal(hmcConfig)
if err != nil {
return nil, err
}
mgmtObj.Spec.Core = &hmc.Core{
HMC: hmc.Component{
Config: &apiextensionsv1.JSON{
Raw: rawConfig,
},
},
hmcConfig := make(chartutil.Values)
release, err := actionConfig.Releases.Last("hmc")
if err != nil {
if !errors.Is(err, driver.ErrReleaseNotFound) {
return err
}

err = r.Create(ctx, mgmtObj)
if err != nil {
return nil, fmt.Errorf("failed to create %s Management object: %s", hmc.ManagementName, err)
} else {
if len(release.Config) > 0 {
chartutil.CoalesceTables(hmcConfig, release.Config)
}
l.Info("Successfully created Management object with default configuration")
}
return mgmtObj, nil
}

func (r *ReleaseReconciler) ensureTemplateManagement(ctx context.Context, mgmt *hmc.Management) error {
l := ctrl.LoggerFrom(ctx)
if !r.CreateTemplateManagement {
return nil
}
if mgmt == nil {
return fmt.Errorf("management object is not found")
// Initially set createManagement:false to automatically create Management object only once
chartutil.CoalesceTables(hmcConfig, map[string]any{
"controller": map[string]any{
"createManagement": false,
},
})
rawConfig, err := json.Marshal(hmcConfig)
if err != nil {
return err
}
tmObj := &hmc.TemplateManagement{
ObjectMeta: metav1.ObjectMeta{
Name: hmc.TemplateManagementName,
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: hmc.GroupVersion.String(),
Kind: mgmt.Kind,
Name: mgmt.Name,
UID: mgmt.UID,
},
mgmtObj.Spec.Core = &hmc.Core{
HMC: hmc.Component{
Config: &apiextensionsv1.JSON{
Raw: rawConfig,
},
},
}
err := r.Get(ctx, client.ObjectKey{
Name: hmc.TemplateManagementName,
}, tmObj)
err = r.Create(ctx, mgmtObj)
if err != nil {
if !apierrors.IsNotFound(err) {
return fmt.Errorf("failed to get %s TemplateManagement object: %w", hmc.TemplateManagementName, err)
}
err = r.Create(ctx, tmObj)
if err != nil {
return fmt.Errorf("failed to create %s TemplateManagement object: %w", hmc.TemplateManagementName, err)
}
l.Info("Successfully created TemplateManagement object")
return fmt.Errorf("failed to create %s Management object: %w", hmc.TemplateManagementName, err)
}

l.Info("Successfully created Management object with default configuration")
return nil
}

Expand Down

0 comments on commit 7694a19

Please sign in to comment.