Exemplo n.º 1
0
    def update_bucket(
            self,  # type: BucketManager
            settings,  # type: BucketSettings
            *options,  # type: UpdateBucketOptions
            **kwargs  # type: Any
    ):
        """
        Updates a bucket. Every setting must be set to what the user wants it to be after the update.
        Any settings that are not set to their desired values may be reverted to default values by the server.

        :param BucketSettings settings: settings for updating the bucket.
        :param UpdateBucketOptions options: options for updating the bucket.
        :param Any kwargs: override corresponding values in the options.

        :raises: InvalidArgumentsException
        :raises: BucketDoesNotExistException
        """

        # prune the missing settings...
        params = settings.as_dict()  #*options, **kwargs)

        # insure flushEnabled is an int
        params['flushEnabled'] = int(params.get('flushEnabled', 0))

        # send it
        return self._admin_bucket.http_request(
            path='/pools/default/buckets/' + settings.name,
            method='POST',
            content_type='application/x-www-form-urlencoded',
            content=mk_formstr(params),
            **forward_args(kwargs, *options))
Exemplo n.º 2
0
    def upsert_group(
            self,  # type: UserManager
            group,  # type: Group
            *options,  # type: UpsertGroupOptions
            **kwargs):
        """
        Add or replace a group.

        :warning: Does not appear to work correctly yet - tracked here: https://issues.couchbase.com/browse/PYCBC-667

        :param Group group: the new version of the group.
        :param Duration timeout: the time allowed for the operation to be terminated. This is controlled by the client.
        :raises: InvalidArgumentsException
        """
        # This endpoint accepts application/x-www-form-urlencoded and requires the data be sent as form data.
        # The name/id should not be included in the form data.
        # Roles should be a comma separated list of strings.
        # If, only if, the role contains a bucket name then the rolename should be suffixed
        # with[<bucket_name>] e.g. bucket_full_access[default],security_admin.

        group_dict = group.as_dict()
        form_data = mk_formstr(group_dict)
        self._admin_bucket.http_request(
            "/settings/rbac/groups/{}".format(group.name), 'PUT', form_data,
            **forward_args(kwargs, *options))
Exemplo n.º 3
0
    def create_bucket(
            self,  # type: BucketManager
            settings,  # type: CreateBucketSettings
            *options,  # type: CreateBucketOptions
            **kwargs  # type: Any
    ):
        """
        Creates a new bucket.

        :param: CreateBucketSettings settings: settings for the bucket.
        :param: CreateBucketOptions options: options for setting the bucket.
        :param: Any kwargs: override corresponding values in the options.

        :raises: BucketAlreadyExistsException
        :raises: InvalidArgumentsException
        """
        # prune the missing settings...
        params = settings.as_dict()

        # insure flushEnabled is an int
        params['flushEnabled'] = int(params.get('flushEnabled', 0))

        # ensure replicaIndex is an int, if specified
        if 'replicaIndex' in params:
            params['replicaIndex'] = 1 if params['replicaIndex'] else 0

        # send it
        return self._admin_bucket.http_request(
            path='/pools/default/buckets',
            method='POST',
            content=mk_formstr(params),
            content_type='application/x-www-form-urlencoded',
            **forward_args(kwargs, *options))
