Esempio n. 1
0
    def test_mongos(self):
        self.server.stop()
        self.server.cleanup()
        self.server = Server(self.mongod, {'configsvr': True},
                             auth_key='secret')
        self.server.start(30)
        mongos = os.path.join(os.environ.get('MONGOBIN', ''), 'mongos')
        self.server2 = Server(mongos, {'configdb': self.server.hostname},
                              auth_key='secret',
                              login='******',
                              password='******')
        self.server2.start()

        for server in (self.server, self.server2):
            c = pymongo.MongoClient(server.host, server.port)
            self.assertRaises(pymongo.errors.OperationFailure,
                              c.admin.collection_names)
            self.assertTrue(c.admin.authenticate('admin', 'admin'))
            self.assertTrue(isinstance(c.admin.collection_names(), list))
            self.assertTrue(c.admin.logout() is None)
            self.assertRaises(pymongo.errors.OperationFailure,
                              c.admin.collection_names)

        self.server2.stop()
        self.server2.cleanup()
Esempio n. 2
0
 def test_mongos(self):
     self.server.cleanup()
     self.server = Server(self.mongod, {'configsvr': True})
     self.server.start(30)
     mongos = os.path.join(os.environ.get('MONGOBIN', ''), 'mongos')
     self.server2 = Server(mongos, {'configdb': self.server.hostname})
     self.assertTrue(self.server2.start())
     self.assertTrue(self.server2.info()['statuses'].get('mongos', False))
     self.server2.stop()
     self.server2.cleanup()
Esempio n. 3
0
    def test_ssl_auth(self):
        if SERVER_VERSION < (2, 4):
            raise SkipTest("Need to be able to set 'authenticationMechanisms' "
                           "parameter to test.")

        proc_params = {
            'setParameter': {
                'authenticationMechanisms': 'MONGODB-X509'
            }
        }
        ssl_params = {
            'sslPEMKeyFile': certificate('server.pem'),
            'sslCAFile': certificate('ca.pem'),
            'sslMode': 'requireSSL',
            'sslAllowInvalidCertificates': True
        }
        # Should not raise an Exception.
        self.server = Server('mongod',
                             proc_params,
                             ssl_params,
                             login=TEST_SUBJECT,
                             auth_source='$external')
        self.server.start()
        # Should create an extra user. Doesn't raise.
        client = pymongo.MongoClient(self.server.hostname,
                                     ssl_certfile=DEFAULT_CLIENT_CERT)
        client['$external'].authenticate(DEFAULT_SUBJECT,
                                         mechanism='MONGODB-X509')
        # Should also create the user we requested. Doesn't raise.
        client = pymongo.MongoClient(self.server.hostname,
                                     ssl_certfile=certificate('client.pem'))
        client['$external'].authenticate(TEST_SUBJECT,
                                         mechanism='MONGODB-X509')
Esempio n. 4
0
 def test_start_with_repair(self):
     self.server.cleanup()
     self.server = Server(self.mongod, {"journal": False})
     self.server.start(30)
     os.kill(self.server.pid, 9)
     self.assertTrue(self.server._is_locked)
     self.assertTrue(self.server.start(20))
Esempio n. 5
0
    def test_info(self):
        self.server.start(30)
        info = self.server.info()
        for item in ("mongodb_uri", "statuses", "serverInfo", "procInfo",
                     "orchestration"):
            self.assertTrue(item in info)

        self.assertTrue(info['mongodb_uri'].find(self.server.hostname))
        self.assertTrue(info['mongodb_uri'].find('mongodb://') == 0)
        fd_log, log_path = tempfile.mkstemp()
        os.close(fd_log)
        db_path = tempfile.mkdtemp()
        params = {'logpath': log_path, 'dbpath': db_path}
        server2 = Server(self.mongod, params)
        server2.start()
        info2 = server2.info()
        for param, value in params.items():
            self.assertTrue(
                info2['procInfo']['params'].get(param, value) == value)
        server2.stop()
        info = server2.info()
        self.assertEqual(len(info['serverInfo']), 0)
        self.assertEqual(len(info['statuses']), 0)
        self.assertEqual(info['orchestration'], 'servers')
        server2.cleanup()
    def test_mongodb_auth_uri(self):
        if SERVER_VERSION < (2, 4):
            raise SkipTest("Need to be able to set 'authenticationMechanisms' "
                           "parameter to test.")

        proc_params = {
            'setParameter': {
                'authenticationMechanisms': 'MONGODB-X509'
            }
        }
        ssl_params = {
            'sslPEMKeyFile': certificate('server.pem'),
            'sslCAFile': certificate('ca.pem'),
            'sslMode': 'requireSSL',
            'sslAllowInvalidCertificates': True
        }
        self.server = Server(self.mongod_name,
                             proc_params,
                             ssl_params,
                             login=TEST_SUBJECT,
                             auth_source='$external')
        self.server.start()

        self.assertIn('mongodb_auth_uri', self.server.info())
        auth_uri = self.server.info()['mongodb_auth_uri']
        self.assertIn(self.server.hostname, auth_uri)
        self.assertIn(TEST_SUBJECT, auth_uri)
        self.assertIn('authSource=$external', auth_uri)
        self.assertIn('authMechanism=MONGODB-X509', auth_uri)
