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

feat: enhances FeatureTracker with spec #17

Merged
Merged
Show file tree
Hide file tree
Changes from 12 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
26 changes: 19 additions & 7 deletions apis/features/v1/features_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ type FeatureTracker struct {
Status FeatureTrackerStatus `json:"status,omitempty"`
}

type OwnerType string

const (
ConditionPhaseFeatureCreated = "FeatureCreated"
ConditionPhasePreConditions = "FeaturePreConditions"
ConditionPhaseResourceCreation = "ResourceCreation"
ConditionPhaseLoadTemplateData = "LoadTemplateData"
ConditionPhaseProcessTemplates = "ProcessTemplates"
ConditionPhaseApplyManifests = "ApplyManifests"
ConditionPhasePostConditions = "FeaturePostConditions"
ConditionPhaseFeatureCreated = "FeatureCreated"
ConditionPhasePreConditions = "FeaturePreConditions"
ConditionPhaseResourceCreation = "ResourceCreation"
ConditionPhaseLoadTemplateData = "LoadTemplateData"
ConditionPhaseProcessTemplates = "ProcessTemplates"
ConditionPhaseApplyManifests = "ApplyManifests"
ConditionPhasePostConditions = "FeaturePostConditions"
ComponentType OwnerType = "Component"
DSCIType OwnerType = "DSCI"
)

func (s *FeatureTracker) ToOwnerReference() metav1.OwnerReference {
Expand All @@ -40,8 +44,16 @@ func (s *FeatureTracker) ToOwnerReference() metav1.OwnerReference {
}
}

// Origin describes the type of object that created the related Feature to this FeatureTracker.
type Origin struct {
Type OwnerType `json:"type,omitempty"`
Name string `json:"name,omitempty"`
}

// FeatureTrackerSpec defines the desired state of FeatureTracker.
type FeatureTrackerSpec struct {
Origin Origin `json:"origin,omitempty"`
AppNamespace string `json:"appNamespace,omitempty"`
}

// FeatureTrackerStatus defines the observed state of FeatureTracker.
Expand Down
15 changes: 13 additions & 2 deletions components/dashboard/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1"
featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
"github.com/opendatahub-io/opendatahub-operator/v2/components"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/common"
Expand Down Expand Up @@ -158,7 +159,12 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context,
return err
}

