Skip to content

Commit

Permalink
Merge branch 'master' into mayday
Browse files Browse the repository at this point in the history
  • Loading branch information
arunmathaisk authored Jan 6, 2025
2 parents 1a245cb + e49c4a9 commit 2a75568
Show file tree
Hide file tree
Showing 20 changed files with 567 additions and 198 deletions.
588 changes: 483 additions & 105 deletions .cspell.json

Large diffs are not rendered by default.

33 changes: 15 additions & 18 deletions press/api/github.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe and contributors
# For license information, please see license.txt

from __future__ import annotations

import re
from base64 import b64decode
from datetime import datetime, timedelta
Expand All @@ -15,7 +16,6 @@
from press.utils import get_current_team, log_error

if TYPE_CHECKING:
from typing import Optional

from press.press.doctype.github_webhook_log.github_webhook_log import GitHubWebhookLog

Expand All @@ -39,17 +39,17 @@ def hook(*args, **kwargs):
try:
doc.insert()
frappe.db.commit()
except Exception:
except Exception as e:
frappe.set_user(user)
log_error("GitHub Webhook Insert Error", args=args, kwargs=kwargs)
raise Exception
raise Exception from e

try:
doc.handle_events()
except Exception:
except Exception as e:
frappe.set_user(user)
log_error("GitHub Webhook Error", doc=doc)
raise Exception
raise Exception from e


def get_jwt_token():
Expand All @@ -58,11 +58,10 @@ def get_jwt_token():
now = datetime.now()
expiry = now + timedelta(minutes=9)
payload = {"iat": int(now.timestamp()), "exp": int(expiry.timestamp()), "iss": app_id}
token = jwt.encode(payload, key.encode(), algorithm="RS256")
return token
return jwt.encode(payload, key.encode(), algorithm="RS256")


def get_access_token(installation_id: "Optional[str]" = None):
def get_access_token(installation_id: str | None = None):
if not installation_id:
return frappe.db.get_value(
"Press Settings",
Expand Down Expand Up @@ -100,12 +99,11 @@ def options():
token = frappe.db.get_value("Team", team, "github_access_token")
public_link = frappe.db.get_single_value("Press Settings", "github_app_public_link")

options = {
return {
"authorized": bool(token),
"installation_url": f"{public_link}/installations/new",
"installations": installations(token) if token else [],
}
return options


def installations(token):
Expand All @@ -128,7 +126,7 @@ def installations(token):
}
)
else:
frappe.throw(data.get("message") or "An error occured")
frappe.throw(data.get("message") or "An error Occurred")

return installations

Expand Down Expand Up @@ -174,9 +172,7 @@ def repository(owner, name, installation=None):
headers = {
"Authorization": f"token {token}",
}
repo = requests.get(
f"https://api.github.com/repos/{owner}/{name}", headers=headers
).json()
repo = requests.get(f"https://api.github.com/repos/{owner}/{name}", headers=headers).json()

current_page, is_last_page = 1, False
branches = []
Expand Down Expand Up @@ -261,11 +257,11 @@ def branches(owner, name, installation=None):

if response.ok:
return response.json()
else:
frappe.throw("Error fetching branch list from GitHub: " + response.text)
frappe.throw("Error fetching branch list from GitHub: " + response.text)
return None


def get_auth_headers(installation_id: "Optional[str]" = None) -> "dict[str, str]":
def get_auth_headers(installation_id: str | None = None) -> "dict[str, str]":
if token := get_access_token(installation_id):
return {"Authorization": f"token {token}"}
return {}
Expand Down Expand Up @@ -311,6 +307,7 @@ def _get_app_name_and_title_from_hooks(
break

frappe.throw(f"Not a valid Frappe App! {reason_for_invalidation}")
return None


def _generate_files_tree(files):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def validate_duplicate(self):
},
):
frappe.throw(
"AWS Savings Plan Recommendation witht this timestamp already exists",
"AWS Savings Plan Recommendation without this timestamp already exists",
frappe.DuplicateEntryError,
)

