Skip to content

Commit

Permalink
Populate bundle status from bundleDeployment status resources (#2535)
Browse files Browse the repository at this point in the history
* Populate bundle status from bundleDeployment status resources

* Add integration tests to check resource keys in bundle status
  • Loading branch information
rubhanazeem authored Jun 21, 2024
1 parent 6fa6a0a commit 69144fe
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 78 deletions.
17 changes: 17 additions & 0 deletions integrationtests/controller/bundle/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,27 @@ var _ = Describe("Bundle Status Fields", func() {
if err != nil {
return err
}
resources := []v1alpha1.BundleDeploymentResource{}
resource := v1alpha1.BundleDeploymentResource{
Kind: "ConfigMap",
APIVersion: "v1",
Namespace: namespace,
Name: "app-config",
}
resources = append(resources, resource)
bd.Status.Display.State = "Ready"
bd.Status.AppliedDeploymentID = bd.Spec.DeploymentID
bd.Status.Ready = true
bd.Status.NonModified = true
bd.Status.Resources = resources
return k8sClient.Status().Update(ctx, bd)
}).ShouldNot(HaveOccurred())

err = k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: "name"}, bd)
Expect(err).NotTo(HaveOccurred())
Expect(bd.Status.Display.State).To(Equal("Ready"))
Expect(bd.Status.AppliedDeploymentID).To(Equal(bd.Spec.DeploymentID))
Expect(len(bd.Status.Resources)).To(Equal(1))

Eventually(func() bool {
err = k8sClient.Get(ctx, types.NamespacedName{Namespace: namespace, Name: "name"}, bundle)
Expand All @@ -89,6 +99,13 @@ var _ = Describe("Bundle Status Fields", func() {
}).Should(BeTrue())
Expect(bundle.Status.Summary.DesiredReady).To(Equal(1))
Expect(bundle.Status.Display.ReadyClusters).To(Equal("1/1"))
Expect(len(bundle.Status.ResourceKey)).To(Equal(1))
bdResource := bd.Status.Resources[0]
bundleResourceKey := bundle.Status.ResourceKey[0]
Expect(bundleResourceKey.APIVersion).To(Equal(bdResource.APIVersion))
Expect(bundleResourceKey.Name).To(Equal(bdResource.Name))
Expect(bundleResourceKey.Namespace).To(Equal(bdResource.Namespace))
Expect(bundleResourceKey.Kind).To(Equal(bdResource.Kind))
})
})

Expand Down
16 changes: 1 addition & 15 deletions internal/cmd/controller/reconciler/bundle_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ import (
"github.com/rancher/fleet/pkg/sharding"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -165,11 +163,7 @@ func (r *BundleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}

if bundle.Status.ObservedGeneration != bundle.Generation {
if err := setResourceKey(context.Background(), &bundle.Status, bundle, manifest, r.isNamespaced); err != nil {
return ctrl.Result{}, err
}
}
setResourceKey(&bundle.Status, matchedTargets)

summary.SetReadyConditions(&bundle.Status, "Cluster", bundle.Status.Summary)
bundle.Status.ObservedGeneration = bundle.Generation
Expand Down Expand Up @@ -227,14 +221,6 @@ func (r *BundleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, err
}

func (r *BundleReconciler) isNamespaced(gvk schema.GroupVersionKind) bool {
mapping, err := r.RESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return true
}
return mapping.Scope.Name() == meta.RESTScopeNameNamespace
}

func upper(op controllerutil.OperationResult) string {
switch op {
case controllerutil.OperationResultNone:
Expand Down
79 changes: 16 additions & 63 deletions internal/cmd/controller/reconciler/bundle_status.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
package reconciler

import (
"context"
"fmt"
"sort"

"github.com/sirupsen/logrus"

"github.com/rancher/fleet/internal/cmd/controller/options"
"github.com/rancher/fleet/internal/cmd/controller/summary"
"github.com/rancher/fleet/internal/cmd/controller/target"
"github.com/rancher/fleet/internal/helmdeployer"
"github.com/rancher/fleet/internal/manifest"
fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"

"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/sirupsen/logrus"
)

const (
Expand All @@ -41,64 +32,26 @@ func updateDisplay(status *fleet.BundleStatus) {
status.Display.State = string(summary.GetSummaryState(status.Summary))
}

// setResourceKey updates status.ResourceKey from the bundle, by running helm template (does not mutate bundle)
func setResourceKey(ctx context.Context, status *fleet.BundleStatus, bundle *fleet.Bundle, manifest *manifest.Manifest, isNSed func(schema.GroupVersionKind) bool) error {
seen := map[fleet.ResourceKey]struct{}{}

// iterate over the defined targets, from "targets.yaml", not the
// actually matched targets to avoid duplicates
for i := range bundle.Spec.Targets {
opts := options.Merge(bundle.Spec.BundleDeploymentOptions, bundle.Spec.Targets[i].BundleDeploymentOptions)
objs, err := helmdeployer.Template(ctx, bundle.Name, manifest, opts)
if err != nil {
logrus.Infof("While calculating status.ResourceKey, error running helm template for bundle %s with target options from %s: %v", bundle.Name, bundle.Spec.Targets[i].Name, err)
// setResourceKey updates status.ResourceKey from the bundleDeployments
func setResourceKey(status *fleet.BundleStatus, allTargets []*target.Target) {
keys := []fleet.ResourceKey{}
for _, target := range allTargets {
if target.Deployment == nil {
continue
}

for _, obj := range objs {
m, err := meta.Accessor(obj)
if err != nil {
return err
}
if target.Deployment.Namespace == "" {
logrus.Infof("Skipping bundledeployment with empty namespace %q", target.Deployment.Name)
continue
}
for _, resource := range target.Deployment.Status.Resources {
key := fleet.ResourceKey{
Namespace: m.GetNamespace(),
Name: m.GetName(),
Name: resource.Name,
Namespace: resource.Namespace,
APIVersion: resource.APIVersion,
Kind: resource.Kind,
}
gvk := obj.GetObjectKind().GroupVersionKind()
if key.Namespace == "" && isNSed(gvk) {
if opts.DefaultNamespace == "" {
key.Namespace = "default"
} else {
key.Namespace = opts.DefaultNamespace
}
}
key.APIVersion, key.Kind = gvk.ToAPIVersionAndKind()
seen[key] = struct{}{}
keys = append(keys, key)
}
}

keys := []fleet.ResourceKey{}
for k := range seen {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
keyi := keys[i]
keyj := keys[j]
if keyi.APIVersion != keyj.APIVersion {
return keyi.APIVersion < keyj.APIVersion
}
if keyi.Kind != keyj.Kind {
return keyi.Kind < keyj.Kind
}
if keyi.Namespace != keyj.Namespace {
return keyi.Namespace < keyj.Namespace
}
if keyi.Name != keyj.Name {
return keyi.Name < keyj.Name
}
return false
})
status.ResourceKey = keys

return nil
}

0 comments on commit 69144fe

Please sign in to comment.