{% extends "internal_base.html" %} {% block meta %} Cheriff · WS · {{ workspace['name'] }} {% end %} {% block style %} {% try %} {% module Template("webpack_templates/cheriff-styles.html") %} {% except %} {% end %} {% end %} {% block content %}

{% if workspace['deleted'] %}Deleted {% end %} Workspace > {{ workspace['name'] }}

{% if workspace['deleted'] or is_branch %} {% end %} {% if main %} {% end %} {% if workspace['deleted'] %} {% end %}
Database {{workspace['database']}}
Members {{len(workspace['members'])}}
Max seats {{workspace['max_seats_limit']}}
Plan {{workspace['plan']}}
Organization {{ organization_name }}
Hard delete workspace
{% module xsrf_form_html() %}
Main workspace {{ main['name'] }}
Created at {{ workspace['created_at'] }}
Deleted at {{ workspace['deleted_date'] }}

Settings

Seats

{% module xsrf_form_html() %}

Add user to workspace

{% module xsrf_form_html() %}

Billing

Current plan: {{ workspace['plan']}}

{% module xsrf_form_html() %}

Please be careful to upgrade a Workspace to "pro" as that plan needs to have the proper Stripe configuration. If you need to do it for a test environment, use the Workspace upgrade flow with a test card from Stripe.

Plan details

{{ plan_details }}

Override billing configs

