Skip to content

Commit

Permalink
test for TaskRun CRD presence, create/configure tekton operator as ne…
Browse files Browse the repository at this point in the history
…eded
  • Loading branch information
gabemontero committed Aug 24, 2021
1 parent 909fc35 commit 8594f4a
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 16 deletions.
22 changes: 19 additions & 3 deletions cmd/operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth"

apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
crdclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

tektonoperatorv1alpha1client "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1"

operatorv1alpha1 "github.com/shipwright-io/operator/api/v1alpha1"
"github.com/shipwright-io/operator/controllers"
// +kubebuilder:scaffold:imports
Expand Down Expand Up @@ -79,10 +82,23 @@ func main() {
os.Exit(1)
}

crdClient, err := crdclientv1.NewForConfig(mgr.GetConfig())
if err != nil {
setupLog.Error(err, "unable to get crd client")
os.Exit(1)
}
tektonOperatorClient, err := tektonoperatorv1alpha1client.NewForConfig(mgr.GetConfig())
if err != nil {
setupLog.Error(err, "unable to get tekton operator client")
os.Exit(1)
}

if err = (&controllers.ShipwrightBuildReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Logger: ctrl.Log.WithName("controllers").WithName("ShipwrightBuild"),
CRDClient: crdClient,
TektonOperatorClient: tektonOperatorClient,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Logger: ctrl.Log.WithName("controllers").WithName("ShipwrightBuild"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ShipwrightBuild")
os.Exit(1)
Expand Down
68 changes: 61 additions & 7 deletions controllers/shipwrightbuild_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import (
"github.com/go-logr/logr"
mfc "github.com/manifestival/controller-runtime-client"
"github.com/manifestival/manifestival"
tektonoperatorv1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
tektonoperatorv1alpha1client "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1"

crdclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
Expand All @@ -32,11 +37,14 @@ const (

// ShipwrightBuildReconciler reconciles a ShipwrightBuild object
type ShipwrightBuildReconciler struct {
client.Client // controller kubernetes client

Logger logr.Logger // decorated logger
Scheme *runtime.Scheme // runtime scheme
Manifest manifestival.Manifest // release manifests render
client.Client // controller kubernetes client
CRDClient crdclientv1.ApiextensionsV1Interface
TektonOperatorClient tektonoperatorv1alpha1client.OperatorV1alpha1Interface

Logger logr.Logger // decorated logger
Scheme *runtime.Scheme // runtime scheme
Manifest manifestival.Manifest // release manifests render
TektonManifest manifestival.Manifest // Tekton release manifest render
}

// setFinalizer append finalizer on the resource, and uses local client to update it immediately.
Expand Down Expand Up @@ -69,7 +77,43 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ
logger := r.Logger.WithValues("namespace", req.Namespace, "name", req.Name)
logger.Info("Starting resource reconciliation...")

// retrieving the ShipwrightBuild instance requested for reconciliation
// See if tekton is there
_, err := r.CRDClient.CustomResourceDefinitions().Get(ctx, "taskruns.tekton.dev", metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
// CRD not there, install tekton via operator; as we have specified the TaskRun CRD as required in
// our operator's CSV, if the TaskRun CRD is not there, that means the operator is not present, as
// OLM should have provisioned the Tekton operator based on our dependency declaration.
if err := r.TektonManifest.Apply(); err != nil {
logger.Error(err, "Rolling out Tekton Operator release 0.49.0 resources")
RequeueOnError(err)
}
logger.Info("The Tekton Operator 0.49.0 release has been applied to the cluster")
// the tekton operator 'lite' profile is all Shipwright currently needs, so configure that up;
// when Shipwright starts leveraging triggers, we will want to bump up to a 'base' or higher
list, err := r.TektonOperatorClient.TektonConfigs().List(ctx, metav1.ListOptions{})
if err != nil {
logger.Error(err, "Listing Tekton Configs")
RequeueOnError(err)
}
if list == nil || len(list.Items) == 0 {
tektonOperatorCfg := &tektonoperatorv1alpha1.TektonConfig{}
tektonOperatorCfg.Name = "config"
tektonOperatorCfg.Spec.TargetNamespace = "tekton-pipelines"
tektonOperatorCfg.Spec.Profile = "lite"
if _, err := r.TektonOperatorClient.TektonConfigs().Create(ctx, tektonOperatorCfg, metav1.CreateOptions{}); err != nil {
logger.Error(err, "Creating Tekton Operator lite config ")
RequeueOnError(err)
}
logger.Info("A Tekton Operator config with the 'lite' profile has been applied to the cluster")
}
} else {
logger.Error(err, "Retrieving TaskRun CRD instance")
return RequeueOnError(err)
}
}

// retrieving the ShipwrightBuild instance requested for reconciliatio
b := &v1alpha1.ShipwrightBuild{}
if err := r.Get(ctx, req.NamespacedName, b); err != nil {
if errors.IsNotFound(err) {
Expand Down Expand Up @@ -142,7 +186,7 @@ func (r *ShipwrightBuildReconciler) Reconcile(ctx context.Context, req ctrl.Requ
return NoRequeue()
}

// setupManifestival instantiate manifestival with local controller attributes.
// setupManifestival instantiate manifestival with local controller attributes, as well as tekton prereqs.
func (r *ShipwrightBuildReconciler) setupManifestival(managerLogger logr.Logger) error {
client := mfc.NewClient(r.Client)
logger := managerLogger.WithName("manifestival")
Expand All @@ -158,6 +202,16 @@ func (r *ShipwrightBuildReconciler) setupManifestival(managerLogger logr.Logger)
manifestival.UseClient(client),
manifestival.UseLogger(logger),
)
if err != nil {
return err
}

tektonOperatorManifest := "https://storage.googleapis.com/tekton-releases/operator/previous/v0.49.0/release.yaml"
r.TektonManifest, err = manifestival.NewManifest(
tektonOperatorManifest,
manifestival.UseClient(client),
manifestival.UseLogger(logger),
)
return err
}

Expand Down
14 changes: 11 additions & 3 deletions controllers/shipwrightbuild_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
o "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
crdclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -19,6 +20,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"github.com/shipwright-io/operator/api/v1alpha1"
tektonoperatorv1alpha1client "github.com/tektoncd/operator/pkg/client/clientset/versioned/fake"
crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)

func init() {
Expand All @@ -32,6 +35,7 @@ func init() {
func bootstrapShipwrightBuildReconciler(
t *testing.T,
b *v1alpha1.ShipwrightBuild,
tcrd *crdv1.CustomResourceDefinition,
) (client.Client, *ShipwrightBuildReconciler) {
g := o.NewGomegaWithT(t)

Expand All @@ -43,7 +47,9 @@ func bootstrapShipwrightBuildReconciler(
logger := zap.New()

c := fake.NewFakeClientWithScheme(s, b)
r := &ShipwrightBuildReconciler{Client: c, Scheme: s, Logger: logger}
crdClient := crdclientv1.NewSimpleClientset(tcrd)
toClient := tektonoperatorv1alpha1client.NewSimpleClientset()
r := &ShipwrightBuildReconciler{CRDClient: crdClient.ApiextensionsV1(), TektonOperatorClient: toClient.OperatorV1alpha1(), Client: c, Scheme: s, Logger: logger}

// creating targetNamespace on which Shipwright-Build will be deployed against, before the other
// tests takes place
Expand Down Expand Up @@ -74,7 +80,7 @@ func TestShipwrightBuildReconciler_Finalizers(t *testing.T) {
g := o.NewGomegaWithT(t)

b := &v1alpha1.ShipwrightBuild{ObjectMeta: metav1.ObjectMeta{Name: "name", Namespace: "default"}}
_, r := bootstrapShipwrightBuildReconciler(t, b)
_, r := bootstrapShipwrightBuildReconciler(t, b, &crdv1.CustomResourceDefinition{})

// adding one entry on finalizers slice, making sure it's registered
t.Run("setFinalizer", func(t *testing.T) {
Expand Down Expand Up @@ -114,7 +120,9 @@ func testShipwrightBuildReconcilerReconcile(t *testing.T, targetNamespace string
TargetNamespace: targetNamespace,
},
}
c, r := bootstrapShipwrightBuildReconciler(t, b)
crd := &crdv1.CustomResourceDefinition{}
crd.Name = "taskruns.tekton.dev"
c, r := bootstrapShipwrightBuildReconciler(t, b, crd)

t.Logf("Deploying Shipwright Controller against '%s' namespace", targetNamespace)

Expand Down
13 changes: 10 additions & 3 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package controllers

import (
"context"
tektonoperatorv1alpha1client "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1"
crdclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
"path/filepath"
"testing"
"time"
Expand Down Expand Up @@ -70,10 +72,15 @@ var _ = BeforeSuite(func() {
Scheme: scheme.Scheme,
})
Expect(err).NotTo(HaveOccurred())
crdClient, err := crdclientv1.NewForConfig(mgr.GetConfig())
Expect(err).NotTo(HaveOccurred())
toClient, err := tektonoperatorv1alpha1client.NewForConfig(mgr.GetConfig())
err = (&ShipwrightBuildReconciler{
Client: mgr.GetClient(),
Scheme: scheme.Scheme,
Logger: ctrl.Log.WithName("controllers").WithName("shipwrightbuild"),
CRDClient: crdClient,
TektonOperatorClient: toClient,
Client: mgr.GetClient(),
Scheme: scheme.Scheme,
Logger: ctrl.Log.WithName("controllers").WithName("shipwrightbuild"),
}).SetupWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

Expand Down

0 comments on commit 8594f4a

Please sign in to comment.