Exemplo n.º 4
0
    def create_bucket(self,      # type: BucketManager
                      settings,  # type: CreateBucketSettings
                      *options,  # type: CreateBucketOptions
                      **kwargs   # type: Any
                      ):
        """
        Creates a new bucket.

        :param: CreateBucketSettings settings: settings for the bucket.
        :param: CreateBucketOptions options: options for setting the bucket.
        :param: Any kwargs: override corresponding values in the options.

        :raises: BucketAlreadyExistsException
        :raises: InvalidArgumentsException
        """
        # prune the missing settings...
        params = ({k:v for k,v in settings.items() if (v is not None)})

        # insure flushEnabled is an int
        params['flushEnabled'] = int(params.get('flushEnabled', None))

        # send it
        return self._admin_bucket.http_request(
            path='/pools/default/buckets',
            method='POST',
            content=mk_formstr(params),
            content_type='application/x-www-form-urlencoded',
            **forward_args(kwargs, *options))
    def create_collection(
            self,  # type: CollectionManager
            collection,  # type: CollectionSpec
            *options,  # type: CreateCollectionOptions
            **kwargs  # type: Any
    ):
        """
        Creates a new collection.

        :param CollectionSpec collection: specification of the collection.
        :param CreateCollectionOptions options:  options (currently just timeout).
        :param kwargs: keyword version of 'options'
        :return:
        :raises: InvalidArgumentsException
        :raises: CollectionAlreadyExistsException
        :raises: ScopeNotFoundException
        """

        params = {'name': collection.name}
        if collection.max_ttl:
            params['maxTTL'] = int(collection.max_ttl.total_seconds())

        form = mk_formstr(params)
        kwargs.update({
            'path':
            '{}/{}/collections'.format(self.base_path, collection.scope_name),
            'method':
            'POST',
            'content_type':
            'application/x-www-form-urlencoded',
            'content':
            form
        })
        return self._admin_bucket.http_request(
            **forward_args(kwargs, *options))
    def create_scope(
            self,  # type: CollectionManager
            scope_name,  # type: str
            *options,  # type: CreateScopeOptions
            **kwargs  # type: Any
    ):
        # type: (...) -> None
        """
        Creates a new scope.

        :param str scope_name: name of the scope.
        :param CreateScopeOptions options: options (currently just timeout).
        :param kwargs: keyword version of `options`
        :return:

        :raises: InvalidArgumentsException
        Any exceptions raised by the underlying platform
        Uri
        POST http://localhost:8091/pools/default/buckets/<bucket>/collections -d name=<scope_name>
        """
        params = {'name': scope_name}

        form = mk_formstr(params)
        kwargs.update({
            'path': self.base_path,
            'method': 'POST',
            'content_type': 'application/x-www-form-urlencoded',
            'content': form
        })

        self._admin_bucket.http_request(**forward_args(kwargs, *options))
