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

Operator crashes when spec.security.modes list is empty #1055

Closed
hoyhbx opened this issue Jul 19, 2022 · 5 comments · Fixed by #1116
Closed

Operator crashes when spec.security.modes list is empty #1055

hoyhbx opened this issue Jul 19, 2022 · 5 comments · Fixed by #1116

Comments

@hoyhbx
Copy link
Contributor

hoyhbx commented Jul 19, 2022

What did you do to encounter the bug?
I was trying to create a mongodb cluster by submitting an CR with the field spec.security.modes being an empty array

Steps to reproduce the behavior:

  1. Apply the following configuration with the field spec.security.modes being an empty array:
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: test-cluster
  namespace: mongodb
spec:
  members: 3
  security:
    authentication:
      modes: []
  statefulSet:
    spec:
      template:
        spec:
          containers:
          - name: mongod
            resources:
              limits:
                cpu: '0.2'
                memory: 250M
              requests:
                cpu: '0.2'
                memory: 200M
          - name: mongodb-agent
            resources:
              limits:
                cpu: '0.2'
                memory: 250M
              requests:
                cpu: '0.2'
                memory: 200M
  type: ReplicaSet
  users:
  - db: admin
    name: my-user
    passwordSecretRef:
      name: my-user-password
    roles:
    - db: admin
      name: clusterAdmin
    - db: admin
      name: userAdminAnyDatabase
    scramCredentialsSecretName: my-scram
  version: 4.4.0

What did you expect?
The operator should capture that the array is empty and not crash.

What happened instead?
The operator crashes with the following error:

panic: runtime error: index out of range [0] with length 0

Operator Information

  • Operator Version - 0.7.3
  • MongoDB Image used - 4.4.0

Kubernetes Cluster Information

kubectl version --short --output=yaml
$ kubectl version --short --output=yaml
clientVersion:
buildDate: "2022-05-24T12:26:19Z"
compiler: gc
gitCommit: 3ddd0f45aa91e2f30c70734b175631bec5b5825a
gitTreeState: clean
gitVersion: v1.24.1
goVersion: go1.18.2
major: "1"
minor: "24"
platform: linux/amd64
kustomizeVersion: v4.5.4
serverVersion:
buildDate: "2022-05-19T19:53:08Z"
compiler: gc
gitCommit: 6df4433e288edc9c40c2e344eb336f63fad45cd2
gitTreeState: clean
gitVersion: v1.22.9
goVersion: go1.16.15
major: "1"
minor: "22"
platform: linux/amd64

Additional context

When setting the AutoAuthMechanism the operator tries to assign the first authentication mode at the 0th index of the Modes array. Since the array is empty, the index is out of range.

  • operator log
Running ./manager
2022-07-18T12:46:03.128Z	INFO	manager/main.go:74	Watching namespace: mongodb
2022-07-18T12:46:03.203Z	INFO	manager/main.go:91	Registering Components.
2022-07-18T12:46:03.204Z	INFO	manager/main.go:104	Starting the Cmd.
2022-07-18T12:46:03.313Z	INFO	controllers/replica_set_controller.go:140	Reconciling MongoDB	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
2022-07-18T12:46:03.314Z	DEBUG	controllers/replica_set_controller.go:142	Validating MongoDB.Spec	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
2022-07-18T12:46:03.314Z	DEBUG	controllers/replica_set_controller.go:151	Ensuring the service exists	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
2022-07-18T12:46:03.464Z	INFO	controllers/replica_set_controller.go:475	Create/Update operation succeeded	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources", "operation": "updated"}
2022-07-18T12:46:03.464Z	DEBUG	controllers/replica_set_controller.go:160	Ensuring the service for Arbiters exists	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
2022-07-18T12:46:03.489Z	INFO	controllers/replica_set_controller.go:475	Create/Update operation succeeded	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources", "operation": "updated"}
2022-07-18T12:46:03.490Z	INFO	controllers/replica_set_controller.go:371	Creating/Updating AutomationConfig	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
2022-07-18T12:46:03.538Z	DEBUG	scram/scram.go:166	Credentials have not changed, using credentials stored in: secret/my-scram-scram-credentials
2022-07-18T12:46:03.539Z	INFO	controllers/replica_set_controller.go:140	Reconciling MongoDB	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
2022-07-18T12:46:03.539Z	DEBUG	controllers/replica_set_controller.go:142	Validating MongoDB.Spec	{"ReplicaSet": "mongodb/mongodb-specify-pod-resources"}
panic: runtime error: index out of range [0] with length 0

