From fbfcf17f3d8d67ec29b38863a9e84161d1cc6d33 Mon Sep 17 00:00:00 2001 From: Shivam Mukhade Date: Fri, 24 Sep 2021 09:35:12 +0530 Subject: [PATCH] Updates TektonConfig Conditions and cleanup This updates the tektonconfig conditions and removes unnecessary code. Signed-off-by: Shivam Mukhade --- .../operator/v1alpha1/tektonaddon_types.go | 4 +- .../v1alpha1/tektonconfig_lifecycle.go | 151 ++++++++++-------- .../v1alpha1/tektonconfig_lifecycle_test.go | 138 ++++++---------- .../operator/v1alpha1/tektonconfig_types.go | 24 +-- .../v1alpha1/zz_generated.deepcopy.go | 5 - .../kubernetes/tektonconfig/extension.go | 9 +- .../openshift/tektonconfig/extension.go | 38 +---- pkg/reconciler/openshift/tektonconfig/rbac.go | 2 - .../shared/tektonconfig/controller.go | 42 +---- .../shared/tektonconfig/instance.go | 6 +- .../shared/tektonconfig/tektonconfig.go | 87 ++++------ 11 files changed, 183 insertions(+), 323 deletions(-) diff --git a/pkg/apis/operator/v1alpha1/tektonaddon_types.go b/pkg/apis/operator/v1alpha1/tektonaddon_types.go index 54814d9b83..3a93c29d84 100644 --- a/pkg/apis/operator/v1alpha1/tektonaddon_types.go +++ b/pkg/apis/operator/v1alpha1/tektonaddon_types.go @@ -17,8 +17,6 @@ limitations under the License. package v1alpha1 import ( - "reflect" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" duckv1 "knative.dev/pkg/apis/duck/v1" ) @@ -75,7 +73,7 @@ type Addon struct { } func (a Addon) IsEmpty() bool { - return reflect.DeepEqual(a, Addon{}) + return len(a.Params) == 0 } // TektonAddonsList contains a list of TektonAddon diff --git a/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle.go b/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle.go index 56fb73cbe4..722a557805 100644 --- a/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle.go +++ b/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle.go @@ -21,107 +21,130 @@ import ( "knative.dev/pkg/apis" ) -var ( - _ TektonComponentStatus = (*TektonConfigStatus)(nil) +const ( + PreInstall apis.ConditionType = "PreInstall" + ComponentsReady apis.ConditionType = "ComponentsReady" + PostInstall apis.ConditionType = "PostInstall" +) +var ( configCondSet = apis.NewLivingConditionSet( - DependenciesInstalled, - DeploymentsAvailable, - InstallSucceeded, + PreInstall, + ComponentsReady, + PostInstall, ) ) -// GroupVersionKind returns SchemeGroupVersion of a TektonConfig -func (tp *TektonConfig) GroupVersionKind() schema.GroupVersionKind { +func (tc *TektonConfig) GroupVersionKind() schema.GroupVersionKind { return SchemeGroupVersion.WithKind(KindTektonConfig) } -// GetCondition returns the current condition of a given condition type -func (tps *TektonConfigStatus) GetCondition(t apis.ConditionType) *apis.Condition { - return configCondSet.Manage(tps).GetCondition(t) +func (tc *TektonConfig) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind(KindTektonConfig) } -// InitializeConditions initializes conditions of an TektonConfigStatus -func (tps *TektonConfigStatus) InitializeConditions() { - configCondSet.Manage(tps).InitializeConditions() +func (tcs *TektonConfigStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return configCondSet.Manage(tcs).GetCondition(t) } -// IsReady looks at the conditions returns true if they are all true. -func (tps *TektonConfigStatus) IsReady() bool { - return configCondSet.Manage(tps).IsHappy() +func (tcs *TektonConfigStatus) InitializeConditions() { + configCondSet.Manage(tcs).InitializeConditions() } -// MarkInstallSucceeded marks the InstallationSucceeded status as true. -func (tps *TektonConfigStatus) MarkInstallSucceeded() { - configCondSet.Manage(tps).MarkTrue(InstallSucceeded) - if tps.GetCondition(DependenciesInstalled).IsUnknown() { - // Assume deps are installed if we're not sure - tps.MarkDependenciesInstalled() - } +func (tcs *TektonConfigStatus) IsReady() bool { + return configCondSet.Manage(tcs).IsHappy() } -// MarkInstallFailed marks the InstallationSucceeded status as false with the given -// message. -func (tps *TektonConfigStatus) MarkInstallFailed(msg string) { - configCondSet.Manage(tps).MarkFalse( - InstallSucceeded, - "Error", - "Install failed with message: %s", msg) +func (tcs *TektonConfigStatus) MarkPreInstallComplete() { + configCondSet.Manage(tcs).MarkTrue(PreInstall) } -// MarkDeploymentsAvailable marks the DeploymentsAvailable status as true. -func (tps *TektonConfigStatus) MarkDeploymentsAvailable() { - configCondSet.Manage(tps).MarkTrue(DeploymentsAvailable) +func (tcs *TektonConfigStatus) MarkComponentsReady() { + configCondSet.Manage(tcs).MarkTrue(ComponentsReady) } -// MarkDeploymentsNotReady marks the DeploymentsAvailable status as false and calls out -// it's waiting for deployments. -func (tps *TektonConfigStatus) MarkDeploymentsNotReady() { - configCondSet.Manage(tps).MarkFalse( - DeploymentsAvailable, - "NotReady", - "Waiting on deployments") +func (tcs *TektonConfigStatus) MarkPostInstallComplete() { + configCondSet.Manage(tcs).MarkTrue(PostInstall) } -// MarkDependenciesInstalled marks the DependenciesInstalled status as true. -func (tps *TektonConfigStatus) MarkDependenciesInstalled() { - configCondSet.Manage(tps).MarkTrue(DependenciesInstalled) +func (tcs *TektonConfigStatus) MarkNotReady(msg string) { + configCondSet.Manage(tcs).MarkFalse( + apis.ConditionReady, + "Error", + "Ready: %s", msg) } -// MarkDependencyInstalling marks the DependenciesInstalled status as false with the -// given message. -func (tps *TektonConfigStatus) MarkDependencyInstalling(msg string) { - configCondSet.Manage(tps).MarkFalse( - DependenciesInstalled, - "Installing", - "Dependency installing: %s", msg) +func (tcs *TektonConfigStatus) MarkPreInstallFailed(msg string) { + tcs.MarkNotReady("PreReconciliation failed") + configCondSet.Manage(tcs).MarkFalse( + PreInstall, + "Error", + "PreReconciliation failed with message: %s", msg) } -// MarkDependencyMissing marks the DependenciesInstalled status as false with the -// given message. -func (tps *TektonConfigStatus) MarkDependencyMissing(msg string) { - configCondSet.Manage(tps).MarkFalse( - DependenciesInstalled, +func (tcs *TektonConfigStatus) MarkComponentNotReady(msg string) { + tcs.MarkNotReady("Components not ready") + configCondSet.Manage(tcs).MarkFalse( + ComponentsReady, "Error", - "Dependency missing: %s", msg) + "Components not in ready state: %s", msg) +} + +func (tcs *TektonConfigStatus) MarkPostInstallFailed(msg string) { + tcs.MarkNotReady("PostReconciliation failed") + configCondSet.Manage(tcs).MarkFalse( + PostInstall, + "Error", + "PostReconciliation failed with message: %s", msg) } // GetVersion gets the currently installed version of the component. -func (tps *TektonConfigStatus) GetVersion() string { - return tps.Version +func (tcs *TektonConfigStatus) GetVersion() string { + return tcs.Version } // SetVersion sets the currently installed version of the component. -func (tps *TektonConfigStatus) SetVersion(version string) { - tps.Version = version +func (tcs *TektonConfigStatus) SetVersion(version string) { + tcs.Version = version } +// TODO: below methods are not required for TektonConfig +// but as extension implements TektonComponent we need to defined them +// this will be removed + // GetManifests gets the url links of the manifests. -func (tps *TektonConfigStatus) GetManifests() []string { - return tps.Manifests +func (tcs *TektonConfigStatus) GetManifests() []string { + return []string{} } // SetVersion sets the url links of the manifests. -func (tps *TektonConfigStatus) SetManifests(manifests []string) { - tps.Manifests = manifests +func (tcs *TektonConfigStatus) SetManifests(manifests []string) { +} + +func (tcs *TektonConfigStatus) MarkInstallSucceeded() { + panic("implement me") +} + +func (tcs *TektonConfigStatus) MarkInstallFailed(msg string) { + panic("implement me") +} + +func (tcs *TektonConfigStatus) MarkDeploymentsAvailable() { + panic("implement me") +} + +func (tcs *TektonConfigStatus) MarkDeploymentsNotReady() { + panic("implement me") +} + +func (tcs *TektonConfigStatus) MarkDependenciesInstalled() { + panic("implement me") +} + +func (tcs *TektonConfigStatus) MarkDependencyInstalling(msg string) { + panic("implement me") +} + +func (tcs *TektonConfigStatus) MarkDependencyMissing(msg string) { + panic("implement me") } diff --git a/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle_test.go b/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle_test.go index 3c1b120473..7dc35ea6ba 100644 --- a/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle_test.go +++ b/pkg/apis/operator/v1alpha1/tektonconfig_lifecycle_test.go @@ -30,109 +30,69 @@ func TestTektonConfigGroupVersionKind(t *testing.T) { Version: SchemaVersion, Kind: KindTektonConfig, } - if got := r.GroupVersionKind(); got != want { + if got := r.GetGroupVersionKind(); got != want { t.Errorf("got: %v, want: %v", got, want) } } func TestTektonConfigHappyPath(t *testing.T) { - tp := &TektonConfigStatus{} - tp.InitializeConditions() - - apistest.CheckConditionOngoing(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionOngoing(tp, InstallSucceeded, t) - - // Install succeeds. - tp.MarkInstallSucceeded() - // Dependencies are assumed successful too. - apistest.CheckConditionSucceeded(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) - - // Deployments are not available at first. - tp.MarkDeploymentsNotReady() - apistest.CheckConditionSucceeded(tp, DependenciesInstalled, t) - apistest.CheckConditionFailed(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) - if ready := tp.IsReady(); ready { - t.Errorf("tp.IsReady() = %v, want false", ready) - } + tc := &TektonConfigStatus{} + tc.InitializeConditions() + + apistest.CheckConditionOngoing(tc, PreInstall, t) + apistest.CheckConditionOngoing(tc, ComponentsReady, t) + apistest.CheckConditionOngoing(tc, PostInstall, t) + + // Pre install completes execution + tc.MarkPreInstallComplete() + apistest.CheckConditionSucceeded(tc, PreInstall, t) + + // Components and then PostInstall completes and we're good. + tc.MarkComponentsReady() + apistest.CheckConditionSucceeded(tc, ComponentsReady, t) - // Deployments become ready and we're good. - tp.MarkDeploymentsAvailable() - apistest.CheckConditionSucceeded(tp, DependenciesInstalled, t) - apistest.CheckConditionSucceeded(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) - if ready := tp.IsReady(); !ready { - t.Errorf("tp.IsReady() = %v, want true", ready) + tc.MarkPostInstallComplete() + apistest.CheckConditionSucceeded(tc, PostInstall, t) + + if ready := tc.IsReady(); !ready { + t.Errorf("tc.IsReady() = %v, want true", ready) } + } func TestTektonConfigErrorPath(t *testing.T) { - tp := &TektonConfigStatus{} - tp.InitializeConditions() - - apistest.CheckConditionOngoing(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionOngoing(tp, InstallSucceeded, t) - - // Install fails. - tp.MarkInstallFailed("test") - apistest.CheckConditionOngoing(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionFailed(tp, InstallSucceeded, t) - - // Dependencies are installing. - tp.MarkDependencyInstalling("testing") - apistest.CheckConditionFailed(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionFailed(tp, InstallSucceeded, t) - - // Install now succeeds. - tp.MarkInstallSucceeded() - apistest.CheckConditionFailed(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) - if ready := tp.IsReady(); ready { - t.Errorf("tp.IsReady() = %v, want false", ready) - } + tc := &TektonConfigStatus{} + tc.InitializeConditions() - // Deployments become ready - tp.MarkDeploymentsAvailable() - apistest.CheckConditionFailed(tp, DependenciesInstalled, t) - apistest.CheckConditionSucceeded(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) - if ready := tp.IsReady(); ready { - t.Errorf("tp.IsReady() = %v, want false", ready) - } + apistest.CheckConditionOngoing(tc, PreInstall, t) + apistest.CheckConditionOngoing(tc, ComponentsReady, t) + apistest.CheckConditionOngoing(tc, PostInstall, t) - // Finally, dependencies become available. - tp.MarkDependenciesInstalled() - apistest.CheckConditionSucceeded(tp, DependenciesInstalled, t) - apistest.CheckConditionSucceeded(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) - if ready := tp.IsReady(); !ready { - t.Errorf("tp.IsReady() = %v, want true", ready) - } -} + // Pre install completes execution + tc.MarkPreInstallComplete() + apistest.CheckConditionSucceeded(tc, PreInstall, t) -func TestTektonConfigExternalDependency(t *testing.T) { - tp := &TektonConfigStatus{} - tp.InitializeConditions() + // ComponentsReady is not ready when components are not in ready state + tc.MarkComponentNotReady("waiting for component") + apistest.CheckConditionFailed(tc, ComponentsReady, t) - // External marks dependency as failed. - tp.MarkDependencyMissing("test") + // ComponentsReady and then PostInstall become ready and we're good. + tc.MarkComponentsReady() + apistest.CheckConditionSucceeded(tc, ComponentsReady, t) - // Install succeeds. - tp.MarkInstallSucceeded() - apistest.CheckConditionFailed(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) + tc.MarkPostInstallComplete() + apistest.CheckConditionSucceeded(tc, PostInstall, t) + + if ready := tc.IsReady(); !ready { + t.Errorf("tc.IsReady() = %v, want true", ready) + } + + // In further reconciliation component might fail + + tc.MarkComponentNotReady("pipeline not ready") + apistest.CheckConditionFailed(tc, ComponentsReady, t) + if ready := tc.IsReady(); ready { + t.Errorf("tc.IsReady() = %v, want false", ready) + } - // Dependencies are now ready. - tp.MarkDependenciesInstalled() - apistest.CheckConditionSucceeded(tp, DependenciesInstalled, t) - apistest.CheckConditionOngoing(tp, DeploymentsAvailable, t) - apistest.CheckConditionSucceeded(tp, InstallSucceeded, t) } diff --git a/pkg/apis/operator/v1alpha1/tektonconfig_types.go b/pkg/apis/operator/v1alpha1/tektonconfig_types.go index ba7dac5db5..4e47d4ef81 100644 --- a/pkg/apis/operator/v1alpha1/tektonconfig_types.go +++ b/pkg/apis/operator/v1alpha1/tektonconfig_types.go @@ -24,11 +24,6 @@ import ( duckv1 "knative.dev/pkg/apis/duck/v1" ) -var ( - _ TektonComponent = (*TektonConfig)(nil) - _ TektonComponentSpec = (*TektonConfigSpec)(nil) -) - // TektonConfig is the Schema for the TektonConfigs API // +genclient // +genreconciler:krshapedlogic=false @@ -95,13 +90,13 @@ type TektonConfigSpec struct { type TektonConfigStatus struct { duckv1.Status `json:",inline"` - // The version of the installed release + // The profile installed // +optional - Version string `json:"version,omitempty"` + Profile string `json:"profile,omitempty"` - // The url links of the manifests, separated by comma + // The version of the installed release // +optional - Manifests []string `json:"manifests,omitempty"` + Version string `json:"version,omitempty"` } // TektonConfigList contains a list of TektonConfig @@ -112,17 +107,6 @@ type TektonConfigList struct { Items []TektonConfig `json:"items"` } -// Addon defines the field to customize Addon component -type Addon struct { - // Params is the list of params passed for Addon customization - // +optional - Params []Param `json:"params,omitempty"` -} - -func (a Addon) IsEmpty() bool { - return reflect.DeepEqual(a, Addon{}) -} - type Config struct { NodeSelector map[string]string `json:"nodeSelector,omitempty"` Tolerations []corev1.Toleration `json:"tolerations,omitempty"` diff --git a/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go index fa0f031415..42f5f7fcb7 100644 --- a/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go @@ -505,11 +505,6 @@ func (in *TektonConfigSpec) DeepCopy() *TektonConfigSpec { func (in *TektonConfigStatus) DeepCopyInto(out *TektonConfigStatus) { *out = *in in.Status.DeepCopyInto(&out.Status) - if in.Manifests != nil { - in, out := &in.Manifests, &out.Manifests - *out = make([]string, len(*in)) - copy(*out, *in) - } return } diff --git a/pkg/reconciler/kubernetes/tektonconfig/extension.go b/pkg/reconciler/kubernetes/tektonconfig/extension.go index 76b5a5c55b..75132d759a 100644 --- a/pkg/reconciler/kubernetes/tektonconfig/extension.go +++ b/pkg/reconciler/kubernetes/tektonconfig/extension.go @@ -25,7 +25,6 @@ import ( operatorclient "github.com/tektoncd/operator/pkg/client/injection/client" "github.com/tektoncd/operator/pkg/reconciler/common" "github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektonconfig/extension" - "k8s.io/apimachinery/pkg/api/errors" ) func KubernetesExtension(ctx context.Context) common.Extension { @@ -52,13 +51,7 @@ func (oe kubernetesExtension) PostReconcile(ctx context.Context, comp v1alpha1.T } if configInstance.Spec.Profile == common.ProfileLite || configInstance.Spec.Profile == common.ProfileBasic { - err := extension.TektonDashboardCRDelete(oe.operatorClientSet.OperatorV1alpha1().TektonDashboards(), common.DashboardResourceName) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } + return extension.TektonDashboardCRDelete(oe.operatorClientSet.OperatorV1alpha1().TektonDashboards(), common.DashboardResourceName) } return nil diff --git a/pkg/reconciler/openshift/tektonconfig/extension.go b/pkg/reconciler/openshift/tektonconfig/extension.go index d6491c3b20..7cf46571f1 100644 --- a/pkg/reconciler/openshift/tektonconfig/extension.go +++ b/pkg/reconciler/openshift/tektonconfig/extension.go @@ -20,8 +20,6 @@ import ( "context" "os" - "github.com/go-logr/zapr" - mfc "github.com/manifestival/client-go-client" mf "github.com/manifestival/manifestival" "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" "github.com/tektoncd/operator/pkg/client/clientset/versioned" @@ -30,14 +28,10 @@ import ( "github.com/tektoncd/operator/pkg/reconciler/openshift/tektonconfig/extension" openshiftPipeline "github.com/tektoncd/operator/pkg/reconciler/openshift/tektonpipeline" openshiftTrigger "github.com/tektoncd/operator/pkg/reconciler/openshift/tektontrigger" - "go.uber.org/zap" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" kubeclient "knative.dev/pkg/client/injection/kube/client" - "knative.dev/pkg/injection" - "knative.dev/pkg/logging" ) const ( @@ -45,30 +39,15 @@ const ( ) func OpenShiftExtension(ctx context.Context) common.Extension { - - logger := logging.FromContext(ctx) - mfclient, err := mfc.NewClient(injection.GetConfig(ctx)) - if err != nil { - logger.Fatalw("error creating client from injected config", zap.Error(err)) - } - mflogger := zapr.NewLogger(logger.Named("manifestival").Desugar()) - manifest, err := mf.ManifestFrom(mf.Slice{}, mf.UseClient(mfclient), mf.UseLogger(mflogger)) - if err != nil { - logger.Fatalw("error creating initial manifest", zap.Error(err)) - } - ext := openshiftExtension{ + return openshiftExtension{ operatorClientSet: operatorclient.Get(ctx), kubeClientSet: kubeclient.Get(ctx), - manifest: manifest, } - - return ext } type openshiftExtension struct { operatorClientSet versioned.Interface kubeClientSet kubernetes.Interface - manifest mf.Manifest } func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Transformer { @@ -88,7 +67,6 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.Tekto r := rbac{ kubeClientSet: oe.kubeClientSet, operatorClientSet: oe.operatorClientSet, - manifest: oe.manifest, ownerRef: configOwnerRef(tc), version: os.Getenv(versionKey), } @@ -97,27 +75,21 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.Tekto func (oe openshiftExtension) PostReconcile(ctx context.Context, comp v1alpha1.TektonComponent) error { configInstance := comp.(*v1alpha1.TektonConfig) - if configInstance.Spec.Profile == common.ProfileAll { + if configInstance.Spec.Profile == v1alpha1.ProfileAll { if err := extension.CreateAddonCR(comp, oe.operatorClientSet.OperatorV1alpha1()); err != nil { return err } } - if configInstance.Spec.Profile == common.ProfileBasic || configInstance.Spec.Profile == common.ProfileLite { - err := extension.TektonAddonCRDelete(oe.operatorClientSet.OperatorV1alpha1().TektonAddons(), common.AddonResourceName) - if err != nil { - if errors.IsNotFound(err) { - return nil - } - return err - } + if configInstance.Spec.Profile == v1alpha1.ProfileBasic || configInstance.Spec.Profile == v1alpha1.ProfileLite { + return extension.TektonAddonCRDelete(oe.operatorClientSet.OperatorV1alpha1().TektonAddons(), common.AddonResourceName) } return nil } func (oe openshiftExtension) Finalize(ctx context.Context, comp v1alpha1.TektonComponent) error { configInstance := comp.(*v1alpha1.TektonConfig) - if configInstance.Spec.Profile == common.ProfileAll { + if configInstance.Spec.Profile == v1alpha1.ProfileAll { if err := extension.TektonAddonCRDelete(oe.operatorClientSet.OperatorV1alpha1().TektonAddons(), common.AddonResourceName); err != nil { return err } diff --git a/pkg/reconciler/openshift/tektonconfig/rbac.go b/pkg/reconciler/openshift/tektonconfig/rbac.go index 4d1c527e1a..7b1816930f 100644 --- a/pkg/reconciler/openshift/tektonconfig/rbac.go +++ b/pkg/reconciler/openshift/tektonconfig/rbac.go @@ -21,7 +21,6 @@ import ( "fmt" "regexp" - mf "github.com/manifestival/manifestival" clientset "github.com/tektoncd/operator/pkg/client/clientset/versioned" "github.com/tektoncd/operator/pkg/reconciler/common" corev1 "k8s.io/api/core/v1" @@ -50,7 +49,6 @@ var nsRegex = regexp.MustCompile(common.NamespaceIgnorePattern) type rbac struct { kubeClientSet kubernetes.Interface operatorClientSet clientset.Interface - manifest mf.Manifest ownerRef metav1.OwnerReference version string } diff --git a/pkg/reconciler/shared/tektonconfig/controller.go b/pkg/reconciler/shared/tektonconfig/controller.go index 4aed1e80ec..4767caba9d 100644 --- a/pkg/reconciler/shared/tektonconfig/controller.go +++ b/pkg/reconciler/shared/tektonconfig/controller.go @@ -20,9 +20,6 @@ import ( "context" "os" - "github.com/go-logr/zapr" - mfc "github.com/manifestival/client-go-client" - mf "github.com/manifestival/manifestival" "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" operatorclient "github.com/tektoncd/operator/pkg/client/injection/client" tektonConfiginformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonconfig" @@ -30,10 +27,8 @@ import ( tektonTriggerinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektontrigger" tektonConfigreconciler "github.com/tektoncd/operator/pkg/client/injection/reconciler/operator/v1alpha1/tektonconfig" "github.com/tektoncd/operator/pkg/reconciler/common" - "go.uber.org/zap" "k8s.io/client-go/tools/cache" kubeclient "knative.dev/pkg/client/injection/kube/client" - deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment" "knative.dev/pkg/configmap" "knative.dev/pkg/controller" "knative.dev/pkg/injection" @@ -43,53 +38,32 @@ import ( // NewExtensibleController returns a controller extended to a specific platform func NewExtensibleController(generator common.ExtensionGenerator) injection.ControllerConstructor { return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl { - tektonConfigInformer := tektonConfiginformer.Get(ctx) - tektonPipelineInformer := tektonPipelineinformer.Get(ctx) - tektonTriggerInformer := tektonTriggerinformer.Get(ctx) - deploymentInformer := deploymentinformer.Get(ctx) - kubeClient := kubeclient.Get(ctx) logger := logging.FromContext(ctx) - mfclient, err := mfc.NewClient(injection.GetConfig(ctx)) - if err != nil { - logger.Fatalw("Error creating client from injected config", zap.Error(err)) - } - mflogger := zapr.NewLogger(logger.Named("manifestival").Desugar()) - manifest, err := mf.ManifestFrom(mf.Slice{}, mf.UseClient(mfclient), mf.UseLogger(mflogger)) - if err != nil { - logger.Fatalw("Error creating initial manifest", zap.Error(err)) - } - c := &Reconciler{ - kubeClientSet: kubeClient, + kubeClientSet: kubeclient.Get(ctx), operatorClientSet: operatorclient.Get(ctx), extension: generator(ctx), - manifest: manifest, } impl := tektonConfigreconciler.NewImpl(ctx, c) - logger.Info("Setting up event handlers") + logger.Info("Setting up event handlers for TektonConfig") - tektonConfigInformer.Informer().AddEventHandler(controller.HandleAll(impl.Enqueue)) - - tektonPipelineInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ - FilterFunc: controller.FilterControllerGVK(v1alpha1.SchemeGroupVersion.WithKind("TektonConfig")), - Handler: controller.HandleAll(impl.EnqueueControllerOf), - }) + tektonConfiginformer.Get(ctx).Informer().AddEventHandler(controller.HandleAll(impl.Enqueue)) - tektonTriggerInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ - FilterFunc: controller.FilterControllerGVK(v1alpha1.SchemeGroupVersion.WithKind("TektonConfig")), + tektonPipelineinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}), Handler: controller.HandleAll(impl.EnqueueControllerOf), }) - deploymentInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ - FilterFunc: controller.FilterControllerGVK(v1alpha1.SchemeGroupVersion.WithKind("TektonConfig")), + tektonTriggerinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}), Handler: controller.HandleAll(impl.EnqueueControllerOf), }) if os.Getenv("AUTOINSTALL_COMPONENTS") == "true" { // try to ensure that there is an instance of tektonConfig - newTektonConfig(operatorclient.Get(ctx), kubeclient.Get(ctx), manifest).ensureInstance(ctx) + newTektonConfig(operatorclient.Get(ctx), kubeclient.Get(ctx)).ensureInstance(ctx) } return impl diff --git a/pkg/reconciler/shared/tektonconfig/instance.go b/pkg/reconciler/shared/tektonconfig/instance.go index 590c889c54..990e363e4e 100644 --- a/pkg/reconciler/shared/tektonconfig/instance.go +++ b/pkg/reconciler/shared/tektonconfig/instance.go @@ -21,7 +21,6 @@ import ( "os" "time" - mf "github.com/manifestival/manifestival" "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" "github.com/tektoncd/operator/pkg/client/clientset/versioned" "github.com/tektoncd/operator/pkg/reconciler/common" @@ -48,17 +47,14 @@ const ( type tektonConfig struct { operatorClientSet versioned.Interface kubeClientSet kubernetes.Interface - manifest mf.Manifest namespace string } -func newTektonConfig(operatorClientSet versioned.Interface, kubeClientSet kubernetes.Interface, - manifest mf.Manifest) tektonConfig { +func newTektonConfig(operatorClientSet versioned.Interface, kubeClientSet kubernetes.Interface) tektonConfig { return tektonConfig{ operatorClientSet: operatorClientSet, kubeClientSet: kubeClientSet, - manifest: manifest, namespace: os.Getenv("DEFAULT_TARGET_NAMESPACE"), } } diff --git a/pkg/reconciler/shared/tektonconfig/tektonconfig.go b/pkg/reconciler/shared/tektonconfig/tektonconfig.go index 927690bbae..bc5ba5953f 100644 --- a/pkg/reconciler/shared/tektonconfig/tektonconfig.go +++ b/pkg/reconciler/shared/tektonconfig/tektonconfig.go @@ -20,17 +20,13 @@ import ( "context" "fmt" - mf "github.com/manifestival/manifestival" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" 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/pipeline" "github.com/tektoncd/operator/pkg/reconciler/shared/tektonconfig/trigger" + "k8s.io/client-go/kubernetes" "knative.dev/pkg/logging" pkgreconciler "knative.dev/pkg/reconciler" ) @@ -41,11 +37,6 @@ type Reconciler struct { kubeClientSet kubernetes.Interface // operatorClientSet allows us to configure operator objects operatorClientSet clientset.Interface - // manifest is empty, but with a valid client and logger. all - // manifests are immutable, and any created during reconcile are - // expected to be appended to this one, obviating the passing of - // client & logger - manifest mf.Manifest // Platform-specific behavior to affect the transform extension common.Extension } @@ -58,20 +49,7 @@ var _ tektonConfigreconciler.Finalizer = (*Reconciler)(nil) func (r *Reconciler) FinalizeKind(ctx context.Context, original *v1alpha1.TektonConfig) pkgreconciler.Event { logger := logging.FromContext(ctx) - // List all TektonConfigs to determine if cluster-scoped resources should be deleted. - tps, err := r.operatorClientSet.OperatorV1alpha1().TektonConfigs().List(ctx, metav1.ListOptions{}) - if err != nil { - return fmt.Errorf("failed to list all TektonConfigs: %w", err) - } - - for _, tp := range tps.Items { - if tp.GetDeletionTimestamp().IsZero() { - // Not deleting all TektonPipelines. Nothing to do here. - return nil - } - } - - if original.Spec.Profile == common.ProfileLite { + if original.Spec.Profile == v1alpha1.ProfileLite { return pipeline.TektonPipelineCRDelete(r.operatorClientSet.OperatorV1alpha1().TektonPipelines(), common.PipelineResourceName) } else { // TektonPipeline and TektonTrigger is common for profile type basic and all @@ -95,7 +73,6 @@ func (r *Reconciler) FinalizeKind(ctx context.Context, original *v1alpha1.Tekton func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfig) pkgreconciler.Event { logger := logging.FromContext(ctx) tc.Status.InitializeConditions() - tc.Status.ObservedGeneration = tc.Generation logger.Infow("Reconciling TektonConfig", "status", tc.Status) if tc.GetName() != common.ConfigResourceName { @@ -104,65 +81,55 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tc *v1alpha1.TektonConfi tc.GetName(), ) logger.Error(msg) - tc.GetStatus().MarkInstallFailed(msg) + tc.Status.MarkNotReady(msg) return nil } tc.SetDefaults(ctx) if err := r.extension.PreReconcile(ctx, tc); err != nil { - // If prereconcile updates the TektonConfig CR, it returns an error + // If pre-reconcile updates the TektonConfig CR, it returns an error // to reconcile if err.Error() == "reconcile" { return err } - tc.GetStatus().MarkInstallFailed(err.Error()) + tc.Status.MarkPreInstallFailed(err.Error()) return err } - var stages common.Stages - if tc.Spec.Profile == common.ProfileLite { - err := trigger.TektonTriggerCRDelete(r.operatorClientSet.OperatorV1alpha1().TektonTriggers(), common.TriggerResourceName) - if err != nil { - if errors.IsNotFound(err) { - return nil - } + tc.Status.MarkPreInstallComplete() + + // Create TektonPipeline CR + if err := pipeline.CreatePipelineCR(tc, r.operatorClientSet.OperatorV1alpha1()); err != nil { + tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonPipeline: %s", err.Error())) + return err + } + + // Create TektonTrigger CR if the profile is all or basic + if tc.Spec.Profile == v1alpha1.ProfileAll || tc.Spec.Profile == v1alpha1.ProfileBasic { + if err := trigger.CreateTriggerCR(tc, r.operatorClientSet.OperatorV1alpha1()); err != nil { + tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonTrigger: %s", err.Error())) return err } - stages = common.Stages{ - r.createPipelineCR, - } } else { - // TektonPipeline and TektonTrigger is common for profile type basic and all - stages = common.Stages{ - r.createPipelineCR, - r.createTriggerCR, + if err := trigger.TektonTriggerCRDelete(r.operatorClientSet.OperatorV1alpha1().TektonTriggers(), common.TriggerResourceName); err != nil { + tc.Status.MarkComponentNotReady(fmt.Sprintf("TektonTrigger: %s", err.Error())) + return err } } - manifest := r.manifest.Append() - if err := stages.Execute(ctx, &manifest, tc); err != nil { - tc.GetStatus().MarkInstallFailed(err.Error()) - return err + if err := common.Prune(r.kubeClientSet, ctx, tc); err != nil { + logger.Error(err) } + + tc.Status.MarkComponentsReady() + if err := r.extension.PostReconcile(ctx, tc); err != nil { - tc.GetStatus().MarkInstallFailed(err.Error()) + tc.Status.MarkPostInstallFailed(err.Error()) return err } - if err := common.Prune(r.kubeClientSet, ctx, tc); err != nil { - logger.Error(err) - } + tc.Status.MarkPostInstallComplete() - tc.Status.MarkInstallSucceeded() - tc.Status.MarkDeploymentsAvailable() return nil } - -func (r *Reconciler) createPipelineCR(ctx context.Context, manifest *mf.Manifest, comp v1alpha1.TektonComponent) error { - return pipeline.CreatePipelineCR(comp, r.operatorClientSet.OperatorV1alpha1()) -} - -func (r *Reconciler) createTriggerCR(ctx context.Context, manifest *mf.Manifest, comp v1alpha1.TektonComponent) error { - return trigger.CreateTriggerCR(comp, r.operatorClientSet.OperatorV1alpha1()) -}