diff --git a/cli/cmd/install.go b/cli/cmd/install.go index cfe5cf355..35367e723 100644 --- a/cli/cmd/install.go +++ b/cli/cmd/install.go @@ -8,6 +8,7 @@ import ( "github.com/odigos-io/odigos/cli/pkg/autodetect" "github.com/odigos-io/odigos/common/consts" + "github.com/odigos-io/odigos/profiles" "github.com/odigos-io/odigos/cli/pkg/labels" @@ -186,7 +187,7 @@ func createNamespace(ctx context.Context, cmd *cobra.Command, client *kube.Clien func validateUserInputProfiles(tier common.OdigosTier) { // Fetch available profiles for the given tier - availableProfiles := resources.GetAvailableProfilesForTier(tier) + availableProfiles := profiles.GetAvailableProfilesForTier(tier) // Create a map for fast lookups of valid profile names profileMap := make(map[string]struct{}) diff --git a/cli/cmd/profile.go b/cli/cmd/profile.go index eeb056793..d7f4e9e8d 100644 --- a/cli/cmd/profile.go +++ b/cli/cmd/profile.go @@ -9,6 +9,7 @@ import ( cmdcontext "github.com/odigos-io/odigos/cli/pkg/cmd_context" "github.com/odigos-io/odigos/common" "github.com/odigos-io/odigos/k8sutils/pkg/getters" + "github.com/odigos-io/odigos/profiles" "github.com/odigos-io/odigos/profiles/profile" "github.com/spf13/cobra" ) @@ -44,7 +45,7 @@ var profileCmd = &cobra.Command{ if availableFlag { fmt.Println("Listing available profiles for", currentTier, "tier:") - profiles := resources.GetAvailableProfilesForTier(currentTier) + profiles := profiles.GetAvailableProfilesForTier(currentTier) if len(profiles) == 0 { fmt.Println("No profiles are available for the current tier") os.Exit(0) @@ -102,7 +103,7 @@ var addProfileCmd = &cobra.Command{ } // Fetch the available profiles for the current tier - profiles := resources.GetAvailableProfilesForTier(currentTier) + profiles := profiles.GetAvailableProfilesForTier(currentTier) var selectedProfile *profile.Profile // Search for the specified profile in the available profiles diff --git a/cli/cmd/resources/instrumentor.go b/cli/cmd/resources/instrumentor.go index 78454e7c0..7b51f077e 100644 --- a/cli/cmd/resources/instrumentor.go +++ b/cli/cmd/resources/instrumentor.go @@ -12,7 +12,6 @@ import ( "github.com/odigos-io/odigos/common/consts" k8sconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" - k8sutilsconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -291,7 +290,7 @@ func NewMutatingWebhookConfiguration(ns string, caBundle []byte) *admissionregis TimeoutSeconds: intPtr(10), ObjectSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - k8sutilsconsts.OdigosInjectInstrumentationLabel: "true", + k8sconsts.OdigosInjectInstrumentationLabel: "true", }, }, AdmissionReviewVersions: []string{ @@ -406,7 +405,7 @@ func NewInstrumentorDeployment(ns string, version string, telemetryEnabled bool, ValueFrom: &corev1.EnvVarSource{ ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: k8sutilsconsts.OdigosDeploymentConfigMapName, + Name: k8sconsts.OdigosDeploymentConfigMapName, }, Key: k8sconsts.OdigosDeploymentConfigMapTierKey, }, diff --git a/cli/cmd/resources/profiles.go b/cli/cmd/resources/profiles.go index 18a126141..badb75c07 100644 --- a/cli/cmd/resources/profiles.go +++ b/cli/cmd/resources/profiles.go @@ -13,7 +13,7 @@ import ( ) func GetResourcesForProfileName(profileName common.ProfileName, tier common.OdigosTier) ([]profile.K8sObject, error) { - allAvailableProfiles := GetAvailableProfilesForTier(tier) + allAvailableProfiles := profiles.GetAvailableProfilesForTier(tier) for _, p := range allAvailableProfiles { if p.ProfileName == common.ProfileName(profileName) { if p.KubeObject != nil { @@ -38,17 +38,6 @@ func GetResourcesForProfileName(profileName common.ProfileName, tier common.Odig return nil, nil } -func GetAvailableProfilesForTier(odigosTier common.OdigosTier) []profile.Profile { - switch odigosTier { - case common.CommunityOdigosTier: - return profiles.CommunityProfiles - case common.OnPremOdigosTier: - return profiles.OnPremProfiles - default: - return []profile.Profile{} - } -} - type profilesResourceManager struct { client *kube.Client ns string diff --git a/cli/cmd/resources/scheduler.go b/cli/cmd/resources/scheduler.go index 3861b4731..9c1501909 100644 --- a/cli/cmd/resources/scheduler.go +++ b/cli/cmd/resources/scheduler.go @@ -8,6 +8,7 @@ import ( "github.com/odigos-io/odigos/cli/pkg/kube" "github.com/odigos-io/odigos/common" "github.com/odigos-io/odigos/common/consts" + k8sconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -230,6 +231,17 @@ func NewSchedulerDeployment(ns string, version string, imagePrefix string) *apps }, }, }, + { + Name: consts.OdigosTierEnvVarName, + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: k8sconsts.OdigosDeploymentConfigMapName, + }, + Key: k8sconsts.OdigosDeploymentConfigMapTierKey, + }, + }, + }, }, EnvFrom: []corev1.EnvFromSource{ { diff --git a/helm/odigos/templates/scheduler/deployment.yaml b/helm/odigos/templates/scheduler/deployment.yaml index 081d8d6e6..15f75bf18 100644 --- a/helm/odigos/templates/scheduler/deployment.yaml +++ b/helm/odigos/templates/scheduler/deployment.yaml @@ -36,6 +36,11 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace + - name: ODIGOS_TIER + valueFrom: + configMapKeyRef: + key: ODIGOS_TIER + name: odigos-deployment envFrom: - configMapRef: name: odigos-own-telemetry-otel-config diff --git a/profiles/aggregators/kratos.go b/profiles/aggregators/kratos.go index 1a781c534..465bd71df 100644 --- a/profiles/aggregators/kratos.go +++ b/profiles/aggregators/kratos.go @@ -9,5 +9,5 @@ var KratosProfile = profile.Profile{ ProfileName: common.ProfileName("kratos"), MinimumTier: common.OdigosTier(common.OnPremOdigosTier), ShortDescription: "Bundle profile that includes db-payload-collection, semconv, category-attributes, copy-scope, hostname-as-podname, code-attributes, query-operation-detector, disableNameProcessorProfile, small-batches, size_m, allow_concurrent_agents", - Dependencies: []common.ProfileName{"db-payload-collection", "semconv", "category-attributes", "copy-scope", "hostname-as-podname", "code-attributes", "query-operation-detector", "disableNameProcessorProfile", "small-batches", "size_m", "allow_concurrent_agents"}, + Dependencies: []common.ProfileName{"db-payload-collection", "semconv", "category-attributes", "copy-scope", "hostname-as-podname", "code-attributes", "query-operation-detector", "disable-name-processor", "small-batches", "size_m", "allow_concurrent_agents"}, } diff --git a/profiles/allprofiles.go b/profiles/allprofiles.go index a8f7c9c2a..721ef5a7d 100644 --- a/profiles/allprofiles.go +++ b/profiles/allprofiles.go @@ -53,3 +53,14 @@ func init() { } } } + +func GetAvailableProfilesForTier(odigosTier common.OdigosTier) []profile.Profile { + switch odigosTier { + case common.CommunityOdigosTier: + return CommunityProfiles + case common.OnPremOdigosTier: + return OnPremProfiles + default: + return []profile.Profile{} + } +} diff --git a/scheduler/controllers/odigosconfig/manager.go b/scheduler/controllers/odigosconfig/manager.go index 1976d76d5..35bc3dcf8 100644 --- a/scheduler/controllers/odigosconfig/manager.go +++ b/scheduler/controllers/odigosconfig/manager.go @@ -1,12 +1,13 @@ package odigosconfig import ( + "github.com/odigos-io/odigos/common" odigospredicates "github.com/odigos-io/odigos/k8sutils/pkg/predicate" corev1 "k8s.io/api/core/v1" ctrl "sigs.k8s.io/controller-runtime" ) -func SetupWithManager(mgr ctrl.Manager) error { +func SetupWithManager(mgr ctrl.Manager, tier common.OdigosTier) error { err := ctrl.NewControllerManagedBy(mgr). For(&corev1.ConfigMap{}). @@ -15,6 +16,7 @@ func SetupWithManager(mgr ctrl.Manager) error { Complete(&odigosConfigController{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), + Tier: tier, }) if err != nil { return err diff --git a/scheduler/controllers/odigosconfig/odigosconfig_controller.go b/scheduler/controllers/odigosconfig/odigosconfig_controller.go index 30455d540..8d66a48b3 100644 --- a/scheduler/controllers/odigosconfig/odigosconfig_controller.go +++ b/scheduler/controllers/odigosconfig/odigosconfig_controller.go @@ -8,6 +8,7 @@ import ( k8sconsts "github.com/odigos-io/odigos/k8sutils/pkg/consts" "github.com/odigos-io/odigos/k8sutils/pkg/env" "github.com/odigos-io/odigos/profiles" + "github.com/odigos-io/odigos/profiles/profile" "github.com/odigos-io/odigos/profiles/sizing" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -21,6 +22,7 @@ import ( type odigosConfigController struct { client.Client Scheme *runtime.Scheme + Tier common.OdigosTier } func (r *odigosConfigController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) { @@ -37,7 +39,11 @@ func (r *odigosConfigController) Reconcile(ctx context.Context, _ ctrl.Request) // make sure the default ignored containers are always present odigosConfig.IgnoredContainers = mergeIgnoredItemLists(odigosConfig.IgnoredContainers, k8sconsts.DefaultIgnoredContainers) - applyProfilesToOdigosConfig(odigosConfig) + // effective profiles are what is actually used in the cluster + availableProfiles := profiles.GetAvailableProfilesForTier(r.Tier) + effectiveProfiles := calculateEffectiveProfiles(odigosConfig.Profiles, availableProfiles) + odigosConfig.Profiles = effectiveProfiles + modifyConfigWithEffectiveProfiles(effectiveProfiles, odigosConfig) // if none of the profiles set sizing for collectors, use size_s as default, so the values are never nil // if the values were already set (by user or profile) this is a no-op @@ -111,23 +117,45 @@ func (r *odigosConfigController) persistEffectiveConfig(ctx context.Context, eff return nil } -func applySingleProfile(profile common.ProfileName, odigosConfig *common.OdigosConfiguration) { - profileConfig, found := profiles.ProfilesByName[profile] - if !found { - return +func modifyConfigWithEffectiveProfiles(effectiveProfiles []common.ProfileName, odigosConfig *common.OdigosConfiguration) { + for _, profileName := range effectiveProfiles { + p := profiles.ProfilesByName[profileName] + if p.ModifyConfigFunc != nil { + p.ModifyConfigFunc(odigosConfig) + } } +} - if profileConfig.ModifyConfigFunc != nil { - profileConfig.ModifyConfigFunc(odigosConfig) - } +// from the list of input profiles, calculate the effective profiles: +// - check the dependencies of each profile and add them to the list +// - remove profiles which are not present in the profiles list +func calculateEffectiveProfiles(configProfiles []common.ProfileName, availableProfiles []profile.Profile) []common.ProfileName { + + effectiveProfiles := []common.ProfileName{} + for _, profileName := range configProfiles { + + // ignored missing profiles (either not available for tier or typos) + p, found := findProfileNameInAvailableList(profileName, availableProfiles) + if !found { + continue + } + + effectiveProfiles = append(effectiveProfiles, profileName) - for _, dependency := range profileConfig.Dependencies { - applySingleProfile(dependency, odigosConfig) + // if this profile has dependencies, add them to the list + if p.Dependencies != nil { + effectiveProfiles = append(effectiveProfiles, calculateEffectiveProfiles(p.Dependencies, availableProfiles)...) + } } + return effectiveProfiles } -func applyProfilesToOdigosConfig(odigosConfig *common.OdigosConfiguration) { - for _, profile := range odigosConfig.Profiles { - applySingleProfile(profile, odigosConfig) +func findProfileNameInAvailableList(profileName common.ProfileName, availableProfiles []profile.Profile) (profile.Profile, bool) { + // there aren't many profiles, so a linear search is fine + for _, p := range availableProfiles { + if p.ProfileName == profileName { + return p, true + } } + return profile.Profile{}, false } diff --git a/scheduler/main.go b/scheduler/main.go index 7eec35ebf..a8bb7782d 100644 --- a/scheduler/main.go +++ b/scheduler/main.go @@ -77,6 +77,7 @@ func main() { logger := zapr.NewLogger(zapLogger) ctrl.SetLogger(logger) + tier := env.GetOdigosTierFromEnv() odigosNs := env.GetCurrentNamespace() nsSelector := client.InNamespace(odigosNs).AsSelector() @@ -118,7 +119,7 @@ func main() { setupLog.Error(err, "unable to create controllers for node collectors group") os.Exit(1) } - err = odigosconfig.SetupWithManager(mgr) + err = odigosconfig.SetupWithManager(mgr, tier) if err != nil { setupLog.Error(err, "unable to create controllers for odigos config") os.Exit(1)