Expand Down
6 changes: 3 additions & 3 deletions press/press/doctype/cluster/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,9 @@ def get_oci_config(self):
return config

def set_oci_availability_zone(self):
identiy_client = IdentityClient(self.get_oci_config())
availibility_domain = identiy_client.list_availability_domains(self.oci_tenancy).data[0].name
self.availability_zone = availibility_domain
identity_client = IdentityClient(self.get_oci_config())
availability_domain = identity_client.list_availability_domains(self.oci_tenancy).data[0].name
self.availability_zone = availability_domain

def provision_on_oci(self):
vcn_client = VirtualNetworkClient(self.get_oci_config())
Expand Down
2 changes: 1 addition & 1 deletion press/press/doctype/press_settings/press_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ def get_github_app_manifest(self):

@property
def boto3_offsite_backup_session(self) -> Session:
"""Get new preconfigured boto3 session for offisite backup provider."""
"""Get new preconfigured boto3 session for offsite backup provider."""
return Session(
aws_access_key_id=self.offsite_backups_access_key_id,
aws_secret_access_key=self.get_password(
Expand Down
64 changes: 21 additions & 43 deletions press/press/doctype/self_hosted_server/self_hosted_server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) 2023, Frappe and contributors
# For license information, please see license.txt

from __future__ import annotations

import json

Expand Down Expand Up @@ -270,7 +271,7 @@ def create_new_rg(self):
try:
for app in task_result:
branches.append(app["branch"])
if not frappe.db.exists("App Source", {"app": app["app"], "branch": app["branch"]}):
if not frappe.db.exists("App Source", {"app": app["app"], "branch": app["branch"]}): # noqa: SIM102
if not frappe.db.exists("App", {"_newname": app["app"]}):
app_doc = frappe.get_doc(
{
Expand Down Expand Up @@ -324,10 +325,9 @@ def set_database_plan(self):
if self.database_plan:
return

if not self.different_database_server:
if not frappe.db.exists("Server Plan", "Unlimited"):
self._create_server_plan("Unlimited")
self.database_plan = "Unlimited"
if not self.different_database_server and not frappe.db.exists("Server Plan", "Unlimited"):
self._create_server_plan("Unlimited")
self.database_plan = "Unlimited"

def _create_server_plan(self, plan_name):
plan = frappe.new_doc("Server Plan")
Expand Down Expand Up @@ -359,7 +359,7 @@ def create_database_server(self):
"mariadb_root_password": self.get_password("mariadb_root_password"),
"cluster": self.cluster,
"agent_password": self.get_password("agent_password"),
"is_server_setup": False if self.new_server else True,
"is_server_setup": not self.new_server,
"plan": self.database_plan,
},
).insert()
Expand All @@ -375,7 +375,7 @@ def create_database_server(self):

frappe.db.commit()

frappe.msgprint(f"Databse server record {db_server.name} created")
frappe.msgprint(f"Database server record {db_server.name} created")
except Exception:
frappe.throw("Adding Server to Database Server Doctype failed")
self.status = "Broken"
Expand All @@ -393,10 +393,7 @@ def append_site_configs(self, play_name):
"output",
)
task_result = json.loads(
ansible_task_op.replace("'", '"')
.replace('"{', "{")
.replace('}"', "}")
.replace("\\n", "")
ansible_task_op.replace("'", '"').replace('"{', "{").replace('}"', "}").replace("\\n", "")
)
self.status = "Pending"
for site in task_result:
Expand Down Expand Up @@ -502,9 +499,7 @@ def create_new_sites(self):

@frappe.whitelist()
def restore_files(self):
frappe.enqueue_doc(
self.doctype, self.name, "_restore_files", queue="long", timeout=2400
)
frappe.enqueue_doc(self.doctype, self.name, "_restore_files", queue="long", timeout=2400)

