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.")
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
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
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.")