Exemplo n.º 7
0
    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.HTTPException` 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.InvalidArgumentException("Roles must be a non-empty list")

        if password and domain == AuthDomain.External:
            raise E.InvalidArgumentException(
                "External domains must not have passwords")
        role_string = self._gen_role_list(roles)
        params = {
            'roles': role_string,
        }

        if password:
            params['password'] = password
        if name:
            params['name'] = name

        form = 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)
Exemplo n.º 8
0
    def bucket_create(self, name, **kwargs):
        """
        Create a new bucket

        :param string name: The name of the bucket to create
        :param string bucket_type: The type of bucket to create. This
            can either be `couchbase` to create a couchbase_core style
            bucket (which persists data and supports replication) or
            `memcached` (which is memory-only and does not support
            replication).
            Since Couchbase version 5.0, you can also specify
            `ephemeral`, which is a replicated bucket which does
            not have strict disk persistence requirements
        :param string bucket_password: The bucket password. This can be
            empty to disable authentication. This can be changed later on
            using :meth:`update_bucket`
        :param int replicas: The number of replicas to use for this
            bucket. The maximum number of replicas is currently 3.
            This setting can be changed via :meth:`update_bucket`
        :param int ram_quota:
            The maximum amount of memory (per node) that this bucket
            may use, in megabytes. The minimum for this value is 100.
            This setting may be changed via :meth:`update_bucket`.
        :param bool flush_enabled:
            Whether the flush API is enabled. When the flush API is
            enabled, any client connected to the bucket is able to
            clear its contents. This may be useful in development but
            not recommended in production. This setting may be changed
            via :meth:`update_bucket`
        :return: A :class:`~.HttpResult`
        :raise: :exc:`~.HTTPException` if the bucket could not be created.
        """
        final_opts = dict(**Admin.bc_defaults)
        final_opts.update(
            **{k: v
               for k, v in kwargs.items() if (v is not None)})
        params = {
            'name': name,
            'bucketType': final_opts['bucket_type'],
            'authType': 'sasl',
            'saslPassword': final_opts['bucket_password'],
            'flushEnabled': int(final_opts['flush_enabled']),
            'ramQuotaMB': final_opts['ram_quota']
        }
        if final_opts['bucket_type'] in ('couchbase', 'membase', 'ephemeral'):
            params['replicaNumber'] = final_opts['replicas']

        return self.http_request(
            path='/pools/default/buckets',
            method='POST',
            content=mk_formstr(params),
            content_type='application/x-www-form-urlencoded')
Exemplo n.º 9
0
    def group_upsert(self,
                     group_name,
                     roles=None,
                     description=None,
                     ldap_group_reference=None,
                     timeout=None):
        """
        Upsert a group in the cluster

        :param group_name: The name of the group
        :param roles: A list of roles
        :param description: The description of the group
        :param ldap_group_reference: The external LDAP group reference
        :param timeout: time allowed for operation to be terminated.
            This is controlled by the client.

        :raise: :exc:`couchbase.exceptions.HTTPException` if the request fails.

        :return: :class:`~.HttpResult`

        .. warning::

           Due to the asynchronous nature of Couchbase management APIs, it may
           take a few moments for the new user settings to take effect.
        """
        params = {}
        if roles:
            params['roles'] = ','.join(
                list(map(lambda r: r.to_server_str(), roles)))

        if description:
            params['description'] = description

        if ldap_group_reference:
            params['ldap_group_ref'] = ldap_group_reference

        path = "/settings/rbac/groups/{}".format(group_name)
        form = mk_formstr(params)
        return self.http_request(
            path=path,
            method='PUT',
            content_type='application/x-www-form-urlencoded',
            content=form,
            timeout=timeout)
Exemplo n.º 10
0
    def user_upsert(self,
                    username,
                    domain,
                    password=None,
                    roles=None,
                    groups=None,
                    name=None,
                    timeout=None):
        """
        Upsert a user in the cluster

        :param username: The new username or user to update
        :param AuthDomain domain: The authentication domain for the user.
        :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: role display name
        :param timeout: time allowed for operation to be terminated.
            This is controlled by the client.
        :raise: :exc:`couchbase.exceptions.HTTPException` if the request fails.
        :return: :class:`~.HttpResult`

        Creating a new read-only admin user ::

            adm.user_upsert(AuthDomain.Local, 'mark', 's3cr3t', ['ro_admin'])

        An example of using more complex roles ::

            adm.user_upsert(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 groups and (not roles or not isinstance(roles, list)):
            raise E.InvalidArgumentException("Roles must be a non-empty list")

        if isinstance(domain, AuthDomain):
            domain = AuthDomain.to_str(domain)

        if password and domain == "external":
            raise E.InvalidArgumentException(
                "External domains must not have passwords")

        params = {}
        if roles:
            params['roles'] = ','.join(
                list(map(lambda r: r.to_server_str(), roles)))
        # For backwards compatibility with Couchbase Server 6.0 and earlier,
        # the "groups" parameter MUST be omitted if the group list is empty.
        # Couchbase Server 6.5 treats the absent parameter the same as an
        # explicit parameter with no value (removes any existing group associations,
        # which is what we want in this case).
        if groups and self._is_6_5_plus():
            params['groups'] = ','.join(groups)
        if password:
            params['password'] = password
        if name:
            params['name'] = name

        form = mk_formstr(params)
        path = self._get_management_path(domain, username)
        return self.http_request(
            path=path,
            method='PUT',
            content_type='application/x-www-form-urlencoded',
            content=form,
            timeout=timeout)
Exemplo n.º 11
0
    def bucket_update(self,
                      current,
                      bucket_password=None,
                      replicas=None,
                      ram_quota=None,
                      flush_enabled=None,
                      **kwargs):
        """
        Update an existing bucket's settings.

        :param string name: The name of the bucket to update
        :param dict current: Current state of the bucket.
            This can be retrieve from :meth:`bucket_info`
        :param str bucket_password: Change the bucket's password
        :param int replicas: The number of replicas for the bucket
        :param int ram_quota: The memory available to the bucket
            on each node.
        :param bool flush_enabled: Whether the flush API should be allowed
            from normal clients
        :return: A :class:`~.HttpResult` object
        :raise: :exc:`~.HTTPError` if the request could not be
            completed


        .. note::

            The default value for all options in this method is
            ``None``. If a value is set to something else, it will
            modify the setting.


        Change the bucket password::

            adm.bucket_update('a_bucket', adm.bucket_info('a_bucket'),
                              bucket_password='******')

        Enable the flush API::

            adm.bucket_update('a_bucket', adm.bucket_info('a_bucket'),
                              flush_enabled=True)
        """
        params = {}
        current = current.value
        name = kwargs.pop('name')
        # Merge params
        params['authType'] = current['authType']
        if 'saslPassword' in current:
            params['saslPassword'] = current['saslPassword']

        if bucket_password is not None:
            params['authType'] = 'sasl'
            params['saslPassword'] = bucket_password

        params['replicaNumber'] = (replicas if replicas is not None else
                                   current['replicaNumber'])

        if ram_quota:
            params['ramQuotaMB'] = ram_quota
        else:
            params['ramQuotaMB'] = int(current['quota']['rawRAM'] / 1024 /
                                       1024)

        if flush_enabled is not None:
            params['flushEnabled'] = int(flush_enabled)

        proxy_port = current.get('proxyPort')
        if proxy_port:
            params['proxyPort'] = proxy_port

        params.update({k: v for k, v in kwargs.items() if (v is not None)})
        return self._admin_bucket.http_request(
            path='/pools/default/buckets/' + name,
            method='POST',
            content_type='application/x-www-form-urlencoded',
            content=mk_formstr(params))