Beispiel #1
0
 def test_embedded_field_none(self):
     del self.cluster_dict["metadata"]
     self.cluster_object.metadata = None
     self.assertEqual(
         self.cluster_object.to_dict(skip_validation=True),
         V1MongoClusterConfiguration(**self.cluster_dict).to_dict(
             skip_validation=True))
Beispiel #2
0
    def setUp(self):
        super().setUp()
        self.cluster_dict = getExampleClusterDefinition()
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
        self.name = self.cluster_object.metadata.name
        self.namespace = self.cluster_object.metadata.namespace

        self.stateful_set = V1beta1StatefulSet(
            metadata=self._createMeta(self.name),
            spec=V1beta1StatefulSetSpec(
                replicas=3,
                service_name=self.name,
                template=V1PodTemplateSpec(
                    metadata=V1ObjectMeta(labels=KubernetesResources.
                                          createDefaultLabels(self.name)),
                    spec=V1PodSpec(containers=[
                        V1Container(
                            name="mongodb",
                            env=[
                                V1EnvVar(name="POD_IP",
                                         value_from=V1EnvVarSource(
                                             field_ref=V1ObjectFieldSelector(
                                                 api_version="v1",
                                                 field_path="status.podIP")))
                            ],
                            command=[
                                "mongod", "--replSet", self.name, "--bind_ip",
                                "0.0.0.0", "--smallfiles", "--noprealloc"
                            ],
                            image="mongo:3.6.4",
                            ports=[
                                V1ContainerPort(name="mongodb",
                                                container_port=27017,
                                                protocol="TCP")
                            ],
                            volume_mounts=[
                                V1VolumeMount(name="mongo-storage",
                                              read_only=False,
                                              mount_path="/data/db")
                            ],
                            resources=V1ResourceRequirements(limits={
                                "cpu": "100m",
                                "memory": "64Mi"
                            },
                                                             requests={
                                                                 "cpu": "100m",
                                                                 "memory":
                                                                 "64Mi"
                                                             }))
                    ])),
                volume_claim_templates=[
                    V1PersistentVolumeClaim(
                        metadata=V1ObjectMeta(name="mongo-storage"),
                        spec=V1PersistentVolumeClaimSpec(
                            access_modes=["ReadWriteOnce"],
                            resources=V1ResourceRequirements(
                                requests={"storage": "30Gi"})))
                ],
            ),
        )
 def setUp(self):
     super().setUp()
     self.kubernetes_service = MagicMock()
     self.checker = AdminSecretChecker(self.kubernetes_service)
     self.cluster_object = V1MongoClusterConfiguration(
         **getExampleClusterDefinition())
     self.secret_name = self.cluster_object.metadata.name + "-admin-credentials"
Beispiel #4
0
 def test_storage_class_name(self):
     self.cluster_dict["spec"]["mongodb"]["storage_class_name"] = "fast"
     self.cluster_object.spec.mongodb.storage_class_name = "fast"
     self.assertEqual(
         self.cluster_object.to_dict(skip_validation=True),
         V1MongoClusterConfiguration(**self.cluster_dict).to_dict(
             skip_validation=True))
Beispiel #5
0
    def test_restoreIfNeeded(self, restore_mock, gcs_service_mock,
                             storage_mock):
        get_bucket_mock = storage_mock.return_value.get_bucket
        get_bucket_mock.return_value.list_blobs.return_value = iter(
            [MockBlob()])

        self.restore_helper.restoreIfNeeded(self.cluster_object)

        self.assertEqual([
            call.getSecret("storage-serviceaccount", "mongo-operator-cluster")
        ], self.kubernetes_service.mock_calls)

        expected_service_call = call.from_service_account_info(
            {"user": "******"})
        self.assertEqual([expected_service_call], gcs_service_mock.mock_calls)

        get_bucket_mock.assert_called_once_with("ultimaker-mongo-backups")

        restore_mock.assert_called_once_with(self.cluster_object,
                                             "somebackupfile.gz")

        # Again, with no needed restore
        restore_mock.reset_mock()

        self.cluster_dict = getExampleClusterDefinition()
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)

        self.restore_helper.restoreIfNeeded(self.cluster_object)
        self.assertFalse(restore_mock.called,
                         "restore_mock should not have been called")
Beispiel #6
0
 def test_wrong_replicas(self):
     self.cluster_dict["spec"]["mongodb"]["replicas"] = 2
     with self.assertRaises(ValueError) as context:
         V1MongoClusterConfiguration(**self.cluster_dict)
     self.assertEqual(
         "The amount of replica sets must be between 3 and 50 (got 2).",
         str(context.exception))
Beispiel #7
0
 def test_wrong_values_kubernetes_field(self):
     self.cluster_dict["metadata"] = {"invalid": "value"}
     with self.assertRaises(ValueError) as context:
         V1MongoClusterConfiguration(**self.cluster_dict)
     self.assertEqual(
         "Invalid values passed to V1ObjectMeta field: __init__() got an unexpected keyword argument "
         "'invalid'. Received {'invalid': 'value'}.",
         str(context.exception))
