sophos-central-mcp-server 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/config.d.ts +1 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +2 -2
- package/dist/config/config.js.map +1 -1
- package/dist/tools/partner.d.ts.map +1 -1
- package/dist/tools/partner.js +62 -1
- package/dist/tools/partner.js.map +1 -1
- package/generate_health_report.py +499 -0
- package/package.json +1 -1
package/dist/config/config.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface SophosConfig {
|
|
|
12
12
|
export declare function loadConfig(): SophosConfig;
|
|
13
13
|
export declare const SOPHOS_AUTH_URL = "https://id.sophos.com/api/v2/oauth2/token";
|
|
14
14
|
export declare const SOPHOS_GLOBAL_API = "https://api.central.sophos.com";
|
|
15
|
-
export declare const CHARACTER_LIMIT
|
|
15
|
+
export declare const CHARACTER_LIMIT: number;
|
|
16
16
|
export declare const DEFAULT_PAGE_SIZE = 50;
|
|
17
17
|
export declare const MAX_PAGE_SIZE = 100;
|
|
18
18
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AAED,wBAAgB,UAAU,IAAI,YAAY,CAwBzC;AAGD,eAAO,MAAM,eAAe,8CAA8C,CAAC;AAC3E,eAAO,MAAM,iBAAiB,mCAAmC,CAAC;AAGlE,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CAC7B;AAED,wBAAgB,UAAU,IAAI,YAAY,CAwBzC;AAGD,eAAO,MAAM,eAAe,8CAA8C,CAAC;AAC3E,eAAO,MAAM,iBAAiB,mCAAmC,CAAC;AAGlE,eAAO,MAAM,eAAe,QAG3B,CAAC;AACF,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,aAAa,MAAM,CAAC"}
|
package/dist/config/config.js
CHANGED
|
@@ -23,8 +23,8 @@ export function loadConfig() {
|
|
|
23
23
|
// Sophos Central global API endpoints
|
|
24
24
|
export const SOPHOS_AUTH_URL = "https://id.sophos.com/api/v2/oauth2/token";
|
|
25
25
|
export const SOPHOS_GLOBAL_API = "https://api.central.sophos.com";
|
|
26
|
-
// Response size limits
|
|
27
|
-
export const CHARACTER_LIMIT =
|
|
26
|
+
// Response size limits (CHARACTER_LIMIT configurable via env var)
|
|
27
|
+
export const CHARACTER_LIMIT = Math.max(10000, parseInt(process.env.CHARACTER_LIMIT || "50000", 10) || 50000);
|
|
28
28
|
export const DEFAULT_PAGE_SIZE = 50;
|
|
29
29
|
export const MAX_PAGE_SIZE = 100;
|
|
30
30
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAEtD,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,gGAAgG,CACjG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,uBAAuB,OAAO,CAAC,GAAG,CAAC,IAAI,4CAA4C,CACpF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,SAAS;QACnD,IAAI,EAAE,OAAO;QACb,SAAS,EAAG,OAAO,CAAC,GAAG,CAAC,SAA8B,IAAI,MAAM;KACjE,CAAC;AACJ,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,MAAM,eAAe,GAAG,2CAA2C,CAAC;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,gCAAgC,CAAC;AAElE,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC9C,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAEtD,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,gGAAgG,CACjG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,uBAAuB,OAAO,CAAC,GAAG,CAAC,IAAI,4CAA4C,CACpF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,SAAS;QACnD,IAAI,EAAE,OAAO;QACb,SAAS,EAAG,OAAO,CAAC,GAAG,CAAC,SAA8B,IAAI,MAAM;KACjE,CAAC;AACJ,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,MAAM,eAAe,GAAG,2CAA2C,CAAC;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,gCAAgC,CAAC;AAElE,kEAAkE;AAClE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CACrC,KAAK,EACL,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,EAAE,EAAE,CAAC,IAAI,KAAK,CAC9D,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,YAAY,EACpB,cAAc,EAAE,cAAc,GAC7B,IAAI,
|
|
1
|
+
{"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,YAAY,EACpB,cAAc,EAAE,cAAc,GAC7B,IAAI,CAk6BN"}
|
package/dist/tools/partner.js
CHANGED
|
@@ -580,10 +580,15 @@ Monthly cost per line item is calculated as: billableQuantity * unitPrice.
|
|
|
580
580
|
The netPrice field in raw billing data is the total order line value shared across
|
|
581
581
|
all customers on that line — NOT the per-customer cost.
|
|
582
582
|
|
|
583
|
+
Use compact=true to get a smaller response with coverage flags (hasMDR, mdrTier,
|
|
584
|
+
hasFirewall, firewallModels) instead of full product arrays. This fits all customers
|
|
585
|
+
in a single response without hitting the character limit.
|
|
586
|
+
|
|
583
587
|
Args:
|
|
584
588
|
- year (number): The year (e.g. 2026).
|
|
585
589
|
- month (number): The month (1-12).
|
|
586
590
|
- limit (number, optional): Return only the top N customers (default: all).
|
|
591
|
+
- compact (boolean, optional): Return coverage flags instead of full product arrays (default: false).
|
|
587
592
|
|
|
588
593
|
Returns:
|
|
589
594
|
Ranked list of customers with monthly cost, product breakdown, and estate totals.`,
|
|
@@ -596,6 +601,10 @@ Returns:
|
|
|
596
601
|
.min(1)
|
|
597
602
|
.optional()
|
|
598
603
|
.describe("Return only the top N customers (default: all)"),
|
|
604
|
+
compact: z
|
|
605
|
+
.boolean()
|
|
606
|
+
.optional()
|
|
607
|
+
.describe("Return coverage flags instead of full product arrays (default: false)"),
|
|
599
608
|
},
|
|
600
609
|
annotations: {
|
|
601
610
|
readOnlyHint: true,
|
|
@@ -603,7 +612,7 @@ Returns:
|
|
|
603
612
|
idempotentHint: true,
|
|
604
613
|
openWorldHint: true,
|
|
605
614
|
},
|
|
606
|
-
}, withErrorHandling(async ({ year, month, limit }) => {
|
|
615
|
+
}, withErrorHandling(async ({ year, month, limit, compact }) => {
|
|
607
616
|
// Auto-paginate to collect ALL billing line items
|
|
608
617
|
const allItems = [];
|
|
609
618
|
let cursor;
|
|
@@ -643,6 +652,10 @@ Returns:
|
|
|
643
652
|
totalUsers: 0,
|
|
644
653
|
totalServers: 0,
|
|
645
654
|
totalDevices: 0,
|
|
655
|
+
hasMDR: false,
|
|
656
|
+
mdrTier: null,
|
|
657
|
+
hasFirewall: false,
|
|
658
|
+
firewallModels: new Set(),
|
|
646
659
|
});
|
|
647
660
|
}
|
|
648
661
|
const cust = customers.get(name);
|
|
@@ -662,6 +675,26 @@ Returns:
|
|
|
662
675
|
cust.totalServers += quantity;
|
|
663
676
|
else if (productGroup === "Device")
|
|
664
677
|
cust.totalDevices += quantity;
|
|
678
|
+
// Track MDR coverage
|
|
679
|
+
const descLower = productDesc.toLowerCase();
|
|
680
|
+
if (descLower.includes("mdr complete")) {
|
|
681
|
+
cust.hasMDR = true;
|
|
682
|
+
cust.mdrTier = "Complete";
|
|
683
|
+
}
|
|
684
|
+
else if (descLower.includes("mdr essentials") && cust.mdrTier !== "Complete") {
|
|
685
|
+
cust.hasMDR = true;
|
|
686
|
+
cust.mdrTier = "Essentials";
|
|
687
|
+
}
|
|
688
|
+
// Track firewall coverage
|
|
689
|
+
if (productGroup === "Device" && (descLower.includes("xgs") || descLower.includes("xg ") ||
|
|
690
|
+
descLower.includes("sf sw") || descLower.includes("sf virtual") ||
|
|
691
|
+
descLower.includes("xstream protection") || descLower.includes("standard protection"))) {
|
|
692
|
+
cust.hasFirewall = true;
|
|
693
|
+
// Extract model from description
|
|
694
|
+
const modelMatch = productDesc.match(/^(XGS \d+|XG \d+|SF SW\/Virtual[^-]*)/i);
|
|
695
|
+
if (modelMatch)
|
|
696
|
+
cust.firewallModels.add(modelMatch[1].trim());
|
|
697
|
+
}
|
|
665
698
|
}
|
|
666
699
|
// Sort by monthly total descending
|
|
667
700
|
const sorted = [...customers.values()]
|
|
@@ -670,6 +703,30 @@ Returns:
|
|
|
670
703
|
// Build summary
|
|
671
704
|
const grandTotal = [...customers.values()].reduce((sum, c) => sum + c.monthlyTotal, 0);
|
|
672
705
|
const totalCustomers = customers.size;
|
|
706
|
+
if (compact) {
|
|
707
|
+
const compactSummary = sorted.map((c, i) => ({
|
|
708
|
+
rank: i + 1,
|
|
709
|
+
customer: c.name,
|
|
710
|
+
accountId: c.accountId,
|
|
711
|
+
monthlyAUD: Math.round(c.monthlyTotal * 100) / 100,
|
|
712
|
+
users: c.totalUsers,
|
|
713
|
+
servers: c.totalServers,
|
|
714
|
+
devices: c.totalDevices,
|
|
715
|
+
hasMDR: c.hasMDR,
|
|
716
|
+
mdrTier: c.mdrTier,
|
|
717
|
+
hasFirewall: c.hasFirewall,
|
|
718
|
+
firewallModels: [...c.firewallModels],
|
|
719
|
+
}));
|
|
720
|
+
return jsonResult({
|
|
721
|
+
period: `${year}-${String(month).padStart(2, "0")}`,
|
|
722
|
+
currency: "AUD",
|
|
723
|
+
totalCustomers,
|
|
724
|
+
totalLineItems: allItems.length,
|
|
725
|
+
grandTotalMonthlyAUD: Math.round(grandTotal * 100) / 100,
|
|
726
|
+
returnedCustomers: compactSummary.length,
|
|
727
|
+
customers: compactSummary,
|
|
728
|
+
});
|
|
729
|
+
}
|
|
673
730
|
const summary = sorted.map((c, i) => ({
|
|
674
731
|
rank: i + 1,
|
|
675
732
|
customer: c.name,
|
|
@@ -678,6 +735,10 @@ Returns:
|
|
|
678
735
|
users: c.totalUsers,
|
|
679
736
|
servers: c.totalServers,
|
|
680
737
|
devices: c.totalDevices,
|
|
738
|
+
hasMDR: c.hasMDR,
|
|
739
|
+
mdrTier: c.mdrTier,
|
|
740
|
+
hasFirewall: c.hasFirewall,
|
|
741
|
+
firewallModels: [...c.firewallModels],
|
|
681
742
|
products: [...c.products.values()].map((p) => ({
|
|
682
743
|
product: p.description,
|
|
683
744
|
group: p.productGroup,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner.js","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"partner.js","sourceRoot":"","sources":["../../src/tools/partner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
"""Generate Rodin Business Solutions - Sophos Central Estate Health Report (PDF)."""
|
|
2
|
+
import sys, os
|
|
3
|
+
sys.stdout = open(sys.stdout.fileno(), mode='w', encoding='utf-8', buffering=1)
|
|
4
|
+
|
|
5
|
+
from fpdf import FPDF
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
# -- Sophos brand colours --
|
|
9
|
+
SOPHOS_BLUE = (0, 53, 128)
|
|
10
|
+
SOPHOS_DARK = (34, 34, 34)
|
|
11
|
+
SOPHOS_RED = (200, 30, 30)
|
|
12
|
+
SOPHOS_AMBER = (210, 140, 0)
|
|
13
|
+
SOPHOS_GREEN = (40, 140, 60)
|
|
14
|
+
SOPHOS_GREY = (100, 100, 100)
|
|
15
|
+
WHITE = (255, 255, 255)
|
|
16
|
+
LIGHT_BG = (245, 247, 250)
|
|
17
|
+
ROW_ALT = (232, 238, 248)
|
|
18
|
+
|
|
19
|
+
PAGE_W = 190 # usable width (A4 210mm - 10mm margins each side)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PDF(FPDF):
|
|
23
|
+
"""Custom PDF with Sophos-branded header/footer."""
|
|
24
|
+
|
|
25
|
+
_skip_header = False # flag for cover page
|
|
26
|
+
|
|
27
|
+
def header(self):
|
|
28
|
+
if self._skip_header:
|
|
29
|
+
return
|
|
30
|
+
self.set_font("Helvetica", "B", 8)
|
|
31
|
+
self.set_text_color(*SOPHOS_GREY)
|
|
32
|
+
self.cell(0, 5, "Rodin Business Solutions | Sophos Central Estate Health Report | March 2026", align="L")
|
|
33
|
+
self.ln(3)
|
|
34
|
+
self.set_draw_color(*SOPHOS_BLUE)
|
|
35
|
+
self.set_line_width(0.5)
|
|
36
|
+
self.line(10, self.get_y(), 200, self.get_y())
|
|
37
|
+
self.ln(5)
|
|
38
|
+
|
|
39
|
+
def footer(self):
|
|
40
|
+
self.set_y(-15)
|
|
41
|
+
self.set_font("Helvetica", "", 8)
|
|
42
|
+
self.set_text_color(*SOPHOS_GREY)
|
|
43
|
+
self.cell(0, 10, f"Page {self.page_no()}/{{nb}}", align="C")
|
|
44
|
+
|
|
45
|
+
# -- Helpers ----------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
def section_title(self, title, colour=SOPHOS_BLUE):
|
|
48
|
+
self.set_font("Helvetica", "B", 14)
|
|
49
|
+
self.set_text_color(*colour)
|
|
50
|
+
self.cell(0, 10, title)
|
|
51
|
+
self.ln(9)
|
|
52
|
+
self.set_text_color(*SOPHOS_DARK)
|
|
53
|
+
|
|
54
|
+
def sub_title(self, title, colour=SOPHOS_DARK):
|
|
55
|
+
self.set_font("Helvetica", "B", 11)
|
|
56
|
+
self.set_text_color(*colour)
|
|
57
|
+
self.cell(0, 8, title)
|
|
58
|
+
self.ln(7)
|
|
59
|
+
self.set_text_color(*SOPHOS_DARK)
|
|
60
|
+
|
|
61
|
+
def body_text(self, text, size=10):
|
|
62
|
+
self.set_font("Helvetica", "", size)
|
|
63
|
+
self.set_text_color(*SOPHOS_DARK)
|
|
64
|
+
self.multi_cell(0, 5.5, text)
|
|
65
|
+
self.ln(2)
|
|
66
|
+
|
|
67
|
+
def table_header(self, cols):
|
|
68
|
+
"""Draw a header row. cols = [(label, width), ...]"""
|
|
69
|
+
self.set_font("Helvetica", "B", 8)
|
|
70
|
+
self.set_fill_color(*SOPHOS_BLUE)
|
|
71
|
+
self.set_text_color(*WHITE)
|
|
72
|
+
for label, w in cols:
|
|
73
|
+
self.cell(w, 7, f" {label}", border=0, fill=True, align="L")
|
|
74
|
+
self.ln()
|
|
75
|
+
self.set_text_color(*SOPHOS_DARK)
|
|
76
|
+
|
|
77
|
+
def _row_height(self, cols, font_size=8):
|
|
78
|
+
"""Calculate the row height needed for the tallest multi-cell."""
|
|
79
|
+
self.set_font("Helvetica", "", font_size)
|
|
80
|
+
max_lines = 1
|
|
81
|
+
for val, w, _align in cols:
|
|
82
|
+
text = str(val)
|
|
83
|
+
# Estimate number of lines: char width ~2.1mm at size 8
|
|
84
|
+
char_w = font_size * 0.23
|
|
85
|
+
chars_per_line = max(int(w / char_w), 1)
|
|
86
|
+
lines = 1
|
|
87
|
+
for paragraph in text.split("\n"):
|
|
88
|
+
lines += max(0, (len(paragraph) - 1) // chars_per_line)
|
|
89
|
+
if len(paragraph) > 0:
|
|
90
|
+
pass
|
|
91
|
+
lines += 0 # already counted
|
|
92
|
+
# Simpler: use fpdf's internal string width
|
|
93
|
+
str_w = self.get_string_width(text)
|
|
94
|
+
est_lines = max(1, int(str_w / (w - 2)) + 1)
|
|
95
|
+
max_lines = max(max_lines, est_lines)
|
|
96
|
+
return max(6.5, max_lines * 4.2)
|
|
97
|
+
|
|
98
|
+
def table_row(self, cols, row_idx=0, font_size=8):
|
|
99
|
+
"""Draw a data row with alternating colours. cols = [(val, width, align), ...]"""
|
|
100
|
+
self.set_font("Helvetica", "", font_size)
|
|
101
|
+
if row_idx % 2 == 1:
|
|
102
|
+
self.set_fill_color(*ROW_ALT)
|
|
103
|
+
else:
|
|
104
|
+
self.set_fill_color(*WHITE)
|
|
105
|
+
|
|
106
|
+
# Check if we need a page break (leave room for row + footer)
|
|
107
|
+
row_h = 6.5
|
|
108
|
+
if self.get_y() + row_h > self.h - self.b_margin - 5:
|
|
109
|
+
self.add_page()
|
|
110
|
+
|
|
111
|
+
for val, w, align in cols:
|
|
112
|
+
self.cell(w, row_h, f" {str(val)}", border=0, fill=True, align=align)
|
|
113
|
+
self.ln()
|
|
114
|
+
|
|
115
|
+
def table_row_multi(self, cols, row_idx=0, row_h=6.5, font_size=8):
|
|
116
|
+
"""Draw a row that may wrap text in the last column."""
|
|
117
|
+
self.set_font("Helvetica", "", font_size)
|
|
118
|
+
if row_idx % 2 == 1:
|
|
119
|
+
self.set_fill_color(*ROW_ALT)
|
|
120
|
+
else:
|
|
121
|
+
self.set_fill_color(*WHITE)
|
|
122
|
+
|
|
123
|
+
if self.get_y() + row_h > self.h - self.b_margin - 5:
|
|
124
|
+
self.add_page()
|
|
125
|
+
|
|
126
|
+
x_start = self.get_x()
|
|
127
|
+
y_start = self.get_y()
|
|
128
|
+
|
|
129
|
+
# Draw fixed cells
|
|
130
|
+
for val, w, align in cols[:-1]:
|
|
131
|
+
self.cell(w, row_h, f" {str(val)}", border=0, fill=True, align=align)
|
|
132
|
+
|
|
133
|
+
# Draw last cell as multi_cell for wrapping
|
|
134
|
+
last_val, last_w, last_align = cols[-1]
|
|
135
|
+
x_last = self.get_x()
|
|
136
|
+
self.multi_cell(last_w, row_h / max(1, len(str(last_val)) // 40 + 1),
|
|
137
|
+
f" {str(last_val)}", border=0, fill=True, align=last_align)
|
|
138
|
+
|
|
139
|
+
y_end = self.get_y()
|
|
140
|
+
actual_h = y_end - y_start
|
|
141
|
+
if actual_h < row_h:
|
|
142
|
+
self.set_y(y_start + row_h)
|
|
143
|
+
|
|
144
|
+
def check_space(self, needed_mm=30):
|
|
145
|
+
"""Add a page if less than needed_mm space remains."""
|
|
146
|
+
if self.get_y() + needed_mm > self.h - self.b_margin:
|
|
147
|
+
self.add_page()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# ===========================================================================
|
|
151
|
+
# BUILD THE PDF
|
|
152
|
+
# ===========================================================================
|
|
153
|
+
pdf = PDF(orientation="P", unit="mm", format="A4")
|
|
154
|
+
pdf.alias_nb_pages()
|
|
155
|
+
pdf.set_auto_page_break(auto=True, margin=20)
|
|
156
|
+
|
|
157
|
+
# ===== COVER PAGE ==========================================================
|
|
158
|
+
pdf._skip_header = True
|
|
159
|
+
pdf.add_page()
|
|
160
|
+
pdf.ln(30)
|
|
161
|
+
|
|
162
|
+
# Title block
|
|
163
|
+
pdf.set_font("Helvetica", "B", 30)
|
|
164
|
+
pdf.set_text_color(*SOPHOS_BLUE)
|
|
165
|
+
pdf.cell(0, 14, "Sophos Central", align="C")
|
|
166
|
+
pdf.ln(16)
|
|
167
|
+
pdf.set_font("Helvetica", "B", 20)
|
|
168
|
+
pdf.cell(0, 12, "Estate Health & Opportunity Report", align="C")
|
|
169
|
+
pdf.ln(18)
|
|
170
|
+
|
|
171
|
+
# Decorative line
|
|
172
|
+
pdf.set_draw_color(*SOPHOS_BLUE)
|
|
173
|
+
pdf.set_line_width(1.0)
|
|
174
|
+
pdf.line(60, pdf.get_y(), 150, pdf.get_y())
|
|
175
|
+
pdf.ln(12)
|
|
176
|
+
|
|
177
|
+
pdf.set_font("Helvetica", "", 14)
|
|
178
|
+
pdf.set_text_color(*SOPHOS_GREY)
|
|
179
|
+
pdf.cell(0, 8, "Rodin Business Solutions | March 2026", align="C")
|
|
180
|
+
pdf.ln(30)
|
|
181
|
+
|
|
182
|
+
# Summary metric boxes
|
|
183
|
+
metrics = [
|
|
184
|
+
("153", "Total Tenants"),
|
|
185
|
+
("115", "Healthy (75%)"),
|
|
186
|
+
("34", "With Gaps (22%)"),
|
|
187
|
+
("$38,923/mo", "Monthly AUD"),
|
|
188
|
+
]
|
|
189
|
+
box_w = 42
|
|
190
|
+
gap = 4
|
|
191
|
+
total_w = len(metrics) * box_w + (len(metrics) - 1) * gap
|
|
192
|
+
start_x = (210 - total_w) / 2
|
|
193
|
+
y_boxes = pdf.get_y()
|
|
194
|
+
|
|
195
|
+
for i, (val, label) in enumerate(metrics):
|
|
196
|
+
x = start_x + i * (box_w + gap)
|
|
197
|
+
pdf.set_fill_color(*LIGHT_BG)
|
|
198
|
+
pdf.set_draw_color(*SOPHOS_BLUE)
|
|
199
|
+
pdf.set_line_width(0.4)
|
|
200
|
+
pdf.rect(x, y_boxes, box_w, 26, style="FD")
|
|
201
|
+
pdf.set_xy(x, y_boxes + 4)
|
|
202
|
+
pdf.set_font("Helvetica", "B", 20)
|
|
203
|
+
pdf.set_text_color(*SOPHOS_BLUE)
|
|
204
|
+
pdf.cell(box_w, 10, val, align="C")
|
|
205
|
+
pdf.set_xy(x, y_boxes + 15)
|
|
206
|
+
pdf.set_font("Helvetica", "", 9)
|
|
207
|
+
pdf.set_text_color(*SOPHOS_GREY)
|
|
208
|
+
pdf.cell(box_w, 6, label, align="C")
|
|
209
|
+
|
|
210
|
+
pdf.set_y(y_boxes + 36)
|
|
211
|
+
|
|
212
|
+
# Executive summary
|
|
213
|
+
pdf.set_text_color(*SOPHOS_DARK)
|
|
214
|
+
pdf.section_title("Executive Summary")
|
|
215
|
+
pdf.body_text(
|
|
216
|
+
"This report provides a comprehensive health assessment of the Rodin Business Solutions "
|
|
217
|
+
"managed Sophos Central estate for March 2026. Across 153 managed tenants, 75% are fully "
|
|
218
|
+
"healthy with no configuration gaps detected. 22% have identifiable security or licensing "
|
|
219
|
+
"gaps that require remediation. The remaining tenants represent commercial upsell opportunities."
|
|
220
|
+
)
|
|
221
|
+
pdf.body_text(
|
|
222
|
+
"Key findings:\n"
|
|
223
|
+
" - 4 tenants have tamper protection completely disabled (0%) representing critical risk\n"
|
|
224
|
+
" - 1 tenant has server protection at 0% despite having enrolled servers\n"
|
|
225
|
+
" - 6 tenants have high-priority partial tamper protection gaps on servers\n"
|
|
226
|
+
" - 10 tenants have moderate gaps (92-99% TP) likely from stale devices\n"
|
|
227
|
+
" - 14 tenants have no server protection enrolled\n"
|
|
228
|
+
" - Multiple customers lack MDR or Sophos Firewall coverage (detailed in sections 5-7)"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
pdf._skip_header = False
|
|
232
|
+
|
|
233
|
+
# ===== SECTION 2: CRITICAL HEALTH GAPS ====================================
|
|
234
|
+
pdf.add_page()
|
|
235
|
+
pdf.section_title("1. Critical Health Gaps", SOPHOS_RED)
|
|
236
|
+
pdf.body_text(
|
|
237
|
+
"The following tenants have tamper protection at 0% or server protection failures. "
|
|
238
|
+
"These represent the highest security risk and must be remediated immediately. "
|
|
239
|
+
"Without tamper protection, a threat actor who gains endpoint access can disable "
|
|
240
|
+
"Sophos protection entirely."
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
critical = [
|
|
244
|
+
("Marco Polo Aged Care Services", "TP 0% computers AND servers", "Re-enable global TP immediately"),
|
|
245
|
+
("Unibuild", "TP 0% computers", "Re-enable global TP"),
|
|
246
|
+
("MasterCraft Windows and Doors", "TP 0% computers", "Re-enable global TP"),
|
|
247
|
+
("Martin Morris & Jones Sydney", "TP 0% computers", "Re-enable global TP"),
|
|
248
|
+
("WIN Sports & Entertainment Centres", "Server protection 0% (2 servers)", "Investigate enrolled servers"),
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
cols_def = [("Customer", 58), ("Issue", 58), ("Recommended Action", 74)]
|
|
252
|
+
pdf.table_header(cols_def)
|
|
253
|
+
for i, (cust, issue, action) in enumerate(critical):
|
|
254
|
+
pdf.table_row([(cust, 58, "L"), (issue, 58, "L"), (action, 74, "L")], i)
|
|
255
|
+
|
|
256
|
+
pdf.ln(8)
|
|
257
|
+
|
|
258
|
+
# ===== SECTION 3: HIGH PRIORITY GAPS ======================================
|
|
259
|
+
pdf.section_title("2. High Priority Gaps", SOPHOS_AMBER)
|
|
260
|
+
pdf.body_text(
|
|
261
|
+
"These tenants have tamper protection below 90% on servers or significant partial gaps. "
|
|
262
|
+
"In most cases, 1-2 specific endpoints or servers need TP re-enabled."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
high = [
|
|
266
|
+
("Durham Green", "TP 59% computers", "Audit and re-enable on multiple endpoints"),
|
|
267
|
+
("Southern Truck Centre", "TP 99% PC, 66% servers", "1 of 3 servers TP disabled"),
|
|
268
|
+
("Gunderson Briggs", "TP 98% PC, 88% servers", "1 server + 1 computer TP disabled"),
|
|
269
|
+
("IOH Injury & Occupational Health", "TP 99% PC, 88% servers", "1 server TP disabled"),
|
|
270
|
+
("Project Portfolio Management", "TP 80% servers", "1 server TP disabled"),
|
|
271
|
+
("Sydney Automotive Paints & Equipment", "TP 85% servers", "1 server TP disabled"),
|
|
272
|
+
]
|
|
273
|
+
|
|
274
|
+
cols_def = [("Customer", 62), ("Issue", 60), ("Action", 68)]
|
|
275
|
+
pdf.table_header(cols_def)
|
|
276
|
+
for i, (cust, issue, action) in enumerate(high):
|
|
277
|
+
pdf.table_row([(cust, 62, "L"), (issue, 60, "L"), (action, 68, "L")], i)
|
|
278
|
+
|
|
279
|
+
pdf.ln(8)
|
|
280
|
+
|
|
281
|
+
# ===== SECTION 4: MODERATE GAPS ===========================================
|
|
282
|
+
pdf.check_space(60)
|
|
283
|
+
pdf.section_title("3. Moderate Gaps (Cleanup Required)")
|
|
284
|
+
pdf.body_text(
|
|
285
|
+
"These tenants have tamper protection between 92-99%. Typically 1-2 stale or "
|
|
286
|
+
"decommissioned endpoints. Check if devices are still active; re-enable TP or "
|
|
287
|
+
"remove stale registrations."
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
moderate = [
|
|
291
|
+
("Australian Survey Solutions", "92%", "1-2 endpoints"),
|
|
292
|
+
("Arex Pty Ltd", "92%", "1-2 endpoints"),
|
|
293
|
+
("Kintyre Country Living", "96%", "1 endpoint"),
|
|
294
|
+
("Van Mal Group Constructions", "96%", "1 endpoint"),
|
|
295
|
+
("The Illawarra ITEC", "96%", "1 endpoint"),
|
|
296
|
+
("The Royce Aged Care", "98%", "1 endpoint"),
|
|
297
|
+
("Gordon MacDonald", "98%", "1 endpoint"),
|
|
298
|
+
("Kiama Community College", "99%", "1 endpoint"),
|
|
299
|
+
("Martin Morris & Jones Wollongong", "99%", "1 endpoint"),
|
|
300
|
+
("Cram Foundation", "99%", "1 endpoint"),
|
|
301
|
+
]
|
|
302
|
+
|
|
303
|
+
cols_def = [("Customer", 80), ("TP Score", 40), ("Likely Scope", 70)]
|
|
304
|
+
pdf.table_header(cols_def)
|
|
305
|
+
for i, (cust, score, scope) in enumerate(moderate):
|
|
306
|
+
pdf.table_row([(cust, 80, "L"), (score, 40, "C"), (scope, 70, "L")], i)
|
|
307
|
+
|
|
308
|
+
# ===== SECTION 5: UPSELL - NO MDR =========================================
|
|
309
|
+
pdf.add_page()
|
|
310
|
+
pdf.section_title("4. Upsell: Customers Without MDR")
|
|
311
|
+
pdf.body_text(
|
|
312
|
+
"The following customers are on Sophos Endpoint only with no MDR coverage. "
|
|
313
|
+
"MDR adds 24/7 threat detection and response by the Sophos MDR team. "
|
|
314
|
+
"Sorted by monthly spend to prioritise the largest existing relationships."
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
no_mdr = [
|
|
318
|
+
("Southern Truck Centre Wollongong", 41, 2, "$446.91", "Endpoint + XG 210", "Strong MDR candidate (43 assets)"),
|
|
319
|
+
("Kintyre Country Living", 3, 0, "$415.77", "XG 310 + Endpoint", "Low user count but premium FW"),
|
|
320
|
+
("REI Process", 0, 0, "$392.30", "XGS 2100 + SF Virtual", "Device-only - check if endpoints needed"),
|
|
321
|
+
("University of Wollongong SmartSpace", 0, 0, "$357.72", "XGS 3300", "Single large firewall"),
|
|
322
|
+
("Autopact", 0, 0, "$306.32", "XGS 126 + SF Virtual", "Device-only estate"),
|
|
323
|
+
("IOH Injury & Occupational Health", 0, 0, "$285.38", "Multiple firewalls", "7 devices no MDR"),
|
|
324
|
+
("Community Gateway Limited", 0, 0, "$181.28", "XGS 126 + XGS 2100", "Firewall-only"),
|
|
325
|
+
("Martin Morris & Jones Wollongong", 0, 0, "$159.72", "XGS 2100 + XGS 107", "Firewall-only"),
|
|
326
|
+
("Gunderson Briggs", 23, 2, "$136.11", "Endpoint + XGS 136", "25 assets - strong candidate"),
|
|
327
|
+
("Custom Built Frames & Trusses", 3, 1, "$33.57", "Endpoint + XGS 107", "Small but bundleable"),
|
|
328
|
+
("The Illawarra ITEC Ltd", 3, 1, "$14.21", "Endpoint only", "Small tenant"),
|
|
329
|
+
("Tulich Project Management", 0, 2, "$13.24", "Server Endpoint only", "Needs MDR Essentials minimum"),
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
cols_def = [("Customer", 52), ("Users", 12), ("Svrs", 12), ("Monthly $", 20), ("Current Products", 42), ("Opportunity", 52)]
|
|
333
|
+
pdf.table_header(cols_def)
|
|
334
|
+
for i, (cust, users, servers, rev, products, opp) in enumerate(no_mdr):
|
|
335
|
+
pdf.table_row([
|
|
336
|
+
(cust, 52, "L"), (str(users), 12, "C"), (str(servers), 12, "C"),
|
|
337
|
+
(rev, 20, "R"), (products, 42, "L"), (opp, 52, "L")
|
|
338
|
+
], i)
|
|
339
|
+
|
|
340
|
+
# ===== SECTION 6: UPSELL - NO FIREWALL ====================================
|
|
341
|
+
pdf.add_page()
|
|
342
|
+
pdf.section_title("5. Upsell: Customers Without Sophos Firewall (20+ Users)")
|
|
343
|
+
pdf.body_text(
|
|
344
|
+
"Customers with 20 or more users and no Sophos firewall (XGS, SF Virtual, or XG) "
|
|
345
|
+
"in their billing. Sorted by monthly spend. Those already on MDR Complete "
|
|
346
|
+
"would benefit most from firewall-endpoint integration via Synchronized Security."
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
no_fw = [
|
|
350
|
+
("Sydwest Multicultural Services", 114, 5, "$1,253.48", "Complete", "TOP PRIORITY - largest no-FW customer"),
|
|
351
|
+
("Master Builders Assoc NSW", 94, 11, "$1,163.00", "Complete", "105 assets with no network protection"),
|
|
352
|
+
("ReadiNow Corporation", 58, 66, "$1,121.98", "Essentials", "124 assets - also MDR upgrade candidate"),
|
|
353
|
+
("Martin Moris & Jones", 79, 2, "$967.30", "Complete", "81 assets no firewall"),
|
|
354
|
+
("QCC", 82, 2, "$871.58", "Complete", "84 assets no network protection"),
|
|
355
|
+
("Community Gateway", 54, 2, "$586.82", "Complete", "56 assets"),
|
|
356
|
+
("Ingenuity Design Group", 67, 17, "$557.20", "Essentials", "84 assets - also MDR upgrade candidate"),
|
|
357
|
+
("Macarthur Diversity Services", 42, 0, "$427.14", "Complete", "No FW, no servers"),
|
|
358
|
+
("Atlas Engineering Group", 30, 1, "$323.92", "Complete", "31 assets"),
|
|
359
|
+
("Regupol", 26, 3, "$320.88", "Complete", "29 assets"),
|
|
360
|
+
("Gordon MacDonald", 31, 0, "$294.45", "Complete", "31 users"),
|
|
361
|
+
("MMJ Real Estate", 23, 0, "$233.91", "Complete", "23 users"),
|
|
362
|
+
("QE Innovations", 19, 1, "$212.05", "Complete", "20 assets"),
|
|
363
|
+
("IAP2 Australasia", 20, 0, "$203.40", "Complete", "20 users"),
|
|
364
|
+
("Market St", 19, 0, "$193.23", "Complete", "19 users"),
|
|
365
|
+
("Southern Pumping", 18, 0, "$183.06", "Complete", "18 users"),
|
|
366
|
+
("Andrew Webb Accounting", 18, 0, "$183.06", "Complete", "18 users"),
|
|
367
|
+
("Anisimoff Legal", 17, 0, "$172.89", "Complete", "17 users"),
|
|
368
|
+
]
|
|
369
|
+
|
|
370
|
+
cols_def = [("Customer", 52), ("Users", 14), ("Svrs", 14), ("Monthly $", 22), ("MDR Tier", 22), ("Opportunity", 66)]
|
|
371
|
+
pdf.table_header(cols_def)
|
|
372
|
+
for i, (cust, users, servers, rev, mdr, opp) in enumerate(no_fw):
|
|
373
|
+
pdf.table_row([
|
|
374
|
+
(cust, 52, "L"), (str(users), 14, "C"), (str(servers), 14, "C"),
|
|
375
|
+
(rev, 22, "R"), (mdr, 22, "C"), (opp, 66, "L")
|
|
376
|
+
], i)
|
|
377
|
+
|
|
378
|
+
# ===== SECTION 7: MDR ESSENTIALS TO COMPLETE ===============================
|
|
379
|
+
pdf.add_page()
|
|
380
|
+
pdf.section_title("6. MDR Essentials to Complete Upgrade Path")
|
|
381
|
+
pdf.body_text(
|
|
382
|
+
"These customers currently have MDR Essentials and are candidates for upgrade to "
|
|
383
|
+
"MDR Complete. MDR Complete adds human-led threat hunting, full incident response, "
|
|
384
|
+
"and a dedicated Sophos response team. Sorted by monthly spend."
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
essentials = [
|
|
388
|
+
("ReadiNow Corporation", 58, 66, "$1,121.98", "124 assets on Essentials - largest upgrade opportunity"),
|
|
389
|
+
("Moduplay Group", 125, 2, "$816.40", "127 assets + 3 firewalls"),
|
|
390
|
+
("Ingenuity Design Group", 67, 17, "$557.20", "84 assets - also no firewall"),
|
|
391
|
+
("National Justice Project", 29, 0, "$149.64", "29 users on Essentials"),
|
|
392
|
+
]
|
|
393
|
+
|
|
394
|
+
cols_def = [("Customer", 52), ("Users", 16), ("Servers", 16), ("Monthly $", 24), ("Notes", 82)]
|
|
395
|
+
pdf.table_header(cols_def)
|
|
396
|
+
for i, (cust, users, servers, rev, notes) in enumerate(essentials):
|
|
397
|
+
pdf.table_row([
|
|
398
|
+
(cust, 52, "L"), (str(users), 16, "C"), (str(servers), 16, "C"),
|
|
399
|
+
(rev, 24, "R"), (notes, 82, "L")
|
|
400
|
+
], i)
|
|
401
|
+
|
|
402
|
+
pdf.ln(8)
|
|
403
|
+
|
|
404
|
+
# ===== SECTION 8: NO SERVER PROTECTION =====================================
|
|
405
|
+
pdf.section_title("7. No Server Protection Enrolled (14 Tenants)")
|
|
406
|
+
pdf.body_text(
|
|
407
|
+
"These tenants have no server protection enrolled in Sophos Central. For customers "
|
|
408
|
+
"with on-premises or cloud servers, Sophos Server Protection or MDR Server should "
|
|
409
|
+
"be deployed. Some may genuinely have no servers (SaaS-only organisations)."
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
no_server = [
|
|
413
|
+
"Big Fat Smile",
|
|
414
|
+
"Intrec Management Pty Ltd",
|
|
415
|
+
"ROKT Pty Limited",
|
|
416
|
+
"Golden West Holden",
|
|
417
|
+
"Etheridge Ford",
|
|
418
|
+
"Gateway Motor Group",
|
|
419
|
+
"C-Lite Pty Ltd",
|
|
420
|
+
"C-Lite",
|
|
421
|
+
"True Blue Chemicals",
|
|
422
|
+
"Sydney Auto Paint",
|
|
423
|
+
"CHL Wollongong Pty Limited",
|
|
424
|
+
"Pumps United",
|
|
425
|
+
"Seapost Pty Ltd t/as Dion's Bus Service",
|
|
426
|
+
"Kiama Community College",
|
|
427
|
+
]
|
|
428
|
+
|
|
429
|
+
cols_def = [("Customer", 95), ("Recommended Action", 95)]
|
|
430
|
+
pdf.table_header(cols_def)
|
|
431
|
+
for i, cust in enumerate(no_server):
|
|
432
|
+
action = "Assess server estate; deploy Sophos Server Protection or MDR Server"
|
|
433
|
+
pdf.table_row([(cust, 95, "L"), (action, 95, "L")], i)
|
|
434
|
+
|
|
435
|
+
# ===== SECTION 9: ACTION PLAN =============================================
|
|
436
|
+
pdf.add_page()
|
|
437
|
+
pdf.section_title("8. Recommended Action Plan")
|
|
438
|
+
|
|
439
|
+
# Immediate
|
|
440
|
+
pdf.sub_title("Immediate - This Week", SOPHOS_RED)
|
|
441
|
+
imm = [
|
|
442
|
+
("Fix Critical TP Gaps", "Re-enable tamper protection on 4 tenants at 0%: Marco Polo Aged Care, Unibuild, MasterCraft Windows and Doors, Martin Morris & Jones Sydney"),
|
|
443
|
+
("Investigate WIN Sports", "2 enrolled servers showing 0% protection - determine root cause"),
|
|
444
|
+
("Fix Durham Green", "TP at 59% - multiple endpoints need TP re-enabled"),
|
|
445
|
+
]
|
|
446
|
+
cols_def = [("Action", 50), ("Detail", 140)]
|
|
447
|
+
pdf.table_header(cols_def)
|
|
448
|
+
for i, (action, detail) in enumerate(imm):
|
|
449
|
+
pdf.table_row([(action, 50, "L"), (detail, 140, "L")], i)
|
|
450
|
+
|
|
451
|
+
pdf.ln(6)
|
|
452
|
+
|
|
453
|
+
# Short term
|
|
454
|
+
pdf.sub_title("Short Term - This Month", SOPHOS_AMBER)
|
|
455
|
+
short = [
|
|
456
|
+
("Fix Server TP Gaps", "Southern Truck Centre, Gunderson Briggs, IOH, Project Portfolio Management, Sydney Automotive Paints & Equipment"),
|
|
457
|
+
("Clean Up Moderate Gaps", "10 tenants with 92-99% TP scores - likely stale devices to remove or re-enable"),
|
|
458
|
+
("Begin MDR Conversations", "Top targets: Southern Truck Centre (43 assets), Gunderson Briggs (25 assets), Tulich Project Management (servers with no MDR)"),
|
|
459
|
+
]
|
|
460
|
+
cols_def = [("Action", 50), ("Detail", 140)]
|
|
461
|
+
pdf.table_header(cols_def)
|
|
462
|
+
for i, (action, detail) in enumerate(short):
|
|
463
|
+
pdf.table_row([(action, 50, "L"), (detail, 140, "L")], i)
|
|
464
|
+
|
|
465
|
+
pdf.ln(6)
|
|
466
|
+
|
|
467
|
+
# QBR
|
|
468
|
+
pdf.sub_title("QBR Conversations", SOPHOS_BLUE)
|
|
469
|
+
qbr = [
|
|
470
|
+
("Firewall Opportunities", "Sydwest Multicultural (114 users), Master Builders (94 users), QCC (82 users) - all MDR Complete with no firewall"),
|
|
471
|
+
("MDR Complete Upgrades", "ReadiNow (124 assets), Moduplay (127 assets), Ingenuity Design (84 assets) - all on MDR Essentials"),
|
|
472
|
+
("Server Protection", "14 tenants with no server enrolment - assess server estates and deploy protection"),
|
|
473
|
+
]
|
|
474
|
+
cols_def = [("Action", 50), ("Detail", 140)]
|
|
475
|
+
pdf.table_header(cols_def)
|
|
476
|
+
for i, (action, detail) in enumerate(qbr):
|
|
477
|
+
pdf.table_row([(action, 50, "L"), (detail, 140, "L")], i)
|
|
478
|
+
|
|
479
|
+
pdf.ln(10)
|
|
480
|
+
|
|
481
|
+
# Data source note
|
|
482
|
+
pdf.set_draw_color(*SOPHOS_BLUE)
|
|
483
|
+
pdf.set_line_width(0.3)
|
|
484
|
+
pdf.line(10, pdf.get_y(), 200, pdf.get_y())
|
|
485
|
+
pdf.ln(4)
|
|
486
|
+
pdf.set_font("Helvetica", "I", 8)
|
|
487
|
+
pdf.set_text_color(*SOPHOS_GREY)
|
|
488
|
+
pdf.multi_cell(0, 4.5, (
|
|
489
|
+
"Data sourced from Sophos Central API via MCP Server v0.2.4. "
|
|
490
|
+
"Health data from Account Health Check API. Billing data from Partner Billing Usage API (March 2026). "
|
|
491
|
+
"All monetary values in AUD at partner net pricing."
|
|
492
|
+
))
|
|
493
|
+
|
|
494
|
+
# == Save ==================================================================
|
|
495
|
+
out_dir = r"C:\Users\Aaron.Jacobs\OneDrive - Sophos Ltd\projects"
|
|
496
|
+
out_path = os.path.join(out_dir, "Rodin_Sophos_Estate_Health_Report_March_2026.pdf")
|
|
497
|
+
pdf.output(out_path)
|
|
498
|
+
print(f"Report saved to: {out_path}")
|
|
499
|
+
print(f"Pages: {pdf.page_no()}")
|
package/package.json
CHANGED