docs: def user_upsert(self, domain, userid, password=None, roles=None, name=None):
          """
          Upsert a user in the cluster
  
          :param AuthDomain domain: The authentication domain for the user.
          :param userid: The user ID
          :param password: The user password
          :param roles: A list of roles. A role can either be a simple string,
              or a list of `(role, bucket)` pairs.
          :param name: Human-readable name
          :raise: :exc:`couchbase.exceptions.HTTPError` if the request fails.
          :return: :class:`~.HttpResult`
  
          Creating a new read-only admin user ::
  
              adm.upsert_user(AuthDomain.Local, 'mark', 's3cr3t', ['ro_admin'])
  
          An example of using more complex roles ::
  
              adm.upsert_user(AuthDomain.Local, 'mark', 's3cr3t',
                                                [('data_reader', '*'),
                                                 ('data_writer', 'inbox')])
  
  
          .. warning::
  
             Due to the asynchronous nature of Couchbase management APIs, it may
             take a few moments for the new user settings to take effect.
          """
          if not roles or not isinstance(roles, list):
              raise E.ArgumentError("Roles must be a non-empty list")
  
          if password and domain == AuthDomain.External:
              raise E.ArgumentError("External domains must not have passwords")
          tmplist = []
          for role in roles:
              if isinstance(role, basestring):
                  tmplist.append(role)
              else:
                  tmplist.append('{0}[{1}]'.format(*role))
  
          role_string = ','.join(tmplist)
          params = {
              'roles': role_string,
          }
  
          if password:
              params['password'] = password
          if name:
              params['name'] = name
  
          form = self._mk_formstr(params)
          path = self._get_management_path(domain, userid)
          return self.http_request(path=path,
                                   method='PUT',
                                   content_type='application/x-www-form-urlencoded',
                                   content=form)