Beispiel #8
0
 def setUp(self):
     super().setUp()
     with patch("mongoOperator.ClusterManager.KubernetesService") as ks:
         self.checker = ClusterManager()
         self.kubernetes_service = ks.return_value
     self.cluster_dict = getExampleClusterDefinition()
     self.cluster_dict["metadata"]["resourceVersion"] = "100"
     self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
Beispiel #9
0
 def setUp(self):
     super().setUp()
     self.cluster_dict = getExampleClusterDefinition()
     self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
     self.name = self.cluster_object.metadata.name
     self.namespace = self.cluster_object.metadata.namespace
     self.cpu_limit = "100m"
     self.memory_limit = "64Mi"
     self.stateful_set = self._createStatefulSet()
Beispiel #10
0
    def setUp(self):
        self.cluster_dict = getExampleClusterDefinition()
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
        self.kubernetes_service = MagicMock()
        self.checker = BackupChecker(self.kubernetes_service)

        self.dummy_credentials = b64encode(
            json.dumps({
                "user": "******"
            }).encode())
        self.kubernetes_service.getSecret.return_value = V1Secret(
            data={"json": self.dummy_credentials})
 def _parseConfiguration(cluster_dict: Dict[str, any]) -> Optional[V1MongoClusterConfiguration]:
     """
     Tries to parse the given cluster configuration, returning None if the object cannot be parsed.
     :param cluster_dict: The dictionary containing the configuration.
     :return: The cluster configuration model, if valid, or None.
     """
     try:
         result = V1MongoClusterConfiguration(**cluster_dict)
         result.validate()
         return result
     except ValueError as err:
         meta = cluster_dict.get("metadata", {})
         logging.error("Could not validate cluster configuration for %s @ ns/%s: %s. The cluster will be ignored.",
                       meta.get("name"), meta.get("namespace"), err)
Beispiel #12
0
    def test_createStatefulSet_no_optional_fields(self, client_mock):
        service = KubernetesService()
        client_mock.reset_mock()
        del self.cluster_dict["spec"]["mongodb"]["cpu_limit"]
        del self.cluster_dict["spec"]["mongodb"]["memory_limit"]
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)

        expected_calls = [
            call.AppsV1beta1Api().create_namespaced_stateful_set(
                self.namespace, self.stateful_set)
        ]

        result = service.createStatefulSet(self.cluster_object)
        self.assertEqual(expected_calls, client_mock.mock_calls)
        self.assertEqual(
            client_mock.AppsV1beta1Api().create_namespaced_stateful_set.
            return_value, result)
Beispiel #13
0
    def setUp(self):
        self.cluster_dict = getExampleClusterDefinitionWithRestore()
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
        self.kubernetes_service = MagicMock()
        self.restore_helper = RestoreHelper(self.kubernetes_service)

        self.dummy_credentials = b64encode(
            json.dumps({
                "user": "******"
            }).encode())
        self.kubernetes_service.getSecret.return_value = V1Secret(
            data={"json": self.dummy_credentials})

        self.expected_cluster_members = [
            "mongo-cluster-0.mongo-cluster.mongo-operator-cluster.svc.cluster.local",
            "mongo-cluster-1.mongo-cluster.mongo-operator-cluster.svc.cluster.local",
            "mongo-cluster-2.mongo-cluster.mongo-operator-cluster.svc.cluster.local"
        ]
Beispiel #14
0
    def test_streamEvents_add_update(self, stream_mock, check_mock):
        updated_cluster = deepcopy(self.cluster_dict)
        updated_cluster["spec"]["mongodb"]["replicas"] = 5
        updated_cluster["metadata"]["resource_version"] = "200"
        stream_mock.return_value = [
            {
                "type": "ADDED",
                "object": self.cluster_dict
            },
            {
                "type": "MODIFIED",
                "object": updated_cluster
            },
        ]

        self.checker.streamEvents()

        self.assertEqual([
            call(self.cluster_object),
            call(V1MongoClusterConfiguration(**updated_cluster))
        ], check_mock.mock_calls)
        stream_mock.assert_called_once_with(
            self.kubernetes_service.listMongoObjects,
            _request_timeout=self.checker.STREAM_REQUEST_TIMEOUT)