if err := d.configureServiceMesh(cli, owner, dscispec); err != nil {
origin := featurev1.Origin{
Type: featurev1.ComponentType,
Name: d.GetComponentName(),
}

if err := d.configureServiceMesh(cli, owner, dscispec, origin); err != nil {
return err
}

Expand Down Expand Up @@ -217,7 +223,12 @@ func (d *Dashboard) Cleanup(cli client.Client, dscispec *dsciv1.DSCInitializatio
}

if shouldConfigureServiceMesh {
serviceMeshInitializer := feature.NewFeaturesInitializer(dscispec, d.defineServiceMeshFeatures(dscispec))
origin := featurev1.Origin{
Type: featurev1.ComponentType,
Name: d.GetComponentName(),
}

serviceMeshInitializer := feature.NewFeaturesInitializer(dscispec, d.defineServiceMeshFeatures(dscispec, origin))

if err := serviceMeshInitializer.Prepare(); err != nil {
return err
Expand Down
9 changes: 5 additions & 4 deletions components/dashboard/servicemesh_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,21 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

dsci "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1"
featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature/servicemesh"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/gvr"
)

func (d *Dashboard) configureServiceMesh(cli client.Client, owner metav1.Object, dscispec *dsci.DSCInitializationSpec) error {
func (d *Dashboard) configureServiceMesh(cli client.Client, owner metav1.Object, dscispec *dsci.DSCInitializationSpec, origin featurev1.Origin) error {
shouldConfigureServiceMesh, err := deploy.ShouldConfigureServiceMesh(cli, dscispec)
if err != nil {
return err
}

if shouldConfigureServiceMesh {
serviceMeshInitializer := feature.NewFeaturesInitializer(dscispec, d.defineServiceMeshFeatures(dscispec))
serviceMeshInitializer := feature.NewFeaturesInitializer(dscispec, d.defineServiceMeshFeatures(dscispec, origin))

if err := serviceMeshInitializer.Prepare(); err != nil {
return err
Expand All @@ -40,10 +41,10 @@ func (d *Dashboard) configureServiceMesh(cli client.Client, owner metav1.Object,
return nil
}

func (d *Dashboard) defineServiceMeshFeatures(dscispec *dsci.DSCInitializationSpec) feature.DefinedFeatures {
func (d *Dashboard) defineServiceMeshFeatures(dscispec *dsci.DSCInitializationSpec, origin featurev1.Origin) feature.DefinedFeatures {
return func(s *feature.FeaturesInitializer) error {
createMeshResources, err := feature.CreateFeature("dashboard-create-service-mesh-routing-resources").
For(dscispec).
For(dscispec, origin).
Manifests(
path.Join(feature.ControlPlaneDir, "components", d.GetComponentName()),
).
Expand Down
23 changes: 20 additions & 3 deletions components/kserve/kserve.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"

dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1"
featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
"github.com/opendatahub-io/opendatahub-operator/v2/components"
infrav1 "github.com/opendatahub-io/opendatahub-operator/v2/infrastructure/v1"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster"
Expand Down Expand Up @@ -185,9 +186,17 @@ func (k *Kserve) configureServerless(instance *dsciv1.DSCInitializationSpec) err
case operatorv1.Managed: // standard workflow to create CR
switch instance.ServiceMesh.ManagementState {
case operatorv1.Unmanaged, operatorv1.Removed:
return fmt.Errorf("ServiceMesh is need to set to 'Managaed' in DSCI CR, it is required by KServe serving field")
return fmt.Errorf("ServiceMesh is need to set to 'Managed' in DSCI CR, it is required by KServe serving field")
}
serverlessInitializer := feature.NewFeaturesInitializer(instance, k.configureServerlessFeatures)
origin := featurev1.Origin{
Type: featurev1.ComponentType,
Name: k.GetComponentName(),
}
configureServerless := func(s *feature.FeaturesInitializer) error {
return k.configureServerlessFeatures(s, origin)
}

serverlessInitializer := feature.NewFeaturesInitializer(instance, configureServerless)

Choose a reason for hiding this comment

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

How about aligning it to how it's done in dashboard.go?

That would mean:

		origin := featurev1.Origin{
			Type: featurev1.ComponentType,
			Name: k.GetComponentName(),
		}
		serverlessInitializer := feature.NewFeaturesInitializer(instance, k.configureServerlessFeatures(instance, origin))

and chaging configureServerlessFeatures to:

func (k *Kserve) configureServerlessFeatures(dscispec *dsci.DSCInitializationSpec, origin featurev1.Origin) feature.DefinedFeatures {
	return func(initializer *feature.FeaturesInitializer) error {
		// old code
	}
}


if err := serverlessInitializer.Prepare(); err != nil {
return err
Expand All @@ -201,7 +210,15 @@ func (k *Kserve) configureServerless(instance *dsciv1.DSCInitializationSpec) err
}

func (k *Kserve) removeServerlessFeatures(instance *dsciv1.DSCInitializationSpec) error {
serverlessInitializer := feature.NewFeaturesInitializer(instance, k.configureServerlessFeatures)
origin := featurev1.Origin{
Type: featurev1.ComponentType,
Name: k.GetComponentName(),
}
configureServerless := func(s *feature.FeaturesInitializer) error {
return k.configureServerlessFeatures(s, origin)
}

serverlessInitializer := feature.NewFeaturesInitializer(instance, configureServerless)

if err := serverlessInitializer.Prepare(); err != nil {
return err
Expand Down
7 changes: 4 additions & 3 deletions components/kserve/serverless_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package kserve
import (
"path"

featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature/serverless"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature/servicemesh"
Expand All @@ -14,9 +15,9 @@ const (
templatesDir = "templates/serverless"
)

func (k *Kserve) configureServerlessFeatures(s *feature.FeaturesInitializer) error {
func (k *Kserve) configureServerlessFeatures(s *feature.FeaturesInitializer, origin featurev1.Origin) error {
servingDeployment, err := feature.CreateFeature("serverless-serving-deployment").
For(s.DSCInitializationSpec).
For(s.DSCInitializationSpec, origin).
Manifests(
path.Join(templatesDir, "serving-install"),
).
Expand All @@ -37,7 +38,7 @@ func (k *Kserve) configureServerlessFeatures(s *feature.FeaturesInitializer) err
s.Features = append(s.Features, servingDeployment)

servingIstioGateways, err := feature.CreateFeature("serverless-serving-gateways").
For(s.DSCInitializationSpec).
For(s.DSCInitializationSpec, origin).
PreConditions(
// Check serverless is installed
feature.WaitForResourceToBeCreated(knativeServingNamespace, gvr.KnativeServing),
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/features.opendatahub.io_featuretrackers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ spec:
type: object
spec:
description: FeatureTrackerSpec defines the desired state of FeatureTracker.
properties:
appNamespace:
type: string
origin:
description: Origin describes the type of object that created the
related Feature to this FeatureTracker.
properties:
name:
type: string
type:
type: string
type: object
type: object
status:
description: FeatureTrackerStatus defines the observed state of FeatureTracker.
Expand Down
38 changes: 27 additions & 11 deletions controllers/dscinitialization/servicemesh_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import (
corev1 "k8s.io/api/core/v1"

dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1"
featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature/servicemesh"
)

func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
func defineServiceMeshFeatures(f *feature.FeaturesInitializer, origin featurev1.Origin) error {
serviceMeshSpec := f.ServiceMesh

smcpCreation, errSmcp := feature.CreateFeature("service-mesh-control-plane-creation").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
Manifests(
path.Join(feature.ControlPlaneDir, "base", "control-plane.tmpl"),
).
Expand All @@ -35,7 +36,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {

if serviceMeshSpec.ControlPlane.MetricsCollection == "Istio" {
metricsCollection, errMetrics := feature.CreateFeature("service-mesh-monitoring").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
Manifests(
path.Join(feature.MonitoringDir),
).
Expand All @@ -51,7 +52,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
}

if oauth, err := feature.CreateFeature("service-mesh-control-plane-configure-oauth").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
Manifests(
path.Join(feature.ControlPlaneDir, "base"),
path.Join(feature.ControlPlaneDir, "oauth"),
Expand Down Expand Up @@ -79,7 +80,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
}

if cfMaps, err := feature.CreateFeature("shared-config-maps").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
WithResources(servicemesh.ConfigMaps).
Load(); err != nil {
return err
Expand All @@ -88,7 +89,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
}

if serviceMesh, err := feature.CreateFeature("app-add-namespace-to-service-mesh").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
Manifests(
path.Join(feature.ControlPlaneDir, "smm.tmpl"),
path.Join(feature.ControlPlaneDir, "namespace.patch.tmpl"),
Expand All @@ -101,7 +102,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
}

if gatewayRoute, err := feature.CreateFeature("service-mesh-create-gateway-route").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
Manifests(
path.Join(feature.ControlPlaneDir, "routing"),
).
Expand All @@ -116,7 +117,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
}

if dataScienceProjects, err := feature.CreateFeature("app-migrate-data-science-projects").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
WithResources(servicemesh.MigratedDataScienceProjects).
Load(); err != nil {
return err
Expand All @@ -125,7 +126,7 @@ func defineServiceMeshFeatures(f *feature.FeaturesInitializer) error {
}

if extAuthz, err := feature.CreateFeature("service-mesh-control-plane-setup-external-authorization").
For(f.DSCInitializationSpec).
For(f.DSCInitializationSpec, origin).
Manifests(
path.Join(feature.AuthDir, "auth-smm.tmpl"),
path.Join(feature.AuthDir, "base"),
Expand Down Expand Up @@ -168,7 +169,15 @@ func (r *DSCInitializationReconciler) configureServiceMesh(instance *dsciv1.DSCI

switch instance.Spec.ServiceMesh.ManagementState {
case operatorv1.Managed:
serviceMeshInitializer := feature.NewFeaturesInitializer(&instance.Spec, defineServiceMeshFeatures)
origin := featurev1.Origin{
Type: featurev1.DSCIType,
Name: instance.Name,
}
defineServiceMesh := func(s *feature.FeaturesInitializer) error {
return defineServiceMeshFeatures(s, origin)
}

serviceMeshInitializer := feature.NewFeaturesInitializer(&instance.Spec, defineServiceMesh)

Choose a reason for hiding this comment

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

Same as for kserve.go

if err := serviceMeshInitializer.Prepare(); err != nil {
r.Log.Error(err, "failed configuring service mesh resources")
r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "failed configuring service mesh resources")
Expand All @@ -195,8 +204,15 @@ func (r *DSCInitializationReconciler) configureServiceMesh(instance *dsciv1.DSCI
func (r *DSCInitializationReconciler) removeServiceMesh(instance *dsciv1.DSCInitialization) error {
// on condition of Managed, do not handle Removed when set to Removed it tigger DSCI reconcile to cleanup
if instance.Spec.ServiceMesh.ManagementState == operatorv1.Managed {
serviceMeshInitializer := feature.NewFeaturesInitializer(&instance.Spec, defineServiceMeshFeatures)
origin := featurev1.Origin{
Type: featurev1.DSCIType,
Name: instance.Name,
}
defineServiceMesh := func(s *feature.FeaturesInitializer) error {
return defineServiceMeshFeatures(s, origin)
}

serviceMeshInitializer := feature.NewFeaturesInitializer(&instance.Spec, defineServiceMesh)
if err := serviceMeshInitializer.Prepare(); err != nil {
r.Log.Error(err, "failed configuring service mesh resources")
r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "failed configuring service mesh resources")
Expand Down
4 changes: 3 additions & 1 deletion pkg/feature/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client/config"

v1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1"
featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
infrav1 "github.com/opendatahub-io/opendatahub-operator/v2/infrastructure/v1"
)

Expand All @@ -26,12 +27,13 @@ func CreateFeature(name string) *featureBuilder {
return &featureBuilder{name: name}
}

func (fb *featureBuilder) For(spec *v1.DSCInitializationSpec) *featureBuilder {
func (fb *featureBuilder) For(spec *v1.DSCInitializationSpec, origin featurev1.Origin) *featureBuilder {
createSpec := func(f *Feature) error {
f.Spec = &Spec{
AppNamespace: spec.ApplicationsNamespace,
ServiceMeshSpec: &spec.ServiceMesh,
Serving: &infrav1.ServingSpec{},
Origin: &origin,
}

return nil
Expand Down
4 changes: 4 additions & 0 deletions pkg/feature/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ func (f *Feature) createFeatureTracker() error {
ObjectMeta: metav1.ObjectMeta{
Name: f.Spec.AppNamespace + "-" + common.TrimToRFC1123Name(f.Name),
},
Spec: featurev1.FeatureTrackerSpec{
Origin: *f.Spec.Origin,
AppNamespace: f.Spec.AppNamespace,
},
}

foundTracker, err := f.DynamicClient.Resource(gvr.FeatureTracker).Get(context.TODO(), tracker.Name, metav1.GetOptions{})
Expand Down
1 change: 1 addition & 0 deletions pkg/feature/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type Spec struct {
KnativeCertificateSecret string
KnativeIngressDomain string
Tracker *featurev1.FeatureTracker
Origin *featurev1.Origin
}

type OAuth struct {
Expand Down
10 changes: 10 additions & 0 deletions tests/envtestutil/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"os"
"path/filepath"

featurev1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/features/v1"
)

func FindProjectRoot() (string, error) {
Expand All @@ -27,3 +29,11 @@ func FindProjectRoot() (string, error) {

return "", fmt.Errorf("project root not found")
}

// NewOrigin creates an origin object with specified component and name
func NewOrigin(component featurev1.OwnerType, name string) featurev1.Origin {
return featurev1.Origin{
Type: component,
Name: name,
}
}
Loading
Loading