Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor TektonConfig Reconciler and Cleanup #421

Merged
merged 3 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions pkg/apis/operator/v1alpha1/tektonaddon_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ type TektonAddonStatus struct {
AddonsInstallerSet map[string]string `json:"installerSets,omitempty"`
}

// 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 len(a.Params) == 0
}

// TektonAddonsList contains a list of TektonAddon
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TektonAddonList struct {
Expand Down
151 changes: 87 additions & 64 deletions pkg/apis/operator/v1alpha1/tektonconfig_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
nikhil-thomas marked this conversation as resolved.
Show resolved Hide resolved
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)
Comment on lines -34 to +43
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to have both ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GroupVersionKind can be removed now.. will update !

Copy link
Member Author

@sm43 sm43 Sep 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in generated code and internally in knative/pkg GroupVersionKind is used, in some transformer
GetGroupVersionKind is defined so that we can used in FilterController

tektonTriggerinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{
			FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}),
			Handler:    controller.HandleAll(impl.EnqueueControllerOf),
		})

so lets keep GroupVersionKind also
i will take a deep look and then remove

}

// 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")
}
138 changes: 49 additions & 89 deletions pkg/apis/operator/v1alpha1/tektonconfig_lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Loading