def _restore_files(self):
"""
Expand Down Expand Up @@ -617,9 +612,7 @@ def setup_nginx(self, server):
port=server.ssh_port or "22",
variables={
"domain": self.name,
"press_domain": frappe.db.get_single_value(
"Press Settings", "domain"
), # for ssl renewal
"press_domain": frappe.db.get_single_value("Press Settings", "domain"), # for ssl renewal
},
)
play = ansible.run()
Expand All @@ -636,13 +629,9 @@ def update_tls(self):
)

try:
cert = frappe.get_last_doc(
"TLS Certificate", {"domain": self.server, "status": "Active"}
)
cert = frappe.get_last_doc("TLS Certificate", {"domain": self.server, "status": "Active"})
except frappe.DoesNotExistError:
cert = frappe.get_last_doc(
"TLS Certificate", {"domain": self.name, "status": "Active"}
)
cert = frappe.get_last_doc("TLS Certificate", {"domain": self.name, "status": "Active"})

update_server_tls_certifcate(self, cert)

Expand Down Expand Up @@ -679,20 +668,14 @@ def can_charge_for_subscription(self, subscription=None):

def _get_play_id(self):
try:
play_id = frappe.get_last_doc(
"Ansible Play", {"server": self.server, "play": "Ping Server"}
).name
play_id = frappe.get_last_doc("Ansible Play", {"server": self.server, "play": "Ping Server"}).name
except frappe.DoesNotExistError:
play_id = frappe.get_last_doc(
"Ansible Play", {"server": self.name, "play": "Ping Server"}
).name
play_id = frappe.get_last_doc("Ansible Play", {"server": self.name, "play": "Ping Server"}).name

return play_id

def _get_play(self, play_id):
play = frappe.get_doc(
"Ansible Task", {"status": "Success", "play": play_id, "task": "Gather Facts"}
)
play = frappe.get_doc("Ansible Task", {"status": "Success", "play": play_id, "task": "Gather Facts"})

return json.loads(play.result)

Expand Down Expand Up @@ -736,9 +719,7 @@ def validate_private_ip(self, play_id=None, server_type="app"):
public_ip = self.mariadb_ip

if private_ip not in all_ipv4_addresses:
frappe.throw(
f"Private IP {private_ip} is not associated with server having IP {public_ip} "
)
frappe.throw(f"Private IP {private_ip} is not associated with server having IP {public_ip} ")

@frappe.whitelist()
def fetch_private_ip(self, play_id=None, server_type="app"):
Expand Down Expand Up @@ -808,12 +789,10 @@ def check_minimum_specs(self):
"""

if round(int(self.ram), -3) < 4000: # Round to nearest thousand
frappe.throw(
f"Minimum RAM requirement not met, Minumum is 4GB and available is {self.ram} MB"
)
frappe.throw(f"Minimum RAM requirement not met, Minimum is 4GB and available is {self.ram} MB")
if int(self.vcpus) < 2:
frappe.throw(
f"Minimum vCPU requirement not met, Minumum is 2 Cores and available is {self.vcpus}"
f"Minimum vCPU requirement not met, Minimum is 2 Cores and available is {self.vcpus}"
)

self._validate_disk()
Expand All @@ -827,12 +806,11 @@ def _validate_disk(self):
if disk_storage_unit.upper() == "TB":
return True

if (
disk_storage_unit.upper() in ["GB", "MB"] and round(int(float(disk_size)), -1) < 40
):
if disk_storage_unit.upper() in ["GB", "MB"] and round(int(float(disk_size)), -1) < 40:
frappe.throw(
f"Minimum Storage requirement not met, Minumum is 50GB and available is {self.total_storage}"
f"Minimum Storage requirement not met, Minimum is 50GB and available is {self.total_storage}"
)
return None


