def __init__(self, rs_params):
        """create replica set according members config
        Args:
            rs_params - replica set configuration
        """
        self.server_map = {}
        self.auth_key = rs_params.get('auth_key', None)
        self.login = rs_params.get('login', '')
        self.password = rs_params.get('password', '')
        self.repl_id = rs_params.get('id', None) or str(uuid4())
        self._version = rs_params.get('version')

        self.sslParams = rs_params.get('sslParams', {})
        self.kwargs = {}

        if not not self.sslParams:
            self.kwargs['ssl'] = True

        config = {
            "_id":
            self.repl_id,
            "members": [
                self.member_create(member, index)
                for index, member in enumerate(rs_params.get('members', {}))
            ]
        }
        logger.debug("replica config: {config}".format(**locals()))
        if not self.repl_init(config):
            self.cleanup()
            raise ReplicaSetError("Could not create replica set.")

        if self.login:
            logger.debug("add admin user {login}/{password}".format(
                login=self.login, password=self.password))
            try:
                c = self.connection()
                c.admin.add_user(self.login,
                                 self.password,
                                 roles=[
                                     '__system', 'clusterAdmin',
                                     'dbAdminAnyDatabase',
                                     'readWriteAnyDatabase',
                                     'userAdminAnyDatabase'
                                 ])
                # Make sure user propagates to secondaries before proceeding.
                c.admin.authenticate(self.login, self.password)
                c.admin.command('getLastError', w=len(self.servers()))
            except pymongo.errors.OperationFailure:
                reraise(
                    ReplicaSetError,
                    "Could not add user %s to the replica set." % self.login)
            finally:
                c.close()

        if not self.waiting_config_state():
            raise ReplicaSetError(
                "Could not actualize replica set configuration.")
Пример #2
0
 def create(self, rs_params):
     """create new replica set
     Args:
        rs_params - replica set configuration
     Return repl_id which can use to take the replica set
     """
     repl_id = rs_params.get('id', None)
     if repl_id is not None and repl_id in self:
         raise ReplicaSetError(
             "replica set with id={id} already exists".format(id=repl_id))
     repl = ReplicaSet(rs_params)
     self[repl.repl_id] = repl
     return repl.repl_id
Пример #3
0
 def repl_member_add(self, params):
     """create new mongod instances and add it to the replica set.
     Args:
         params - mongod params
     return True if operation success otherwise False
     """
     repl_config = self.config
     member_id = max([member['_id'] for member in repl_config['members']]) + 1
     member_config = self.member_create(params, member_id)
     repl_config['members'].append(member_config)
     if not self.repl_update(repl_config):
         self.member_del(member_id, reconfig=True)
         raise ReplicaSetError("Could not add member to ReplicaSet.")
     return member_id
Пример #4
0
    def __init__(self, rs_params):
        """create replica set according members config
        Args:
            rs_params - replica set configuration
        """
        self.server_map = {}
        self.auth_key = rs_params.get('auth_key', None)
        self.login = rs_params.get('login', '')
        self.auth_source = rs_params.get('authSource', 'admin')
        self.password = rs_params.get('password', '')
        self.admin_added = False
        self.repl_id = rs_params.get('id', None) or str(uuid4())
        self._version = rs_params.get('version')

        self.sslParams = rs_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)

        members = rs_params.get('members', {})
        config = {"_id": self.repl_id, "members": [
            self.member_create(member, index)
            for index, member in enumerate(members)
        ]}
        if 'rsSettings' in rs_params:
            config['settings'] = rs_params['rsSettings']
        # Explicitly set write concern to number of data-bearing members.
        # If we add a user later, we need to guarantee that every node
        # has the user before we authenticate ('majority' is insufficient).
        self._write_concern = len(
            [m for m in members
             if not m.get('rsParams', {}).get('arbiterOnly')]
        )

        logger.debug("replica config: {config}".format(**locals()))
        if not self.repl_init(config):
            self.cleanup()
            raise ReplicaSetError("Could not create replica set.")

        if not self.waiting_config_state():
            raise ReplicaSetError(
                "Could not actualize replica set configuration.")

        if self.login:
            # If the only authentication mechanism enabled is MONGODB-X509,
            # we'll need to add our own user using SSL certificates we already
            # have. Otherwise, the user of MO would have to copy their own
            # certificates to wherever MO happens to be running so that MO
            # might authenticate.
            for member in members:
                proc_params = member.get('procParams', {})
                set_params = proc_params.get('setParameter', {})
                auth_mechs = set_params.get('authenticationMechanisms', '')
                auth_mechs = auth_mechs.split(',')
                if len(auth_mechs) == 1 and auth_mechs[0] == 'MONGODB-X509':
                    self.x509_extra_user = True
                    break

            self._add_users(self.connection()[self.auth_source])
        if self.restart_required:
            # Restart all the servers with auth flags and ssl.
            for idx, member in enumerate(members):
                server_id = self._servers.host_to_server_id(
                    self.member_id_to_host(idx))
                server = self._servers._storage[server_id]
                # If this is an arbiter, we can't authenticate as the user,
                # so don't set the login/password.
                if not member.get('rsParams', {}).get('arbiterOnly'):
                    server.x509_extra_user = self.x509_extra_user
                    server.auth_source = self.auth_source
                    server.login = self.login
                    server.password = self.password

                def add_auth(config):
                    if self.auth_key:
                        config['keyFile'] = self.key_file
                    config.update(member.get('procParams', {}))
                    return config

                server.restart(config_callback=add_auth)
            self.restart_required = False

        if not self.waiting_member_state() and self.waiting_config_state():
            raise ReplicaSetError(
                "Could not actualize replica set configuration.")
        for i in range(100):
            if self.connection().primary:
                break
            time.sleep(0.1)
        else:
            raise ReplicaSetError("No primary was ever elected.")