Skip to content

Commit 212aaf2

Browse files
MaciejKaraslucian-tosaanandsyncs
authored
CLOUDP-314921 Telemetry for authentication modes (#62)
# Summary Adds Telemetry support for Authentication mode and Agent Authentication Mode. New fields `authenticationModes` and `authenticationAgentModes` will take any value passed from CRD. Because of the limitations of Telemetry subsystem used (Segment) we need to send flat `map[string]any` without any nested fields. For multiple Authentication modes we will flatten the values to `authenticationMode***` where `***` is one of the possible modes specified in the CRD. For example when `SCRAM` and `OIDC` are enabled we will send telemetry output: ```go { [...] "authenticationModeOIDC": true, "authenticationModeSCRAM": true, "authenticationAgentMode": util.SCRAM, } ``` ## Proof of Work Passing unit tests. ## Checklist - [x] Have you linked a jira ticket and/or is the ticket in the title? - [x] Have you checked whether your jira ticket required DOCSP changes? - [ ] Have you checked for release_note changes? ## Reminder (Please remove this when merging) - Please try to Approve or Reject Changes the PR, keep PRs in review as short as possible - Our Short Guide for PRs: [Link](https://docs.google.com/document/d/1T93KUtdvONq43vfTfUt8l92uo4e4SEEvFbIEKOxGr44/edit?tab=t.0) - Remember the following Communication Standards - use comment prefixes for clarity: * **blocking**: Must be addressed before approval. * **follow-up**: Can be addressed in a later PR or ticket. * **q**: Clarifying question. * **nit**: Non-blocking suggestions. * **note**: Side-note, non-actionable. Example: Praise * --> no prefix is considered a question --------- Co-authored-by: Lucian Tosa <[email protected]> Co-authored-by: Anand <[email protected]> Co-authored-by: Lucian Tosa <[email protected]>
1 parent ef8dc7c commit 212aaf2

File tree

9 files changed

+293
-94
lines changed

9 files changed

+293
-94
lines changed

api/v1/mdb/mongodb_types.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -807,13 +807,6 @@ func (s *Security) IsTLSEnabled() bool {
807807
return s.CertificatesSecretsPrefix != ""
808808
}
809809

810-
func (s *Security) IsOIDCEnabled() bool {
811-
if s == nil || s.Authentication == nil || !s.Authentication.Enabled {
812-
return false
813-
}
814-
return s.Authentication.IsOIDCEnabled()
815-
}
816-
817810
// GetAgentMechanism returns the authentication mechanism that the agents will be using.
818811
// The agents will use X509 if it is the only mechanism specified, otherwise they will use SCRAM if specified
819812
// and no auth if no mechanisms exist.
@@ -1006,16 +999,28 @@ type AgentAuthentication struct {
1006999
// IsX509Enabled determines if X509 is to be enabled at the project level
10071000
// it does not necessarily mean that the agents are using X509 authentication
10081001
func (a *Authentication) IsX509Enabled() bool {
1002+
if a == nil || !a.Enabled {
1003+
return false
1004+
}
1005+
10091006
return stringutil.Contains(a.GetModes(), util.X509)
10101007
}
10111008

10121009
// IsLDAPEnabled determines if LDAP is to be enabled at the project level
10131010
func (a *Authentication) IsLDAPEnabled() bool {
1011+
if a == nil || !a.Enabled {
1012+
return false
1013+
}
1014+
10141015
return stringutil.Contains(a.GetModes(), util.LDAP)
10151016
}
10161017

10171018
// IsOIDCEnabled determines if OIDC is to be enabled at the project level
10181019
func (a *Authentication) IsOIDCEnabled() bool {
1020+
if a == nil || !a.Enabled {
1021+
return false
1022+
}
1023+
10191024
return stringutil.Contains(a.GetModes(), util.OIDC)
10201025
}
10211026

api/v1/mdb/mongodb_types_test.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,20 @@ func TestGetAuthenticationIsEnabledMethods(t *testing.T) {
8383
expectedLDAP: false,
8484
expectedOIDC: false,
8585
},
86+
{
87+
name: "Empty authentication mode list",
88+
authentication: &Authentication{
89+
Enabled: true,
90+
},
91+
expectedX509: false,
92+
expectedLDAP: false,
93+
expectedOIDC: false,
94+
},
8695
{
8796
name: "Authentication with x509 only",
8897
authentication: &Authentication{
89-
Modes: []AuthMode{util.X509},
98+
Enabled: true,
99+
Modes: []AuthMode{util.X509},
90100
},
91101
expectedX509: true,
92102
expectedLDAP: false,
@@ -95,7 +105,8 @@ func TestGetAuthenticationIsEnabledMethods(t *testing.T) {
95105
{
96106
name: "Authentication with LDAP only",
97107
authentication: &Authentication{
98-
Modes: []AuthMode{util.LDAP},
108+
Enabled: true,
109+
Modes: []AuthMode{util.LDAP},
99110
},
100111
expectedX509: false,
101112
expectedLDAP: true,
@@ -104,7 +115,8 @@ func TestGetAuthenticationIsEnabledMethods(t *testing.T) {
104115
{
105116
name: "Authentication with OIDC only",
106117
authentication: &Authentication{
107-
Modes: []AuthMode{util.OIDC},
118+
Enabled: true,
119+
Modes: []AuthMode{util.OIDC},
108120
},
109121
expectedX509: false,
110122
expectedLDAP: false,
@@ -113,7 +125,8 @@ func TestGetAuthenticationIsEnabledMethods(t *testing.T) {
113125
{
114126
name: "Authentication with multiple modes",
115127
authentication: &Authentication{
116-
Modes: []AuthMode{util.X509, util.LDAP, util.OIDC, util.SCRAM},
128+
Enabled: true,
129+
Modes: []AuthMode{util.X509, util.LDAP, util.OIDC, util.SCRAM},
117130
},
118131
expectedX509: true,
119132
expectedLDAP: true,

api/v1/mdb/mongodb_validation.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func deploymentsMustHaveTLSInX509Env(d DbCommonSpec) v1.ValidationResult {
5454
if authSpec == nil {
5555
return v1.ValidationSuccess()
5656
}
57-
if authSpec.Enabled && authSpec.IsX509Enabled() && !d.GetSecurity().IsTLSEnabled() {
57+
if authSpec.IsX509Enabled() && !d.GetSecurity().IsTLSEnabled() {
5858
return v1.ValidationError("Cannot have a non-tls deployment when x509 authentication is enabled")
5959
}
6060
return v1.ValidationSuccess()
@@ -107,11 +107,15 @@ func scramSha1AuthValidation(d DbCommonSpec) v1.ValidationResult {
107107

108108
func oidcAuthValidators(db DbCommonSpec) []func(DbCommonSpec) v1.ValidationResult {
109109
validators := make([]func(DbCommonSpec) v1.ValidationResult, 0)
110-
if !db.Security.IsOIDCEnabled() {
110+
if db.Security == nil || db.Security.Authentication == nil {
111111
return validators
112112
}
113113

114114
authentication := db.Security.Authentication
115+
if !authentication.IsOIDCEnabled() {
116+
return validators
117+
}
118+
115119
validators = append(validators, oidcAuthModeValidator(authentication))
116120
validators = append(validators, oidcAuthRequiresEnterprise)
117121

api/v1/om/opsmanager_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ func ensureSecurityWithSCRAM(specSecurity *mdbv1.Security) *mdbv1.Security {
633633
specSecurity = &mdbv1.Security{TLSConfig: &mdbv1.TLSConfig{}}
634634
}
635635
// the only allowed authentication is SCRAM - it's implicit to the user and hidden from him
636-
specSecurity.Authentication = &mdbv1.Authentication{Modes: []mdbv1.AuthMode{util.SCRAM}}
636+
specSecurity.Authentication = &mdbv1.Authentication{Enabled: true, Modes: []mdbv1.AuthMode{util.SCRAM}}
637637
return specSecurity
638638
}
639639

controllers/operator/mongodbshardedcluster_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ func (r *ShardedClusterReconcileHelper) doShardedClusterProcessing(ctx context.C
10141014
}
10151015

10161016
security := sc.Spec.Security
1017-
if security.Authentication != nil && security.Authentication.Enabled && security.Authentication.IsX509Enabled() && !sc.Spec.GetSecurity().IsTLSEnabled() {
1017+
if security.Authentication.IsX509Enabled() && !security.IsTLSEnabled() {
10181018
return workflow.Invalid("cannot have a non-tls deployment when x509 authentication is enabled")
10191019
}
10201020

controllers/operator/mongodbstandalone_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (r *ReconcileMongoDbStandalone) Reconcile(ctx context.Context, request reco
177177
// cannot have a non-tls deployment in an x509 environment
178178
// TODO move to webhook validations
179179
security := s.Spec.Security
180-
if security.Authentication != nil && security.Authentication.Enabled && security.Authentication.IsX509Enabled() && !s.Spec.GetSecurity().IsTLSEnabled() {
180+
if security.Authentication.IsX509Enabled() && !security.IsTLSEnabled() {
181181
return r.updateStatus(ctx, s, workflow.Invalid("cannot have a non-tls deployment when x509 authentication is enabled"), log)
182182
}
183183

pkg/telemetry/collector.go

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/mongodb/mongodb-kubernetes/pkg/images"
2525
"github.com/mongodb/mongodb-kubernetes/pkg/util"
2626
"github.com/mongodb/mongodb-kubernetes/pkg/util/architectures"
27-
"github.com/mongodb/mongodb-kubernetes/pkg/util/maputil"
2827
"github.com/mongodb/mongodb-kubernetes/pkg/util/versionutil"
2928
)
3029

@@ -179,19 +178,13 @@ func collectOperatorSnapshot(ctx context.Context, memberClusterMap map[string]Co
179178
OperatorVersion: versionutil.StaticContainersOperatorVersion(),
180179
OperatorType: MEKO,
181180
}
182-
operatorProperties, err := maputil.StructToMap(operatorEvent)
183-
if err != nil {
184-
Logger.Debugf("failed converting properties to map: %s", err)
185-
return nil
186-
}
187181

188-
return []Event{
189-
{
190-
Timestamp: time.Now(),
191-
Source: Operators,
192-
Properties: operatorProperties,
193-
},
182+
event := createEvent(operatorEvent, time.Now(), Operators)
183+
if event == nil {
184+
return []Event{}
194185
}
186+
187+
return []Event{*event}
195188
}
196189

197190
func collectDeploymentsSnapshot(ctx context.Context, operatorClusterMgr manager.Manager, operatorUUID, mongodbImage, databaseNonStaticImage string) []Event {
@@ -234,6 +227,8 @@ func getMdbEvents(ctx context.Context, operatorClusterClient kubeclient.Client,
234227
Type: string(item.Spec.GetResourceType()),
235228
IsRunningEnterpriseImage: images.IsEnterpriseImage(imageURL),
236229
ExternalDomains: getExternalDomainProperty(item),
230+
AuthenticationModes: getAuthenticationModes(item.Spec.Security),
231+
AuthenticationAgentMode: getAuthenticationAgentMode(item.Spec.Security),
237232
}
238233

239234
if numberOfClustersUsed > 0 {
@@ -272,6 +267,8 @@ func addMultiEvents(ctx context.Context, operatorClusterClient kubeclient.Client
272267
Type: string(item.Spec.GetResourceType()),
273268
IsRunningEnterpriseImage: images.IsEnterpriseImage(imageURL),
274269
ExternalDomains: getExternalDomainPropertyForMongoDBMulti(item),
270+
AuthenticationModes: getAuthenticationModes(item.Spec.Security),
271+
AuthenticationAgentMode: getAuthenticationAgentMode(item.Spec.Security),
275272
}
276273

277274
if event := createEvent(properties, now, Deployments); event != nil {
@@ -319,8 +316,8 @@ func addOmEvents(ctx context.Context, operatorClusterClient kubeclient.Client, o
319316
return events
320317
}
321318

322-
func createEvent(properties any, now time.Time, eventType EventType) *Event {
323-
convertedProperties, err := maputil.StructToMap(properties)
319+
func createEvent(properties FlatProperties, now time.Time, eventType EventType) *Event {
320+
convertedProperties, err := properties.ConvertToFlatMap()
324321
if err != nil {
325322
Logger.Debugf("failed to parse %s properties: %v", eventType, err)
326323
return nil
@@ -422,13 +419,12 @@ func handleEvents(ctx context.Context, atlasClient *Client, events []Event, even
422419
return
423420
}
424421

425-
err = atlasClient.SendEventWithRetry(ctx, events)
426-
if err == nil {
427-
if err := updateTelemetryConfigMapTimeStamp(ctx, operatorClusterClient, namespace, OperatorConfigMapTelemetryConfigMapName, eventType); err != nil {
428-
Logger.Debugf("Failed saving timestamp of successful sending of data for type: %s with error: %s", eventType, err)
422+
if sendErr := atlasClient.SendEventWithRetry(ctx, events); sendErr == nil {
423+
if updateErr := updateTelemetryConfigMapTimeStamp(ctx, operatorClusterClient, namespace, OperatorConfigMapTelemetryConfigMapName, eventType); updateErr != nil {
424+
Logger.Debugf("Failed saving timestamp of successful sending of data for type: %s with error: %s", eventType, updateErr)
429425
}
430426
} else {
431-
Logger.Debugf("Encountered error while trying to send payload to atlas; err: %s", err)
427+
Logger.Debugf("Encountered error while trying to send payload to atlas; err: %s", sendErr)
432428
}
433429
}
434430

@@ -534,3 +530,27 @@ func isExternalDomainSpecifiedInClusterSpecList(clusterSpecList mdbv1.ClusterSpe
534530

535531
return clusterSpecList.IsExternalDomainSpecifiedInClusterSpecList()
536532
}
533+
534+
func getAuthenticationModes(security *mdbv1.Security) []string {
535+
if security == nil || security.Authentication == nil {
536+
return nil
537+
}
538+
539+
if !security.Authentication.Enabled {
540+
return nil
541+
}
542+
543+
return security.Authentication.GetModes()
544+
}
545+
546+
func getAuthenticationAgentMode(security *mdbv1.Security) string {
547+
if security == nil || security.Authentication == nil {
548+
return ""
549+
}
550+
551+
if !security.Authentication.Enabled {
552+
return ""
553+
}
554+
555+
return security.Authentication.Agents.Mode
556+
}

0 commit comments

Comments
 (0)