Skip to content

Commit

Permalink
update inventory status with aggregated values (#138)
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Bortnikov <[email protected]>
  • Loading branch information
aobort authored Jun 26, 2024
1 parent 67a3ba7 commit 506b5b6
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 11 deletions.
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func main() {

if p.enableInventoryController {
var inventoryReconciler *controller.InventoryReconciler
inventoryReconciler, err = controller.NewInventoryReconciler()
inventoryReconciler, err = controller.NewInventoryReconciler(p.systemNamespace)
if err != nil {
log.Error(ctx, fmt.Errorf("cannot create controller: %w", err), "controller", "Inventory")
exitCode = 1
Expand Down
30 changes: 30 additions & 0 deletions config/rbac/aggregate_editor_role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: aggregate-editor-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: metal
app.kubernetes.io/part-of: metal
app.kubernetes.io/managed-by: kustomize
name: aggregate-editor-role
rules:
- apiGroups:
- metal.ironcore.dev
resources:
- aggregates
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metal.ironcore.dev
resources:
- aggregates/status
verbs:
- get
26 changes: 26 additions & 0 deletions config/rbac/aggregate_viewer_role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: aggregate-viewer-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: metal
app.kubernetes.io/part-of: metal
app.kubernetes.io/managed-by: kustomize
name: aggregate-viewer-role
rules:
- apiGroups:
- metal.ironcore.dev
resources:
- aggregates
verbs:
- get
- list
- watch
- apiGroups:
- metal.ironcore.dev
resources:
- aggregates/status
verbs:
- get
12 changes: 6 additions & 6 deletions internal/controller/aggregate_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=aggregates/finalizers,verbs=update

const (
AggregateFinalizer = "aggregate.metal.ironcore.dev/finalizer"
AggregateFieldOwner = "metal.ironcore.dev/aggregate"
AggregateFinalizer = "aggregate.metal.ironcore.dev/finalizer"
AggregateFieldManager = "metal.ironcore.dev/aggregate"
)

func NewAggregateReconciler() (*AggregateReconciler, error) {
Expand Down Expand Up @@ -56,7 +56,7 @@ func (r *AggregateReconciler) reconcile(ctx context.Context, aggregate *metalv1a
aggregateApply := metalv1alpha1apply.Aggregate(aggregate.Name, aggregate.Namespace).
WithFinalizers(AggregateFinalizer)
return r.Patch(
ctx, aggregate, ssa.Apply(aggregateApply), client.FieldOwner(AggregateFieldOwner), client.ForceOwnership)
ctx, aggregate, ssa.Apply(aggregateApply), client.FieldOwner(AggregateFieldManager), client.ForceOwnership)
}

inventories := &metalv1alpha1.InventoryList{}
Expand Down Expand Up @@ -85,7 +85,7 @@ func (r *AggregateReconciler) reconcile(ctx context.Context, aggregate *metalv1a
WithComputed(metalv1alpha1.AggregationResults{Object: aggregateResults})
inventoryApply = inventoryApply.WithStatus(inventoryStatusApply)
if err := r.Status().Patch(
ctx, &inventory, ssa.Apply(inventoryApply), client.FieldOwner(AggregateFieldOwner), client.ForceOwnership); err != nil {
ctx, &inventory, ssa.Apply(inventoryApply), client.FieldOwner(AggregateFieldManager), client.ForceOwnership); err != nil {
log.Error(ctx, fmt.Errorf("failed to patch inventory: %w", err), "inventory", inventory.Name)
}
}
Expand All @@ -112,14 +112,14 @@ func (r *AggregateReconciler) finalize(ctx context.Context, aggregate metalv1alp
WithComputed(metalv1alpha1.AggregationResults{Object: computed})
inventoryApply = inventoryApply.WithStatus(inventoryStatusApply)
if err := r.Status().Patch(
ctx, &inventory, ssa.Apply(inventoryApply), client.FieldOwner(AggregateFieldOwner), client.ForceOwnership); err != nil {
ctx, &inventory, ssa.Apply(inventoryApply), client.FieldOwner(AggregateFieldManager), client.ForceOwnership); err != nil {
log.Error(ctx, fmt.Errorf("failed to patch inventory: %w", err), "inventory", inventory.Name)
}
}

aggregateApply := metalv1alpha1apply.Aggregate(aggregate.Name, aggregate.Namespace).
WithFinalizers()
return r.Patch(ctx, &aggregate, ssa.Apply(aggregateApply), client.FieldOwner(AggregateFieldOwner), client.ForceOwnership)
return r.Patch(ctx, &aggregate, ssa.Apply(aggregateApply), client.FieldOwner(AggregateFieldManager), client.ForceOwnership)
}

func (r *AggregateReconciler) SetupWithManager(mgr ctrl.Manager) error {
Expand Down
72 changes: 69 additions & 3 deletions internal/controller/inventory_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,31 @@ import (
metalv1alpha1apply "github.com/ironcore-dev/metal/client/applyconfiguration/api/v1alpha1"
"github.com/ironcore-dev/metal/internal/ssa"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
metav1apply "k8s.io/client-go/applyconfigurations/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const InventoryFieldManager = "metal.ironcore.dev/inventory-controller"
const (
InventoryFieldManager = "metal.ironcore.dev/inventory-controller"
defaultAggregateName = "default"
)

// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=inventories,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=inventories/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=metal.ironcore.dev,resources=inventories/finalizers,verbs=update

func NewInventoryReconciler() (*InventoryReconciler, error) {
return &InventoryReconciler{}, nil
func NewInventoryReconciler(systemNamespace string) (*InventoryReconciler, error) {
return &InventoryReconciler{systemNamespace: systemNamespace}, nil
}

type InventoryReconciler struct {
client.Client

systemNamespace string
}

func (r *InventoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
Expand All @@ -45,6 +52,26 @@ func (r *InventoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
}

func (r *InventoryReconciler) reconcile(ctx context.Context, inventory metalv1alpha1.Inventory) error {
if err := r.ensureAggregate(ctx); err != nil {
return err
}
return r.reconcileMachine(ctx, inventory)
}

func (r *InventoryReconciler) ensureAggregate(ctx context.Context) error {
key := types.NamespacedName{Name: defaultAggregateName, Namespace: r.systemNamespace}
aggregate := metalv1alpha1.Aggregate{}
err := r.Get(ctx, key, &aggregate)
if apierrors.IsNotFound(err) {
return r.createAggregate(ctx)
}
if err != nil {
return fmt.Errorf("failed to get Aggregate: %w", err)
}
return nil
}

func (r *InventoryReconciler) reconcileMachine(ctx context.Context, inventory metalv1alpha1.Inventory) error {
machines := &metalv1alpha1.MachineList{}
if err := r.List(ctx, machines); err != nil {
return err
Expand Down Expand Up @@ -117,6 +144,45 @@ func (r *InventoryReconciler) setControllerReference(ctx context.Context, machin
ctx, inventory, ssa.Apply(inventoryApply), client.FieldOwner(InventoryFieldManager), client.ForceOwnership)
}

func (r *InventoryReconciler) createAggregate(ctx context.Context) error {
aggregate := &metalv1alpha1.Aggregate{
ObjectMeta: metav1.ObjectMeta{Name: defaultAggregateName, Namespace: r.systemNamespace},
}

aggregateSpecApply := metalv1alpha1apply.AggregateSpec()
aggregatesList := []*metalv1alpha1apply.AggregateItemApplyConfiguration{
metalv1alpha1apply.AggregateItem().
WithAggregate(metalv1alpha1.CountAggregateType).
WithSourcePath(*metalv1alpha1.JSONPathFromString("spec.blocks[*]")).
WithTargetPath(*metalv1alpha1.JSONPathFromString("blocks.count")),
metalv1alpha1apply.AggregateItem().
WithAggregate(metalv1alpha1.SumAggregateType).
WithSourcePath(*metalv1alpha1.JSONPathFromString("spec.blocks[*].size")).
WithTargetPath(*metalv1alpha1.JSONPathFromString("blocks.capacity")),
metalv1alpha1apply.AggregateItem().
WithAggregate(metalv1alpha1.CountAggregateType).
WithSourcePath(*metalv1alpha1.JSONPathFromString("spec.cpus[*]")).
WithTargetPath(*metalv1alpha1.JSONPathFromString("cpus.sockets")),
metalv1alpha1apply.AggregateItem().
WithAggregate(metalv1alpha1.SumAggregateType).
WithSourcePath(*metalv1alpha1.JSONPathFromString("spec.cpus[*].cores")).
WithTargetPath(*metalv1alpha1.JSONPathFromString("cpus.cores")),
metalv1alpha1apply.AggregateItem().
WithAggregate(metalv1alpha1.SumAggregateType).
WithSourcePath(*metalv1alpha1.JSONPathFromString("spec.cpus[*].siblings")).
WithTargetPath(*metalv1alpha1.JSONPathFromString("cpus.threads")),
metalv1alpha1apply.AggregateItem().
WithAggregate(metalv1alpha1.CountAggregateType).
WithSourcePath(*metalv1alpha1.JSONPathFromString("spec.nics[*]")).
WithTargetPath(*metalv1alpha1.JSONPathFromString("nics.count")),
}
aggregateSpecApply = aggregateSpecApply.WithAggregates(aggregatesList...)
aggregateApply := metalv1alpha1apply.Aggregate(defaultAggregateName, r.systemNamespace).
WithSpec(aggregateSpecApply)
return r.Patch(
ctx, aggregate, ssa.Apply(aggregateApply), client.FieldOwner(InventoryFieldManager), client.ForceOwnership)
}

func (r *InventoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
r.Client = mgr.GetClient()

Expand Down
2 changes: 1 addition & 1 deletion internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ var _ = BeforeSuite(func() {
Expect(CreateIndexes(ctx, mgr)).To(Succeed())

var inventoryReconciler *InventoryReconciler
inventoryReconciler, err = NewInventoryReconciler()
inventoryReconciler, err = NewInventoryReconciler(ns.Name)
Expect(err).NotTo(HaveOccurred())
Expect(inventoryReconciler).NotTo(BeNil())
Expect(inventoryReconciler.SetupWithManager(mgr)).To(Succeed())
Expand Down

0 comments on commit 506b5b6

Please sign in to comment.