Esempio n. 7
0
 def setUp(self):
     PortPool().change_range()
     self.mongod = os.path.join(os.environ.get('MONGOBIN', ''), 'mongod')
     self.server = Server(self.mongod, {},
                          auth_key='secret',
                          login='******',
                          password='******')
     self.server.start()
Esempio n. 8
0
    def test_start(self):
        self.assertNotIn('pid', self.server.info()['procInfo'])
        self.assertTrue(self.server.start(30))
        self.assertTrue(self.server.info()['procInfo']['pid'] > 0)

        fake_server = Server('fake_proc_', {})
        self.assertRaises(OSError, fake_server.start, 5)
        fake_server.cleanup()
 def test_init_path(self):
     self.server.cleanup()
     mongod = os.path.join(os.environ.get('MONGOBIN', ''), 'mongod')
     log_dir = os.path.join(tempfile.gettempdir(), os.path.split(tempfile.mktemp())[-1])
     log_path = tempfile.mktemp(dir=log_dir)
     db_path = os.path.join(tempfile.gettempdir(), os.path.split(tempfile.mktemp())[-1])
     self.assertFalse(os.path.exists(log_dir))
     self.assertFalse(os.path.exists(db_path))
     self.server = Server(mongod, {'logpath': log_path, 'dbpath': db_path})
     self.assertTrue(os.path.exists(log_dir))
     self.assertTrue(os.path.exists(db_path))
 def test_set_parameter(self):
     self.server.cleanup()
     cfg = {"setParameter": {"textSearchEnabled": True,
                             "enableTestCommands": 1}}
     self.server = Server(self.mongod, cfg)
     self.server.start()
     c = pymongo.MongoClient(self.server.hostname)
     c.foo.bar.insert({"data": "text stuff"})
     # No Exception.
     c.foo.bar.ensure_index([("data", pymongo.TEXT)])
     # No Exception.
     c.admin.command("sleep", secs=1)
