From 1eda5b2c1dbc32fa1614a97c9140fa1204628b12 Mon Sep 17 00:00:00 2001 From: Piyush Garg Date: Mon, 7 Mar 2022 13:30:00 +0530 Subject: [PATCH] Make TektonChain out of all profile This will move TektonChain out of all profile as installing it by default will not provide any use and just adding extra resource consumption because chains reconcile requires key to sign Now users can create chains CR and install it as required --- docs/README.md | 4 +- docs/TektonChain.md | 47 +++-- docs/TektonConfig.md | 7 +- .../kubernetes/tektonchain/controller.go | 1 - .../shared/tektonconfig/chain/chain.go | 180 ------------------ .../shared/tektonconfig/chain/chain_test.go | 46 ----- .../shared/tektonconfig/controller.go | 6 - .../shared/tektonconfig/tektonconfig.go | 16 -- .../common/00_tektonconfigdeployment_test.go | 10 - 9 files changed, 40 insertions(+), 277 deletions(-) delete mode 100644 pkg/reconciler/shared/tektonconfig/chain/chain.go delete mode 100644 pkg/reconciler/shared/tektonconfig/chain/chain_test.go diff --git a/docs/README.md b/docs/README.md index e8070b8d97..36ee8ff180 100644 --- a/docs/README.md +++ b/docs/README.md @@ -72,11 +72,11 @@ To install Operator there are multiple ways You can clone and repository and install the Operator. You can find the instruction in [here](../DEVELOPMENT.md) -After installing the Operator, to install the required Tekton Component such as Tekton Pipeline, Tekton Triggers, Tekton Chains. +After installing the Operator, to install the required Tekton Component such as Tekton Pipeline, Tekton Triggers. Create an instance of `TektonConfig` which will create the required components. You can find more details and the available configuration in [TektonConfig](TektonConfig.md). -NOTE: `TektonResult` is an optional component added recently and is not installed through `TektonConfig` currently. You can find the installation steps in its [doc](TektonResult.md). +NOTE: `TektonResult` and `TektonChain` are optional components and are not installed through `TektonConfig` currently. You can find the installation steps in their docs. ## Understanding Tekton Operator diff --git a/docs/TektonChain.md b/docs/TektonChain.md index 806e58138c..0b36cc6f1f 100644 --- a/docs/TektonChain.md +++ b/docs/TektonChain.md @@ -8,17 +8,40 @@ weight: 9 TektonChain custom resource allows user to install and manage [Tekton Chains][chains]. -It is recommended to install the components through [TektonConfig](./TektonConfig.md). - -The TektonChain CR is as below: -```yaml -apiVersion: operator.tekton.dev/v1alpha1 -kind: TektonChain -metadata: - name: chain -spec: - targetNamespace: tekton-pipelines -``` -You can install this component using [TektonConfig](./TektonConfig.md) by choosing appropriate `profile`. +TektonChain is an optional component and currently cannot be installed through TektonConfig. It has to be installed separately. + +To install TektonChain on your cluster follow steps as given below: + +- Make sure Tekton Pipelines is installed on your cluster, using the Operator. + +- Create the TektonChain CR. + + - On Kubernetes, TektonChain CR is as below: + + ```yaml + apiVersion: operator.tekton.dev/v1alpha1 + kind: TektonChain + metadata: + name: chain + spec: + targetNamespace: tekton-pipelines + ``` + + - On OpenShift, TektonChain CR is as below: + + ```yaml + apiVersion: operator.tekton.dev/v1alpha1 + kind: TektonChain + metadata: + name: chain + spec: + targetNamespace: openshift-pipelines + ``` + +- Check the status of installation using following command: + + ```sh + kubectl get tektonchains.operator.tekton.dev + ``` [chains]:https://github.com/tektoncd/chains diff --git a/docs/TektonConfig.md b/docs/TektonConfig.md index 4dddcb4149..eb9b9f0950 100644 --- a/docs/TektonConfig.md +++ b/docs/TektonConfig.md @@ -13,10 +13,10 @@ Operator provides support for installing and managing following operator compone - [TektonPipeline](./TektonPipeline.md) - [TektonTrigger](./TektonTrigger.md) -- [TektonChain](./TektonChain.md) Other than the above components depending on the platform operator also provides support for - +- On both Kubernetes and OpenShift + - [TektonChain](./TektonChain.md) - On Kubernetes - [TektonDashboard](./TekonDashboard.md) - On OpenShift @@ -74,13 +74,12 @@ By default, namespace would be `tekton-pipelines` for Kubernetes and `openshift- This allows user to choose which all components to install on the cluster. There are 3 profiles available: -- `all`: This profile will install all components (TektonPipeline, TektonTrigger and TektonChain) +- `all`: This profile will install all components (TektonPipeline and TektonTrigger) - `basic`: This profile will install only TektonPipeline and TektonTrigger component - `lite`: This profile will install only TektonPipeline component On Kubernetes, `all` profile will install `TektonDashboard` and on OpenShift `TektonAddon` will be installed. - ### Config Config provides fields to configure deployments created by the Operator. diff --git a/pkg/reconciler/kubernetes/tektonchain/controller.go b/pkg/reconciler/kubernetes/tektonchain/controller.go index 2b4076cd14..821c84eb7b 100644 --- a/pkg/reconciler/kubernetes/tektonchain/controller.go +++ b/pkg/reconciler/kubernetes/tektonchain/controller.go @@ -27,7 +27,6 @@ import ( tektonChainreconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonchain" "github.com/tektoncd/operator/pkg/reconciler/common" "k8s.io/client-go/tools/cache" - //kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/configmap" "knative.dev/pkg/controller" "knative.dev/pkg/injection" diff --git a/pkg/reconciler/shared/tektonconfig/chain/chain.go b/pkg/reconciler/shared/tektonconfig/chain/chain.go deleted file mode 100644 index 5b0786f730..0000000000 --- a/pkg/reconciler/shared/tektonconfig/chain/chain.go +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright 2022 The Tekton Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package chain - -import ( - "context" - "errors" - "fmt" - "reflect" - - "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" - op "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1" - "github.com/tektoncd/operator/pkg/reconciler/common" - apierrs "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" -) - -func EnsureTektonChainExists(ctx context.Context, clients op.TektonChainInterface, config *v1alpha1.TektonConfig) (*v1alpha1.TektonChain, error) { - tcCR, err := GetChain(ctx, clients, v1alpha1.ChainResourceName) - if err != nil { - if !apierrs.IsNotFound(err) { - return nil, err - } - // if TektonChain CR is not found in the cluster, then create one - _, err = CreateChain(ctx, clients, config) - if err != nil { - return nil, err - } - return nil, v1alpha1.RECONCILE_AGAIN_ERR - } - - // so TektonChain CR does exist in the cluster, checking if any updates are required. - // if the chain spec is changed then update the instance - tcCR, err = UpdateChain(ctx, tcCR, config, clients) - if err != nil { - return nil, err - } - - ok, err := isTektonChainReady(tcCR, err) - if err != nil { - return nil, err - } - if !ok { - return nil, v1alpha1.RECONCILE_AGAIN_ERR - } - - return tcCR, err -} - -func GetChain(ctx context.Context, clients op.TektonChainInterface, name string) (*v1alpha1.TektonChain, error) { - return clients.Get(ctx, name, metav1.GetOptions{}) -} - -func CreateChain(ctx context.Context, clients op.TektonChainInterface, config *v1alpha1.TektonConfig) (*v1alpha1.TektonChain, error) { - ownerRef := *metav1.NewControllerRef(config, config.GroupVersionKind()) - tcCR := &v1alpha1.TektonChain{ - ObjectMeta: metav1.ObjectMeta{ - Name: v1alpha1.ChainResourceName, - OwnerReferences: []metav1.OwnerReference{ownerRef}, - }, - Spec: v1alpha1.TektonChainSpec{ - CommonSpec: v1alpha1.CommonSpec{ - TargetNamespace: config.Spec.TargetNamespace, - }, - Config: config.Spec.Config, - }, - } - _, err := clients.Create(ctx, tcCR, metav1.CreateOptions{}) - if err != nil { - return nil, err - } - return tcCR, err -} - -func UpdateChain(ctx context.Context, tcCR *v1alpha1.TektonChain, config *v1alpha1.TektonConfig, clients op.TektonChainInterface) (*v1alpha1.TektonChain, error) { - // if the chain spec is changed then update the instance - updated := false - - if config.Spec.TargetNamespace != tcCR.Spec.TargetNamespace { - tcCR.Spec.TargetNamespace = config.Spec.TargetNamespace - updated = true - } - - if !reflect.DeepEqual(tcCR.Spec.Config, config.Spec.Config) { - tcCR.Spec.Config = config.Spec.Config - updated = true - } - - if tcCR.ObjectMeta.OwnerReferences == nil { - ownerRef := *metav1.NewControllerRef(config, config.GroupVersionKind()) - tcCR.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ownerRef} - updated = true - } - - if updated { - _, err := clients.Update(ctx, tcCR, metav1.UpdateOptions{}) - if err != nil { - return nil, err - } - return nil, v1alpha1.RECONCILE_AGAIN_ERR - } - return tcCR, nil -} - -// isTektonChainReady will check the status conditions of the TektonChain and return true if the TektonChain is ready. -func isTektonChainReady(s *v1alpha1.TektonChain, err error) (bool, error) { - upgradePending, errInternal := common.CheckUpgradePending(s) - if err != nil { - return false, errInternal - } - if upgradePending { - return false, v1alpha1.DEPENDENCY_UPGRADE_PENDING_ERR - } - return s.Status.IsReady(), err -} - -// TektonChainCRDelete deletes TektonChain CR to see if all resources will be deleted -func TektonChainCRDelete(ctx context.Context, clients op.TektonChainInterface, name string) error { - if _, err := GetChain(ctx, clients, v1alpha1.ChainResourceName); err != nil { - // nothing to delete if CR does not exist in the cluster - if apierrs.IsNotFound(err) { - return nil - } - return err - } - if err := clients.Delete(ctx, name, metav1.DeleteOptions{}); err != nil { - return fmt.Errorf("TektonChain %q failed to delete: %v", name, err) - } - err := wait.PollImmediate(common.Interval, common.Timeout, func() (bool, error) { - _, err := clients.Get(ctx, name, metav1.GetOptions{}) - if apierrs.IsNotFound(err) { - return true, nil - } - return false, err - }) - if err != nil { - return fmt.Errorf("Timed out waiting on TektonChain to delete %v", err) - } - return verifyNoTektonChainCR(ctx, clients) -} - -func verifyNoTektonChainCR(ctx context.Context, clients op.TektonChainInterface) error { - chains, err := clients.List(ctx, metav1.ListOptions{}) - if err != nil { - return err - } - if len(chains.Items) > 0 { - return errors.New("Unable to verify cluster-scoped resources are deleted if any TektonChain exists") - } - return nil -} - -func GetTektonConfig() *v1alpha1.TektonConfig { - return &v1alpha1.TektonConfig{ - ObjectMeta: metav1.ObjectMeta{ - Name: v1alpha1.ConfigResourceName, - }, - Spec: v1alpha1.TektonConfigSpec{ - Profile: "all", - CommonSpec: v1alpha1.CommonSpec{ - TargetNamespace: "tekton-pipelines", - }, - }, - } -} diff --git a/pkg/reconciler/shared/tektonconfig/chain/chain_test.go b/pkg/reconciler/shared/tektonconfig/chain/chain_test.go deleted file mode 100644 index e2f2e546c2..0000000000 --- a/pkg/reconciler/shared/tektonconfig/chain/chain_test.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2022 The Tekton Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package chain - -import ( - "testing" - - "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" - "github.com/tektoncd/operator/pkg/client/injection/client/fake" - util "github.com/tektoncd/operator/pkg/reconciler/common/testing" - ts "knative.dev/pkg/reconciler/testing" -) - -func TestTektonChainCreateAndDeleteCR(t *testing.T) { - ctx, _, _ := ts.SetupFakeContextWithCancel(t) - c := fake.Get(ctx) - tConfig := GetTektonConfig() - _, err := EnsureTektonChainExists(ctx, c.OperatorV1alpha1().TektonChains(), tConfig) - util.AssertNotEqual(t, err, nil) - // recheck chain creation - _, err = EnsureTektonChainExists(ctx, c.OperatorV1alpha1().TektonChains(), tConfig) - util.AssertNotEqual(t, err, nil) - err = TektonChainCRDelete(ctx, c.OperatorV1alpha1().TektonChains(), v1alpha1.ChainResourceName) - util.AssertEqual(t, err, nil) -} - -func TestTektonChainCRDelete(t *testing.T) { - ctx, _, _ := ts.SetupFakeContextWithCancel(t) - c := fake.Get(ctx) - err := TektonChainCRDelete(ctx, c.OperatorV1alpha1().TektonChains(), v1alpha1.ChainResourceName) - util.AssertEqual(t, err, nil) -} diff --git a/pkg/reconciler/shared/tektonconfig/controller.go b/pkg/reconciler/shared/tektonconfig/controller.go index bb308d29c1..66031b73f1 100644 --- a/pkg/reconciler/shared/tektonconfig/controller.go +++ b/pkg/reconciler/shared/tektonconfig/controller.go @@ -26,7 +26,6 @@ import ( mf "github.com/manifestival/manifestival" "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" operatorclient "github.com/tektoncd/operator/pkg/client/injection/client" - tektonChaininformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonchain" tektonConfiginformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonconfig" tektonInstallerinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektoninstallerset" tektonPipelineinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonpipeline" @@ -92,11 +91,6 @@ func NewExtensibleController(generator common.ExtensionGenerator) injection.Cont Handler: controller.HandleAll(impl.EnqueueControllerOf), }) - tektonChaininformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{ - FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}), - Handler: controller.HandleAll(impl.EnqueueControllerOf), - }) - tektonInstallerinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{ FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}), Handler: controller.HandleAll(impl.EnqueueControllerOf), diff --git a/pkg/reconciler/shared/tektonconfig/tektonconfig.go b/pkg/reconciler/shared/tektonconfig/tektonconfig.go index 55fdc750b4..3fa2fc5183 100644 --- a/pkg/reconciler/shared/tektonconfig/tektonconfig.go +++ b/pkg/reconciler/shared/tektonconfig/tektonconfig.go @@ -26,7 +26,6 @@ import ( clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned" tektonConfigreconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonconfig" "github.com/tektoncd/operator/pkg/reconciler/common" - "github.com/tektoncd/operator/pkg/reconciler/shared/tektonconfig/chain" "github.com/tektoncd/operator/pkg/reconciler/shared/tektonconfig/pipeline" "github.com/tektoncd/operator/pkg/reconciler/shared/tektonconfig/trigger" "k8s.io/apimachinery/pkg/api/errors" @@ -145,21 +144,6 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfi } } - // Create TektonChain CR if profile is all - if tc.Spec.Profile == v1alpha1.ProfileAll { - if _, err := chain.EnsureTektonChainExists(ctx, r.operatorClientSet.OperatorV1alpha1().TektonChains(), tc); err != nil { - tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonChain: %s", err.Error())) - r.enqueueAfter(tc, 10*time.Second) - return err - } - } else { - if err := chain.TektonChainCRDelete(ctx, r.operatorClientSet.OperatorV1alpha1().TektonChains(), v1alpha1.ChainResourceName); err != nil { - tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonChain: %s", err.Error())) - r.enqueueAfter(tc, 10*time.Second) - return err - } - } - if err := common.Prune(ctx, r.kubeClientSet, tc); err != nil { tc.Status.MarkComponentNotReady(fmt.Sprintf("tekton-resource-pruner: %s", err.Error())) logger.Error(err) diff --git a/test/e2e/common/00_tektonconfigdeployment_test.go b/test/e2e/common/00_tektonconfigdeployment_test.go index c5647275f6..ce3c6e1891 100644 --- a/test/e2e/common/00_tektonconfigdeployment_test.go +++ b/test/e2e/common/00_tektonconfigdeployment_test.go @@ -121,11 +121,6 @@ func runFeatureTest(t *testing.T, clients *utils.Clients, tc *v1alpha1.TektonCon } } - // make sure chain is created - if _, err := clients.Operator.TektonChains().Get(context.TODO(), v1alpha1.ChainResourceName, metav1.GetOptions{}); err != nil { - t.Fatalf("failed to get tektonchain") - } - // change the profile and make sure it is reflected on the cluster // ALL -> BASIC tc.Spec.Profile = v1alpha1.ProfileBasic @@ -153,11 +148,6 @@ func runFeatureTest(t *testing.T, clients *utils.Clients, tc *v1alpha1.TektonCon t.Fatalf("expected error but got nil, tektondashboard not deleted") } } - - // make sure chain is deleted - if _, err := clients.Operator.TektonChains().Get(context.TODO(), v1alpha1.ChainResourceName, metav1.GetOptions{}); err == nil { - t.Fatalf("expected error but got nil, tektonchain not deleted") - } }) t.Run("change-spec-configuration-and-validate", func(t *testing.T) {