diff --git a/docs/_ext/region_box.py b/docs/_ext/region_box.py new file mode 100644 index 000000000..33e7f2bea --- /dev/null +++ b/docs/_ext/region_box.py @@ -0,0 +1,145 @@ +""" +Directives and role for Robusta platform URL / code components with an +embedded region selector. + +Usage in .rst:: + + .. robusta-url:: https://platform.robusta.dev/account + + .. robusta-code:: bash + + curl --location --request POST 'https://api.robusta.dev/api/alerts' \ + --header 'Authorization: Bearer API-KEY' + + Sign up at :robusta-url:`https://platform.robusta.dev/signup` to get started. + + Or with custom link text: + + Visit :robusta-url:`our platform ` today. + +The rendered HTML carries ``robusta-region-box`` (block) or +``robusta-region-inline`` (inline) classes; the client-side script in +``_static/region-selector.js`` injects the US/EU/AP selector and keeps +every region-aware component on the page in sync. +""" + +import re +from html import escape + +from docutils import nodes +from sphinx.util.docutils import SphinxDirective + + +_LABELLED_URL_RE = re.compile(r"^\s*(.+?)\s*<\s*([^<>\s]+)\s*>\s*$", re.DOTALL) + + +class RobustaUrlDirective(SphinxDirective): + has_content = True + required_arguments = 0 + optional_arguments = 1 + final_argument_whitespace = True + + def run(self): + if self.arguments: + url = self.arguments[0].strip() + else: + url = "\n".join(self.content).strip() + if not url: + return [ + self.state.document.reporter.warning( + "robusta-url requires a URL argument or content", + line=self.lineno, + ) + ] + + url_attr = escape(url, quote=True) + url_text = escape(url) + html = ( + f'
' + f'
' + f'{url_text}' + f'
' + ) + return [nodes.raw("", html, format="html")] + + +class RobustaCodeDirective(SphinxDirective): + has_content = True + required_arguments = 0 + optional_arguments = 1 + final_argument_whitespace = False + + def run(self): + language = self.arguments[0] if self.arguments else "text" + code = "\n".join(self.content) + if not code.strip(): + return [ + self.state.document.reporter.warning( + "robusta-code requires a code block as content", + line=self.lineno, + ) + ] + + container = nodes.container(classes=["robusta-region-box", "robusta-region-box--code"]) + literal = nodes.literal_block(code, code) + literal["language"] = language + container += literal + return [container] + + +class RobustaRegionPickerDirective(SphinxDirective): + """Standalone region picker: a 'Select Region' label + dropdown, no URL.""" + + has_content = False + required_arguments = 0 + optional_arguments = 1 + final_argument_whitespace = True + + def run(self): + label = (self.arguments[0].strip() if self.arguments else "Select Region") + html = ( + f'
' + f'{escape(label)}' + f'' + f"
" + ) + return [nodes.raw("", html, format="html")] + + +def robusta_url_role(name, rawtext, text, lineno, inliner, options=None, content=None): + """Inline ``:robusta-url:`URL``` or ``:robusta-url:`label ```.""" + raw_text = nodes.unescape(text) + match = _LABELLED_URL_RE.match(raw_text) + if match: + label = match.group(1).strip() + url = match.group(2).strip() + else: + url = raw_text.strip() + label = url + if not label: + label = url + if not url: + msg = inliner.reporter.error( + "robusta-url role requires a URL", line=lineno + ) + return [inliner.problematic(rawtext, rawtext, msg)], [msg] + + html = ( + f'' + f'' + f"{escape(label)}" + f"" + ) + return [nodes.raw("", html, format="html")], [] + + +def setup(app): + app.add_directive("robusta-url", RobustaUrlDirective) + app.add_directive("robusta-code", RobustaCodeDirective) + app.add_directive("robusta-region-picker", RobustaRegionPickerDirective) + app.add_role("robusta-url", robusta_url_role) + return { + "version": "0.3", + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/docs/_static/custom.css b/docs/_static/custom.css index c6a8be02c..c858b5add 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -352,3 +352,262 @@ h3 { .success-icon { color: #28a745; /* or any green color you prefer */ } + +/* Robusta region-aware URL / code component */ +.md-typeset .robusta-region-box, +.robusta-region-box { + margin: 1rem 0 1.5rem !important; + border: 1px solid var(--md-default-fg-color--lightest, rgba(0, 0, 0, 0.12)); + border-radius: 4px; + background-color: var(--md-code-bg-color, rgba(0, 0, 0, 0.04)); + overflow: hidden; +} + +.md-typeset .robusta-region-box__bar, +.robusta-region-box__bar { + display: flex !important; + align-items: center; + gap: 0.6rem; + padding: 0.35rem 0.6rem; + background-color: var(--md-default-fg-color--lightest, rgba(0, 0, 0, 0.06)); + border-bottom: 1px solid var(--md-default-fg-color--lightest, rgba(0, 0, 0, 0.08)); + font-size: 0.72rem; + line-height: 1.2; +} + +.md-typeset .robusta-region-box__bar-label, +.robusta-region-box__bar-label { + font-weight: 600; + color: var(--md-default-fg-color--light, rgba(0, 0, 0, 0.6)); +} + +.md-typeset .robusta-region-box__region-options, +.robusta-region-box__region-options { + display: inline-flex !important; + align-items: center; + gap: 0; + border-radius: 3px; + overflow: hidden; +} + +.md-typeset .robusta-region-box__region-btn, +.robusta-region-box__region-btn { + -webkit-appearance: none; + appearance: none; + display: inline-block !important; + border: 1px solid var(--md-default-fg-color--lighter, rgba(0, 0, 0, 0.26)) !important; + background: var(--md-default-bg-color, #fff) !important; + color: var(--md-default-fg-color, #333) !important; + padding: 0.2rem 0.7rem !important; + margin: 0 !important; + cursor: pointer; + font: inherit; + font-size: 0.72rem !important; + font-weight: 600; + line-height: 1.2; + min-width: 2.2rem; + text-align: center; + box-shadow: none; + border-radius: 0 !important; + transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease; +} + +.md-typeset .robusta-region-box__region-btn + .robusta-region-box__region-btn, +.robusta-region-box__region-btn + .robusta-region-box__region-btn { + border-left-width: 0 !important; +} + +.md-typeset .robusta-region-box__region-btn:first-child, +.robusta-region-box__region-btn:first-child { + border-top-left-radius: 3px !important; + border-bottom-left-radius: 3px !important; +} + +.md-typeset .robusta-region-box__region-btn:last-child, +.robusta-region-box__region-btn:last-child { + border-top-right-radius: 3px !important; + border-bottom-right-radius: 3px !important; +} + +.md-typeset .robusta-region-box__region-btn:hover, +.robusta-region-box__region-btn:hover { + color: var(--md-primary-fg-color, #1976d2) !important; +} + +.md-typeset .robusta-region-box__region-btn.is-active, +.robusta-region-box__region-btn.is-active { + background: var(--md-primary-fg-color, #1976d2) !important; + border-color: var(--md-primary-fg-color, #1976d2) !important; + color: var(--md-primary-bg-color, #fff) !important; + z-index: 1; + position: relative; +} + +.md-typeset .robusta-region-box__region-btn:focus-visible, +.robusta-region-box__region-btn:focus-visible { + outline: 2px solid var(--md-accent-fg-color, #1976d2); + outline-offset: 2px; + z-index: 1; + position: relative; +} + +/* URL body */ +.md-typeset .robusta-region-box__body, +.robusta-region-box__body { + padding: 0.6rem 0.85rem; + font-family: var(--md-code-font, "Roboto Mono", monospace); + font-size: 0.78rem; + word-break: break-all; +} + +.md-typeset .robusta-region-box--url a.robusta-region-box__url, +.robusta-region-box--url a.robusta-region-box__url { + color: var(--md-typeset-a-color, var(--md-primary-fg-color, #1976d2)); + text-decoration: none; +} + +.md-typeset .robusta-region-box--url a.robusta-region-box__url:hover, +.robusta-region-box--url a.robusta-region-box__url:hover { + text-decoration: underline; +} + +/* Let the inner literal block sit flush inside the frame */ +.md-typeset .robusta-region-box--code > .highlight, +.md-typeset .robusta-region-box--code > div[class*="highlight"], +.md-typeset .robusta-region-box--code > pre { + margin: 0 !important; + border: 0 !important; + border-radius: 0 !important; +} + +/* Inline region-aware URL: small picker beside the link */ +.md-typeset .robusta-region-inline, +.robusta-region-inline { + display: inline-flex; + align-items: baseline; + gap: 0.3rem; + white-space: nowrap; + max-width: 100%; +} + +.md-typeset .robusta-region-inline__url, +.robusta-region-inline__url { + word-break: break-all; + white-space: normal; +} + +.md-typeset .robusta-region-inline__picker, +.robusta-region-inline__picker { + position: relative; + display: inline-block !important; + vertical-align: baseline; + line-height: 1; + font-size: 0.72rem; + font-weight: 600; + white-space: nowrap; +} + +.md-typeset .robusta-region-inline__trigger, +.robusta-region-inline__trigger { + -webkit-appearance: none; + appearance: none; + display: inline-flex !important; + align-items: center; + gap: 0.2rem; + border: 1px solid var(--md-default-fg-color--lighter, rgba(0, 0, 0, 0.26)) !important; + background: var(--md-default-bg-color, #fff) !important; + color: var(--md-default-fg-color, #333) !important; + padding: 0.1rem 0.45rem !important; + margin: 0 !important; + cursor: pointer; + font: inherit; + font-size: 0.72rem !important; + font-weight: 600; + line-height: 1.2; + border-radius: 3px !important; + box-shadow: none; + transition: border-color 0.15s ease, color 0.15s ease; +} + +.md-typeset .robusta-region-inline__trigger:hover, +.robusta-region-inline__trigger:hover { + border-color: var(--md-primary-fg-color, #1976d2) !important; + color: var(--md-primary-fg-color, #1976d2) !important; +} + +.md-typeset .robusta-region-inline__trigger:focus-visible, +.robusta-region-inline__trigger:focus-visible { + outline: 2px solid var(--md-accent-fg-color, #1976d2); + outline-offset: 2px; +} + +.md-typeset .robusta-region-inline__caret, +.robusta-region-inline__caret { + font-size: 0.7em; + line-height: 1; + opacity: 0.7; +} + +.md-typeset .robusta-region-inline__menu, +.robusta-region-inline__menu { + position: absolute; + top: calc(100% + 2px); + left: 0; + z-index: 30; + display: none !important; + margin: 0 !important; + padding: 0.15rem 0 !important; + list-style: none !important; + min-width: 100%; + width: auto; + background: var(--md-default-bg-color, #fff); + border: 1px solid var(--md-default-fg-color--lighter, rgba(0, 0, 0, 0.18)); + border-radius: 4px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); + font-weight: 500; +} + +.md-typeset .robusta-region-inline__picker.is-open .robusta-region-inline__menu, +.robusta-region-inline__picker.is-open .robusta-region-inline__menu { + display: block !important; +} + +.md-typeset .robusta-region-inline__option, +.robusta-region-inline__option { + display: block !important; + padding: 0.25rem 0.5rem !important; + margin: 0 !important; + cursor: pointer; + color: var(--md-default-fg-color, #333); + user-select: none; + text-align: center; + line-height: 1.2; +} + +.md-typeset .robusta-region-inline__option:hover, +.robusta-region-inline__option:hover { + background: var(--md-default-fg-color--lightest, rgba(0, 0, 0, 0.06)); +} + +.md-typeset .robusta-region-inline__option.is-active, +.robusta-region-inline__option.is-active { + background: var(--md-primary-fg-color, #1976d2); + color: var(--md-primary-bg-color, #fff); +} + +/* Standalone region picker block (label + dropdown, no URL) */ +.md-typeset .robusta-region-picker, +.robusta-region-picker { + display: inline-flex !important; + align-items: center; + gap: 0.5rem; + margin: 0.75rem 0 0.5rem !important; + font-size: 0.78rem; + line-height: 1.4; +} + +.md-typeset .robusta-region-picker__label, +.robusta-region-picker__label { + font-weight: 600; + color: var(--md-default-fg-color--light, rgba(0, 0, 0, 0.7)); +} diff --git a/docs/_static/region-selector.js b/docs/_static/region-selector.js new file mode 100644 index 000000000..7b7ac9ffe --- /dev/null +++ b/docs/_static/region-selector.js @@ -0,0 +1,344 @@ +(function () { + "use strict"; + + const REGIONS = { + us: { label: "US", infix: "" }, + eu: { label: "EU", infix: ".eu" }, + ap: { label: "AP", infix: ".ap" }, + }; + const STORAGE_KEY = "robusta-docs-region"; + const URL_PATTERN = /\b(platform|api)(?:\.(?:eu|ap))?\.robusta\.dev\b/g; + const DETECT_PATTERN = /\b(?:platform|api)(?:\.(?:eu|ap))?\.robusta\.dev\b/; + const BAR_CLASS = "robusta-region-box__bar"; + const BTN_CLASS = "robusta-region-box__region-btn"; + const INLINE_PICKER_CLASS = "robusta-region-inline__picker"; + const INLINE_BTN_CLASS = "robusta-region-inline__btn"; + + function getRegion() { + try { + const r = localStorage.getItem(STORAGE_KEY); + return REGIONS[r] ? r : "us"; + } catch (e) { + return "us"; + } + } + + function saveRegion(r) { + try { + localStorage.setItem(STORAGE_KEY, r); + } catch (e) {} + } + + function rewrite(text, regionKey) { + const infix = REGIONS[regionKey].infix; + return text.replace(URL_PATTERN, function (_, sub) { + return sub + infix + ".robusta.dev"; + }); + } + + // All URL occurrences across the page content (text nodes + relevant + // attributes). Boxes are separate — each holds its selector buttons so + // every box on the page stays visually in sync on region change. + const targets = []; + const boxes = []; + + function collectTargets(root) { + const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, { + acceptNode: function (node) { + if (!node.nodeValue || !DETECT_PATTERN.test(node.nodeValue)) { + return NodeFilter.FILTER_REJECT; + } + const parent = node.parentNode; + if (parent && (parent.tagName === "SCRIPT" || parent.tagName === "STYLE")) { + return NodeFilter.FILTER_REJECT; + } + return NodeFilter.FILTER_ACCEPT; + }, + }); + let node; + while ((node = walker.nextNode())) { + targets.push({ kind: "text", node: node, original: node.nodeValue }); + } + const ATTR_NAMES = ["href", "src", "data-clipboard-text", "value", "title"]; + const selector = ATTR_NAMES.map(function (a) { return "[" + a + "]"; }).join(","); + root.querySelectorAll(selector).forEach(function (el) { + ATTR_NAMES.forEach(function (attr) { + const v = el.getAttribute(attr); + if (v && DETECT_PATTERN.test(v)) { + targets.push({ kind: "attr", node: el, attr: attr, original: v }); + } + }); + }); + } + + function applyRegion(regionKey) { + for (let i = 0; i < targets.length; i++) { + const t = targets[i]; + const next = rewrite(t.original, regionKey); + if (t.kind === "text") { + if (t.node.nodeValue !== next) t.node.nodeValue = next; + } else { + if (t.node.getAttribute(t.attr) !== next) t.node.setAttribute(t.attr, next); + } + } + for (let j = 0; j < boxes.length; j++) { + const box = boxes[j]; + if (box.buttons) { + for (let k = 0; k < box.buttons.length; k++) { + const btn = box.buttons[k]; + const active = btn.getAttribute("data-region") === regionKey; + btn.classList.toggle("is-active", active); + btn.setAttribute("aria-checked", String(active)); + } + } + if (box.items) { + if (box.currentEl) box.currentEl.textContent = REGIONS[regionKey].label; + for (let m = 0; m < box.items.length; m++) { + const item = box.items[m]; + const active = item.getAttribute("data-region") === regionKey; + item.classList.toggle("is-active", active); + item.setAttribute("aria-selected", String(active)); + } + } + } + } + + function syncAll(regionKey) { + saveRegion(regionKey); + applyRegion(regionKey); + } + + function closeAllInlineMenus(except) { + document.querySelectorAll("." + INLINE_PICKER_CLASS + ".is-open").forEach(function (p) { + if (p === except) return; + p.classList.remove("is-open"); + const trig = p.querySelector(".robusta-region-inline__trigger"); + if (trig) trig.setAttribute("aria-expanded", "false"); + }); + } + + function buildInlinePicker(currentRegion) { + const picker = document.createElement("span"); + picker.className = INLINE_PICKER_CLASS; + + const trigger = document.createElement("button"); + trigger.type = "button"; + trigger.className = "robusta-region-inline__trigger"; + trigger.setAttribute("aria-haspopup", "listbox"); + trigger.setAttribute("aria-expanded", "false"); + + const currentEl = document.createElement("span"); + currentEl.className = "robusta-region-inline__current"; + currentEl.textContent = REGIONS[currentRegion].label; + + const caret = document.createElement("span"); + caret.className = "robusta-region-inline__caret"; + caret.setAttribute("aria-hidden", "true"); + caret.textContent = "▾"; + + trigger.appendChild(currentEl); + trigger.appendChild(caret); + + const menu = document.createElement("ul"); + menu.className = "robusta-region-inline__menu"; + menu.setAttribute("role", "listbox"); + + const items = []; + + function focusItem(idx) { + if (idx < 0) idx = items.length - 1; + if (idx >= items.length) idx = 0; + items.forEach(function (it, i) { it.tabIndex = i === idx ? 0 : -1; }); + items[idx].focus(); + } + + function selectItem(key) { + syncAll(key); + picker.classList.remove("is-open"); + trigger.setAttribute("aria-expanded", "false"); + trigger.focus(); + } + + Object.keys(REGIONS).forEach(function (key) { + const item = document.createElement("li"); + item.setAttribute("role", "option"); + item.setAttribute("data-region", key); + item.className = "robusta-region-inline__option"; + const isActive = key === currentRegion; + item.setAttribute("aria-selected", String(isActive)); + item.tabIndex = isActive ? 0 : -1; + if (isActive) item.classList.add("is-active"); + item.textContent = REGIONS[key].label; + item.addEventListener("click", function (e) { + e.preventDefault(); + selectItem(key); + }); + item.addEventListener("keydown", function (e) { + const idx = items.indexOf(item); + switch (e.key) { + case "Enter": + case " ": + e.preventDefault(); + selectItem(key); + break; + case "ArrowDown": + e.preventDefault(); + focusItem(idx + 1); + break; + case "ArrowUp": + e.preventDefault(); + focusItem(idx - 1); + break; + case "Home": + e.preventDefault(); + focusItem(0); + break; + case "End": + e.preventDefault(); + focusItem(items.length - 1); + break; + case "Tab": + picker.classList.remove("is-open"); + trigger.setAttribute("aria-expanded", "false"); + break; + case "Escape": + e.preventDefault(); + picker.classList.remove("is-open"); + trigger.setAttribute("aria-expanded", "false"); + trigger.focus(); + break; + } + }); + menu.appendChild(item); + items.push(item); + }); + + function openMenu() { + closeAllInlineMenus(picker); + picker.classList.add("is-open"); + trigger.setAttribute("aria-expanded", "true"); + const activeIdx = items.findIndex(function (it) { return it.classList.contains("is-active"); }); + focusItem(activeIdx >= 0 ? activeIdx : 0); + } + + trigger.addEventListener("click", function (e) { + e.preventDefault(); + e.stopPropagation(); + if (picker.classList.contains("is-open")) { + picker.classList.remove("is-open"); + trigger.setAttribute("aria-expanded", "false"); + } else { + openMenu(); + } + }); + + trigger.addEventListener("keydown", function (e) { + if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") { + e.preventDefault(); + openMenu(); + } else if (e.key === "ArrowUp") { + e.preventDefault(); + openMenu(); + focusItem(items.length - 1); + } + }); + + picker.appendChild(trigger); + picker.appendChild(menu); + + return { picker: picker, trigger: trigger, currentEl: currentEl, items: items }; + } + + function buildBar(currentRegion) { + const bar = document.createElement("div"); + bar.className = BAR_CLASS; + + const label = document.createElement("span"); + label.className = "robusta-region-box__bar-label"; + label.textContent = "Select Region"; + bar.appendChild(label); + + const group = document.createElement("div"); + group.className = "robusta-region-box__region-options"; + group.setAttribute("role", "radiogroup"); + group.setAttribute("aria-label", "Select your Robusta region"); + + const buttons = []; + Object.keys(REGIONS).forEach(function (key) { + const btn = document.createElement("button"); + btn.type = "button"; + btn.setAttribute("role", "radio"); + btn.setAttribute("data-region", key); + btn.className = BTN_CLASS; + btn.textContent = REGIONS[key].label; + const active = key === currentRegion; + btn.setAttribute("aria-checked", String(active)); + if (active) btn.classList.add("is-active"); + btn.addEventListener("click", function () { + syncAll(key); + }); + group.appendChild(btn); + buttons.push(btn); + }); + + bar.appendChild(group); + return { bar: bar, buttons: buttons }; + } + + function init() { + targets.length = 0; + boxes.length = 0; + + const content = + document.querySelector(".md-content__inner") || + document.querySelector("article") || + document.querySelector("main") || + document.body; + if (!content) return; + + const region = getRegion(); + + content.querySelectorAll(".robusta-region-box").forEach(function (el) { + const existingBar = el.querySelector(":scope > ." + BAR_CLASS); + if (existingBar) existingBar.remove(); + const built = buildBar(region); + el.insertBefore(built.bar, el.firstChild); + boxes.push({ buttons: built.buttons }); + }); + + content.querySelectorAll(".robusta-region-inline").forEach(function (el) { + const existingPicker = el.querySelector(":scope > ." + INLINE_PICKER_CLASS); + if (existingPicker) existingPicker.remove(); + const built = buildInlinePicker(region); + el.appendChild(built.picker); + boxes.push({ currentEl: built.currentEl, items: built.items }); + }); + + collectTargets(content); + + if (targets.length === 0 && boxes.length === 0) return; + + applyRegion(region); + } + + document.addEventListener("click", function (e) { + const open = document.querySelector("." + INLINE_PICKER_CLASS + ".is-open"); + if (open && !open.contains(e.target)) closeAllInlineMenus(null); + }); + document.addEventListener("keydown", function (e) { + if (e.key === "Escape") closeAllInlineMenus(null); + }); + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } + + // Material/Sphinx-Immaterial instant navigation swaps the content area + // without firing DOMContentLoaded. The theme exposes an RxJS `document$` + // observable that emits on every swap; re-run init() on each emission. + if (typeof window !== "undefined" && window.document$ && typeof window.document$.subscribe === "function") { + window.document$.subscribe(init); + } +})(); diff --git a/docs/conf.py b/docs/conf.py index 4ee9e6978..a00a1619d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -50,6 +50,7 @@ "sphinx_design", "sphinxcontrib.images", "autorobusta", + "region_box", "sphinx_immaterial", "sphinxcontrib.details.directive", "sphinx_jinja", @@ -370,7 +371,7 @@ "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css", ] -html_js_files = ["analytics.js"] +html_js_files = ["analytics.js", "region-selector.js"] html_favicon = "_static/favicon.png" diff --git a/docs/configuration/alertmanager-integration/coralogix_managed_prometheus.rst b/docs/configuration/alertmanager-integration/coralogix_managed_prometheus.rst index 6ee721476..d86b016d6 100644 --- a/docs/configuration/alertmanager-integration/coralogix_managed_prometheus.rst +++ b/docs/configuration/alertmanager-integration/coralogix_managed_prometheus.rst @@ -20,7 +20,7 @@ Common Configuration (for both webhooks) 1. In the Coralogix site go to Data Flow, then Outbound Webhooks, and click ``Generic webhook``. 2. In the url insert: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/alertmanager diff --git a/docs/configuration/alertmanager-integration/dynatrace.rst b/docs/configuration/alertmanager-integration/dynatrace.rst index a9d640165..57e6a693d 100644 --- a/docs/configuration/alertmanager-integration/dynatrace.rst +++ b/docs/configuration/alertmanager-integration/dynatrace.rst @@ -33,7 +33,7 @@ Step 2: Create a Dynatrace Problems Webhook 3. Click **Add notification** and choose **Webhook**. 4. Configure the **URL**: - ``https://api.robusta.dev/integrations/generic/dynatrace`` + :robusta-url:`https://api.robusta.dev/integrations/generic/dynatrace` 5. Set the **Custom payload** to the Dynatrace macro: diff --git a/docs/configuration/alertmanager-integration/gcp-monitoring.rst b/docs/configuration/alertmanager-integration/gcp-monitoring.rst index 78b737bc3..9482b69b8 100644 --- a/docs/configuration/alertmanager-integration/gcp-monitoring.rst +++ b/docs/configuration/alertmanager-integration/gcp-monitoring.rst @@ -37,7 +37,7 @@ Step 2: Create a Webhook Notification Channel in GCP 3. Configure the webhook with the following settings: - **Display Name**: ``RobustaWebhook`` - - **Endpoint URL**: ``https://api.robusta.dev/integrations/generic/gcp`` + - **Endpoint URL**: :robusta-url:`https://api.robusta.dev/integrations/generic/gcp` - **Authentication**: Select **Basic Authentication** - **Username**: Your Robusta ``account_id`` from Step 1 - **Password**: Your Robusta API key from Step 1 diff --git a/docs/configuration/alertmanager-integration/google-managed-alertmanager.rst b/docs/configuration/alertmanager-integration/google-managed-alertmanager.rst index 18a5cdb1e..916a51d97 100644 --- a/docs/configuration/alertmanager-integration/google-managed-alertmanager.rst +++ b/docs/configuration/alertmanager-integration/google-managed-alertmanager.rst @@ -22,7 +22,7 @@ Configure the Alertmanager webhook Apply the following Secret in the GMP namespace (default ``gmp-public``). Replace ```` and ```` with your credentials. -.. code-block:: yaml +.. robusta-code:: yaml apiVersion: v1 kind: Secret @@ -103,7 +103,7 @@ Optional: verify credentials with curl You can manually validate the webhook and credentials by posting a sample alert: -.. code-block:: bash +.. robusta-code:: bash curl -X POST 'https://api.robusta.dev/integrations/generic/alertmanager' \ -H 'Authorization: Bearer ' \ diff --git a/docs/configuration/alertmanager-integration/grafana-self-hosted.rst b/docs/configuration/alertmanager-integration/grafana-self-hosted.rst index 0809277b0..8889bde88 100644 --- a/docs/configuration/alertmanager-integration/grafana-self-hosted.rst +++ b/docs/configuration/alertmanager-integration/grafana-self-hosted.rst @@ -44,7 +44,7 @@ Generate and save your new ``API Key`` Select ``Webhook`` from the Integration options. Add the following URL. Add your ``account_id`` to it: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/alerts/grafana?account_id=YOUR_ACCOUNT_ID @@ -111,7 +111,7 @@ To configure it: 2. Insert the following URL: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/alertmanager diff --git a/docs/configuration/alertmanager-integration/launchdarkly.rst b/docs/configuration/alertmanager-integration/launchdarkly.rst index 2bd3b4633..b1420129d 100644 --- a/docs/configuration/alertmanager-integration/launchdarkly.rst +++ b/docs/configuration/alertmanager-integration/launchdarkly.rst @@ -43,7 +43,7 @@ In LaunchDarkly: 3. Configure: - **Name**: ``Robusta`` - - **URL**: ``https://api.robusta.dev/integrations/generic/launchdarkly?api_key=YOUR_API_KEY_HERE&account_id=YOUR_ACCOUNT_ID_HERE`` + - **URL**: :robusta-url:`https://api.robusta.dev/integrations/generic/launchdarkly?api_key=YOUR_API_KEY_HERE&account_id=YOUR_ACCOUNT_ID_HERE` - Replace ``YOUR_API_KEY_HERE`` with the API key from Step 1. - Replace ``YOUR_ACCOUNT_ID_HERE`` with your account ID from Step 1. @@ -64,7 +64,7 @@ Including API keys in URLs can expose them in logs, browser history, and monitor If you’re using a third-party service that supports custom headers, configure the webhook like this: -- **URL**: ``https://api.robusta.dev/integrations/generic/launchdarkly?account_id=YOUR_ACCOUNT_ID_HERE`` +- **URL**: :robusta-url:`https://api.robusta.dev/integrations/generic/launchdarkly?account_id=YOUR_ACCOUNT_ID_HERE` - **Headers**: .. code-block:: text diff --git a/docs/configuration/alertmanager-integration/nagios.rst b/docs/configuration/alertmanager-integration/nagios.rst index 437b527bf..541ddbd5f 100644 --- a/docs/configuration/alertmanager-integration/nagios.rst +++ b/docs/configuration/alertmanager-integration/nagios.rst @@ -14,7 +14,7 @@ Requirements - Robusta must already be deployed and running in your environment. - The Nagios host must be able to send `curl` requests to the Robusta API endpoint: - .. code-block:: + .. robusta-code:: https://api.robusta.dev/integrations/generic/nagios @@ -80,7 +80,7 @@ Step 4: Create the Bash Command Script Save this as `notify-robusta.sh`, ensure it's executable (`chmod +x notify-robusta.sh`), and Nagios can access it. -.. code-block:: bash +.. robusta-code:: bash #!/bin/sh diff --git a/docs/configuration/alertmanager-integration/newrelic.rst b/docs/configuration/alertmanager-integration/newrelic.rst index 3de168969..96bfcdadb 100644 --- a/docs/configuration/alertmanager-integration/newrelic.rst +++ b/docs/configuration/alertmanager-integration/newrelic.rst @@ -44,7 +44,7 @@ In New Relic: 2. Click **New destination** → choose **Webhook**. 3. Configure: - - **URL**: ``https://api.robusta.dev/integrations/generic/newrelic`` + - **URL**: :robusta-url:`https://api.robusta.dev/integrations/generic/newrelic` - **Authentication**: **Bearer token** - **Token**: paste the **Robusta API key** from Step 1. diff --git a/docs/configuration/alertmanager-integration/outofcluster-prometheus.rst b/docs/configuration/alertmanager-integration/outofcluster-prometheus.rst index 10a857501..b3a87fc11 100644 --- a/docs/configuration/alertmanager-integration/outofcluster-prometheus.rst +++ b/docs/configuration/alertmanager-integration/outofcluster-prometheus.rst @@ -21,7 +21,7 @@ This integration lets your central Prometheus send alerts to Robusta, as if they .. admonition:: alertmanager.yaml - .. code-block:: yaml + .. robusta-code:: yaml receivers: - name: 'robusta' @@ -72,7 +72,7 @@ If you are using a third-party AlertManager and want to give it separate credent .. admonition:: alertmanager.yaml - .. code-block:: yaml + .. robusta-code:: yaml receivers: - name: 'robusta' diff --git a/docs/configuration/alertmanager-integration/pagerduty-alerting.rst b/docs/configuration/alertmanager-integration/pagerduty-alerting.rst index d765bb8a6..308620609 100644 --- a/docs/configuration/alertmanager-integration/pagerduty-alerting.rst +++ b/docs/configuration/alertmanager-integration/pagerduty-alerting.rst @@ -47,7 +47,7 @@ Set the following values: * **Webhook URL**: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/pagerduty/incidents @@ -88,7 +88,7 @@ Step 1: Create an Integration for Alertmanager 1. In Event Orchestration, create a new **Integration** named ``Alertmanager``. 2. Use the following webhook URL: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/pagerduty/alerts @@ -116,7 +116,7 @@ Step 3: Add a Webhook Action * **URL**: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/pagerduty/alerts @@ -171,7 +171,7 @@ Optional: Cluster Name via Query Param You can specify the target cluster using a query parameter in the webhook URL: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/pagerduty/incidents?cluster=your-cluster-name @@ -179,7 +179,7 @@ This is useful for multi-cluster setups where Robusta should assign findings to For example: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/integrations/generic/pagerduty/incidents?cluster=test-cluster diff --git a/docs/configuration/alertmanager-integration/solarwinds.rst b/docs/configuration/alertmanager-integration/solarwinds.rst index b6d857b8a..6d9ff0cda 100644 --- a/docs/configuration/alertmanager-integration/solarwinds.rst +++ b/docs/configuration/alertmanager-integration/solarwinds.rst @@ -37,7 +37,7 @@ Step 3: Create a Webhook Configuration in SolarWinds - **Description**: Robusta Webhook - **Destination URL**: - .. code-block:: + .. robusta-code:: https://api.robusta.dev/integrations/generic/solarwinds?account_id=ACCOUNT_ID_HERE diff --git a/docs/configuration/exporting/alert-export-api.rst b/docs/configuration/exporting/alert-export-api.rst index dae4feab5..adc6a7f84 100644 --- a/docs/configuration/exporting/alert-export-api.rst +++ b/docs/configuration/exporting/alert-export-api.rst @@ -48,7 +48,7 @@ Example Request The following ``curl`` command demonstrates how to export alert history data for the ``CrashLoopBackoff`` alert: -.. code-block:: bash +.. robusta-code:: bash curl --location 'https://api.robusta.dev/api/query/alerts?alert_name=CrashLoopBackoff&account_id=ACCOUNT_ID&start_ts=2024-09-02T04%3A02%3A05.032Z&end_ts=2024-09-17T05%3A02%3A05.032Z' \ --header 'Authorization: Bearer API-KEY' diff --git a/docs/configuration/exporting/alert-statistics-api.rst b/docs/configuration/exporting/alert-statistics-api.rst index 9e79fd7b1..f969aa659 100644 --- a/docs/configuration/exporting/alert-statistics-api.rst +++ b/docs/configuration/exporting/alert-statistics-api.rst @@ -41,7 +41,7 @@ Example Request The following `curl` command demonstrates how to query aggregated alert data for a specified time range: -.. code-block:: bash +.. robusta-code:: bash curl --location 'https://api.robusta.dev/api/query/report?account_id=XXXXXX-XXXX_XXXX_XXXXX7&start_ts=2024-10-27T04:02:05.032Z&end_ts=2024-11-27T05:02:05.032Z' \ --header 'Authorization: Bearer API-KEY' diff --git a/docs/configuration/exporting/configuration-changes-api.rst b/docs/configuration/exporting/configuration-changes-api.rst index 3891990ea..0ef5b19b8 100644 --- a/docs/configuration/exporting/configuration-changes-api.rst +++ b/docs/configuration/exporting/configuration-changes-api.rst @@ -114,7 +114,7 @@ Example Request Here is an example of a ``POST`` request to send a list of configuration changes: -.. code-block:: bash +.. robusta-code:: bash curl --location --request POST 'https://api.robusta.dev/api/config-changes' \ --header 'Authorization: Bearer API-KEY' \ diff --git a/docs/configuration/exporting/custom-webhooks.rst b/docs/configuration/exporting/custom-webhooks.rst index a7b9bb629..2f8701dc6 100644 --- a/docs/configuration/exporting/custom-webhooks.rst +++ b/docs/configuration/exporting/custom-webhooks.rst @@ -18,7 +18,7 @@ Webhook Endpoint Send alerts to Robusta using the following endpoint: -.. code-block:: bash +.. robusta-code:: bash POST https://api.robusta.dev/api/alerts @@ -37,7 +37,7 @@ Quick Example Here's a simple example of sending a custom alert: -.. code-block:: bash +.. robusta-code:: bash curl --location --request POST 'https://api.robusta.dev/api/alerts' \ --header 'Authorization: Bearer YOUR_API_KEY' \ diff --git a/docs/configuration/exporting/namespace-resources-api.rst b/docs/configuration/exporting/namespace-resources-api.rst index 8e4141197..b604f04f0 100644 --- a/docs/configuration/exporting/namespace-resources-api.rst +++ b/docs/configuration/exporting/namespace-resources-api.rst @@ -63,7 +63,7 @@ Example Request Here is an example of a ``POST`` request to query the resource count in a namespace: -.. code-block:: bash +.. robusta-code:: bash curl --location 'https://api.robusta.dev/api/namespaces/resources' \ --header 'Authorization: Bearer API-KEY-HERE' \ diff --git a/docs/configuration/exporting/prometheus-query-api.rst b/docs/configuration/exporting/prometheus-query-api.rst index d02a94f38..245c44378 100644 --- a/docs/configuration/exporting/prometheus-query-api.rst +++ b/docs/configuration/exporting/prometheus-query-api.rst @@ -12,7 +12,7 @@ in your connected clusters. Endpoint -------- -.. code-block:: +.. robusta-code:: POST https://api.robusta.dev/api/accounts/{account_id}/clusters/{cluster_name}/prometheus/query @@ -86,7 +86,7 @@ Example Request Using duration (last 5 minutes): -.. code-block:: bash +.. robusta-code:: bash curl -X POST "https://api.robusta.dev/api/accounts/ACCOUNT_ID/clusters/CLUSTER_NAME/prometheus/query" \ -H "Authorization: Bearer YOUR_API_KEY" \ @@ -99,7 +99,7 @@ Using duration (last 5 minutes): Using date range: -.. code-block:: bash +.. robusta-code:: bash curl -X POST "https://api.robusta.dev/api/accounts/ACCOUNT_ID/clusters/CLUSTER_NAME/prometheus/query" \ -H "Authorization: Bearer YOUR_API_KEY" \ diff --git a/docs/configuration/exporting/rbac-api.rst b/docs/configuration/exporting/rbac-api.rst index 0f6f17697..b60133b21 100644 --- a/docs/configuration/exporting/rbac-api.rst +++ b/docs/configuration/exporting/rbac-api.rst @@ -56,7 +56,7 @@ Retrieve the current RBAC configuration for your account. **Request:** -.. code-block:: bash +.. robusta-code:: bash curl -X GET 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' @@ -109,7 +109,7 @@ Create or update the RBAC configuration for your account. **Request:** -.. code-block:: bash +.. robusta-code:: bash curl -X POST 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' \ @@ -186,7 +186,7 @@ Remove all RBAC configurations for your account. **Request:** -.. code-block:: bash +.. robusta-code:: bash curl -X DELETE 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' @@ -319,7 +319,7 @@ Examples **Set up namespace-level permissions for developers:** -.. code-block:: bash +.. robusta-code:: bash curl -X POST 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' \ @@ -349,7 +349,7 @@ Examples **Set up cluster-wide admin access:** -.. code-block:: bash +.. robusta-code:: bash curl -X POST 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' \ @@ -367,7 +367,7 @@ Examples **Complex configuration with multiple scopes and permission groups:** -.. code-block:: bash +.. robusta-code:: bash curl -X POST 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' \ @@ -429,14 +429,14 @@ Examples **Retrieve current configuration:** -.. code-block:: bash +.. robusta-code:: bash curl -X GET 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' **Clear all RBAC configurations:** -.. code-block:: bash +.. robusta-code:: bash curl -X DELETE 'https://api.robusta.dev/api/rbac?account_id=YOUR_ACCOUNT_ID' \ -H 'Authorization: Bearer YOUR_API_KEY' diff --git a/docs/configuration/exporting/robusta-pro-features.rst b/docs/configuration/exporting/robusta-pro-features.rst index ae1b3404f..466e23e53 100644 --- a/docs/configuration/exporting/robusta-pro-features.rst +++ b/docs/configuration/exporting/robusta-pro-features.rst @@ -25,5 +25,5 @@ Getting Started To access these APIs: -1. `Sign up `_ for Robusta SaaS or contact support@robusta.dev for self-hosted plans +1. :robusta-url:`Sign up ` for Robusta SaaS or contact support@robusta.dev for self-hosted plans 2. Generate API keys in the Robusta Platform under **Settings** → **API Keys** diff --git a/docs/configuration/exporting/send-alerts-api.rst b/docs/configuration/exporting/send-alerts-api.rst index 0fc423832..01e220662 100644 --- a/docs/configuration/exporting/send-alerts-api.rst +++ b/docs/configuration/exporting/send-alerts-api.rst @@ -21,8 +21,10 @@ Use this endpoint to send alert data to Robusta. You can send up to 1000 alerts .. _send-alerts-api: -POST https://api.robusta.dev/api/alerts -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +POST endpoint +^^^^^^^^^^^^^ + +.. robusta-url:: https://api.robusta.dev/api/alerts Request Body Schema """""""""""""""""""" @@ -133,7 +135,7 @@ Example Request Here is an example of a ``POST`` request to send a list of alerts: -.. code-block:: bash +.. robusta-code:: bash curl --location --request POST 'https://api.robusta.dev/api/alerts' \ --header 'Authorization: Bearer API-KEY' \ diff --git a/docs/configuration/exporting/send-events-api.rst b/docs/configuration/exporting/send-events-api.rst index 4fe9b94dc..fe940c8ec 100644 --- a/docs/configuration/exporting/send-events-api.rst +++ b/docs/configuration/exporting/send-events-api.rst @@ -27,7 +27,7 @@ This is the recommended ingestion path for new integrations. The legacy :doc:`Se Endpoint -------- -.. code-block:: +.. robusta-code:: POST https://api.robusta.dev/webhooks?type=alert&origin=&account_id= @@ -61,7 +61,7 @@ The key must be scoped to the ``account_id`` query parameter. Mismatches return Example Request --------------- -.. code-block:: bash +.. robusta-code:: bash curl --location --request POST \ 'https://api.robusta.dev/webhooks?type=alert&origin=datadog&account_id=ACCOUNT_ID' \ diff --git a/docs/configuration/exporting/send-events/alertmanager.rst b/docs/configuration/exporting/send-events/alertmanager.rst index e695a3dcf..9336e09ac 100644 --- a/docs/configuration/exporting/send-events/alertmanager.rst +++ b/docs/configuration/exporting/send-events/alertmanager.rst @@ -13,7 +13,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=alertmanager&account_id= @@ -22,7 +22,7 @@ Configure AlertManager Add a webhook receiver to ``alertmanager.yml``: -.. code-block:: yaml +.. robusta-code:: yaml receivers: - name: robusta diff --git a/docs/configuration/exporting/send-events/aws-cloudwatch.rst b/docs/configuration/exporting/send-events/aws-cloudwatch.rst index 49db98e71..05d582ba9 100644 --- a/docs/configuration/exporting/send-events/aws-cloudwatch.rst +++ b/docs/configuration/exporting/send-events/aws-cloudwatch.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=awscloudwatch&account_id= @@ -25,7 +25,7 @@ Recipe 2. Create a Lambda function (Python 3.12) and subscribe it to the ``robusta`` SNS topic. Store the Robusta API key in **Lambda → Configuration → Environment variables** as ``ROBUSTA_API_KEY``. 3. Use the following handler: - .. code-block:: python + .. robusta-code:: python import json import os diff --git a/docs/configuration/exporting/send-events/azure-monitor.rst b/docs/configuration/exporting/send-events/azure-monitor.rst index dea8498b0..6ddcfc3bc 100644 --- a/docs/configuration/exporting/send-events/azure-monitor.rst +++ b/docs/configuration/exporting/send-events/azure-monitor.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=azure&account_id= @@ -23,7 +23,7 @@ Configure Azure Action Group webhook receivers do not allow custom headers, so authenticate via the URL: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=azure&account_id=&token= diff --git a/docs/configuration/exporting/send-events/datadog.rst b/docs/configuration/exporting/send-events/datadog.rst index 5ef568485..aaddc57c7 100644 --- a/docs/configuration/exporting/send-events/datadog.rst +++ b/docs/configuration/exporting/send-events/datadog.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=datadog&account_id= diff --git a/docs/configuration/exporting/send-events/dynatrace.rst b/docs/configuration/exporting/send-events/dynatrace.rst index a19624079..c0fe8c225 100644 --- a/docs/configuration/exporting/send-events/dynatrace.rst +++ b/docs/configuration/exporting/send-events/dynatrace.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=dynatrace&account_id= diff --git a/docs/configuration/exporting/send-events/gcp-monitoring.rst b/docs/configuration/exporting/send-events/gcp-monitoring.rst index d2b7ae5ec..8845678d1 100644 --- a/docs/configuration/exporting/send-events/gcp-monitoring.rst +++ b/docs/configuration/exporting/send-events/gcp-monitoring.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=gcp&account_id= @@ -23,7 +23,7 @@ Configure GCP GCP webhook notification channels do not support custom headers in the console, so include the API key in the URL: -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=gcp&account_id=&token= diff --git a/docs/configuration/exporting/send-events/grafana.rst b/docs/configuration/exporting/send-events/grafana.rst index d9692385c..f3cd2b453 100644 --- a/docs/configuration/exporting/send-events/grafana.rst +++ b/docs/configuration/exporting/send-events/grafana.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=grafana&account_id= diff --git a/docs/configuration/exporting/send-events/nagios.rst b/docs/configuration/exporting/send-events/nagios.rst index a58a565ff..8e1a35412 100644 --- a/docs/configuration/exporting/send-events/nagios.rst +++ b/docs/configuration/exporting/send-events/nagios.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=nagios&account_id= @@ -37,7 +37,7 @@ Restrict the file to the Nagios user: Define a notification command that references ``$USER20$``: -.. code-block:: +.. robusta-code:: define command { command_name notify-robusta-service diff --git a/docs/configuration/exporting/send-events/newrelic.rst b/docs/configuration/exporting/send-events/newrelic.rst index 3ac1e29d2..cbcdd962a 100644 --- a/docs/configuration/exporting/send-events/newrelic.rst +++ b/docs/configuration/exporting/send-events/newrelic.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=newrelic&account_id= diff --git a/docs/configuration/exporting/send-events/opsgenie.rst b/docs/configuration/exporting/send-events/opsgenie.rst index 516de1e7d..ac00f4971 100644 --- a/docs/configuration/exporting/send-events/opsgenie.rst +++ b/docs/configuration/exporting/send-events/opsgenie.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=opsgenie&account_id= diff --git a/docs/configuration/exporting/send-events/pagerduty.rst b/docs/configuration/exporting/send-events/pagerduty.rst index 466d31550..20efad710 100644 --- a/docs/configuration/exporting/send-events/pagerduty.rst +++ b/docs/configuration/exporting/send-events/pagerduty.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=pagerduty&account_id= diff --git a/docs/configuration/exporting/send-events/sentry.rst b/docs/configuration/exporting/send-events/sentry.rst index 2f11170f6..0b01d2885 100644 --- a/docs/configuration/exporting/send-events/sentry.rst +++ b/docs/configuration/exporting/send-events/sentry.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=sentry&account_id= diff --git a/docs/configuration/exporting/send-events/solarwinds.rst b/docs/configuration/exporting/send-events/solarwinds.rst index cd2db4e56..5ff02ee86 100644 --- a/docs/configuration/exporting/send-events/solarwinds.rst +++ b/docs/configuration/exporting/send-events/solarwinds.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=solarwinds&account_id= @@ -23,7 +23,7 @@ Configure SolarWinds SolarWinds does not ship a native bearer-token webhook action. Use the **Execute an external program** alert action to invoke ``curl`` (bundled with Windows 10+ and Windows Server 2019+): -.. code-block:: +.. robusta-code:: curl -sS -X POST -H "Authorization: Bearer " -H "Content-Type: application/json" --data "{ \"alertName\": \"${N=Alerting;M=AlertName}\", \"node\": \"${N=SwisEntity;M=Caption}\", \"severity\": \"${N=Alerting;M=Severity}\", \"message\": \"${N=Alerting;M=AlertMessage}\" }" "https://api.robusta.dev/webhooks?type=alert&origin=solarwinds&account_id=" diff --git a/docs/configuration/exporting/send-events/splunk.rst b/docs/configuration/exporting/send-events/splunk.rst index e02a4fd07..fe6b6702e 100644 --- a/docs/configuration/exporting/send-events/splunk.rst +++ b/docs/configuration/exporting/send-events/splunk.rst @@ -14,7 +14,7 @@ Prerequisites Webhook URL ----------- -.. code-block:: +.. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=splunk&account_id= @@ -26,7 +26,7 @@ Splunk's built-in **Webhook** alert action does not let you set custom headers, 1. Open or create a Splunk saved search and choose **Add Actions → Webhook**. 2. Set the **URL** to the webhook URL above with ``&token=`` appended, so authentication travels with the request: - .. code-block:: + .. robusta-code:: https://api.robusta.dev/webhooks?type=alert&origin=splunk&account_id=&token= diff --git a/docs/configuration/github-actions/holmes-pr-review.rst b/docs/configuration/github-actions/holmes-pr-review.rst index 373189774..818561094 100644 --- a/docs/configuration/github-actions/holmes-pr-review.rst +++ b/docs/configuration/github-actions/holmes-pr-review.rst @@ -69,7 +69,7 @@ Step 4: Add the Workflow File Create a new file in your repository at ``.github/workflows/holmes-pr-review.yaml`` with the following contents: -.. code-block:: yaml +.. robusta-code:: yaml name: Holmes PR review on: diff --git a/docs/configuration/holmesgpt/holmes-chat-api.rst b/docs/configuration/holmesgpt/holmes-chat-api.rst index 2ca935d58..11de7d9a7 100644 --- a/docs/configuration/holmesgpt/holmes-chat-api.rst +++ b/docs/configuration/holmesgpt/holmes-chat-api.rst @@ -64,7 +64,7 @@ Example Request The following ``curl`` command demonstrates how to ask Holmes about a failing pod: -.. code-block:: bash +.. robusta-code:: bash curl -X POST 'https://api.robusta.dev/api/holmes/ACCOUNT_ID/chat' \ --header 'Content-Type: application/json' \ @@ -211,7 +211,7 @@ To enable streaming, set ``stream`` to ``true`` in the request body. All other p Example Streaming Request ^^^^^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: bash +.. robusta-code:: bash curl -N -X POST 'https://api.robusta.dev/api/holmes/ACCOUNT_ID/chat' \ --header 'Content-Type: application/json' \ @@ -499,7 +499,7 @@ Consuming the Stream **Python (using requests):** -.. code-block:: python +.. robusta-code:: python import requests import json diff --git a/docs/configuration/metric-providers-external.rst b/docs/configuration/metric-providers-external.rst index 334224961..518679289 100644 --- a/docs/configuration/metric-providers-external.rst +++ b/docs/configuration/metric-providers-external.rst @@ -185,5 +185,5 @@ Next Steps ---------- - Configure :doc:`alert routing ` -- `Set up AI-powered insights `_ +- :robusta-url:`Set up AI-powered insights ` - Learn about :doc:`common configuration options ` \ No newline at end of file diff --git a/docs/configuration/resource-recommender.rst b/docs/configuration/resource-recommender.rst index 0069400a1..dac56a709 100644 --- a/docs/configuration/resource-recommender.rst +++ b/docs/configuration/resource-recommender.rst @@ -227,7 +227,7 @@ Retrieves KRR resource recommendations for a specific cluster and namespace. **Example Request** -.. code-block:: bash +.. robusta-code:: bash curl -X GET "https://api.robusta.dev/api/krr/recommendations?account_id=YOUR_ACCOUNT_ID&cluster_id=my-cluster&namespace=default" \ -H "Authorization: Bearer YOUR_API_KEY" \ diff --git a/docs/configuration/sinks/RobustaUI.rst b/docs/configuration/sinks/RobustaUI.rst index 440840712..136780064 100644 --- a/docs/configuration/sinks/RobustaUI.rst +++ b/docs/configuration/sinks/RobustaUI.rst @@ -20,7 +20,7 @@ Configuring the Robusta UI Sink ------------------------------------------------ .. tip:: - This guide is for users who have already installed Robusta on their cluster. If you haven't installed Robusta yet, we recommend starting by `creating a free Robusta UI account ↗ `_ instead. + This guide is for users who have already installed Robusta on their cluster. If you haven't installed Robusta yet, we recommend starting by :robusta-url:`creating a free Robusta UI account ↗ ` instead. Use the ``robusta`` CLI to generate a token: diff --git a/docs/configuration/sinks/slack.rst b/docs/configuration/sinks/slack.rst index 6cbbc2567..7de6b179c 100644 --- a/docs/configuration/sinks/slack.rst +++ b/docs/configuration/sinks/slack.rst @@ -108,7 +108,7 @@ Set the ``SLACK_FORWARD_URL`` environment variable on the Robusta Runner pod to Add the following to your ``values.yaml`` file and upgrade: -.. code-block:: yaml +.. robusta-code:: yaml runner: additional_env_vars: diff --git a/docs/configuration/sinks/webhook.rst b/docs/configuration/sinks/webhook.rst index 0bb9b42ce..f1ba780a2 100644 --- a/docs/configuration/sinks/webhook.rst +++ b/docs/configuration/sinks/webhook.rst @@ -58,7 +58,7 @@ JSON payload When ``format: json`` is set, the POST body is a JSON object with the following top-level fields: -.. code-block:: json +.. robusta-code:: json { "title": "CrashLoopBackOff", diff --git a/docs/help.rst b/docs/help.rst index ae03332ef..5de4072ca 100644 --- a/docs/help.rst +++ b/docs/help.rst @@ -260,7 +260,7 @@ Alert Manager is not working .. tip:: - If you're using the Robusta UI, you can test alert routing by `Simulating an alert `_. + If you're using the Robusta UI, you can test alert routing by :robusta-url:`Simulating an alert `. diff --git a/docs/how-it-works/architecture.rst b/docs/how-it-works/architecture.rst index 696535dc9..0cef5e512 100644 --- a/docs/how-it-works/architecture.rst +++ b/docs/how-it-works/architecture.rst @@ -48,7 +48,7 @@ Security & Networking Next Steps ^^^^^^^^^^ -`Ready to install Robusta? Get started. `_ +:robusta-url:`Ready to install Robusta? Get started. ` .. _Robusta Classic: diff --git a/docs/how-it-works/oss-vs-saas.rst b/docs/how-it-works/oss-vs-saas.rst index a7161b4db..b70f3c96f 100644 --- a/docs/how-it-works/oss-vs-saas.rst +++ b/docs/how-it-works/oss-vs-saas.rst @@ -6,7 +6,7 @@ Robusta is delivered through the **Robusta Platform** — a centralized place to SaaS (Hosted) ^^^^^^^^^^^^^^ -The hosted Platform runs in Robusta's infrastructure. You install the in-cluster Agent, sign up at `platform.robusta.dev `_, and your alerts and investigations stream into the hosted UI. +The hosted Platform runs in Robusta's infrastructure. You install the in-cluster Agent, sign up at :robusta-url:`platform.robusta.dev `, and your alerts and investigations stream into the hosted UI. The SaaS Platform is **SOC 2 compliant** and available in multiple regions, including the **US**, **EU**, and **Asia Pacific**. diff --git a/docs/index.rst b/docs/index.rst index 7ecbafbfa..daebf5e55 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -77,6 +77,8 @@ Robusta is available as **SaaS**, **self-hosted**, or **open source**. See :doc: Ready to get started? --------------------- +.. robusta-region-picker:: + .. button-link:: https://platform.robusta.dev/signup :color: primary :outline: diff --git a/docs/notification-routing/routing-with-scopes.rst b/docs/notification-routing/routing-with-scopes.rst index b74ebd5c1..966be353a 100644 --- a/docs/notification-routing/routing-with-scopes.rst +++ b/docs/notification-routing/routing-with-scopes.rst @@ -277,7 +277,7 @@ Testing Alert Routing ---------------------- .. tip:: - Use the Robusta UI to test your alert routing rules by `simulating an alert `_. + Use the Robusta UI to test your alert routing rules by :robusta-url:`simulating an alert `. Scope Reference ----------------- diff --git a/docs/playbook-reference/index.rst b/docs/playbook-reference/index.rst index c71db435d..241995d30 100644 --- a/docs/playbook-reference/index.rst +++ b/docs/playbook-reference/index.rst @@ -18,7 +18,7 @@ Playbooks Basics Playbooks are deterministic rules for responding to alerts and unhealthy conditions in a Kubernetes cluster. -Playbooks are recommended for advanced use cases. Most users should start with the `Robusta SRE Agent `_, which requires far less configuration. +Playbooks are recommended for advanced use cases. Most users should start with the :robusta-url:`Robusta SRE Agent `, which requires far less configuration. How Playbooks Work ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/playbook-reference/triggers/elasticsearch.rst b/docs/playbook-reference/triggers/elasticsearch.rst index 1268bc68b..57ba1fd26 100644 --- a/docs/playbook-reference/triggers/elasticsearch.rst +++ b/docs/playbook-reference/triggers/elasticsearch.rst @@ -28,7 +28,7 @@ The following Elasticsearch Watcher configuration will trigger a Robusta playboo Make sure you update ````, ````, and ```` in the emphasized line. These should match the Robusta Helm chart values. -.. code-block:: json +.. robusta-code:: json :emphasize-lines: 26,27,33 { diff --git a/docs/setup-robusta/installation/_see_robusta_in_action-2.rst b/docs/setup-robusta/installation/_see_robusta_in_action-2.rst index bf5e3fcf7..af65fe648 100644 --- a/docs/setup-robusta/installation/_see_robusta_in_action-2.rst +++ b/docs/setup-robusta/installation/_see_robusta_in_action-2.rst @@ -55,7 +55,7 @@ Once the pod has reached two restarts, you'll get notified in Slack (or whatever .. image:: /images/crash-report.png -Now open the `Robusta UI `_ and look for the same message there. +Now open the :robusta-url:`Robusta UI ` and look for the same message there. Finally, clean up the crashing pod: diff --git a/docs/setup-robusta/installation/index.rst b/docs/setup-robusta/installation/index.rst index 10ef78996..84796e5ab 100644 --- a/docs/setup-robusta/installation/index.rst +++ b/docs/setup-robusta/installation/index.rst @@ -19,7 +19,7 @@ Prerequisites Sign Up and Install --------------------- -Sign up `for a free Robusta account ↗ `_ and follow the install wizard. It generates a ``generated_values.yaml`` file and provides the Helm install commands tailored to your cluster. +Sign up :robusta-url:`for a free Robusta account ↗ ` and follow the install wizard. It generates a ``generated_values.yaml`` file and provides the Helm install commands tailored to your cluster. .. note:: diff --git a/docs/setup-robusta/proxies.rst b/docs/setup-robusta/proxies.rst index 486ed6a11..563ec17aa 100644 --- a/docs/setup-robusta/proxies.rst +++ b/docs/setup-robusta/proxies.rst @@ -36,7 +36,7 @@ When deploying Robusta in a tightly restricted environment, the runner needs out .. note:: Traffic is **always initiated outbound from the runner**. No inbound connections to your cluster are required. All endpoints are reached over HTTPS (TCP/443) unless noted otherwise. -.. code-block:: text +.. robusta-code:: text # Robusta SaaS platform (required if robusta_sink enabled) *.robusta.dev @@ -118,7 +118,7 @@ Verifying the Allowlist After applying firewall rules, you can sanity-check connectivity from inside the runner pod: -.. code-block:: bash +.. robusta-code:: bash kubectl exec -n deploy/robusta-runner -- \ sh -c 'for host in api.robusta.dev relay.robusta.dev platform.robusta.dev; do