Esempio n. 11
0
 def test_ssl(self):
     ssl_params = {
         'sslPEMKeyFile': certificate('server.pem'),
         'sslCAFile': certificate('ca.pem'),
         'sslMode': 'requireSSL',
         'sslAllowInvalidCertificates': True
     }
     # Should not raise an Exception.
     self.server = Server('mongod', {}, ssl_params)
     self.server.start()
     # Server should require SSL.
     self.assertRaises(pymongo.errors.ConnectionFailure,
                       pymongo.MongoClient, self.server.hostname)
     # Doesn't raise with certificate provided.
     pymongo.MongoClient(self.server.hostname,
                         ssl_certfile=certificate('client.pem'))
    def test_operations(self):
        server_id = self.servers.create('mongod', {}, autostart=False)
        self.assertTrue(len(self.servers) == 1)
        self.assertTrue(server_id in self.servers)
        server_id2 = 'server-id2'
        server2 = Server(os.path.join(os.environ.get('MONGOBIN', ''), 'mongod'), {})
        server2.start(30)
        server2_pid = server2.info()['procInfo']['pid']
        self.servers[server_id2] = server2
        self.assertTrue(self.servers[server_id2]['procInfo']['pid'] == server2_pid)
        self.assertTrue(server_id2 in self.servers)
        for h_id in self.servers:
            self.assertTrue(h_id in (server_id, server_id2))

        operator.delitem(self.servers, server_id2)
        self.assertFalse(server_id2 in self.servers)
        server2.stop()
        server2.cleanup()
 def test_scram_with_ssl(self):
     ssl_params = {
         'sslPEMKeyFile': certificate('server.pem'),
         'sslCAFile': certificate('ca.pem'),
         'sslMode': 'requireSSL',
         'sslAllowInvalidCertificates': True
     }
     # Should not raise an Exception.
     self.server = Server(
         'mongod', {}, ssl_params, login='******', password='******')
     self.server.start()
     # Should create the user we requested. No raise on authenticate.
     client = pymongo.MongoClient(
         self.server.hostname, ssl_certfile=certificate('client.pem'))
     client.admin.authenticate('luke', 'ekul')
     # This should be the only user.
     self.assertEqual(len(client.admin.command('usersInfo')['users']), 1)
     self.assertFalse(client['$external'].command('usersInfo')['users'])
 def test_set_parameter(self):
     if SERVER_VERSION < (2, 4):
         raise SkipTest(
             "Need at least MongoDB >= 2.4 to test setParameter.")
     self.server.cleanup()
     cfg = {
         "setParameter": {
             "textSearchEnabled": True,
             "enableTestCommands": 1
         }
     }
     self.server = Server(self.mongod, cfg)
     self.server.start()
     c = pymongo.MongoClient(self.server.hostname)
     c.foo.bar.insert({"data": "text stuff"})
     # No Exception.
     c.foo.bar.ensure_index([("data", pymongo.TEXT)])
     # No Exception.
     c.admin.command("sleep", secs=1)
    def __init__(self, params):
        """init configuration acording params"""
        self.id = params.get('id', None) or str(uuid4())
        self.admin_added = False
        self.login = params.get('login', '')
        self.password = params.get('password', '')
        self.auth_key = params.get('auth_key', None)
        self.auth_source = params.get('authSource', 'admin')
        self._version = params.get('version')
        self._configsvrs = []
        self._routers = []
        self._shards = {}
        self.tags = {}

        self.sslParams = params.get('sslParams', {})
        self.kwargs = {}
        self.restart_required = self.login or self.auth_key
        self.x509_extra_user = False

        if self.sslParams:
            self.kwargs.update(DEFAULT_SSL_OPTIONS)

        self.enable_ipv6 = common.ipv6_enabled_sharded(params)
        # Determine what to do with config servers via mongos version.
        mongos_name = os.path.join(Servers().bin_path(self._version), 'mongos')
        mongos = Server(name=mongos_name, procParams={})
        mongos_version = mongos.version
        mongos.cleanup()
        configsvr_configs = params.get('configsvrs', [{}])
        self.uses_rs_configdb = (mongos_version >= (3, 1, 2)
                                 and len(configsvr_configs) == 1)
        self.configdb_singleton = (ReplicaSets()
                                   if self.uses_rs_configdb else Servers())
        if self.uses_rs_configdb:
            self.__init_configrs(configsvr_configs[0])
        elif mongos_version >= (3, 3, 2):
            raise ShardedClusterError(
                'mongos >= 3.3.2 requires the config database to be backed by '
                'a replica set.')
        elif mongos_version >= (3, 1, 2) and len(configsvr_configs) != 3:
            raise ShardedClusterError(
                "mongos >= 3.1.2 needs a config replica set or 3 old-style "
                "config servers.")
        else:
            self.__init_configsvrs(configsvr_configs)

        for r in params.get('routers', [{}]):
            self.router_add(r)
        for cfg in params.get('shards', []):
            shard_params = cfg.get('shardParams', {})
            shard_tags = shard_params.pop('tags', None)
            info = self.member_add(cfg.get('id', None), shard_params)
            if shard_tags:
                self.tags[info['id']] = shard_tags

        # SERVER-37631 changed 3.6 sharded cluster setup so that it's required
        # to run refreshLogicalSessionCacheNow on the config server followed by
        # each mongos. Only then will each 3.6 mongos correctly report
        # logicalSessionTimeoutMinutes in its isMaster responses.
        if mongos_version[:2] == (3, 6):
            router_clients = self.router_connections()
            is_master = router_clients[0].admin.command('isMaster')
            if 'logicalSessionTimeoutMinutes' not in is_master:
                self.config_connection().admin.command(
                    'refreshLogicalSessionCacheNow')
                for client in router_clients:
                    client.admin.command('refreshLogicalSessionCacheNow')

        if self.tags:
            for sh_id in self.tags:
                logger.debug('Add tags %r to %s' % (self.tags[sh_id], sh_id))
                db = self.connection().get_database(
                    'config',
                    write_concern=write_concern.WriteConcern(fsync=True))
                db.shards.update(
                    {'_id': sh_id},
                    {'$addToSet': {
                        'tags': {
                            '$each': self.tags[sh_id]
                        }
                    }})

        shard_configs = [
            s.get('shardParams', {}).get('procParams', {})
            for s in params.get('shards', [])
        ]
        if self.login:
            # Do we need to add an extra x509 user?
            def only_x509(config):
                set_params = config.get('setParameter', {})
                auth_mechs = set_params.get('authenticationMechanisms', '')
                auth_mechs = auth_mechs.split(',')
                if len(auth_mechs) == 1 and auth_mechs[0] == 'MONGODB-X509':
                    return True
                return False

            any_only_x509 = lambda l: any(map(only_x509, l))
            rs_shard_configs = [
                m.get('procParams', {}) for s in params.get('shards', [])
                for m in s.get('shardParams', {}).get('members', [])
            ]
            router_configs = params.get('routers', [])

            self.x509_extra_user = (any_only_x509(configsvr_configs)
                                    or any_only_x509(shard_configs)
                                    or any_only_x509(rs_shard_configs)
                                    or any_only_x509(router_configs))

            self._add_users(
                self.connection().get_database(
                    self.auth_source,
                    write_concern=write_concern.WriteConcern(fsync=True)),
                mongos_version)

            # Secondary user given from request.
            secondary_login = {
                'name': self.login,
                'roles': self._user_roles(self.connection())
            }
            if self.password:
                secondary_login['password'] = self.password

            if mongos_version >= (3, 7, 2):
                secondary_login['mechanisms'] = ['SCRAM-SHA-1']
            # Do the same for the shards.
            for shard_id, config in zip(self._shards, shard_configs):
                shard = self._shards[shard_id]
                instance_id = shard['_id']
                if shard.get('isServer'):
                    client = Servers()._storage[instance_id].connection
                elif shard.get('isReplicaSet'):
                    client = ReplicaSets()._storage[instance_id].connection()
                db = client[self.auth_source]
                if self.x509_extra_user:
                    db.add_user(DEFAULT_SUBJECT,
                                roles=self._user_roles(client))
                if self.login:
                    db.add_user(**secondary_login)

        if self.restart_required:
            # Do we need to add clusterAuthMode back?
            cluster_auth_mode = None
            for cfg in shard_configs:
                cam = cfg.get('clusterAuthMode')
                if cam:
                    cluster_auth_mode = cam
                    break

            def restart_with_auth(server_or_rs):
                server_or_rs.x509_extra_user = self.x509_extra_user
                server_or_rs.auth_source = self.auth_source
                server_or_rs.ssl_params = self.sslParams
                server_or_rs.login = self.login
                server_or_rs.password = self.password
                server_or_rs.auth_key = self.auth_key

                def add_auth(cfg):
                    if self.auth_key:
                        cfg['keyFile'] = self.key_file
                    # Add clusterAuthMode back in.
                    if cluster_auth_mode:
                        cfg['clusterAuthMode'] = cam
                    return cfg

                server_or_rs.restart(config_callback=add_auth)

            for config_id in self._configsvrs:
                restart_with_auth(self.configdb_singleton._storage[config_id])

            for server_id in self._routers:
                server = Servers()._storage[server_id]
                restart_with_auth(server)

            for shard_id in self._shards:
                shard = self._shards[shard_id]
                instance_id = shard['_id']
                klass = ReplicaSets if shard.get('isReplicaSet') else Servers
                instance = klass()._storage[instance_id]
                restart_with_auth(instance)

            self.restart_required = False
Esempio n. 16
0
 def setUp(self):
     PortPool().change_range()
     self.mongod = os.path.join(os.environ.get('MONGOBIN', ''), 'mongod')
     self.server = Server(self.mongod, {})