Skip to content

Commit

Permalink
Add Results configuration in tekton config
Browse files Browse the repository at this point in the history
This will add the Results configuration to the tekton config and will be
installed by default through tekton config

Signed-off-by: Shiv Verma <[email protected]>
  • Loading branch information
pratap0007 committed Nov 26, 2024
1 parent 40d62eb commit 7fda76f
Show file tree
Hide file tree
Showing 12 changed files with 484 additions and 8 deletions.
1 change: 1 addition & 0 deletions pkg/apis/operator/v1alpha1/tektonconfig_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func (tc *TektonConfig) SetDefaults(ctx context.Context) {
tc.Spec.Pipeline.setDefaults()
tc.Spec.Trigger.setDefaults()
tc.Spec.Chain.setDefaults()
tc.Spec.Result.setDefaults()

if IsOpenShiftPlatform() {
if tc.Spec.Platforms.OpenShift.PipelinesAsCode == nil {
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/operator/v1alpha1/tektonconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ type TektonConfigSpec struct {
// Chain holds the customizable option for chains component
// +optional
Chain Chain `json:"chain,omitempty"`
// Result holds the customize option for results component
// +optional
Result Result `json:"result,omitempty"`
// Dashboard holds the customizable options for dashboards component
// +optional
Dashboard Dashboard `json:"dashboard,omitempty"`
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/operator/v1alpha1/tektonconfig_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func (tc *TektonConfig) Validate(ctx context.Context) (errs *apis.FieldError) {
errs = errs.Also(tc.Spec.Dashboard.Options.validate("spec.dashboard.options"))
errs = errs.Also(tc.Spec.Chain.Options.validate("spec.chain.options"))
errs = errs.Also(tc.Spec.Trigger.Options.validate("spec.trigger.options"))
errs = errs.Also(tc.Spec.Result.Options.validate("spec.result.options"))

return errs.Also(tc.Spec.Trigger.TriggersProperties.validate("spec.trigger"))
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/operator/v1alpha1/tektonresult_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ func (tp *TektonResult) SetDefaults(ctx context.Context) {
tp.Spec.TLSHostnameOverride = ""
}
}

// Sets default values of Result
func (c *Result) setDefaults() {
// TODO: Set the other default values for Result
}
9 changes: 9 additions & 0 deletions pkg/apis/operator/v1alpha1/tektonresult_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ type LokiStackProperties struct {
LokiStackNamespace string `json:"loki_stack_namespace,omitempty"`
}

// Result defines the field to customize Result component
type Result struct {
// enable or disable Result Component
Disabled bool `json:"disabled"`
TektonResultSpec `json:",inline"`
// Options holds additions fields and these fields will be updated on the manifests
Options AdditionalOptions `json:"options"`
}

// ResultsAPIProperties defines the fields which are configurable for
// Results API server config
type ResultsAPIProperties struct {
Expand Down
15 changes: 15 additions & 0 deletions pkg/reconciler/kubernetes/tektoninstallerset/client/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,18 @@ func (i *InstallerSetClient) ListCustomSet(ctx context.Context, labelSelector st
}
return is, nil
}

// ListPreSet return the lists of Pre sets with the provided labelSelector
func (i *InstallerSetClient) ListPreSet(ctx context.Context, labelSelector string) (*v1alpha1.TektonInstallerSetList, error) {
logger := logging.FromContext(ctx)
logger.Debugf("%v: checking installer sets with labels: %v", i.resourceKind, labelSelector)

is, err := i.clientSet.List(ctx, v1.ListOptions{LabelSelector: labelSelector})
if err != nil {
return nil, err
}
if len(is.Items) == 0 {
logger.Debugf("%v: no installer sets found with labels: %v", i.resourceKind, labelSelector)
}
return is, nil
}
87 changes: 79 additions & 8 deletions pkg/reconciler/kubernetes/tektonresult/tektonresult.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package tektonresult

import (
"context"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"

Expand Down Expand Up @@ -145,12 +147,24 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tr *v1alpha1.TektonResul
return errors.New(errMsg)
}

// check if the secrets are created
// TODO: Create secret automatically if they don't exist
// TODO: And remove this check in future release.
if err := r.validateSecretsAreCreated(ctx, tr); err != nil {
return err
// If external database is not set then create default DB otherwise validate it
if !tr.Spec.IsExternalDB {
if err := r.createDBSecret(ctx, tr); err != nil {
return err
}
} else {
if err := r.validateSecretsAreCreated(ctx, tr, DbSecretName); err != nil {
return err
}
}

// Validated TLS Secret for kubernetes platform
if !v1alpha1.IsOpenShiftPlatform() {
if err := r.validateSecretsAreCreated(ctx, tr, TlsSecretName); err != nil {
return err
}
}

tr.Status.MarkDependenciesInstalled()

if err := r.extension.PreReconcile(ctx, tr); err != nil {
Expand Down Expand Up @@ -314,17 +328,74 @@ func (r *Reconciler) updateTektonResultsStatus(ctx context.Context, tr *v1alpha1
}

// TektonResults expects secrets to be created before installing
func (r *Reconciler) validateSecretsAreCreated(ctx context.Context, tr *v1alpha1.TektonResult) error {
func (r *Reconciler) validateSecretsAreCreated(ctx context.Context, tr *v1alpha1.TektonResult, secretName string) error {
logger := logging.FromContext(ctx)
_, err := r.kubeClientSet.CoreV1().Secrets(tr.Spec.TargetNamespace).Get(ctx, DbSecretName, metav1.GetOptions{})
_, err := r.kubeClientSet.CoreV1().Secrets(tr.Spec.TargetNamespace).Get(ctx, secretName, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
logger.Error(err)
tr.Status.MarkDependencyMissing(fmt.Sprintf("%s secret is missing", DbSecretName))
tr.Status.MarkDependencyMissing(fmt.Sprintf("%s secret is missing", secretName))
return err
}
logger.Error(err)
return err
}
return nil
}

// Generate the DB secret
func (r *Reconciler) getDBSecret(name string, namespace string, tr *v1alpha1.TektonResult) *corev1.Secret {
s := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
OwnerReferences: []metav1.OwnerReference{getOwnerRef(tr)},
},
Type: corev1.SecretTypeOpaque,
StringData: map[string]string{},
}
password, _ := generateRandomBaseString(20)
s.StringData["POSTGRES_PASSWORD"] = password
s.StringData["POSTGRES_USER"] = "result"
return s
}

// Create Result default database
func (r *Reconciler) createDBSecret(ctx context.Context, tr *v1alpha1.TektonResult) error {
logger := logging.FromContext(ctx)

// Get the DB secret, if not found then create the DB secret
_, err := r.kubeClientSet.CoreV1().Secrets(tr.Spec.TargetNamespace).Get(ctx, DbSecretName, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
// If not found then create DB secret with default data
newDBSecret := r.getDBSecret(DbSecretName, tr.Spec.TargetNamespace, tr)
_, err := r.kubeClientSet.CoreV1().Secrets(tr.Spec.TargetNamespace).Create(ctx, newDBSecret, metav1.CreateOptions{})
if err != nil {
logger.Error(err)
tr.Status.MarkDependencyMissing(fmt.Sprintf("Default db %s creation is failing", DbSecretName))
return err
}
}
}
return nil
}

// Get an owner reference of Tekton Result
func getOwnerRef(tr *v1alpha1.TektonResult) metav1.OwnerReference {
return *metav1.NewControllerRef(tr, tr.GroupVersionKind())
}

func generateRandomBaseString(size int) (string, error) {
bytes := make([]byte, size)

// Generate random bytes
_, err := rand.Read(bytes)
if err != nil {
return "", err
}
// Encode the random bytes into a Base64 string
base64String := base64.StdEncoding.EncodeToString(bytes)

return base64String, nil
}
32 changes: 32 additions & 0 deletions pkg/reconciler/openshift/tektonresult/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import (
"github.com/tektoncd/operator/pkg/reconciler/common"
"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektoninstallerset/client"
occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common"
"github.com/tektoncd/operator/pkg/reconciler/shared/hash"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
"knative.dev/pkg/logging"
Expand Down Expand Up @@ -110,6 +112,36 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.Tekto
mf = *oe.internalDBManifest
}

preSetLabel := metav1.LabelSelector{
MatchLabels: map[string]string{
v1alpha1.CreatedByKey: "TektonResult",
v1alpha1.InstallerSetType: "pre",
},
}
preSetLabelSelector, err := common.LabelSelector(preSetLabel)
if err != nil {
return err
}
preSetList, err := oe.installerSetClient.ListPreSet(ctx, preSetLabelSelector)
if err != nil {
return err
}
for _, is := range preSetList.Items {
// compute TektonResult Spec
expectedSpecHash, err := hash.Compute(result.Spec)
if err != nil {
return err
}
// delete the preset installersets if spec hash been changed
if expectedSpecHash != is.Annotations[v1alpha1.LastAppliedHashKey] {
if err := oe.installerSetClient.CleanupPreSet(ctx); err != nil {
return err
}

}

}

if (result.Spec.LokiStackName != "" && result.Spec.LokiStackNamespace != "") ||
strings.EqualFold(result.Spec.LogsType, "LOKI") {
mf = mf.Append(*oe.logsRBACManifest)
Expand Down
8 changes: 8 additions & 0 deletions pkg/reconciler/shared/tektonconfig/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
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"
tektonResultinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonresult"
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"
Expand Down Expand Up @@ -105,6 +106,13 @@ func NewExtensibleController(generator common.ExtensionGenerator) injection.Cont
logger.Panicf("Couldn't register TektonChain informer event handler: %w", err)
}

if _, err := tektonResultinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
}); err != nil {
logger.Panicf("Couldn't register TektonResult informer event handler: %w", err)
}

if _, err := tektonInstallerinformer.Get(ctx).Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: controller.FilterController(&v1alpha1.TektonConfig{}),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
Expand Down
Loading

0 comments on commit 7fda76f

Please sign in to comment.