Beispiel #15
0
    def setUp(self):
        super().setUp()
        self.kubernetes_service: Union[MagicMock,
                                       KubernetesService] = MagicMock()
        self.kubernetes_service.getSecret.return_value = V1Secret(
            metadata=V1ObjectMeta(name="mongo-cluster-admin-credentials",
                                  namespace="default"),
            data={
                "password": b64encode(b"random-password"),
                "username": b64encode(b"root")
            },
        )

        self.service = MongoService(self.kubernetes_service)
        self.cluster_dict = getExampleClusterDefinition()
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)

        self.not_initialized_response = {
            "info": "run rs.initiate(...) if not yet done for the set",
            "ok": 0,
            "errmsg": "no replset config has been received",
            "code": 94,
            "codeName": "NotYetInitialized"
        }

        self.initiate_ok_response = {
            "ok": 1,
            "operationTime": 1528365094.1,
            "$clusterTime": {
                "clusterTime": 1528365094.1,
                "signature": {
                    "hash": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
                    "keyId": 0
                }
            }
        }

        self.initiate_not_found_response = {
            "ok":
            0,
            "errmsg":
            "replSetInitiate quorum check failed because not all proposed set members responded "
            "affirmatively: some-db-2.some-db.default.svc.cluster.local:27017 failed with Connection refused",
            "code":
            74,
            "codeName":
            "NodeNotFound"
        }

        self.expected_cluster_config = json.dumps({
            "_id":
            "mongo-cluster",
            "version":
            1,
            "members": [{
                "_id":
                0,
                "host":
                "mongo-cluster-0.mongo-cluster.default.svc.cluster.local"
            }, {
                "_id":
                1,
                "host":
                "mongo-cluster-1.mongo-cluster.default.svc.cluster.local"
            }, {
                "_id":
                2,
                "host":
                "mongo-cluster-2.mongo-cluster.default.svc.cluster.local"
            }]
        })

        self.expected_user_create = """
 def setUp(self):
     self.cluster_dict = getExampleClusterDefinition()
     self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
     self.kubernetes_service = MagicMock()
     self._onAllHostsReadyCallback = MagicMock()
 def setUp(self):
     self.kubernetes_service = MagicMock()
     self.checker = BaseResourceChecker(self.kubernetes_service)
     self.cluster_object = V1MongoClusterConfiguration(
         **getExampleClusterDefinition())
Beispiel #18
0
 def test_equals(self):
     self.assertEquals(self.cluster_object,
                       V1MongoClusterConfiguration(**self.cluster_dict))
Beispiel #19
0
 def test_non_required_fields(self):
     cluster_dict = getExampleClusterDefinition(replicas=5)
     cluster_object = V1MongoClusterConfiguration(**cluster_dict)
     self.assertEqual(dict(replicas=5), cluster_dict["spec"]["mongodb"])
     self.assertEqual(V1MongoClusterConfigurationSpecMongoDB(replicas=5),
                      cluster_object.spec.mongodb)
    def setUp(self):
        super().setUp()
        self.kubernetes_service = MagicMock()
        self.dummy_credentials = b64encode(
            json.dumps({
                "user": "******"
            }).encode())
        self.kubernetes_service.getSecret.return_value = V1Secret(
            metadata=V1ObjectMeta(name="mongo-cluster-admin-credentials",
                                  namespace="default"),
            data={
                "password": b64encode(b"random-password"),
                "username": b64encode(b"root"),
                "json": self.dummy_credentials
            },
        )
        self.service = MongoService(self.kubernetes_service)
        self.cluster_dict = getExampleClusterDefinition()
        self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)

        self.not_initialized_response = {
            "info": "run rs.initiate(...) if not yet done for the set",
            "ok": 0,
            "errmsg": "no replset config has been received",
            "code": 94,
            "codeName": "NotYetInitialized"
        }

        self.initiate_ok_response = loads("""
            {"ok": 1.0, "operationTime": {"$timestamp": {"t": 1549963040, "i": 1}}, "$clusterTime": {"clusterTime":
            {"$timestamp": {"t": 1549963040, "i": 1}}, "signature": {"hash": {"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
            "$type": "00"}, "keyId": 0}}}
        """)

        self.initiate_not_found_response = loads("""
            {"ok": 2, "operationTime": {"$timestamp": {"t": 1549963040, "i": 1}}, "$clusterTime": {"clusterTime":
            {"$timestamp": {"t": 1549963040, "i": 1}}, "signature": {"hash": {"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
            "$type": "00"}, "keyId": 0}}}
        """)

        self.expected_cluster_config = {
            "_id":
            "mongo-cluster",
            "version":
            1,
            "members": [{
                "_id":
                0,
                "host":
                "mongo-cluster-0.mongo-cluster.mongo-operator-cluster.svc.cluster.local"
            }, {
                "_id":
                1,
                "host":
                "mongo-cluster-1.mongo-cluster.mongo-operator-cluster.svc.cluster.local"
            }, {
                "_id":
                2,
                "host":
                "mongo-cluster-2.mongo-cluster.mongo-operator-cluster.svc.cluster.local"
            }]
        }

        self.expected_user_create = {
            "pwd": "random-password",
            "roles": [{
                "role": "root",
                "db": "admin"
            }]
        }
Beispiel #21
0
 def setUp(self):
     self.cluster_dict = getExampleClusterDefinition()
     self.cluster_object = V1MongoClusterConfiguration(**self.cluster_dict)
 def setUp(self):
     super().setUp()
     self.kubernetes_service = MagicMock()
     self.checker = HeadlessServiceChecker(self.kubernetes_service)
     self.cluster_object = V1MongoClusterConfiguration(
         **getExampleClusterDefinition())