package flux import ( "context" "fmt" "github.com/aws/eks-anywhere/pkg/cluster" "github.com/aws/eks-anywhere/pkg/logger" "github.com/aws/eks-anywhere/pkg/types" ) const upgradeFluxconfigCommitMessage = "Upgrade commit of flux configuration; generated by EKS-A CLI" func (f *Flux) Upgrade(ctx context.Context, managementCluster *types.Cluster, currentSpec *cluster.Spec, newSpec *cluster.Spec) (*types.ChangeDiff, error) { logger.V(1).Info("Checking for Flux upgrades") changeDiff := FluxChangeDiff(currentSpec, newSpec) if changeDiff == nil { logger.V(1).Info("Nothing to upgrade for Flux") return nil, nil } logger.V(1).Info("Starting Flux upgrades") if err := f.upgradeFilesAndCommit(ctx, newSpec); err != nil { return nil, fmt.Errorf("upgrading Flux from bundles %d to bundles %d: %v", currentSpec.Bundles.Spec.Number, newSpec.Bundles.Spec.Number, err) } if err := f.fluxClient.DeleteSystemSecret(ctx, managementCluster, newSpec.FluxConfig.Spec.SystemNamespace); err != nil { return nil, fmt.Errorf("upgrading Flux when deleting old flux-system secret: %v", err) } if err := f.BootstrapGithub(ctx, managementCluster, newSpec); err != nil { return nil, fmt.Errorf("upgrading Flux components with github provider: %v", err) } if err := f.BootstrapGit(ctx, managementCluster, newSpec); err != nil { return nil, fmt.Errorf("upgrading Flux components with git provider: %v", err) } if err := f.fluxClient.Reconcile(ctx, managementCluster, newSpec.FluxConfig); err != nil { return nil, fmt.Errorf("reconciling Flux components: %v", err) } return changeDiff, nil } func FluxChangeDiff(currentSpec, newSpec *cluster.Spec) *types.ChangeDiff { if !newSpec.Cluster.IsSelfManaged() { logger.V(1).Info("Skipping Flux upgrades, not a self-managed cluster") return nil } if currentSpec.Cluster.Spec.GitOpsRef == nil && newSpec.Cluster.Spec.GitOpsRef != nil { logger.V(1).Info("Skipping Flux upgrades, no previous flux installed in the cluster") return nil } if currentSpec.Cluster.Spec.GitOpsRef == nil { logger.V(1).Info("Skipping Flux upgrades, GitOps not enabled") return nil } oldVersionsBundle := currentSpec.ControlPlaneVersionsBundle() newVersionsBundle := newSpec.ControlPlaneVersionsBundle() oldVersion := oldVersionsBundle.Flux.Version newVersion := newVersionsBundle.Flux.Version if oldVersion != newVersion { logger.V(1).Info("Flux change diff ", "oldVersion ", oldVersion, "newVersion ", newVersion) return &types.ChangeDiff{ ComponentReports: []types.ComponentChangeDiff{ { ComponentName: "Flux", NewVersion: newVersion, OldVersion: oldVersion, }, }, } } return nil } func (f *Flux) Install(ctx context.Context, cluster *types.Cluster, oldSpec, newSpec *cluster.Spec) error { if oldSpec.Cluster.Spec.GitOpsRef == nil && newSpec.Cluster.Spec.GitOpsRef != nil { return f.InstallGitOps(ctx, cluster, newSpec, nil, nil) } return nil } func (f *Flux) upgradeFilesAndCommit(ctx context.Context, newSpec *cluster.Spec) error { fc := &fluxForCluster{ Flux: f, clusterSpec: newSpec, } if err := fc.syncGitRepo(ctx); err != nil { return err } if err := fc.commitFluxUpgradeFilesToGit(ctx); err != nil { return err } return nil } func (fc *fluxForCluster) commitFluxUpgradeFilesToGit(ctx context.Context) error { logger.Info("Adding flux configuration files to Git") g := NewFileGenerator() if err := g.Init(fc.writer, fc.eksaSystemDir(), fc.fluxSystemDir()); err != nil { return err } if err := g.WriteFluxPatch(fc.clusterSpec); err != nil { return err } if err := fc.gitClient.Add(fc.path()); err != nil { return fmt.Errorf("adding %s to git: %v", fc.path(), err) } if err := fc.Flux.pushToRemoteRepo(ctx, fc.path(), upgradeFluxconfigCommitMessage); err != nil { return err } logger.V(3).Info("Finished pushing flux custom manifest files to git", "repository", fc.repository()) return nil }