def fetch_private_ip_based_on_vendor(play_result: dict):
Expand Down
9 changes: 7 additions & 2 deletions press/press/doctype/site/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
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 get_plan_config
from press.press.doctype.site_plan.site_plan import UNLIMITED_PLANS, get_plan_config
from press.press.report.mariadb_slow_queries.mariadb_slow_queries import (
get_doctype_name,
)
Expand Down Expand Up @@ -2124,7 +2124,12 @@ def get_plan_name(self, plan=None):
return plan

def get_plan_config(self, plan=None):
return get_plan_config(self.get_plan_name(plan))
plan = self.get_plan_name(plan)
config = get_plan_config(plan)
if plan in UNLIMITED_PLANS:
# PERF: do not enable usage tracking on unlimited sites.
config.pop("rate_limit", None)
return config

def set_latest_bench(self):
from pypika.terms import PseudoColumn
Expand Down
2 changes: 2 additions & 0 deletions press/press/doctype/site_plan/site_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from press.press.doctype.site_plan.plan import Plan

UNLIMITED_PLANS = ["Unlimited", "Unlimited - Supported"]


class SitePlan(Plan):
# begin: auto-generated types
Expand Down
2 changes: 1 addition & 1 deletion press/press/doctype/team/team.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ def get_partnership_start_date(self):
def create_new_invoice(self):
"""
After enabling partner privileges, new invoice should be created
to track the partner achivements
to track the partner achievements
"""
# check if any active user with an invoice
if not frappe.get_all("Invoice", {"team": self.name, "docstatus": ("<", 2)}, pluck="name"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ frappe.query_reports['MariaDB Process List'] = {
{
fieldtype: 'Int',
default: 120,
label: __('Kill Proceeses Running Longer Than (Seconds)'),
label: __('Kill Processes Running Longer Than (Seconds)'),
fieldname: 'kill_threshold',
},
],
Expand Down
2 changes: 1 addition & 1 deletion press/saas/api/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def get_plans():
filtered_plans.append(plan)

"""
plans `site_api.get_site_plans()` doesn't include trial plan, as we don't have any roles specfied for trial plan
plans `site_api.get_site_plans()` doesn't include trial plan, as we don't have any roles specified for trial plan
because from backend only we set the trial plan, end-user can't subscribe to trial plan directly
If the site is on a trial plan, add it to the starting of the list
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def get_setup_wizard_payload(self):
return frappe._dict(_locals.get("payload", {}))

except Exception as e:
frappe.log_error(title="Product Trial Reqeust Setup Wizard Payload Generation Error")
frappe.log_error(title="Product Trial Request Setup Wizard Payload Generation Error")
frappe.throw(f"Failed to generate payload for Setup Wizard: {e}")

def get_user_login_password_from_signup_details(self) -> str | None:
Expand Down
4 changes: 2 additions & 2 deletions press/templates/saas/macros.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ <h2 class="font-size-base mt-0">Verification Email Sent!</h2>
</div>
<h2 class="font-size-base mb-2">Payment Request Received</h2>
</div>
<span>Thank you for your payment request. We will send you a confirmation email shortly. In the meantime if you have any queries please reach us at
<span>Thank you for your payment request. We will send you a confirmation email shortly. In the meantime if you have any queries please reach us at
our <a href="https://frappecloud.com/support" class="text-blue-500 hover:text-blue-500">support page</a>.</span>
</div>
{% endmacro %}
Expand Down Expand Up @@ -163,6 +163,6 @@ <h2 class="font-size-base mb-2">Something Went Wrong</h2>

{% macro load_subs() %}
<div id="loading" class="mx-auto my-auto">
<span class="spinner-border spinner-border-sm mr-3" role="status"></span><span>Loading Susbcriptions </span>
<span class="spinner-border spinner-border-sm mr-3" role="status"></span><span>Loading Subscriptions </span>
</div>
{% endmacro %}
Loading

0 comments on commit 2a75568

Please sign in to comment.