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: dashboard with new manifests structure #1065

Merged
merged 4 commits into from
Jul 2, 2024
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
2 changes: 1 addition & 1 deletion components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ can be found [here](https://github.com/opendatahub-io/opendatahub-operator/tree/
Cleanup(cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error
GetComponentName() string
GetManagementState() operatorv1.ManagementState
OverrideManifests(platform string) error
OverrideManifests(platform cluster.Platform) error
UpdatePrometheusConfig(cli client.Client, enable bool, component string) error
ConfigComponentLogger(logger logr.Logger, component string, dscispec *dsciv1.DSCInitializationSpec) logr.Logger
}
Expand Down
4 changes: 2 additions & 2 deletions components/codeflare/codeflare.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type CodeFlare struct {
components.Component `json:""`
}

func (c *CodeFlare) OverrideManifests(ctx context.Context, _ string) error {
func (c *CodeFlare) OverrideManifests(ctx context.Context, _ cluster.Platform) error {
// If devflags are set, update default manifests path
if len(c.DevFlags.Manifests) != 0 {
manifestConfig := c.DevFlags.Manifests[0]
Expand Down Expand Up @@ -76,7 +76,7 @@ func (c *CodeFlare) ReconcileComponent(ctx context.Context,
if enabled {
if c.DevFlags != nil {
// Download manifests and update paths
if err := c.OverrideManifests(ctx, string(platform)); err != nil {
if err := c.OverrideManifests(ctx, platform); err != nil {
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion components/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type ComponentInterface interface {
Cleanup(ctx context.Context, cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error
GetComponentName() string
GetManagementState() operatorv1.ManagementState
OverrideManifests(ctx context.Context, platform string) error
OverrideManifests(ctx context.Context, platform cluster.Platform) error
UpdatePrometheusConfig(cli client.Client, enable bool, component string) error
ConfigComponentLogger(logger logr.Logger, component string, dscispec *dsciv1.DSCInitializationSpec) logr.Logger
}
Expand Down
226 changes: 76 additions & 150 deletions components/dashboard/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ package dashboard

import (
"context"
"errors"
"fmt"
"path/filepath"
"strings"

"github.com/go-logr/logr"
operatorv1 "github.com/openshift/api/operator/v1"
routev1 "github.com/openshift/api/route/v1"
corev1 "k8s.io/api/core/v1"
k8serr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -20,26 +19,18 @@ import (
dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/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"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy"
)

var (
ComponentName = "dashboard"
Path = deploy.DefaultManifestPath + "/" + ComponentName + "/base" // ODH
PathISV = deploy.DefaultManifestPath + "/" + ComponentName + "/apps" // ODH APPS
PathCRDs = deploy.DefaultManifestPath + "/" + ComponentName + "/crd" // ODH + RHOAI
PathConsoleLink = deploy.DefaultManifestPath + "/" + ComponentName + "/consolelink" // ODH consolelink

ComponentNameSupported = "rhods-dashboard"
PathSupported = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/rhoai" // RHOAI
PathISVSM = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/apps/apps-onprem" // RHOAI APPS
PathISVAddOn = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/apps/apps-addon" // RHOAI APPS
PathConsoleLinkSupported = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/consolelink" // RHOAI
PathODHDashboardConfig = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/odhdashboardconfig" // RHOAI odhdashboardconfig

NameConsoleLink = "console"
NamespaceConsoleLink = "openshift-console"
ComponentNameUpstream = "dashboard"
PathUpstream = deploy.DefaultManifestPath + "/" + ComponentNameUpstream + "/odh"

ComponentNameDownstream = "rhods-dashboard"
PathDownstream = deploy.DefaultManifestPath + "/" + ComponentNameUpstream + "/rhoai"
PathSelfDownstream = PathDownstream + "/onprem"
PathManagedDownstream = PathDownstream + "/addon"
OverridePath = ""
)

// Verifies that Dashboard implements ComponentInterface.
Expand All @@ -51,37 +42,24 @@ type Dashboard struct {
components.Component `json:""`
}

func (d *Dashboard) OverrideManifests(ctx context.Context, platform string) error {
func (d *Dashboard) OverrideManifests(ctx context.Context, platform cluster.Platform) error {
// If devflags are set, update default manifests path
if len(d.DevFlags.Manifests) != 0 {
manifestConfig := d.DevFlags.Manifests[0]
if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil {
if err := deploy.DownloadManifests(ctx, ComponentNameUpstream, manifestConfig); err != nil {
return err
}
// If overlay is defined, update paths
if platform == string(cluster.ManagedRhods) || platform == string(cluster.SelfManagedRhods) {
defaultKustomizePath := "overlays/rhoai"
if manifestConfig.SourcePath != "" {
defaultKustomizePath = manifestConfig.SourcePath
}
PathSupported = filepath.Join(deploy.DefaultManifestPath, ComponentName, defaultKustomizePath)
} else {
defaultKustomizePath := "base"
if manifestConfig.SourcePath != "" {
defaultKustomizePath = manifestConfig.SourcePath
}
Path = filepath.Join(deploy.DefaultManifestPath, ComponentName, defaultKustomizePath)
if manifestConfig.SourcePath != "" {
OverridePath = filepath.Join(deploy.DefaultManifestPath, ComponentNameUpstream, manifestConfig.SourcePath)
}
}

return nil
}

func (d *Dashboard) GetComponentName() string {
return ComponentName
return ComponentNameUpstream
}

//nolint:gocyclo
func (d *Dashboard) ReconcileComponent(ctx context.Context,
cli client.Client,
logger logr.Logger,
Expand All @@ -93,54 +71,62 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context,
var l logr.Logger

if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods {
l = d.ConfigComponentLogger(logger, ComponentNameSupported, dscispec)
l = d.ConfigComponentLogger(logger, ComponentNameDownstream, dscispec)
} else {
l = d.ConfigComponentLogger(logger, ComponentName, dscispec)
l = d.ConfigComponentLogger(logger, ComponentNameUpstream, dscispec)
}

var imageParamMap = map[string]string{
"odh-dashboard-image": "RELATED_IMAGE_ODH_DASHBOARD_IMAGE",
}
entryPath := map[cluster.Platform]string{
cluster.SelfManagedRhods: PathDownstream + "/onprem",
cluster.ManagedRhods: PathDownstream + "/addon",
cluster.OpenDataHub: PathUpstream,
cluster.Unknown: PathUpstream,
}[platform]

enabled := d.GetManagementState() == operatorv1.Managed
monitoringEnabled := dscispec.Monitoring.ManagementState == operatorv1.Managed

// Update Default rolebinding
if enabled {
// Update Default rolebinding
// cleanup OAuth client related secret and CR if dashboard is in 'installed false' status
// 1. cleanup OAuth client related secret and CR if dashboard is in 'installed false' status
if err := d.cleanOauthClient(ctx, cli, dscispec, currentComponentExist, l); err != nil {
return err
}
if d.DevFlags != nil {
// Download manifests and update paths
if err := d.OverrideManifests(ctx, string(platform)); err != nil {
if err := d.OverrideManifests(ctx, platform); err != nil {
return err
}
}
// 1. Deploy CRDs
if err := d.deployCRDsForPlatform(ctx, cli, owner, dscispec.ApplicationsNamespace, platform); err != nil {
return fmt.Errorf("failed to deploy Dashboard CRD: %w", err)
if OverridePath != "" {
entryPath = OverridePath
}
}

// 2. platform specific RBAC
if platform == cluster.OpenDataHub || platform == "" {
err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "odh-dashboard")
if err != nil {
if err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "odh-dashboard"); err != nil {
return err
}
}

if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods {
err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "rhods-dashboard")
if err != nil {
} else {
if err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "rhods-dashboard"); err != nil {
return err
}
}

// 3. Update image parameters
var imageParamMap = map[string]string{
"odh-dashboard-image": "RELATED_IMAGE_ODH_DASHBOARD_IMAGE",
}

// 4. Append or Update variable for component to consume
extraParamsMap, err := updateKustomizeVariable(ctx, cli, platform, dscispec)
if err != nil {
return errors.New("failed to set variable for extraParamsMap")
}

// 5. update params.env
if (dscispec.DevFlags == nil || dscispec.DevFlags.ManifestsUri == "") && (d.DevFlags == nil || len(d.DevFlags.Manifests) == 0) {
if err := deploy.ApplyParams(PathSupported, imageParamMap, false); err != nil {
return fmt.Errorf("failed to update image from %s : %w", PathSupported, err)
if err := deploy.ApplyParams(entryPath, imageParamMap, false, extraParamsMap); err != nil {
return fmt.Errorf("failed to update params.env from %s : %w", entryPath, err)
}
}
}
Expand All @@ -153,32 +139,23 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context,
if err := cluster.CreateSecret(ctx, cli, "anaconda-ce-access", dscispec.ApplicationsNamespace); err != nil {
return fmt.Errorf("failed to create access-secret for anaconda: %w", err)
}
// overlay which including ../../base + anaconda-ce-validator
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathSupported, dscispec.ApplicationsNamespace, ComponentNameSupported, enabled); err != nil {
return fmt.Errorf("failed to apply manifests from %s: %w", PathSupported, err)
}

// Apply RHOAI specific configs, e.g anaconda screct and cronjob and ISV
if err := d.applyRHOAISpecificConfigs(ctx, cli, owner, dscispec.ApplicationsNamespace, platform); err != nil {
return err
}
// consolelink
if err := d.deployConsoleLink(ctx, cli, owner, platform, dscispec.ApplicationsNamespace, ComponentNameSupported); err != nil {
return err
// Deploy RHOAI manifests
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, entryPath, dscispec.ApplicationsNamespace, ComponentNameDownstream, enabled); err != nil {
return fmt.Errorf("failed to apply manifests from %s: %w", PathDownstream, err)
}
l.Info("apply manifests done")

// CloudService Monitoring handling
if platform == cluster.ManagedRhods {
if enabled {
// first check if the service is up, so prometheus won't fire alerts when it is just startup
if err := cluster.WaitForDeploymentAvailable(ctx, cli, ComponentNameSupported, dscispec.ApplicationsNamespace, 20, 3); err != nil {
return fmt.Errorf("deployment for %s is not ready to server: %w", ComponentName, err)
if err := cluster.WaitForDeploymentAvailable(ctx, cli, ComponentNameDownstream, dscispec.ApplicationsNamespace, 20, 3); err != nil {
return fmt.Errorf("deployment for %s is not ready to server: %w", ComponentNameDownstream, err)
}
l.Info("deployment is done, updating monitoring rules")
}

if err := d.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentNameSupported); err != nil {
if err := d.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentNameDownstream); err != nil {
return err
}
if err := deploy.DeployManifestsFromPath(ctx, cli, owner,
Expand All @@ -190,99 +167,48 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context,
l.Info("updating SRE monitoring done")
}
return nil

default:
// base
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil {
return err
}
// ISV
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathISV, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil {
return err
}
// consolelink
if err := d.deployConsoleLink(ctx, cli, owner, platform, dscispec.ApplicationsNamespace, ComponentName); err != nil {
// Deploy ODH manifests
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, entryPath, dscispec.ApplicationsNamespace, ComponentNameUpstream, enabled); err != nil {
return err
}
l.Info("apply manifests done")
return nil
}
}

func (d *Dashboard) deployCRDsForPlatform(ctx context.Context, cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error {
componentName := ComponentName
if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods {
componentName = ComponentNameSupported
}
// we only deploy CRD, we do not remove CRD
return deploy.DeployManifestsFromPath(ctx, cli, owner, PathCRDs, namespace, componentName, true)
}

func (d *Dashboard) applyRHOAISpecificConfigs(ctx context.Context, cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error {
enabled := d.ManagementState == operatorv1.Managed

// set proper group name
dashboardConfig := filepath.Join(PathODHDashboardConfig, "odhdashboardconfig.yaml")
func updateKustomizeVariable(ctx context.Context, cli client.Client, platform cluster.Platform, dscispec *dsciv1.DSCInitializationSpec) (map[string]string, error) {
adminGroups := map[cluster.Platform]string{
cluster.SelfManagedRhods: "rhods-admins",
cluster.ManagedRhods: "dedicated-admins",
cluster.OpenDataHub: "odh-admins",
cluster.Unknown: "odh-admins",
}[platform]

if err := common.ReplaceStringsInFile(dashboardConfig, map[string]string{"<admin_groups>": adminGroups}); err != nil {
return err
}
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathODHDashboardConfig, namespace, ComponentNameSupported, enabled); err != nil {
return fmt.Errorf("failed to create OdhDashboardConfig from %s: %w", PathODHDashboardConfig, err)
}
// ISV
path := PathISVSM
if platform == cluster.ManagedRhods {
path = PathISVAddOn
}
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, path, namespace, ComponentNameSupported, enabled); err != nil {
return fmt.Errorf("failed to set dashboard ISV from %s : %w", Path, err)
}
return nil
}

func (d *Dashboard) deployConsoleLink(ctx context.Context, cli client.Client, owner metav1.Object, platform cluster.Platform, namespace, componentName string) error {
var manifestsPath, sectionTitle, routeName string
switch platform {
case cluster.SelfManagedRhods:
sectionTitle = "OpenShift Self Managed Services"
manifestsPath = PathConsoleLinkSupported
routeName = componentName
case cluster.ManagedRhods:
sectionTitle = "OpenShift Managed Services"
manifestsPath = PathConsoleLinkSupported
routeName = componentName
default:
sectionTitle = "OpenShift Open Data Hub"
manifestsPath = PathConsoleLink
routeName = "odh-dashboard"
}

pathConsoleLink := filepath.Join(manifestsPath, "consolelink.yaml")

consoleRoute := &routev1.Route{}
if err := cli.Get(ctx, client.ObjectKey{Name: NameConsoleLink, Namespace: NamespaceConsoleLink}, consoleRoute); err != nil {
return fmt.Errorf("error getting console route URL %s : %w", NameConsoleLink, err)
}

domainIndex := strings.Index(consoleRoute.Spec.Host, ".")
consoleLinkDomain := consoleRoute.Spec.Host[domainIndex+1:]
if err := common.ReplaceStringsInFile(pathConsoleLink, map[string]string{
"<dashboard-url>": "https://" + routeName + "-" + namespace + "." + consoleLinkDomain,
"<section-title>": sectionTitle,
}); err != nil {
return fmt.Errorf("error replacing with correct dashboard URL for consolelink : %w", err)
}
sectionTitle := map[cluster.Platform]string{
cluster.SelfManagedRhods: "OpenShift Self Managed Services",
cluster.ManagedRhods: "OpenShift Managed Services",
cluster.OpenDataHub: "OpenShift Open Data Hub",
cluster.Unknown: "OpenShift Open Data Hub",
}[platform]

enabled := d.ManagementState == operatorv1.Managed
if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathConsoleLink, namespace, componentName, enabled); err != nil {
return fmt.Errorf("failed to set dashboard consolelink %s : %w", pathConsoleLink, err)
consoleLinkDomain, err := cluster.GetDomain(ctx, cli)
if err != nil {
return nil, fmt.Errorf("error getting console route URL %s : %w", consoleLinkDomain, err)
}
consoleURL := map[cluster.Platform]string{
cluster.SelfManagedRhods: "https://rhods-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain,
cluster.ManagedRhods: "https://rhods-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain,
cluster.OpenDataHub: "https://odh-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain,
cluster.Unknown: "https://odh-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain,
}[platform]

return nil
return map[string]string{
"admin_groups": adminGroups,
"dashboard-url": consoleURL,
"section-title": sectionTitle,
}, nil
}

func (d *Dashboard) cleanOauthClient(ctx context.Context, cli client.Client, dscispec *dsciv1.DSCInitializationSpec, currentComponentExist bool, l logr.Logger) error {
Expand Down
4 changes: 2 additions & 2 deletions components/datasciencepipelines/datasciencepipelines.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type DataSciencePipelines struct {
components.Component `json:""`
}

func (d *DataSciencePipelines) OverrideManifests(ctx context.Context, _ string) error {
func (d *DataSciencePipelines) OverrideManifests(ctx context.Context, _ cluster.Platform) error {
// If devflags are set, update default manifests path
if len(d.DevFlags.Manifests) != 0 {
manifestConfig := d.DevFlags.Manifests[0]
Expand Down Expand Up @@ -97,7 +97,7 @@ func (d *DataSciencePipelines) ReconcileComponent(ctx context.Context,
if enabled {
if d.DevFlags != nil {
// Download manifests and update paths
if err := d.OverrideManifests(ctx, string(platform)); err != nil {
if err := d.OverrideManifests(ctx, platform); err != nil {
return err
}
}
Expand Down
Loading
Loading