{% for name, value in current_billing_config_overrides %} {% module xsrf_form_html() %} {% end %} {% if available_billing_config_overrides %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Members

{% for u in sorted(users, key = lambda user: user['created_at'], reverse=True) %} {% end %}
Email Role Actions
{{u['email']}} {{ u['role'] }}
{% module xsrf_form_html() %} {% set relationship = u['role'] %}
{% module xsrf_form_html() %}

Branches

{% for branch in sorted(branches, key = lambda branch: branch['created_at'], reverse=True) %} {% end %}
Name Database Created at
{{branch['name']}} {{branch['database']}} {{branch['created_at']}}

Releases

{% for release in sorted(releases, key = lambda release: release['semver'], reverse=True) %} {% module xsrf_form_html() %} {% if release['status'] == 'preview' %} {% end %} {% if release['status'] == 'live' %} {% end %} {% if release['status'] in ['rollback','failed', 'deploying'] %} {% end %} {% end %}
id Semver Commit Status Metadata Change status
{{release['id']}} {{release['semver']}} {{release['commit']}} {{release['status']}} {{release['metadata_id']}}

Remote settings

{% module xsrf_form_html() %}

Database settings

Change server

{% module xsrf_form_html() %}

Enabled clusters

{% if available_clusters_error is not None %}

Could not list available clusters.
Reason: {{ available_clusters_error }}

{% else %}
{% module xsrf_form_html() %}

{% end %}

Create datatabase

Use this action to create the database if the Workspace's server or the Workspace's cluster has been changed.

{% module xsrf_form_html() %}

Query API limits

If you want to set a limit to an endpoint use Endpoint Limits.
For Workspace rate limits use Rate Limits or change the Workspace plan.
To limit concurrency in the CH cluster enable DISTRIBUTED_ENDPOINT_CONCURRENCY FF and use `max_concurrency_queries`, the number is global, so to limit to 10 concurrent queries, set it to 10.
Setting max concurrency queries to 0 means we will not limit the concurrency of the endpoint.

{% for name, config in current_query_api_limits.items() %} {% module xsrf_form_html() %} {% end %} {% if available_query_api_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Query API Value Actions
{{ config['endpoint_name']}} - {{ config['limit_setting'] }}
{% set limit_value = 0 %} {% set limit_endpoint_name = "" %} {% set limit_setting = "" %}
You cannot set new Query API limits.

Endpoint Limits

If you want to set a limit to a new endpoint, you need to publish it first.
To limit concurrency in the CH cluster enable DISTRIBUTED_ENDPOINT_CONCURRENCY FF and use `max_concurrency_queries`, the number is global, so to limit to 10 concurrent queries, set it to 10.
Setting max concurrency queries to 0 means we will not limit the concurrency of the endpoint.
Setting max threads to 0 means we will use the default value.
Setting backend hint to 1 will disable the default sticky behaviour. It forces the endpoint to backend_hint = None.
Setting max rps to 0 means we will not limit the amount of requests per second for the endpoint.
Do not use max_rps to limit concurrency, use max_concurrent_queries, or use max_rps and set max_execution_time to 1s both together. For max threads and backend hint, the priority setting is: Workspace Limit > Query template setting > Endpoint Limit > Default setting.

{% for name, config in current_endpoint_limits.items() %} {% module xsrf_form_html() %} {% end %} {% if available_endpoint_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Endpoint Value Actions
{{ config['endpoint_name']}} - {{ config['limit_setting'] }}
{% set limit_value = 0 %} {% set limit_endpoint_name = "" %} {% set limit_setting = "" %}
You cannot set new endpoint limits: All the endpoints has all limits defined or there is not endpoint published.

ClickHouse Limits

{% for name, value in current_ch_limits %} {% module xsrf_form_html() %} {% end %} {% if available_ch_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

HFI Configuration

{% module xsrf_form_html() %} {% module xsrf_form_html() %} {% module xsrf_form_html() %} {% module xsrf_form_html() %} {% module xsrf_form_html() %} {% module xsrf_form_html() %} {% module xsrf_form_html() %} {% module xsrf_form_html() %}
Name Value Actions
HFI frequency (CH pushes/second/worker. Empty for default value: {{default_hfi_frequency}})
HFI frequency through the Gatherer (CH pushes/second/worker. Empty for default value: {{default_hfi_frequency_gatherer}})
HFI database server (empty to default to the "normal" database server)
HFI concurrency limit (Per datasource. Empty for default value: {{default_hfi_semaphore_counter}})
HFI concurrency timeout limit (Per Datasource. Empty for default value: {{default_hfi_semaphore_timeout}})
HFI max request size (in MB, empty for default value: {{default_hfi_max_request_mb}})
Ratio of wait=false traffic through the Gatherer [0-1]: (Empty for default value: {{default_gatherer_wait_false_traffic}})
Ratio of wait=true traffic through the Gatherer [0-1]: (Empty for default value: {{default_gatherer_wait_true_traffic}})

Gatherer Configuration

{% if workspace['use_gatherer'] %}

Use of Gatherer for HFI and Kafka is enabled

{% else %}

Use of Gatherer for HFI and Kafka is disabled

{% end %} {% if workspace['allow_gatherer_fallback'] %}

Allow HFI to insert directly into the landing when no Gatherer is present is enabled

{% else %}

Allow inserting directly into the landing when no Gatherer is present is disabled

{% end %} {% if workspace['gatherer_allow_s3_backup_on_user_errors'] %}

Allow S3 backups on user errors is enabled

{% else %}

Allow S3 backups on user errors is disabled

{% end %} {% module xsrf_form_html() %} {% module xsrf_form_html() %} {% for name, value in current_gatherer_flush_time_ds %} {% module xsrf_form_html() %} {% end %} {% module xsrf_form_html() %} {% for name, value in current_gatherer_ch_limits %} {% module xsrf_form_html() %} {% end %} {% if available_gatherer_ch_limits %} {% module xsrf_form_html() %} {% else %} {% end %} {% for name, value in current_gatherer_multiwriter_limits %} {% module xsrf_form_html() %} {% end %} {% if available_gatherer_multiwriter_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
Gatherer Flush Interval: (default: {{default_gatherer_flush_interval}} seconds)
Gatherer Deduplication: (default: Value set in the Gatherer at gatherer.ini})
Gatherer flush time per table
{{ name }}
DS id:
ClickHouse configuration
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.
Multiwriter configuration
{{ name }}
{% set limit_value = 5 %}
You cannot set new multiwriter limits: the user already has all limits defined.
{% if len(storage_policies) %}

S3 Configuration

{% module xsrf_form_html() %}
Name Value Actions
S3 Storage Policy: {{ workspace['storage_policy'] if workspace['storage_policy'] else 'No policy applied' }}
{% end %}

Kafka Limits

{% for name, value in current_kafka_limits %} {% module xsrf_form_html() %} {% end %} {% if available_kafka_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Populate Limits

{% for name, value in current_populate_limits %} {% module xsrf_form_html() %} {% end %} {% if available_populate_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Copy Limits

{% for name, value in current_copy_limits %} {% module xsrf_form_html() %} {% end %} {% if available_copy_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Branch Copy Limits

To override a branch copy limit, it should exist as a copy limit. If you need to override a default value in the branch, add the limit in the Copy Limits section with the same value as the default.

These limits are only automatically applied on branch creation, not in branches that already exist. For existing branches, you can go to the Cheriff page of the branch.

{% for name, value in current_copy_branch_limits %} {% module xsrf_form_html() %} {% end %} {% if available_copy_branch_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Data Sinks Limits

{% for name, value in current_sinks_limits %} {% module xsrf_form_html() %} {% end %} {% if available_sinks_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

DynamoDB Limits

{% for name, value in current_dynamodb_limits %} {% module xsrf_form_html() %} {% end %} {% if available_sinks_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Delete Limits

{% for name, value in current_delete_limits %} {% module xsrf_form_html() %} {% end %} {% if available_delete_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Iterating Limits

{% for name, value in current_iterating_limits %} {% module xsrf_form_html() %} {% end %} {% if available_iterating_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 3 %}
You cannot set new limits: the user already has all limits defined.

Rate Limits

Options

  • Count: Number of requests allowed per time period.
    Must be greater than zero.
  • Period: The time extent in seconds of the check.
    Must be greater than zero.
  • Max Burst: Number of requests that will be allowed to exceed the rate in a single burst.
    Must be greater than or equal to zero.
    To allow some momentary flexibility, you have to set this value higher than 0. Think about this as if you were consuming tokens from the future count. When in doubt, set the max burst value to match the count value.

Examples

  • count=6, period=60, burst=0: allow 6 requests per minute.
    With burst set to zero, you will have to wait 10 seconds between requests.
    This is equivalent to count=1, period=10, burst=0 or 1 request every 10 seconds.
  • count=5, period=60, burst=3: allow 5 requests per minute but momentary bursts of 3 requests.
    This means that you will not have to wait 12 seconds between requests as you are allowed to do 3 consecutive requests.
{% for name, rl_config in current_rate_limit_config %} {% module xsrf_form_html() %} {% end %} {% if available_rate_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Count Period (seconds) Max Burst Actions
{{ name }}
{% set limit_count = 5 %} {% set limit_period = 60 %} {% set limit_max_burst = 5 %}
You cannot set new limits: the user already has all limits defined.

Import Limits

{% for name, value in current_import_limits %} {% module xsrf_form_html() %} {% end %} {% if available_import_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

CDK Limits

⚠️ The change of any of these limits will only affect connections created from that moment forward


{% for name, value in current_cdk_limits %} {% module xsrf_form_html() %} {% end %} {% if available_cdk_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Workspace Limits


{% for name, value in current_workspace_limits %} {% module xsrf_form_html() %} {% end %} {% if available_workspace_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Release Limits

{% for name, value in current_release_limits %} {% module xsrf_form_html() %} {% end %} {% if available_release_limits %} {% module xsrf_form_html() %} {% else %} {% end %}
Name Value Actions
{{ name }}
{% set limit_value = 5 %}
You cannot set new limits: the user already has all limits defined.

Feature Flags

{% for flag, value, is_override in workspace_feature_flags %} {% end %}
Name Status Actions
{{ flag['name'] }}
{% raw flag['description'] %}
{% if value %} Activated{% if is_override %}*{% end %} {% else %} Deactivated{% if is_override %}*{% end %} {% end %}
{% module xsrf_form_html() %} {% if value %} {% else %} {% end %}
{% if is_override %}
{% module xsrf_form_html() %}
{% end %}

Postgres connector settings

{% module xsrf_form_html() %}

Database {{workspace['database']}}
User user_{{workspace['database']}}
{% module xsrf_form_html() %} {% if workspace['enabled_pg'] %}

Postgres connector is enabled

{% else %}

Postgres connector is deactivated

{% end %}

Database operations

After clicking on "Create database" make sure to change the password

{% module xsrf_form_html() %}

{% module xsrf_form_html() %}

{% module xsrf_form_html() %}

Change password

This runs an "ALTER ROLE" in the PostgreSQL instance. Once changed, the connector is ready and the user and password can be shared with the customer.

{% module xsrf_form_html() %}

ClickHouse BI Connector

Mirror DataSources and Endpoints to a ClickHouse BI Connector machine. It might not account for all cases. If you want to try, we'll need to provide you with the CH BI Server Address. Let us know in #tmp-bi-connector.

{% module xsrf_form_html() %}

Database {{workspace['database']}}
User user_{{workspace['name']}}

Data Connectors

{% if data_connectors %} {% for connector in data_connectors %}
Name ID Type
{{connector['name']}} {{connector['id']}} {{connector['service']}}
Connector settings
{% module xsrf_form_html() %} {% for setting in connector['settings'] %} {% end %}
Setting Value
{{ setting }}
Linkers {% if connector['linkers'] %}
{% module xsrf_form_html() %}
{% end %} {% for linker in connector['linkers'] %}
{% module xsrf_form_html() %} {% for linker_setting in linker['settings'] %} {# Deprecated settings that we don't use anymore but still can exist in Redis #} {% if linker_setting not in ['token', 'json_deserialization', 'gatherer_enabled'] %} {% end %} {% end %} {% if connector['service']== 'kafka' %} {% if 'kafka_store_raw_value' not in linker['settings'] %} {% end %} {% if 'kafka_store_binary_headers' not in linker['settings'] %} {% end %} {% end %} {% if connector['service']== 'dynamodb' %} {% if 'linker_workers' not in linker['settings'] %} {% end %} {% if 'dynamodb_min_time_between_iterations' not in linker['settings'] %} {% end %} {% if 'dynamodb_sleep_closed_shards' not in linker['settings'] %} {% end %} {% if 'dynamodb_sleep_open_shards' not in linker['settings'] %} {% end %} {% if 'dynamodb_sleep_closed_shard_cursor' not in linker['settings'] %} {% end %} {% if 'dynamodb_sleep_open_shard_cursor' not in linker['settings'] %} {% end %} {% if 'dynamodb_max_records_read' not in linker['settings'] %} {% end %} {% if 'dynamodb_max_shards_read_from_redis' not in linker['settings'] %} {% end %} {% end %}
Setting Value
id {{ linker['id'] }}
name {{ linker['name'] }}
{{ linker_setting }}
kafka_store_raw_value
kafka_store_binary_headers
linker_workers
dynamodb_min_time_between_iterations
dynamodb_sleep_closed_shards
dynamodb_sleep_open_shards
dynamodb_sleep_closed_shard_cursor
dynamodb_sleep_open_shard_cursor
dynamodb_max_records_read
dynamodb_max_shards_read_from_redis
json_deserialization
data_connector_id
{% end %}
{% end %} {% else %}

No settings

{% end %}

Kafka

{% module xsrf_form_html() %}


This value will sent kafka traffic of this workspace to tbakafka cluster labeled with the kafka server group value.
Empty to use default cluster

External Datasources Integration

{% if workspace.cdk_gcp_service_account %}

Hard-delete GCP Service account

Panic button to delete the workspace's service account in case there is some leak. WARNING: Once this is used all permissions granted by the user to the account will be lost and all schedules in the workspace will lose access to BQ.

{% module xsrf_form_html() %}

{% else %}

No GCP service account provisioned

{% end %}

Token restoration

{% module xsrf_form_html() %}

This section allows you to restore a token with a previous one in the case of an accidental "refresh" by a customer.


  • Please be extra careful when using this feature!
  • Beware of social engineering! If a customer asked you for this, try to get verification using an alternate channel (phone or video call, for example)


Note: this token will be erased.


Note: this token will be restored.


As a safety measure, please, write the name of the workspace where you want to make the change.

Query Profiles

{% for name, value in profiles.items() %} {% module xsrf_form_html() %} {% end %} {% module xsrf_form_html() %}
Name Value Actions
{{ name }}

Tags

{% if tags_error %}

{{ tags_error }}

{% else %} {% if len(tags) > 0 %} {% try %}
{% for tag in tags %} {% end %}
Tag Resources
{{ tag.name }} {% for resource in tag.resources %} {{ resource.get('name', '') }} - {{ resource.get('id') }}
{% end %}
{% except %} There was an exception while rendering the tags {% end %} {% else %}

No tags found

{% end %} {% end %}
{% set resources, edges = graph %}

Tables and Materialized Views

{% for r in sorted(resources, key=lambda r: r.name) %} {% if r.resource in ('Datasource', 'OrphanTable', 'MaterializedNode') %} {% end %} {% end %}
Data Source Table Engine Disk usage Hosts Clusters
{{ r.name }} {{ r.id }} {{ tables.get(r.id, {}).get('engine', 'Unknown') }} {{ tables.get(r.id, {}).get('disk_usage', 'Unknown') }} {% set hosts = tables.get(r.id, {}).get('hosts', {}) %}
    {% for h in available_hosts %}
  • {{ h }}
  • {% end %}
{% set clusters = tables.get(r.id, {}).get('clusters', {}) %} {{ clusters if clusters else 'None' }}

Data lineage

{% end %}