goroutine 231 [running]:
github.com/mongodb/mongodb-kubernetes-operator/api/v1.MongoDBCommunity.GetScramOptions({{{0x134105c, 0x10}, {0xc000540340, 0x1f}}, {{0xc0002b13a0, 0x1d}, {0x0, 0x0}, {0xc000456f39, 0x7}, ...}, ...})
	/workspace/api/v1/mongodbcommunity_types.go:539 +0x33e
github.com/mongodb/mongodb-kubernetes-operator/pkg/authentication/scram.Enable(0x189aa80, {0x7fc2c97090d8, 0xc0002c4d90}, {0x189aa80, 0xc0001ec600})
	/workspace/pkg/authentication/scram/scram.go:138 +0x3a7
github.com/mongodb/mongodb-kubernetes-operator/controllers.ReplicaSetReconciler.buildAutomationConfig({{_, _}, _, _, _, _}, {{{0x134105c, 0x10}, {0xc000540340, 0x1f}}, ...})
	/workspace/controllers/replica_set_controller.go:638 +0x49e
github.com/mongodb/mongodb-kubernetes-operator/controllers.ReplicaSetReconciler.ensureAutomationConfig({{_, _}, _, _, _, _}, {{{0x134105c, 0x10}, {0xc000540340, 0x1f}}, ...})
	/workspace/controllers/replica_set_controller.go:508 +0x112
github.com/mongodb/mongodb-kubernetes-operator/controllers.(*ReplicaSetReconciler).deployAutomationConfig(_, {{{0x134105c, 0x10}, {0xc000540340, 0x1f}}, {{0xc0002b13a0, 0x1d}, {0x0, 0x0}, {0xc000456f39, ...}, ...}, ...})
	/workspace/controllers/replica_set_controller.go:378 +0x27d
github.com/mongodb/mongodb-kubernetes-operator/controllers.(*ReplicaSetReconciler).deployMongoDBReplicaSet.func1()
	/workspace/controllers/replica_set_controller.go:446 +0x4a
github.com/mongodb/mongodb-kubernetes-operator/pkg/util/functions.runInOrder({0xc00060d700, 0x2, 0x0})
	/workspace/pkg/util/functions/functions.go:16 +0x46
github.com/mongodb/mongodb-kubernetes-operator/pkg/util/functions.RunSequentially(0x5c, {0xc0006f5700, 0xc000540340, 0x1f})
	/workspace/pkg/util/functions/functions.go:9 +0x2b
github.com/mongodb/mongodb-kubernetes-operator/controllers.(*ReplicaSetReconciler).deployMongoDBReplicaSet(_, {{{0x134105c, 0x10}, {0xc000540340, 0x1f}}, {{0xc0002b13a0, 0x1d}, {0x0, 0x0}, {0xc000456f39, ...}, ...}, ...})
	/workspace/controllers/replica_set_controller.go:444 +0x108
