Select Plan
@@ -239,6 +244,7 @@
:isPrivateBenchSite="!!bench"
:isDedicatedServerSite="isDedicatedServerSite"
:serverPlanPrice="serverPriceUsd"
+ :serverserverSupportQuotaAvailable="serverSupportQuotaAvailable"
:selectedCluster="cluster"
:selectedApps="apps"
:selectedVersion="version"
@@ -423,6 +429,7 @@ export default {
useDedicatedServer: false,
selectedDedicatedServer: null,
serverPriceUsd: null,
+ serverSupportQuotaAvailable: null,
};
},
watch: {
@@ -504,6 +511,8 @@ export default {
this.cluster = server.cluster;
this.provider = server.provider;
this.serverPriceUsd = server.price_usd;
+ this.serverSupportQuotaAvailable =
+ server.product_warranty?.total > server.product_warranty?.consumed;
}
},
subdomain: {
diff --git a/press/api/site.py b/press/api/site.py
index 4bed6ed5080..f0757697df9 100644
--- a/press/api/site.py
+++ b/press/api/site.py
@@ -16,6 +16,7 @@
from frappe.query_builder.terms import ValueWrapper
from frappe.rate_limiter import rate_limit
from frappe.utils import flt, sbool, time_diff_in_hours
+from frappe.utils.data import format_datetime, get_datetime
from frappe.utils.password import get_decrypted_password
from frappe.utils.typing_validations import validate_argument_types
from frappe.utils.user import is_system_user
@@ -29,7 +30,15 @@
)
from press.press.doctype.remote_file.remote_file import get_remote_key
from press.press.doctype.server.server import is_dedicated_server
-from press.press.doctype.site.site import Site, get_updates_between_current_and_next_apps
+from press.press.doctype.site.site import (
+ Site,
+ get_updates_between_current_and_next_apps,
+)
+from press.press.doctype.site.site_plan_utils import (
+ attach_warranty_info_to_dedicated_servers,
+ get_next_allowed_dedicated_product_warranty_change_date,
+ is_product_warranty_enabled_for_plan_,
+)
from press.press.doctype.site_plan.plan import Plan
from press.press.doctype.site_update.site_update import benches_with_available_update
from press.utils import (
@@ -185,7 +194,7 @@ def _new(site, server: str | None = None, ignore_plan_validation: bool = False):
plan = site["plan"]
app_plans = site.get("selected_app_plans")
if not ignore_plan_validation:
- validate_plan(bench.server, plan)
+ validate_plan(bench.server, plan, is_new=True)
site = frappe.get_doc(
{
@@ -242,7 +251,9 @@ def get_group_for_new_site_and_set_localisation_app(site, apps):
# if localisation country is selected, move site to a public bench with the same localisation app
localisation_app = frappe.db.get_value(
- "Marketplace Localisation App", {"country": localisation_country}, "marketplace_app"
+ "Marketplace Localisation App",
+ {"country": localisation_country},
+ "marketplace_app",
)
restricted_release_group_names = frappe.db.get_all(
"Site Plan Release Group",
@@ -273,13 +284,15 @@ def get_group_for_new_site_and_set_localisation_app(site, apps):
@validate_argument_types
-def validate_plan(server: str, plan: str) -> None:
- if not frappe.db.exists("Site Plan", plan):
- frappe.throw(f"Plan {plan} does not exist", frappe.DoesNotExistError) # nosemgrep
+def validate_plan(server: str, site: str, new_plan: str, is_new: bool = False) -> None:
+ if not frappe.db.exists("Site Plan", new_plan):
+ frappe.throw(f"Plan {new_plan} does not exist", frappe.DoesNotExistError) # nosemgrep
+
+ current_site_plan = frappe.get_value("Site", site, "plan")
- site_plan = frappe.db.get_value(
+ new_site_plan = frappe.db.get_value(
"Site Plan",
- plan,
+ new_plan,
[
"price_usd",
"dedicated_server_plan",
@@ -289,17 +302,32 @@ def validate_plan(server: str, plan: str) -> None:
as_dict=True,
)
- if site_plan.get("price_usd", 0) > 0:
+ next_warranty_change = get_next_allowed_dedicated_product_warranty_change_date(site)
+
+ if (
+ not is_new
+ and not is_system_user()
+ and current_site_plan.get("dedicated_server_plan", False)
+ and (
+ is_product_warranty_enabled_for_plan_(current_site_plan)
+ != is_product_warranty_enabled_for_plan_(new_plan)
+ )
+ and get_datetime() < next_warranty_change
+ ):
+ pretty_date = format_datetime(next_warranty_change, "MMM d, YYYY hh:mm a")
+ frappe.throw(f"Cannot change product warranty for this site before {pretty_date}") # nosemgrep
+
+ if new_site_plan.get("price_usd", 0) > 0:
return
if (
- site_plan.get("dedicated_server_plan", 0)
+ new_site_plan.get("dedicated_server_plan", 0)
and frappe.db.get_value("Server", server, "team") == get_current_team()
):
- if not site_plan.get("restrict_based_on_dedicated_server_plan", 0):
+ if not new_site_plan.get("restrict_based_on_dedicated_server_plan", 0):
return
app_server_plan = frappe.db.get_value("Server", server, "plan")
- min_app_server_price_usd = site_plan.get("minimum_server_price_usd", 0)
+ min_app_server_price_usd = new_site_plan.get("minimum_server_price_usd", 0)
app_server_price_usd = frappe.db.get_value("Server Plan", app_server_plan, "price_usd")
if app_server_price_usd >= min_app_server_price_usd:
return
@@ -332,7 +360,9 @@ def new(site):
if selected_dedicated_server:
if localisation_country := site.get("localisation_country"):
localisation_app = frappe.db.get_value(
- "Marketplace Localisation App", {"country": localisation_country}, "marketplace_app"
+ "Marketplace Localisation App",
+ {"country": localisation_country},
+ "marketplace_app",
)
if localisation_app and localisation_app not in apps:
apps.append(localisation_app)
@@ -464,7 +494,9 @@ def create_site_on_private_bench(
if localisation_country:
localisation_app = frappe.db.get_value(
- "Marketplace Localisation App", {"country": localisation_country}, "marketplace_app"
+ "Marketplace Localisation App",
+ {"country": localisation_country},
+ "marketplace_app",
)
if localisation_app:
apps.append(localisation_app)
@@ -700,7 +732,12 @@ def activities(filters=None, order_by=None, limit_start=None, limit_page_length=
SiteActivity = frappe.qb.DocType("Site Activity")
activities = (
frappe.qb.from_(SiteActivity)
- .select(SiteActivity.action, SiteActivity.reason, SiteActivity.creation, SiteActivity.owner)
+ .select(
+ SiteActivity.action,
+ SiteActivity.reason,
+ SiteActivity.creation,
+ SiteActivity.owner,
+ )
.where(SiteActivity.site == filters["site"])
.where((SiteActivity.action != "Backup") | (SiteActivity.owner != "Administrator"))
.orderby(SiteActivity.creation, order=frappe.qb.desc)
@@ -780,11 +817,11 @@ def _get_dedicated_server_info_for_release_group(release_group_name: str) -> dic
Returns dict with:
- case: str - one of:
- - "dedicated_only_single" - exactly one dedicated server
- - "dedicated_only_multiple" - multiple dedicated servers
- - "user_choice_single" - one dedicated server and other public server(s)
- "user_choice_multiple" - multiple dedicated servers and public server(s)
- - "no_dedicated_server"
+ - "dedicated_only_single" - exactly one dedicated server
+ - "dedicated_only_multiple" - multiple dedicated servers
+ - "user_choice_single" - one dedicated server and other public server(s)
+ "user_choice_multiple" - multiple dedicated servers and public server(s)
+ - "no_dedicated_server"
- dedicated_servers: list - Available dedicated servers for user selection
"""
current_team = get_current_team()
@@ -806,6 +843,9 @@ def _get_dedicated_server_info_for_release_group(release_group_name: str) -> dic
filters={"name": ("in", linked_servers), "status": "Active"},
fields=["name", "title", "public", "team", "cluster", "provider"],
)
+
+ servers = attach_warranty_info_to_dedicated_servers(servers)
+
public_servers = [s for s in servers if s.public]
team_private_servers = [s for s in servers if not s.public and s.team == current_team]
@@ -853,9 +893,20 @@ def _get_team_dedicated_server_info(for_server: str | None = None):
servers = frappe.db.get_all(
"Server",
filters=filters,
- fields=["name", "title", "cluster", "provider", "plan", "plan.price_usd as price_usd"],
+ fields=[
+ "name",
+ "title",
+ "cluster",
+ "provider",
+ "plan",
+ "plan.price_usd as price_usd",
+ "public",
+ ],
)
+ if for_server:
+ servers = attach_warranty_info_to_dedicated_servers(servers)
+
if not servers:
if for_server:
frappe.throw(f"Server {for_server} not found") # nosemgrep
@@ -877,7 +928,7 @@ def _get_team_dedicated_server_info(for_server: str | None = None):
@frappe.whitelist()
-def options_for_new(for_bench: str | None = None, for_server: str | None = None): # noqa: C901
+def options_for_new(for_bench: str | None = None, for_server: str | None = None):
from press.press.doctype.cloud_provider.cloud_provider import get_cloud_providers
from press.utils import get_nearest_cluster
@@ -916,7 +967,14 @@ def options_for_new(for_bench: str | None = None, for_server: str | None = None)
marketplace_apps = frappe.db.get_all(
"Marketplace App",
- fields=["title", "image", "description", "app", "route", "subscription_type"],
+ fields=[
+ "title",
+ "image",
+ "description",
+ "app",
+ "route",
+ "subscription_type",
+ ],
filters={"app": ("in", unique_apps)},
)
total_installs_by_app = get_total_installs_by_app()
@@ -975,7 +1033,7 @@ def options_for_new(for_bench: str | None = None, for_server: str | None = None)
"app_source_details": app_source_details_grouped,
"providers": list(unique_providers.values()),
"additional_clusters": private_bench_clusters,
- "dedicated_server_config": _get_team_dedicated_server_info(for_server) if not for_bench else [],
+ "dedicated_server_config": (_get_team_dedicated_server_info(for_server) if not for_bench else []),
}
@@ -1774,7 +1832,10 @@ def get_installed_apps(site, query_filters: dict | None = None):
)
app_source.update(app_tags if app_tags else {})
app_source.subscription_available = bool(
- frappe.db.exists("Marketplace App Plan", {"price_usd": (">", 0), "app": app.app, "enabled": 1})
+ frappe.db.exists(
+ "Marketplace App Plan",
+ {"price_usd": (">", 0), "app": app.app, "enabled": 1},
+ )
)
app_source.billing_type = is_prepaid_marketplace_app(app.app)
if frappe.db.exists(
@@ -2044,7 +2105,9 @@ def validate_restoration_space_requirements(
database_server: DatabaseServer = frappe.get_cached_doc("Database Server", server.database_server)
required_space_on_app_server = site.get_restore_space_required_on_app(
- db_file_size=db_file_size, public_file_size=public_file_size, private_file_size=private_file_size
+ db_file_size=db_file_size,
+ public_file_size=public_file_size,
+ private_file_size=private_file_size,
)
required_space_on_db_server = site.get_restore_space_required_on_db(db_file_size=db_file_size)
@@ -2055,9 +2118,9 @@ def validate_restoration_space_requirements(
if server.public:
"""
- If it's a public server, Frappe Cloud will auto extend the disk space
- to accommodate the restoration.
- """
+ If it's a public server, Frappe Cloud will auto extend the disk space
+ to accommodate the restoration.
+ """
allowed_to_upload = True
else:
if (
@@ -2068,10 +2131,10 @@ def validate_restoration_space_requirements(
return {
"allowed_to_upload": allowed_to_upload,
- "free_space_on_app_server": free_space_on_app_server
- if not server.public
- else -1, # -1 indicates unlimited space, no need to expose public server space
- "free_space_on_db_server": free_space_on_db_server if not database_server.public else -1,
+ "free_space_on_app_server": (
+ free_space_on_app_server if not server.public else -1
+ ), # -1 indicates unlimited space, no need to expose public server space
+ "free_space_on_db_server": (free_space_on_db_server if not database_server.public else -1),
"is_insufficient_space_on_app_server": free_space_on_app_server < required_space_on_app_server,
"is_insufficient_space_on_db_server": free_space_on_db_server < required_space_on_db_server,
"required_space_on_app_server": required_space_on_app_server,
@@ -2389,7 +2452,8 @@ def confirm_site_transfer(key: str):
team_change = frappe.get_doc("Team Change", team_change)
to_team = team_change.to_team
if not frappe.db.get_value(
- "Team Member", {"user": frappe.session.user, "parent": to_team, "parenttype": "Team"}
+ "Team Member",
+ {"user": frappe.session.user, "parent": to_team, "parenttype": "Team"},
):
return frappe.respond_as_web_page(
_("Not Permitted"),
@@ -2495,7 +2559,11 @@ def get_private_groups_for_upgrade(name, version, release_groups=None):
@frappe.whitelist()
@protected("Site")
def version_upgrade(
- name, destination_group, scheduled_datetime=None, skip_failing_patches=False, skip_backups=False
+ name,
+ destination_group,
+ scheduled_datetime=None,
+ skip_failing_patches=False,
+ skip_backups=False,
):
site = frappe.get_doc("Site", name)
current_version, shared_site, central_site = frappe.db.get_value(
@@ -2550,9 +2618,9 @@ def check_existing_upgrade_bench(name, version):
which includes all the apps installed on the site.
Returns: {
- "exists": bool,
- "bench_name": str or None,
- "release_group": str or None,
+ "exists": bool,
+ "bench_name": str or None,
+ "release_group": str or None,
}
"""
site_server = frappe.db.get_value("Site", name, "server")
@@ -2589,11 +2657,18 @@ def check_existing_upgrade_bench(name, version):
).run(as_dict=True)
if not benches:
- return {"exists": False, "bench_name": None, "release_group": None, "release_group_title": None}
+ return {
+ "exists": False,
+ "bench_name": None,
+ "release_group": None,
+ "release_group_title": None,
+ }
bench_groups = [bench.group for bench in benches]
all_bench_apps = frappe.db.get_all(
- "Release Group App", filters={"parent": ("in", bench_groups)}, fields=["parent", "app"]
+ "Release Group App",
+ filters={"parent": ("in", bench_groups)},
+ fields=["parent", "app"],
)
bench_apps_map = {}
for row in all_bench_apps:
@@ -2611,7 +2686,12 @@ def check_existing_upgrade_bench(name, version):
"release_group_title": bench.title,
}
- return {"exists": False, "bench_name": None, "release_group": None, "release_group_title": None}
+ return {
+ "exists": False,
+ "bench_name": None,
+ "release_group": None,
+ "release_group_title": None,
+ }
@frappe.whitelist()
@@ -2818,7 +2898,11 @@ def change_server_options(name):
return {
"servers": frappe.db.get_all(
"Server",
- {"team": get_current_team(), "status": "Active", "name": ("!=", site.server)},
+ {
+ "team": get_current_team(),
+ "status": "Active",
+ "name": ("!=", site.server),
+ },
["name", "title"],
),
"estimated_duration": site.get_estimated_duration_for_server_change(),
diff --git a/press/press/doctype/press_settings/press_settings.json b/press/press/doctype/press_settings/press_settings.json
index 70a39fd96fa..44cc0412d2c 100644
--- a/press/press/doctype/press_settings/press_settings.json
+++ b/press/press/doctype/press_settings/press_settings.json
@@ -1,1681 +1,1760 @@
{
- "actions": [],
- "creation": "2022-02-08 15:13:48.372783",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
- "domain",
- "cluster",
- "trial_sites_count",
- "press_trial_plan",
- "column_break_2",
- "bench_configuration",
- "billing_tab",
- "free_credits_usd",
- "free_credits_inr",
- "column_break_cpry",
- "micro_debit_charge_usd",
- "micro_debit_charge_inr",
- "column_break_wrqp",
- "usage_record_creation_batch_size",
- "default_server_plan_type",
- "invoicing_section",
- "invoicing_column",
- "gst_percentage",
- "npo_discount",
- "autoscale_discount",
- "column_break_qfwx",
- "print_format",
- "ic_key",
- "stripe_settings_section",
- "stripe_publishable_key",
- "stripe_secret_key",
- "column_break_26",
- "create_stripe_plans",
- "stripe_product_id",
- "stripe_usd_plan_id",
- "stripe_inr_plan_id",
- "column_break_yhwz",
- "create_stripe_webhook",
- "stripe_webhook_endpoint_id",
- "stripe_webhook_secret",
- "ngrok_auth_token",
- "razorpay_settings_section",
- "razorpay_key_id",
- "razorpay_webhook_secret",
- "paypal_enabled",
- "column_break_123",
- "razorpay_key_secret",
- "erpnext_authentication",
- "erpnext_url",
- "erpnext_api_key",
- "erpnext_api_secret",
- "column_break_38",
- "frappeio_authentication_section",
- "disable_frappe_auth",
- "frappe_url",
- "frappeio_api_key",
- "column_break_39",
- "frappeio_api_secret",
- "backups_tab",
- "offsite_backups_section",
- "backup_region",
- "offsite_backups_provider",
- "aws_s3_bucket",
- "data_40",
- "backup_rotation_scheme",
- "column_break_35",
- "offsite_backups_access_key_id",
- "offsite_backups_secret_access_key",
- "offsite_backups_count",
- "backups_section",
- "backup_interval",
- "backup_offset",
- "column_break_48",
- "backup_limit",
- "max_failed_backup_attempts_in_a_day",
- "physical_backups_section",
- "disable_physical_backup",
- "max_concurrent_physical_restorations",
- "docker_tab",
- "section_break_59",
- "docker_registry_url",
- "docker_registry_namespace",
- "docker_s3_access_key",
- "column_break_64",
- "docker_registry_username",
- "docker_registry_password",
- "docker_s3_secret_key",
- "asset_store_section",
- "asset_store_access_key",
- "asset_store_secret_access_key",
- "asset_store_endpoint",
- "asset_store_region",
- "asset_store_bucket_name",
- "use_asset_store",
- "docker_build_section",
- "suspend_builds",
- "clone_directory",
- "build_directory",
- "build_server",
- "minimum_rebuild_memory",
- "new_bench_concurrency_limit",
- "column_break_66",
- "code_server",
- "code_server_password",
- "use_app_cache",
- "compress_app_cache",
- "use_delta_builds",
- "use_agent_job_callbacks",
- "auto_update_section",
- "auto_update_queue_size",
- "remote_files_section",
- "remote_uploads_bucket",
- "remote_link_expiry",
- "column_break_51",
- "remote_access_key_id",
- "remote_secret_access_key",
- "product_documentation_section",
- "publish_docs",
- "storage_and_disk_limits_section",
- "enforce_storage_limits",
- "erpnext_tab",
- "erpnext_signups_section",
- "erpnext_domain",
- "erpnext_cluster",
- "erpnext_plan",
- "erpnext_group",
- "column_break_89",
- "erpnext_apps",
- "central_migration_server",
- "staging_sites_section",
- "staging_plan",
- "staging_expiry",
- "erpnext_site_pool_section",
- "enable_site_pooling",
- "standby_pool_size",
- "column_break_95",
- "standby_queue_size",
- "integrations_tab",
- "telegram_section",
- "telegram_chat_id",
- "column_break_65",
- "telegram_bot_token",
- "mailgun_settings_section",
- "mailgun_api_key",
- "root_domain",
- "column_break_117",
- "default_outgoing_id",
- "default_outgoing_pass",
- "section_break_33",
- "create_github_app",
- "github_app_id",
- "github_app_client_id",
- "github_app_client_secret",
- "column_break_36",
- "github_app_public_link",
- "github_webhook_secret",
- "github_access_token",
- "deploy_marker",
- "section_break_41",
- "column_break_tcmy",
- "column_break_edst",
- "github_app_private_key",
- "aws_section",
- "aws_access_key_id",
- "column_break_agig",
- "aws_secret_access_key",
- "twilio_section",
- "twilio_account_sid",
- "twilio_api_key_sid",
- "twilio_api_key_secret",
- "column_break_kxuj",
- "twilio_phone_number",
- "spamd_section",
- "enable_spam_check",
- "spamd_endpoint",
- "column_break_xhfy",
- "spamd_api_key",
- "spamd_api_secret",
- "marketplace_tab",
- "marketplace_settings_section",
- "max_allowed_screenshots",
- "threshold",
- "commission",
- "usd_rate",
- "app_include_script",
- "github_pat_token",
- "plausible_column",
- "plausible_url",
- "plausible_site_id",
- "plausible_api_key",
- "infrastructure_tab",
- "general_section",
- "production_server_ip",
- "agent_section",
- "agent_repository_owner",
- "agent_sentry_dsn",
- "column_break_105",
- "agent_github_access_token",
- "branch",
- "lets_encrypt_section",
- "certbot_directory",
- "webroot_directory",
- "rsa_key_size",
- "column_break_15",
- "eff_registration_email",
- "use_staging_ca",
- "ssh_section",
- "ssh_certificate_authority",
- "bench_section",
- "redis_cache_size",
- "set_redis_password",
- "monitoring_section",
- "monitor_server",
- "monitor_token",
- "press_monitoring_password",
- "send_telegram_notifications",
- "column_break_jlzi",
- "log_server",
- "telegram_alert_chat_id",
- "telegram_alerts_chat_group",
- "send_email_notifications",
- "email_recipients",
- "section_break_nloq",
- "servers_using_alternative_http_port_for_communication",
- "auto_scale_section",
- "shared_directory",
- "cool_off_period",
- "feature_flags_tab",
- "verify_cards_with_micro_charge",
- "enable_google_oauth",
- "realtime_job_updates",
- "disable_agent_job_deduplication",
- "disable_binlog_indexer_service",
- "column_break_rdlr",
- "disable_auto_retry",
- "disallow_disposable_emails",
- "enable_email_pre_verification",
- "execute_incident_action",
- "enable_server_snapshot_recovery",
- "use_new_deploy_flow",
- "section_break_jstu",
- "enable_app_grouping",
- "default_apps",
- "partner_tab",
- "partnership_fees_section",
- "partnership_fee_usd",
- "column_break_yxrj",
- "partnership_fee_inr",
- "section_break_dhzi",
- "drive_resource_link",
- "frappe_school_authentication_section",
- "school_url",
- "school_api_key",
- "column_break_uxxz",
- "school_api_secret",
- "hybrid_server_tab",
- "hybrid_cluster",
- "hybrid_domain",
- "tls_renewal_queue_size",
- "security_tab",
- "wazuh_server"
- ],
- "fields": [
- {
- "fieldname": "domain",
- "fieldtype": "Link",
- "label": "Domain",
- "options": "Root Domain"
- },
- {
- "fieldname": "cluster",
- "fieldtype": "Link",
- "label": "Cluster",
- "options": "Cluster"
- },
- {
- "default": "1",
- "fieldname": "trial_sites_count",
- "fieldtype": "Int",
- "label": "Number of Sites in Trial"
- },
- {
- "fieldname": "column_break_2",
- "fieldtype": "Column Break"
- },
- {
- "default": "{}",
- "fieldname": "bench_configuration",
- "fieldtype": "Code",
- "in_list_view": 1,
- "label": "Bench Confguration",
- "options": "JSON",
- "reqd": 1
- },
- {
- "fieldname": "billing_tab",
- "fieldtype": "Tab Break",
- "label": "Billing"
- },
- {
- "collapsible": 1,
- "fieldname": "stripe_settings_section",
- "fieldtype": "Section Break",
- "label": "Stripe Settings"
- },
- {
- "fieldname": "stripe_inr_plan_id",
- "fieldtype": "Data",
- "label": "Stripe INR Plan ID",
- "read_only": 1
- },
- {
- "fieldname": "stripe_publishable_key",
- "fieldtype": "Data",
- "label": "Stripe Publishable Key"
- },
- {
- "fieldname": "create_stripe_plans",
- "fieldtype": "Button",
- "label": "Create Stripe Plans"
- },
- {
- "fieldname": "stripe_product_id",
- "fieldtype": "Data",
- "label": "Stripe Product ID",
- "read_only": 1
- },
- {
- "fieldname": "stripe_usd_plan_id",
- "fieldtype": "Data",
- "label": "Stripe USD Plan ID",
- "read_only": 1
- },
- {
- "fieldname": "create_stripe_webhook",
- "fieldtype": "Button",
- "label": "Create Stripe Webhook"
- },
- {
- "fieldname": "stripe_webhook_endpoint_id",
- "fieldtype": "Data",
- "label": "Stripe Webhook Endpoint ID",
- "read_only": 1
- },
- {
- "fieldname": "stripe_webhook_secret",
- "fieldtype": "Data",
- "label": "Stripe Webhook Secret",
- "read_only": 1
- },
- {
- "fieldname": "column_break_26",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "stripe_secret_key",
- "fieldtype": "Password",
- "label": "Stripe Secret Key"
- },
- {
- "fieldname": "free_credits_inr",
- "fieldtype": "Currency",
- "label": "Credits on Signup (INR)",
- "options": "INR"
- },
- {
- "fieldname": "free_credits_usd",
- "fieldtype": "Currency",
- "label": "Credits on Signup (USD)",
- "options": "USD"
- },
- {
- "description": "Sign up on ngrok.com to get one for free",
- "fieldname": "ngrok_auth_token",
- "fieldtype": "Data",
- "label": "Ngrok Auth Token"
- },
- {
- "collapsible": 1,
- "fieldname": "razorpay_settings_section",
- "fieldtype": "Section Break",
- "label": "Razorpay Settings"
- },
- {
- "fieldname": "razorpay_key_id",
- "fieldtype": "Data",
- "label": "Razorpay Key ID"
- },
- {
- "fieldname": "razorpay_webhook_secret",
- "fieldtype": "Data",
- "label": "Razorpay Webhook Secret"
- },
- {
- "fieldname": "column_break_123",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "razorpay_key_secret",
- "fieldtype": "Password",
- "label": "Razorpay Key Secret"
- },
- {
- "collapsible": 1,
- "fieldname": "erpnext_authentication",
- "fieldtype": "Section Break",
- "label": "ERPNext Authentication"
- },
- {
- "fieldname": "erpnext_url",
- "fieldtype": "Data",
- "label": "ERPNext URL"
- },
- {
- "fieldname": "erpnext_api_key",
- "fieldtype": "Data",
- "label": "ERPNext API Key"
- },
- {
- "fieldname": "erpnext_api_secret",
- "fieldtype": "Password",
- "label": "ERPNext API Secret"
- },
- {
- "fieldname": "column_break_38",
- "fieldtype": "Column Break"
- },
- {
- "collapsible": 1,
- "fieldname": "frappeio_authentication_section",
- "fieldtype": "Section Break",
- "label": "Frappe.io Authentication"
- },
- {
- "fieldname": "frappe_url",
- "fieldtype": "Data",
- "label": "URL"
- },
- {
- "fieldname": "frappeio_api_key",
- "fieldtype": "Data",
- "label": "Frappe.io API Key"
- },
- {
- "fieldname": "column_break_39",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "frappeio_api_secret",
- "fieldtype": "Password",
- "label": "Frappe.io API Secret"
- },
- {
- "fieldname": "backups_tab",
- "fieldtype": "Tab Break",
- "label": "Backups"
- },
- {
- "fieldname": "offsite_backups_section",
- "fieldtype": "Section Break",
- "label": "Offsite Backups"
- },
- {
- "fieldname": "backup_region",
- "fieldtype": "Data",
- "label": "Backup Region"
- },
- {
- "default": "AWS S3",
- "fieldname": "offsite_backups_provider",
- "fieldtype": "Select",
- "label": "Backup Provider",
- "options": "AWS S3"
- },
- {
- "fieldname": "aws_s3_bucket",
- "fieldtype": "Data",
- "label": "Bucket Name"
- },
- {
- "fieldname": "data_40",
- "fieldtype": "Data"
- },
- {
- "fieldname": "backup_rotation_scheme",
- "fieldtype": "Select",
- "label": "Backup Rotation Scheme",
- "options": "FIFO\nGrandfather-father-son"
- },
- {
- "fieldname": "column_break_35",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "offsite_backups_access_key_id",
- "fieldtype": "Data",
- "label": "Access Key ID"
- },
- {
- "fieldname": "offsite_backups_secret_access_key",
- "fieldtype": "Password",
- "label": "Secret Access Key"
- },
- {
- "depends_on": "eval:doc.backup_rotation_scheme==\"FIFO\"",
- "description": "The max number of Offsite backups that will be retained at any given time (for each site)",
- "fieldname": "offsite_backups_count",
- "fieldtype": "Int",
- "label": "Total Backups Count"
- },
- {
- "fieldname": "backups_section",
- "fieldtype": "Section Break",
- "label": "Backups"
- },
- {
- "fieldname": "backup_interval",
- "fieldtype": "Int",
- "label": "Backup Interval"
- },
- {
- "default": "0",
- "fieldname": "backup_offset",
- "fieldtype": "Int",
- "label": "Backup Offset"
- },
- {
- "fieldname": "column_break_48",
- "fieldtype": "Column Break"
- },
- {
- "description": "Number of backups to take per ScheduledBackupJob",
- "fieldname": "backup_limit",
- "fieldtype": "Int",
- "label": "Backup Limit"
- },
- {
- "fieldname": "docker_tab",
- "fieldtype": "Tab Break",
- "label": "Docker"
- },
- {
- "fieldname": "section_break_59",
- "fieldtype": "Section Break",
- "label": "Docker Registry"
- },
- {
- "fieldname": "docker_registry_url",
- "fieldtype": "Data",
- "label": "Docker Registry URL"
- },
- {
- "fieldname": "docker_registry_namespace",
- "fieldtype": "Data",
- "label": "Docker Registry Namespace"
- },
- {
- "fieldname": "column_break_64",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "docker_registry_username",
- "fieldtype": "Data",
- "label": "Docker Registry Username"
- },
- {
- "fieldname": "docker_registry_password",
- "fieldtype": "Data",
- "label": "Docker Registry Password"
- },
- {
- "collapsible": 1,
- "fieldname": "docker_build_section",
- "fieldtype": "Section Break",
- "label": "Docker Build"
- },
- {
- "fieldname": "clone_directory",
- "fieldtype": "Data",
- "label": "Clone Directory"
- },
- {
- "fieldname": "build_directory",
- "fieldtype": "Data",
- "label": "Build Directory"
- },
- {
- "fieldname": "column_break_66",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "code_server",
- "fieldtype": "Data",
- "label": "Code Server"
- },
- {
- "fieldname": "code_server_password",
- "fieldtype": "Data",
- "label": "Code Server Password"
- },
- {
- "collapsible": 1,
- "fieldname": "auto_update_section",
- "fieldtype": "Section Break",
- "label": "Auto Update"
- },
- {
- "default": "4",
- "fieldname": "auto_update_queue_size",
- "fieldtype": "Int",
- "label": "Auto Update Queue Size"
- },
- {
- "collapsible": 1,
- "fieldname": "remote_files_section",
- "fieldtype": "Section Break",
- "label": "Remote Files"
- },
- {
- "fieldname": "remote_uploads_bucket",
- "fieldtype": "Data",
- "label": "Uploads Bucket Name"
- },
- {
- "fieldname": "remote_link_expiry",
- "fieldtype": "Int",
- "label": "Link Expiry"
- },
- {
- "fieldname": "column_break_51",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "remote_access_key_id",
- "fieldtype": "Data",
- "label": "Remote Access Key ID"
- },
- {
- "fieldname": "remote_secret_access_key",
- "fieldtype": "Password",
- "label": "Remote Secret Access Key"
- },
- {
- "collapsible": 1,
- "fieldname": "product_documentation_section",
- "fieldtype": "Section Break",
- "label": "Product Documentation"
- },
- {
- "default": "0",
- "fieldname": "publish_docs",
- "fieldtype": "Check",
- "label": "Published"
- },
- {
- "collapsible": 1,
- "fieldname": "storage_and_disk_limits_section",
- "fieldtype": "Section Break",
- "label": "Storage and Disk Limits"
- },
- {
- "default": "0",
- "description": "Setting this to true will start suspending sites that cross the Site Usages with respect to their existing plans.",
- "fieldname": "enforce_storage_limits",
- "fieldtype": "Check",
- "label": "Enforce Storage and Disk Limits"
- },
- {
- "fieldname": "erpnext_tab",
- "fieldtype": "Tab Break",
- "label": "ERPNext"
- },
- {
- "fieldname": "erpnext_signups_section",
- "fieldtype": "Section Break",
- "label": "ERPNext Signups"
- },
- {
- "fieldname": "erpnext_domain",
- "fieldtype": "Link",
- "label": "ERPNext Domain",
- "options": "Root Domain"
- },
- {
- "fetch_from": "erpnext_domain.default_cluster",
- "fetch_if_empty": 1,
- "fieldname": "erpnext_cluster",
- "fieldtype": "Link",
- "label": "ERPNext Cluster",
- "options": "Cluster"
- },
- {
- "fieldname": "erpnext_plan",
- "fieldtype": "Link",
- "label": "ERPNext Plan",
- "options": "Site Plan"
- },
- {
- "fieldname": "erpnext_group",
- "fieldtype": "Link",
- "label": "ERPNext Group",
- "options": "Release Group"
- },
- {
- "fieldname": "column_break_89",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "erpnext_apps",
- "fieldtype": "Table",
- "label": "ERPNext Apps",
- "options": "ERPNext App"
- },
- {
- "fieldname": "central_migration_server",
- "fieldtype": "Link",
- "label": "Central Migration Server",
- "options": "Server"
- },
- {
- "collapsible": 1,
- "fieldname": "staging_sites_section",
- "fieldtype": "Section Break",
- "label": "Staging Sites"
- },
- {
- "fieldname": "staging_plan",
- "fieldtype": "Link",
- "label": "Staging Plan",
- "options": "Site Plan"
- },
- {
- "default": "24",
- "fieldname": "staging_expiry",
- "fieldtype": "Int",
- "label": "Staging Expiry"
- },
- {
- "collapsible": 1,
- "fieldname": "erpnext_site_pool_section",
- "fieldtype": "Section Break",
- "label": "ERPNext Site Pool"
- },
- {
- "default": "0",
- "fieldname": "enable_site_pooling",
- "fieldtype": "Check",
- "label": "Enable Site Pooling"
- },
- {
- "default": "5",
- "fieldname": "standby_pool_size",
- "fieldtype": "Int",
- "label": "Standby Pool Size"
- },
- {
- "fieldname": "column_break_95",
- "fieldtype": "Column Break"
- },
- {
- "default": "1",
- "fieldname": "standby_queue_size",
- "fieldtype": "Int",
- "label": "Standby Queue Size"
- },
- {
- "fieldname": "integrations_tab",
- "fieldtype": "Tab Break",
- "label": "Integrations"
- },
- {
- "fieldname": "telegram_section",
- "fieldtype": "Section Break",
- "label": "Telegram"
- },
- {
- "fieldname": "telegram_chat_id",
- "fieldtype": "Data",
- "label": "Telegram Chat ID"
- },
- {
- "fieldname": "column_break_65",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "telegram_bot_token",
- "fieldtype": "Data",
- "label": "Telegram Bot Token"
- },
- {
- "fieldname": "mailgun_settings_section",
- "fieldtype": "Section Break",
- "label": "Mailgun"
- },
- {
- "fieldname": "mailgun_api_key",
- "fieldtype": "Data",
- "label": "Api Key"
- },
- {
- "fieldname": "root_domain",
- "fieldtype": "Data",
- "label": "Root Domain"
- },
- {
- "fieldname": "column_break_117",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "default_outgoing_id",
- "fieldtype": "Data",
- "label": "Default outgoing id"
- },
- {
- "fieldname": "default_outgoing_pass",
- "fieldtype": "Data",
- "label": "Default outgoing pass"
- },
- {
- "collapsible": 1,
- "fieldname": "section_break_33",
- "fieldtype": "Section Break",
- "label": "GitHub"
- },
- {
- "depends_on": "eval: !doc.github_app_id",
- "fieldname": "create_github_app",
- "fieldtype": "Button",
- "label": "Create GitHub App",
- "mandatory_depends_on": "eval"
- },
- {
- "fieldname": "github_app_id",
- "fieldtype": "Data",
- "label": "GitHub App ID",
- "read_only": 1
- },
- {
- "fieldname": "github_app_client_id",
- "fieldtype": "Data",
- "label": "GitHub App Client ID",
- "read_only": 1
- },
- {
- "fieldname": "github_app_client_secret",
- "fieldtype": "Data",
- "label": "GitHub App Client Secret",
- "read_only": 1
- },
- {
- "default": "fc-deploy",
- "fieldname": "column_break_36",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "github_app_public_link",
- "fieldtype": "Data",
- "label": "GitHub App Public Link",
- "read_only": 1
- },
- {
- "fieldname": "github_webhook_secret",
- "fieldtype": "Data",
- "label": "GitHub Webhook Secret",
- "read_only": 1
- },
- {
- "fieldname": "github_access_token",
- "fieldtype": "Data",
- "label": "GitHub Access Token"
- },
- {
- "collapsible": 1,
- "fieldname": "section_break_41",
- "fieldtype": "Section Break",
- "hide_border": 1
- },
- {
- "fieldname": "github_app_private_key",
- "fieldtype": "Code",
- "hidden": 1,
- "label": "GitHub App Private Key",
- "read_only": 1
- },
- {
- "fieldname": "marketplace_tab",
- "fieldtype": "Tab Break",
- "label": "Marketplace"
- },
- {
- "fieldname": "marketplace_settings_section",
- "fieldtype": "Section Break",
- "label": "Marketplace Settings"
- },
- {
- "default": "6",
- "fieldname": "max_allowed_screenshots",
- "fieldtype": "Int",
- "label": "Max number of Allowed Screenshots",
- "non_negative": 1
- },
- {
- "fieldname": "infrastructure_tab",
- "fieldtype": "Tab Break",
- "label": "Infrastructure"
- },
- {
- "fieldname": "agent_section",
- "fieldtype": "Section Break",
- "label": "Agent"
- },
- {
- "default": "frappe",
- "fieldname": "agent_repository_owner",
- "fieldtype": "Data",
- "label": "Agent Repository Owner"
- },
- {
- "fieldname": "column_break_105",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "agent_github_access_token",
- "fieldtype": "Data",
- "label": "Agent GitHub Access Token"
- },
- {
- "fieldname": "lets_encrypt_section",
- "fieldtype": "Section Break",
- "label": "Let's Encrypt"
- },
- {
- "fieldname": "certbot_directory",
- "fieldtype": "Data",
- "label": "Certbot Directory",
- "reqd": 1
- },
- {
- "fieldname": "webroot_directory",
- "fieldtype": "Data",
- "label": "Webroot Directory"
- },
- {
- "default": "2048",
- "fieldname": "rsa_key_size",
- "fieldtype": "Select",
- "label": "RSA Key Size",
- "options": "2048\n3072\n4096",
- "reqd": 1
- },
- {
- "fieldname": "column_break_15",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "eff_registration_email",
- "fieldtype": "Data",
- "label": "EFF Registration Email",
- "reqd": 1
- },
- {
- "default": "0",
- "fieldname": "use_staging_ca",
- "fieldtype": "Check",
- "label": "Use Staging CA"
- },
- {
- "collapsible": 1,
- "fieldname": "ssh_section",
- "fieldtype": "Section Break",
- "label": "SSH"
- },
- {
- "fieldname": "ssh_certificate_authority",
- "fieldtype": "Link",
- "label": "SSH Certificate Authority",
- "options": "SSH Certificate Authority"
- },
- {
- "collapsible": 1,
- "fieldname": "monitoring_section",
- "fieldtype": "Section Break",
- "label": "Monitoring"
- },
- {
- "fieldname": "telegram_alert_chat_id",
- "fieldtype": "Data",
- "label": "Telegram Alert Chat ID"
- },
- {
- "fieldname": "monitor_server",
- "fieldtype": "Link",
- "label": "Monitor Server",
- "options": "Monitor Server"
- },
- {
- "fieldname": "monitor_token",
- "fieldtype": "Data",
- "label": "Monitor Token"
- },
- {
- "fieldname": "log_server",
- "fieldtype": "Link",
- "label": "Log Server",
- "options": "Log Server"
- },
- {
- "fieldname": "feature_flags_tab",
- "fieldtype": "Tab Break",
- "label": "Feature Flags"
- },
- {
- "default": "No",
- "fieldname": "verify_cards_with_micro_charge",
- "fieldtype": "Select",
- "label": "Verify Cards with Micro Charge",
- "options": "No\nOnly INR\nOnly USD\nBoth INR and USD"
- },
- {
- "fieldname": "threshold",
- "fieldtype": "Float",
- "label": "Marketplace Payout Threshold"
- },
- {
- "fieldname": "commission",
- "fieldtype": "Float",
- "label": "Marketplace Commission"
- },
- {
- "fieldname": "usd_rate",
- "fieldtype": "Float",
- "label": "USD Rate"
- },
- {
- "fieldname": "press_monitoring_password",
- "fieldtype": "Password",
- "label": "Press Monitoring Password"
- },
- {
- "description": "Adds this script to app_include_js via site config. Used for in-site billing",
- "fieldname": "app_include_script",
- "fieldtype": "Data",
- "label": "App Include Script"
- },
- {
- "fieldname": "telegram_alerts_chat_group",
- "fieldtype": "Link",
- "label": "Telegram Alerts Chat Group",
- "options": "Telegram Group"
- },
- {
- "default": "0",
- "fieldname": "enable_google_oauth",
- "fieldtype": "Check",
- "label": "Enable Google Oauth "
- },
- {
- "fieldname": "plausible_api_key",
- "fieldtype": "Password",
- "label": "Plausible API Key"
- },
- {
- "fieldname": "plausible_column",
- "fieldtype": "Column Break",
- "label": "Plausible"
- },
- {
- "fieldname": "plausible_url",
- "fieldtype": "Data",
- "label": "Plausible URL"
- },
- {
- "fieldname": "plausible_site_id",
- "fieldtype": "Data",
- "label": "Plausible site id"
- },
- {
- "default": "0",
- "fieldname": "suspend_builds",
- "fieldtype": "Check",
- "label": "Suspend Builds",
- "read_only": 1
- },
- {
- "fieldname": "aws_section",
- "fieldtype": "Section Break",
- "label": "AWS"
- },
- {
- "fieldname": "aws_access_key_id",
- "fieldtype": "Data",
- "label": "AWS Access Key ID"
- },
- {
- "fieldname": "column_break_agig",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "aws_secret_access_key",
- "fieldtype": "Password",
- "label": "AWS Secret Access Key"
- },
- {
- "fieldname": "twilio_section",
- "fieldtype": "Section Break",
- "label": "Twilio"
- },
- {
- "fieldname": "twilio_account_sid",
- "fieldtype": "Data",
- "label": "Twilio Account SID"
- },
- {
- "fieldname": "column_break_kxuj",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "twilio_phone_number",
- "fieldtype": "Phone",
- "label": "Twilio Phone Number"
- },
- {
- "fieldname": "invoicing_column",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "gst_percentage",
- "fieldtype": "Float",
- "label": "GST Percentage"
- },
- {
- "fieldname": "column_break_tcmy",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "column_break_edst",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "twilio_api_key_sid",
- "fieldtype": "Data",
- "label": "Twilio API Key SID"
- },
- {
- "fieldname": "twilio_api_key_secret",
- "fieldtype": "Password",
- "label": "Twilio API Key Secret"
- },
- {
- "fieldname": "invoicing_section",
- "fieldtype": "Section Break",
- "label": "Invoicing"
- },
- {
- "fieldname": "column_break_qfwx",
- "fieldtype": "Column Break"
- },
- {
- "description": "Fetched from frappe.io",
- "fieldname": "print_format",
- "fieldtype": "Data",
- "label": "Print Format"
- },
- {
- "default": "0",
- "description": "Uses Bench get-app cache for faster image builds. Will be set only if Bench version is 5.22.1 or later.",
- "fieldname": "use_app_cache",
- "fieldtype": "Check",
- "label": "Use App Cache"
- },
- {
- "default": "0",
- "depends_on": "eval: doc.use_app_cache",
- "description": "Use Gzip to compress bench get-app artifacts before caching.",
- "fieldname": "compress_app_cache",
- "fieldtype": "Check",
- "label": "Compress App Cache"
- },
- {
- "fieldname": "column_break_rdlr",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "fieldname": "realtime_job_updates",
- "fieldtype": "Check",
- "label": "Realtime Job Updates"
- },
- {
- "default": "0",
- "description": "Quickens builds by fetching app changes without rebuilding app if app rebuild is not required.",
- "fieldname": "use_delta_builds",
- "fieldtype": "Check",
- "label": "Use Delta Builds"
- },
- {
- "fieldname": "hybrid_server_tab",
- "fieldtype": "Tab Break",
- "label": "Hybrid Server"
- },
- {
- "fieldname": "hybrid_cluster",
- "fieldtype": "Link",
- "label": "Hybrid Cluster",
- "options": "Cluster"
- },
- {
- "fieldname": "hybrid_domain",
- "fieldtype": "Link",
- "label": "Hybrid Domain",
- "options": "Root Domain"
- },
- {
- "default": "0",
- "fieldname": "disable_auto_retry",
- "fieldtype": "Check",
- "label": "Disable Auto Retry"
- },
- {
- "default": "1",
- "fieldname": "disable_agent_job_deduplication",
- "fieldtype": "Check",
- "label": "Disable Agent Job Deduplication"
- },
- {
- "fieldname": "agent_sentry_dsn",
- "fieldtype": "Data",
- "label": "Agent Sentry DSN"
- },
- {
- "fieldname": "build_server",
- "fieldtype": "Link",
- "label": "Build Server",
- "options": "Server"
- },
- {
- "default": "10",
- "fieldname": "tls_renewal_queue_size",
- "fieldtype": "Int",
- "label": "TLS Renewal Queue Size"
- },
- {
- "default": "80",
- "fieldname": "micro_debit_charge_inr",
- "fieldtype": "Currency",
- "label": "Micro Debit Charge (INR)",
- "precision": "0"
- },
- {
- "default": "1",
- "fieldname": "micro_debit_charge_usd",
- "fieldtype": "Currency",
- "label": "Micro Debit Charge (USD)",
- "precision": "0"
- },
- {
- "default": "master",
- "fieldname": "branch",
- "fieldtype": "Data",
- "label": "Branch"
- },
- {
- "fieldname": "column_break_yhwz",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "column_break_cpry",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "column_break_wrqp",
- "fieldtype": "Column Break"
- },
- {
- "default": "500",
- "fieldname": "usage_record_creation_batch_size",
- "fieldtype": "Int",
- "label": "Usage Record Creation Batch Size"
- },
- {
- "fieldname": "press_trial_plan",
- "fieldtype": "Link",
- "label": "Press Trial Plan",
- "options": "Site Plan"
- },
- {
- "fieldname": "section_break_jstu",
- "fieldtype": "Section Break"
- },
- {
- "default": "0",
- "fieldname": "enable_app_grouping",
- "fieldtype": "Check",
- "label": "Enable App Grouping"
- },
- {
- "fieldname": "default_apps",
- "fieldtype": "Table",
- "label": "Default Apps",
- "options": "App Group"
- },
- {
- "default": "0",
- "fieldname": "enable_email_pre_verification",
- "fieldtype": "Check",
- "label": "Enable Email Pre-Verification"
- },
- {
- "fieldname": "bench_section",
- "fieldtype": "Section Break",
- "label": "Bench"
- },
- {
- "default": "512",
- "fieldname": "redis_cache_size",
- "fieldtype": "Int",
- "label": "Redis Cache Size (MB)"
- },
- {
- "fieldname": "partner_tab",
- "fieldtype": "Tab Break",
- "label": "Partner"
- },
- {
- "fieldname": "partnership_fees_section",
- "fieldtype": "Section Break",
- "label": "Partnership Fees"
- },
- {
- "fieldname": "partnership_fee_usd",
- "fieldtype": "Int",
- "label": "Partnership Fee USD"
- },
- {
- "fieldname": "column_break_yxrj",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "partnership_fee_inr",
- "fieldtype": "Int",
- "label": "Partnership Fee INR"
- },
- {
- "fieldname": "github_pat_token",
- "fieldtype": "Data",
- "label": "Github PAT Token"
- },
- {
- "default": "1",
- "fieldname": "disable_physical_backup",
- "fieldtype": "Check",
- "label": "Disable Physical Backup"
- },
- {
- "fieldname": "physical_backups_section",
- "fieldtype": "Section Break",
- "label": "Physical Backups"
- },
- {
- "fieldname": "spamd_section",
- "fieldtype": "Section Break",
- "label": "Spamd"
- },
- {
- "default": "0",
- "fieldname": "enable_spam_check",
- "fieldtype": "Check",
- "label": "Enable Spam Check"
- },
- {
- "fieldname": "spamd_endpoint",
- "fieldtype": "Data",
- "label": "Spamd Endpoint"
- },
- {
- "fieldname": "column_break_xhfy",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "spamd_api_key",
- "fieldtype": "Data",
- "label": "Spamd API Key"
- },
- {
- "fieldname": "spamd_api_secret",
- "fieldtype": "Password",
- "label": "Spamd API Secret"
- },
- {
- "default": "2",
- "fieldname": "max_concurrent_physical_restorations",
- "fieldtype": "Int",
- "label": "Max Concurrent Physical Restorations"
- },
- {
- "default": "1",
- "fieldname": "send_telegram_notifications",
- "fieldtype": "Check",
- "label": "Send Telegram Notifications"
- },
- {
- "fieldname": "column_break_jlzi",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "fieldname": "send_email_notifications",
- "fieldtype": "Check",
- "label": "Send Email Notifications"
- },
- {
- "depends_on": "eval: doc.send_email_notifications== true",
- "fieldname": "email_recipients",
- "fieldtype": "Small Text",
- "label": "Email Recipients"
- },
- {
- "default": "1",
- "fieldname": "use_agent_job_callbacks",
- "fieldtype": "Check",
- "label": "Use Agent Job Callbacks"
- },
- {
- "default": "2",
- "fieldname": "minimum_rebuild_memory",
- "fieldtype": "Int",
- "label": "Minimum Rebuild Memory (GB)",
- "non_negative": 1
- },
- {
- "description": "Max attempts we will do on a site with failed attempts",
- "fieldname": "max_failed_backup_attempts_in_a_day",
- "fieldtype": "Int",
- "label": "Max Failed Backup Attempts In A Day"
- },
- {
- "default": "0",
- "fieldname": "disable_frappe_auth",
- "fieldtype": "Check",
- "label": "Disable Frappe Auth"
- },
- {
- "fieldname": "section_break_nloq",
- "fieldtype": "Section Break"
- },
- {
- "fieldname": "servers_using_alternative_http_port_for_communication",
- "fieldtype": "Small Text",
- "label": "Servers Using Alternative HTTP Port For Communication"
- },
- {
- "description": "Add value in percent (%). e.g. 10",
- "fieldname": "npo_discount",
- "fieldtype": "Float",
- "label": "NPO Discount"
- },
- {
- "default": "0",
- "fieldname": "execute_incident_action",
- "fieldtype": "Check",
- "label": "Execute Incident Action"
- },
- {
- "default": "0",
- "fieldname": "enable_server_snapshot_recovery",
- "fieldtype": "Check",
- "label": "Enable Server Snapshot Recovery"
- },
- {
- "fieldname": "docker_s3_access_key",
- "fieldtype": "Data",
- "label": "Docker S3 Access Key"
- },
- {
- "fieldname": "docker_s3_secret_key",
- "fieldtype": "Password",
- "label": "Docker S3 Secret Key"
- },
- {
- "default": "0",
- "description": "Enable via RazorPay dashboard",
- "fieldname": "paypal_enabled",
- "fieldtype": "Check",
- "label": "PayPal Enabled"
- },
- {
- "default": "1",
- "description": "Set redis password common site config and redis configs at release group level",
- "fieldname": "set_redis_password",
- "fieldtype": "Check",
- "label": "Set Redis Password"
- },
- {
- "default": "1",
- "fieldname": "disallow_disposable_emails",
- "fieldtype": "Check",
- "label": "Disallow disposable emails"
- },
- {
- "fieldname": "drive_resource_link",
- "fieldtype": "Data",
- "label": "Drive Resource Link"
- },
- {
- "fieldname": "ic_key",
- "fieldtype": "Password",
- "label": "IC Key"
- },
- {
- "fieldname": "section_break_dhzi",
- "fieldtype": "Section Break"
- },
- {
- "fieldname": "auto_scale_section",
- "fieldtype": "Section Break",
- "label": "Auto Scale"
- },
- {
- "default": "/home/frappe/shared",
- "fieldname": "shared_directory",
- "fieldtype": "Data",
- "label": "Shared Directory"
- },
- {
- "default": "600",
- "description": "Time between two autoscale events (up scale or down scale)",
- "fieldname": "cool_off_period",
- "fieldtype": "Int",
- "label": "Cool off period"
- },
- {
- "fieldname": "deploy_marker",
- "fieldtype": "Data",
- "label": "Deploy Marker",
- "options": "If found in commit message deploy will be triggered"
- },
- {
- "fieldname": "security_tab",
- "fieldtype": "Tab Break",
- "label": "Security"
- },
- {
- "fieldname": "wazuh_server",
- "fieldtype": "Data",
- "label": "Wazuh Server"
- },
- {
- "fieldname": "autoscale_discount",
- "fieldtype": "Float",
- "label": "Autoscale Discount"
- },
- {
- "default": "1",
- "fieldname": "disable_binlog_indexer_service",
- "fieldtype": "Check",
- "label": "Disable Binlog Indexer Service"
- },
- {
- "fieldname": "default_server_plan_type",
- "fieldtype": "Link",
- "label": "Default Server Plan Type",
- "options": "Server Plan Type"
- },
- {
- "fieldname": "frappe_school_authentication_section",
- "fieldtype": "Section Break",
- "label": "Frappe School Authentication"
- },
- {
- "fieldname": "school_url",
- "fieldtype": "Data",
- "label": "School URL"
- },
- {
- "fieldname": "school_api_key",
- "fieldtype": "Data",
- "label": "School API Key"
- },
- {
- "fieldname": "column_break_uxxz",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "school_api_secret",
- "fieldtype": "Password",
- "label": "School API Secret"
- },
- {
- "collapsible": 1,
- "fieldname": "asset_store_section",
- "fieldtype": "Section Break",
- "label": "Asset Store"
- },
- {
- "default": "0",
- "description": "Will only use this asset storage backend if checked.",
- "fieldname": "use_asset_store",
- "fieldtype": "Check",
- "label": "Use Asset Store"
- },
- {
- "fieldname": "asset_store_access_key",
- "fieldtype": "Data",
- "label": "Asset Store Access Key"
- },
- {
- "fieldname": "asset_store_secret_access_key",
- "fieldtype": "Password",
- "label": "Asset Store Secret Access Key"
- },
- {
- "fieldname": "asset_store_endpoint",
- "fieldtype": "Data",
- "label": "Asset Store Endpoint"
- },
- {
- "fieldname": "asset_store_bucket_name",
- "fieldtype": "Data",
- "label": "Asset Store Bucket Name "
- },
- {
- "fieldname": "asset_store_region",
- "fieldtype": "Data",
- "label": "Asset Store Region"
- },
- {
- "fieldname": "frappe_school_authentication_section",
- "fieldtype": "Section Break",
- "label": "Frappe School Authentication"
- },
- {
- "fieldname": "general_section",
- "fieldtype": "Section Break",
- "label": "General"
- },
- {
- "fieldname": "production_server_ip",
- "fieldtype": "Data",
- "label": "Production Server IP"
- },
- {
- "default": "30",
- "fieldname": "new_bench_concurrency_limit",
- "fieldtype": "Int",
- "label": "New Bench Concurrency Limit"
- },
- {
- "default": "0",
- "fieldname": "use_new_deploy_flow",
- "fieldtype": "Check",
- "label": "Use New Deploy Flow"
- }
- ],
- "issingle": 1,
- "links": [],
- "modified": "2026-04-13 18:54:30.323908",
- "modified_by": "Administrator",
- "module": "Press",
- "name": "Press Settings",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "print": 1,
- "read": 1,
- "role": "System Manager",
- "share": 1,
- "write": 1
- }
- ],
- "quick_entry": 1,
- "row_format": "Dynamic",
- "sort_field": "modified",
- "sort_order": "DESC",
- "states": [],
- "track_changes": 1
-}
\ No newline at end of file
+ "actions": [],
+ "creation": "2022-02-08 15:13:48.372783",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "domain",
+ "cluster",
+ "trial_sites_count",
+ "press_trial_plan",
+ "column_break_2",
+ "bench_configuration",
+ "billing_tab",
+ "free_credits_usd",
+ "free_credits_inr",
+ "column_break_cpry",
+ "micro_debit_charge_usd",
+ "micro_debit_charge_inr",
+ "column_break_wrqp",
+ "usage_record_creation_batch_size",
+ "default_server_plan_type",
+ "plans_section",
+ "default_dedicated_server_site_warranty_change_cooldown",
+ "column_break_kujg",
+ "default_dedicated_server_site_warranty_quota",
+ "invoicing_section",
+ "invoicing_column",
+ "gst_percentage",
+ "npo_discount",
+ "autoscale_discount",
+ "column_break_qfwx",
+ "print_format",
+ "ic_key",
+ "stripe_settings_section",
+ "stripe_publishable_key",
+ "stripe_secret_key",
+ "column_break_26",
+ "create_stripe_plans",
+ "stripe_product_id",
+ "stripe_usd_plan_id",
+ "stripe_inr_plan_id",
+ "column_break_yhwz",
+ "create_stripe_webhook",
+ "stripe_webhook_endpoint_id",
+ "stripe_webhook_secret",
+ "ngrok_auth_token",
+ "razorpay_settings_section",
+ "razorpay_key_id",
+ "razorpay_webhook_secret",
+ "paypal_enabled",
+ "column_break_123",
+ "razorpay_key_secret",
+ "erpnext_authentication",
+ "erpnext_url",
+ "erpnext_api_key",
+ "erpnext_api_secret",
+ "column_break_38",
+ "frappeio_authentication_section",
+ "disable_frappe_auth",
+ "frappe_url",
+ "frappeio_api_key",
+ "column_break_39",
+ "frappeio_api_secret",
+ "backups_tab",
+ "offsite_backups_section",
+ "backup_region",
+ "offsite_backups_provider",
+ "aws_s3_bucket",
+ "data_40",
+ "backup_rotation_scheme",
+ "column_break_35",
+ "offsite_backups_access_key_id",
+ "offsite_backups_secret_access_key",
+ "offsite_backups_count",
+ "backups_section",
+ "backup_interval",
+ "backup_offset",
+ "column_break_48",
+ "backup_limit",
+ "max_failed_backup_attempts_in_a_day",
+ "physical_backups_section",
+ "disable_physical_backup",
+ "max_concurrent_physical_restorations",
+ "docker_tab",
+ "section_break_59",
+ "docker_registry_url",
+ "docker_registry_namespace",
+ "docker_s3_access_key",
+ "column_break_64",
+ "docker_registry_username",
+ "docker_registry_password",
+ "docker_s3_secret_key",
+ "asset_store_section",
+ "asset_store_access_key",
+ "asset_store_secret_access_key",
+ "asset_store_endpoint",
+ "asset_store_region",
+ "asset_store_bucket_name",
+ "use_asset_store",
+ "docker_build_section",
+ "suspend_builds",
+ "clone_directory",
+ "build_directory",
+ "build_server",
+ "minimum_rebuild_memory",
+ "new_bench_concurrency_limit",
+ "column_break_66",
+ "code_server",
+ "code_server_password",
+ "use_app_cache",
+ "compress_app_cache",
+ "use_delta_builds",
+ "use_agent_job_callbacks",
+ "auto_update_section",
+ "auto_update_queue_size",
+ "remote_files_section",
+ "remote_uploads_bucket",
+ "remote_link_expiry",
+ "region_name",
+ "column_break_51",
+ "remote_access_key_id",
+ "remote_secret_access_key",
+ "product_documentation_section",
+ "publish_docs",
+ "storage_and_disk_limits_section",
+ "enforce_storage_limits",
+ "erpnext_tab",
+ "erpnext_signups_section",
+ "erpnext_domain",
+ "erpnext_cluster",
+ "erpnext_plan",
+ "erpnext_group",
+ "column_break_89",
+ "erpnext_apps",
+ "central_migration_server",
+ "staging_sites_section",
+ "staging_plan",
+ "staging_expiry",
+ "erpnext_site_pool_section",
+ "enable_site_pooling",
+ "standby_pool_size",
+ "column_break_95",
+ "standby_queue_size",
+ "integrations_tab",
+ "telegram_section",
+ "telegram_chat_id",
+ "column_break_65",
+ "telegram_bot_token",
+ "mailgun_settings_section",
+ "mailgun_api_key",
+ "root_domain",
+ "column_break_117",
+ "default_outgoing_id",
+ "default_outgoing_pass",
+ "section_break_33",
+ "create_github_app",
+ "github_app_id",
+ "github_app_client_id",
+ "github_app_client_secret",
+ "column_break_36",
+ "github_app_public_link",
+ "github_webhook_secret",
+ "github_access_token",
+ "deploy_marker",
+ "section_break_41",
+ "column_break_tcmy",
+ "column_break_edst",
+ "github_app_private_key",
+ "aws_section",
+ "aws_access_key_id",
+ "column_break_agig",
+ "aws_secret_access_key",
+ "twilio_section",
+ "twilio_account_sid",
+ "twilio_api_key_sid",
+ "twilio_api_key_secret",
+ "column_break_kxuj",
+ "twilio_phone_number",
+ "spamd_section",
+ "enable_spam_check",
+ "spamd_endpoint",
+ "column_break_xhfy",
+ "spamd_api_key",
+ "spamd_api_secret",
+ "chatwoot_section",
+ "enable_chat",
+ "chat_base_url",
+ "chat_website_token",
+ "column_break_srse",
+ "chat_support_start_time",
+ "chat_support_end_time",
+ "marketplace_tab",
+ "marketplace_settings_section",
+ "max_allowed_screenshots",
+ "threshold",
+ "commission",
+ "usd_rate",
+ "app_include_script",
+ "github_pat_token",
+ "plausible_column",
+ "plausible_url",
+ "plausible_site_id",
+ "plausible_api_key",
+ "infrastructure_tab",
+ "general_section",
+ "production_server_ip",
+ "agent_section",
+ "agent_repository_owner",
+ "agent_sentry_dsn",
+ "column_break_105",
+ "agent_github_access_token",
+ "branch",
+ "lets_encrypt_section",
+ "certbot_directory",
+ "webroot_directory",
+ "rsa_key_size",
+ "column_break_15",
+ "eff_registration_email",
+ "use_staging_ca",
+ "ssh_section",
+ "ssh_certificate_authority",
+ "bench_section",
+ "redis_cache_size",
+ "set_redis_password",
+ "monitoring_section",
+ "monitor_server",
+ "monitor_token",
+ "press_monitoring_password",
+ "send_telegram_notifications",
+ "column_break_jlzi",
+ "log_server",
+ "telegram_alert_chat_id",
+ "telegram_alerts_chat_group",
+ "send_email_notifications",
+ "email_recipients",
+ "section_break_nloq",
+ "servers_using_alternative_http_port_for_communication",
+ "auto_scale_section",
+ "shared_directory",
+ "cool_off_period",
+ "feature_flags_tab",
+ "verify_cards_with_micro_charge",
+ "enable_google_oauth",
+ "realtime_job_updates",
+ "disable_agent_job_deduplication",
+ "disable_binlog_indexer_service",
+ "column_break_rdlr",
+ "disable_auto_retry",
+ "disallow_disposable_emails",
+ "enable_email_pre_verification",
+ "execute_incident_action",
+ "enable_server_snapshot_recovery",
+ "use_new_deploy_flow",
+ "section_break_jstu",
+ "enable_app_grouping",
+ "default_apps",
+ "partner_tab",
+ "partnership_fees_section",
+ "partnership_fee_usd",
+ "column_break_yxrj",
+ "partnership_fee_inr",
+ "section_break_dhzi",
+ "drive_resource_link",
+ "frappe_school_authentication_section",
+ "school_url",
+ "school_api_key",
+ "column_break_uxxz",
+ "school_api_secret",
+ "hybrid_server_tab",
+ "hybrid_cluster",
+ "hybrid_domain",
+ "tls_renewal_queue_size",
+ "security_tab",
+ "wazuh_server"
+ ],
+ "fields": [
+ {
+ "fieldname": "domain",
+ "fieldtype": "Link",
+ "label": "Domain",
+ "options": "Root Domain"
+ },
+ {
+ "fieldname": "cluster",
+ "fieldtype": "Link",
+ "label": "Cluster",
+ "options": "Cluster"
+ },
+ {
+ "default": "1",
+ "fieldname": "trial_sites_count",
+ "fieldtype": "Int",
+ "label": "Number of Sites in Trial"
+ },
+ {
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "{}",
+ "fieldname": "bench_configuration",
+ "fieldtype": "Code",
+ "in_list_view": 1,
+ "label": "Bench Confguration",
+ "options": "JSON",
+ "reqd": 1
+ },
+ {
+ "fieldname": "billing_tab",
+ "fieldtype": "Tab Break",
+ "label": "Billing"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "stripe_settings_section",
+ "fieldtype": "Section Break",
+ "label": "Stripe Settings"
+ },
+ {
+ "fieldname": "stripe_inr_plan_id",
+ "fieldtype": "Data",
+ "label": "Stripe INR Plan ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "stripe_publishable_key",
+ "fieldtype": "Data",
+ "label": "Stripe Publishable Key"
+ },
+ {
+ "fieldname": "create_stripe_plans",
+ "fieldtype": "Button",
+ "label": "Create Stripe Plans"
+ },
+ {
+ "fieldname": "stripe_product_id",
+ "fieldtype": "Data",
+ "label": "Stripe Product ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "stripe_usd_plan_id",
+ "fieldtype": "Data",
+ "label": "Stripe USD Plan ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "create_stripe_webhook",
+ "fieldtype": "Button",
+ "label": "Create Stripe Webhook"
+ },
+ {
+ "fieldname": "stripe_webhook_endpoint_id",
+ "fieldtype": "Data",
+ "label": "Stripe Webhook Endpoint ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "stripe_webhook_secret",
+ "fieldtype": "Data",
+ "label": "Stripe Webhook Secret",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_26",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "stripe_secret_key",
+ "fieldtype": "Password",
+ "label": "Stripe Secret Key"
+ },
+ {
+ "fieldname": "free_credits_inr",
+ "fieldtype": "Currency",
+ "label": "Credits on Signup (INR)",
+ "options": "INR"
+ },
+ {
+ "fieldname": "free_credits_usd",
+ "fieldtype": "Currency",
+ "label": "Credits on Signup (USD)",
+ "options": "USD"
+ },
+ {
+ "description": "Sign up on ngrok.com to get one for free",
+ "fieldname": "ngrok_auth_token",
+ "fieldtype": "Data",
+ "label": "Ngrok Auth Token"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "razorpay_settings_section",
+ "fieldtype": "Section Break",
+ "label": "Razorpay Settings"
+ },
+ {
+ "fieldname": "razorpay_key_id",
+ "fieldtype": "Data",
+ "label": "Razorpay Key ID"
+ },
+ {
+ "fieldname": "razorpay_webhook_secret",
+ "fieldtype": "Data",
+ "label": "Razorpay Webhook Secret"
+ },
+ {
+ "fieldname": "column_break_123",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "razorpay_key_secret",
+ "fieldtype": "Password",
+ "label": "Razorpay Key Secret"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "erpnext_authentication",
+ "fieldtype": "Section Break",
+ "label": "ERPNext Authentication"
+ },
+ {
+ "fieldname": "erpnext_url",
+ "fieldtype": "Data",
+ "label": "ERPNext URL"
+ },
+ {
+ "fieldname": "erpnext_api_key",
+ "fieldtype": "Data",
+ "label": "ERPNext API Key"
+ },
+ {
+ "fieldname": "erpnext_api_secret",
+ "fieldtype": "Password",
+ "label": "ERPNext API Secret"
+ },
+ {
+ "fieldname": "column_break_38",
+ "fieldtype": "Column Break"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "frappeio_authentication_section",
+ "fieldtype": "Section Break",
+ "label": "Frappe.io Authentication"
+ },
+ {
+ "fieldname": "frappe_url",
+ "fieldtype": "Data",
+ "label": "URL"
+ },
+ {
+ "fieldname": "frappeio_api_key",
+ "fieldtype": "Data",
+ "label": "Frappe.io API Key"
+ },
+ {
+ "fieldname": "column_break_39",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "frappeio_api_secret",
+ "fieldtype": "Password",
+ "label": "Frappe.io API Secret"
+ },
+ {
+ "fieldname": "backups_tab",
+ "fieldtype": "Tab Break",
+ "label": "Backups"
+ },
+ {
+ "fieldname": "offsite_backups_section",
+ "fieldtype": "Section Break",
+ "label": "Offsite Backups"
+ },
+ {
+ "fieldname": "backup_region",
+ "fieldtype": "Data",
+ "label": "Backup Region"
+ },
+ {
+ "default": "AWS S3",
+ "fieldname": "offsite_backups_provider",
+ "fieldtype": "Select",
+ "label": "Backup Provider",
+ "options": "AWS S3"
+ },
+ {
+ "fieldname": "aws_s3_bucket",
+ "fieldtype": "Data",
+ "label": "Bucket Name"
+ },
+ {
+ "fieldname": "data_40",
+ "fieldtype": "Data"
+ },
+ {
+ "fieldname": "backup_rotation_scheme",
+ "fieldtype": "Select",
+ "label": "Backup Rotation Scheme",
+ "options": "FIFO\nGrandfather-father-son"
+ },
+ {
+ "fieldname": "column_break_35",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "offsite_backups_access_key_id",
+ "fieldtype": "Data",
+ "label": "Access Key ID"
+ },
+ {
+ "fieldname": "offsite_backups_secret_access_key",
+ "fieldtype": "Password",
+ "label": "Secret Access Key"
+ },
+ {
+ "depends_on": "eval:doc.backup_rotation_scheme==\"FIFO\"",
+ "description": "The max number of Offsite backups that will be retained at any given time (for each site)",
+ "fieldname": "offsite_backups_count",
+ "fieldtype": "Int",
+ "label": "Total Backups Count"
+ },
+ {
+ "fieldname": "backups_section",
+ "fieldtype": "Section Break",
+ "label": "Backups"
+ },
+ {
+ "fieldname": "backup_interval",
+ "fieldtype": "Int",
+ "label": "Backup Interval"
+ },
+ {
+ "default": "0",
+ "fieldname": "backup_offset",
+ "fieldtype": "Int",
+ "label": "Backup Offset"
+ },
+ {
+ "fieldname": "column_break_48",
+ "fieldtype": "Column Break"
+ },
+ {
+ "description": "Number of backups to take per ScheduledBackupJob",
+ "fieldname": "backup_limit",
+ "fieldtype": "Int",
+ "label": "Backup Limit"
+ },
+ {
+ "fieldname": "docker_tab",
+ "fieldtype": "Tab Break",
+ "label": "Docker"
+ },
+ {
+ "fieldname": "section_break_59",
+ "fieldtype": "Section Break",
+ "label": "Docker Registry"
+ },
+ {
+ "fieldname": "docker_registry_url",
+ "fieldtype": "Data",
+ "label": "Docker Registry URL"
+ },
+ {
+ "fieldname": "docker_registry_namespace",
+ "fieldtype": "Data",
+ "label": "Docker Registry Namespace"
+ },
+ {
+ "fieldname": "column_break_64",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "docker_registry_username",
+ "fieldtype": "Data",
+ "label": "Docker Registry Username"
+ },
+ {
+ "fieldname": "docker_registry_password",
+ "fieldtype": "Data",
+ "label": "Docker Registry Password"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "docker_build_section",
+ "fieldtype": "Section Break",
+ "label": "Docker Build"
+ },
+ {
+ "fieldname": "clone_directory",
+ "fieldtype": "Data",
+ "label": "Clone Directory"
+ },
+ {
+ "fieldname": "build_directory",
+ "fieldtype": "Data",
+ "label": "Build Directory"
+ },
+ {
+ "fieldname": "column_break_66",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "code_server",
+ "fieldtype": "Data",
+ "label": "Code Server"
+ },
+ {
+ "fieldname": "code_server_password",
+ "fieldtype": "Data",
+ "label": "Code Server Password"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "auto_update_section",
+ "fieldtype": "Section Break",
+ "label": "Auto Update"
+ },
+ {
+ "default": "4",
+ "fieldname": "auto_update_queue_size",
+ "fieldtype": "Int",
+ "label": "Auto Update Queue Size"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "remote_files_section",
+ "fieldtype": "Section Break",
+ "label": "Remote Files"
+ },
+ {
+ "fieldname": "remote_uploads_bucket",
+ "fieldtype": "Data",
+ "label": "Uploads Bucket Name"
+ },
+ {
+ "fieldname": "remote_link_expiry",
+ "fieldtype": "Int",
+ "label": "Link Expiry"
+ },
+ {
+ "fieldname": "column_break_51",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "remote_access_key_id",
+ "fieldtype": "Data",
+ "label": "Remote Access Key ID"
+ },
+ {
+ "fieldname": "remote_secret_access_key",
+ "fieldtype": "Password",
+ "label": "Remote Secret Access Key"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "product_documentation_section",
+ "fieldtype": "Section Break",
+ "label": "Product Documentation"
+ },
+ {
+ "default": "0",
+ "fieldname": "publish_docs",
+ "fieldtype": "Check",
+ "label": "Published"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "storage_and_disk_limits_section",
+ "fieldtype": "Section Break",
+ "label": "Storage and Disk Limits"
+ },
+ {
+ "default": "0",
+ "description": "Setting this to true will start suspending sites that cross the Site Usages with respect to their existing plans.",
+ "fieldname": "enforce_storage_limits",
+ "fieldtype": "Check",
+ "label": "Enforce Storage and Disk Limits"
+ },
+ {
+ "fieldname": "erpnext_tab",
+ "fieldtype": "Tab Break",
+ "label": "ERPNext"
+ },
+ {
+ "fieldname": "erpnext_signups_section",
+ "fieldtype": "Section Break",
+ "label": "ERPNext Signups"
+ },
+ {
+ "fieldname": "erpnext_domain",
+ "fieldtype": "Link",
+ "label": "ERPNext Domain",
+ "options": "Root Domain"
+ },
+ {
+ "fetch_from": "erpnext_domain.default_cluster",
+ "fetch_if_empty": 1,
+ "fieldname": "erpnext_cluster",
+ "fieldtype": "Link",
+ "label": "ERPNext Cluster",
+ "options": "Cluster"
+ },
+ {
+ "fieldname": "erpnext_plan",
+ "fieldtype": "Link",
+ "label": "ERPNext Plan",
+ "options": "Site Plan"
+ },
+ {
+ "fieldname": "erpnext_group",
+ "fieldtype": "Link",
+ "label": "ERPNext Group",
+ "options": "Release Group"
+ },
+ {
+ "fieldname": "column_break_89",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "erpnext_apps",
+ "fieldtype": "Table",
+ "label": "ERPNext Apps",
+ "options": "ERPNext App"
+ },
+ {
+ "fieldname": "central_migration_server",
+ "fieldtype": "Link",
+ "label": "Central Migration Server",
+ "options": "Server"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "staging_sites_section",
+ "fieldtype": "Section Break",
+ "label": "Staging Sites"
+ },
+ {
+ "fieldname": "staging_plan",
+ "fieldtype": "Link",
+ "label": "Staging Plan",
+ "options": "Site Plan"
+ },
+ {
+ "default": "24",
+ "fieldname": "staging_expiry",
+ "fieldtype": "Int",
+ "label": "Staging Expiry"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "erpnext_site_pool_section",
+ "fieldtype": "Section Break",
+ "label": "ERPNext Site Pool"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_site_pooling",
+ "fieldtype": "Check",
+ "label": "Enable Site Pooling"
+ },
+ {
+ "default": "5",
+ "fieldname": "standby_pool_size",
+ "fieldtype": "Int",
+ "label": "Standby Pool Size"
+ },
+ {
+ "fieldname": "column_break_95",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "1",
+ "fieldname": "standby_queue_size",
+ "fieldtype": "Int",
+ "label": "Standby Queue Size"
+ },
+ {
+ "fieldname": "integrations_tab",
+ "fieldtype": "Tab Break",
+ "label": "Integrations"
+ },
+ {
+ "fieldname": "telegram_section",
+ "fieldtype": "Section Break",
+ "label": "Telegram"
+ },
+ {
+ "fieldname": "telegram_chat_id",
+ "fieldtype": "Data",
+ "label": "Telegram Chat ID"
+ },
+ {
+ "fieldname": "column_break_65",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "telegram_bot_token",
+ "fieldtype": "Data",
+ "label": "Telegram Bot Token"
+ },
+ {
+ "fieldname": "mailgun_settings_section",
+ "fieldtype": "Section Break",
+ "label": "Mailgun"
+ },
+ {
+ "fieldname": "mailgun_api_key",
+ "fieldtype": "Data",
+ "label": "Api Key"
+ },
+ {
+ "fieldname": "root_domain",
+ "fieldtype": "Data",
+ "label": "Root Domain"
+ },
+ {
+ "fieldname": "column_break_117",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "default_outgoing_id",
+ "fieldtype": "Data",
+ "label": "Default outgoing id"
+ },
+ {
+ "fieldname": "default_outgoing_pass",
+ "fieldtype": "Data",
+ "label": "Default outgoing pass"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "section_break_33",
+ "fieldtype": "Section Break",
+ "label": "GitHub"
+ },
+ {
+ "depends_on": "eval: !doc.github_app_id",
+ "fieldname": "create_github_app",
+ "fieldtype": "Button",
+ "label": "Create GitHub App",
+ "mandatory_depends_on": "eval"
+ },
+ {
+ "fieldname": "github_app_id",
+ "fieldtype": "Data",
+ "label": "GitHub App ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "github_app_client_id",
+ "fieldtype": "Data",
+ "label": "GitHub App Client ID",
+ "read_only": 1
+ },
+ {
+ "fieldname": "github_app_client_secret",
+ "fieldtype": "Data",
+ "label": "GitHub App Client Secret",
+ "read_only": 1
+ },
+ {
+ "default": "fc-deploy",
+ "fieldname": "column_break_36",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "github_app_public_link",
+ "fieldtype": "Data",
+ "label": "GitHub App Public Link",
+ "read_only": 1
+ },
+ {
+ "fieldname": "github_webhook_secret",
+ "fieldtype": "Data",
+ "label": "GitHub Webhook Secret",
+ "read_only": 1
+ },
+ {
+ "fieldname": "github_access_token",
+ "fieldtype": "Data",
+ "label": "GitHub Access Token"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "section_break_41",
+ "fieldtype": "Section Break",
+ "hide_border": 1
+ },
+ {
+ "fieldname": "github_app_private_key",
+ "fieldtype": "Code",
+ "hidden": 1,
+ "label": "GitHub App Private Key",
+ "read_only": 1
+ },
+ {
+ "fieldname": "marketplace_tab",
+ "fieldtype": "Tab Break",
+ "label": "Marketplace"
+ },
+ {
+ "fieldname": "marketplace_settings_section",
+ "fieldtype": "Section Break",
+ "label": "Marketplace Settings"
+ },
+ {
+ "default": "6",
+ "fieldname": "max_allowed_screenshots",
+ "fieldtype": "Int",
+ "label": "Max number of Allowed Screenshots",
+ "non_negative": 1
+ },
+ {
+ "fieldname": "infrastructure_tab",
+ "fieldtype": "Tab Break",
+ "label": "Infrastructure"
+ },
+ {
+ "fieldname": "agent_section",
+ "fieldtype": "Section Break",
+ "label": "Agent"
+ },
+ {
+ "default": "frappe",
+ "fieldname": "agent_repository_owner",
+ "fieldtype": "Data",
+ "label": "Agent Repository Owner"
+ },
+ {
+ "fieldname": "column_break_105",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "agent_github_access_token",
+ "fieldtype": "Data",
+ "label": "Agent GitHub Access Token"
+ },
+ {
+ "fieldname": "lets_encrypt_section",
+ "fieldtype": "Section Break",
+ "label": "Let's Encrypt"
+ },
+ {
+ "fieldname": "certbot_directory",
+ "fieldtype": "Data",
+ "label": "Certbot Directory",
+ "reqd": 1
+ },
+ {
+ "fieldname": "webroot_directory",
+ "fieldtype": "Data",
+ "label": "Webroot Directory"
+ },
+ {
+ "default": "2048",
+ "fieldname": "rsa_key_size",
+ "fieldtype": "Select",
+ "label": "RSA Key Size",
+ "options": "2048\n3072\n4096",
+ "reqd": 1
+ },
+ {
+ "fieldname": "column_break_15",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "eff_registration_email",
+ "fieldtype": "Data",
+ "label": "EFF Registration Email",
+ "reqd": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "use_staging_ca",
+ "fieldtype": "Check",
+ "label": "Use Staging CA"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "ssh_section",
+ "fieldtype": "Section Break",
+ "label": "SSH"
+ },
+ {
+ "fieldname": "ssh_certificate_authority",
+ "fieldtype": "Link",
+ "label": "SSH Certificate Authority",
+ "options": "SSH Certificate Authority"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "monitoring_section",
+ "fieldtype": "Section Break",
+ "label": "Monitoring"
+ },
+ {
+ "fieldname": "telegram_alert_chat_id",
+ "fieldtype": "Data",
+ "label": "Telegram Alert Chat ID"
+ },
+ {
+ "fieldname": "monitor_server",
+ "fieldtype": "Link",
+ "label": "Monitor Server",
+ "options": "Monitor Server"
+ },
+ {
+ "fieldname": "monitor_token",
+ "fieldtype": "Data",
+ "label": "Monitor Token"
+ },
+ {
+ "fieldname": "log_server",
+ "fieldtype": "Link",
+ "label": "Log Server",
+ "options": "Log Server"
+ },
+ {
+ "fieldname": "feature_flags_tab",
+ "fieldtype": "Tab Break",
+ "label": "Feature Flags"
+ },
+ {
+ "default": "No",
+ "fieldname": "verify_cards_with_micro_charge",
+ "fieldtype": "Select",
+ "label": "Verify Cards with Micro Charge",
+ "options": "No\nOnly INR\nOnly USD\nBoth INR and USD"
+ },
+ {
+ "fieldname": "threshold",
+ "fieldtype": "Float",
+ "label": "Marketplace Payout Threshold"
+ },
+ {
+ "fieldname": "commission",
+ "fieldtype": "Float",
+ "label": "Marketplace Commission"
+ },
+ {
+ "fieldname": "usd_rate",
+ "fieldtype": "Float",
+ "label": "USD Rate"
+ },
+ {
+ "fieldname": "press_monitoring_password",
+ "fieldtype": "Password",
+ "label": "Press Monitoring Password"
+ },
+ {
+ "description": "Adds this script to app_include_js via site config. Used for in-site billing",
+ "fieldname": "app_include_script",
+ "fieldtype": "Data",
+ "label": "App Include Script"
+ },
+ {
+ "fieldname": "telegram_alerts_chat_group",
+ "fieldtype": "Link",
+ "label": "Telegram Alerts Chat Group",
+ "options": "Telegram Group"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_google_oauth",
+ "fieldtype": "Check",
+ "label": "Enable Google Oauth "
+ },
+ {
+ "fieldname": "plausible_api_key",
+ "fieldtype": "Password",
+ "label": "Plausible API Key"
+ },
+ {
+ "fieldname": "plausible_column",
+ "fieldtype": "Column Break",
+ "label": "Plausible"
+ },
+ {
+ "fieldname": "plausible_url",
+ "fieldtype": "Data",
+ "label": "Plausible URL"
+ },
+ {
+ "fieldname": "plausible_site_id",
+ "fieldtype": "Data",
+ "label": "Plausible site id"
+ },
+ {
+ "default": "0",
+ "fieldname": "suspend_builds",
+ "fieldtype": "Check",
+ "label": "Suspend Builds",
+ "read_only": 1
+ },
+ {
+ "fieldname": "aws_section",
+ "fieldtype": "Section Break",
+ "label": "AWS"
+ },
+ {
+ "fieldname": "aws_access_key_id",
+ "fieldtype": "Data",
+ "label": "AWS Access Key ID"
+ },
+ {
+ "fieldname": "column_break_agig",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "aws_secret_access_key",
+ "fieldtype": "Password",
+ "label": "AWS Secret Access Key"
+ },
+ {
+ "fieldname": "twilio_section",
+ "fieldtype": "Section Break",
+ "label": "Twilio"
+ },
+ {
+ "fieldname": "twilio_account_sid",
+ "fieldtype": "Data",
+ "label": "Twilio Account SID"
+ },
+ {
+ "fieldname": "column_break_kxuj",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "twilio_phone_number",
+ "fieldtype": "Phone",
+ "label": "Twilio Phone Number"
+ },
+ {
+ "fieldname": "invoicing_column",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "gst_percentage",
+ "fieldtype": "Float",
+ "label": "GST Percentage"
+ },
+ {
+ "fieldname": "column_break_tcmy",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "column_break_edst",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "twilio_api_key_sid",
+ "fieldtype": "Data",
+ "label": "Twilio API Key SID"
+ },
+ {
+ "fieldname": "twilio_api_key_secret",
+ "fieldtype": "Password",
+ "label": "Twilio API Key Secret"
+ },
+ {
+ "fieldname": "invoicing_section",
+ "fieldtype": "Section Break",
+ "label": "Invoicing"
+ },
+ {
+ "fieldname": "column_break_qfwx",
+ "fieldtype": "Column Break"
+ },
+ {
+ "description": "Fetched from frappe.io",
+ "fieldname": "print_format",
+ "fieldtype": "Data",
+ "label": "Print Format"
+ },
+ {
+ "default": "0",
+ "description": "Uses Bench get-app cache for faster image builds. Will be set only if Bench version is 5.22.1 or later.",
+ "fieldname": "use_app_cache",
+ "fieldtype": "Check",
+ "label": "Use App Cache"
+ },
+ {
+ "default": "0",
+ "depends_on": "eval: doc.use_app_cache",
+ "description": "Use Gzip to compress bench get-app artifacts before caching.",
+ "fieldname": "compress_app_cache",
+ "fieldtype": "Check",
+ "label": "Compress App Cache"
+ },
+ {
+ "fieldname": "column_break_rdlr",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "realtime_job_updates",
+ "fieldtype": "Check",
+ "label": "Realtime Job Updates"
+ },
+ {
+ "default": "0",
+ "description": "Quickens builds by fetching app changes without rebuilding app if app rebuild is not required.",
+ "fieldname": "use_delta_builds",
+ "fieldtype": "Check",
+ "label": "Use Delta Builds"
+ },
+ {
+ "fieldname": "hybrid_server_tab",
+ "fieldtype": "Tab Break",
+ "label": "Hybrid Server"
+ },
+ {
+ "fieldname": "hybrid_cluster",
+ "fieldtype": "Link",
+ "label": "Hybrid Cluster",
+ "options": "Cluster"
+ },
+ {
+ "fieldname": "hybrid_domain",
+ "fieldtype": "Link",
+ "label": "Hybrid Domain",
+ "options": "Root Domain"
+ },
+ {
+ "default": "0",
+ "fieldname": "disable_auto_retry",
+ "fieldtype": "Check",
+ "label": "Disable Auto Retry"
+ },
+ {
+ "default": "1",
+ "fieldname": "disable_agent_job_deduplication",
+ "fieldtype": "Check",
+ "label": "Disable Agent Job Deduplication"
+ },
+ {
+ "fieldname": "agent_sentry_dsn",
+ "fieldtype": "Data",
+ "label": "Agent Sentry DSN"
+ },
+ {
+ "fieldname": "build_server",
+ "fieldtype": "Link",
+ "label": "Build Server",
+ "options": "Server"
+ },
+ {
+ "default": "10",
+ "fieldname": "tls_renewal_queue_size",
+ "fieldtype": "Int",
+ "label": "TLS Renewal Queue Size"
+ },
+ {
+ "default": "80",
+ "fieldname": "micro_debit_charge_inr",
+ "fieldtype": "Currency",
+ "label": "Micro Debit Charge (INR)",
+ "precision": "0"
+ },
+ {
+ "default": "1",
+ "fieldname": "micro_debit_charge_usd",
+ "fieldtype": "Currency",
+ "label": "Micro Debit Charge (USD)",
+ "precision": "0"
+ },
+ {
+ "default": "master",
+ "fieldname": "branch",
+ "fieldtype": "Data",
+ "label": "Branch"
+ },
+ {
+ "fieldname": "column_break_yhwz",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "column_break_cpry",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "column_break_wrqp",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "500",
+ "fieldname": "usage_record_creation_batch_size",
+ "fieldtype": "Int",
+ "label": "Usage Record Creation Batch Size"
+ },
+ {
+ "fieldname": "press_trial_plan",
+ "fieldtype": "Link",
+ "label": "Press Trial Plan",
+ "options": "Site Plan"
+ },
+ {
+ "fieldname": "section_break_jstu",
+ "fieldtype": "Section Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_app_grouping",
+ "fieldtype": "Check",
+ "label": "Enable App Grouping"
+ },
+ {
+ "fieldname": "default_apps",
+ "fieldtype": "Table",
+ "label": "Default Apps",
+ "options": "App Group"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_email_pre_verification",
+ "fieldtype": "Check",
+ "label": "Enable Email Pre-Verification"
+ },
+ {
+ "fieldname": "bench_section",
+ "fieldtype": "Section Break",
+ "label": "Bench"
+ },
+ {
+ "default": "512",
+ "fieldname": "redis_cache_size",
+ "fieldtype": "Int",
+ "label": "Redis Cache Size (MB)"
+ },
+ {
+ "fieldname": "partner_tab",
+ "fieldtype": "Tab Break",
+ "label": "Partner"
+ },
+ {
+ "fieldname": "partnership_fees_section",
+ "fieldtype": "Section Break",
+ "label": "Partnership Fees"
+ },
+ {
+ "fieldname": "partnership_fee_usd",
+ "fieldtype": "Int",
+ "label": "Partnership Fee USD"
+ },
+ {
+ "fieldname": "column_break_yxrj",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "partnership_fee_inr",
+ "fieldtype": "Int",
+ "label": "Partnership Fee INR"
+ },
+ {
+ "fieldname": "github_pat_token",
+ "fieldtype": "Data",
+ "label": "Github PAT Token"
+ },
+ {
+ "default": "1",
+ "fieldname": "disable_physical_backup",
+ "fieldtype": "Check",
+ "label": "Disable Physical Backup"
+ },
+ {
+ "fieldname": "physical_backups_section",
+ "fieldtype": "Section Break",
+ "label": "Physical Backups"
+ },
+ {
+ "fieldname": "spamd_section",
+ "fieldtype": "Section Break",
+ "label": "Spamd"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_spam_check",
+ "fieldtype": "Check",
+ "label": "Enable Spam Check"
+ },
+ {
+ "fieldname": "spamd_endpoint",
+ "fieldtype": "Data",
+ "label": "Spamd Endpoint"
+ },
+ {
+ "fieldname": "column_break_xhfy",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "spamd_api_key",
+ "fieldtype": "Data",
+ "label": "Spamd API Key"
+ },
+ {
+ "fieldname": "spamd_api_secret",
+ "fieldtype": "Password",
+ "label": "Spamd API Secret"
+ },
+ {
+ "default": "2",
+ "fieldname": "max_concurrent_physical_restorations",
+ "fieldtype": "Int",
+ "label": "Max Concurrent Physical Restorations"
+ },
+ {
+ "default": "1",
+ "fieldname": "send_telegram_notifications",
+ "fieldtype": "Check",
+ "label": "Send Telegram Notifications"
+ },
+ {
+ "fieldname": "column_break_jlzi",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "send_email_notifications",
+ "fieldtype": "Check",
+ "label": "Send Email Notifications"
+ },
+ {
+ "depends_on": "eval: doc.send_email_notifications== true",
+ "fieldname": "email_recipients",
+ "fieldtype": "Small Text",
+ "label": "Email Recipients"
+ },
+ {
+ "default": "1",
+ "fieldname": "use_agent_job_callbacks",
+ "fieldtype": "Check",
+ "label": "Use Agent Job Callbacks"
+ },
+ {
+ "default": "2",
+ "fieldname": "minimum_rebuild_memory",
+ "fieldtype": "Int",
+ "label": "Minimum Rebuild Memory (GB)",
+ "non_negative": 1
+ },
+ {
+ "description": "Max attempts we will do on a site with failed attempts",
+ "fieldname": "max_failed_backup_attempts_in_a_day",
+ "fieldtype": "Int",
+ "label": "Max Failed Backup Attempts In A Day"
+ },
+ {
+ "default": "0",
+ "fieldname": "disable_frappe_auth",
+ "fieldtype": "Check",
+ "label": "Disable Frappe Auth"
+ },
+ {
+ "fieldname": "section_break_nloq",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "servers_using_alternative_http_port_for_communication",
+ "fieldtype": "Small Text",
+ "label": "Servers Using Alternative HTTP Port For Communication"
+ },
+ {
+ "description": "Add value in percent (%). e.g. 10",
+ "fieldname": "npo_discount",
+ "fieldtype": "Float",
+ "label": "NPO Discount"
+ },
+ {
+ "default": "0",
+ "fieldname": "execute_incident_action",
+ "fieldtype": "Check",
+ "label": "Execute Incident Action"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_server_snapshot_recovery",
+ "fieldtype": "Check",
+ "label": "Enable Server Snapshot Recovery"
+ },
+ {
+ "fieldname": "docker_s3_access_key",
+ "fieldtype": "Data",
+ "label": "Docker S3 Access Key"
+ },
+ {
+ "fieldname": "docker_s3_secret_key",
+ "fieldtype": "Password",
+ "label": "Docker S3 Secret Key"
+ },
+ {
+ "default": "0",
+ "description": "Enable via RazorPay dashboard",
+ "fieldname": "paypal_enabled",
+ "fieldtype": "Check",
+ "label": "PayPal Enabled"
+ },
+ {
+ "default": "1",
+ "description": "Set redis password common site config and redis configs at release group level",
+ "fieldname": "set_redis_password",
+ "fieldtype": "Check",
+ "label": "Set Redis Password"
+ },
+ {
+ "default": "1",
+ "fieldname": "disallow_disposable_emails",
+ "fieldtype": "Check",
+ "label": "Disallow disposable emails"
+ },
+ {
+ "fieldname": "drive_resource_link",
+ "fieldtype": "Data",
+ "label": "Drive Resource Link"
+ },
+ {
+ "fieldname": "ic_key",
+ "fieldtype": "Password",
+ "label": "IC Key"
+ },
+ {
+ "fieldname": "section_break_dhzi",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "auto_scale_section",
+ "fieldtype": "Section Break",
+ "label": "Auto Scale"
+ },
+ {
+ "default": "/home/frappe/shared",
+ "fieldname": "shared_directory",
+ "fieldtype": "Data",
+ "label": "Shared Directory"
+ },
+ {
+ "default": "600",
+ "description": "Time between two autoscale events (up scale or down scale)",
+ "fieldname": "cool_off_period",
+ "fieldtype": "Int",
+ "label": "Cool off period"
+ },
+ {
+ "fieldname": "deploy_marker",
+ "fieldtype": "Data",
+ "label": "Deploy Marker",
+ "options": "If found in commit message deploy will be triggered"
+ },
+ {
+ "fieldname": "security_tab",
+ "fieldtype": "Tab Break",
+ "label": "Security"
+ },
+ {
+ "fieldname": "wazuh_server",
+ "fieldtype": "Data",
+ "label": "Wazuh Server"
+ },
+ {
+ "fieldname": "autoscale_discount",
+ "fieldtype": "Float",
+ "label": "Autoscale Discount"
+ },
+ {
+ "default": "1",
+ "fieldname": "disable_binlog_indexer_service",
+ "fieldtype": "Check",
+ "label": "Disable Binlog Indexer Service"
+ },
+ {
+ "fieldname": "default_server_plan_type",
+ "fieldtype": "Link",
+ "label": "Default Server Plan Type",
+ "options": "Server Plan Type"
+ },
+ {
+ "fieldname": "frappe_school_authentication_section",
+ "fieldtype": "Section Break",
+ "label": "Frappe School Authentication"
+ },
+ {
+ "fieldname": "school_url",
+ "fieldtype": "Data",
+ "label": "School URL"
+ },
+ {
+ "fieldname": "school_api_key",
+ "fieldtype": "Data",
+ "label": "School API Key"
+ },
+ {
+ "fieldname": "column_break_uxxz",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "school_api_secret",
+ "fieldtype": "Password",
+ "label": "School API Secret"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "asset_store_section",
+ "fieldtype": "Section Break",
+ "label": "Asset Store"
+ },
+ {
+ "default": "0",
+ "description": "Will only use this asset storage backend if checked.",
+ "fieldname": "use_asset_store",
+ "fieldtype": "Check",
+ "label": "Use Asset Store"
+ },
+ {
+ "fieldname": "asset_store_access_key",
+ "fieldtype": "Data",
+ "label": "Asset Store Access Key"
+ },
+ {
+ "fieldname": "asset_store_secret_access_key",
+ "fieldtype": "Password",
+ "label": "Asset Store Secret Access Key"
+ },
+ {
+ "fieldname": "asset_store_endpoint",
+ "fieldtype": "Data",
+ "label": "Asset Store Endpoint"
+ },
+ {
+ "fieldname": "asset_store_bucket_name",
+ "fieldtype": "Data",
+ "label": "Asset Store Bucket Name "
+ },
+ {
+ "fieldname": "asset_store_region",
+ "fieldtype": "Data",
+ "label": "Asset Store Region"
+ },
+ {
+ "fieldname": "frappe_school_authentication_section",
+ "fieldtype": "Section Break",
+ "label": "Frappe School Authentication"
+ },
+ {
+ "fieldname": "general_section",
+ "fieldtype": "Section Break",
+ "label": "General"
+ },
+ {
+ "fieldname": "production_server_ip",
+ "fieldtype": "Data",
+ "label": "Production Server IP"
+ },
+ {
+ "default": "30",
+ "fieldname": "new_bench_concurrency_limit",
+ "fieldtype": "Int",
+ "label": "New Bench Concurrency Limit"
+ },
+ {
+ "default": "0",
+ "fieldname": "use_new_deploy_flow",
+ "fieldtype": "Check",
+ "label": "Use New Deploy Flow"
+ },
+ {
+ "fieldname": "plans_section",
+ "fieldtype": "Section Break",
+ "label": "Plans"
+ },
+ {
+ "fieldname": "column_break_kujg",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "30",
+ "description": "Default number of days before the site warranty setting can be changed for newly created dedicated servers",
+ "fieldname": "default_dedicated_server_site_warranty_change_cooldown",
+ "fieldtype": "Int",
+ "label": "Default Dedicated Server Site Warranty change Cooldown"
+ },
+ {
+ "default": "5",
+ "description": "Default max number of sites with product warranty for newly created dedicated servers\n",
+ "fieldname": "default_dedicated_server_site_warranty_quota",
+ "fieldtype": "Int",
+ "label": "Default Dedicated Server Supported Site Quota"
+ },
+ {
+ "fieldname": "chatwoot_section",
+ "fieldtype": "Section Break",
+ "label": "Chat Support"
+ },
+ {
+ "fieldname": "column_break_srse",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_chat",
+ "fieldtype": "Check",
+ "label": "Enable Chat"
+ },
+ {
+ "fieldname": "chat_base_url",
+ "fieldtype": "Data",
+ "label": "Chat Base URL"
+ },
+ {
+ "fieldname": "chat_website_token",
+ "fieldtype": "Data",
+ "label": "Chat Website Token"
+ },
+ {
+ "default": "10",
+ "fieldname": "chat_support_start_time",
+ "fieldtype": "Select",
+ "label": "Chat Support Start Time",
+ "options": "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23"
+ },
+ {
+ "default": "18",
+ "fieldname": "chat_support_end_time",
+ "fieldtype": "Select",
+ "label": "Chat Support End Time",
+ "options": "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24"
+ },
+ {
+ "fieldname": "region_name",
+ "fieldtype": "Data",
+ "label": "Region Name"
+ }
+ ],
+ "issingle": 1,
+ "links": [],
+ "modified": "2026-04-27 11:01:14.970816",
+ "modified_by": "Administrator",
+ "module": "Press",
+ "name": "Press Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "row_format": "Dynamic",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": [],
+ "track_changes": 1
+}
diff --git a/press/press/doctype/press_settings/press_settings.py b/press/press/doctype/press_settings/press_settings.py
index 4607b5cfb9d..89ff07f87c7 100644
--- a/press/press/doctype/press_settings/press_settings.py
+++ b/press/press/doctype/press_settings/press_settings.py
@@ -60,6 +60,8 @@ class PressSettings(Document):
cool_off_period: DF.Int
data_40: DF.Data | None
default_apps: DF.Table[AppGroup]
+ default_dedicated_server_site_warranty_change_cooldown: DF.Int
+ default_dedicated_server_site_warranty_quota: DF.Int
default_outgoing_id: DF.Data | None
default_outgoing_pass: DF.Data | None
default_server_plan_type: DF.Link | None
@@ -319,7 +321,10 @@ def twilio_client(self) -> Client:
return Client(api_key_sid, api_key_secret, account_sid)
def get_default_apps(self):
- if hasattr(self, "enable_app_grouping") and hasattr(self, "default_apps"): # noqa
- if self.enable_app_grouping:
- return [app.app for app in self.default_apps]
+ if (
+ hasattr(self, "enable_app_grouping")
+ and hasattr(self, "default_apps")
+ and self.enable_app_grouping
+ ):
+ return [app.app for app in self.default_apps]
return []
diff --git a/press/press/doctype/server/server.json b/press/press/doctype/server/server.json
index 6ca58700b9b..011170d2b86 100644
--- a/press/press/doctype/server/server.json
+++ b/press/press/doctype/server/server.json
@@ -1,808 +1,821 @@
{
- "actions": [],
- "creation": "2019-12-09 12:34:13.844800",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
- "title",
- "status",
- "hostname",
- "hostname_abbreviation",
- "domain",
- "self_hosted_server_domain",
- "tls_certificate_renewal_failed",
- "is_unified_server",
- "column_break_4",
- "cluster",
- "provider",
- "virtual_machine",
- "ignore_incidents_till",
- "section_break_mequ",
- "is_server_setup",
- "is_server_prepared",
- "is_server_renamed",
- "is_provisioning_press_job_completed",
- "is_self_hosted",
- "keep_files_on_server_in_offsite_backup",
- "public",
- "column_break_laiq",
- "use_agent_job_callbacks",
- "is_pyspy_setup",
- "halt_agent_jobs",
- "stop_deployments",
- "is_for_recovery",
- "is_monitoring_disabled",
- "enable_on_prem_failover_support",
- "billing_section",
- "team",
- "plan",
- "column_break_11",
- "auto_increase_storage",
- "auto_add_storage_min",
- "auto_add_storage_max",
- "networking_section",
- "ip",
- "is_static_ip",
- "ipv6",
- "nat_server",
- "column_break_3",
- "private_ip",
- "private_mac_address",
- "private_vlan_id",
- "agent_section",
- "agent_password",
- "column_break_pdbx",
- "disable_agent_job_auto_retry",
- "reverse_proxy_section",
- "proxy_server",
- "column_break_12",
- "is_upstream_setup",
- "database_section",
- "database_server",
- "self_hosted_mariadb_server",
- "is_managed_database",
- "enable_logical_replication_during_site_update",
- "column_break_jdiy",
- "self_hosted_mariadb_root_password",
- "managed_database_service",
- "replication",
- "is_primary",
- "is_replication_setup",
- "column_break_24",
- "primary",
- "auto_scale_section",
- "secondary_server",
- "is_secondary",
- "benches_on_shared_volume",
- "scaled_up",
- "column_break_ywnx",
- "auto_scale_trigger",
- "ssh_section",
- "ssh_user",
- "ssh_port",
- "frappe_user_password",
- "frappe_public_key",
- "column_break_20",
- "bastion_server",
- "root_public_key",
- "section_break_22",
- "use_for_new_benches",
- "use_for_new_sites",
- "staging",
- "use_for_build",
- "platform",
- "column_break_ktkv",
- "new_worker_allocation",
- "set_bench_memory_limits",
- "ram",
- "backups_section",
- "skip_scheduled_backups",
- "standalone_section",
- "is_standalone",
- "column_break_edyf",
- "is_standalone_setup",
- "tags_section",
- "tags",
- "mounts_section",
- "has_data_volume",
- "mounts",
- "notifications_section",
- "communication_infos"
- ],
- "fields": [
- {
- "fetch_from": "virtual_machine.public_ip_address",
- "fieldname": "ip",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "IP"
- },
- {
- "fieldname": "proxy_server",
- "fieldtype": "Link",
- "label": "Proxy Server",
- "options": "Proxy Server"
- },
- {
- "fetch_from": "virtual_machine.private_ip_address",
- "fieldname": "private_ip",
- "fieldtype": "Data",
- "label": "Private IP"
- },
- {
- "fieldname": "agent_password",
- "fieldtype": "Password",
- "label": "Agent Password",
- "read_only": 1
- },
- {
- "collapsible": 1,
- "fieldname": "agent_section",
- "fieldtype": "Section Break",
- "label": "Agent"
- },
- {
- "default": "0",
- "fieldname": "is_server_setup",
- "fieldtype": "Check",
- "label": "Is Server Setup",
- "read_only": 1
- },
- {
- "default": "0",
- "fieldname": "is_upstream_setup",
- "fieldtype": "Check",
- "label": "Upstream Setup",
- "read_only": 1
- },
- {
- "default": "Pending",
- "fieldname": "status",
- "fieldtype": "Select",
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Status",
- "options": "Pending\nInstalling\nActive\nBroken\nArchived",
- "read_only": 1,
- "reqd": 1
- },
- {
- "fieldname": "column_break_3",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "column_break_12",
- "fieldtype": "Column Break"
- },
- {
- "collapsible": 1,
- "fieldname": "reverse_proxy_section",
- "fieldtype": "Section Break",
- "label": "Reverse Proxy"
- },
- {
- "fieldname": "database_section",
- "fieldtype": "Section Break",
- "label": "Database"
- },
- {
- "depends_on": "eval:!doc.is_managed_database",
- "fieldname": "database_server",
- "fieldtype": "Link",
- "label": "Database Server",
- "options": "Database Server"
- },
- {
- "collapsible": 1,
- "fieldname": "ssh_section",
- "fieldtype": "Section Break",
- "label": "SSH"
- },
- {
- "fieldname": "root_public_key",
- "fieldtype": "Code",
- "label": "Root Public Key",
- "read_only": 1
- },
- {
- "fieldname": "frappe_public_key",
- "fieldtype": "Code",
- "label": "Frappe Public Key",
- "read_only": 1
- },
- {
- "fieldname": "column_break_20",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "section_break_22",
- "fieldtype": "Section Break"
- },
- {
- "default": "0",
- "fieldname": "use_for_new_benches",
- "fieldtype": "Check",
- "label": "Use For New Benches",
- "read_only": 1
- },
- {
- "fieldname": "hostname",
- "fieldtype": "Data",
- "label": "Hostname",
- "reqd": 1,
- "set_only_once": 1
- },
- {
- "fieldname": "domain",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Domain",
- "options": "Root Domain",
- "set_only_once": 1
- },
- {
- "default": "0",
- "fieldname": "use_for_new_sites",
- "fieldtype": "Check",
- "label": "Use For New Sites",
- "read_only": 1
- },
- {
- "fieldname": "cluster",
- "fieldtype": "Link",
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Cluster",
- "options": "Cluster",
- "set_only_once": 1
- },
- {
- "fieldname": "column_break_4",
- "fieldtype": "Column Break"
- },
- {
- "collapsible": 1,
- "fieldname": "networking_section",
- "fieldtype": "Section Break",
- "label": "Networking"
- },
- {
- "depends_on": "eval: doc.provider === \"Scaleway\"",
- "fieldname": "private_mac_address",
- "fieldtype": "Data",
- "label": "Private Mac Address",
- "mandatory_depends_on": "eval: doc.provider === \"Scaleway\"",
- "set_only_once": 1
- },
- {
- "depends_on": "eval: doc.provider === \"Scaleway\"",
- "fieldname": "private_vlan_id",
- "fieldtype": "Data",
- "label": "Private VLAN ID",
- "mandatory_depends_on": "eval: doc.provider === \"Scaleway\"",
- "set_only_once": 1
- },
- {
- "default": "Generic",
- "fieldname": "provider",
- "fieldtype": "Select",
- "label": "Provider",
- "options": "Generic\nScaleway\nAWS EC2\nOCI\nHetzner\nVodacom\nDigitalOcean\nFrappe Compute",
- "set_only_once": 1
- },
- {
- "fieldname": "frappe_user_password",
- "fieldtype": "Password",
- "label": "Frappe User Password",
- "set_only_once": 1
- },
- {
- "collapsible": 1,
- "fieldname": "replication",
- "fieldtype": "Section Break",
- "label": "Replication"
- },
- {
- "default": "1",
- "fieldname": "is_primary",
- "fieldtype": "Check",
- "label": "Is Primary"
- },
- {
- "fieldname": "column_break_24",
- "fieldtype": "Column Break"
- },
- {
- "depends_on": "eval: !doc.is_primary",
- "fieldname": "primary",
- "fieldtype": "Link",
- "label": "Primary",
- "mandatory_depends_on": "eval: !doc.is_primary",
- "options": "Server"
- },
- {
- "default": "0",
- "depends_on": "eval: !doc.is_primary",
- "fieldname": "is_replication_setup",
- "fieldtype": "Check",
- "label": "Is Replication Setup",
- "read_only": 1
- },
- {
- "default": "0",
- "fieldname": "staging",
- "fieldtype": "Check",
- "label": "Staging"
- },
- {
- "depends_on": "eval:[\"AWS EC2\", \"OCI\", \"Hetzner\", \"DigitalOcean\", \"Frappe Compute\"].includes(doc.provider)",
- "fieldname": "virtual_machine",
- "fieldtype": "Link",
- "label": "Virtual Machine",
- "mandatory_depends_on": "eval:[\"AWS EC2\", \"OCI\"].includes(doc.provider)",
- "options": "Virtual Machine"
- },
- {
- "default": "1",
- "fieldname": "new_worker_allocation",
- "fieldtype": "Check",
- "label": "New Worker Allocation"
- },
- {
- "fieldname": "ram",
- "fieldtype": "Float",
- "label": "RAM"
- },
- {
- "fieldname": "team",
- "fieldtype": "Link",
- "label": "Team",
- "options": "Team"
- },
- {
- "fieldname": "billing_section",
- "fieldtype": "Section Break",
- "label": "Billing"
- },
- {
- "fieldname": "column_break_11",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "plan",
- "fieldtype": "Link",
- "label": "Plan",
- "options": "Server Plan"
- },
- {
- "default": "0",
- "fieldname": "is_server_prepared",
- "fieldtype": "Check",
- "label": "Is Server Prepared",
- "read_only": 1
- },
- {
- "default": "0",
- "fieldname": "is_server_renamed",
- "fieldtype": "Check",
- "label": "Is Server Renamed",
- "read_only": 1
- },
- {
- "fieldname": "title",
- "fieldtype": "Data",
- "label": "Title"
- },
- {
- "default": "0",
- "fieldname": "is_self_hosted",
- "fieldtype": "Check",
- "label": "Is Self Hosted"
- },
- {
- "default": "root",
- "fieldname": "ssh_user",
- "fieldtype": "Data",
- "label": "SSH User"
- },
- {
- "depends_on": "eval:doc.is_self_hosted==true && !doc.is_managed_database",
- "fieldname": "self_hosted_mariadb_server",
- "fieldtype": "Data",
- "label": "Self Hosted MariaDB Server IP"
- },
- {
- "depends_on": "eval:doc.is_self_hosted==true",
- "fieldname": "column_break_jdiy",
- "fieldtype": "Column Break"
- },
- {
- "depends_on": "eval:doc.is_self_hosted==true && !doc.is_managed_database",
- "fieldname": "self_hosted_mariadb_root_password",
- "fieldtype": "Password",
- "label": "Self Hosted MariaDB Root Password"
- },
- {
- "depends_on": "eval:doc.is_self_hosted",
- "fieldname": "self_hosted_server_domain",
- "fieldtype": "Data",
- "label": "Self Hosted Server Domain"
- },
- {
- "default": "22",
- "fieldname": "ssh_port",
- "fieldtype": "Int",
- "label": "SSH Port"
- },
- {
- "collapsible": 1,
- "fieldname": "standalone_section",
- "fieldtype": "Section Break",
- "label": "Standalone"
- },
- {
- "default": "0",
- "fieldname": "is_standalone",
- "fieldtype": "Check",
- "label": "Is Standalone"
- },
- {
- "fieldname": "column_break_edyf",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "fieldname": "is_standalone_setup",
- "fieldtype": "Check",
- "label": "Is Standalone Setup",
- "read_only": 1
- },
- {
- "fieldname": "tags_section",
- "fieldtype": "Section Break",
- "label": "Tags"
- },
- {
- "fieldname": "tags",
- "fieldtype": "Table",
- "label": "Tags",
- "options": "Resource Tag"
- },
- {
- "fieldname": "column_break_ktkv",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "fieldname": "set_bench_memory_limits",
- "fieldtype": "Check",
- "label": "Set Bench Memory Limits"
- },
- {
- "fieldname": "hostname_abbreviation",
- "fieldtype": "Data",
- "label": "Hostname Abbreviation"
- },
- {
- "collapsible": 1,
- "fieldname": "backups_section",
- "fieldtype": "Section Break",
- "label": "Backups"
- },
- {
- "default": "0",
- "fieldname": "skip_scheduled_backups",
- "fieldtype": "Check",
- "label": "Skip Scheduled Backups"
- },
- {
- "fieldname": "column_break_pdbx",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "fieldname": "disable_agent_job_auto_retry",
- "fieldtype": "Check",
- "label": "Disable Agent Job Auto Retry"
- },
- {
- "default": "0",
- "description": "If user opts DBaaS eg. RDS",
- "fieldname": "is_managed_database",
- "fieldtype": "Check",
- "label": "Is Managed Database"
- },
- {
- "fieldname": "managed_database_service",
- "fieldtype": "Link",
- "label": "Managed Database Service",
- "options": "Managed Database Service"
- },
- {
- "default": "0",
- "description": "Public release groups will be deployed here",
- "fieldname": "public",
- "fieldtype": "Check",
- "label": "Public"
- },
- {
- "default": "0",
- "description": "If checked, server will be used to run Docker builds.",
- "fieldname": "use_for_build",
- "fieldtype": "Check",
- "label": "Use For Build",
- "search_index": 1
- },
- {
- "default": "25",
- "description": "Minimum storage to add automatically each time",
- "fieldname": "auto_add_storage_min",
- "fieldtype": "Int",
- "label": "Auto Add Storage Min",
- "non_negative": 1
- },
- {
- "default": "250",
- "description": "Maximum storage to add automatically each time",
- "fieldname": "auto_add_storage_max",
- "fieldtype": "Int",
- "label": "Auto Add Storage Max",
- "non_negative": 1
- },
- {
- "fieldname": "mounts_section",
- "fieldtype": "Section Break",
- "label": "Mounts"
- },
- {
- "fieldname": "mounts",
- "fieldtype": "Table",
- "label": "Mounts",
- "options": "Server Mount"
- },
- {
- "default": "0",
- "fetch_from": "virtual_machine.has_data_volume",
- "fieldname": "has_data_volume",
- "fieldtype": "Check",
- "label": "Has Data Volume",
- "read_only": 1
- },
- {
- "fieldname": "ipv6",
- "fieldtype": "Data",
- "label": "IPv6"
- },
- {
- "default": "0",
- "fieldname": "use_agent_job_callbacks",
- "fieldtype": "Check",
- "label": "Use Agent Job Callbacks"
- },
- {
- "default": "0",
- "fieldname": "is_pyspy_setup",
- "fieldtype": "Check",
- "label": "Is PySpy Setup",
- "read_only": 1
- },
- {
- "fieldname": "section_break_mequ",
- "fieldtype": "Section Break"
- },
- {
- "fieldname": "column_break_laiq",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "description": "Stop polling and queuing agent jobs",
- "fieldname": "halt_agent_jobs",
- "fieldtype": "Check",
- "label": "Halt Agent Jobs"
- },
- {
- "default": "x86_64",
- "fieldname": "platform",
- "fieldtype": "Select",
- "label": "Platform",
- "options": "x86_64\narm64"
- },
- {
- "default": "1",
- "fieldname": "auto_increase_storage",
- "fieldtype": "Check",
- "label": "Auto Increase Storage"
- },
- {
- "default": "0",
- "description": "Stop all deployments on this server.",
- "fieldname": "stop_deployments",
- "fieldtype": "Check",
- "label": "Stop Deployments"
- },
- {
- "default": "0",
- "fieldname": "keep_files_on_server_in_offsite_backup",
- "fieldtype": "Check",
- "label": "Keep Backup Files Onsite"
- },
- {
- "default": "0",
- "fieldname": "is_for_recovery",
- "fieldtype": "Check",
- "label": "Is for Recovery"
- },
- {
- "default": "0",
- "fieldname": "enable_logical_replication_during_site_update",
- "fieldtype": "Check",
- "label": "Enable Logical Replication During Site Update"
- },
- {
- "fieldname": "ignore_incidents_till",
- "fieldtype": "Datetime",
- "label": "Ignore Incidents Till"
- },
- {
- "default": "0",
- "fieldname": "tls_certificate_renewal_failed",
- "fieldtype": "Check",
- "label": "TLS Certificate Renewal Failed",
- "read_only": 1
- },
- {
- "default": "0",
- "fieldname": "is_static_ip",
- "fieldtype": "Check",
- "label": "Is Static IP",
- "read_only": 1
- },
- {
- "fieldname": "notifications_section",
- "fieldtype": "Section Break",
- "label": "Notifications"
- },
- {
- "fieldname": "communication_infos",
- "fieldtype": "Table",
- "label": "Communication Infos",
- "options": "Communication Info"
- },
- {
- "fieldname": "bastion_server",
- "fieldtype": "Link",
- "label": "Bastion Server",
- "options": "Bastion Server"
- },
- {
- "description": "Used during horizontal scaling.",
- "fieldname": "secondary_server",
- "fieldtype": "Link",
- "label": "Secondary Server",
- "options": "Server",
- "read_only": 1
- },
- {
- "collapsible": 1,
- "fieldname": "auto_scale_section",
- "fieldtype": "Section Break",
- "label": "Auto Scale"
- },
- {
- "default": "0",
- "fieldname": "is_monitoring_disabled",
- "fieldtype": "Check",
- "label": "Is Monitoring Disabled",
- "search_index": 1
- },
- {
- "default": "0",
- "description": "Is this a secondary server",
- "fieldname": "is_secondary",
- "fieldtype": "Check",
- "label": "Is Secondary",
- "read_only": 1
- },
- {
- "default": "0",
- "description": "Are the benches running on a shared volume",
- "fieldname": "benches_on_shared_volume",
- "fieldtype": "Check",
- "label": "Benches on Shared Volume",
- "read_only": 1
- },
- {
- "fieldname": "auto_scale_trigger",
- "fieldtype": "Table",
- "label": "Auto Scale Trigger",
- "options": "Auto Scale Trigger"
- },
- {
- "default": "0",
- "description": "Check if the benches are running on the secondary server",
- "fieldname": "scaled_up",
- "fieldtype": "Check",
- "label": "Scaled Up",
- "read_only": 1
- },
- {
- "fieldname": "column_break_ywnx",
- "fieldtype": "Column Break"
- },
- {
- "default": "0",
- "description": "Checked if database and app are hosted on the server server",
- "fieldname": "is_unified_server",
- "fieldtype": "Check",
- "label": "Is Unified Server"
- },
- {
- "default": "0",
- "fieldname": "is_provisioning_press_job_completed",
- "fieldtype": "Check",
- "label": "Is Provisioning Job Completed"
- },
- {
- "fieldname": "nat_server",
- "fieldtype": "Link",
- "label": "NAT Server",
- "options": "NAT Server"
- },
- {
- "default": "0",
- "fieldname": "enable_on_prem_failover_support",
- "fieldtype": "Check",
- "label": "Enable On-Prem Failover Support"
- }
- ],
- "links": [
- {
- "link_doctype": "Auto Scale Record",
- "link_fieldname": "primary_server"
- },
- {
- "link_doctype": "On-Prem Failover",
- "link_fieldname": "app_server"
- }
- ],
- "modified": "2026-03-18 02:33:48.730257",
- "modified_by": "Administrator",
- "module": "Press",
- "name": "Server",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "share": 1,
- "write": 1
- },
- {
- "create": 1,
- "read": 1,
- "role": "Press Admin",
- "write": 1
- },
- {
- "create": 1,
- "read": 1,
- "role": "Press Member",
- "write": 1
- }
- ],
- "row_format": "Dynamic",
- "rows_threshold_for_grid_search": 20,
- "sort_field": "modified",
- "sort_order": "DESC",
- "states": [],
- "title_field": "title",
- "track_changes": 1
-}
\ No newline at end of file
+ "actions": [],
+ "creation": "2019-12-09 12:34:13.844800",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "title",
+ "status",
+ "hostname",
+ "hostname_abbreviation",
+ "domain",
+ "self_hosted_server_domain",
+ "tls_certificate_renewal_failed",
+ "is_unified_server",
+ "column_break_4",
+ "cluster",
+ "provider",
+ "virtual_machine",
+ "ignore_incidents_till",
+ "section_break_mequ",
+ "is_server_setup",
+ "is_server_prepared",
+ "is_server_renamed",
+ "is_provisioning_press_job_completed",
+ "is_self_hosted",
+ "keep_files_on_server_in_offsite_backup",
+ "public",
+ "column_break_laiq",
+ "use_agent_job_callbacks",
+ "is_pyspy_setup",
+ "halt_agent_jobs",
+ "stop_deployments",
+ "is_for_recovery",
+ "is_monitoring_disabled",
+ "enable_on_prem_failover_support",
+ "billing_section",
+ "team",
+ "plan",
+ "site_warranty_change_cooldown",
+ "supported_site_quota",
+ "column_break_11",
+ "auto_increase_storage",
+ "auto_add_storage_min",
+ "auto_add_storage_max",
+ "networking_section",
+ "ip",
+ "is_static_ip",
+ "ipv6",
+ "column_break_3",
+ "private_ip",
+ "private_mac_address",
+ "private_vlan_id",
+ "agent_section",
+ "agent_password",
+ "column_break_pdbx",
+ "disable_agent_job_auto_retry",
+ "reverse_proxy_section",
+ "proxy_server",
+ "column_break_12",
+ "is_upstream_setup",
+ "database_section",
+ "database_server",
+ "self_hosted_mariadb_server",
+ "is_managed_database",
+ "enable_logical_replication_during_site_update",
+ "column_break_jdiy",
+ "self_hosted_mariadb_root_password",
+ "managed_database_service",
+ "replication",
+ "is_primary",
+ "is_replication_setup",
+ "column_break_24",
+ "primary",
+ "auto_scale_section",
+ "secondary_server",
+ "is_secondary",
+ "benches_on_shared_volume",
+ "scaled_up",
+ "column_break_ywnx",
+ "auto_scale_trigger",
+ "ssh_section",
+ "ssh_user",
+ "ssh_port",
+ "frappe_user_password",
+ "frappe_public_key",
+ "column_break_20",
+ "bastion_server",
+ "root_public_key",
+ "section_break_22",
+ "use_for_new_benches",
+ "use_for_new_sites",
+ "staging",
+ "use_for_build",
+ "platform",
+ "column_break_ktkv",
+ "new_worker_allocation",
+ "set_bench_memory_limits",
+ "ram",
+ "backups_section",
+ "skip_scheduled_backups",
+ "standalone_section",
+ "is_standalone",
+ "column_break_edyf",
+ "is_standalone_setup",
+ "tags_section",
+ "tags",
+ "mounts_section",
+ "has_data_volume",
+ "mounts",
+ "notifications_section",
+ "communication_infos"
+ ],
+ "fields": [
+ {
+ "fetch_from": "virtual_machine.public_ip_address",
+ "fieldname": "ip",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "IP"
+ },
+ {
+ "fieldname": "proxy_server",
+ "fieldtype": "Link",
+ "label": "Proxy Server",
+ "options": "Proxy Server"
+ },
+ {
+ "fetch_from": "virtual_machine.private_ip_address",
+ "fieldname": "private_ip",
+ "fieldtype": "Data",
+ "label": "Private IP"
+ },
+ {
+ "fieldname": "agent_password",
+ "fieldtype": "Password",
+ "label": "Agent Password",
+ "read_only": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "agent_section",
+ "fieldtype": "Section Break",
+ "label": "Agent"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_server_setup",
+ "fieldtype": "Check",
+ "label": "Is Server Setup",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "is_upstream_setup",
+ "fieldtype": "Check",
+ "label": "Upstream Setup",
+ "read_only": 1
+ },
+ {
+ "default": "Pending",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Status",
+ "options": "Pending\nInstalling\nActive\nBroken\nArchived",
+ "read_only": 1,
+ "reqd": 1
+ },
+ {
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "reverse_proxy_section",
+ "fieldtype": "Section Break",
+ "label": "Reverse Proxy"
+ },
+ {
+ "fieldname": "database_section",
+ "fieldtype": "Section Break",
+ "label": "Database"
+ },
+ {
+ "depends_on": "eval:!doc.is_managed_database",
+ "fieldname": "database_server",
+ "fieldtype": "Link",
+ "label": "Database Server",
+ "options": "Database Server"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "ssh_section",
+ "fieldtype": "Section Break",
+ "label": "SSH"
+ },
+ {
+ "fieldname": "root_public_key",
+ "fieldtype": "Code",
+ "label": "Root Public Key",
+ "read_only": 1
+ },
+ {
+ "fieldname": "frappe_public_key",
+ "fieldtype": "Code",
+ "label": "Frappe Public Key",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_20",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "section_break_22",
+ "fieldtype": "Section Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "use_for_new_benches",
+ "fieldtype": "Check",
+ "label": "Use For New Benches",
+ "read_only": 1
+ },
+ {
+ "fieldname": "hostname",
+ "fieldtype": "Data",
+ "label": "Hostname",
+ "reqd": 1,
+ "set_only_once": 1
+ },
+ {
+ "fieldname": "domain",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Domain",
+ "options": "Root Domain",
+ "set_only_once": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "use_for_new_sites",
+ "fieldtype": "Check",
+ "label": "Use For New Sites",
+ "read_only": 1
+ },
+ {
+ "fieldname": "cluster",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Cluster",
+ "options": "Cluster",
+ "set_only_once": 1
+ },
+ {
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "networking_section",
+ "fieldtype": "Section Break",
+ "label": "Networking"
+ },
+ {
+ "depends_on": "eval: doc.provider === \"Scaleway\"",
+ "fieldname": "private_mac_address",
+ "fieldtype": "Data",
+ "label": "Private Mac Address",
+ "mandatory_depends_on": "eval: doc.provider === \"Scaleway\"",
+ "set_only_once": 1
+ },
+ {
+ "depends_on": "eval: doc.provider === \"Scaleway\"",
+ "fieldname": "private_vlan_id",
+ "fieldtype": "Data",
+ "label": "Private VLAN ID",
+ "mandatory_depends_on": "eval: doc.provider === \"Scaleway\"",
+ "set_only_once": 1
+ },
+ {
+ "default": "Generic",
+ "fieldname": "provider",
+ "fieldtype": "Select",
+ "label": "Provider",
+ "options": "Generic\nScaleway\nAWS EC2\nOCI\nHetzner\nVodacom\nDigitalOcean\nFrappe Compute",
+ "set_only_once": 1
+ },
+ {
+ "fieldname": "frappe_user_password",
+ "fieldtype": "Password",
+ "label": "Frappe User Password",
+ "set_only_once": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "replication",
+ "fieldtype": "Section Break",
+ "label": "Replication"
+ },
+ {
+ "default": "1",
+ "fieldname": "is_primary",
+ "fieldtype": "Check",
+ "label": "Is Primary"
+ },
+ {
+ "fieldname": "column_break_24",
+ "fieldtype": "Column Break"
+ },
+ {
+ "depends_on": "eval: !doc.is_primary",
+ "fieldname": "primary",
+ "fieldtype": "Link",
+ "label": "Primary",
+ "mandatory_depends_on": "eval: !doc.is_primary",
+ "options": "Server"
+ },
+ {
+ "default": "0",
+ "depends_on": "eval: !doc.is_primary",
+ "fieldname": "is_replication_setup",
+ "fieldtype": "Check",
+ "label": "Is Replication Setup",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "staging",
+ "fieldtype": "Check",
+ "label": "Staging"
+ },
+ {
+ "depends_on": "eval:[\"AWS EC2\", \"OCI\", \"Hetzner\", \"DigitalOcean\", \"Frappe Compute\"].includes(doc.provider)",
+ "fieldname": "virtual_machine",
+ "fieldtype": "Link",
+ "label": "Virtual Machine",
+ "mandatory_depends_on": "eval:[\"AWS EC2\", \"OCI\"].includes(doc.provider)",
+ "options": "Virtual Machine"
+ },
+ {
+ "default": "1",
+ "fieldname": "new_worker_allocation",
+ "fieldtype": "Check",
+ "label": "New Worker Allocation"
+ },
+ {
+ "fieldname": "ram",
+ "fieldtype": "Float",
+ "label": "RAM"
+ },
+ {
+ "fieldname": "team",
+ "fieldtype": "Link",
+ "label": "Team",
+ "options": "Team"
+ },
+ {
+ "fieldname": "billing_section",
+ "fieldtype": "Section Break",
+ "label": "Billing"
+ },
+ {
+ "fieldname": "column_break_11",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "plan",
+ "fieldtype": "Link",
+ "label": "Plan",
+ "options": "Server Plan"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_server_prepared",
+ "fieldtype": "Check",
+ "label": "Is Server Prepared",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "is_server_renamed",
+ "fieldtype": "Check",
+ "label": "Is Server Renamed",
+ "read_only": 1
+ },
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "label": "Title"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_self_hosted",
+ "fieldtype": "Check",
+ "label": "Is Self Hosted"
+ },
+ {
+ "default": "root",
+ "fieldname": "ssh_user",
+ "fieldtype": "Data",
+ "label": "SSH User"
+ },
+ {
+ "depends_on": "eval:doc.is_self_hosted==true && !doc.is_managed_database",
+ "fieldname": "self_hosted_mariadb_server",
+ "fieldtype": "Data",
+ "label": "Self Hosted MariaDB Server IP"
+ },
+ {
+ "depends_on": "eval:doc.is_self_hosted==true",
+ "fieldname": "column_break_jdiy",
+ "fieldtype": "Column Break"
+ },
+ {
+ "depends_on": "eval:doc.is_self_hosted==true && !doc.is_managed_database",
+ "fieldname": "self_hosted_mariadb_root_password",
+ "fieldtype": "Password",
+ "label": "Self Hosted MariaDB Root Password"
+ },
+ {
+ "depends_on": "eval:doc.is_self_hosted",
+ "fieldname": "self_hosted_server_domain",
+ "fieldtype": "Data",
+ "label": "Self Hosted Server Domain"
+ },
+ {
+ "default": "22",
+ "fieldname": "ssh_port",
+ "fieldtype": "Int",
+ "label": "SSH Port"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "standalone_section",
+ "fieldtype": "Section Break",
+ "label": "Standalone"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_standalone",
+ "fieldtype": "Check",
+ "label": "Is Standalone"
+ },
+ {
+ "fieldname": "column_break_edyf",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_standalone_setup",
+ "fieldtype": "Check",
+ "label": "Is Standalone Setup",
+ "read_only": 1
+ },
+ {
+ "fieldname": "tags_section",
+ "fieldtype": "Section Break",
+ "label": "Tags"
+ },
+ {
+ "fieldname": "tags",
+ "fieldtype": "Table",
+ "label": "Tags",
+ "options": "Resource Tag"
+ },
+ {
+ "fieldname": "column_break_ktkv",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "set_bench_memory_limits",
+ "fieldtype": "Check",
+ "label": "Set Bench Memory Limits"
+ },
+ {
+ "fieldname": "hostname_abbreviation",
+ "fieldtype": "Data",
+ "label": "Hostname Abbreviation"
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "backups_section",
+ "fieldtype": "Section Break",
+ "label": "Backups"
+ },
+ {
+ "default": "0",
+ "fieldname": "skip_scheduled_backups",
+ "fieldtype": "Check",
+ "label": "Skip Scheduled Backups"
+ },
+ {
+ "fieldname": "column_break_pdbx",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "fieldname": "disable_agent_job_auto_retry",
+ "fieldtype": "Check",
+ "label": "Disable Agent Job Auto Retry"
+ },
+ {
+ "default": "0",
+ "description": "If user opts DBaaS eg. RDS",
+ "fieldname": "is_managed_database",
+ "fieldtype": "Check",
+ "label": "Is Managed Database"
+ },
+ {
+ "fieldname": "managed_database_service",
+ "fieldtype": "Link",
+ "label": "Managed Database Service",
+ "options": "Managed Database Service"
+ },
+ {
+ "default": "0",
+ "description": "Public release groups will be deployed here",
+ "fieldname": "public",
+ "fieldtype": "Check",
+ "label": "Public"
+ },
+ {
+ "default": "0",
+ "description": "If checked, server will be used to run Docker builds.",
+ "fieldname": "use_for_build",
+ "fieldtype": "Check",
+ "label": "Use For Build",
+ "search_index": 1
+ },
+ {
+ "default": "25",
+ "description": "Minimum storage to add automatically each time",
+ "fieldname": "auto_add_storage_min",
+ "fieldtype": "Int",
+ "label": "Auto Add Storage Min",
+ "non_negative": 1
+ },
+ {
+ "default": "250",
+ "description": "Maximum storage to add automatically each time",
+ "fieldname": "auto_add_storage_max",
+ "fieldtype": "Int",
+ "label": "Auto Add Storage Max",
+ "non_negative": 1
+ },
+ {
+ "fieldname": "mounts_section",
+ "fieldtype": "Section Break",
+ "label": "Mounts"
+ },
+ {
+ "fieldname": "mounts",
+ "fieldtype": "Table",
+ "label": "Mounts",
+ "options": "Server Mount"
+ },
+ {
+ "default": "0",
+ "fetch_from": "virtual_machine.has_data_volume",
+ "fieldname": "has_data_volume",
+ "fieldtype": "Check",
+ "label": "Has Data Volume",
+ "read_only": 1
+ },
+ {
+ "fieldname": "ipv6",
+ "fieldtype": "Data",
+ "label": "IPv6"
+ },
+ {
+ "default": "0",
+ "fieldname": "use_agent_job_callbacks",
+ "fieldtype": "Check",
+ "label": "Use Agent Job Callbacks"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_pyspy_setup",
+ "fieldtype": "Check",
+ "label": "Is PySpy Setup",
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_mequ",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "column_break_laiq",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "description": "Stop polling and queuing agent jobs",
+ "fieldname": "halt_agent_jobs",
+ "fieldtype": "Check",
+ "label": "Halt Agent Jobs"
+ },
+ {
+ "default": "x86_64",
+ "fieldname": "platform",
+ "fieldtype": "Select",
+ "label": "Platform",
+ "options": "x86_64\narm64"
+ },
+ {
+ "default": "1",
+ "fieldname": "auto_increase_storage",
+ "fieldtype": "Check",
+ "label": "Auto Increase Storage"
+ },
+ {
+ "default": "0",
+ "description": "Stop all deployments on this server.",
+ "fieldname": "stop_deployments",
+ "fieldtype": "Check",
+ "label": "Stop Deployments"
+ },
+ {
+ "default": "0",
+ "fieldname": "keep_files_on_server_in_offsite_backup",
+ "fieldtype": "Check",
+ "label": "Keep Backup Files Onsite"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_for_recovery",
+ "fieldtype": "Check",
+ "label": "Is for Recovery"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_logical_replication_during_site_update",
+ "fieldtype": "Check",
+ "label": "Enable Logical Replication During Site Update"
+ },
+ {
+ "fieldname": "ignore_incidents_till",
+ "fieldtype": "Datetime",
+ "label": "Ignore Incidents Till"
+ },
+ {
+ "default": "0",
+ "fieldname": "tls_certificate_renewal_failed",
+ "fieldtype": "Check",
+ "label": "TLS Certificate Renewal Failed",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "is_static_ip",
+ "fieldtype": "Check",
+ "label": "Is Static IP",
+ "read_only": 1
+ },
+ {
+ "fieldname": "notifications_section",
+ "fieldtype": "Section Break",
+ "label": "Notifications"
+ },
+ {
+ "fieldname": "communication_infos",
+ "fieldtype": "Table",
+ "label": "Communication Infos",
+ "options": "Communication Info"
+ },
+ {
+ "fieldname": "bastion_server",
+ "fieldtype": "Link",
+ "label": "Bastion Server",
+ "options": "Bastion Server"
+ },
+ {
+ "description": "Used during horizontal scaling.",
+ "fieldname": "secondary_server",
+ "fieldtype": "Link",
+ "label": "Secondary Server",
+ "options": "Server",
+ "read_only": 1
+ },
+ {
+ "collapsible": 1,
+ "fieldname": "auto_scale_section",
+ "fieldtype": "Section Break",
+ "label": "Auto Scale"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_monitoring_disabled",
+ "fieldtype": "Check",
+ "label": "Is Monitoring Disabled",
+ "search_index": 1
+ },
+ {
+ "default": "0",
+ "description": "Is this a secondary server",
+ "fieldname": "is_secondary",
+ "fieldtype": "Check",
+ "label": "Is Secondary",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "description": "Are the benches running on a shared volume",
+ "fieldname": "benches_on_shared_volume",
+ "fieldtype": "Check",
+ "label": "Benches on Shared Volume",
+ "read_only": 1
+ },
+ {
+ "fieldname": "auto_scale_trigger",
+ "fieldtype": "Table",
+ "label": "Auto Scale Trigger",
+ "options": "Auto Scale Trigger"
+ },
+ {
+ "default": "0",
+ "description": "Check if the benches are running on the secondary server",
+ "fieldname": "scaled_up",
+ "fieldtype": "Check",
+ "label": "Scaled Up",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_ywnx",
+ "fieldtype": "Column Break"
+ },
+ {
+ "default": "0",
+ "description": "Checked if database and app are hosted on the server server",
+ "fieldname": "is_unified_server",
+ "fieldtype": "Check",
+ "label": "Is Unified Server"
+ },
+ {
+ "default": "0",
+ "fieldname": "is_provisioning_press_job_completed",
+ "fieldtype": "Check",
+ "label": "Is Provisioning Job Completed"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_on_prem_failover_support",
+ "fieldtype": "Check",
+ "label": "Enable On-Prem Failover Support"
+ },
+ {
+ "default": "0",
+ "depends_on": "eval:!doc.__islocal && !doc.public",
+ "description": "No. of days before product warranty setting can be changed again for sites in this server",
+ "fieldname": "site_warranty_change_cooldown",
+ "fieldtype": "Int",
+ "label": "Site Warranty change Cooldown",
+ "read_only_depends_on": "eval:!!doc.__islocal"
+ },
+ {
+ "default": "0",
+ "depends_on": "eval:!doc.__islocal && !doc.public",
+ "description": "Max no. of sites with product warranty this server can have",
+ "fieldname": "supported_site_quota",
+ "fieldtype": "Int",
+ "label": "Supported Site Quota",
+ "read_only_depends_on": "eval:!!doc.__islocal"
+ }
+ ],
+ "links": [
+ {
+ "link_doctype": "Auto Scale Record",
+ "link_fieldname": "primary_server"
+ },
+ {
+ "link_doctype": "On-Prem Failover",
+ "link_fieldname": "app_server"
+ }
+ ],
+ "modified": "2026-04-27 11:14:27.975215",
+ "modified_by": "Administrator",
+ "module": "Press",
+ "name": "Server",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ },
+ {
+ "create": 1,
+ "read": 1,
+ "role": "Press Admin",
+ "write": 1
+ },
+ {
+ "create": 1,
+ "read": 1,
+ "role": "Press Member",
+ "write": 1
+ }
+ ],
+ "row_format": "Dynamic",
+ "rows_threshold_for_grid_search": 20,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": [],
+ "title_field": "title",
+ "track_changes": 1
+}
diff --git a/press/press/doctype/server/server.py b/press/press/doctype/server/server.py
index e38e4e0edda..95131c5277d 100644
--- a/press/press/doctype/server/server.py
+++ b/press/press/doctype/server/server.py
@@ -2705,12 +2705,14 @@ class Server(BaseServer):
self_hosted_mariadb_server: DF.Data | None
self_hosted_server_domain: DF.Data | None
set_bench_memory_limits: DF.Check
+ site_warranty_change_cooldown: DF.Int
skip_scheduled_backups: DF.Check
ssh_port: DF.Int
ssh_user: DF.Data | None
staging: DF.Check
status: DF.Literal["Pending", "Installing", "Active", "Broken", "Archived"]
stop_deployments: DF.Check
+ site_warranty_quota: DF.Int
tags: DF.Table[ResourceTag]
team: DF.Link | None
title: DF.Data | None
@@ -2774,6 +2776,9 @@ def on_update(self):
"Cannot enable logical replication during site update if multiple sites are present on the server. Please drop the sites in order to enable logical replication."
)
+ if self.is_new() and is_dedicated_server(self.name):
+ self.set_dedicated_server_site_warranty_quota_and_cooldown()
+
def update_db_server(self):
if not self.database_server:
return
@@ -2860,6 +2865,14 @@ def update_subscription(self):
"Subscription", add_on_storage_subscription.name, {"team": self.team, "enabled": 1}
)
+ def set_dedicated_server_site_warranty_quota_and_cooldown(self):
+ self.site_warranty_quota = frappe.get_value(
+ "Press Settings", None, "default_dedicated_server_site_warranty_quota"
+ )
+ self.site_warranty_change_cooldown = frappe.get_value(
+ "Press Settings", None, "default_dedicated_server_site_warranty_change_cooldown"
+ )
+
def create_secondary_server(self, plan_name: str) -> None:
"""Create a secondary server for this server"""
plan: ServerPlan = frappe.get_cached_doc("Server Plan", plan_name)
diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py
index ae23fb96aaf..952159867d9 100644
--- a/press/press/doctype/site/site.py
+++ b/press/press/doctype/site/site.py
@@ -51,7 +51,11 @@
)
from press.press.doctype.communication_info.communication_info import get_communication_info
from press.press.doctype.root_domain.root_domain import get_matching_domain
-from press.press.doctype.server.server import Server
+from press.press.doctype.server.server import Server, is_dedicated_server
+from press.press.doctype.site.site_plan_utils import (
+ get_available_warranty_quota_for_server,
+ get_next_allowed_dedicated_product_warranty_change_date,
+)
from press.saas.doctype.product_trial.product_trial import create_free_app_subscription
from press.utils.jobs import has_job_timeout_exceeded
from press.utils.telemetry import capture
@@ -77,7 +81,6 @@
marketplace_app_hook,
)
from press.press.doctype.resource_tag.tag_helpers import TagHelpers
-from press.press.doctype.server.server import is_dedicated_server
from press.press.doctype.site_activity.site_activity import log_site_activity
from press.press.doctype.site_analytics.site_analytics import create_site_analytics
from press.press.doctype.site_plan.site_plan import UNLIMITED_PLANS, get_plan_config
@@ -264,6 +267,7 @@ class Site(Document, TagHelpers):
"allow_physical_backup_by_user",
"site_usage_exceeded",
"is_monitoring_disabled",
+ "is_dedicated_server",
"reason_for_disabling_monitoring",
"creation_failed",
"fatal_site_update",
@@ -378,6 +382,13 @@ def get_doc(self, doc):
doc.server_provider = server.provider
doc.inbound_ip = self.inbound_ip
doc.is_dedicated_server = is_dedicated_server(self.server)
+
+ if doc.is_dedicated_server:
+ doc.next_allowed_dedicated_product_warranty_change_date = (
+ get_next_allowed_dedicated_product_warranty_change_date(self.name)
+ )
+ doc.dedicated_server_warranty_limit = get_available_warranty_quota_for_server(self.server)
+
doc.suspension_reason = (
frappe.db.get_value("Site Activity", {"site": self.name, "action": "Suspend Site"}, "reason")
if self.status == "Suspended"
@@ -2660,10 +2671,10 @@ def can_change_plan(self, ignore_card_setup):
# TODO: rename to change_plan and remove the need for ignore_card_setup param
@dashboard_whitelist()
- def set_plan(self, plan):
+ def set_plan(self, plan: None | str = None):
from press.api.site import validate_plan
- validate_plan(self.server, plan)
+ validate_plan(self.server, self.name, plan)
self.change_plan(plan)
def change_plan(self, plan, ignore_card_setup=False):
@@ -3531,6 +3542,13 @@ def get_actions(self):
"button_label": "Clear",
"doc_method": "clear_site_cache",
},
+ {
+ "action": "Manage Product Warranty",
+ "description": "Enable or disable warranty for this site",
+ "button_label": "Manage",
+ "doc_method": "dummy",
+ "condition": is_dedicated_server(self.server),
+ },
{
"action": "Deactivate site",
"description": "Deactivating will put the site in maintenance mode and make it inaccessible",
@@ -3538,6 +3556,14 @@ def get_actions(self):
"condition": self.status == "Active",
"doc_method": "deactivate",
},
+ {
+ "action": "Configure compute allocation",
+ "description": "Adjust compute power to be allotted to this site",
+ "button_label": "Manage",
+ "doc_method": "dummy",
+ "condition": is_dedicated_server(self.server),
+ "group": "Dangerous Actions",
+ },
{
"action": "Restore with files",
"description": "Restore with database, public and private files",
diff --git a/press/press/doctype/site/site_plan_utils.py b/press/press/doctype/site/site_plan_utils.py
new file mode 100644
index 00000000000..d9a3483c54a
--- /dev/null
+++ b/press/press/doctype/site/site_plan_utils.py
@@ -0,0 +1,107 @@
+# Copyright (c) 2024, Frappe and contributors
+# For license information, please see license.txt
+
+from datetime import datetime, timedelta
+
+import frappe
+from frappe.query_builder import DocType
+from frappe.query_builder.functions import Count
+
+
+def get_server_site_warranty_count(server: str | None = None, site: str | None = None):
+ if not server and not site:
+ frappe.throw("One of `site` or `server` is required", frappe.ValidationError)
+
+ if site:
+ server = frappe.get_value("Site", site, "server")
+
+ Site = frappe.qb.DocType("Site")
+ SitePlan = frappe.qb.DocType("Site Plan")
+
+ query = (
+ frappe.qb.from_(Site)
+ .left_join(SitePlan)
+ .on(Site.plan == SitePlan.name)
+ .select(Count(Site.name).as_("supported_sites"))
+ .where(
+ (SitePlan.support_included == 1) & (SitePlan.dedicated_server_plan == 1) & (Site.server == server)
+ )
+ )
+
+ return query.run(as_dict=True)[0]["supported_sites"]
+
+
+def get_server_site_warranty_quota(server: str | None = None, site: str | None = None):
+ if not server and not site:
+ frappe.throw("One of `site` or `server` is required", frappe.ValidationError)
+
+ if site:
+ server = frappe.get_value("Site", site, "server")
+
+ return frappe.get_value("Server", server, "site_warranty_quota")
+
+
+def get_available_warranty_quota_for_server(server: str | None) -> dict:
+ consumed = get_server_site_warranty_count(server)
+ total = get_server_site_warranty_quota(server)
+
+ return {
+ "consumed": int(consumed),
+ "total": int(total),
+ "available": total - consumed,
+ }
+
+
+def is_product_warranty_enabled_for_plan_(site_plan: str):
+ return frappe.get_value("Site Plan", site_plan, "support_included")
+
+
+def get_next_allowed_dedicated_product_warranty_change_date(site: str):
+ server = frappe.get_value("Site", site, "server")
+ COOLDOWN = frappe.get_value("Server", server, "site_warranty_change_cooldown")
+
+ if not COOLDOWN:
+ return datetime.now()
+
+ SitePlanChange = DocType("Site Plan Change")
+ FromPlan = DocType("Site Plan").as_("from_plan")
+ ToPlan = DocType("Site Plan").as_("to_plan")
+
+ query = (
+ frappe.qb.from_(SitePlanChange)
+ .left_join(FromPlan)
+ .on(FromPlan.name == SitePlanChange.from_plan)
+ .left_join(ToPlan)
+ .on(ToPlan.name == SitePlanChange.to_plan)
+ .select(
+ SitePlanChange.name,
+ SitePlanChange.timestamp,
+ FromPlan.support_included.as_("from_support_included"),
+ ToPlan.support_included.as_("to_support_included"),
+ )
+ .where(
+ (SitePlanChange.site == site)
+ & (SitePlanChange.timestamp >= datetime.now() - timedelta(days=COOLDOWN))
+ # both must be dedicated server site plans
+ & (FromPlan.dedicated_server_plan == 1)
+ & (ToPlan.dedicated_server_plan == 1)
+ # support_included changed
+ & (FromPlan.support_included != ToPlan.support_included)
+ )
+ .orderby(SitePlanChange.timestamp, order=frappe.qb.desc)
+ .limit(1)
+ )
+
+ warranty_changes = query.run(as_dict=True)
+
+ if not warranty_changes:
+ return datetime.now()
+
+ return warranty_changes[0]["timestamp"] + timedelta(days=COOLDOWN)
+
+
+def attach_warranty_info_to_dedicated_servers(servers: list[dict]) -> list[dict]:
+ for server in servers:
+ if not server.get("public", True):
+ server["product_warranty"] = get_available_warranty_quota_for_server(server.get("name"))
+ return servers