Skip to content

Commit

Permalink
Build Controller and Inventory
Browse files Browse the repository at this point in the history
  • Loading branch information
otaviof committed Nov 28, 2022
1 parent e1d01fb commit df3cdca
Show file tree
Hide file tree
Showing 14 changed files with 892 additions and 0 deletions.
73 changes: 73 additions & 0 deletions controllers/inventory_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package controllers

import (
"context"

"github.com/shipwright-io/build/pkg/apis/build/v1alpha1"
"github.com/shipwright-io/triggers/pkg/inventory"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)

// InventoryReconciler reconciles Build instances on the Inventory.
type InventoryReconciler struct {
client.Client // kubernetes client
Scheme *runtime.Scheme // shared scheme
Clock // local clock instance

buildInventory *inventory.Inventory // local build triggers database
}

//+kubebuilder:rbac:groups=shipwright.io,resources=builds,verbs=get;list;watch

// Reconcile reconciles Build instances reflecting it's status on the Inventory.
func (r *InventoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := log.FromContext(ctx)

var b v1alpha1.Build
if err := r.Get(ctx, req.NamespacedName, &b); err != nil {
if !errors.IsNotFound(err) {
logger.Error(err, "Unable to fetch Build, removing from the Inventory")
}
r.buildInventory.Remove(req.NamespacedName)
return ctrl.Result{}, client.IgnoreNotFound(err)
}

if b.ObjectMeta.DeletionTimestamp.IsZero() {
logger.V(0).Info("Adding Build on the Inventory")
r.buildInventory.Add(&b)
} else {
logger.V(0).Info("Removing Build from the Inventory, marked for deletion")
r.buildInventory.Remove(req.NamespacedName)
}

return ctrl.Result{}, nil
}

// SetupWithManager uses the manager to watch over Builds.
func (r *InventoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
if r.Clock == nil {
r.Clock = realClock{}
}

return ctrl.NewControllerManagedBy(mgr).
For(&v1alpha1.Build{}).
Complete(r)
}

// NewInventoryReconciler instantiate the InventoryReconciler.
func NewInventoryReconciler(
ctrlClient client.Client,
scheme *runtime.Scheme,
buildInventory *inventory.Inventory,
) *InventoryReconciler {
return &InventoryReconciler{
Client: ctrlClient,
Scheme: scheme,
buildInventory: buildInventory,
}
}
17 changes: 17 additions & 0 deletions controllers/real_clock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package controllers

import (
"time"
)

type realClock struct{}

func (_ realClock) Now() time.Time {
return time.Now()
}

type Clock interface {
Now() time.Time
}

// +kubebuilder:docs-gen:collapse=Clock
27 changes: 27 additions & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package constants

import (
"fmt"

"github.com/shipwright-io/build/pkg/apis/build/v1alpha1"

tknv1alpha1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
tknv1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
)

var (
TektonAPIv1alpha1 = fmt.Sprintf(
"%s/%s",
tknv1alpha1.SchemeGroupVersion.Group,
tknv1alpha1.SchemeGroupVersion.Version,
)
TektonAPIv1beta1 = fmt.Sprintf("%s/%s",
tknv1beta1.SchemeGroupVersion.Group,
tknv1beta1.SchemeGroupVersion.Version,
)
ShipwrightAPIVersion = fmt.Sprintf(
"%s/%s",
v1alpha1.SchemeGroupVersion.Group,
v1alpha1.SchemeGroupVersion.Version,
)
)
94 changes: 94 additions & 0 deletions pkg/inventory/fake_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package inventory

import (
"log"
"sync"

"github.com/shipwright-io/build/pkg/apis/build/v1alpha1"
"github.com/shipwright-io/triggers/test/stubs"
"k8s.io/apimachinery/pkg/types"
)

// FakeInventory testing instance of Inventory, adds all objects o the local cache, and returns all
// of them on the search queries.
type FakeInventory struct {
m sync.Mutex

cache map[types.NamespacedName]*v1alpha1.Build
}

var _ Interface = &FakeInventory{}

// Contains checks if the informed key is in the cache.
func (i *FakeInventory) Contains(name string) bool {
i.m.Lock()
defer i.m.Unlock()

log.Printf("Cheking if Build %q is cached", name)
_, ok := i.cache[types.NamespacedName{Namespace: stubs.Namespace, Name: name}]
return ok
}

// Add adds a Build to the cache.
func (i *FakeInventory) Add(b *v1alpha1.Build) {
i.m.Lock()
defer i.m.Unlock()

key := types.NamespacedName{Namespace: b.GetNamespace(), Name: b.GetName()}
log.Printf("Adding Build %q to the inventory", key)
i.cache[key] = b
}

// Remove removes a Build from the cache.
func (i *FakeInventory) Remove(key types.NamespacedName) {
i.m.Lock()
defer i.m.Unlock()

log.Printf("Removing Build %q from the inventory", key)
delete(i.cache, key)
}

// search returns all instances as SearchResult slice.
func (i *FakeInventory) search() []SearchResult {
searchResults := []SearchResult{}
if len(i.cache) == 0 {
return searchResults
}
for _, b := range i.cache {
secretName := types.NamespacedName{}
if b.Spec.Trigger != nil &&
b.Spec.Trigger.SecretRef != nil &&
b.Spec.Trigger.SecretRef.Name != "" {
secretName.Namespace = b.GetNamespace()
secretName.Namespace = b.Spec.Trigger.SecretRef.Name
}
searchResults = append(searchResults, SearchResult{
BuildName: types.NamespacedName{Namespace: b.GetNamespace(), Name: b.GetName()},
SecretName: secretName,
})
}
return searchResults
}

// SearchForObjectRef returns all Builds in cache.
func (i *FakeInventory) SearchForObjectRef(v1alpha1.TriggerType, *v1alpha1.WhenObjectRef) []SearchResult {
i.m.Lock()
defer i.m.Unlock()

return i.search()
}

// SearchForGit returns all Builds in cache.
func (i *FakeInventory) SearchForGit(v1alpha1.TriggerType, string, string) []SearchResult {
i.m.Lock()
defer i.m.Unlock()

return i.search()
}

// NewFakeInventory instante a fake inventory for testing.
func NewFakeInventory() *FakeInventory {
return &FakeInventory{
cache: map[types.NamespacedName]*v1alpha1.Build{},
}
}
13 changes: 13 additions & 0 deletions pkg/inventory/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package inventory

import (
"github.com/shipwright-io/build/pkg/apis/build/v1alpha1"
"k8s.io/apimachinery/pkg/types"
)

type Interface interface {
Add(*v1alpha1.Build)
Remove(types.NamespacedName)
SearchForObjectRef(v1alpha1.TriggerType, *v1alpha1.WhenObjectRef) []SearchResult
SearchForGit(v1alpha1.TriggerType, string, string) []SearchResult
}
Loading

0 comments on commit df3cdca

Please sign in to comment.