github.com/mongodb/mongodb-kubernetes-operator/controllers.ReplicaSetReconciler.Reconcile({{0x18bf290, 0xc0002c4d90}, 0xc0001c4d90, 0xc00000fb48, 0xc00048e2e8, 0xc00048e2f0}, {0x187fc98, 0xc0006b7740}, {{{0xc000456f39, 0x7}, ...}})
	/workspace/controllers/replica_set_controller.go:210 +0x11f3
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Reconcile(0xc0001b7540, {0x187fc98, 0xc0006b76e0}, {{{0xc000456f39, 0x14df7a0}, {0xc0002b13a0, 0xc0004034c0}}})
	/root/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:114 +0x222
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler(0xc0001b7540, {0x187fbf0, 0xc0004b5940}, {0x1495720, 0xc0004a6080})
	/root/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:311 +0x2f2
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem(0xc0001b7540, {0x187fbf0, 0xc0004b5940})
	/root/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:266 +0x205
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2()
	/root/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:227 +0x85
created by sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2
	/root/go/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:223 +0x356

Possible Fix

This issue can ideally be resolved through CRD validation. Currently, only the strings within Modes array are being validated.

type Authentication struct {
	// Modes is an array specifying which authentication methods should be enabled.
	Modes []AuthMode `json:"modes"`

	// IgnoreUnknownUsers set to true will ensure any users added manually (not through the CRD)
	// will not be removed.

	// TODO: defaults will work once we update to v1 CRD.

	// +optional
	// +kubebuilder:default:=true
	// +nullable
	IgnoreUnknownUsers *bool `json:"ignoreUnknownUsers,omitempty"`
}

// +kubebuilder:validation:Enum=SCRAM;SCRAM-SHA-256;SCRAM-SHA-1
type AuthMode string

We can include the following marker to validate the minimum length of the Modes array:

// +kubebuilder:validation:MinItems=1

Alternative Fix

Alternatively, during validation of the AuthModeSpec, in addition to checking for duplicates, we can include an additional check as part of validateAuthModeSpec in controllers/validation/validation.go:

func validateAuthModeSpec(mdb mdbv1.MongoDBCommunity) error {
	allModes := mdb.Spec.Security.Authentication.Modes

	// Check that no auth is defined more than once
	mapModes := make(map[mdbv1.AuthMode]struct{})
	for i, mode := range allModes {
		if value := mdbv1.ConvertAuthModeToAuthMechanism(mode); value == "" {
			return fmt.Errorf("unexpected value (%q) defined for supported authentication modes", value)
		}
		mapModes[allModes[i]] = struct{}{}
	}
	if len(mapModes) != len(allModes) {
		return fmt.Errorf("some authentication modes are declared twice or more")
	}

	return nil
}
if len(allModes) == 0 {
	return fmt.Errorf("modes list is empty.")
}
@github-actions
Copy link
Contributor

This issue is being marked stale because it has been open for 60 days with no activity. Please comment if this issue is still affecting you. If there is no change, this issue will be closed in 30 days.

@github-actions github-actions bot added the stale label Sep 21, 2022
@hoyhbx
Copy link
Contributor Author

hoyhbx commented Sep 22, 2022

Remove stale

@slaskawi
Copy link
Contributor

@hoyhbx There are unresolved comments in your PR: #1116

Could you please take a look?

@github-actions github-actions bot removed the stale label Oct 19, 2022
@slaskawi
Copy link
Contributor

@hoyhbx Just a friendly reminder.

@dan-mckean
Copy link
Collaborator

Hi, I'm Dan and I'm the Product Manager for MongoDB's support of Kubernetes.

I'm doing some work right now to try and identify how the Community Operator is being used. The Community Operator is something I inherited when I started at MongoDB, but it doesn't get as much attention from us as we'd like and we're trying to understand how it's used in order to establish its future. It will help us prioritize future issues and PRs raised by the community 🙂

Here's a super short survey (it's much easier for us to review all the feedback that way!): https://docs.google.com/forms/d/e/1FAIpQLSfwrwyxBSlUyJ6AmC-eYlgW_3JEdfA48SB2i5--_WpiynMW2w/viewform?usp=sf_link

If you'd rather email me instead: [email protected]

Thank you in advance!
Dan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants